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