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 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 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 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