12874c5fdSThomas Gleixner // SPDX-License-Identifier: GPL-2.0-or-later 27657c3a7SAlbert Herranz /* 37657c3a7SAlbert Herranz * Freescale eSDHC controller driver. 47657c3a7SAlbert Herranz * 5f060bc9cSJerry Huang * Copyright (c) 2007, 2010, 2012 Freescale Semiconductor, Inc. 67657c3a7SAlbert Herranz * Copyright (c) 2009 MontaVista Software, Inc. 7011fde48SYangbo Lu * Copyright 2020 NXP 87657c3a7SAlbert Herranz * 97657c3a7SAlbert Herranz * Authors: Xiaobo Xie <X.Xie@freescale.com> 107657c3a7SAlbert Herranz * Anton Vorontsov <avorontsov@ru.mvista.com> 117657c3a7SAlbert Herranz */ 127657c3a7SAlbert Herranz 1366b50a00SOded Gabbay #include <linux/err.h> 147657c3a7SAlbert Herranz #include <linux/io.h> 15f060bc9cSJerry Huang #include <linux/of.h> 16ea35645aSyangbo lu #include <linux/of_address.h> 177657c3a7SAlbert Herranz #include <linux/delay.h> 1888b47679SPaul Gortmaker #include <linux/module.h> 19151ede40Syangbo lu #include <linux/sys_soc.h> 2019c3a0efSyangbo lu #include <linux/clk.h> 2119c3a0efSyangbo lu #include <linux/ktime.h> 225552d7adSLaurentiu Tudor #include <linux/dma-mapping.h> 23011fde48SYangbo Lu #include <linux/iopoll.h> 247657c3a7SAlbert Herranz #include <linux/mmc/host.h> 25b214fe59SYinbo Zhu #include <linux/mmc/mmc.h> 2638576af1SShawn Guo #include "sdhci-pltfm.h" 2780872e21SWolfram Sang #include "sdhci-esdhc.h" 287657c3a7SAlbert Herranz 29137ccd46SJerry Huang #define VENDOR_V_22 0x12 30a4071fbbSHaijun Zhang #define VENDOR_V_23 0x13 31f4932cfdSyangbo lu 3267fdfbdfSyinbo.zhu #define MMC_TIMING_NUM (MMC_TIMING_MMC_HS400 + 1) 3367fdfbdfSyinbo.zhu 3467fdfbdfSyinbo.zhu struct esdhc_clk_fixup { 3567fdfbdfSyinbo.zhu const unsigned int sd_dflt_max_clk; 3667fdfbdfSyinbo.zhu const unsigned int max_clk[MMC_TIMING_NUM]; 3767fdfbdfSyinbo.zhu }; 3867fdfbdfSyinbo.zhu 3967fdfbdfSyinbo.zhu static const struct esdhc_clk_fixup ls1021a_esdhc_clk = { 4067fdfbdfSyinbo.zhu .sd_dflt_max_clk = 25000000, 4167fdfbdfSyinbo.zhu .max_clk[MMC_TIMING_MMC_HS] = 46500000, 4267fdfbdfSyinbo.zhu .max_clk[MMC_TIMING_SD_HS] = 46500000, 4367fdfbdfSyinbo.zhu }; 4467fdfbdfSyinbo.zhu 45*c8d2d76dSAndy Tang static const struct esdhc_clk_fixup ls1043a_esdhc_clk = { 46*c8d2d76dSAndy Tang .sd_dflt_max_clk = 25000000, 47*c8d2d76dSAndy Tang .max_clk[MMC_TIMING_UHS_SDR104] = 116700000, 48*c8d2d76dSAndy Tang .max_clk[MMC_TIMING_MMC_HS200] = 116700000, 49*c8d2d76dSAndy Tang }; 50*c8d2d76dSAndy Tang 5167fdfbdfSyinbo.zhu static const struct esdhc_clk_fixup ls1046a_esdhc_clk = { 5267fdfbdfSyinbo.zhu .sd_dflt_max_clk = 25000000, 5367fdfbdfSyinbo.zhu .max_clk[MMC_TIMING_UHS_SDR104] = 167000000, 5467fdfbdfSyinbo.zhu .max_clk[MMC_TIMING_MMC_HS200] = 167000000, 5567fdfbdfSyinbo.zhu }; 5667fdfbdfSyinbo.zhu 5767fdfbdfSyinbo.zhu static const struct esdhc_clk_fixup ls1012a_esdhc_clk = { 5867fdfbdfSyinbo.zhu .sd_dflt_max_clk = 25000000, 5967fdfbdfSyinbo.zhu .max_clk[MMC_TIMING_UHS_SDR104] = 125000000, 6067fdfbdfSyinbo.zhu .max_clk[MMC_TIMING_MMC_HS200] = 125000000, 6167fdfbdfSyinbo.zhu }; 6267fdfbdfSyinbo.zhu 6367fdfbdfSyinbo.zhu static const struct esdhc_clk_fixup p1010_esdhc_clk = { 6467fdfbdfSyinbo.zhu .sd_dflt_max_clk = 20000000, 6567fdfbdfSyinbo.zhu .max_clk[MMC_TIMING_LEGACY] = 20000000, 6667fdfbdfSyinbo.zhu .max_clk[MMC_TIMING_MMC_HS] = 42000000, 6767fdfbdfSyinbo.zhu .max_clk[MMC_TIMING_SD_HS] = 40000000, 6867fdfbdfSyinbo.zhu }; 6967fdfbdfSyinbo.zhu 7067fdfbdfSyinbo.zhu static const struct of_device_id sdhci_esdhc_of_match[] = { 7167fdfbdfSyinbo.zhu { .compatible = "fsl,ls1021a-esdhc", .data = &ls1021a_esdhc_clk}, 72*c8d2d76dSAndy Tang { .compatible = "fsl,ls1043a-esdhc", .data = &ls1043a_esdhc_clk}, 7367fdfbdfSyinbo.zhu { .compatible = "fsl,ls1046a-esdhc", .data = &ls1046a_esdhc_clk}, 7467fdfbdfSyinbo.zhu { .compatible = "fsl,ls1012a-esdhc", .data = &ls1012a_esdhc_clk}, 7567fdfbdfSyinbo.zhu { .compatible = "fsl,p1010-esdhc", .data = &p1010_esdhc_clk}, 7667fdfbdfSyinbo.zhu { .compatible = "fsl,mpc8379-esdhc" }, 7767fdfbdfSyinbo.zhu { .compatible = "fsl,mpc8536-esdhc" }, 7867fdfbdfSyinbo.zhu { .compatible = "fsl,esdhc" }, 7967fdfbdfSyinbo.zhu { } 8067fdfbdfSyinbo.zhu }; 8167fdfbdfSyinbo.zhu MODULE_DEVICE_TABLE(of, sdhci_esdhc_of_match); 8267fdfbdfSyinbo.zhu 83f4932cfdSyangbo lu struct sdhci_esdhc { 84f4932cfdSyangbo lu u8 vendor_ver; 85f4932cfdSyangbo lu u8 spec_ver; 86151ede40Syangbo lu bool quirk_incorrect_hostver; 876079e63cSYangbo Lu bool quirk_limited_clk_division; 8848e304ccSYangbo Lu bool quirk_unreliable_pulse_detection; 8922dc132dSYangbo Lu bool quirk_tuning_erratum_type1; 9022dc132dSYangbo Lu bool quirk_tuning_erratum_type2; 911f1929f3SYangbo Lu bool quirk_ignore_data_inhibit; 92f667216cSYangbo Lu bool quirk_delay_before_data_reset; 93060522d8SChris Packham bool quirk_trans_complete_erratum; 9422dc132dSYangbo Lu bool in_sw_tuning; 9519c3a0efSyangbo lu unsigned int peripheral_clock; 9667fdfbdfSyinbo.zhu const struct esdhc_clk_fixup *clk_fixup; 97b1f378abSYinbo Zhu u32 div_ratio; 98f4932cfdSyangbo lu }; 99f4932cfdSyangbo lu 100f4932cfdSyangbo lu /** 101f4932cfdSyangbo lu * esdhc_read*_fixup - Fixup the value read from incompatible eSDHC register 102f4932cfdSyangbo lu * to make it compatible with SD spec. 103f4932cfdSyangbo lu * 104f4932cfdSyangbo lu * @host: pointer to sdhci_host 105f4932cfdSyangbo lu * @spec_reg: SD spec register address 106f4932cfdSyangbo lu * @value: 32bit eSDHC register value on spec_reg address 107f4932cfdSyangbo lu * 108f4932cfdSyangbo lu * In SD spec, there are 8/16/32/64 bits registers, while all of eSDHC 109f4932cfdSyangbo lu * registers are 32 bits. There are differences in register size, register 110f4932cfdSyangbo lu * address, register function, bit position and function between eSDHC spec 111f4932cfdSyangbo lu * and SD spec. 112f4932cfdSyangbo lu * 113f4932cfdSyangbo lu * Return a fixed up register value 114f4932cfdSyangbo lu */ 115f4932cfdSyangbo lu static u32 esdhc_readl_fixup(struct sdhci_host *host, 116f4932cfdSyangbo lu int spec_reg, u32 value) 117137ccd46SJerry Huang { 118f4932cfdSyangbo lu struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); 1198605e7aeSJisheng Zhang struct sdhci_esdhc *esdhc = sdhci_pltfm_priv(pltfm_host); 120137ccd46SJerry Huang u32 ret; 121137ccd46SJerry Huang 122137ccd46SJerry Huang /* 123137ccd46SJerry Huang * The bit of ADMA flag in eSDHC is not compatible with standard 124137ccd46SJerry Huang * SDHC register, so set fake flag SDHCI_CAN_DO_ADMA2 when ADMA is 125137ccd46SJerry Huang * supported by eSDHC. 126137ccd46SJerry Huang * And for many FSL eSDHC controller, the reset value of field 127f4932cfdSyangbo lu * SDHCI_CAN_DO_ADMA1 is 1, but some of them can't support ADMA, 128137ccd46SJerry Huang * only these vendor version is greater than 2.2/0x12 support ADMA. 129137ccd46SJerry Huang */ 130f4932cfdSyangbo lu if ((spec_reg == SDHCI_CAPABILITIES) && (value & SDHCI_CAN_DO_ADMA1)) { 131f4932cfdSyangbo lu if (esdhc->vendor_ver > VENDOR_V_22) { 132f4932cfdSyangbo lu ret = value | SDHCI_CAN_DO_ADMA2; 133f4932cfdSyangbo lu return ret; 134137ccd46SJerry Huang } 135f4932cfdSyangbo lu } 136b0921d5cSMichael Walle /* 137b0921d5cSMichael Walle * The DAT[3:0] line signal levels and the CMD line signal level are 138b0921d5cSMichael Walle * not compatible with standard SDHC register. The line signal levels 139b0921d5cSMichael Walle * DAT[7:0] are at bits 31:24 and the command line signal level is at 140b0921d5cSMichael Walle * bit 23. All other bits are the same as in the standard SDHC 141b0921d5cSMichael Walle * register. 142b0921d5cSMichael Walle */ 143b0921d5cSMichael Walle if (spec_reg == SDHCI_PRESENT_STATE) { 144b0921d5cSMichael Walle ret = value & 0x000fffff; 145b0921d5cSMichael Walle ret |= (value >> 4) & SDHCI_DATA_LVL_MASK; 146b0921d5cSMichael Walle ret |= (value << 1) & SDHCI_CMD_LVL; 147b0921d5cSMichael Walle return ret; 148b0921d5cSMichael Walle } 149b0921d5cSMichael Walle 1502f3110ccSyangbo lu /* 1512f3110ccSyangbo lu * DTS properties of mmc host are used to enable each speed mode 1522f3110ccSyangbo lu * according to soc and board capability. So clean up 1532f3110ccSyangbo lu * SDR50/SDR104/DDR50 support bits here. 1542f3110ccSyangbo lu */ 1552f3110ccSyangbo lu if (spec_reg == SDHCI_CAPABILITIES_1) { 1562f3110ccSyangbo lu ret = value & ~(SDHCI_SUPPORT_SDR50 | SDHCI_SUPPORT_SDR104 | 1572f3110ccSyangbo lu SDHCI_SUPPORT_DDR50); 1582f3110ccSyangbo lu return ret; 1592f3110ccSyangbo lu } 1602f3110ccSyangbo lu 1611f1929f3SYangbo Lu /* 1621f1929f3SYangbo Lu * Some controllers have unreliable Data Line Active 1631f1929f3SYangbo Lu * bit for commands with busy signal. This affects 1641f1929f3SYangbo Lu * Command Inhibit (data) bit. Just ignore it since 1651f1929f3SYangbo Lu * MMC core driver has already polled card status 1661f1929f3SYangbo Lu * with CMD13 after any command with busy siganl. 1671f1929f3SYangbo Lu */ 1681f1929f3SYangbo Lu if ((spec_reg == SDHCI_PRESENT_STATE) && 1691f1929f3SYangbo Lu (esdhc->quirk_ignore_data_inhibit == true)) { 1701f1929f3SYangbo Lu ret = value & ~SDHCI_DATA_INHIBIT; 1711f1929f3SYangbo Lu return ret; 1721f1929f3SYangbo Lu } 1731f1929f3SYangbo Lu 174f4932cfdSyangbo lu ret = value; 175137ccd46SJerry Huang return ret; 176137ccd46SJerry Huang } 177137ccd46SJerry Huang 178f4932cfdSyangbo lu static u16 esdhc_readw_fixup(struct sdhci_host *host, 179f4932cfdSyangbo lu int spec_reg, u32 value) 1807657c3a7SAlbert Herranz { 181151ede40Syangbo lu struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); 182151ede40Syangbo lu struct sdhci_esdhc *esdhc = sdhci_pltfm_priv(pltfm_host); 1837657c3a7SAlbert Herranz u16 ret; 184f4932cfdSyangbo lu int shift = (spec_reg & 0x2) * 8; 1857657c3a7SAlbert Herranz 186429d939cSYangbo Lu if (spec_reg == SDHCI_TRANSFER_MODE) 187429d939cSYangbo Lu return pltfm_host->xfer_mode_shadow; 188429d939cSYangbo Lu 189f4932cfdSyangbo lu if (spec_reg == SDHCI_HOST_VERSION) 190f4932cfdSyangbo lu ret = value & 0xffff; 1917657c3a7SAlbert Herranz else 192f4932cfdSyangbo lu ret = (value >> shift) & 0xffff; 193151ede40Syangbo lu /* Workaround for T4240-R1.0-R2.0 eSDHC which has incorrect 194151ede40Syangbo lu * vendor version and spec version information. 195151ede40Syangbo lu */ 196151ede40Syangbo lu if ((spec_reg == SDHCI_HOST_VERSION) && 197151ede40Syangbo lu (esdhc->quirk_incorrect_hostver)) 198151ede40Syangbo lu ret = (VENDOR_V_23 << SDHCI_VENDOR_VER_SHIFT) | SDHCI_SPEC_200; 199e51cbc9eSXu lei return ret; 200e51cbc9eSXu lei } 201e51cbc9eSXu lei 202f4932cfdSyangbo lu static u8 esdhc_readb_fixup(struct sdhci_host *host, 203f4932cfdSyangbo lu int spec_reg, u32 value) 204e51cbc9eSXu lei { 205f4932cfdSyangbo lu u8 ret; 206f4932cfdSyangbo lu u8 dma_bits; 207f4932cfdSyangbo lu int shift = (spec_reg & 0x3) * 8; 208f4932cfdSyangbo lu 209f4932cfdSyangbo lu ret = (value >> shift) & 0xff; 210ba8c4dc9SRoy Zang 211ba8c4dc9SRoy Zang /* 212ba8c4dc9SRoy Zang * "DMA select" locates at offset 0x28 in SD specification, but on 213ba8c4dc9SRoy Zang * P5020 or P3041, it locates at 0x29. 214ba8c4dc9SRoy Zang */ 215f4932cfdSyangbo lu if (spec_reg == SDHCI_HOST_CONTROL) { 216ba8c4dc9SRoy Zang /* DMA select is 22,23 bits in Protocol Control Register */ 217f4932cfdSyangbo lu dma_bits = (value >> 5) & SDHCI_CTRL_DMA_MASK; 218ba8c4dc9SRoy Zang /* fixup the result */ 219ba8c4dc9SRoy Zang ret &= ~SDHCI_CTRL_DMA_MASK; 220ba8c4dc9SRoy Zang ret |= dma_bits; 221ba8c4dc9SRoy Zang } 222f4932cfdSyangbo lu return ret; 223f4932cfdSyangbo lu } 224f4932cfdSyangbo lu 225f4932cfdSyangbo lu /** 226f4932cfdSyangbo lu * esdhc_write*_fixup - Fixup the SD spec register value so that it could be 227f4932cfdSyangbo lu * written into eSDHC register. 228f4932cfdSyangbo lu * 229f4932cfdSyangbo lu * @host: pointer to sdhci_host 230f4932cfdSyangbo lu * @spec_reg: SD spec register address 231f4932cfdSyangbo lu * @value: 8/16/32bit SD spec register value that would be written 232f4932cfdSyangbo lu * @old_value: 32bit eSDHC register value on spec_reg address 233f4932cfdSyangbo lu * 234f4932cfdSyangbo lu * In SD spec, there are 8/16/32/64 bits registers, while all of eSDHC 235f4932cfdSyangbo lu * registers are 32 bits. There are differences in register size, register 236f4932cfdSyangbo lu * address, register function, bit position and function between eSDHC spec 237f4932cfdSyangbo lu * and SD spec. 238f4932cfdSyangbo lu * 239f4932cfdSyangbo lu * Return a fixed up register value 240f4932cfdSyangbo lu */ 241f4932cfdSyangbo lu static u32 esdhc_writel_fixup(struct sdhci_host *host, 242f4932cfdSyangbo lu int spec_reg, u32 value, u32 old_value) 243f4932cfdSyangbo lu { 244f4932cfdSyangbo lu u32 ret; 245f4932cfdSyangbo lu 246f4932cfdSyangbo lu /* 247f4932cfdSyangbo lu * Enabling IRQSTATEN[BGESEN] is just to set IRQSTAT[BGE] 248f4932cfdSyangbo lu * when SYSCTL[RSTD] is set for some special operations. 249f4932cfdSyangbo lu * No any impact on other operation. 250f4932cfdSyangbo lu */ 251f4932cfdSyangbo lu if (spec_reg == SDHCI_INT_ENABLE) 252f4932cfdSyangbo lu ret = value | SDHCI_INT_BLK_GAP; 253f4932cfdSyangbo lu else 254f4932cfdSyangbo lu ret = value; 255ba8c4dc9SRoy Zang 2567657c3a7SAlbert Herranz return ret; 2577657c3a7SAlbert Herranz } 2587657c3a7SAlbert Herranz 259f4932cfdSyangbo lu static u32 esdhc_writew_fixup(struct sdhci_host *host, 260f4932cfdSyangbo lu int spec_reg, u16 value, u32 old_value) 261a4071fbbSHaijun Zhang { 262f4932cfdSyangbo lu struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); 263f4932cfdSyangbo lu int shift = (spec_reg & 0x2) * 8; 264f4932cfdSyangbo lu u32 ret; 265f4932cfdSyangbo lu 266f4932cfdSyangbo lu switch (spec_reg) { 267f4932cfdSyangbo lu case SDHCI_TRANSFER_MODE: 268a4071fbbSHaijun Zhang /* 269f4932cfdSyangbo lu * Postpone this write, we must do it together with a 270f4932cfdSyangbo lu * command write that is down below. Return old value. 271a4071fbbSHaijun Zhang */ 272f4932cfdSyangbo lu pltfm_host->xfer_mode_shadow = value; 273f4932cfdSyangbo lu return old_value; 274f4932cfdSyangbo lu case SDHCI_COMMAND: 275f4932cfdSyangbo lu ret = (value << 16) | pltfm_host->xfer_mode_shadow; 276f4932cfdSyangbo lu return ret; 277a4071fbbSHaijun Zhang } 278a4071fbbSHaijun Zhang 279f4932cfdSyangbo lu ret = old_value & (~(0xffff << shift)); 280f4932cfdSyangbo lu ret |= (value << shift); 281f4932cfdSyangbo lu 282f4932cfdSyangbo lu if (spec_reg == SDHCI_BLOCK_SIZE) { 2837657c3a7SAlbert Herranz /* 2847657c3a7SAlbert Herranz * Two last DMA bits are reserved, and first one is used for 2857657c3a7SAlbert Herranz * non-standard blksz of 4096 bytes that we don't support 2867657c3a7SAlbert Herranz * yet. So clear the DMA boundary bits. 2877657c3a7SAlbert Herranz */ 288f4932cfdSyangbo lu ret &= (~SDHCI_MAKE_BLKSZ(0x7, 0)); 2897657c3a7SAlbert Herranz } 290f4932cfdSyangbo lu return ret; 2917657c3a7SAlbert Herranz } 2927657c3a7SAlbert Herranz 293f4932cfdSyangbo lu static u32 esdhc_writeb_fixup(struct sdhci_host *host, 294f4932cfdSyangbo lu int spec_reg, u8 value, u32 old_value) 2957657c3a7SAlbert Herranz { 296f4932cfdSyangbo lu u32 ret; 297f4932cfdSyangbo lu u32 dma_bits; 298f4932cfdSyangbo lu u8 tmp; 299f4932cfdSyangbo lu int shift = (spec_reg & 0x3) * 8; 300f4932cfdSyangbo lu 301ba8c4dc9SRoy Zang /* 3029e4703dfSyangbo lu * eSDHC doesn't have a standard power control register, so we do 3039e4703dfSyangbo lu * nothing here to avoid incorrect operation. 3049e4703dfSyangbo lu */ 3059e4703dfSyangbo lu if (spec_reg == SDHCI_POWER_CONTROL) 3069e4703dfSyangbo lu return old_value; 3079e4703dfSyangbo lu /* 308ba8c4dc9SRoy Zang * "DMA select" location is offset 0x28 in SD specification, but on 309ba8c4dc9SRoy Zang * P5020 or P3041, it's located at 0x29. 310ba8c4dc9SRoy Zang */ 311f4932cfdSyangbo lu if (spec_reg == SDHCI_HOST_CONTROL) { 312dcaff04dSOded Gabbay /* 313dcaff04dSOded Gabbay * If host control register is not standard, exit 314dcaff04dSOded Gabbay * this function 315dcaff04dSOded Gabbay */ 316dcaff04dSOded Gabbay if (host->quirks2 & SDHCI_QUIRK2_BROKEN_HOST_CONTROL) 317f4932cfdSyangbo lu return old_value; 318dcaff04dSOded Gabbay 319ba8c4dc9SRoy Zang /* DMA select is 22,23 bits in Protocol Control Register */ 320f4932cfdSyangbo lu dma_bits = (value & SDHCI_CTRL_DMA_MASK) << 5; 321f4932cfdSyangbo lu ret = (old_value & (~(SDHCI_CTRL_DMA_MASK << 5))) | dma_bits; 322f4932cfdSyangbo lu tmp = (value & (~SDHCI_CTRL_DMA_MASK)) | 323f4932cfdSyangbo lu (old_value & SDHCI_CTRL_DMA_MASK); 324f4932cfdSyangbo lu ret = (ret & (~0xff)) | tmp; 325f4932cfdSyangbo lu 326f4932cfdSyangbo lu /* Prevent SDHCI core from writing reserved bits (e.g. HISPD) */ 327f4932cfdSyangbo lu ret &= ~ESDHC_HOST_CONTROL_RES; 328f4932cfdSyangbo lu return ret; 329ba8c4dc9SRoy Zang } 330ba8c4dc9SRoy Zang 331f4932cfdSyangbo lu ret = (old_value & (~(0xff << shift))) | (value << shift); 332f4932cfdSyangbo lu return ret; 333f4932cfdSyangbo lu } 334f4932cfdSyangbo lu 335f4932cfdSyangbo lu static u32 esdhc_be_readl(struct sdhci_host *host, int reg) 336f4932cfdSyangbo lu { 337f4932cfdSyangbo lu u32 ret; 338f4932cfdSyangbo lu u32 value; 339f4932cfdSyangbo lu 3402f3110ccSyangbo lu if (reg == SDHCI_CAPABILITIES_1) 3412f3110ccSyangbo lu value = ioread32be(host->ioaddr + ESDHC_CAPABILITIES_1); 3422f3110ccSyangbo lu else 343f4932cfdSyangbo lu value = ioread32be(host->ioaddr + reg); 3442f3110ccSyangbo lu 345f4932cfdSyangbo lu ret = esdhc_readl_fixup(host, reg, value); 346f4932cfdSyangbo lu 347f4932cfdSyangbo lu return ret; 348f4932cfdSyangbo lu } 349f4932cfdSyangbo lu 350f4932cfdSyangbo lu static u32 esdhc_le_readl(struct sdhci_host *host, int reg) 351f4932cfdSyangbo lu { 352f4932cfdSyangbo lu u32 ret; 353f4932cfdSyangbo lu u32 value; 354f4932cfdSyangbo lu 3552f3110ccSyangbo lu if (reg == SDHCI_CAPABILITIES_1) 3562f3110ccSyangbo lu value = ioread32(host->ioaddr + ESDHC_CAPABILITIES_1); 3572f3110ccSyangbo lu else 358f4932cfdSyangbo lu value = ioread32(host->ioaddr + reg); 3592f3110ccSyangbo lu 360f4932cfdSyangbo lu ret = esdhc_readl_fixup(host, reg, value); 361f4932cfdSyangbo lu 362f4932cfdSyangbo lu return ret; 363f4932cfdSyangbo lu } 364f4932cfdSyangbo lu 365f4932cfdSyangbo lu static u16 esdhc_be_readw(struct sdhci_host *host, int reg) 366f4932cfdSyangbo lu { 367f4932cfdSyangbo lu u16 ret; 368f4932cfdSyangbo lu u32 value; 369f4932cfdSyangbo lu int base = reg & ~0x3; 370f4932cfdSyangbo lu 371f4932cfdSyangbo lu value = ioread32be(host->ioaddr + base); 372f4932cfdSyangbo lu ret = esdhc_readw_fixup(host, reg, value); 373f4932cfdSyangbo lu return ret; 374f4932cfdSyangbo lu } 375f4932cfdSyangbo lu 376f4932cfdSyangbo lu static u16 esdhc_le_readw(struct sdhci_host *host, int reg) 377f4932cfdSyangbo lu { 378f4932cfdSyangbo lu u16 ret; 379f4932cfdSyangbo lu u32 value; 380f4932cfdSyangbo lu int base = reg & ~0x3; 381f4932cfdSyangbo lu 382f4932cfdSyangbo lu value = ioread32(host->ioaddr + base); 383f4932cfdSyangbo lu ret = esdhc_readw_fixup(host, reg, value); 384f4932cfdSyangbo lu return ret; 385f4932cfdSyangbo lu } 386f4932cfdSyangbo lu 387f4932cfdSyangbo lu static u8 esdhc_be_readb(struct sdhci_host *host, int reg) 388f4932cfdSyangbo lu { 389f4932cfdSyangbo lu u8 ret; 390f4932cfdSyangbo lu u32 value; 391f4932cfdSyangbo lu int base = reg & ~0x3; 392f4932cfdSyangbo lu 393f4932cfdSyangbo lu value = ioread32be(host->ioaddr + base); 394f4932cfdSyangbo lu ret = esdhc_readb_fixup(host, reg, value); 395f4932cfdSyangbo lu return ret; 396f4932cfdSyangbo lu } 397f4932cfdSyangbo lu 398f4932cfdSyangbo lu static u8 esdhc_le_readb(struct sdhci_host *host, int reg) 399f4932cfdSyangbo lu { 400f4932cfdSyangbo lu u8 ret; 401f4932cfdSyangbo lu u32 value; 402f4932cfdSyangbo lu int base = reg & ~0x3; 403f4932cfdSyangbo lu 404f4932cfdSyangbo lu value = ioread32(host->ioaddr + base); 405f4932cfdSyangbo lu ret = esdhc_readb_fixup(host, reg, value); 406f4932cfdSyangbo lu return ret; 407f4932cfdSyangbo lu } 408f4932cfdSyangbo lu 409f4932cfdSyangbo lu static void esdhc_be_writel(struct sdhci_host *host, u32 val, int reg) 410f4932cfdSyangbo lu { 411f4932cfdSyangbo lu u32 value; 412f4932cfdSyangbo lu 413f4932cfdSyangbo lu value = esdhc_writel_fixup(host, reg, val, 0); 414f4932cfdSyangbo lu iowrite32be(value, host->ioaddr + reg); 415f4932cfdSyangbo lu } 416f4932cfdSyangbo lu 417f4932cfdSyangbo lu static void esdhc_le_writel(struct sdhci_host *host, u32 val, int reg) 418f4932cfdSyangbo lu { 419f4932cfdSyangbo lu u32 value; 420f4932cfdSyangbo lu 421f4932cfdSyangbo lu value = esdhc_writel_fixup(host, reg, val, 0); 422f4932cfdSyangbo lu iowrite32(value, host->ioaddr + reg); 423f4932cfdSyangbo lu } 424f4932cfdSyangbo lu 425f4932cfdSyangbo lu static void esdhc_be_writew(struct sdhci_host *host, u16 val, int reg) 426f4932cfdSyangbo lu { 42722dc132dSYangbo Lu struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); 42822dc132dSYangbo Lu struct sdhci_esdhc *esdhc = sdhci_pltfm_priv(pltfm_host); 429f4932cfdSyangbo lu int base = reg & ~0x3; 430f4932cfdSyangbo lu u32 value; 431f4932cfdSyangbo lu u32 ret; 432f4932cfdSyangbo lu 433f4932cfdSyangbo lu value = ioread32be(host->ioaddr + base); 434f4932cfdSyangbo lu ret = esdhc_writew_fixup(host, reg, val, value); 435f4932cfdSyangbo lu if (reg != SDHCI_TRANSFER_MODE) 436f4932cfdSyangbo lu iowrite32be(ret, host->ioaddr + base); 43722dc132dSYangbo Lu 43822dc132dSYangbo Lu /* Starting SW tuning requires ESDHC_SMPCLKSEL to be set 43922dc132dSYangbo Lu * 1us later after ESDHC_EXTN is set. 44022dc132dSYangbo Lu */ 44122dc132dSYangbo Lu if (base == ESDHC_SYSTEM_CONTROL_2) { 44222dc132dSYangbo Lu if (!(value & ESDHC_EXTN) && (ret & ESDHC_EXTN) && 44322dc132dSYangbo Lu esdhc->in_sw_tuning) { 44422dc132dSYangbo Lu udelay(1); 44522dc132dSYangbo Lu ret |= ESDHC_SMPCLKSEL; 44622dc132dSYangbo Lu iowrite32be(ret, host->ioaddr + base); 44722dc132dSYangbo Lu } 44822dc132dSYangbo Lu } 449f4932cfdSyangbo lu } 450f4932cfdSyangbo lu 451f4932cfdSyangbo lu static void esdhc_le_writew(struct sdhci_host *host, u16 val, int reg) 452f4932cfdSyangbo lu { 45322dc132dSYangbo Lu struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); 45422dc132dSYangbo Lu struct sdhci_esdhc *esdhc = sdhci_pltfm_priv(pltfm_host); 455f4932cfdSyangbo lu int base = reg & ~0x3; 456f4932cfdSyangbo lu u32 value; 457f4932cfdSyangbo lu u32 ret; 458f4932cfdSyangbo lu 459f4932cfdSyangbo lu value = ioread32(host->ioaddr + base); 460f4932cfdSyangbo lu ret = esdhc_writew_fixup(host, reg, val, value); 461f4932cfdSyangbo lu if (reg != SDHCI_TRANSFER_MODE) 462f4932cfdSyangbo lu iowrite32(ret, host->ioaddr + base); 46322dc132dSYangbo Lu 46422dc132dSYangbo Lu /* Starting SW tuning requires ESDHC_SMPCLKSEL to be set 46522dc132dSYangbo Lu * 1us later after ESDHC_EXTN is set. 46622dc132dSYangbo Lu */ 46722dc132dSYangbo Lu if (base == ESDHC_SYSTEM_CONTROL_2) { 46822dc132dSYangbo Lu if (!(value & ESDHC_EXTN) && (ret & ESDHC_EXTN) && 46922dc132dSYangbo Lu esdhc->in_sw_tuning) { 47022dc132dSYangbo Lu udelay(1); 47122dc132dSYangbo Lu ret |= ESDHC_SMPCLKSEL; 47222dc132dSYangbo Lu iowrite32(ret, host->ioaddr + base); 47322dc132dSYangbo Lu } 47422dc132dSYangbo Lu } 475f4932cfdSyangbo lu } 476f4932cfdSyangbo lu 477f4932cfdSyangbo lu static void esdhc_be_writeb(struct sdhci_host *host, u8 val, int reg) 478f4932cfdSyangbo lu { 479f4932cfdSyangbo lu int base = reg & ~0x3; 480f4932cfdSyangbo lu u32 value; 481f4932cfdSyangbo lu u32 ret; 482f4932cfdSyangbo lu 483f4932cfdSyangbo lu value = ioread32be(host->ioaddr + base); 484f4932cfdSyangbo lu ret = esdhc_writeb_fixup(host, reg, val, value); 485f4932cfdSyangbo lu iowrite32be(ret, host->ioaddr + base); 486f4932cfdSyangbo lu } 487f4932cfdSyangbo lu 488f4932cfdSyangbo lu static void esdhc_le_writeb(struct sdhci_host *host, u8 val, int reg) 489f4932cfdSyangbo lu { 490f4932cfdSyangbo lu int base = reg & ~0x3; 491f4932cfdSyangbo lu u32 value; 492f4932cfdSyangbo lu u32 ret; 493f4932cfdSyangbo lu 494f4932cfdSyangbo lu value = ioread32(host->ioaddr + base); 495f4932cfdSyangbo lu ret = esdhc_writeb_fixup(host, reg, val, value); 496f4932cfdSyangbo lu iowrite32(ret, host->ioaddr + base); 4977657c3a7SAlbert Herranz } 4987657c3a7SAlbert Herranz 499a4071fbbSHaijun Zhang /* 500a4071fbbSHaijun Zhang * For Abort or Suspend after Stop at Block Gap, ignore the ADMA 501a4071fbbSHaijun Zhang * error(IRQSTAT[ADMAE]) if both Transfer Complete(IRQSTAT[TC]) 502a4071fbbSHaijun Zhang * and Block Gap Event(IRQSTAT[BGE]) are also set. 503a4071fbbSHaijun Zhang * For Continue, apply soft reset for data(SYSCTL[RSTD]); 504a4071fbbSHaijun Zhang * and re-issue the entire read transaction from beginning. 505a4071fbbSHaijun Zhang */ 506f4932cfdSyangbo lu static void esdhc_of_adma_workaround(struct sdhci_host *host, u32 intmask) 507a4071fbbSHaijun Zhang { 508f4932cfdSyangbo lu struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); 5098605e7aeSJisheng Zhang struct sdhci_esdhc *esdhc = sdhci_pltfm_priv(pltfm_host); 510a4071fbbSHaijun Zhang bool applicable; 511a4071fbbSHaijun Zhang dma_addr_t dmastart; 512a4071fbbSHaijun Zhang dma_addr_t dmanow; 513a4071fbbSHaijun Zhang 514a4071fbbSHaijun Zhang applicable = (intmask & SDHCI_INT_DATA_END) && 515a4071fbbSHaijun Zhang (intmask & SDHCI_INT_BLK_GAP) && 516f4932cfdSyangbo lu (esdhc->vendor_ver == VENDOR_V_23); 517a4071fbbSHaijun Zhang if (!applicable) 518a4071fbbSHaijun Zhang return; 519a4071fbbSHaijun Zhang 520a4071fbbSHaijun Zhang host->data->error = 0; 521a4071fbbSHaijun Zhang dmastart = sg_dma_address(host->data->sg); 522a4071fbbSHaijun Zhang dmanow = dmastart + host->data->bytes_xfered; 523a4071fbbSHaijun Zhang /* 524a4071fbbSHaijun Zhang * Force update to the next DMA block boundary. 525a4071fbbSHaijun Zhang */ 526a4071fbbSHaijun Zhang dmanow = (dmanow & ~(SDHCI_DEFAULT_BOUNDARY_SIZE - 1)) + 527a4071fbbSHaijun Zhang SDHCI_DEFAULT_BOUNDARY_SIZE; 528a4071fbbSHaijun Zhang host->data->bytes_xfered = dmanow - dmastart; 529a4071fbbSHaijun Zhang sdhci_writel(host, dmanow, SDHCI_DMA_ADDRESS); 530a4071fbbSHaijun Zhang } 531a4071fbbSHaijun Zhang 53280872e21SWolfram Sang static int esdhc_of_enable_dma(struct sdhci_host *host) 5337657c3a7SAlbert Herranz { 53440c67c29SJiasheng Jiang int ret; 535f4932cfdSyangbo lu u32 value; 5365552d7adSLaurentiu Tudor struct device *dev = mmc_dev(host->mmc); 5375552d7adSLaurentiu Tudor 5385552d7adSLaurentiu Tudor if (of_device_is_compatible(dev->of_node, "fsl,ls1043a-esdhc") || 53940c67c29SJiasheng Jiang of_device_is_compatible(dev->of_node, "fsl,ls1046a-esdhc")) { 54040c67c29SJiasheng Jiang ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(40)); 54140c67c29SJiasheng Jiang if (ret) 54240c67c29SJiasheng Jiang return ret; 54340c67c29SJiasheng Jiang } 544f4932cfdSyangbo lu 545f4932cfdSyangbo lu value = sdhci_readl(host, ESDHC_DMA_SYSCTL); 546121bd08bSRussell King 547121bd08bSRussell King if (of_dma_is_coherent(dev->of_node)) 548f4932cfdSyangbo lu value |= ESDHC_DMA_SNOOP; 549121bd08bSRussell King else 550121bd08bSRussell King value &= ~ESDHC_DMA_SNOOP; 551121bd08bSRussell King 552f4932cfdSyangbo lu sdhci_writel(host, value, ESDHC_DMA_SYSCTL); 5537657c3a7SAlbert Herranz return 0; 5547657c3a7SAlbert Herranz } 5557657c3a7SAlbert Herranz 55680872e21SWolfram Sang static unsigned int esdhc_of_get_max_clock(struct sdhci_host *host) 5577657c3a7SAlbert Herranz { 558e307148fSShawn Guo struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); 55919c3a0efSyangbo lu struct sdhci_esdhc *esdhc = sdhci_pltfm_priv(pltfm_host); 5607657c3a7SAlbert Herranz 56119c3a0efSyangbo lu if (esdhc->peripheral_clock) 56219c3a0efSyangbo lu return esdhc->peripheral_clock; 56319c3a0efSyangbo lu else 564e307148fSShawn Guo return pltfm_host->clock; 5657657c3a7SAlbert Herranz } 5667657c3a7SAlbert Herranz 56780872e21SWolfram Sang static unsigned int esdhc_of_get_min_clock(struct sdhci_host *host) 5687657c3a7SAlbert Herranz { 569e307148fSShawn Guo struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); 57019c3a0efSyangbo lu struct sdhci_esdhc *esdhc = sdhci_pltfm_priv(pltfm_host); 57119c3a0efSyangbo lu unsigned int clock; 5727657c3a7SAlbert Herranz 57319c3a0efSyangbo lu if (esdhc->peripheral_clock) 57419c3a0efSyangbo lu clock = esdhc->peripheral_clock; 57519c3a0efSyangbo lu else 57619c3a0efSyangbo lu clock = pltfm_host->clock; 57719c3a0efSyangbo lu return clock / 256 / 16; 5787657c3a7SAlbert Herranz } 5797657c3a7SAlbert Herranz 580dd3f6983Syangbo lu static void esdhc_clock_enable(struct sdhci_host *host, bool enable) 581dd3f6983Syangbo lu { 5821b21a701SYangbo Lu struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); 5831b21a701SYangbo Lu struct sdhci_esdhc *esdhc = sdhci_pltfm_priv(pltfm_host); 584dd3f6983Syangbo lu ktime_t timeout; 5851b21a701SYangbo Lu u32 val, clk_en; 5861b21a701SYangbo Lu 5871b21a701SYangbo Lu clk_en = ESDHC_CLOCK_SDCLKEN; 5881b21a701SYangbo Lu 5891b21a701SYangbo Lu /* 5901b21a701SYangbo Lu * IPGEN/HCKEN/PEREN bits exist on eSDHC whose vendor version 5911b21a701SYangbo Lu * is 2.2 or lower. 5921b21a701SYangbo Lu */ 5931b21a701SYangbo Lu if (esdhc->vendor_ver <= VENDOR_V_22) 5941b21a701SYangbo Lu clk_en |= (ESDHC_CLOCK_IPGEN | ESDHC_CLOCK_HCKEN | 5951b21a701SYangbo Lu ESDHC_CLOCK_PEREN); 596dd3f6983Syangbo lu 597dd3f6983Syangbo lu val = sdhci_readl(host, ESDHC_SYSTEM_CONTROL); 598dd3f6983Syangbo lu 599dd3f6983Syangbo lu if (enable) 6001b21a701SYangbo Lu val |= clk_en; 601dd3f6983Syangbo lu else 6021b21a701SYangbo Lu val &= ~clk_en; 603dd3f6983Syangbo lu 604dd3f6983Syangbo lu sdhci_writel(host, val, ESDHC_SYSTEM_CONTROL); 605dd3f6983Syangbo lu 6061b21a701SYangbo Lu /* 6071b21a701SYangbo Lu * Wait max 20 ms. If vendor version is 2.2 or lower, do not 6081b21a701SYangbo Lu * wait clock stable bit which does not exist. 6091b21a701SYangbo Lu */ 610dd3f6983Syangbo lu timeout = ktime_add_ms(ktime_get(), 20); 6111b21a701SYangbo Lu while (esdhc->vendor_ver > VENDOR_V_22) { 612ea6d0273SAdrian Hunter bool timedout = ktime_after(ktime_get(), timeout); 613ea6d0273SAdrian Hunter 6141b21a701SYangbo Lu if (sdhci_readl(host, ESDHC_PRSSTAT) & ESDHC_CLOCK_STABLE) 615ea6d0273SAdrian Hunter break; 616ea6d0273SAdrian Hunter if (timedout) { 617dd3f6983Syangbo lu pr_err("%s: Internal clock never stabilised.\n", 618dd3f6983Syangbo lu mmc_hostname(host->mmc)); 619dd3f6983Syangbo lu break; 620dd3f6983Syangbo lu } 6211b21a701SYangbo Lu usleep_range(10, 20); 622dd3f6983Syangbo lu } 623dd3f6983Syangbo lu } 624dd3f6983Syangbo lu 6256e32f65cSYangbo Lu static void esdhc_flush_async_fifo(struct sdhci_host *host) 6266e32f65cSYangbo Lu { 6276e32f65cSYangbo Lu ktime_t timeout; 6286e32f65cSYangbo Lu u32 val; 6296e32f65cSYangbo Lu 6306e32f65cSYangbo Lu val = sdhci_readl(host, ESDHC_DMA_SYSCTL); 6316e32f65cSYangbo Lu val |= ESDHC_FLUSH_ASYNC_FIFO; 6326e32f65cSYangbo Lu sdhci_writel(host, val, ESDHC_DMA_SYSCTL); 6336e32f65cSYangbo Lu 6346e32f65cSYangbo Lu /* Wait max 20 ms */ 6356e32f65cSYangbo Lu timeout = ktime_add_ms(ktime_get(), 20); 6366e32f65cSYangbo Lu while (1) { 6376e32f65cSYangbo Lu bool timedout = ktime_after(ktime_get(), timeout); 6386e32f65cSYangbo Lu 6396e32f65cSYangbo Lu if (!(sdhci_readl(host, ESDHC_DMA_SYSCTL) & 6406e32f65cSYangbo Lu ESDHC_FLUSH_ASYNC_FIFO)) 6416e32f65cSYangbo Lu break; 6426e32f65cSYangbo Lu if (timedout) { 6436e32f65cSYangbo Lu pr_err("%s: flushing asynchronous FIFO timeout.\n", 6446e32f65cSYangbo Lu mmc_hostname(host->mmc)); 6456e32f65cSYangbo Lu break; 6466e32f65cSYangbo Lu } 6476e32f65cSYangbo Lu usleep_range(10, 20); 6486e32f65cSYangbo Lu } 6496e32f65cSYangbo Lu } 6506e32f65cSYangbo Lu 651f060bc9cSJerry Huang static void esdhc_of_set_clock(struct sdhci_host *host, unsigned int clock) 652f060bc9cSJerry Huang { 653f4932cfdSyangbo lu struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); 6548605e7aeSJisheng Zhang struct sdhci_esdhc *esdhc = sdhci_pltfm_priv(pltfm_host); 6551b21a701SYangbo Lu unsigned int pre_div = 1, div = 1; 6561b21a701SYangbo Lu unsigned int clock_fixup = 0; 657e145ac45Syangbo lu ktime_t timeout; 658d31fc00aSDong Aisheng u32 temp; 659d31fc00aSDong Aisheng 660dd3f6983Syangbo lu if (clock == 0) { 6611b21a701SYangbo Lu host->mmc->actual_clock = 0; 662dd3f6983Syangbo lu esdhc_clock_enable(host, false); 663373073efSRussell King return; 664dd3f6983Syangbo lu } 665d31fc00aSDong Aisheng 6661b21a701SYangbo Lu /* Start pre_div at 2 for vendor version < 2.3. */ 667f4932cfdSyangbo lu if (esdhc->vendor_ver < VENDOR_V_23) 66877bd2f6fSYangbo Lu pre_div = 2; 66977bd2f6fSYangbo Lu 6701b21a701SYangbo Lu /* Fix clock value. */ 67167fdfbdfSyinbo.zhu if (host->mmc->card && mmc_card_sd(host->mmc->card) && 67267fdfbdfSyinbo.zhu esdhc->clk_fixup && host->mmc->ios.timing == MMC_TIMING_LEGACY) 6731b21a701SYangbo Lu clock_fixup = esdhc->clk_fixup->sd_dflt_max_clk; 67467fdfbdfSyinbo.zhu else if (esdhc->clk_fixup) 6751b21a701SYangbo Lu clock_fixup = esdhc->clk_fixup->max_clk[host->mmc->ios.timing]; 676a627f025Syangbo lu 6771b21a701SYangbo Lu if (clock_fixup == 0 || clock < clock_fixup) 6781b21a701SYangbo Lu clock_fixup = clock; 679f060bc9cSJerry Huang 6801b21a701SYangbo Lu /* Calculate pre_div and div. */ 6811b21a701SYangbo Lu while (host->max_clk / pre_div / 16 > clock_fixup && pre_div < 256) 682d31fc00aSDong Aisheng pre_div *= 2; 683d31fc00aSDong Aisheng 6841b21a701SYangbo Lu while (host->max_clk / pre_div / div > clock_fixup && div < 16) 685d31fc00aSDong Aisheng div++; 686d31fc00aSDong Aisheng 6871b21a701SYangbo Lu esdhc->div_ratio = pre_div * div; 6881b21a701SYangbo Lu 6891b21a701SYangbo Lu /* Limit clock division for HS400 200MHz clock for quirk. */ 6906079e63cSYangbo Lu if (esdhc->quirk_limited_clk_division && 6916079e63cSYangbo Lu clock == MMC_HS200_MAX_DTR && 6926079e63cSYangbo Lu (host->mmc->ios.timing == MMC_TIMING_MMC_HS400 || 6936079e63cSYangbo Lu host->flags & SDHCI_HS400_TUNING)) { 6941b21a701SYangbo Lu if (esdhc->div_ratio <= 4) { 6956079e63cSYangbo Lu pre_div = 4; 6966079e63cSYangbo Lu div = 1; 6971b21a701SYangbo Lu } else if (esdhc->div_ratio <= 8) { 6986079e63cSYangbo Lu pre_div = 4; 6996079e63cSYangbo Lu div = 2; 7001b21a701SYangbo Lu } else if (esdhc->div_ratio <= 12) { 7016079e63cSYangbo Lu pre_div = 4; 7026079e63cSYangbo Lu div = 3; 7036079e63cSYangbo Lu } else { 704b11c36d5SColin Ian King pr_warn("%s: using unsupported clock division.\n", 7056079e63cSYangbo Lu mmc_hostname(host->mmc)); 7066079e63cSYangbo Lu } 7071b21a701SYangbo Lu esdhc->div_ratio = pre_div * div; 7086079e63cSYangbo Lu } 7096079e63cSYangbo Lu 7101b21a701SYangbo Lu host->mmc->actual_clock = host->max_clk / esdhc->div_ratio; 7111b21a701SYangbo Lu 712d31fc00aSDong Aisheng dev_dbg(mmc_dev(host->mmc), "desired SD clock: %d, actual: %d\n", 7131b21a701SYangbo Lu clock, host->mmc->actual_clock); 7141b21a701SYangbo Lu 7151b21a701SYangbo Lu /* Set clock division into register. */ 716d31fc00aSDong Aisheng pre_div >>= 1; 717d31fc00aSDong Aisheng div--; 718d31fc00aSDong Aisheng 7191b21a701SYangbo Lu esdhc_clock_enable(host, false); 7201b21a701SYangbo Lu 721d31fc00aSDong Aisheng temp = sdhci_readl(host, ESDHC_SYSTEM_CONTROL); 7221b21a701SYangbo Lu temp &= ~ESDHC_CLOCK_MASK; 7231b21a701SYangbo Lu temp |= ((div << ESDHC_DIVIDER_SHIFT) | 7241b21a701SYangbo Lu (pre_div << ESDHC_PREDIV_SHIFT)); 725d31fc00aSDong Aisheng sdhci_writel(host, temp, ESDHC_SYSTEM_CONTROL); 726e87d2db2Syangbo lu 7271b21a701SYangbo Lu /* 7281b21a701SYangbo Lu * Wait max 20 ms. If vendor version is 2.2 or lower, do not 7291b21a701SYangbo Lu * wait clock stable bit which does not exist. 7301b21a701SYangbo Lu */ 7311b21a701SYangbo Lu timeout = ktime_add_ms(ktime_get(), 20); 7321b21a701SYangbo Lu while (esdhc->vendor_ver > VENDOR_V_22) { 7331b21a701SYangbo Lu bool timedout = ktime_after(ktime_get(), timeout); 7341b21a701SYangbo Lu 7351b21a701SYangbo Lu if (sdhci_readl(host, ESDHC_PRSSTAT) & ESDHC_CLOCK_STABLE) 7361b21a701SYangbo Lu break; 7371b21a701SYangbo Lu if (timedout) { 7381b21a701SYangbo Lu pr_err("%s: Internal clock never stabilised.\n", 7391b21a701SYangbo Lu mmc_hostname(host->mmc)); 7401b21a701SYangbo Lu break; 7411b21a701SYangbo Lu } 7421b21a701SYangbo Lu usleep_range(10, 20); 7431b21a701SYangbo Lu } 7441b21a701SYangbo Lu 7451b21a701SYangbo Lu /* Additional setting for HS400. */ 74654e08d9aSYangbo Lu if (host->mmc->ios.timing == MMC_TIMING_MMC_HS400 && 74754e08d9aSYangbo Lu clock == MMC_HS200_MAX_DTR) { 74854e08d9aSYangbo Lu temp = sdhci_readl(host, ESDHC_TBCTL); 74954e08d9aSYangbo Lu sdhci_writel(host, temp | ESDHC_HS400_MODE, ESDHC_TBCTL); 75054e08d9aSYangbo Lu temp = sdhci_readl(host, ESDHC_SDCLKCTL); 75154e08d9aSYangbo Lu sdhci_writel(host, temp | ESDHC_CMD_CLK_CTL, ESDHC_SDCLKCTL); 75254e08d9aSYangbo Lu esdhc_clock_enable(host, true); 75354e08d9aSYangbo Lu 75454e08d9aSYangbo Lu temp = sdhci_readl(host, ESDHC_DLLCFG0); 75558d0bf84SYangbo Lu temp |= ESDHC_DLL_ENABLE; 75658d0bf84SYangbo Lu if (host->mmc->actual_clock == MMC_HS200_MAX_DTR) 75758d0bf84SYangbo Lu temp |= ESDHC_DLL_FREQ_SEL; 75854e08d9aSYangbo Lu sdhci_writel(host, temp, ESDHC_DLLCFG0); 759011fde48SYangbo Lu 760011fde48SYangbo Lu temp |= ESDHC_DLL_RESET; 761011fde48SYangbo Lu sdhci_writel(host, temp, ESDHC_DLLCFG0); 762011fde48SYangbo Lu udelay(1); 763011fde48SYangbo Lu temp &= ~ESDHC_DLL_RESET; 764011fde48SYangbo Lu sdhci_writel(host, temp, ESDHC_DLLCFG0); 765011fde48SYangbo Lu 766011fde48SYangbo Lu /* Wait max 20 ms */ 767011fde48SYangbo Lu if (read_poll_timeout(sdhci_readl, temp, 768011fde48SYangbo Lu temp & ESDHC_DLL_STS_SLV_LOCK, 769011fde48SYangbo Lu 10, 20000, false, 770011fde48SYangbo Lu host, ESDHC_DLLSTAT0)) 771011fde48SYangbo Lu pr_err("%s: timeout for delay chain lock.\n", 772011fde48SYangbo Lu mmc_hostname(host->mmc)); 773011fde48SYangbo Lu 77454e08d9aSYangbo Lu temp = sdhci_readl(host, ESDHC_TBCTL); 77554e08d9aSYangbo Lu sdhci_writel(host, temp | ESDHC_HS400_WNDW_ADJUST, ESDHC_TBCTL); 77654e08d9aSYangbo Lu 77754e08d9aSYangbo Lu esdhc_clock_enable(host, false); 7786e32f65cSYangbo Lu esdhc_flush_async_fifo(host); 77954e08d9aSYangbo Lu } 78080c74823SYangbo Lu esdhc_clock_enable(host, true); 781e87d2db2Syangbo lu } 782e87d2db2Syangbo lu 7832317f56cSRussell King static void esdhc_pltfm_set_bus_width(struct sdhci_host *host, int width) 78466b50a00SOded Gabbay { 78566b50a00SOded Gabbay u32 ctrl; 78666b50a00SOded Gabbay 787f4932cfdSyangbo lu ctrl = sdhci_readl(host, ESDHC_PROCTL); 788f4932cfdSyangbo lu ctrl &= (~ESDHC_CTRL_BUSWIDTH_MASK); 78966b50a00SOded Gabbay switch (width) { 79066b50a00SOded Gabbay case MMC_BUS_WIDTH_8: 791f4932cfdSyangbo lu ctrl |= ESDHC_CTRL_8BITBUS; 79266b50a00SOded Gabbay break; 79366b50a00SOded Gabbay 79466b50a00SOded Gabbay case MMC_BUS_WIDTH_4: 795f4932cfdSyangbo lu ctrl |= ESDHC_CTRL_4BITBUS; 79666b50a00SOded Gabbay break; 79766b50a00SOded Gabbay 79866b50a00SOded Gabbay default: 79966b50a00SOded Gabbay break; 80066b50a00SOded Gabbay } 80166b50a00SOded Gabbay 802f4932cfdSyangbo lu sdhci_writel(host, ctrl, ESDHC_PROCTL); 80366b50a00SOded Gabbay } 80466b50a00SOded Gabbay 805304f0a98SAlessio Igor Bogani static void esdhc_reset(struct sdhci_host *host, u8 mask) 806304f0a98SAlessio Igor Bogani { 80748e304ccSYangbo Lu struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); 80848e304ccSYangbo Lu struct sdhci_esdhc *esdhc = sdhci_pltfm_priv(pltfm_host); 8092aa3d826SYangbo Lu u32 val, bus_width = 0; 810f2bc6000Syinbo.zhu 8112aa3d826SYangbo Lu /* 8122aa3d826SYangbo Lu * Add delay to make sure all the DMA transfers are finished 8132aa3d826SYangbo Lu * for quirk. 8142aa3d826SYangbo Lu */ 815f667216cSYangbo Lu if (esdhc->quirk_delay_before_data_reset && 816f667216cSYangbo Lu (mask & SDHCI_RESET_DATA) && 817f667216cSYangbo Lu (host->flags & SDHCI_REQ_USE_DMA)) 818f667216cSYangbo Lu mdelay(5); 819f667216cSYangbo Lu 8202aa3d826SYangbo Lu /* 8212aa3d826SYangbo Lu * Save bus-width for eSDHC whose vendor version is 2.2 8222aa3d826SYangbo Lu * or lower for data reset. 8232aa3d826SYangbo Lu */ 8242aa3d826SYangbo Lu if ((mask & SDHCI_RESET_DATA) && 8252aa3d826SYangbo Lu (esdhc->vendor_ver <= VENDOR_V_22)) { 8262aa3d826SYangbo Lu val = sdhci_readl(host, ESDHC_PROCTL); 8272aa3d826SYangbo Lu bus_width = val & ESDHC_CTRL_BUSWIDTH_MASK; 8282aa3d826SYangbo Lu } 8292aa3d826SYangbo Lu 830304f0a98SAlessio Igor Bogani sdhci_reset(host, mask); 831304f0a98SAlessio Igor Bogani 8322aa3d826SYangbo Lu /* 8332aa3d826SYangbo Lu * Restore bus-width setting and interrupt registers for eSDHC 8342aa3d826SYangbo Lu * whose vendor version is 2.2 or lower for data reset. 8352aa3d826SYangbo Lu */ 8362aa3d826SYangbo Lu if ((mask & SDHCI_RESET_DATA) && 8372aa3d826SYangbo Lu (esdhc->vendor_ver <= VENDOR_V_22)) { 8382aa3d826SYangbo Lu val = sdhci_readl(host, ESDHC_PROCTL); 8392aa3d826SYangbo Lu val &= ~ESDHC_CTRL_BUSWIDTH_MASK; 8402aa3d826SYangbo Lu val |= bus_width; 8412aa3d826SYangbo Lu sdhci_writel(host, val, ESDHC_PROCTL); 8422aa3d826SYangbo Lu 843304f0a98SAlessio Igor Bogani sdhci_writel(host, host->ier, SDHCI_INT_ENABLE); 844304f0a98SAlessio Igor Bogani sdhci_writel(host, host->ier, SDHCI_SIGNAL_ENABLE); 8452aa3d826SYangbo Lu } 846f2bc6000Syinbo.zhu 8472aa3d826SYangbo Lu /* 8482aa3d826SYangbo Lu * Some bits have to be cleaned manually for eSDHC whose spec 8492aa3d826SYangbo Lu * version is higher than 3.0 for all reset. 8502aa3d826SYangbo Lu */ 8512aa3d826SYangbo Lu if ((mask & SDHCI_RESET_ALL) && 8522aa3d826SYangbo Lu (esdhc->spec_ver >= SDHCI_SPEC_300)) { 853f2bc6000Syinbo.zhu val = sdhci_readl(host, ESDHC_TBCTL); 854f2bc6000Syinbo.zhu val &= ~ESDHC_TB_EN; 855f2bc6000Syinbo.zhu sdhci_writel(host, val, ESDHC_TBCTL); 85648e304ccSYangbo Lu 8572aa3d826SYangbo Lu /* 8582aa3d826SYangbo Lu * Initialize eSDHC_DLLCFG1[DLL_PD_PULSE_STRETCH_SEL] to 8592aa3d826SYangbo Lu * 0 for quirk. 8602aa3d826SYangbo Lu */ 86148e304ccSYangbo Lu if (esdhc->quirk_unreliable_pulse_detection) { 86248e304ccSYangbo Lu val = sdhci_readl(host, ESDHC_DLLCFG1); 86348e304ccSYangbo Lu val &= ~ESDHC_DLL_PD_PULSE_STRETCH_SEL; 86448e304ccSYangbo Lu sdhci_writel(host, val, ESDHC_DLLCFG1); 86548e304ccSYangbo Lu } 866f2bc6000Syinbo.zhu } 867304f0a98SAlessio Igor Bogani } 868304f0a98SAlessio Igor Bogani 869ea35645aSyangbo lu /* The SCFG, Supplemental Configuration Unit, provides SoC specific 870ea35645aSyangbo lu * configuration and status registers for the device. There is a 871ea35645aSyangbo lu * SDHC IO VSEL control register on SCFG for some platforms. It's 872ea35645aSyangbo lu * used to support SDHC IO voltage switching. 873ea35645aSyangbo lu */ 874ea35645aSyangbo lu static const struct of_device_id scfg_device_ids[] = { 875ea35645aSyangbo lu { .compatible = "fsl,t1040-scfg", }, 876ea35645aSyangbo lu { .compatible = "fsl,ls1012a-scfg", }, 877ea35645aSyangbo lu { .compatible = "fsl,ls1046a-scfg", }, 878ea35645aSyangbo lu {} 879ea35645aSyangbo lu }; 880ea35645aSyangbo lu 881ea35645aSyangbo lu /* SDHC IO VSEL control register definition */ 882ea35645aSyangbo lu #define SCFG_SDHCIOVSELCR 0x408 883ea35645aSyangbo lu #define SDHCIOVSELCR_TGLEN 0x80000000 884ea35645aSyangbo lu #define SDHCIOVSELCR_VSELVAL 0x60000000 885ea35645aSyangbo lu #define SDHCIOVSELCR_SDHC_VS 0x00000001 886ea35645aSyangbo lu 887ea35645aSyangbo lu static int esdhc_signal_voltage_switch(struct mmc_host *mmc, 888ea35645aSyangbo lu struct mmc_ios *ios) 889ea35645aSyangbo lu { 890ea35645aSyangbo lu struct sdhci_host *host = mmc_priv(mmc); 891ea35645aSyangbo lu struct device_node *scfg_node; 892ea35645aSyangbo lu void __iomem *scfg_base = NULL; 893ea35645aSyangbo lu u32 sdhciovselcr; 894ea35645aSyangbo lu u32 val; 895ea35645aSyangbo lu 896ea35645aSyangbo lu /* 897ea35645aSyangbo lu * Signal Voltage Switching is only applicable for Host Controllers 898ea35645aSyangbo lu * v3.00 and above. 899ea35645aSyangbo lu */ 900ea35645aSyangbo lu if (host->version < SDHCI_SPEC_300) 901ea35645aSyangbo lu return 0; 902ea35645aSyangbo lu 903ea35645aSyangbo lu val = sdhci_readl(host, ESDHC_PROCTL); 904ea35645aSyangbo lu 905ea35645aSyangbo lu switch (ios->signal_voltage) { 906ea35645aSyangbo lu case MMC_SIGNAL_VOLTAGE_330: 907ea35645aSyangbo lu val &= ~ESDHC_VOLT_SEL; 908ea35645aSyangbo lu sdhci_writel(host, val, ESDHC_PROCTL); 909ea35645aSyangbo lu return 0; 910ea35645aSyangbo lu case MMC_SIGNAL_VOLTAGE_180: 911ea35645aSyangbo lu scfg_node = of_find_matching_node(NULL, scfg_device_ids); 912ea35645aSyangbo lu if (scfg_node) 913ea35645aSyangbo lu scfg_base = of_iomap(scfg_node, 0); 914b5899a3eSMiaoqian Lin of_node_put(scfg_node); 915ea35645aSyangbo lu if (scfg_base) { 916ea35645aSyangbo lu sdhciovselcr = SDHCIOVSELCR_TGLEN | 917ea35645aSyangbo lu SDHCIOVSELCR_VSELVAL; 918ea35645aSyangbo lu iowrite32be(sdhciovselcr, 919ea35645aSyangbo lu scfg_base + SCFG_SDHCIOVSELCR); 920ea35645aSyangbo lu 921ea35645aSyangbo lu val |= ESDHC_VOLT_SEL; 922ea35645aSyangbo lu sdhci_writel(host, val, ESDHC_PROCTL); 923ea35645aSyangbo lu mdelay(5); 924ea35645aSyangbo lu 925ea35645aSyangbo lu sdhciovselcr = SDHCIOVSELCR_TGLEN | 926ea35645aSyangbo lu SDHCIOVSELCR_SDHC_VS; 927ea35645aSyangbo lu iowrite32be(sdhciovselcr, 928ea35645aSyangbo lu scfg_base + SCFG_SDHCIOVSELCR); 929ea35645aSyangbo lu iounmap(scfg_base); 930ea35645aSyangbo lu } else { 931ea35645aSyangbo lu val |= ESDHC_VOLT_SEL; 932ea35645aSyangbo lu sdhci_writel(host, val, ESDHC_PROCTL); 933ea35645aSyangbo lu } 934ea35645aSyangbo lu return 0; 935ea35645aSyangbo lu default: 936ea35645aSyangbo lu return 0; 937ea35645aSyangbo lu } 938ea35645aSyangbo lu } 939ea35645aSyangbo lu 94022dc132dSYangbo Lu static struct soc_device_attribute soc_tuning_erratum_type1[] = { 9415b742232SYangbo Lu { .family = "QorIQ T1023", }, 9425b742232SYangbo Lu { .family = "QorIQ T1040", }, 9435b742232SYangbo Lu { .family = "QorIQ T2080", }, 9445b742232SYangbo Lu { .family = "QorIQ LS1021A", }, 9450ffd498dSGeert Uytterhoeven { /* sentinel */ } 94622dc132dSYangbo Lu }; 94722dc132dSYangbo Lu 94822dc132dSYangbo Lu static struct soc_device_attribute soc_tuning_erratum_type2[] = { 9495b742232SYangbo Lu { .family = "QorIQ LS1012A", }, 9505b742232SYangbo Lu { .family = "QorIQ LS1043A", }, 9515b742232SYangbo Lu { .family = "QorIQ LS1046A", }, 9525b742232SYangbo Lu { .family = "QorIQ LS1080A", }, 9535b742232SYangbo Lu { .family = "QorIQ LS2080A", }, 9545b742232SYangbo Lu { .family = "QorIQ LA1575A", }, 9550ffd498dSGeert Uytterhoeven { /* sentinel */ } 956b1f378abSYinbo Zhu }; 957b1f378abSYinbo Zhu 95854e08d9aSYangbo Lu static void esdhc_tuning_block_enable(struct sdhci_host *host, bool enable) 959ba49cbd0Syangbo lu { 960ba49cbd0Syangbo lu u32 val; 961ba49cbd0Syangbo lu 962ba49cbd0Syangbo lu esdhc_clock_enable(host, false); 9636e32f65cSYangbo Lu esdhc_flush_async_fifo(host); 964ba49cbd0Syangbo lu 965ba49cbd0Syangbo lu val = sdhci_readl(host, ESDHC_TBCTL); 96654e08d9aSYangbo Lu if (enable) 967ba49cbd0Syangbo lu val |= ESDHC_TB_EN; 96854e08d9aSYangbo Lu else 96954e08d9aSYangbo Lu val &= ~ESDHC_TB_EN; 970ba49cbd0Syangbo lu sdhci_writel(host, val, ESDHC_TBCTL); 971ba49cbd0Syangbo lu 97254e08d9aSYangbo Lu esdhc_clock_enable(host, true); 97354e08d9aSYangbo Lu } 97454e08d9aSYangbo Lu 975f3c20825SYangbo Lu static void esdhc_tuning_window_ptr(struct sdhci_host *host, u8 *window_start, 97622dc132dSYangbo Lu u8 *window_end) 97722dc132dSYangbo Lu { 97822dc132dSYangbo Lu u32 val; 97922dc132dSYangbo Lu 98022dc132dSYangbo Lu /* Write TBCTL[11:8]=4'h8 */ 98122dc132dSYangbo Lu val = sdhci_readl(host, ESDHC_TBCTL); 98222dc132dSYangbo Lu val &= ~(0xf << 8); 98322dc132dSYangbo Lu val |= 8 << 8; 98422dc132dSYangbo Lu sdhci_writel(host, val, ESDHC_TBCTL); 98522dc132dSYangbo Lu 98622dc132dSYangbo Lu mdelay(1); 98722dc132dSYangbo Lu 98822dc132dSYangbo Lu /* Read TBCTL[31:0] register and rewrite again */ 98922dc132dSYangbo Lu val = sdhci_readl(host, ESDHC_TBCTL); 99022dc132dSYangbo Lu sdhci_writel(host, val, ESDHC_TBCTL); 99122dc132dSYangbo Lu 99222dc132dSYangbo Lu mdelay(1); 99322dc132dSYangbo Lu 99422dc132dSYangbo Lu /* Read the TBSTAT[31:0] register twice */ 99522dc132dSYangbo Lu val = sdhci_readl(host, ESDHC_TBSTAT); 99622dc132dSYangbo Lu val = sdhci_readl(host, ESDHC_TBSTAT); 99722dc132dSYangbo Lu 998f3c20825SYangbo Lu *window_end = val & 0xff; 999f3c20825SYangbo Lu *window_start = (val >> 8) & 0xff; 1000f3c20825SYangbo Lu } 1001f3c20825SYangbo Lu 1002f3c20825SYangbo Lu static void esdhc_prepare_sw_tuning(struct sdhci_host *host, u8 *window_start, 1003f3c20825SYangbo Lu u8 *window_end) 1004f3c20825SYangbo Lu { 1005f3c20825SYangbo Lu struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); 1006f3c20825SYangbo Lu struct sdhci_esdhc *esdhc = sdhci_pltfm_priv(pltfm_host); 1007f3c20825SYangbo Lu u8 start_ptr, end_ptr; 1008f3c20825SYangbo Lu 1009f3c20825SYangbo Lu if (esdhc->quirk_tuning_erratum_type1) { 1010f3c20825SYangbo Lu *window_start = 5 * esdhc->div_ratio; 1011f3c20825SYangbo Lu *window_end = 3 * esdhc->div_ratio; 1012f3c20825SYangbo Lu return; 1013f3c20825SYangbo Lu } 1014f3c20825SYangbo Lu 1015f3c20825SYangbo Lu esdhc_tuning_window_ptr(host, &start_ptr, &end_ptr); 1016f3c20825SYangbo Lu 101722dc132dSYangbo Lu /* Reset data lines by setting ESDHCCTL[RSTD] */ 101822dc132dSYangbo Lu sdhci_reset(host, SDHCI_RESET_DATA); 101922dc132dSYangbo Lu /* Write 32'hFFFF_FFFF to IRQSTAT register */ 102022dc132dSYangbo Lu sdhci_writel(host, 0xFFFFFFFF, SDHCI_INT_STATUS); 102122dc132dSYangbo Lu 10225b742232SYangbo Lu /* If TBSTAT[15:8]-TBSTAT[7:0] > (4 * div_ratio) + 2 10235b742232SYangbo Lu * or TBSTAT[7:0]-TBSTAT[15:8] > (4 * div_ratio) + 2, 102422dc132dSYangbo Lu * then program TBPTR[TB_WNDW_END_PTR] = 4 * div_ratio 102522dc132dSYangbo Lu * and program TBPTR[TB_WNDW_START_PTR] = 8 * div_ratio. 102622dc132dSYangbo Lu */ 102722dc132dSYangbo Lu 10285b742232SYangbo Lu if (abs(start_ptr - end_ptr) > (4 * esdhc->div_ratio + 2)) { 102922dc132dSYangbo Lu *window_start = 8 * esdhc->div_ratio; 103022dc132dSYangbo Lu *window_end = 4 * esdhc->div_ratio; 103122dc132dSYangbo Lu } else { 103222dc132dSYangbo Lu *window_start = 5 * esdhc->div_ratio; 103322dc132dSYangbo Lu *window_end = 3 * esdhc->div_ratio; 103422dc132dSYangbo Lu } 103522dc132dSYangbo Lu } 103622dc132dSYangbo Lu 103722dc132dSYangbo Lu static int esdhc_execute_sw_tuning(struct mmc_host *mmc, u32 opcode, 103822dc132dSYangbo Lu u8 window_start, u8 window_end) 103922dc132dSYangbo Lu { 104022dc132dSYangbo Lu struct sdhci_host *host = mmc_priv(mmc); 104122dc132dSYangbo Lu struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); 104222dc132dSYangbo Lu struct sdhci_esdhc *esdhc = sdhci_pltfm_priv(pltfm_host); 104322dc132dSYangbo Lu u32 val; 104422dc132dSYangbo Lu int ret; 104522dc132dSYangbo Lu 104622dc132dSYangbo Lu /* Program TBPTR[TB_WNDW_END_PTR] and TBPTR[TB_WNDW_START_PTR] */ 104722dc132dSYangbo Lu val = ((u32)window_start << ESDHC_WNDW_STRT_PTR_SHIFT) & 104822dc132dSYangbo Lu ESDHC_WNDW_STRT_PTR_MASK; 104922dc132dSYangbo Lu val |= window_end & ESDHC_WNDW_END_PTR_MASK; 105022dc132dSYangbo Lu sdhci_writel(host, val, ESDHC_TBPTR); 105122dc132dSYangbo Lu 105222dc132dSYangbo Lu /* Program the software tuning mode by setting TBCTL[TB_MODE]=2'h3 */ 105322dc132dSYangbo Lu val = sdhci_readl(host, ESDHC_TBCTL); 105422dc132dSYangbo Lu val &= ~ESDHC_TB_MODE_MASK; 105522dc132dSYangbo Lu val |= ESDHC_TB_MODE_SW; 105622dc132dSYangbo Lu sdhci_writel(host, val, ESDHC_TBCTL); 105722dc132dSYangbo Lu 105822dc132dSYangbo Lu esdhc->in_sw_tuning = true; 105922dc132dSYangbo Lu ret = sdhci_execute_tuning(mmc, opcode); 106022dc132dSYangbo Lu esdhc->in_sw_tuning = false; 106122dc132dSYangbo Lu return ret; 106222dc132dSYangbo Lu } 106322dc132dSYangbo Lu 106454e08d9aSYangbo Lu static int esdhc_execute_tuning(struct mmc_host *mmc, u32 opcode) 106554e08d9aSYangbo Lu { 106654e08d9aSYangbo Lu struct sdhci_host *host = mmc_priv(mmc); 106754e08d9aSYangbo Lu struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); 106854e08d9aSYangbo Lu struct sdhci_esdhc *esdhc = sdhci_pltfm_priv(pltfm_host); 106922dc132dSYangbo Lu u8 window_start, window_end; 107022dc132dSYangbo Lu int ret, retries = 1; 107154e08d9aSYangbo Lu bool hs400_tuning; 107204509d77SYangbo Lu unsigned int clk; 107354e08d9aSYangbo Lu u32 val; 107454e08d9aSYangbo Lu 107504509d77SYangbo Lu /* For tuning mode, the sd clock divisor value 107604509d77SYangbo Lu * must be larger than 3 according to reference manual. 107704509d77SYangbo Lu */ 107804509d77SYangbo Lu clk = esdhc->peripheral_clock / 3; 107904509d77SYangbo Lu if (host->clock > clk) 108004509d77SYangbo Lu esdhc_of_set_clock(host, clk); 108104509d77SYangbo Lu 108254e08d9aSYangbo Lu esdhc_tuning_block_enable(host, true); 108354e08d9aSYangbo Lu 10840add6e9bSMichael Walle /* 10850add6e9bSMichael Walle * The eSDHC controller takes the data timeout value into account 10860add6e9bSMichael Walle * during tuning. If the SD card is too slow sending the response, the 10870add6e9bSMichael Walle * timer will expire and a "Buffer Read Ready" interrupt without data 10880add6e9bSMichael Walle * is triggered. This leads to tuning errors. 10890add6e9bSMichael Walle * 10900add6e9bSMichael Walle * Just set the timeout to the maximum value because the core will 10910add6e9bSMichael Walle * already take care of it in sdhci_send_tuning(). 10920add6e9bSMichael Walle */ 10930add6e9bSMichael Walle sdhci_writeb(host, 0xe, SDHCI_TIMEOUT_CONTROL); 10940add6e9bSMichael Walle 109554e08d9aSYangbo Lu hs400_tuning = host->flags & SDHCI_HS400_TUNING; 109654e08d9aSYangbo Lu 109722dc132dSYangbo Lu do { 109822dc132dSYangbo Lu if (esdhc->quirk_limited_clk_division && 109922dc132dSYangbo Lu hs400_tuning) 110022dc132dSYangbo Lu esdhc_of_set_clock(host, host->clock); 110122dc132dSYangbo Lu 110222dc132dSYangbo Lu /* Do HW tuning */ 110322dc132dSYangbo Lu val = sdhci_readl(host, ESDHC_TBCTL); 110422dc132dSYangbo Lu val &= ~ESDHC_TB_MODE_MASK; 110522dc132dSYangbo Lu val |= ESDHC_TB_MODE_3; 110622dc132dSYangbo Lu sdhci_writel(host, val, ESDHC_TBCTL); 110722dc132dSYangbo Lu 110822dc132dSYangbo Lu ret = sdhci_execute_tuning(mmc, opcode); 110922dc132dSYangbo Lu if (ret) 111022dc132dSYangbo Lu break; 111122dc132dSYangbo Lu 11125b742232SYangbo Lu /* For type2 affected platforms of the tuning erratum, 11135b742232SYangbo Lu * tuning may succeed although eSDHC might not have 11145b742232SYangbo Lu * tuned properly. Need to check tuning window. 11155b742232SYangbo Lu */ 11165b742232SYangbo Lu if (esdhc->quirk_tuning_erratum_type2 && 11175b742232SYangbo Lu !host->tuning_err) { 11185b742232SYangbo Lu esdhc_tuning_window_ptr(host, &window_start, 11195b742232SYangbo Lu &window_end); 11205b742232SYangbo Lu if (abs(window_start - window_end) > 11215b742232SYangbo Lu (4 * esdhc->div_ratio + 2)) 11225b742232SYangbo Lu host->tuning_err = -EAGAIN; 11235b742232SYangbo Lu } 11245b742232SYangbo Lu 112522dc132dSYangbo Lu /* If HW tuning fails and triggers erratum, 112622dc132dSYangbo Lu * try workaround. 112722dc132dSYangbo Lu */ 112822dc132dSYangbo Lu ret = host->tuning_err; 112922dc132dSYangbo Lu if (ret == -EAGAIN && 113022dc132dSYangbo Lu (esdhc->quirk_tuning_erratum_type1 || 113122dc132dSYangbo Lu esdhc->quirk_tuning_erratum_type2)) { 113222dc132dSYangbo Lu /* Recover HS400 tuning flag */ 113322dc132dSYangbo Lu if (hs400_tuning) 113422dc132dSYangbo Lu host->flags |= SDHCI_HS400_TUNING; 113522dc132dSYangbo Lu pr_info("%s: Hold on to use fixed sampling clock. Try SW tuning!\n", 113622dc132dSYangbo Lu mmc_hostname(mmc)); 113722dc132dSYangbo Lu /* Do SW tuning */ 113822dc132dSYangbo Lu esdhc_prepare_sw_tuning(host, &window_start, 113922dc132dSYangbo Lu &window_end); 114022dc132dSYangbo Lu ret = esdhc_execute_sw_tuning(mmc, opcode, 114122dc132dSYangbo Lu window_start, 114222dc132dSYangbo Lu window_end); 114322dc132dSYangbo Lu if (ret) 114422dc132dSYangbo Lu break; 114522dc132dSYangbo Lu 114622dc132dSYangbo Lu /* Retry both HW/SW tuning with reduced clock. */ 114722dc132dSYangbo Lu ret = host->tuning_err; 114822dc132dSYangbo Lu if (ret == -EAGAIN && retries) { 114922dc132dSYangbo Lu /* Recover HS400 tuning flag */ 115022dc132dSYangbo Lu if (hs400_tuning) 115122dc132dSYangbo Lu host->flags |= SDHCI_HS400_TUNING; 115222dc132dSYangbo Lu 115322dc132dSYangbo Lu clk = host->max_clk / (esdhc->div_ratio + 1); 115422dc132dSYangbo Lu esdhc_of_set_clock(host, clk); 115522dc132dSYangbo Lu pr_info("%s: Hold on to use fixed sampling clock. Try tuning with reduced clock!\n", 115622dc132dSYangbo Lu mmc_hostname(mmc)); 115722dc132dSYangbo Lu } else { 115822dc132dSYangbo Lu break; 115922dc132dSYangbo Lu } 116022dc132dSYangbo Lu } else { 116122dc132dSYangbo Lu break; 116222dc132dSYangbo Lu } 116322dc132dSYangbo Lu } while (retries--); 116422dc132dSYangbo Lu 116522dc132dSYangbo Lu if (ret) { 116622dc132dSYangbo Lu esdhc_tuning_block_enable(host, false); 116722dc132dSYangbo Lu } else if (hs400_tuning) { 116854e08d9aSYangbo Lu val = sdhci_readl(host, ESDHC_SDTIMNGCTL); 116954e08d9aSYangbo Lu val |= ESDHC_FLW_CTL_BG; 117054e08d9aSYangbo Lu sdhci_writel(host, val, ESDHC_SDTIMNGCTL); 117154e08d9aSYangbo Lu } 117254e08d9aSYangbo Lu 117354e08d9aSYangbo Lu return ret; 117454e08d9aSYangbo Lu } 117554e08d9aSYangbo Lu 117654e08d9aSYangbo Lu static void esdhc_set_uhs_signaling(struct sdhci_host *host, 117754e08d9aSYangbo Lu unsigned int timing) 117854e08d9aSYangbo Lu { 117947e9e107SYangbo Lu u32 val; 118047e9e107SYangbo Lu 118147e9e107SYangbo Lu /* 118247e9e107SYangbo Lu * There are specific registers setting for HS400 mode. 118347e9e107SYangbo Lu * Clean all of them if controller is in HS400 mode to 118447e9e107SYangbo Lu * exit HS400 mode before re-setting any speed mode. 118547e9e107SYangbo Lu */ 118647e9e107SYangbo Lu val = sdhci_readl(host, ESDHC_TBCTL); 118747e9e107SYangbo Lu if (val & ESDHC_HS400_MODE) { 118847e9e107SYangbo Lu val = sdhci_readl(host, ESDHC_SDTIMNGCTL); 118947e9e107SYangbo Lu val &= ~ESDHC_FLW_CTL_BG; 119047e9e107SYangbo Lu sdhci_writel(host, val, ESDHC_SDTIMNGCTL); 119147e9e107SYangbo Lu 119247e9e107SYangbo Lu val = sdhci_readl(host, ESDHC_SDCLKCTL); 119347e9e107SYangbo Lu val &= ~ESDHC_CMD_CLK_CTL; 119447e9e107SYangbo Lu sdhci_writel(host, val, ESDHC_SDCLKCTL); 119547e9e107SYangbo Lu 119647e9e107SYangbo Lu esdhc_clock_enable(host, false); 119747e9e107SYangbo Lu val = sdhci_readl(host, ESDHC_TBCTL); 119847e9e107SYangbo Lu val &= ~ESDHC_HS400_MODE; 119947e9e107SYangbo Lu sdhci_writel(host, val, ESDHC_TBCTL); 120047e9e107SYangbo Lu esdhc_clock_enable(host, true); 120147e9e107SYangbo Lu 120247e9e107SYangbo Lu val = sdhci_readl(host, ESDHC_DLLCFG0); 120347e9e107SYangbo Lu val &= ~(ESDHC_DLL_ENABLE | ESDHC_DLL_FREQ_SEL); 120447e9e107SYangbo Lu sdhci_writel(host, val, ESDHC_DLLCFG0); 120547e9e107SYangbo Lu 120647e9e107SYangbo Lu val = sdhci_readl(host, ESDHC_TBCTL); 120747e9e107SYangbo Lu val &= ~ESDHC_HS400_WNDW_ADJUST; 120847e9e107SYangbo Lu sdhci_writel(host, val, ESDHC_TBCTL); 120947e9e107SYangbo Lu 121047e9e107SYangbo Lu esdhc_tuning_block_enable(host, false); 121147e9e107SYangbo Lu } 121247e9e107SYangbo Lu 121354e08d9aSYangbo Lu if (timing == MMC_TIMING_MMC_HS400) 121454e08d9aSYangbo Lu esdhc_tuning_block_enable(host, true); 121554e08d9aSYangbo Lu else 121654e08d9aSYangbo Lu sdhci_set_uhs_signaling(host, timing); 1217ba49cbd0Syangbo lu } 1218ba49cbd0Syangbo lu 1219b214fe59SYinbo Zhu static u32 esdhc_irq(struct sdhci_host *host, u32 intmask) 1220b214fe59SYinbo Zhu { 1221060522d8SChris Packham struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); 1222060522d8SChris Packham struct sdhci_esdhc *esdhc = sdhci_pltfm_priv(pltfm_host); 1223b214fe59SYinbo Zhu u32 command; 1224b214fe59SYinbo Zhu 1225060522d8SChris Packham if (esdhc->quirk_trans_complete_erratum) { 1226b214fe59SYinbo Zhu command = SDHCI_GET_CMD(sdhci_readw(host, 1227b214fe59SYinbo Zhu SDHCI_COMMAND)); 1228b214fe59SYinbo Zhu if (command == MMC_WRITE_MULTIPLE_BLOCK && 1229b214fe59SYinbo Zhu sdhci_readw(host, SDHCI_BLOCK_COUNT) && 1230b214fe59SYinbo Zhu intmask & SDHCI_INT_DATA_END) { 1231b214fe59SYinbo Zhu intmask &= ~SDHCI_INT_DATA_END; 1232b214fe59SYinbo Zhu sdhci_writel(host, SDHCI_INT_DATA_END, 1233b214fe59SYinbo Zhu SDHCI_INT_STATUS); 1234b214fe59SYinbo Zhu } 1235b214fe59SYinbo Zhu } 1236b214fe59SYinbo Zhu return intmask; 1237b214fe59SYinbo Zhu } 1238b214fe59SYinbo Zhu 12399e48b336SUlf Hansson #ifdef CONFIG_PM_SLEEP 1240723f7924SRussell King static u32 esdhc_proctl; 1241723f7924SRussell King static int esdhc_of_suspend(struct device *dev) 1242723f7924SRussell King { 1243723f7924SRussell King struct sdhci_host *host = dev_get_drvdata(dev); 1244723f7924SRussell King 1245f4932cfdSyangbo lu esdhc_proctl = sdhci_readl(host, SDHCI_HOST_CONTROL); 1246723f7924SRussell King 1247d38dcad4SAdrian Hunter if (host->tuning_mode != SDHCI_TUNING_MODE_3) 1248d38dcad4SAdrian Hunter mmc_retune_needed(host->mmc); 1249d38dcad4SAdrian Hunter 1250723f7924SRussell King return sdhci_suspend_host(host); 1251723f7924SRussell King } 1252723f7924SRussell King 125306732b84SUlf Hansson static int esdhc_of_resume(struct device *dev) 1254723f7924SRussell King { 1255723f7924SRussell King struct sdhci_host *host = dev_get_drvdata(dev); 1256723f7924SRussell King int ret = sdhci_resume_host(host); 1257723f7924SRussell King 1258723f7924SRussell King if (ret == 0) { 1259723f7924SRussell King /* Isn't this already done by sdhci_resume_host() ? --rmk */ 1260723f7924SRussell King esdhc_of_enable_dma(host); 1261f4932cfdSyangbo lu sdhci_writel(host, esdhc_proctl, SDHCI_HOST_CONTROL); 1262723f7924SRussell King } 1263723f7924SRussell King return ret; 1264723f7924SRussell King } 1265723f7924SRussell King #endif 1266723f7924SRussell King 12679e48b336SUlf Hansson static SIMPLE_DEV_PM_OPS(esdhc_of_dev_pm_ops, 12689e48b336SUlf Hansson esdhc_of_suspend, 12699e48b336SUlf Hansson esdhc_of_resume); 12709e48b336SUlf Hansson 1271f4932cfdSyangbo lu static const struct sdhci_ops sdhci_esdhc_be_ops = { 1272f4932cfdSyangbo lu .read_l = esdhc_be_readl, 1273f4932cfdSyangbo lu .read_w = esdhc_be_readw, 1274f4932cfdSyangbo lu .read_b = esdhc_be_readb, 1275f4932cfdSyangbo lu .write_l = esdhc_be_writel, 1276f4932cfdSyangbo lu .write_w = esdhc_be_writew, 1277f4932cfdSyangbo lu .write_b = esdhc_be_writeb, 1278f4932cfdSyangbo lu .set_clock = esdhc_of_set_clock, 1279f4932cfdSyangbo lu .enable_dma = esdhc_of_enable_dma, 1280f4932cfdSyangbo lu .get_max_clock = esdhc_of_get_max_clock, 1281f4932cfdSyangbo lu .get_min_clock = esdhc_of_get_min_clock, 1282f4932cfdSyangbo lu .adma_workaround = esdhc_of_adma_workaround, 1283f4932cfdSyangbo lu .set_bus_width = esdhc_pltfm_set_bus_width, 1284f4932cfdSyangbo lu .reset = esdhc_reset, 128554e08d9aSYangbo Lu .set_uhs_signaling = esdhc_set_uhs_signaling, 1286b214fe59SYinbo Zhu .irq = esdhc_irq, 1287f4932cfdSyangbo lu }; 1288f4932cfdSyangbo lu 1289f4932cfdSyangbo lu static const struct sdhci_ops sdhci_esdhc_le_ops = { 1290f4932cfdSyangbo lu .read_l = esdhc_le_readl, 1291f4932cfdSyangbo lu .read_w = esdhc_le_readw, 1292f4932cfdSyangbo lu .read_b = esdhc_le_readb, 1293f4932cfdSyangbo lu .write_l = esdhc_le_writel, 1294f4932cfdSyangbo lu .write_w = esdhc_le_writew, 1295f4932cfdSyangbo lu .write_b = esdhc_le_writeb, 1296f4932cfdSyangbo lu .set_clock = esdhc_of_set_clock, 1297f4932cfdSyangbo lu .enable_dma = esdhc_of_enable_dma, 1298f4932cfdSyangbo lu .get_max_clock = esdhc_of_get_max_clock, 1299f4932cfdSyangbo lu .get_min_clock = esdhc_of_get_min_clock, 1300f4932cfdSyangbo lu .adma_workaround = esdhc_of_adma_workaround, 1301f4932cfdSyangbo lu .set_bus_width = esdhc_pltfm_set_bus_width, 1302f4932cfdSyangbo lu .reset = esdhc_reset, 130354e08d9aSYangbo Lu .set_uhs_signaling = esdhc_set_uhs_signaling, 1304b214fe59SYinbo Zhu .irq = esdhc_irq, 1305f4932cfdSyangbo lu }; 1306f4932cfdSyangbo lu 1307f4932cfdSyangbo lu static const struct sdhci_pltfm_data sdhci_esdhc_be_pdata = { 1308e9acc77dSyangbo lu .quirks = ESDHC_DEFAULT_QUIRKS | 1309e9acc77dSyangbo lu #ifdef CONFIG_PPC 1310e9acc77dSyangbo lu SDHCI_QUIRK_BROKEN_CARD_DETECTION | 1311e9acc77dSyangbo lu #endif 1312e9acc77dSyangbo lu SDHCI_QUIRK_NO_CARD_NO_RESET | 1313e9acc77dSyangbo lu SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC, 1314f4932cfdSyangbo lu .ops = &sdhci_esdhc_be_ops, 13157657c3a7SAlbert Herranz }; 131638576af1SShawn Guo 1317f4932cfdSyangbo lu static const struct sdhci_pltfm_data sdhci_esdhc_le_pdata = { 1318e9acc77dSyangbo lu .quirks = ESDHC_DEFAULT_QUIRKS | 1319e9acc77dSyangbo lu SDHCI_QUIRK_NO_CARD_NO_RESET | 1320e9acc77dSyangbo lu SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC, 1321f4932cfdSyangbo lu .ops = &sdhci_esdhc_le_ops, 1322f4932cfdSyangbo lu }; 1323f4932cfdSyangbo lu 1324151ede40Syangbo lu static struct soc_device_attribute soc_incorrect_hostver[] = { 1325151ede40Syangbo lu { .family = "QorIQ T4240", .revision = "1.0", }, 1326151ede40Syangbo lu { .family = "QorIQ T4240", .revision = "2.0", }, 13270ffd498dSGeert Uytterhoeven { /* sentinel */ } 1328151ede40Syangbo lu }; 1329151ede40Syangbo lu 13306079e63cSYangbo Lu static struct soc_device_attribute soc_fixup_sdhc_clkdivs[] = { 13316079e63cSYangbo Lu { .family = "QorIQ LX2160A", .revision = "1.0", }, 13328e9a6919SYinbo Zhu { .family = "QorIQ LX2160A", .revision = "2.0", }, 13335f3ad196SYinbo Zhu { .family = "QorIQ LS1028A", .revision = "1.0", }, 13340ffd498dSGeert Uytterhoeven { /* sentinel */ } 13356079e63cSYangbo Lu }; 13366079e63cSYangbo Lu 133748e304ccSYangbo Lu static struct soc_device_attribute soc_unreliable_pulse_detection[] = { 133848e304ccSYangbo Lu { .family = "QorIQ LX2160A", .revision = "1.0", }, 133971b05327SYangbo Lu { .family = "QorIQ LX2160A", .revision = "2.0", }, 134071b05327SYangbo Lu { .family = "QorIQ LS1028A", .revision = "1.0", }, 13410ffd498dSGeert Uytterhoeven { /* sentinel */ } 134248e304ccSYangbo Lu }; 134348e304ccSYangbo Lu 1344f4932cfdSyangbo lu static void esdhc_init(struct platform_device *pdev, struct sdhci_host *host) 1345f4932cfdSyangbo lu { 134667fdfbdfSyinbo.zhu const struct of_device_id *match; 1347f4932cfdSyangbo lu struct sdhci_pltfm_host *pltfm_host; 1348f4932cfdSyangbo lu struct sdhci_esdhc *esdhc; 134919c3a0efSyangbo lu struct device_node *np; 135019c3a0efSyangbo lu struct clk *clk; 135119c3a0efSyangbo lu u32 val; 1352f4932cfdSyangbo lu u16 host_ver; 1353f4932cfdSyangbo lu 1354f4932cfdSyangbo lu pltfm_host = sdhci_priv(host); 13558605e7aeSJisheng Zhang esdhc = sdhci_pltfm_priv(pltfm_host); 1356f4932cfdSyangbo lu 1357f4932cfdSyangbo lu host_ver = sdhci_readw(host, SDHCI_HOST_VERSION); 1358f4932cfdSyangbo lu esdhc->vendor_ver = (host_ver & SDHCI_VENDOR_VER_MASK) >> 1359f4932cfdSyangbo lu SDHCI_VENDOR_VER_SHIFT; 1360f4932cfdSyangbo lu esdhc->spec_ver = host_ver & SDHCI_SPEC_VER_MASK; 1361151ede40Syangbo lu if (soc_device_match(soc_incorrect_hostver)) 1362151ede40Syangbo lu esdhc->quirk_incorrect_hostver = true; 1363151ede40Syangbo lu else 1364151ede40Syangbo lu esdhc->quirk_incorrect_hostver = false; 136519c3a0efSyangbo lu 13666079e63cSYangbo Lu if (soc_device_match(soc_fixup_sdhc_clkdivs)) 13676079e63cSYangbo Lu esdhc->quirk_limited_clk_division = true; 13686079e63cSYangbo Lu else 13696079e63cSYangbo Lu esdhc->quirk_limited_clk_division = false; 13706079e63cSYangbo Lu 137148e304ccSYangbo Lu if (soc_device_match(soc_unreliable_pulse_detection)) 137248e304ccSYangbo Lu esdhc->quirk_unreliable_pulse_detection = true; 137348e304ccSYangbo Lu else 137448e304ccSYangbo Lu esdhc->quirk_unreliable_pulse_detection = false; 137548e304ccSYangbo Lu 137667fdfbdfSyinbo.zhu match = of_match_node(sdhci_esdhc_of_match, pdev->dev.of_node); 137767fdfbdfSyinbo.zhu if (match) 137867fdfbdfSyinbo.zhu esdhc->clk_fixup = match->data; 137919c3a0efSyangbo lu np = pdev->dev.of_node; 1380f667216cSYangbo Lu 1381060522d8SChris Packham if (of_device_is_compatible(np, "fsl,p2020-esdhc")) { 1382f667216cSYangbo Lu esdhc->quirk_delay_before_data_reset = true; 1383060522d8SChris Packham esdhc->quirk_trans_complete_erratum = true; 1384060522d8SChris Packham } 1385f667216cSYangbo Lu 138619c3a0efSyangbo lu clk = of_clk_get(np, 0); 138719c3a0efSyangbo lu if (!IS_ERR(clk)) { 138819c3a0efSyangbo lu /* 138919c3a0efSyangbo lu * esdhc->peripheral_clock would be assigned with a value 139019c3a0efSyangbo lu * which is eSDHC base clock when use periperal clock. 1391791463baSYangbo Lu * For some platforms, the clock value got by common clk 1392791463baSYangbo Lu * API is peripheral clock while the eSDHC base clock is 1393791463baSYangbo Lu * 1/2 peripheral clock. 139419c3a0efSyangbo lu */ 1395791463baSYangbo Lu if (of_device_is_compatible(np, "fsl,ls1046a-esdhc") || 139666a83febSYangbo Lu of_device_is_compatible(np, "fsl,ls1028a-esdhc") || 139766a83febSYangbo Lu of_device_is_compatible(np, "fsl,ls1088a-esdhc")) 139819c3a0efSyangbo lu esdhc->peripheral_clock = clk_get_rate(clk) / 2; 139919c3a0efSyangbo lu else 140019c3a0efSyangbo lu esdhc->peripheral_clock = clk_get_rate(clk); 140119c3a0efSyangbo lu 140219c3a0efSyangbo lu clk_put(clk); 140319c3a0efSyangbo lu } 140419c3a0efSyangbo lu 140519c3a0efSyangbo lu esdhc_clock_enable(host, false); 140619c3a0efSyangbo lu val = sdhci_readl(host, ESDHC_DMA_SYSCTL); 1407975520fcSYangbo Lu /* 1408975520fcSYangbo Lu * This bit is not able to be reset by SDHCI_RESET_ALL. Need to 1409975520fcSYangbo Lu * initialize it as 1 or 0 once, to override the different value 1410975520fcSYangbo Lu * which may be configured in bootloader. 1411975520fcSYangbo Lu */ 1412975520fcSYangbo Lu if (esdhc->peripheral_clock) 141319c3a0efSyangbo lu val |= ESDHC_PERIPHERAL_CLK_SEL; 1414975520fcSYangbo Lu else 1415975520fcSYangbo Lu val &= ~ESDHC_PERIPHERAL_CLK_SEL; 141619c3a0efSyangbo lu sdhci_writel(host, val, ESDHC_DMA_SYSCTL); 141719c3a0efSyangbo lu esdhc_clock_enable(host, true); 141819c3a0efSyangbo lu } 1419f4932cfdSyangbo lu 142054e08d9aSYangbo Lu static int esdhc_hs400_prepare_ddr(struct mmc_host *mmc) 142154e08d9aSYangbo Lu { 142254e08d9aSYangbo Lu esdhc_tuning_block_enable(mmc_priv(mmc), false); 142354e08d9aSYangbo Lu return 0; 142454e08d9aSYangbo Lu } 142554e08d9aSYangbo Lu 1426c3be1efdSBill Pemberton static int sdhci_esdhc_probe(struct platform_device *pdev) 142738576af1SShawn Guo { 142866b50a00SOded Gabbay struct sdhci_host *host; 142939c86b5cSLiang He struct device_node *np, *tp; 14301ef5e49eSyangbo lu struct sdhci_pltfm_host *pltfm_host; 14311ef5e49eSyangbo lu struct sdhci_esdhc *esdhc; 143266b50a00SOded Gabbay int ret; 143366b50a00SOded Gabbay 1434f4932cfdSyangbo lu np = pdev->dev.of_node; 1435f4932cfdSyangbo lu 1436150d4240SJulia Lawall if (of_property_read_bool(np, "little-endian")) 14378605e7aeSJisheng Zhang host = sdhci_pltfm_init(pdev, &sdhci_esdhc_le_pdata, 14388605e7aeSJisheng Zhang sizeof(struct sdhci_esdhc)); 1439f4932cfdSyangbo lu else 14408605e7aeSJisheng Zhang host = sdhci_pltfm_init(pdev, &sdhci_esdhc_be_pdata, 14418605e7aeSJisheng Zhang sizeof(struct sdhci_esdhc)); 1442f4932cfdSyangbo lu 144366b50a00SOded Gabbay if (IS_ERR(host)) 144466b50a00SOded Gabbay return PTR_ERR(host); 144566b50a00SOded Gabbay 1446ea35645aSyangbo lu host->mmc_host_ops.start_signal_voltage_switch = 1447ea35645aSyangbo lu esdhc_signal_voltage_switch; 1448ba49cbd0Syangbo lu host->mmc_host_ops.execute_tuning = esdhc_execute_tuning; 144954e08d9aSYangbo Lu host->mmc_host_ops.hs400_prepare_ddr = esdhc_hs400_prepare_ddr; 14506b236f37Syangbo lu host->tuning_delay = 1; 1451ea35645aSyangbo lu 1452f4932cfdSyangbo lu esdhc_init(pdev, host); 1453f4932cfdSyangbo lu 145466b50a00SOded Gabbay sdhci_get_of_property(pdev); 145566b50a00SOded Gabbay 14561ef5e49eSyangbo lu pltfm_host = sdhci_priv(host); 14578605e7aeSJisheng Zhang esdhc = sdhci_pltfm_priv(pltfm_host); 145822dc132dSYangbo Lu if (soc_device_match(soc_tuning_erratum_type1)) 145922dc132dSYangbo Lu esdhc->quirk_tuning_erratum_type1 = true; 1460b1f378abSYinbo Zhu else 146122dc132dSYangbo Lu esdhc->quirk_tuning_erratum_type1 = false; 146222dc132dSYangbo Lu 146322dc132dSYangbo Lu if (soc_device_match(soc_tuning_erratum_type2)) 146422dc132dSYangbo Lu esdhc->quirk_tuning_erratum_type2 = true; 146522dc132dSYangbo Lu else 146622dc132dSYangbo Lu esdhc->quirk_tuning_erratum_type2 = false; 1467b1f378abSYinbo Zhu 14681ef5e49eSyangbo lu if (esdhc->vendor_ver == VENDOR_V_22) 14691ef5e49eSyangbo lu host->quirks2 |= SDHCI_QUIRK2_HOST_NO_CMD23; 14701ef5e49eSyangbo lu 14711ef5e49eSyangbo lu if (esdhc->vendor_ver > VENDOR_V_22) 14721ef5e49eSyangbo lu host->quirks &= ~SDHCI_QUIRK_NO_BUSY_IRQ; 14731ef5e49eSyangbo lu 147439c86b5cSLiang He tp = of_find_compatible_node(NULL, NULL, "fsl,p2020-esdhc"); 147539c86b5cSLiang He if (tp) { 147639c86b5cSLiang He of_node_put(tp); 1477fe0acab4SYangbo Lu host->quirks |= SDHCI_QUIRK_RESET_AFTER_REQUEST; 1478fe0acab4SYangbo Lu host->quirks |= SDHCI_QUIRK_BROKEN_TIMEOUT_VAL; 147905cb6b2aSYinbo Zhu } 1480a46e4271SYinbo Zhu 148174fd5e30SYangbo Lu if (of_device_is_compatible(np, "fsl,p5040-esdhc") || 148274fd5e30SYangbo Lu of_device_is_compatible(np, "fsl,p5020-esdhc") || 148374fd5e30SYangbo Lu of_device_is_compatible(np, "fsl,p4080-esdhc") || 148474fd5e30SYangbo Lu of_device_is_compatible(np, "fsl,p1020-esdhc") || 1485e9acc77dSyangbo lu of_device_is_compatible(np, "fsl,t1040-esdhc")) 148674fd5e30SYangbo Lu host->quirks &= ~SDHCI_QUIRK_BROKEN_CARD_DETECTION; 148774fd5e30SYangbo Lu 1488a22950c8Syangbo lu if (of_device_is_compatible(np, "fsl,ls1021a-esdhc")) 1489a22950c8Syangbo lu host->quirks |= SDHCI_QUIRK_BROKEN_TIMEOUT_VAL; 1490a22950c8Syangbo lu 14911f1929f3SYangbo Lu esdhc->quirk_ignore_data_inhibit = false; 1492dcaff04dSOded Gabbay if (of_device_is_compatible(np, "fsl,p2020-esdhc")) { 1493dcaff04dSOded Gabbay /* 1494dcaff04dSOded Gabbay * Freescale messed up with P2020 as it has a non-standard 1495dcaff04dSOded Gabbay * host control register 1496dcaff04dSOded Gabbay */ 1497dcaff04dSOded Gabbay host->quirks2 |= SDHCI_QUIRK2_BROKEN_HOST_CONTROL; 14981f1929f3SYangbo Lu esdhc->quirk_ignore_data_inhibit = true; 1499dcaff04dSOded Gabbay } 1500dcaff04dSOded Gabbay 150166b50a00SOded Gabbay /* call to generic mmc_of_parse to support additional capabilities */ 1502f0991408SUlf Hansson ret = mmc_of_parse(host->mmc); 1503f0991408SUlf Hansson if (ret) 1504f0991408SUlf Hansson goto err; 1505f0991408SUlf Hansson 15066dab809bSAndy Shevchenko mmc_of_parse_voltage(host->mmc, &host->ocr_mask); 150766b50a00SOded Gabbay 150866b50a00SOded Gabbay ret = sdhci_add_host(host); 150966b50a00SOded Gabbay if (ret) 1510f0991408SUlf Hansson goto err; 151166b50a00SOded Gabbay 1512f0991408SUlf Hansson return 0; 1513f0991408SUlf Hansson err: 1514f0991408SUlf Hansson sdhci_pltfm_free(pdev); 151566b50a00SOded Gabbay return ret; 151638576af1SShawn Guo } 151738576af1SShawn Guo 151838576af1SShawn Guo static struct platform_driver sdhci_esdhc_driver = { 151938576af1SShawn Guo .driver = { 152038576af1SShawn Guo .name = "sdhci-esdhc", 152121b2cec6SDouglas Anderson .probe_type = PROBE_PREFER_ASYNCHRONOUS, 152238576af1SShawn Guo .of_match_table = sdhci_esdhc_of_match, 15239e48b336SUlf Hansson .pm = &esdhc_of_dev_pm_ops, 152438576af1SShawn Guo }, 152538576af1SShawn Guo .probe = sdhci_esdhc_probe, 1526caebcae9SKevin Hao .remove = sdhci_pltfm_unregister, 152738576af1SShawn Guo }; 152838576af1SShawn Guo 1529d1f81a64SAxel Lin module_platform_driver(sdhci_esdhc_driver); 153038576af1SShawn Guo 153138576af1SShawn Guo MODULE_DESCRIPTION("SDHCI OF driver for Freescale MPC eSDHC"); 153238576af1SShawn Guo MODULE_AUTHOR("Xiaobo Xie <X.Xie@freescale.com>, " 153338576af1SShawn Guo "Anton Vorontsov <avorontsov@ru.mvista.com>"); 153438576af1SShawn Guo MODULE_LICENSE("GPL v2"); 1535