xref: /arm-trusted-firmware/drivers/cadence/combo_phy/cdns_combo_phy.c (revision 91f16700b400a8c0651d24a598fc48ee2997a0d7)
1*91f16700Schasinglulu /*
2*91f16700Schasinglulu  * Copyright (c) 2022-2023, Intel Corporation. All rights reserved.
3*91f16700Schasinglulu  *
4*91f16700Schasinglulu  * SPDX-License-Identifier: BSD-3-Clause
5*91f16700Schasinglulu  */
6*91f16700Schasinglulu 
7*91f16700Schasinglulu #include <assert.h>
8*91f16700Schasinglulu #include <errno.h>
9*91f16700Schasinglulu #include <stdbool.h>
10*91f16700Schasinglulu #include <string.h>
11*91f16700Schasinglulu 
12*91f16700Schasinglulu #include <arch_helpers.h>
13*91f16700Schasinglulu #include <common/debug.h>
14*91f16700Schasinglulu #include <drivers/cadence/cdns_combo_phy.h>
15*91f16700Schasinglulu #include <drivers/cadence/cdns_sdmmc.h>
16*91f16700Schasinglulu #include <drivers/delay_timer.h>
17*91f16700Schasinglulu #include <lib/mmio.h>
18*91f16700Schasinglulu #include <lib/utils.h>
19*91f16700Schasinglulu 
20*91f16700Schasinglulu int cdns_sdmmc_write_phy_reg(uint32_t phy_reg_addr, uint32_t phy_reg_addr_value,
21*91f16700Schasinglulu 			uint32_t phy_reg_data, uint32_t phy_reg_data_value)
22*91f16700Schasinglulu {
23*91f16700Schasinglulu 	uint32_t data = 0U;
24*91f16700Schasinglulu 	uint32_t value = 0U;
25*91f16700Schasinglulu 
26*91f16700Schasinglulu 	/* Get PHY register address, write HRS04*/
27*91f16700Schasinglulu 	value = mmio_read_32(phy_reg_addr);
28*91f16700Schasinglulu 	value &= ~PHY_REG_ADDR_MASK;
29*91f16700Schasinglulu 	value |= phy_reg_addr_value;
30*91f16700Schasinglulu 	mmio_write_32(phy_reg_addr, value);
31*91f16700Schasinglulu 	data = mmio_read_32(phy_reg_addr);
32*91f16700Schasinglulu 	if ((data & PHY_REG_ADDR_MASK) != phy_reg_addr_value) {
33*91f16700Schasinglulu 		ERROR("PHY_REG_ADDR is not set properly\n");
34*91f16700Schasinglulu 		return -ENXIO;
35*91f16700Schasinglulu 	}
36*91f16700Schasinglulu 
37*91f16700Schasinglulu 	/* Get PHY register data, write HRS05 */
38*91f16700Schasinglulu 	value &= ~PHY_REG_DATA_MASK;
39*91f16700Schasinglulu 	value |= phy_reg_data_value;
40*91f16700Schasinglulu 	mmio_write_32(phy_reg_data, value);
41*91f16700Schasinglulu 	data = mmio_read_32(phy_reg_data);
42*91f16700Schasinglulu 	if (data != phy_reg_data_value) {
43*91f16700Schasinglulu 		ERROR("PHY_REG_DATA is not set properly\n");
44*91f16700Schasinglulu 		return -ENXIO;
45*91f16700Schasinglulu 	}
46*91f16700Schasinglulu 
47*91f16700Schasinglulu 	return 0;
48*91f16700Schasinglulu }
49*91f16700Schasinglulu 
50*91f16700Schasinglulu int cdns_sd_card_detect(void)
51*91f16700Schasinglulu {
52*91f16700Schasinglulu 	uint32_t value = 0;
53*91f16700Schasinglulu 
54*91f16700Schasinglulu 	/* Card detection */
55*91f16700Schasinglulu 	do {
56*91f16700Schasinglulu 		value = mmio_read_32(SDMMC_CDN(SRS09));
57*91f16700Schasinglulu 	/* Wait for card insertion. SRS09.CI = 1 */
58*91f16700Schasinglulu 	} while ((value & (1 << SDMMC_CDN_CI)) == 0);
59*91f16700Schasinglulu 
60*91f16700Schasinglulu 	if ((value & (1 << SDMMC_CDN_CI)) == 0) {
61*91f16700Schasinglulu 		ERROR("Card does not detect\n");
62*91f16700Schasinglulu 		return -ENXIO;
63*91f16700Schasinglulu 	}
64*91f16700Schasinglulu 
65*91f16700Schasinglulu 	return 0;
66*91f16700Schasinglulu }
67*91f16700Schasinglulu 
68*91f16700Schasinglulu int cdns_emmc_card_reset(void)
69*91f16700Schasinglulu {
70*91f16700Schasinglulu 	uint32_t _status = 0;
71*91f16700Schasinglulu 
72*91f16700Schasinglulu 	/* Reset embedded card */
73*91f16700Schasinglulu 	mmio_write_32(SDMMC_CDN(SRS10), (7 << SDMMC_CDN_BVS) | (1 << SDMMC_CDN_BP) | _status);
74*91f16700Schasinglulu 	mdelay(68680); /* ~68680us */
75*91f16700Schasinglulu 	mmio_write_32(SDMMC_CDN(SRS10), (7 << SDMMC_CDN_BVS) | (0 << SDMMC_CDN_BP));
76*91f16700Schasinglulu 	udelay(340); /* ~340us */
77*91f16700Schasinglulu 
78*91f16700Schasinglulu 	/* Turn on supply voltage */
79*91f16700Schasinglulu 	/* BVS = 7, BP = 1, BP2 only in UHS2 mode */
80*91f16700Schasinglulu 	mmio_write_32(SDMMC_CDN(SRS10), (7 << SDMMC_CDN_BVS) | (1 << SDMMC_CDN_BP) | _status);
81*91f16700Schasinglulu 
82*91f16700Schasinglulu 	return 0;
83*91f16700Schasinglulu }
84