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