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 4567fdfbdfSyinbo.zhu static const struct esdhc_clk_fixup ls1046a_esdhc_clk = { 4667fdfbdfSyinbo.zhu .sd_dflt_max_clk = 25000000, 4767fdfbdfSyinbo.zhu .max_clk[MMC_TIMING_UHS_SDR104] = 167000000, 4867fdfbdfSyinbo.zhu .max_clk[MMC_TIMING_MMC_HS200] = 167000000, 4967fdfbdfSyinbo.zhu }; 5067fdfbdfSyinbo.zhu 5167fdfbdfSyinbo.zhu static const struct esdhc_clk_fixup ls1012a_esdhc_clk = { 5267fdfbdfSyinbo.zhu .sd_dflt_max_clk = 25000000, 5367fdfbdfSyinbo.zhu .max_clk[MMC_TIMING_UHS_SDR104] = 125000000, 5467fdfbdfSyinbo.zhu .max_clk[MMC_TIMING_MMC_HS200] = 125000000, 5567fdfbdfSyinbo.zhu }; 5667fdfbdfSyinbo.zhu 5767fdfbdfSyinbo.zhu static const struct esdhc_clk_fixup p1010_esdhc_clk = { 5867fdfbdfSyinbo.zhu .sd_dflt_max_clk = 20000000, 5967fdfbdfSyinbo.zhu .max_clk[MMC_TIMING_LEGACY] = 20000000, 6067fdfbdfSyinbo.zhu .max_clk[MMC_TIMING_MMC_HS] = 42000000, 6167fdfbdfSyinbo.zhu .max_clk[MMC_TIMING_SD_HS] = 40000000, 6267fdfbdfSyinbo.zhu }; 6367fdfbdfSyinbo.zhu 6467fdfbdfSyinbo.zhu static const struct of_device_id sdhci_esdhc_of_match[] = { 6567fdfbdfSyinbo.zhu { .compatible = "fsl,ls1021a-esdhc", .data = &ls1021a_esdhc_clk}, 6667fdfbdfSyinbo.zhu { .compatible = "fsl,ls1046a-esdhc", .data = &ls1046a_esdhc_clk}, 6767fdfbdfSyinbo.zhu { .compatible = "fsl,ls1012a-esdhc", .data = &ls1012a_esdhc_clk}, 6867fdfbdfSyinbo.zhu { .compatible = "fsl,p1010-esdhc", .data = &p1010_esdhc_clk}, 6967fdfbdfSyinbo.zhu { .compatible = "fsl,mpc8379-esdhc" }, 7067fdfbdfSyinbo.zhu { .compatible = "fsl,mpc8536-esdhc" }, 7167fdfbdfSyinbo.zhu { .compatible = "fsl,esdhc" }, 7267fdfbdfSyinbo.zhu { } 7367fdfbdfSyinbo.zhu }; 7467fdfbdfSyinbo.zhu MODULE_DEVICE_TABLE(of, sdhci_esdhc_of_match); 7567fdfbdfSyinbo.zhu 76f4932cfdSyangbo lu struct sdhci_esdhc { 77f4932cfdSyangbo lu u8 vendor_ver; 78f4932cfdSyangbo lu u8 spec_ver; 79151ede40Syangbo lu bool quirk_incorrect_hostver; 806079e63cSYangbo Lu bool quirk_limited_clk_division; 8148e304ccSYangbo Lu bool quirk_unreliable_pulse_detection; 8222dc132dSYangbo Lu bool quirk_tuning_erratum_type1; 8322dc132dSYangbo Lu bool quirk_tuning_erratum_type2; 841f1929f3SYangbo Lu bool quirk_ignore_data_inhibit; 85f667216cSYangbo Lu bool quirk_delay_before_data_reset; 86060522d8SChris Packham bool quirk_trans_complete_erratum; 8722dc132dSYangbo Lu bool in_sw_tuning; 8819c3a0efSyangbo lu unsigned int peripheral_clock; 8967fdfbdfSyinbo.zhu const struct esdhc_clk_fixup *clk_fixup; 90b1f378abSYinbo Zhu u32 div_ratio; 91f4932cfdSyangbo lu }; 92f4932cfdSyangbo lu 93f4932cfdSyangbo lu /** 94f4932cfdSyangbo lu * esdhc_read*_fixup - Fixup the value read from incompatible eSDHC register 95f4932cfdSyangbo lu * to make it compatible with SD spec. 96f4932cfdSyangbo lu * 97f4932cfdSyangbo lu * @host: pointer to sdhci_host 98f4932cfdSyangbo lu * @spec_reg: SD spec register address 99f4932cfdSyangbo lu * @value: 32bit eSDHC register value on spec_reg address 100f4932cfdSyangbo lu * 101f4932cfdSyangbo lu * In SD spec, there are 8/16/32/64 bits registers, while all of eSDHC 102f4932cfdSyangbo lu * registers are 32 bits. There are differences in register size, register 103f4932cfdSyangbo lu * address, register function, bit position and function between eSDHC spec 104f4932cfdSyangbo lu * and SD spec. 105f4932cfdSyangbo lu * 106f4932cfdSyangbo lu * Return a fixed up register value 107f4932cfdSyangbo lu */ 108f4932cfdSyangbo lu static u32 esdhc_readl_fixup(struct sdhci_host *host, 109f4932cfdSyangbo lu int spec_reg, u32 value) 110137ccd46SJerry Huang { 111f4932cfdSyangbo lu struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); 1128605e7aeSJisheng Zhang struct sdhci_esdhc *esdhc = sdhci_pltfm_priv(pltfm_host); 113137ccd46SJerry Huang u32 ret; 114137ccd46SJerry Huang 115137ccd46SJerry Huang /* 116137ccd46SJerry Huang * The bit of ADMA flag in eSDHC is not compatible with standard 117137ccd46SJerry Huang * SDHC register, so set fake flag SDHCI_CAN_DO_ADMA2 when ADMA is 118137ccd46SJerry Huang * supported by eSDHC. 119137ccd46SJerry Huang * And for many FSL eSDHC controller, the reset value of field 120f4932cfdSyangbo lu * SDHCI_CAN_DO_ADMA1 is 1, but some of them can't support ADMA, 121137ccd46SJerry Huang * only these vendor version is greater than 2.2/0x12 support ADMA. 122137ccd46SJerry Huang */ 123f4932cfdSyangbo lu if ((spec_reg == SDHCI_CAPABILITIES) && (value & SDHCI_CAN_DO_ADMA1)) { 124f4932cfdSyangbo lu if (esdhc->vendor_ver > VENDOR_V_22) { 125f4932cfdSyangbo lu ret = value | SDHCI_CAN_DO_ADMA2; 126f4932cfdSyangbo lu return ret; 127137ccd46SJerry Huang } 128f4932cfdSyangbo lu } 129b0921d5cSMichael Walle /* 130b0921d5cSMichael Walle * The DAT[3:0] line signal levels and the CMD line signal level are 131b0921d5cSMichael Walle * not compatible with standard SDHC register. The line signal levels 132b0921d5cSMichael Walle * DAT[7:0] are at bits 31:24 and the command line signal level is at 133b0921d5cSMichael Walle * bit 23. All other bits are the same as in the standard SDHC 134b0921d5cSMichael Walle * register. 135b0921d5cSMichael Walle */ 136b0921d5cSMichael Walle if (spec_reg == SDHCI_PRESENT_STATE) { 137b0921d5cSMichael Walle ret = value & 0x000fffff; 138b0921d5cSMichael Walle ret |= (value >> 4) & SDHCI_DATA_LVL_MASK; 139b0921d5cSMichael Walle ret |= (value << 1) & SDHCI_CMD_LVL; 140b0921d5cSMichael Walle return ret; 141b0921d5cSMichael Walle } 142b0921d5cSMichael Walle 1432f3110ccSyangbo lu /* 1442f3110ccSyangbo lu * DTS properties of mmc host are used to enable each speed mode 1452f3110ccSyangbo lu * according to soc and board capability. So clean up 1462f3110ccSyangbo lu * SDR50/SDR104/DDR50 support bits here. 1472f3110ccSyangbo lu */ 1482f3110ccSyangbo lu if (spec_reg == SDHCI_CAPABILITIES_1) { 1492f3110ccSyangbo lu ret = value & ~(SDHCI_SUPPORT_SDR50 | SDHCI_SUPPORT_SDR104 | 1502f3110ccSyangbo lu SDHCI_SUPPORT_DDR50); 1512f3110ccSyangbo lu return ret; 1522f3110ccSyangbo lu } 1532f3110ccSyangbo lu 1541f1929f3SYangbo Lu /* 1551f1929f3SYangbo Lu * Some controllers have unreliable Data Line Active 1561f1929f3SYangbo Lu * bit for commands with busy signal. This affects 1571f1929f3SYangbo Lu * Command Inhibit (data) bit. Just ignore it since 1581f1929f3SYangbo Lu * MMC core driver has already polled card status 1591f1929f3SYangbo Lu * with CMD13 after any command with busy siganl. 1601f1929f3SYangbo Lu */ 1611f1929f3SYangbo Lu if ((spec_reg == SDHCI_PRESENT_STATE) && 1621f1929f3SYangbo Lu (esdhc->quirk_ignore_data_inhibit == true)) { 1631f1929f3SYangbo Lu ret = value & ~SDHCI_DATA_INHIBIT; 1641f1929f3SYangbo Lu return ret; 1651f1929f3SYangbo Lu } 1661f1929f3SYangbo Lu 167f4932cfdSyangbo lu ret = value; 168137ccd46SJerry Huang return ret; 169137ccd46SJerry Huang } 170137ccd46SJerry Huang 171f4932cfdSyangbo lu static u16 esdhc_readw_fixup(struct sdhci_host *host, 172f4932cfdSyangbo lu int spec_reg, u32 value) 1737657c3a7SAlbert Herranz { 174151ede40Syangbo lu struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); 175151ede40Syangbo lu struct sdhci_esdhc *esdhc = sdhci_pltfm_priv(pltfm_host); 1767657c3a7SAlbert Herranz u16 ret; 177f4932cfdSyangbo lu int shift = (spec_reg & 0x2) * 8; 1787657c3a7SAlbert Herranz 179429d939cSYangbo Lu if (spec_reg == SDHCI_TRANSFER_MODE) 180429d939cSYangbo Lu return pltfm_host->xfer_mode_shadow; 181429d939cSYangbo Lu 182f4932cfdSyangbo lu if (spec_reg == SDHCI_HOST_VERSION) 183f4932cfdSyangbo lu ret = value & 0xffff; 1847657c3a7SAlbert Herranz else 185f4932cfdSyangbo lu ret = (value >> shift) & 0xffff; 186151ede40Syangbo lu /* Workaround for T4240-R1.0-R2.0 eSDHC which has incorrect 187151ede40Syangbo lu * vendor version and spec version information. 188151ede40Syangbo lu */ 189151ede40Syangbo lu if ((spec_reg == SDHCI_HOST_VERSION) && 190151ede40Syangbo lu (esdhc->quirk_incorrect_hostver)) 191151ede40Syangbo lu ret = (VENDOR_V_23 << SDHCI_VENDOR_VER_SHIFT) | SDHCI_SPEC_200; 192e51cbc9eSXu lei return ret; 193e51cbc9eSXu lei } 194e51cbc9eSXu lei 195f4932cfdSyangbo lu static u8 esdhc_readb_fixup(struct sdhci_host *host, 196f4932cfdSyangbo lu int spec_reg, u32 value) 197e51cbc9eSXu lei { 198f4932cfdSyangbo lu u8 ret; 199f4932cfdSyangbo lu u8 dma_bits; 200f4932cfdSyangbo lu int shift = (spec_reg & 0x3) * 8; 201f4932cfdSyangbo lu 202f4932cfdSyangbo lu ret = (value >> shift) & 0xff; 203ba8c4dc9SRoy Zang 204ba8c4dc9SRoy Zang /* 205ba8c4dc9SRoy Zang * "DMA select" locates at offset 0x28 in SD specification, but on 206ba8c4dc9SRoy Zang * P5020 or P3041, it locates at 0x29. 207ba8c4dc9SRoy Zang */ 208f4932cfdSyangbo lu if (spec_reg == SDHCI_HOST_CONTROL) { 209ba8c4dc9SRoy Zang /* DMA select is 22,23 bits in Protocol Control Register */ 210f4932cfdSyangbo lu dma_bits = (value >> 5) & SDHCI_CTRL_DMA_MASK; 211ba8c4dc9SRoy Zang /* fixup the result */ 212ba8c4dc9SRoy Zang ret &= ~SDHCI_CTRL_DMA_MASK; 213ba8c4dc9SRoy Zang ret |= dma_bits; 214ba8c4dc9SRoy Zang } 215f4932cfdSyangbo lu return ret; 216f4932cfdSyangbo lu } 217f4932cfdSyangbo lu 218f4932cfdSyangbo lu /** 219f4932cfdSyangbo lu * esdhc_write*_fixup - Fixup the SD spec register value so that it could be 220f4932cfdSyangbo lu * written into eSDHC register. 221f4932cfdSyangbo lu * 222f4932cfdSyangbo lu * @host: pointer to sdhci_host 223f4932cfdSyangbo lu * @spec_reg: SD spec register address 224f4932cfdSyangbo lu * @value: 8/16/32bit SD spec register value that would be written 225f4932cfdSyangbo lu * @old_value: 32bit eSDHC register value on spec_reg address 226f4932cfdSyangbo lu * 227f4932cfdSyangbo lu * In SD spec, there are 8/16/32/64 bits registers, while all of eSDHC 228f4932cfdSyangbo lu * registers are 32 bits. There are differences in register size, register 229f4932cfdSyangbo lu * address, register function, bit position and function between eSDHC spec 230f4932cfdSyangbo lu * and SD spec. 231f4932cfdSyangbo lu * 232f4932cfdSyangbo lu * Return a fixed up register value 233f4932cfdSyangbo lu */ 234f4932cfdSyangbo lu static u32 esdhc_writel_fixup(struct sdhci_host *host, 235f4932cfdSyangbo lu int spec_reg, u32 value, u32 old_value) 236f4932cfdSyangbo lu { 237f4932cfdSyangbo lu u32 ret; 238f4932cfdSyangbo lu 239f4932cfdSyangbo lu /* 240f4932cfdSyangbo lu * Enabling IRQSTATEN[BGESEN] is just to set IRQSTAT[BGE] 241f4932cfdSyangbo lu * when SYSCTL[RSTD] is set for some special operations. 242f4932cfdSyangbo lu * No any impact on other operation. 243f4932cfdSyangbo lu */ 244f4932cfdSyangbo lu if (spec_reg == SDHCI_INT_ENABLE) 245f4932cfdSyangbo lu ret = value | SDHCI_INT_BLK_GAP; 246f4932cfdSyangbo lu else 247f4932cfdSyangbo lu ret = value; 248ba8c4dc9SRoy Zang 2497657c3a7SAlbert Herranz return ret; 2507657c3a7SAlbert Herranz } 2517657c3a7SAlbert Herranz 252f4932cfdSyangbo lu static u32 esdhc_writew_fixup(struct sdhci_host *host, 253f4932cfdSyangbo lu int spec_reg, u16 value, u32 old_value) 254a4071fbbSHaijun Zhang { 255f4932cfdSyangbo lu struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); 256f4932cfdSyangbo lu int shift = (spec_reg & 0x2) * 8; 257f4932cfdSyangbo lu u32 ret; 258f4932cfdSyangbo lu 259f4932cfdSyangbo lu switch (spec_reg) { 260f4932cfdSyangbo lu case SDHCI_TRANSFER_MODE: 261a4071fbbSHaijun Zhang /* 262f4932cfdSyangbo lu * Postpone this write, we must do it together with a 263f4932cfdSyangbo lu * command write that is down below. Return old value. 264a4071fbbSHaijun Zhang */ 265f4932cfdSyangbo lu pltfm_host->xfer_mode_shadow = value; 266f4932cfdSyangbo lu return old_value; 267f4932cfdSyangbo lu case SDHCI_COMMAND: 268f4932cfdSyangbo lu ret = (value << 16) | pltfm_host->xfer_mode_shadow; 269f4932cfdSyangbo lu return ret; 270a4071fbbSHaijun Zhang } 271a4071fbbSHaijun Zhang 272f4932cfdSyangbo lu ret = old_value & (~(0xffff << shift)); 273f4932cfdSyangbo lu ret |= (value << shift); 274f4932cfdSyangbo lu 275f4932cfdSyangbo lu if (spec_reg == SDHCI_BLOCK_SIZE) { 2767657c3a7SAlbert Herranz /* 2777657c3a7SAlbert Herranz * Two last DMA bits are reserved, and first one is used for 2787657c3a7SAlbert Herranz * non-standard blksz of 4096 bytes that we don't support 2797657c3a7SAlbert Herranz * yet. So clear the DMA boundary bits. 2807657c3a7SAlbert Herranz */ 281f4932cfdSyangbo lu ret &= (~SDHCI_MAKE_BLKSZ(0x7, 0)); 2827657c3a7SAlbert Herranz } 283f4932cfdSyangbo lu return ret; 2847657c3a7SAlbert Herranz } 2857657c3a7SAlbert Herranz 286f4932cfdSyangbo lu static u32 esdhc_writeb_fixup(struct sdhci_host *host, 287f4932cfdSyangbo lu int spec_reg, u8 value, u32 old_value) 2887657c3a7SAlbert Herranz { 289f4932cfdSyangbo lu u32 ret; 290f4932cfdSyangbo lu u32 dma_bits; 291f4932cfdSyangbo lu u8 tmp; 292f4932cfdSyangbo lu int shift = (spec_reg & 0x3) * 8; 293f4932cfdSyangbo lu 294ba8c4dc9SRoy Zang /* 2959e4703dfSyangbo lu * eSDHC doesn't have a standard power control register, so we do 2969e4703dfSyangbo lu * nothing here to avoid incorrect operation. 2979e4703dfSyangbo lu */ 2989e4703dfSyangbo lu if (spec_reg == SDHCI_POWER_CONTROL) 2999e4703dfSyangbo lu return old_value; 3009e4703dfSyangbo lu /* 301ba8c4dc9SRoy Zang * "DMA select" location is offset 0x28 in SD specification, but on 302ba8c4dc9SRoy Zang * P5020 or P3041, it's located at 0x29. 303ba8c4dc9SRoy Zang */ 304f4932cfdSyangbo lu if (spec_reg == SDHCI_HOST_CONTROL) { 305dcaff04dSOded Gabbay /* 306dcaff04dSOded Gabbay * If host control register is not standard, exit 307dcaff04dSOded Gabbay * this function 308dcaff04dSOded Gabbay */ 309dcaff04dSOded Gabbay if (host->quirks2 & SDHCI_QUIRK2_BROKEN_HOST_CONTROL) 310f4932cfdSyangbo lu return old_value; 311dcaff04dSOded Gabbay 312ba8c4dc9SRoy Zang /* DMA select is 22,23 bits in Protocol Control Register */ 313f4932cfdSyangbo lu dma_bits = (value & SDHCI_CTRL_DMA_MASK) << 5; 314f4932cfdSyangbo lu ret = (old_value & (~(SDHCI_CTRL_DMA_MASK << 5))) | dma_bits; 315f4932cfdSyangbo lu tmp = (value & (~SDHCI_CTRL_DMA_MASK)) | 316f4932cfdSyangbo lu (old_value & SDHCI_CTRL_DMA_MASK); 317f4932cfdSyangbo lu ret = (ret & (~0xff)) | tmp; 318f4932cfdSyangbo lu 319f4932cfdSyangbo lu /* Prevent SDHCI core from writing reserved bits (e.g. HISPD) */ 320f4932cfdSyangbo lu ret &= ~ESDHC_HOST_CONTROL_RES; 321f4932cfdSyangbo lu return ret; 322ba8c4dc9SRoy Zang } 323ba8c4dc9SRoy Zang 324f4932cfdSyangbo lu ret = (old_value & (~(0xff << shift))) | (value << shift); 325f4932cfdSyangbo lu return ret; 326f4932cfdSyangbo lu } 327f4932cfdSyangbo lu 328f4932cfdSyangbo lu static u32 esdhc_be_readl(struct sdhci_host *host, int reg) 329f4932cfdSyangbo lu { 330f4932cfdSyangbo lu u32 ret; 331f4932cfdSyangbo lu u32 value; 332f4932cfdSyangbo lu 3332f3110ccSyangbo lu if (reg == SDHCI_CAPABILITIES_1) 3342f3110ccSyangbo lu value = ioread32be(host->ioaddr + ESDHC_CAPABILITIES_1); 3352f3110ccSyangbo lu else 336f4932cfdSyangbo lu value = ioread32be(host->ioaddr + reg); 3372f3110ccSyangbo lu 338f4932cfdSyangbo lu ret = esdhc_readl_fixup(host, reg, value); 339f4932cfdSyangbo lu 340f4932cfdSyangbo lu return ret; 341f4932cfdSyangbo lu } 342f4932cfdSyangbo lu 343f4932cfdSyangbo lu static u32 esdhc_le_readl(struct sdhci_host *host, int reg) 344f4932cfdSyangbo lu { 345f4932cfdSyangbo lu u32 ret; 346f4932cfdSyangbo lu u32 value; 347f4932cfdSyangbo lu 3482f3110ccSyangbo lu if (reg == SDHCI_CAPABILITIES_1) 3492f3110ccSyangbo lu value = ioread32(host->ioaddr + ESDHC_CAPABILITIES_1); 3502f3110ccSyangbo lu else 351f4932cfdSyangbo lu value = ioread32(host->ioaddr + reg); 3522f3110ccSyangbo lu 353f4932cfdSyangbo lu ret = esdhc_readl_fixup(host, reg, value); 354f4932cfdSyangbo lu 355f4932cfdSyangbo lu return ret; 356f4932cfdSyangbo lu } 357f4932cfdSyangbo lu 358f4932cfdSyangbo lu static u16 esdhc_be_readw(struct sdhci_host *host, int reg) 359f4932cfdSyangbo lu { 360f4932cfdSyangbo lu u16 ret; 361f4932cfdSyangbo lu u32 value; 362f4932cfdSyangbo lu int base = reg & ~0x3; 363f4932cfdSyangbo lu 364f4932cfdSyangbo lu value = ioread32be(host->ioaddr + base); 365f4932cfdSyangbo lu ret = esdhc_readw_fixup(host, reg, value); 366f4932cfdSyangbo lu return ret; 367f4932cfdSyangbo lu } 368f4932cfdSyangbo lu 369f4932cfdSyangbo lu static u16 esdhc_le_readw(struct sdhci_host *host, int reg) 370f4932cfdSyangbo lu { 371f4932cfdSyangbo lu u16 ret; 372f4932cfdSyangbo lu u32 value; 373f4932cfdSyangbo lu int base = reg & ~0x3; 374f4932cfdSyangbo lu 375f4932cfdSyangbo lu value = ioread32(host->ioaddr + base); 376f4932cfdSyangbo lu ret = esdhc_readw_fixup(host, reg, value); 377f4932cfdSyangbo lu return ret; 378f4932cfdSyangbo lu } 379f4932cfdSyangbo lu 380f4932cfdSyangbo lu static u8 esdhc_be_readb(struct sdhci_host *host, int reg) 381f4932cfdSyangbo lu { 382f4932cfdSyangbo lu u8 ret; 383f4932cfdSyangbo lu u32 value; 384f4932cfdSyangbo lu int base = reg & ~0x3; 385f4932cfdSyangbo lu 386f4932cfdSyangbo lu value = ioread32be(host->ioaddr + base); 387f4932cfdSyangbo lu ret = esdhc_readb_fixup(host, reg, value); 388f4932cfdSyangbo lu return ret; 389f4932cfdSyangbo lu } 390f4932cfdSyangbo lu 391f4932cfdSyangbo lu static u8 esdhc_le_readb(struct sdhci_host *host, int reg) 392f4932cfdSyangbo lu { 393f4932cfdSyangbo lu u8 ret; 394f4932cfdSyangbo lu u32 value; 395f4932cfdSyangbo lu int base = reg & ~0x3; 396f4932cfdSyangbo lu 397f4932cfdSyangbo lu value = ioread32(host->ioaddr + base); 398f4932cfdSyangbo lu ret = esdhc_readb_fixup(host, reg, value); 399f4932cfdSyangbo lu return ret; 400f4932cfdSyangbo lu } 401f4932cfdSyangbo lu 402f4932cfdSyangbo lu static void esdhc_be_writel(struct sdhci_host *host, u32 val, int reg) 403f4932cfdSyangbo lu { 404f4932cfdSyangbo lu u32 value; 405f4932cfdSyangbo lu 406f4932cfdSyangbo lu value = esdhc_writel_fixup(host, reg, val, 0); 407f4932cfdSyangbo lu iowrite32be(value, host->ioaddr + reg); 408f4932cfdSyangbo lu } 409f4932cfdSyangbo lu 410f4932cfdSyangbo lu static void esdhc_le_writel(struct sdhci_host *host, u32 val, int reg) 411f4932cfdSyangbo lu { 412f4932cfdSyangbo lu u32 value; 413f4932cfdSyangbo lu 414f4932cfdSyangbo lu value = esdhc_writel_fixup(host, reg, val, 0); 415f4932cfdSyangbo lu iowrite32(value, host->ioaddr + reg); 416f4932cfdSyangbo lu } 417f4932cfdSyangbo lu 418f4932cfdSyangbo lu static void esdhc_be_writew(struct sdhci_host *host, u16 val, int reg) 419f4932cfdSyangbo lu { 42022dc132dSYangbo Lu struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); 42122dc132dSYangbo Lu struct sdhci_esdhc *esdhc = sdhci_pltfm_priv(pltfm_host); 422f4932cfdSyangbo lu int base = reg & ~0x3; 423f4932cfdSyangbo lu u32 value; 424f4932cfdSyangbo lu u32 ret; 425f4932cfdSyangbo lu 426f4932cfdSyangbo lu value = ioread32be(host->ioaddr + base); 427f4932cfdSyangbo lu ret = esdhc_writew_fixup(host, reg, val, value); 428f4932cfdSyangbo lu if (reg != SDHCI_TRANSFER_MODE) 429f4932cfdSyangbo lu iowrite32be(ret, host->ioaddr + base); 43022dc132dSYangbo Lu 43122dc132dSYangbo Lu /* Starting SW tuning requires ESDHC_SMPCLKSEL to be set 43222dc132dSYangbo Lu * 1us later after ESDHC_EXTN is set. 43322dc132dSYangbo Lu */ 43422dc132dSYangbo Lu if (base == ESDHC_SYSTEM_CONTROL_2) { 43522dc132dSYangbo Lu if (!(value & ESDHC_EXTN) && (ret & ESDHC_EXTN) && 43622dc132dSYangbo Lu esdhc->in_sw_tuning) { 43722dc132dSYangbo Lu udelay(1); 43822dc132dSYangbo Lu ret |= ESDHC_SMPCLKSEL; 43922dc132dSYangbo Lu iowrite32be(ret, host->ioaddr + base); 44022dc132dSYangbo Lu } 44122dc132dSYangbo Lu } 442f4932cfdSyangbo lu } 443f4932cfdSyangbo lu 444f4932cfdSyangbo lu static void esdhc_le_writew(struct sdhci_host *host, u16 val, int reg) 445f4932cfdSyangbo lu { 44622dc132dSYangbo Lu struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); 44722dc132dSYangbo Lu struct sdhci_esdhc *esdhc = sdhci_pltfm_priv(pltfm_host); 448f4932cfdSyangbo lu int base = reg & ~0x3; 449f4932cfdSyangbo lu u32 value; 450f4932cfdSyangbo lu u32 ret; 451f4932cfdSyangbo lu 452f4932cfdSyangbo lu value = ioread32(host->ioaddr + base); 453f4932cfdSyangbo lu ret = esdhc_writew_fixup(host, reg, val, value); 454f4932cfdSyangbo lu if (reg != SDHCI_TRANSFER_MODE) 455f4932cfdSyangbo lu iowrite32(ret, host->ioaddr + base); 45622dc132dSYangbo Lu 45722dc132dSYangbo Lu /* Starting SW tuning requires ESDHC_SMPCLKSEL to be set 45822dc132dSYangbo Lu * 1us later after ESDHC_EXTN is set. 45922dc132dSYangbo Lu */ 46022dc132dSYangbo Lu if (base == ESDHC_SYSTEM_CONTROL_2) { 46122dc132dSYangbo Lu if (!(value & ESDHC_EXTN) && (ret & ESDHC_EXTN) && 46222dc132dSYangbo Lu esdhc->in_sw_tuning) { 46322dc132dSYangbo Lu udelay(1); 46422dc132dSYangbo Lu ret |= ESDHC_SMPCLKSEL; 46522dc132dSYangbo Lu iowrite32(ret, host->ioaddr + base); 46622dc132dSYangbo Lu } 46722dc132dSYangbo Lu } 468f4932cfdSyangbo lu } 469f4932cfdSyangbo lu 470f4932cfdSyangbo lu static void esdhc_be_writeb(struct sdhci_host *host, u8 val, int reg) 471f4932cfdSyangbo lu { 472f4932cfdSyangbo lu int base = reg & ~0x3; 473f4932cfdSyangbo lu u32 value; 474f4932cfdSyangbo lu u32 ret; 475f4932cfdSyangbo lu 476f4932cfdSyangbo lu value = ioread32be(host->ioaddr + base); 477f4932cfdSyangbo lu ret = esdhc_writeb_fixup(host, reg, val, value); 478f4932cfdSyangbo lu iowrite32be(ret, host->ioaddr + base); 479f4932cfdSyangbo lu } 480f4932cfdSyangbo lu 481f4932cfdSyangbo lu static void esdhc_le_writeb(struct sdhci_host *host, u8 val, int reg) 482f4932cfdSyangbo lu { 483f4932cfdSyangbo lu int base = reg & ~0x3; 484f4932cfdSyangbo lu u32 value; 485f4932cfdSyangbo lu u32 ret; 486f4932cfdSyangbo lu 487f4932cfdSyangbo lu value = ioread32(host->ioaddr + base); 488f4932cfdSyangbo lu ret = esdhc_writeb_fixup(host, reg, val, value); 489f4932cfdSyangbo lu iowrite32(ret, host->ioaddr + base); 4907657c3a7SAlbert Herranz } 4917657c3a7SAlbert Herranz 492a4071fbbSHaijun Zhang /* 493a4071fbbSHaijun Zhang * For Abort or Suspend after Stop at Block Gap, ignore the ADMA 494a4071fbbSHaijun Zhang * error(IRQSTAT[ADMAE]) if both Transfer Complete(IRQSTAT[TC]) 495a4071fbbSHaijun Zhang * and Block Gap Event(IRQSTAT[BGE]) are also set. 496a4071fbbSHaijun Zhang * For Continue, apply soft reset for data(SYSCTL[RSTD]); 497a4071fbbSHaijun Zhang * and re-issue the entire read transaction from beginning. 498a4071fbbSHaijun Zhang */ 499f4932cfdSyangbo lu static void esdhc_of_adma_workaround(struct sdhci_host *host, u32 intmask) 500a4071fbbSHaijun Zhang { 501f4932cfdSyangbo lu struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); 5028605e7aeSJisheng Zhang struct sdhci_esdhc *esdhc = sdhci_pltfm_priv(pltfm_host); 503a4071fbbSHaijun Zhang bool applicable; 504a4071fbbSHaijun Zhang dma_addr_t dmastart; 505a4071fbbSHaijun Zhang dma_addr_t dmanow; 506a4071fbbSHaijun Zhang 507a4071fbbSHaijun Zhang applicable = (intmask & SDHCI_INT_DATA_END) && 508a4071fbbSHaijun Zhang (intmask & SDHCI_INT_BLK_GAP) && 509f4932cfdSyangbo lu (esdhc->vendor_ver == VENDOR_V_23); 510a4071fbbSHaijun Zhang if (!applicable) 511a4071fbbSHaijun Zhang return; 512a4071fbbSHaijun Zhang 513a4071fbbSHaijun Zhang host->data->error = 0; 514a4071fbbSHaijun Zhang dmastart = sg_dma_address(host->data->sg); 515a4071fbbSHaijun Zhang dmanow = dmastart + host->data->bytes_xfered; 516a4071fbbSHaijun Zhang /* 517a4071fbbSHaijun Zhang * Force update to the next DMA block boundary. 518a4071fbbSHaijun Zhang */ 519a4071fbbSHaijun Zhang dmanow = (dmanow & ~(SDHCI_DEFAULT_BOUNDARY_SIZE - 1)) + 520a4071fbbSHaijun Zhang SDHCI_DEFAULT_BOUNDARY_SIZE; 521a4071fbbSHaijun Zhang host->data->bytes_xfered = dmanow - dmastart; 522a4071fbbSHaijun Zhang sdhci_writel(host, dmanow, SDHCI_DMA_ADDRESS); 523a4071fbbSHaijun Zhang } 524a4071fbbSHaijun Zhang 52580872e21SWolfram Sang static int esdhc_of_enable_dma(struct sdhci_host *host) 5267657c3a7SAlbert Herranz { 527*40c67c29SJiasheng Jiang int ret; 528f4932cfdSyangbo lu u32 value; 5295552d7adSLaurentiu Tudor struct device *dev = mmc_dev(host->mmc); 5305552d7adSLaurentiu Tudor 5315552d7adSLaurentiu Tudor if (of_device_is_compatible(dev->of_node, "fsl,ls1043a-esdhc") || 532*40c67c29SJiasheng Jiang of_device_is_compatible(dev->of_node, "fsl,ls1046a-esdhc")) { 533*40c67c29SJiasheng Jiang ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(40)); 534*40c67c29SJiasheng Jiang if (ret) 535*40c67c29SJiasheng Jiang return ret; 536*40c67c29SJiasheng Jiang } 537f4932cfdSyangbo lu 538f4932cfdSyangbo lu value = sdhci_readl(host, ESDHC_DMA_SYSCTL); 539121bd08bSRussell King 540121bd08bSRussell King if (of_dma_is_coherent(dev->of_node)) 541f4932cfdSyangbo lu value |= ESDHC_DMA_SNOOP; 542121bd08bSRussell King else 543121bd08bSRussell King value &= ~ESDHC_DMA_SNOOP; 544121bd08bSRussell King 545f4932cfdSyangbo lu sdhci_writel(host, value, ESDHC_DMA_SYSCTL); 5467657c3a7SAlbert Herranz return 0; 5477657c3a7SAlbert Herranz } 5487657c3a7SAlbert Herranz 54980872e21SWolfram Sang static unsigned int esdhc_of_get_max_clock(struct sdhci_host *host) 5507657c3a7SAlbert Herranz { 551e307148fSShawn Guo struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); 55219c3a0efSyangbo lu struct sdhci_esdhc *esdhc = sdhci_pltfm_priv(pltfm_host); 5537657c3a7SAlbert Herranz 55419c3a0efSyangbo lu if (esdhc->peripheral_clock) 55519c3a0efSyangbo lu return esdhc->peripheral_clock; 55619c3a0efSyangbo lu else 557e307148fSShawn Guo return pltfm_host->clock; 5587657c3a7SAlbert Herranz } 5597657c3a7SAlbert Herranz 56080872e21SWolfram Sang static unsigned int esdhc_of_get_min_clock(struct sdhci_host *host) 5617657c3a7SAlbert Herranz { 562e307148fSShawn Guo struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); 56319c3a0efSyangbo lu struct sdhci_esdhc *esdhc = sdhci_pltfm_priv(pltfm_host); 56419c3a0efSyangbo lu unsigned int clock; 5657657c3a7SAlbert Herranz 56619c3a0efSyangbo lu if (esdhc->peripheral_clock) 56719c3a0efSyangbo lu clock = esdhc->peripheral_clock; 56819c3a0efSyangbo lu else 56919c3a0efSyangbo lu clock = pltfm_host->clock; 57019c3a0efSyangbo lu return clock / 256 / 16; 5717657c3a7SAlbert Herranz } 5727657c3a7SAlbert Herranz 573dd3f6983Syangbo lu static void esdhc_clock_enable(struct sdhci_host *host, bool enable) 574dd3f6983Syangbo lu { 5751b21a701SYangbo Lu struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); 5761b21a701SYangbo Lu struct sdhci_esdhc *esdhc = sdhci_pltfm_priv(pltfm_host); 577dd3f6983Syangbo lu ktime_t timeout; 5781b21a701SYangbo Lu u32 val, clk_en; 5791b21a701SYangbo Lu 5801b21a701SYangbo Lu clk_en = ESDHC_CLOCK_SDCLKEN; 5811b21a701SYangbo Lu 5821b21a701SYangbo Lu /* 5831b21a701SYangbo Lu * IPGEN/HCKEN/PEREN bits exist on eSDHC whose vendor version 5841b21a701SYangbo Lu * is 2.2 or lower. 5851b21a701SYangbo Lu */ 5861b21a701SYangbo Lu if (esdhc->vendor_ver <= VENDOR_V_22) 5871b21a701SYangbo Lu clk_en |= (ESDHC_CLOCK_IPGEN | ESDHC_CLOCK_HCKEN | 5881b21a701SYangbo Lu ESDHC_CLOCK_PEREN); 589dd3f6983Syangbo lu 590dd3f6983Syangbo lu val = sdhci_readl(host, ESDHC_SYSTEM_CONTROL); 591dd3f6983Syangbo lu 592dd3f6983Syangbo lu if (enable) 5931b21a701SYangbo Lu val |= clk_en; 594dd3f6983Syangbo lu else 5951b21a701SYangbo Lu val &= ~clk_en; 596dd3f6983Syangbo lu 597dd3f6983Syangbo lu sdhci_writel(host, val, ESDHC_SYSTEM_CONTROL); 598dd3f6983Syangbo lu 5991b21a701SYangbo Lu /* 6001b21a701SYangbo Lu * Wait max 20 ms. If vendor version is 2.2 or lower, do not 6011b21a701SYangbo Lu * wait clock stable bit which does not exist. 6021b21a701SYangbo Lu */ 603dd3f6983Syangbo lu timeout = ktime_add_ms(ktime_get(), 20); 6041b21a701SYangbo Lu while (esdhc->vendor_ver > VENDOR_V_22) { 605ea6d0273SAdrian Hunter bool timedout = ktime_after(ktime_get(), timeout); 606ea6d0273SAdrian Hunter 6071b21a701SYangbo Lu if (sdhci_readl(host, ESDHC_PRSSTAT) & ESDHC_CLOCK_STABLE) 608ea6d0273SAdrian Hunter break; 609ea6d0273SAdrian Hunter if (timedout) { 610dd3f6983Syangbo lu pr_err("%s: Internal clock never stabilised.\n", 611dd3f6983Syangbo lu mmc_hostname(host->mmc)); 612dd3f6983Syangbo lu break; 613dd3f6983Syangbo lu } 6141b21a701SYangbo Lu usleep_range(10, 20); 615dd3f6983Syangbo lu } 616dd3f6983Syangbo lu } 617dd3f6983Syangbo lu 6186e32f65cSYangbo Lu static void esdhc_flush_async_fifo(struct sdhci_host *host) 6196e32f65cSYangbo Lu { 6206e32f65cSYangbo Lu ktime_t timeout; 6216e32f65cSYangbo Lu u32 val; 6226e32f65cSYangbo Lu 6236e32f65cSYangbo Lu val = sdhci_readl(host, ESDHC_DMA_SYSCTL); 6246e32f65cSYangbo Lu val |= ESDHC_FLUSH_ASYNC_FIFO; 6256e32f65cSYangbo Lu sdhci_writel(host, val, ESDHC_DMA_SYSCTL); 6266e32f65cSYangbo Lu 6276e32f65cSYangbo Lu /* Wait max 20 ms */ 6286e32f65cSYangbo Lu timeout = ktime_add_ms(ktime_get(), 20); 6296e32f65cSYangbo Lu while (1) { 6306e32f65cSYangbo Lu bool timedout = ktime_after(ktime_get(), timeout); 6316e32f65cSYangbo Lu 6326e32f65cSYangbo Lu if (!(sdhci_readl(host, ESDHC_DMA_SYSCTL) & 6336e32f65cSYangbo Lu ESDHC_FLUSH_ASYNC_FIFO)) 6346e32f65cSYangbo Lu break; 6356e32f65cSYangbo Lu if (timedout) { 6366e32f65cSYangbo Lu pr_err("%s: flushing asynchronous FIFO timeout.\n", 6376e32f65cSYangbo Lu mmc_hostname(host->mmc)); 6386e32f65cSYangbo Lu break; 6396e32f65cSYangbo Lu } 6406e32f65cSYangbo Lu usleep_range(10, 20); 6416e32f65cSYangbo Lu } 6426e32f65cSYangbo Lu } 6436e32f65cSYangbo Lu 644f060bc9cSJerry Huang static void esdhc_of_set_clock(struct sdhci_host *host, unsigned int clock) 645f060bc9cSJerry Huang { 646f4932cfdSyangbo lu struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); 6478605e7aeSJisheng Zhang struct sdhci_esdhc *esdhc = sdhci_pltfm_priv(pltfm_host); 6481b21a701SYangbo Lu unsigned int pre_div = 1, div = 1; 6491b21a701SYangbo Lu unsigned int clock_fixup = 0; 650e145ac45Syangbo lu ktime_t timeout; 651d31fc00aSDong Aisheng u32 temp; 652d31fc00aSDong Aisheng 653dd3f6983Syangbo lu if (clock == 0) { 6541b21a701SYangbo Lu host->mmc->actual_clock = 0; 655dd3f6983Syangbo lu esdhc_clock_enable(host, false); 656373073efSRussell King return; 657dd3f6983Syangbo lu } 658d31fc00aSDong Aisheng 6591b21a701SYangbo Lu /* Start pre_div at 2 for vendor version < 2.3. */ 660f4932cfdSyangbo lu if (esdhc->vendor_ver < VENDOR_V_23) 66177bd2f6fSYangbo Lu pre_div = 2; 66277bd2f6fSYangbo Lu 6631b21a701SYangbo Lu /* Fix clock value. */ 66467fdfbdfSyinbo.zhu if (host->mmc->card && mmc_card_sd(host->mmc->card) && 66567fdfbdfSyinbo.zhu esdhc->clk_fixup && host->mmc->ios.timing == MMC_TIMING_LEGACY) 6661b21a701SYangbo Lu clock_fixup = esdhc->clk_fixup->sd_dflt_max_clk; 66767fdfbdfSyinbo.zhu else if (esdhc->clk_fixup) 6681b21a701SYangbo Lu clock_fixup = esdhc->clk_fixup->max_clk[host->mmc->ios.timing]; 669a627f025Syangbo lu 6701b21a701SYangbo Lu if (clock_fixup == 0 || clock < clock_fixup) 6711b21a701SYangbo Lu clock_fixup = clock; 672f060bc9cSJerry Huang 6731b21a701SYangbo Lu /* Calculate pre_div and div. */ 6741b21a701SYangbo Lu while (host->max_clk / pre_div / 16 > clock_fixup && pre_div < 256) 675d31fc00aSDong Aisheng pre_div *= 2; 676d31fc00aSDong Aisheng 6771b21a701SYangbo Lu while (host->max_clk / pre_div / div > clock_fixup && div < 16) 678d31fc00aSDong Aisheng div++; 679d31fc00aSDong Aisheng 6801b21a701SYangbo Lu esdhc->div_ratio = pre_div * div; 6811b21a701SYangbo Lu 6821b21a701SYangbo Lu /* Limit clock division for HS400 200MHz clock for quirk. */ 6836079e63cSYangbo Lu if (esdhc->quirk_limited_clk_division && 6846079e63cSYangbo Lu clock == MMC_HS200_MAX_DTR && 6856079e63cSYangbo Lu (host->mmc->ios.timing == MMC_TIMING_MMC_HS400 || 6866079e63cSYangbo Lu host->flags & SDHCI_HS400_TUNING)) { 6871b21a701SYangbo Lu if (esdhc->div_ratio <= 4) { 6886079e63cSYangbo Lu pre_div = 4; 6896079e63cSYangbo Lu div = 1; 6901b21a701SYangbo Lu } else if (esdhc->div_ratio <= 8) { 6916079e63cSYangbo Lu pre_div = 4; 6926079e63cSYangbo Lu div = 2; 6931b21a701SYangbo Lu } else if (esdhc->div_ratio <= 12) { 6946079e63cSYangbo Lu pre_div = 4; 6956079e63cSYangbo Lu div = 3; 6966079e63cSYangbo Lu } else { 697b11c36d5SColin Ian King pr_warn("%s: using unsupported clock division.\n", 6986079e63cSYangbo Lu mmc_hostname(host->mmc)); 6996079e63cSYangbo Lu } 7001b21a701SYangbo Lu esdhc->div_ratio = pre_div * div; 7016079e63cSYangbo Lu } 7026079e63cSYangbo Lu 7031b21a701SYangbo Lu host->mmc->actual_clock = host->max_clk / esdhc->div_ratio; 7041b21a701SYangbo Lu 705d31fc00aSDong Aisheng dev_dbg(mmc_dev(host->mmc), "desired SD clock: %d, actual: %d\n", 7061b21a701SYangbo Lu clock, host->mmc->actual_clock); 7071b21a701SYangbo Lu 7081b21a701SYangbo Lu /* Set clock division into register. */ 709d31fc00aSDong Aisheng pre_div >>= 1; 710d31fc00aSDong Aisheng div--; 711d31fc00aSDong Aisheng 7121b21a701SYangbo Lu esdhc_clock_enable(host, false); 7131b21a701SYangbo Lu 714d31fc00aSDong Aisheng temp = sdhci_readl(host, ESDHC_SYSTEM_CONTROL); 7151b21a701SYangbo Lu temp &= ~ESDHC_CLOCK_MASK; 7161b21a701SYangbo Lu temp |= ((div << ESDHC_DIVIDER_SHIFT) | 7171b21a701SYangbo Lu (pre_div << ESDHC_PREDIV_SHIFT)); 718d31fc00aSDong Aisheng sdhci_writel(host, temp, ESDHC_SYSTEM_CONTROL); 719e87d2db2Syangbo lu 7201b21a701SYangbo Lu /* 7211b21a701SYangbo Lu * Wait max 20 ms. If vendor version is 2.2 or lower, do not 7221b21a701SYangbo Lu * wait clock stable bit which does not exist. 7231b21a701SYangbo Lu */ 7241b21a701SYangbo Lu timeout = ktime_add_ms(ktime_get(), 20); 7251b21a701SYangbo Lu while (esdhc->vendor_ver > VENDOR_V_22) { 7261b21a701SYangbo Lu bool timedout = ktime_after(ktime_get(), timeout); 7271b21a701SYangbo Lu 7281b21a701SYangbo Lu if (sdhci_readl(host, ESDHC_PRSSTAT) & ESDHC_CLOCK_STABLE) 7291b21a701SYangbo Lu break; 7301b21a701SYangbo Lu if (timedout) { 7311b21a701SYangbo Lu pr_err("%s: Internal clock never stabilised.\n", 7321b21a701SYangbo Lu mmc_hostname(host->mmc)); 7331b21a701SYangbo Lu break; 7341b21a701SYangbo Lu } 7351b21a701SYangbo Lu usleep_range(10, 20); 7361b21a701SYangbo Lu } 7371b21a701SYangbo Lu 7381b21a701SYangbo Lu /* Additional setting for HS400. */ 73954e08d9aSYangbo Lu if (host->mmc->ios.timing == MMC_TIMING_MMC_HS400 && 74054e08d9aSYangbo Lu clock == MMC_HS200_MAX_DTR) { 74154e08d9aSYangbo Lu temp = sdhci_readl(host, ESDHC_TBCTL); 74254e08d9aSYangbo Lu sdhci_writel(host, temp | ESDHC_HS400_MODE, ESDHC_TBCTL); 74354e08d9aSYangbo Lu temp = sdhci_readl(host, ESDHC_SDCLKCTL); 74454e08d9aSYangbo Lu sdhci_writel(host, temp | ESDHC_CMD_CLK_CTL, ESDHC_SDCLKCTL); 74554e08d9aSYangbo Lu esdhc_clock_enable(host, true); 74654e08d9aSYangbo Lu 74754e08d9aSYangbo Lu temp = sdhci_readl(host, ESDHC_DLLCFG0); 74858d0bf84SYangbo Lu temp |= ESDHC_DLL_ENABLE; 74958d0bf84SYangbo Lu if (host->mmc->actual_clock == MMC_HS200_MAX_DTR) 75058d0bf84SYangbo Lu temp |= ESDHC_DLL_FREQ_SEL; 75154e08d9aSYangbo Lu sdhci_writel(host, temp, ESDHC_DLLCFG0); 752011fde48SYangbo Lu 753011fde48SYangbo Lu temp |= ESDHC_DLL_RESET; 754011fde48SYangbo Lu sdhci_writel(host, temp, ESDHC_DLLCFG0); 755011fde48SYangbo Lu udelay(1); 756011fde48SYangbo Lu temp &= ~ESDHC_DLL_RESET; 757011fde48SYangbo Lu sdhci_writel(host, temp, ESDHC_DLLCFG0); 758011fde48SYangbo Lu 759011fde48SYangbo Lu /* Wait max 20 ms */ 760011fde48SYangbo Lu if (read_poll_timeout(sdhci_readl, temp, 761011fde48SYangbo Lu temp & ESDHC_DLL_STS_SLV_LOCK, 762011fde48SYangbo Lu 10, 20000, false, 763011fde48SYangbo Lu host, ESDHC_DLLSTAT0)) 764011fde48SYangbo Lu pr_err("%s: timeout for delay chain lock.\n", 765011fde48SYangbo Lu mmc_hostname(host->mmc)); 766011fde48SYangbo Lu 76754e08d9aSYangbo Lu temp = sdhci_readl(host, ESDHC_TBCTL); 76854e08d9aSYangbo Lu sdhci_writel(host, temp | ESDHC_HS400_WNDW_ADJUST, ESDHC_TBCTL); 76954e08d9aSYangbo Lu 77054e08d9aSYangbo Lu esdhc_clock_enable(host, false); 7716e32f65cSYangbo Lu esdhc_flush_async_fifo(host); 77254e08d9aSYangbo Lu } 77380c74823SYangbo Lu esdhc_clock_enable(host, true); 774e87d2db2Syangbo lu } 775e87d2db2Syangbo lu 7762317f56cSRussell King static void esdhc_pltfm_set_bus_width(struct sdhci_host *host, int width) 77766b50a00SOded Gabbay { 77866b50a00SOded Gabbay u32 ctrl; 77966b50a00SOded Gabbay 780f4932cfdSyangbo lu ctrl = sdhci_readl(host, ESDHC_PROCTL); 781f4932cfdSyangbo lu ctrl &= (~ESDHC_CTRL_BUSWIDTH_MASK); 78266b50a00SOded Gabbay switch (width) { 78366b50a00SOded Gabbay case MMC_BUS_WIDTH_8: 784f4932cfdSyangbo lu ctrl |= ESDHC_CTRL_8BITBUS; 78566b50a00SOded Gabbay break; 78666b50a00SOded Gabbay 78766b50a00SOded Gabbay case MMC_BUS_WIDTH_4: 788f4932cfdSyangbo lu ctrl |= ESDHC_CTRL_4BITBUS; 78966b50a00SOded Gabbay break; 79066b50a00SOded Gabbay 79166b50a00SOded Gabbay default: 79266b50a00SOded Gabbay break; 79366b50a00SOded Gabbay } 79466b50a00SOded Gabbay 795f4932cfdSyangbo lu sdhci_writel(host, ctrl, ESDHC_PROCTL); 79666b50a00SOded Gabbay } 79766b50a00SOded Gabbay 798304f0a98SAlessio Igor Bogani static void esdhc_reset(struct sdhci_host *host, u8 mask) 799304f0a98SAlessio Igor Bogani { 80048e304ccSYangbo Lu struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); 80148e304ccSYangbo Lu struct sdhci_esdhc *esdhc = sdhci_pltfm_priv(pltfm_host); 8022aa3d826SYangbo Lu u32 val, bus_width = 0; 803f2bc6000Syinbo.zhu 8042aa3d826SYangbo Lu /* 8052aa3d826SYangbo Lu * Add delay to make sure all the DMA transfers are finished 8062aa3d826SYangbo Lu * for quirk. 8072aa3d826SYangbo Lu */ 808f667216cSYangbo Lu if (esdhc->quirk_delay_before_data_reset && 809f667216cSYangbo Lu (mask & SDHCI_RESET_DATA) && 810f667216cSYangbo Lu (host->flags & SDHCI_REQ_USE_DMA)) 811f667216cSYangbo Lu mdelay(5); 812f667216cSYangbo Lu 8132aa3d826SYangbo Lu /* 8142aa3d826SYangbo Lu * Save bus-width for eSDHC whose vendor version is 2.2 8152aa3d826SYangbo Lu * or lower for data reset. 8162aa3d826SYangbo Lu */ 8172aa3d826SYangbo Lu if ((mask & SDHCI_RESET_DATA) && 8182aa3d826SYangbo Lu (esdhc->vendor_ver <= VENDOR_V_22)) { 8192aa3d826SYangbo Lu val = sdhci_readl(host, ESDHC_PROCTL); 8202aa3d826SYangbo Lu bus_width = val & ESDHC_CTRL_BUSWIDTH_MASK; 8212aa3d826SYangbo Lu } 8222aa3d826SYangbo Lu 823304f0a98SAlessio Igor Bogani sdhci_reset(host, mask); 824304f0a98SAlessio Igor Bogani 8252aa3d826SYangbo Lu /* 8262aa3d826SYangbo Lu * Restore bus-width setting and interrupt registers for eSDHC 8272aa3d826SYangbo Lu * whose vendor version is 2.2 or lower for data reset. 8282aa3d826SYangbo Lu */ 8292aa3d826SYangbo Lu if ((mask & SDHCI_RESET_DATA) && 8302aa3d826SYangbo Lu (esdhc->vendor_ver <= VENDOR_V_22)) { 8312aa3d826SYangbo Lu val = sdhci_readl(host, ESDHC_PROCTL); 8322aa3d826SYangbo Lu val &= ~ESDHC_CTRL_BUSWIDTH_MASK; 8332aa3d826SYangbo Lu val |= bus_width; 8342aa3d826SYangbo Lu sdhci_writel(host, val, ESDHC_PROCTL); 8352aa3d826SYangbo Lu 836304f0a98SAlessio Igor Bogani sdhci_writel(host, host->ier, SDHCI_INT_ENABLE); 837304f0a98SAlessio Igor Bogani sdhci_writel(host, host->ier, SDHCI_SIGNAL_ENABLE); 8382aa3d826SYangbo Lu } 839f2bc6000Syinbo.zhu 8402aa3d826SYangbo Lu /* 8412aa3d826SYangbo Lu * Some bits have to be cleaned manually for eSDHC whose spec 8422aa3d826SYangbo Lu * version is higher than 3.0 for all reset. 8432aa3d826SYangbo Lu */ 8442aa3d826SYangbo Lu if ((mask & SDHCI_RESET_ALL) && 8452aa3d826SYangbo Lu (esdhc->spec_ver >= SDHCI_SPEC_300)) { 846f2bc6000Syinbo.zhu val = sdhci_readl(host, ESDHC_TBCTL); 847f2bc6000Syinbo.zhu val &= ~ESDHC_TB_EN; 848f2bc6000Syinbo.zhu sdhci_writel(host, val, ESDHC_TBCTL); 84948e304ccSYangbo Lu 8502aa3d826SYangbo Lu /* 8512aa3d826SYangbo Lu * Initialize eSDHC_DLLCFG1[DLL_PD_PULSE_STRETCH_SEL] to 8522aa3d826SYangbo Lu * 0 for quirk. 8532aa3d826SYangbo Lu */ 85448e304ccSYangbo Lu if (esdhc->quirk_unreliable_pulse_detection) { 85548e304ccSYangbo Lu val = sdhci_readl(host, ESDHC_DLLCFG1); 85648e304ccSYangbo Lu val &= ~ESDHC_DLL_PD_PULSE_STRETCH_SEL; 85748e304ccSYangbo Lu sdhci_writel(host, val, ESDHC_DLLCFG1); 85848e304ccSYangbo Lu } 859f2bc6000Syinbo.zhu } 860304f0a98SAlessio Igor Bogani } 861304f0a98SAlessio Igor Bogani 862ea35645aSyangbo lu /* The SCFG, Supplemental Configuration Unit, provides SoC specific 863ea35645aSyangbo lu * configuration and status registers for the device. There is a 864ea35645aSyangbo lu * SDHC IO VSEL control register on SCFG for some platforms. It's 865ea35645aSyangbo lu * used to support SDHC IO voltage switching. 866ea35645aSyangbo lu */ 867ea35645aSyangbo lu static const struct of_device_id scfg_device_ids[] = { 868ea35645aSyangbo lu { .compatible = "fsl,t1040-scfg", }, 869ea35645aSyangbo lu { .compatible = "fsl,ls1012a-scfg", }, 870ea35645aSyangbo lu { .compatible = "fsl,ls1046a-scfg", }, 871ea35645aSyangbo lu {} 872ea35645aSyangbo lu }; 873ea35645aSyangbo lu 874ea35645aSyangbo lu /* SDHC IO VSEL control register definition */ 875ea35645aSyangbo lu #define SCFG_SDHCIOVSELCR 0x408 876ea35645aSyangbo lu #define SDHCIOVSELCR_TGLEN 0x80000000 877ea35645aSyangbo lu #define SDHCIOVSELCR_VSELVAL 0x60000000 878ea35645aSyangbo lu #define SDHCIOVSELCR_SDHC_VS 0x00000001 879ea35645aSyangbo lu 880ea35645aSyangbo lu static int esdhc_signal_voltage_switch(struct mmc_host *mmc, 881ea35645aSyangbo lu struct mmc_ios *ios) 882ea35645aSyangbo lu { 883ea35645aSyangbo lu struct sdhci_host *host = mmc_priv(mmc); 884ea35645aSyangbo lu struct device_node *scfg_node; 885ea35645aSyangbo lu void __iomem *scfg_base = NULL; 886ea35645aSyangbo lu u32 sdhciovselcr; 887ea35645aSyangbo lu u32 val; 888ea35645aSyangbo lu 889ea35645aSyangbo lu /* 890ea35645aSyangbo lu * Signal Voltage Switching is only applicable for Host Controllers 891ea35645aSyangbo lu * v3.00 and above. 892ea35645aSyangbo lu */ 893ea35645aSyangbo lu if (host->version < SDHCI_SPEC_300) 894ea35645aSyangbo lu return 0; 895ea35645aSyangbo lu 896ea35645aSyangbo lu val = sdhci_readl(host, ESDHC_PROCTL); 897ea35645aSyangbo lu 898ea35645aSyangbo lu switch (ios->signal_voltage) { 899ea35645aSyangbo lu case MMC_SIGNAL_VOLTAGE_330: 900ea35645aSyangbo lu val &= ~ESDHC_VOLT_SEL; 901ea35645aSyangbo lu sdhci_writel(host, val, ESDHC_PROCTL); 902ea35645aSyangbo lu return 0; 903ea35645aSyangbo lu case MMC_SIGNAL_VOLTAGE_180: 904ea35645aSyangbo lu scfg_node = of_find_matching_node(NULL, scfg_device_ids); 905ea35645aSyangbo lu if (scfg_node) 906ea35645aSyangbo lu scfg_base = of_iomap(scfg_node, 0); 907ea35645aSyangbo lu if (scfg_base) { 908ea35645aSyangbo lu sdhciovselcr = SDHCIOVSELCR_TGLEN | 909ea35645aSyangbo lu SDHCIOVSELCR_VSELVAL; 910ea35645aSyangbo lu iowrite32be(sdhciovselcr, 911ea35645aSyangbo lu scfg_base + SCFG_SDHCIOVSELCR); 912ea35645aSyangbo lu 913ea35645aSyangbo lu val |= ESDHC_VOLT_SEL; 914ea35645aSyangbo lu sdhci_writel(host, val, ESDHC_PROCTL); 915ea35645aSyangbo lu mdelay(5); 916ea35645aSyangbo lu 917ea35645aSyangbo lu sdhciovselcr = SDHCIOVSELCR_TGLEN | 918ea35645aSyangbo lu SDHCIOVSELCR_SDHC_VS; 919ea35645aSyangbo lu iowrite32be(sdhciovselcr, 920ea35645aSyangbo lu scfg_base + SCFG_SDHCIOVSELCR); 921ea35645aSyangbo lu iounmap(scfg_base); 922ea35645aSyangbo lu } else { 923ea35645aSyangbo lu val |= ESDHC_VOLT_SEL; 924ea35645aSyangbo lu sdhci_writel(host, val, ESDHC_PROCTL); 925ea35645aSyangbo lu } 926ea35645aSyangbo lu return 0; 927ea35645aSyangbo lu default: 928ea35645aSyangbo lu return 0; 929ea35645aSyangbo lu } 930ea35645aSyangbo lu } 931ea35645aSyangbo lu 93222dc132dSYangbo Lu static struct soc_device_attribute soc_tuning_erratum_type1[] = { 9335b742232SYangbo Lu { .family = "QorIQ T1023", }, 9345b742232SYangbo Lu { .family = "QorIQ T1040", }, 9355b742232SYangbo Lu { .family = "QorIQ T2080", }, 9365b742232SYangbo Lu { .family = "QorIQ LS1021A", }, 93722dc132dSYangbo Lu { }, 93822dc132dSYangbo Lu }; 93922dc132dSYangbo Lu 94022dc132dSYangbo Lu static struct soc_device_attribute soc_tuning_erratum_type2[] = { 9415b742232SYangbo Lu { .family = "QorIQ LS1012A", }, 9425b742232SYangbo Lu { .family = "QorIQ LS1043A", }, 9435b742232SYangbo Lu { .family = "QorIQ LS1046A", }, 9445b742232SYangbo Lu { .family = "QorIQ LS1080A", }, 9455b742232SYangbo Lu { .family = "QorIQ LS2080A", }, 9465b742232SYangbo Lu { .family = "QorIQ LA1575A", }, 947b1f378abSYinbo Zhu { }, 948b1f378abSYinbo Zhu }; 949b1f378abSYinbo Zhu 95054e08d9aSYangbo Lu static void esdhc_tuning_block_enable(struct sdhci_host *host, bool enable) 951ba49cbd0Syangbo lu { 952ba49cbd0Syangbo lu u32 val; 953ba49cbd0Syangbo lu 954ba49cbd0Syangbo lu esdhc_clock_enable(host, false); 9556e32f65cSYangbo Lu esdhc_flush_async_fifo(host); 956ba49cbd0Syangbo lu 957ba49cbd0Syangbo lu val = sdhci_readl(host, ESDHC_TBCTL); 95854e08d9aSYangbo Lu if (enable) 959ba49cbd0Syangbo lu val |= ESDHC_TB_EN; 96054e08d9aSYangbo Lu else 96154e08d9aSYangbo Lu val &= ~ESDHC_TB_EN; 962ba49cbd0Syangbo lu sdhci_writel(host, val, ESDHC_TBCTL); 963ba49cbd0Syangbo lu 96454e08d9aSYangbo Lu esdhc_clock_enable(host, true); 96554e08d9aSYangbo Lu } 96654e08d9aSYangbo Lu 967f3c20825SYangbo Lu static void esdhc_tuning_window_ptr(struct sdhci_host *host, u8 *window_start, 96822dc132dSYangbo Lu u8 *window_end) 96922dc132dSYangbo Lu { 97022dc132dSYangbo Lu u32 val; 97122dc132dSYangbo Lu 97222dc132dSYangbo Lu /* Write TBCTL[11:8]=4'h8 */ 97322dc132dSYangbo Lu val = sdhci_readl(host, ESDHC_TBCTL); 97422dc132dSYangbo Lu val &= ~(0xf << 8); 97522dc132dSYangbo Lu val |= 8 << 8; 97622dc132dSYangbo Lu sdhci_writel(host, val, ESDHC_TBCTL); 97722dc132dSYangbo Lu 97822dc132dSYangbo Lu mdelay(1); 97922dc132dSYangbo Lu 98022dc132dSYangbo Lu /* Read TBCTL[31:0] register and rewrite again */ 98122dc132dSYangbo Lu val = sdhci_readl(host, ESDHC_TBCTL); 98222dc132dSYangbo Lu sdhci_writel(host, val, ESDHC_TBCTL); 98322dc132dSYangbo Lu 98422dc132dSYangbo Lu mdelay(1); 98522dc132dSYangbo Lu 98622dc132dSYangbo Lu /* Read the TBSTAT[31:0] register twice */ 98722dc132dSYangbo Lu val = sdhci_readl(host, ESDHC_TBSTAT); 98822dc132dSYangbo Lu val = sdhci_readl(host, ESDHC_TBSTAT); 98922dc132dSYangbo Lu 990f3c20825SYangbo Lu *window_end = val & 0xff; 991f3c20825SYangbo Lu *window_start = (val >> 8) & 0xff; 992f3c20825SYangbo Lu } 993f3c20825SYangbo Lu 994f3c20825SYangbo Lu static void esdhc_prepare_sw_tuning(struct sdhci_host *host, u8 *window_start, 995f3c20825SYangbo Lu u8 *window_end) 996f3c20825SYangbo Lu { 997f3c20825SYangbo Lu struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); 998f3c20825SYangbo Lu struct sdhci_esdhc *esdhc = sdhci_pltfm_priv(pltfm_host); 999f3c20825SYangbo Lu u8 start_ptr, end_ptr; 1000f3c20825SYangbo Lu 1001f3c20825SYangbo Lu if (esdhc->quirk_tuning_erratum_type1) { 1002f3c20825SYangbo Lu *window_start = 5 * esdhc->div_ratio; 1003f3c20825SYangbo Lu *window_end = 3 * esdhc->div_ratio; 1004f3c20825SYangbo Lu return; 1005f3c20825SYangbo Lu } 1006f3c20825SYangbo Lu 1007f3c20825SYangbo Lu esdhc_tuning_window_ptr(host, &start_ptr, &end_ptr); 1008f3c20825SYangbo Lu 100922dc132dSYangbo Lu /* Reset data lines by setting ESDHCCTL[RSTD] */ 101022dc132dSYangbo Lu sdhci_reset(host, SDHCI_RESET_DATA); 101122dc132dSYangbo Lu /* Write 32'hFFFF_FFFF to IRQSTAT register */ 101222dc132dSYangbo Lu sdhci_writel(host, 0xFFFFFFFF, SDHCI_INT_STATUS); 101322dc132dSYangbo Lu 10145b742232SYangbo Lu /* If TBSTAT[15:8]-TBSTAT[7:0] > (4 * div_ratio) + 2 10155b742232SYangbo Lu * or TBSTAT[7:0]-TBSTAT[15:8] > (4 * div_ratio) + 2, 101622dc132dSYangbo Lu * then program TBPTR[TB_WNDW_END_PTR] = 4 * div_ratio 101722dc132dSYangbo Lu * and program TBPTR[TB_WNDW_START_PTR] = 8 * div_ratio. 101822dc132dSYangbo Lu */ 101922dc132dSYangbo Lu 10205b742232SYangbo Lu if (abs(start_ptr - end_ptr) > (4 * esdhc->div_ratio + 2)) { 102122dc132dSYangbo Lu *window_start = 8 * esdhc->div_ratio; 102222dc132dSYangbo Lu *window_end = 4 * esdhc->div_ratio; 102322dc132dSYangbo Lu } else { 102422dc132dSYangbo Lu *window_start = 5 * esdhc->div_ratio; 102522dc132dSYangbo Lu *window_end = 3 * esdhc->div_ratio; 102622dc132dSYangbo Lu } 102722dc132dSYangbo Lu } 102822dc132dSYangbo Lu 102922dc132dSYangbo Lu static int esdhc_execute_sw_tuning(struct mmc_host *mmc, u32 opcode, 103022dc132dSYangbo Lu u8 window_start, u8 window_end) 103122dc132dSYangbo Lu { 103222dc132dSYangbo Lu struct sdhci_host *host = mmc_priv(mmc); 103322dc132dSYangbo Lu struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); 103422dc132dSYangbo Lu struct sdhci_esdhc *esdhc = sdhci_pltfm_priv(pltfm_host); 103522dc132dSYangbo Lu u32 val; 103622dc132dSYangbo Lu int ret; 103722dc132dSYangbo Lu 103822dc132dSYangbo Lu /* Program TBPTR[TB_WNDW_END_PTR] and TBPTR[TB_WNDW_START_PTR] */ 103922dc132dSYangbo Lu val = ((u32)window_start << ESDHC_WNDW_STRT_PTR_SHIFT) & 104022dc132dSYangbo Lu ESDHC_WNDW_STRT_PTR_MASK; 104122dc132dSYangbo Lu val |= window_end & ESDHC_WNDW_END_PTR_MASK; 104222dc132dSYangbo Lu sdhci_writel(host, val, ESDHC_TBPTR); 104322dc132dSYangbo Lu 104422dc132dSYangbo Lu /* Program the software tuning mode by setting TBCTL[TB_MODE]=2'h3 */ 104522dc132dSYangbo Lu val = sdhci_readl(host, ESDHC_TBCTL); 104622dc132dSYangbo Lu val &= ~ESDHC_TB_MODE_MASK; 104722dc132dSYangbo Lu val |= ESDHC_TB_MODE_SW; 104822dc132dSYangbo Lu sdhci_writel(host, val, ESDHC_TBCTL); 104922dc132dSYangbo Lu 105022dc132dSYangbo Lu esdhc->in_sw_tuning = true; 105122dc132dSYangbo Lu ret = sdhci_execute_tuning(mmc, opcode); 105222dc132dSYangbo Lu esdhc->in_sw_tuning = false; 105322dc132dSYangbo Lu return ret; 105422dc132dSYangbo Lu } 105522dc132dSYangbo Lu 105654e08d9aSYangbo Lu static int esdhc_execute_tuning(struct mmc_host *mmc, u32 opcode) 105754e08d9aSYangbo Lu { 105854e08d9aSYangbo Lu struct sdhci_host *host = mmc_priv(mmc); 105954e08d9aSYangbo Lu struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); 106054e08d9aSYangbo Lu struct sdhci_esdhc *esdhc = sdhci_pltfm_priv(pltfm_host); 106122dc132dSYangbo Lu u8 window_start, window_end; 106222dc132dSYangbo Lu int ret, retries = 1; 106354e08d9aSYangbo Lu bool hs400_tuning; 106404509d77SYangbo Lu unsigned int clk; 106554e08d9aSYangbo Lu u32 val; 106654e08d9aSYangbo Lu 106704509d77SYangbo Lu /* For tuning mode, the sd clock divisor value 106804509d77SYangbo Lu * must be larger than 3 according to reference manual. 106904509d77SYangbo Lu */ 107004509d77SYangbo Lu clk = esdhc->peripheral_clock / 3; 107104509d77SYangbo Lu if (host->clock > clk) 107204509d77SYangbo Lu esdhc_of_set_clock(host, clk); 107304509d77SYangbo Lu 107454e08d9aSYangbo Lu esdhc_tuning_block_enable(host, true); 107554e08d9aSYangbo Lu 10760add6e9bSMichael Walle /* 10770add6e9bSMichael Walle * The eSDHC controller takes the data timeout value into account 10780add6e9bSMichael Walle * during tuning. If the SD card is too slow sending the response, the 10790add6e9bSMichael Walle * timer will expire and a "Buffer Read Ready" interrupt without data 10800add6e9bSMichael Walle * is triggered. This leads to tuning errors. 10810add6e9bSMichael Walle * 10820add6e9bSMichael Walle * Just set the timeout to the maximum value because the core will 10830add6e9bSMichael Walle * already take care of it in sdhci_send_tuning(). 10840add6e9bSMichael Walle */ 10850add6e9bSMichael Walle sdhci_writeb(host, 0xe, SDHCI_TIMEOUT_CONTROL); 10860add6e9bSMichael Walle 108754e08d9aSYangbo Lu hs400_tuning = host->flags & SDHCI_HS400_TUNING; 108854e08d9aSYangbo Lu 108922dc132dSYangbo Lu do { 109022dc132dSYangbo Lu if (esdhc->quirk_limited_clk_division && 109122dc132dSYangbo Lu hs400_tuning) 109222dc132dSYangbo Lu esdhc_of_set_clock(host, host->clock); 109322dc132dSYangbo Lu 109422dc132dSYangbo Lu /* Do HW tuning */ 109522dc132dSYangbo Lu val = sdhci_readl(host, ESDHC_TBCTL); 109622dc132dSYangbo Lu val &= ~ESDHC_TB_MODE_MASK; 109722dc132dSYangbo Lu val |= ESDHC_TB_MODE_3; 109822dc132dSYangbo Lu sdhci_writel(host, val, ESDHC_TBCTL); 109922dc132dSYangbo Lu 110022dc132dSYangbo Lu ret = sdhci_execute_tuning(mmc, opcode); 110122dc132dSYangbo Lu if (ret) 110222dc132dSYangbo Lu break; 110322dc132dSYangbo Lu 11045b742232SYangbo Lu /* For type2 affected platforms of the tuning erratum, 11055b742232SYangbo Lu * tuning may succeed although eSDHC might not have 11065b742232SYangbo Lu * tuned properly. Need to check tuning window. 11075b742232SYangbo Lu */ 11085b742232SYangbo Lu if (esdhc->quirk_tuning_erratum_type2 && 11095b742232SYangbo Lu !host->tuning_err) { 11105b742232SYangbo Lu esdhc_tuning_window_ptr(host, &window_start, 11115b742232SYangbo Lu &window_end); 11125b742232SYangbo Lu if (abs(window_start - window_end) > 11135b742232SYangbo Lu (4 * esdhc->div_ratio + 2)) 11145b742232SYangbo Lu host->tuning_err = -EAGAIN; 11155b742232SYangbo Lu } 11165b742232SYangbo Lu 111722dc132dSYangbo Lu /* If HW tuning fails and triggers erratum, 111822dc132dSYangbo Lu * try workaround. 111922dc132dSYangbo Lu */ 112022dc132dSYangbo Lu ret = host->tuning_err; 112122dc132dSYangbo Lu if (ret == -EAGAIN && 112222dc132dSYangbo Lu (esdhc->quirk_tuning_erratum_type1 || 112322dc132dSYangbo Lu esdhc->quirk_tuning_erratum_type2)) { 112422dc132dSYangbo Lu /* Recover HS400 tuning flag */ 112522dc132dSYangbo Lu if (hs400_tuning) 112622dc132dSYangbo Lu host->flags |= SDHCI_HS400_TUNING; 112722dc132dSYangbo Lu pr_info("%s: Hold on to use fixed sampling clock. Try SW tuning!\n", 112822dc132dSYangbo Lu mmc_hostname(mmc)); 112922dc132dSYangbo Lu /* Do SW tuning */ 113022dc132dSYangbo Lu esdhc_prepare_sw_tuning(host, &window_start, 113122dc132dSYangbo Lu &window_end); 113222dc132dSYangbo Lu ret = esdhc_execute_sw_tuning(mmc, opcode, 113322dc132dSYangbo Lu window_start, 113422dc132dSYangbo Lu window_end); 113522dc132dSYangbo Lu if (ret) 113622dc132dSYangbo Lu break; 113722dc132dSYangbo Lu 113822dc132dSYangbo Lu /* Retry both HW/SW tuning with reduced clock. */ 113922dc132dSYangbo Lu ret = host->tuning_err; 114022dc132dSYangbo Lu if (ret == -EAGAIN && retries) { 114122dc132dSYangbo Lu /* Recover HS400 tuning flag */ 114222dc132dSYangbo Lu if (hs400_tuning) 114322dc132dSYangbo Lu host->flags |= SDHCI_HS400_TUNING; 114422dc132dSYangbo Lu 114522dc132dSYangbo Lu clk = host->max_clk / (esdhc->div_ratio + 1); 114622dc132dSYangbo Lu esdhc_of_set_clock(host, clk); 114722dc132dSYangbo Lu pr_info("%s: Hold on to use fixed sampling clock. Try tuning with reduced clock!\n", 114822dc132dSYangbo Lu mmc_hostname(mmc)); 114922dc132dSYangbo Lu } else { 115022dc132dSYangbo Lu break; 115122dc132dSYangbo Lu } 115222dc132dSYangbo Lu } else { 115322dc132dSYangbo Lu break; 115422dc132dSYangbo Lu } 115522dc132dSYangbo Lu } while (retries--); 115622dc132dSYangbo Lu 115722dc132dSYangbo Lu if (ret) { 115822dc132dSYangbo Lu esdhc_tuning_block_enable(host, false); 115922dc132dSYangbo Lu } else if (hs400_tuning) { 116054e08d9aSYangbo Lu val = sdhci_readl(host, ESDHC_SDTIMNGCTL); 116154e08d9aSYangbo Lu val |= ESDHC_FLW_CTL_BG; 116254e08d9aSYangbo Lu sdhci_writel(host, val, ESDHC_SDTIMNGCTL); 116354e08d9aSYangbo Lu } 116454e08d9aSYangbo Lu 116554e08d9aSYangbo Lu return ret; 116654e08d9aSYangbo Lu } 116754e08d9aSYangbo Lu 116854e08d9aSYangbo Lu static void esdhc_set_uhs_signaling(struct sdhci_host *host, 116954e08d9aSYangbo Lu unsigned int timing) 117054e08d9aSYangbo Lu { 117147e9e107SYangbo Lu u32 val; 117247e9e107SYangbo Lu 117347e9e107SYangbo Lu /* 117447e9e107SYangbo Lu * There are specific registers setting for HS400 mode. 117547e9e107SYangbo Lu * Clean all of them if controller is in HS400 mode to 117647e9e107SYangbo Lu * exit HS400 mode before re-setting any speed mode. 117747e9e107SYangbo Lu */ 117847e9e107SYangbo Lu val = sdhci_readl(host, ESDHC_TBCTL); 117947e9e107SYangbo Lu if (val & ESDHC_HS400_MODE) { 118047e9e107SYangbo Lu val = sdhci_readl(host, ESDHC_SDTIMNGCTL); 118147e9e107SYangbo Lu val &= ~ESDHC_FLW_CTL_BG; 118247e9e107SYangbo Lu sdhci_writel(host, val, ESDHC_SDTIMNGCTL); 118347e9e107SYangbo Lu 118447e9e107SYangbo Lu val = sdhci_readl(host, ESDHC_SDCLKCTL); 118547e9e107SYangbo Lu val &= ~ESDHC_CMD_CLK_CTL; 118647e9e107SYangbo Lu sdhci_writel(host, val, ESDHC_SDCLKCTL); 118747e9e107SYangbo Lu 118847e9e107SYangbo Lu esdhc_clock_enable(host, false); 118947e9e107SYangbo Lu val = sdhci_readl(host, ESDHC_TBCTL); 119047e9e107SYangbo Lu val &= ~ESDHC_HS400_MODE; 119147e9e107SYangbo Lu sdhci_writel(host, val, ESDHC_TBCTL); 119247e9e107SYangbo Lu esdhc_clock_enable(host, true); 119347e9e107SYangbo Lu 119447e9e107SYangbo Lu val = sdhci_readl(host, ESDHC_DLLCFG0); 119547e9e107SYangbo Lu val &= ~(ESDHC_DLL_ENABLE | ESDHC_DLL_FREQ_SEL); 119647e9e107SYangbo Lu sdhci_writel(host, val, ESDHC_DLLCFG0); 119747e9e107SYangbo Lu 119847e9e107SYangbo Lu val = sdhci_readl(host, ESDHC_TBCTL); 119947e9e107SYangbo Lu val &= ~ESDHC_HS400_WNDW_ADJUST; 120047e9e107SYangbo Lu sdhci_writel(host, val, ESDHC_TBCTL); 120147e9e107SYangbo Lu 120247e9e107SYangbo Lu esdhc_tuning_block_enable(host, false); 120347e9e107SYangbo Lu } 120447e9e107SYangbo Lu 120554e08d9aSYangbo Lu if (timing == MMC_TIMING_MMC_HS400) 120654e08d9aSYangbo Lu esdhc_tuning_block_enable(host, true); 120754e08d9aSYangbo Lu else 120854e08d9aSYangbo Lu sdhci_set_uhs_signaling(host, timing); 1209ba49cbd0Syangbo lu } 1210ba49cbd0Syangbo lu 1211b214fe59SYinbo Zhu static u32 esdhc_irq(struct sdhci_host *host, u32 intmask) 1212b214fe59SYinbo Zhu { 1213060522d8SChris Packham struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); 1214060522d8SChris Packham struct sdhci_esdhc *esdhc = sdhci_pltfm_priv(pltfm_host); 1215b214fe59SYinbo Zhu u32 command; 1216b214fe59SYinbo Zhu 1217060522d8SChris Packham if (esdhc->quirk_trans_complete_erratum) { 1218b214fe59SYinbo Zhu command = SDHCI_GET_CMD(sdhci_readw(host, 1219b214fe59SYinbo Zhu SDHCI_COMMAND)); 1220b214fe59SYinbo Zhu if (command == MMC_WRITE_MULTIPLE_BLOCK && 1221b214fe59SYinbo Zhu sdhci_readw(host, SDHCI_BLOCK_COUNT) && 1222b214fe59SYinbo Zhu intmask & SDHCI_INT_DATA_END) { 1223b214fe59SYinbo Zhu intmask &= ~SDHCI_INT_DATA_END; 1224b214fe59SYinbo Zhu sdhci_writel(host, SDHCI_INT_DATA_END, 1225b214fe59SYinbo Zhu SDHCI_INT_STATUS); 1226b214fe59SYinbo Zhu } 1227b214fe59SYinbo Zhu } 1228b214fe59SYinbo Zhu return intmask; 1229b214fe59SYinbo Zhu } 1230b214fe59SYinbo Zhu 12319e48b336SUlf Hansson #ifdef CONFIG_PM_SLEEP 1232723f7924SRussell King static u32 esdhc_proctl; 1233723f7924SRussell King static int esdhc_of_suspend(struct device *dev) 1234723f7924SRussell King { 1235723f7924SRussell King struct sdhci_host *host = dev_get_drvdata(dev); 1236723f7924SRussell King 1237f4932cfdSyangbo lu esdhc_proctl = sdhci_readl(host, SDHCI_HOST_CONTROL); 1238723f7924SRussell King 1239d38dcad4SAdrian Hunter if (host->tuning_mode != SDHCI_TUNING_MODE_3) 1240d38dcad4SAdrian Hunter mmc_retune_needed(host->mmc); 1241d38dcad4SAdrian Hunter 1242723f7924SRussell King return sdhci_suspend_host(host); 1243723f7924SRussell King } 1244723f7924SRussell King 124506732b84SUlf Hansson static int esdhc_of_resume(struct device *dev) 1246723f7924SRussell King { 1247723f7924SRussell King struct sdhci_host *host = dev_get_drvdata(dev); 1248723f7924SRussell King int ret = sdhci_resume_host(host); 1249723f7924SRussell King 1250723f7924SRussell King if (ret == 0) { 1251723f7924SRussell King /* Isn't this already done by sdhci_resume_host() ? --rmk */ 1252723f7924SRussell King esdhc_of_enable_dma(host); 1253f4932cfdSyangbo lu sdhci_writel(host, esdhc_proctl, SDHCI_HOST_CONTROL); 1254723f7924SRussell King } 1255723f7924SRussell King return ret; 1256723f7924SRussell King } 1257723f7924SRussell King #endif 1258723f7924SRussell King 12599e48b336SUlf Hansson static SIMPLE_DEV_PM_OPS(esdhc_of_dev_pm_ops, 12609e48b336SUlf Hansson esdhc_of_suspend, 12619e48b336SUlf Hansson esdhc_of_resume); 12629e48b336SUlf Hansson 1263f4932cfdSyangbo lu static const struct sdhci_ops sdhci_esdhc_be_ops = { 1264f4932cfdSyangbo lu .read_l = esdhc_be_readl, 1265f4932cfdSyangbo lu .read_w = esdhc_be_readw, 1266f4932cfdSyangbo lu .read_b = esdhc_be_readb, 1267f4932cfdSyangbo lu .write_l = esdhc_be_writel, 1268f4932cfdSyangbo lu .write_w = esdhc_be_writew, 1269f4932cfdSyangbo lu .write_b = esdhc_be_writeb, 1270f4932cfdSyangbo lu .set_clock = esdhc_of_set_clock, 1271f4932cfdSyangbo lu .enable_dma = esdhc_of_enable_dma, 1272f4932cfdSyangbo lu .get_max_clock = esdhc_of_get_max_clock, 1273f4932cfdSyangbo lu .get_min_clock = esdhc_of_get_min_clock, 1274f4932cfdSyangbo lu .adma_workaround = esdhc_of_adma_workaround, 1275f4932cfdSyangbo lu .set_bus_width = esdhc_pltfm_set_bus_width, 1276f4932cfdSyangbo lu .reset = esdhc_reset, 127754e08d9aSYangbo Lu .set_uhs_signaling = esdhc_set_uhs_signaling, 1278b214fe59SYinbo Zhu .irq = esdhc_irq, 1279f4932cfdSyangbo lu }; 1280f4932cfdSyangbo lu 1281f4932cfdSyangbo lu static const struct sdhci_ops sdhci_esdhc_le_ops = { 1282f4932cfdSyangbo lu .read_l = esdhc_le_readl, 1283f4932cfdSyangbo lu .read_w = esdhc_le_readw, 1284f4932cfdSyangbo lu .read_b = esdhc_le_readb, 1285f4932cfdSyangbo lu .write_l = esdhc_le_writel, 1286f4932cfdSyangbo lu .write_w = esdhc_le_writew, 1287f4932cfdSyangbo lu .write_b = esdhc_le_writeb, 1288f4932cfdSyangbo lu .set_clock = esdhc_of_set_clock, 1289f4932cfdSyangbo lu .enable_dma = esdhc_of_enable_dma, 1290f4932cfdSyangbo lu .get_max_clock = esdhc_of_get_max_clock, 1291f4932cfdSyangbo lu .get_min_clock = esdhc_of_get_min_clock, 1292f4932cfdSyangbo lu .adma_workaround = esdhc_of_adma_workaround, 1293f4932cfdSyangbo lu .set_bus_width = esdhc_pltfm_set_bus_width, 1294f4932cfdSyangbo lu .reset = esdhc_reset, 129554e08d9aSYangbo Lu .set_uhs_signaling = esdhc_set_uhs_signaling, 1296b214fe59SYinbo Zhu .irq = esdhc_irq, 1297f4932cfdSyangbo lu }; 1298f4932cfdSyangbo lu 1299f4932cfdSyangbo lu static const struct sdhci_pltfm_data sdhci_esdhc_be_pdata = { 1300e9acc77dSyangbo lu .quirks = ESDHC_DEFAULT_QUIRKS | 1301e9acc77dSyangbo lu #ifdef CONFIG_PPC 1302e9acc77dSyangbo lu SDHCI_QUIRK_BROKEN_CARD_DETECTION | 1303e9acc77dSyangbo lu #endif 1304e9acc77dSyangbo lu SDHCI_QUIRK_NO_CARD_NO_RESET | 1305e9acc77dSyangbo lu SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC, 1306f4932cfdSyangbo lu .ops = &sdhci_esdhc_be_ops, 13077657c3a7SAlbert Herranz }; 130838576af1SShawn Guo 1309f4932cfdSyangbo lu static const struct sdhci_pltfm_data sdhci_esdhc_le_pdata = { 1310e9acc77dSyangbo lu .quirks = ESDHC_DEFAULT_QUIRKS | 1311e9acc77dSyangbo lu SDHCI_QUIRK_NO_CARD_NO_RESET | 1312e9acc77dSyangbo lu SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC, 1313f4932cfdSyangbo lu .ops = &sdhci_esdhc_le_ops, 1314f4932cfdSyangbo lu }; 1315f4932cfdSyangbo lu 1316151ede40Syangbo lu static struct soc_device_attribute soc_incorrect_hostver[] = { 1317151ede40Syangbo lu { .family = "QorIQ T4240", .revision = "1.0", }, 1318151ede40Syangbo lu { .family = "QorIQ T4240", .revision = "2.0", }, 1319151ede40Syangbo lu { }, 1320151ede40Syangbo lu }; 1321151ede40Syangbo lu 13226079e63cSYangbo Lu static struct soc_device_attribute soc_fixup_sdhc_clkdivs[] = { 13236079e63cSYangbo Lu { .family = "QorIQ LX2160A", .revision = "1.0", }, 13248e9a6919SYinbo Zhu { .family = "QorIQ LX2160A", .revision = "2.0", }, 13255f3ad196SYinbo Zhu { .family = "QorIQ LS1028A", .revision = "1.0", }, 13266079e63cSYangbo Lu { }, 13276079e63cSYangbo Lu }; 13286079e63cSYangbo Lu 132948e304ccSYangbo Lu static struct soc_device_attribute soc_unreliable_pulse_detection[] = { 133048e304ccSYangbo Lu { .family = "QorIQ LX2160A", .revision = "1.0", }, 133171b05327SYangbo Lu { .family = "QorIQ LX2160A", .revision = "2.0", }, 133271b05327SYangbo Lu { .family = "QorIQ LS1028A", .revision = "1.0", }, 133348e304ccSYangbo Lu { }, 133448e304ccSYangbo Lu }; 133548e304ccSYangbo Lu 1336f4932cfdSyangbo lu static void esdhc_init(struct platform_device *pdev, struct sdhci_host *host) 1337f4932cfdSyangbo lu { 133867fdfbdfSyinbo.zhu const struct of_device_id *match; 1339f4932cfdSyangbo lu struct sdhci_pltfm_host *pltfm_host; 1340f4932cfdSyangbo lu struct sdhci_esdhc *esdhc; 134119c3a0efSyangbo lu struct device_node *np; 134219c3a0efSyangbo lu struct clk *clk; 134319c3a0efSyangbo lu u32 val; 1344f4932cfdSyangbo lu u16 host_ver; 1345f4932cfdSyangbo lu 1346f4932cfdSyangbo lu pltfm_host = sdhci_priv(host); 13478605e7aeSJisheng Zhang esdhc = sdhci_pltfm_priv(pltfm_host); 1348f4932cfdSyangbo lu 1349f4932cfdSyangbo lu host_ver = sdhci_readw(host, SDHCI_HOST_VERSION); 1350f4932cfdSyangbo lu esdhc->vendor_ver = (host_ver & SDHCI_VENDOR_VER_MASK) >> 1351f4932cfdSyangbo lu SDHCI_VENDOR_VER_SHIFT; 1352f4932cfdSyangbo lu esdhc->spec_ver = host_ver & SDHCI_SPEC_VER_MASK; 1353151ede40Syangbo lu if (soc_device_match(soc_incorrect_hostver)) 1354151ede40Syangbo lu esdhc->quirk_incorrect_hostver = true; 1355151ede40Syangbo lu else 1356151ede40Syangbo lu esdhc->quirk_incorrect_hostver = false; 135719c3a0efSyangbo lu 13586079e63cSYangbo Lu if (soc_device_match(soc_fixup_sdhc_clkdivs)) 13596079e63cSYangbo Lu esdhc->quirk_limited_clk_division = true; 13606079e63cSYangbo Lu else 13616079e63cSYangbo Lu esdhc->quirk_limited_clk_division = false; 13626079e63cSYangbo Lu 136348e304ccSYangbo Lu if (soc_device_match(soc_unreliable_pulse_detection)) 136448e304ccSYangbo Lu esdhc->quirk_unreliable_pulse_detection = true; 136548e304ccSYangbo Lu else 136648e304ccSYangbo Lu esdhc->quirk_unreliable_pulse_detection = false; 136748e304ccSYangbo Lu 136867fdfbdfSyinbo.zhu match = of_match_node(sdhci_esdhc_of_match, pdev->dev.of_node); 136967fdfbdfSyinbo.zhu if (match) 137067fdfbdfSyinbo.zhu esdhc->clk_fixup = match->data; 137119c3a0efSyangbo lu np = pdev->dev.of_node; 1372f667216cSYangbo Lu 1373060522d8SChris Packham if (of_device_is_compatible(np, "fsl,p2020-esdhc")) { 1374f667216cSYangbo Lu esdhc->quirk_delay_before_data_reset = true; 1375060522d8SChris Packham esdhc->quirk_trans_complete_erratum = true; 1376060522d8SChris Packham } 1377f667216cSYangbo Lu 137819c3a0efSyangbo lu clk = of_clk_get(np, 0); 137919c3a0efSyangbo lu if (!IS_ERR(clk)) { 138019c3a0efSyangbo lu /* 138119c3a0efSyangbo lu * esdhc->peripheral_clock would be assigned with a value 138219c3a0efSyangbo lu * which is eSDHC base clock when use periperal clock. 1383791463baSYangbo Lu * For some platforms, the clock value got by common clk 1384791463baSYangbo Lu * API is peripheral clock while the eSDHC base clock is 1385791463baSYangbo Lu * 1/2 peripheral clock. 138619c3a0efSyangbo lu */ 1387791463baSYangbo Lu if (of_device_is_compatible(np, "fsl,ls1046a-esdhc") || 138866a83febSYangbo Lu of_device_is_compatible(np, "fsl,ls1028a-esdhc") || 138966a83febSYangbo Lu of_device_is_compatible(np, "fsl,ls1088a-esdhc")) 139019c3a0efSyangbo lu esdhc->peripheral_clock = clk_get_rate(clk) / 2; 139119c3a0efSyangbo lu else 139219c3a0efSyangbo lu esdhc->peripheral_clock = clk_get_rate(clk); 139319c3a0efSyangbo lu 139419c3a0efSyangbo lu clk_put(clk); 139519c3a0efSyangbo lu } 139619c3a0efSyangbo lu 139719c3a0efSyangbo lu esdhc_clock_enable(host, false); 139819c3a0efSyangbo lu val = sdhci_readl(host, ESDHC_DMA_SYSCTL); 1399975520fcSYangbo Lu /* 1400975520fcSYangbo Lu * This bit is not able to be reset by SDHCI_RESET_ALL. Need to 1401975520fcSYangbo Lu * initialize it as 1 or 0 once, to override the different value 1402975520fcSYangbo Lu * which may be configured in bootloader. 1403975520fcSYangbo Lu */ 1404975520fcSYangbo Lu if (esdhc->peripheral_clock) 140519c3a0efSyangbo lu val |= ESDHC_PERIPHERAL_CLK_SEL; 1406975520fcSYangbo Lu else 1407975520fcSYangbo Lu val &= ~ESDHC_PERIPHERAL_CLK_SEL; 140819c3a0efSyangbo lu sdhci_writel(host, val, ESDHC_DMA_SYSCTL); 140919c3a0efSyangbo lu esdhc_clock_enable(host, true); 141019c3a0efSyangbo lu } 1411f4932cfdSyangbo lu 141254e08d9aSYangbo Lu static int esdhc_hs400_prepare_ddr(struct mmc_host *mmc) 141354e08d9aSYangbo Lu { 141454e08d9aSYangbo Lu esdhc_tuning_block_enable(mmc_priv(mmc), false); 141554e08d9aSYangbo Lu return 0; 141654e08d9aSYangbo Lu } 141754e08d9aSYangbo Lu 1418c3be1efdSBill Pemberton static int sdhci_esdhc_probe(struct platform_device *pdev) 141938576af1SShawn Guo { 142066b50a00SOded Gabbay struct sdhci_host *host; 1421dcaff04dSOded Gabbay struct device_node *np; 14221ef5e49eSyangbo lu struct sdhci_pltfm_host *pltfm_host; 14231ef5e49eSyangbo lu struct sdhci_esdhc *esdhc; 142466b50a00SOded Gabbay int ret; 142566b50a00SOded Gabbay 1426f4932cfdSyangbo lu np = pdev->dev.of_node; 1427f4932cfdSyangbo lu 1428150d4240SJulia Lawall if (of_property_read_bool(np, "little-endian")) 14298605e7aeSJisheng Zhang host = sdhci_pltfm_init(pdev, &sdhci_esdhc_le_pdata, 14308605e7aeSJisheng Zhang sizeof(struct sdhci_esdhc)); 1431f4932cfdSyangbo lu else 14328605e7aeSJisheng Zhang host = sdhci_pltfm_init(pdev, &sdhci_esdhc_be_pdata, 14338605e7aeSJisheng Zhang sizeof(struct sdhci_esdhc)); 1434f4932cfdSyangbo lu 143566b50a00SOded Gabbay if (IS_ERR(host)) 143666b50a00SOded Gabbay return PTR_ERR(host); 143766b50a00SOded Gabbay 1438ea35645aSyangbo lu host->mmc_host_ops.start_signal_voltage_switch = 1439ea35645aSyangbo lu esdhc_signal_voltage_switch; 1440ba49cbd0Syangbo lu host->mmc_host_ops.execute_tuning = esdhc_execute_tuning; 144154e08d9aSYangbo Lu host->mmc_host_ops.hs400_prepare_ddr = esdhc_hs400_prepare_ddr; 14426b236f37Syangbo lu host->tuning_delay = 1; 1443ea35645aSyangbo lu 1444f4932cfdSyangbo lu esdhc_init(pdev, host); 1445f4932cfdSyangbo lu 144666b50a00SOded Gabbay sdhci_get_of_property(pdev); 144766b50a00SOded Gabbay 14481ef5e49eSyangbo lu pltfm_host = sdhci_priv(host); 14498605e7aeSJisheng Zhang esdhc = sdhci_pltfm_priv(pltfm_host); 145022dc132dSYangbo Lu if (soc_device_match(soc_tuning_erratum_type1)) 145122dc132dSYangbo Lu esdhc->quirk_tuning_erratum_type1 = true; 1452b1f378abSYinbo Zhu else 145322dc132dSYangbo Lu esdhc->quirk_tuning_erratum_type1 = false; 145422dc132dSYangbo Lu 145522dc132dSYangbo Lu if (soc_device_match(soc_tuning_erratum_type2)) 145622dc132dSYangbo Lu esdhc->quirk_tuning_erratum_type2 = true; 145722dc132dSYangbo Lu else 145822dc132dSYangbo Lu esdhc->quirk_tuning_erratum_type2 = false; 1459b1f378abSYinbo Zhu 14601ef5e49eSyangbo lu if (esdhc->vendor_ver == VENDOR_V_22) 14611ef5e49eSyangbo lu host->quirks2 |= SDHCI_QUIRK2_HOST_NO_CMD23; 14621ef5e49eSyangbo lu 14631ef5e49eSyangbo lu if (esdhc->vendor_ver > VENDOR_V_22) 14641ef5e49eSyangbo lu host->quirks &= ~SDHCI_QUIRK_NO_BUSY_IRQ; 14651ef5e49eSyangbo lu 146605cb6b2aSYinbo Zhu if (of_find_compatible_node(NULL, NULL, "fsl,p2020-esdhc")) { 1467fe0acab4SYangbo Lu host->quirks |= SDHCI_QUIRK_RESET_AFTER_REQUEST; 1468fe0acab4SYangbo Lu host->quirks |= SDHCI_QUIRK_BROKEN_TIMEOUT_VAL; 146905cb6b2aSYinbo Zhu } 1470a46e4271SYinbo Zhu 147174fd5e30SYangbo Lu if (of_device_is_compatible(np, "fsl,p5040-esdhc") || 147274fd5e30SYangbo Lu of_device_is_compatible(np, "fsl,p5020-esdhc") || 147374fd5e30SYangbo Lu of_device_is_compatible(np, "fsl,p4080-esdhc") || 147474fd5e30SYangbo Lu of_device_is_compatible(np, "fsl,p1020-esdhc") || 1475e9acc77dSyangbo lu of_device_is_compatible(np, "fsl,t1040-esdhc")) 147674fd5e30SYangbo Lu host->quirks &= ~SDHCI_QUIRK_BROKEN_CARD_DETECTION; 147774fd5e30SYangbo Lu 1478a22950c8Syangbo lu if (of_device_is_compatible(np, "fsl,ls1021a-esdhc")) 1479a22950c8Syangbo lu host->quirks |= SDHCI_QUIRK_BROKEN_TIMEOUT_VAL; 1480a22950c8Syangbo lu 14811f1929f3SYangbo Lu esdhc->quirk_ignore_data_inhibit = false; 1482dcaff04dSOded Gabbay if (of_device_is_compatible(np, "fsl,p2020-esdhc")) { 1483dcaff04dSOded Gabbay /* 1484dcaff04dSOded Gabbay * Freescale messed up with P2020 as it has a non-standard 1485dcaff04dSOded Gabbay * host control register 1486dcaff04dSOded Gabbay */ 1487dcaff04dSOded Gabbay host->quirks2 |= SDHCI_QUIRK2_BROKEN_HOST_CONTROL; 14881f1929f3SYangbo Lu esdhc->quirk_ignore_data_inhibit = true; 1489dcaff04dSOded Gabbay } 1490dcaff04dSOded Gabbay 149166b50a00SOded Gabbay /* call to generic mmc_of_parse to support additional capabilities */ 1492f0991408SUlf Hansson ret = mmc_of_parse(host->mmc); 1493f0991408SUlf Hansson if (ret) 1494f0991408SUlf Hansson goto err; 1495f0991408SUlf Hansson 14966dab809bSAndy Shevchenko mmc_of_parse_voltage(host->mmc, &host->ocr_mask); 149766b50a00SOded Gabbay 149866b50a00SOded Gabbay ret = sdhci_add_host(host); 149966b50a00SOded Gabbay if (ret) 1500f0991408SUlf Hansson goto err; 150166b50a00SOded Gabbay 1502f0991408SUlf Hansson return 0; 1503f0991408SUlf Hansson err: 1504f0991408SUlf Hansson sdhci_pltfm_free(pdev); 150566b50a00SOded Gabbay return ret; 150638576af1SShawn Guo } 150738576af1SShawn Guo 150838576af1SShawn Guo static struct platform_driver sdhci_esdhc_driver = { 150938576af1SShawn Guo .driver = { 151038576af1SShawn Guo .name = "sdhci-esdhc", 151121b2cec6SDouglas Anderson .probe_type = PROBE_PREFER_ASYNCHRONOUS, 151238576af1SShawn Guo .of_match_table = sdhci_esdhc_of_match, 15139e48b336SUlf Hansson .pm = &esdhc_of_dev_pm_ops, 151438576af1SShawn Guo }, 151538576af1SShawn Guo .probe = sdhci_esdhc_probe, 1516caebcae9SKevin Hao .remove = sdhci_pltfm_unregister, 151738576af1SShawn Guo }; 151838576af1SShawn Guo 1519d1f81a64SAxel Lin module_platform_driver(sdhci_esdhc_driver); 152038576af1SShawn Guo 152138576af1SShawn Guo MODULE_DESCRIPTION("SDHCI OF driver for Freescale MPC eSDHC"); 152238576af1SShawn Guo MODULE_AUTHOR("Xiaobo Xie <X.Xie@freescale.com>, " 152338576af1SShawn Guo "Anton Vorontsov <avorontsov@ru.mvista.com>"); 152438576af1SShawn Guo MODULE_LICENSE("GPL v2"); 1525