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