1d2912cb1SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only 21c6a0718SPierre Ossman /* 370f10482SPierre Ossman * linux/drivers/mmc/host/mmci.c - ARM PrimeCell MMCI PL180/1 driver 41c6a0718SPierre Ossman * 51c6a0718SPierre Ossman * Copyright (C) 2003 Deep Blue Solutions, Ltd, All Rights Reserved. 6c8ebae37SRussell King * Copyright (C) 2010 ST-Ericsson SA 71c6a0718SPierre Ossman */ 81c6a0718SPierre Ossman #include <linux/module.h> 91c6a0718SPierre Ossman #include <linux/moduleparam.h> 101c6a0718SPierre Ossman #include <linux/init.h> 111c6a0718SPierre Ossman #include <linux/ioport.h> 121c6a0718SPierre Ossman #include <linux/device.h> 13ef289982SUlf Hansson #include <linux/io.h> 141c6a0718SPierre Ossman #include <linux/interrupt.h> 15613b152cSRussell King #include <linux/kernel.h> 16000bc9d5SLee Jones #include <linux/slab.h> 171c6a0718SPierre Ossman #include <linux/delay.h> 181c6a0718SPierre Ossman #include <linux/err.h> 191c6a0718SPierre Ossman #include <linux/highmem.h> 20019a5f56SNicolas Pitre #include <linux/log2.h> 21c8073e52SLudovic Barre #include <linux/mmc/mmc.h> 2270be208fSUlf Hansson #include <linux/mmc/pm.h> 231c6a0718SPierre Ossman #include <linux/mmc/host.h> 2434177802SLinus Walleij #include <linux/mmc/card.h> 25d2762090SUlf Hansson #include <linux/mmc/slot-gpio.h> 261c6a0718SPierre Ossman #include <linux/amba/bus.h> 271c6a0718SPierre Ossman #include <linux/clk.h> 28bd6dee6fSJens Axboe #include <linux/scatterlist.h> 299ef986a6SLinus Walleij #include <linux/of.h> 3034e84f39SLinus Walleij #include <linux/regulator/consumer.h> 31c8ebae37SRussell King #include <linux/dmaengine.h> 32c8ebae37SRussell King #include <linux/dma-mapping.h> 33c8ebae37SRussell King #include <linux/amba/mmci.h> 341c3be369SRussell King #include <linux/pm_runtime.h> 35258aea76SViresh Kumar #include <linux/types.h> 36a9a83785SLinus Walleij #include <linux/pinctrl/consumer.h> 3715878e58SLudovic Barre #include <linux/reset.h> 381c6a0718SPierre Ossman 391c6a0718SPierre Ossman #include <asm/div64.h> 401c6a0718SPierre Ossman #include <asm/io.h> 411c6a0718SPierre Ossman 421c6a0718SPierre Ossman #include "mmci.h" 431c6a0718SPierre Ossman 441c6a0718SPierre Ossman #define DRIVER_NAME "mmci-pl18x" 451c6a0718SPierre Ossman 4671953e0eSUlf Hansson static void mmci_variant_init(struct mmci_host *host); 47cb0335b7SLudovic Barre static void ux500_variant_init(struct mmci_host *host); 48b3fb9d64SLudovic Barre static void ux500v2_variant_init(struct mmci_host *host); 49c3647fdcSLudovic Barre 501c6a0718SPierre Ossman static unsigned int fmax = 515633; 511c6a0718SPierre Ossman 524956e109SRabin Vincent static struct variant_data variant_arm = { 538301bb68SRabin Vincent .fifosize = 16 * 4, 548301bb68SRabin Vincent .fifohalfsize = 8 * 4, 550f244804SLudovic Barre .cmdreg_cpsm_enable = MCI_CPSM_ENABLE, 560f244804SLudovic Barre .cmdreg_lrsp_crc = MCI_CPSM_RESPONSE | MCI_CPSM_LONGRSP, 570f244804SLudovic Barre .cmdreg_srsp_crc = MCI_CPSM_RESPONSE, 580f244804SLudovic Barre .cmdreg_srsp = MCI_CPSM_RESPONSE, 5908458ef6SRabin Vincent .datalength_bits = 16, 60c931d495SLudovic Barre .datactrl_blocksz = 11, 617d72a1d4SUlf Hansson .pwrreg_powerup = MCI_PWR_UP, 62dc6500bfSSrinivas Kandagatla .f_max = 100000000, 637878289bSUlf Hansson .reversed_irq_handling = true, 646ea9cdf3SPatrice Chotard .mmcimask1 = true, 6559db5e2dSLudovic Barre .irq_pio_mask = MCI_IRQ_PIO_MASK, 667f7b5503SPatrice Chotard .start_err = MCI_STARTBITERR, 6711dfb970SPatrice Chotard .opendrain = MCI_ROD, 68c3647fdcSLudovic Barre .init = mmci_variant_init, 694956e109SRabin Vincent }; 704956e109SRabin Vincent 71768fbc18SPawel Moll static struct variant_data variant_arm_extended_fifo = { 72768fbc18SPawel Moll .fifosize = 128 * 4, 73768fbc18SPawel Moll .fifohalfsize = 64 * 4, 740f244804SLudovic Barre .cmdreg_cpsm_enable = MCI_CPSM_ENABLE, 750f244804SLudovic Barre .cmdreg_lrsp_crc = MCI_CPSM_RESPONSE | MCI_CPSM_LONGRSP, 760f244804SLudovic Barre .cmdreg_srsp_crc = MCI_CPSM_RESPONSE, 770f244804SLudovic Barre .cmdreg_srsp = MCI_CPSM_RESPONSE, 78768fbc18SPawel Moll .datalength_bits = 16, 79c931d495SLudovic Barre .datactrl_blocksz = 11, 807d72a1d4SUlf Hansson .pwrreg_powerup = MCI_PWR_UP, 81dc6500bfSSrinivas Kandagatla .f_max = 100000000, 826ea9cdf3SPatrice Chotard .mmcimask1 = true, 8359db5e2dSLudovic Barre .irq_pio_mask = MCI_IRQ_PIO_MASK, 847f7b5503SPatrice Chotard .start_err = MCI_STARTBITERR, 8511dfb970SPatrice Chotard .opendrain = MCI_ROD, 86c3647fdcSLudovic Barre .init = mmci_variant_init, 87768fbc18SPawel Moll }; 88768fbc18SPawel Moll 893a37298aSPawel Moll static struct variant_data variant_arm_extended_fifo_hwfc = { 903a37298aSPawel Moll .fifosize = 128 * 4, 913a37298aSPawel Moll .fifohalfsize = 64 * 4, 923a37298aSPawel Moll .clkreg_enable = MCI_ARM_HWFCEN, 930f244804SLudovic Barre .cmdreg_cpsm_enable = MCI_CPSM_ENABLE, 940f244804SLudovic Barre .cmdreg_lrsp_crc = MCI_CPSM_RESPONSE | MCI_CPSM_LONGRSP, 950f244804SLudovic Barre .cmdreg_srsp_crc = MCI_CPSM_RESPONSE, 960f244804SLudovic Barre .cmdreg_srsp = MCI_CPSM_RESPONSE, 973a37298aSPawel Moll .datalength_bits = 16, 98c931d495SLudovic Barre .datactrl_blocksz = 11, 993a37298aSPawel Moll .pwrreg_powerup = MCI_PWR_UP, 100dc6500bfSSrinivas Kandagatla .f_max = 100000000, 1016ea9cdf3SPatrice Chotard .mmcimask1 = true, 10259db5e2dSLudovic Barre .irq_pio_mask = MCI_IRQ_PIO_MASK, 1037f7b5503SPatrice Chotard .start_err = MCI_STARTBITERR, 10411dfb970SPatrice Chotard .opendrain = MCI_ROD, 105c3647fdcSLudovic Barre .init = mmci_variant_init, 1063a37298aSPawel Moll }; 1073a37298aSPawel Moll 1084956e109SRabin Vincent static struct variant_data variant_u300 = { 1098301bb68SRabin Vincent .fifosize = 16 * 4, 1108301bb68SRabin Vincent .fifohalfsize = 8 * 4, 11149ac215eSLinus Walleij .clkreg_enable = MCI_ST_U300_HWFCEN, 112e1412d85SSrinivas Kandagatla .clkreg_8bit_bus_enable = MCI_ST_8BIT_BUS, 1130f244804SLudovic Barre .cmdreg_cpsm_enable = MCI_CPSM_ENABLE, 1140f244804SLudovic Barre .cmdreg_lrsp_crc = MCI_CPSM_RESPONSE | MCI_CPSM_LONGRSP, 1150f244804SLudovic Barre .cmdreg_srsp_crc = MCI_CPSM_RESPONSE, 1160f244804SLudovic Barre .cmdreg_srsp = MCI_CPSM_RESPONSE, 11708458ef6SRabin Vincent .datalength_bits = 16, 118c931d495SLudovic Barre .datactrl_blocksz = 11, 1195db3eee7SLinus Walleij .datactrl_mask_sdio = MCI_DPSM_ST_SDIOEN, 120c7354133SSrinivas Kandagatla .st_sdio = true, 1217d72a1d4SUlf Hansson .pwrreg_powerup = MCI_PWR_ON, 122dc6500bfSSrinivas Kandagatla .f_max = 100000000, 1234d1a3a0dSUlf Hansson .signal_direction = true, 124f4670daeSUlf Hansson .pwrreg_clkgate = true, 1251ff44433SUlf Hansson .pwrreg_nopower = true, 1266ea9cdf3SPatrice Chotard .mmcimask1 = true, 12759db5e2dSLudovic Barre .irq_pio_mask = MCI_IRQ_PIO_MASK, 1287f7b5503SPatrice Chotard .start_err = MCI_STARTBITERR, 12911dfb970SPatrice Chotard .opendrain = MCI_OD, 130c3647fdcSLudovic Barre .init = mmci_variant_init, 1314956e109SRabin Vincent }; 1324956e109SRabin Vincent 13334fd4213SLinus Walleij static struct variant_data variant_nomadik = { 13434fd4213SLinus Walleij .fifosize = 16 * 4, 13534fd4213SLinus Walleij .fifohalfsize = 8 * 4, 13634fd4213SLinus Walleij .clkreg = MCI_CLK_ENABLE, 137f5abc767SLinus Walleij .clkreg_8bit_bus_enable = MCI_ST_8BIT_BUS, 1380f244804SLudovic Barre .cmdreg_cpsm_enable = MCI_CPSM_ENABLE, 1390f244804SLudovic Barre .cmdreg_lrsp_crc = MCI_CPSM_RESPONSE | MCI_CPSM_LONGRSP, 1400f244804SLudovic Barre .cmdreg_srsp_crc = MCI_CPSM_RESPONSE, 1410f244804SLudovic Barre .cmdreg_srsp = MCI_CPSM_RESPONSE, 14234fd4213SLinus Walleij .datalength_bits = 24, 143c931d495SLudovic Barre .datactrl_blocksz = 11, 1445db3eee7SLinus Walleij .datactrl_mask_sdio = MCI_DPSM_ST_SDIOEN, 145c7354133SSrinivas Kandagatla .st_sdio = true, 14634fd4213SLinus Walleij .st_clkdiv = true, 14734fd4213SLinus Walleij .pwrreg_powerup = MCI_PWR_ON, 148dc6500bfSSrinivas Kandagatla .f_max = 100000000, 14934fd4213SLinus Walleij .signal_direction = true, 150f4670daeSUlf Hansson .pwrreg_clkgate = true, 1511ff44433SUlf Hansson .pwrreg_nopower = true, 1526ea9cdf3SPatrice Chotard .mmcimask1 = true, 15359db5e2dSLudovic Barre .irq_pio_mask = MCI_IRQ_PIO_MASK, 1547f7b5503SPatrice Chotard .start_err = MCI_STARTBITERR, 15511dfb970SPatrice Chotard .opendrain = MCI_OD, 156c3647fdcSLudovic Barre .init = mmci_variant_init, 15734fd4213SLinus Walleij }; 15834fd4213SLinus Walleij 1594956e109SRabin Vincent static struct variant_data variant_ux500 = { 1608301bb68SRabin Vincent .fifosize = 30 * 4, 1618301bb68SRabin Vincent .fifohalfsize = 8 * 4, 1624956e109SRabin Vincent .clkreg = MCI_CLK_ENABLE, 16349ac215eSLinus Walleij .clkreg_enable = MCI_ST_UX500_HWFCEN, 164e1412d85SSrinivas Kandagatla .clkreg_8bit_bus_enable = MCI_ST_8BIT_BUS, 165e8740644SSrinivas Kandagatla .clkreg_neg_edge_enable = MCI_ST_UX500_NEG_EDGE, 1660f244804SLudovic Barre .cmdreg_cpsm_enable = MCI_CPSM_ENABLE, 1670f244804SLudovic Barre .cmdreg_lrsp_crc = MCI_CPSM_RESPONSE | MCI_CPSM_LONGRSP, 1680f244804SLudovic Barre .cmdreg_srsp_crc = MCI_CPSM_RESPONSE, 1690f244804SLudovic Barre .cmdreg_srsp = MCI_CPSM_RESPONSE, 17008458ef6SRabin Vincent .datalength_bits = 24, 171c931d495SLudovic Barre .datactrl_blocksz = 11, 1725db3eee7SLinus Walleij .datactrl_mask_sdio = MCI_DPSM_ST_SDIOEN, 173c7354133SSrinivas Kandagatla .st_sdio = true, 174b70a67f9SLinus Walleij .st_clkdiv = true, 1757d72a1d4SUlf Hansson .pwrreg_powerup = MCI_PWR_ON, 176dc6500bfSSrinivas Kandagatla .f_max = 100000000, 1774d1a3a0dSUlf Hansson .signal_direction = true, 178f4670daeSUlf Hansson .pwrreg_clkgate = true, 17901259620SUlf Hansson .busy_detect = true, 18049adc0caSLinus Walleij .busy_dpsm_flag = MCI_DPSM_ST_BUSYMODE, 18149adc0caSLinus Walleij .busy_detect_flag = MCI_ST_CARDBUSY, 18249adc0caSLinus Walleij .busy_detect_mask = MCI_ST_BUSYENDMASK, 1831ff44433SUlf Hansson .pwrreg_nopower = true, 1846ea9cdf3SPatrice Chotard .mmcimask1 = true, 18559db5e2dSLudovic Barre .irq_pio_mask = MCI_IRQ_PIO_MASK, 1867f7b5503SPatrice Chotard .start_err = MCI_STARTBITERR, 18711dfb970SPatrice Chotard .opendrain = MCI_OD, 188cb0335b7SLudovic Barre .init = ux500_variant_init, 1894956e109SRabin Vincent }; 190b70a67f9SLinus Walleij 1911784b157SPhilippe Langlais static struct variant_data variant_ux500v2 = { 1921784b157SPhilippe Langlais .fifosize = 30 * 4, 1931784b157SPhilippe Langlais .fifohalfsize = 8 * 4, 1941784b157SPhilippe Langlais .clkreg = MCI_CLK_ENABLE, 1951784b157SPhilippe Langlais .clkreg_enable = MCI_ST_UX500_HWFCEN, 196e1412d85SSrinivas Kandagatla .clkreg_8bit_bus_enable = MCI_ST_8BIT_BUS, 197e8740644SSrinivas Kandagatla .clkreg_neg_edge_enable = MCI_ST_UX500_NEG_EDGE, 1980f244804SLudovic Barre .cmdreg_cpsm_enable = MCI_CPSM_ENABLE, 1990f244804SLudovic Barre .cmdreg_lrsp_crc = MCI_CPSM_RESPONSE | MCI_CPSM_LONGRSP, 2000f244804SLudovic Barre .cmdreg_srsp_crc = MCI_CPSM_RESPONSE, 2010f244804SLudovic Barre .cmdreg_srsp = MCI_CPSM_RESPONSE, 2025db3eee7SLinus Walleij .datactrl_mask_ddrmode = MCI_DPSM_ST_DDRMODE, 2031784b157SPhilippe Langlais .datalength_bits = 24, 204c931d495SLudovic Barre .datactrl_blocksz = 11, 2055db3eee7SLinus Walleij .datactrl_mask_sdio = MCI_DPSM_ST_SDIOEN, 206c7354133SSrinivas Kandagatla .st_sdio = true, 2071784b157SPhilippe Langlais .st_clkdiv = true, 2087d72a1d4SUlf Hansson .pwrreg_powerup = MCI_PWR_ON, 209dc6500bfSSrinivas Kandagatla .f_max = 100000000, 2104d1a3a0dSUlf Hansson .signal_direction = true, 211f4670daeSUlf Hansson .pwrreg_clkgate = true, 21201259620SUlf Hansson .busy_detect = true, 21349adc0caSLinus Walleij .busy_dpsm_flag = MCI_DPSM_ST_BUSYMODE, 21449adc0caSLinus Walleij .busy_detect_flag = MCI_ST_CARDBUSY, 21549adc0caSLinus Walleij .busy_detect_mask = MCI_ST_BUSYENDMASK, 2161ff44433SUlf Hansson .pwrreg_nopower = true, 2176ea9cdf3SPatrice Chotard .mmcimask1 = true, 21859db5e2dSLudovic Barre .irq_pio_mask = MCI_IRQ_PIO_MASK, 2197f7b5503SPatrice Chotard .start_err = MCI_STARTBITERR, 22011dfb970SPatrice Chotard .opendrain = MCI_OD, 221b3fb9d64SLudovic Barre .init = ux500v2_variant_init, 2221784b157SPhilippe Langlais }; 2231784b157SPhilippe Langlais 2242a9d6c80SPatrice Chotard static struct variant_data variant_stm32 = { 2252a9d6c80SPatrice Chotard .fifosize = 32 * 4, 2262a9d6c80SPatrice Chotard .fifohalfsize = 8 * 4, 2272a9d6c80SPatrice Chotard .clkreg = MCI_CLK_ENABLE, 2282a9d6c80SPatrice Chotard .clkreg_enable = MCI_ST_UX500_HWFCEN, 2292a9d6c80SPatrice Chotard .clkreg_8bit_bus_enable = MCI_ST_8BIT_BUS, 2302a9d6c80SPatrice Chotard .clkreg_neg_edge_enable = MCI_ST_UX500_NEG_EDGE, 2310f244804SLudovic Barre .cmdreg_cpsm_enable = MCI_CPSM_ENABLE, 2320f244804SLudovic Barre .cmdreg_lrsp_crc = MCI_CPSM_RESPONSE | MCI_CPSM_LONGRSP, 2330f244804SLudovic Barre .cmdreg_srsp_crc = MCI_CPSM_RESPONSE, 2340f244804SLudovic Barre .cmdreg_srsp = MCI_CPSM_RESPONSE, 23559db5e2dSLudovic Barre .irq_pio_mask = MCI_IRQ_PIO_MASK, 2362a9d6c80SPatrice Chotard .datalength_bits = 24, 237c931d495SLudovic Barre .datactrl_blocksz = 11, 2382a9d6c80SPatrice Chotard .datactrl_mask_sdio = MCI_DPSM_ST_SDIOEN, 2392a9d6c80SPatrice Chotard .st_sdio = true, 2402a9d6c80SPatrice Chotard .st_clkdiv = true, 2412a9d6c80SPatrice Chotard .pwrreg_powerup = MCI_PWR_ON, 2422a9d6c80SPatrice Chotard .f_max = 48000000, 2432a9d6c80SPatrice Chotard .pwrreg_clkgate = true, 2442a9d6c80SPatrice Chotard .pwrreg_nopower = true, 245c3647fdcSLudovic Barre .init = mmci_variant_init, 2462a9d6c80SPatrice Chotard }; 2472a9d6c80SPatrice Chotard 24846b723ddSLudovic Barre static struct variant_data variant_stm32_sdmmc = { 24946b723ddSLudovic Barre .fifosize = 16 * 4, 25046b723ddSLudovic Barre .fifohalfsize = 8 * 4, 25146b723ddSLudovic Barre .f_max = 208000000, 25246b723ddSLudovic Barre .stm32_clkdiv = true, 25346b723ddSLudovic Barre .cmdreg_cpsm_enable = MCI_CPSM_STM32_ENABLE, 25446b723ddSLudovic Barre .cmdreg_lrsp_crc = MCI_CPSM_STM32_LRSP_CRC, 25546b723ddSLudovic Barre .cmdreg_srsp_crc = MCI_CPSM_STM32_SRSP_CRC, 25646b723ddSLudovic Barre .cmdreg_srsp = MCI_CPSM_STM32_SRSP, 257c8073e52SLudovic Barre .cmdreg_stop = MCI_CPSM_STM32_CMDSTOP, 25846b723ddSLudovic Barre .data_cmd_enable = MCI_CPSM_STM32_CMDTRANS, 25946b723ddSLudovic Barre .irq_pio_mask = MCI_IRQ_PIO_STM32_MASK, 26046b723ddSLudovic Barre .datactrl_first = true, 26146b723ddSLudovic Barre .datacnt_useless = true, 26246b723ddSLudovic Barre .datalength_bits = 25, 26346b723ddSLudovic Barre .datactrl_blocksz = 14, 26446b723ddSLudovic Barre .stm32_idmabsize_mask = GENMASK(12, 5), 26546b723ddSLudovic Barre .init = sdmmc_variant_init, 26646b723ddSLudovic Barre }; 26746b723ddSLudovic Barre 26855b604aeSSrinivas Kandagatla static struct variant_data variant_qcom = { 26955b604aeSSrinivas Kandagatla .fifosize = 16 * 4, 27055b604aeSSrinivas Kandagatla .fifohalfsize = 8 * 4, 27155b604aeSSrinivas Kandagatla .clkreg = MCI_CLK_ENABLE, 27255b604aeSSrinivas Kandagatla .clkreg_enable = MCI_QCOM_CLK_FLOWENA | 27355b604aeSSrinivas Kandagatla MCI_QCOM_CLK_SELECT_IN_FBCLK, 27455b604aeSSrinivas Kandagatla .clkreg_8bit_bus_enable = MCI_QCOM_CLK_WIDEBUS_8, 27555b604aeSSrinivas Kandagatla .datactrl_mask_ddrmode = MCI_QCOM_CLK_SELECT_IN_DDR_MODE, 2760f244804SLudovic Barre .cmdreg_cpsm_enable = MCI_CPSM_ENABLE, 2770f244804SLudovic Barre .cmdreg_lrsp_crc = MCI_CPSM_RESPONSE | MCI_CPSM_LONGRSP, 2780f244804SLudovic Barre .cmdreg_srsp_crc = MCI_CPSM_RESPONSE, 2790f244804SLudovic Barre .cmdreg_srsp = MCI_CPSM_RESPONSE, 2805db3eee7SLinus Walleij .data_cmd_enable = MCI_CPSM_QCOM_DATCMD, 28155b604aeSSrinivas Kandagatla .datalength_bits = 24, 282c931d495SLudovic Barre .datactrl_blocksz = 11, 28355b604aeSSrinivas Kandagatla .pwrreg_powerup = MCI_PWR_UP, 28455b604aeSSrinivas Kandagatla .f_max = 208000000, 28555b604aeSSrinivas Kandagatla .explicit_mclk_control = true, 28655b604aeSSrinivas Kandagatla .qcom_fifo = true, 2879cb15142SSrinivas Kandagatla .qcom_dml = true, 2886ea9cdf3SPatrice Chotard .mmcimask1 = true, 28959db5e2dSLudovic Barre .irq_pio_mask = MCI_IRQ_PIO_MASK, 2907f7b5503SPatrice Chotard .start_err = MCI_STARTBITERR, 29111dfb970SPatrice Chotard .opendrain = MCI_ROD, 29229aba07aSUlf Hansson .init = qcom_variant_init, 29355b604aeSSrinivas Kandagatla }; 29455b604aeSSrinivas Kandagatla 29549adc0caSLinus Walleij /* Busy detection for the ST Micro variant */ 29601259620SUlf Hansson static int mmci_card_busy(struct mmc_host *mmc) 29701259620SUlf Hansson { 29801259620SUlf Hansson struct mmci_host *host = mmc_priv(mmc); 29901259620SUlf Hansson unsigned long flags; 30001259620SUlf Hansson int busy = 0; 30101259620SUlf Hansson 30201259620SUlf Hansson spin_lock_irqsave(&host->lock, flags); 30349adc0caSLinus Walleij if (readl(host->base + MMCISTATUS) & host->variant->busy_detect_flag) 30401259620SUlf Hansson busy = 1; 30501259620SUlf Hansson spin_unlock_irqrestore(&host->lock, flags); 30601259620SUlf Hansson 30701259620SUlf Hansson return busy; 30801259620SUlf Hansson } 30901259620SUlf Hansson 310f829c042SUlf Hansson static void mmci_reg_delay(struct mmci_host *host) 311f829c042SUlf Hansson { 312f829c042SUlf Hansson /* 313f829c042SUlf Hansson * According to the spec, at least three feedback clock cycles 314f829c042SUlf Hansson * of max 52 MHz must pass between two writes to the MMCICLOCK reg. 315f829c042SUlf Hansson * Three MCLK clock cycles must pass between two MMCIPOWER reg writes. 316f829c042SUlf Hansson * Worst delay time during card init is at 100 kHz => 30 us. 317f829c042SUlf Hansson * Worst delay time when up and running is at 25 MHz => 120 ns. 318f829c042SUlf Hansson */ 319f829c042SUlf Hansson if (host->cclk < 25000000) 320f829c042SUlf Hansson udelay(30); 321f829c042SUlf Hansson else 322f829c042SUlf Hansson ndelay(120); 323f829c042SUlf Hansson } 324f829c042SUlf Hansson 325653a761eSUlf Hansson /* 326a6a6464aSLinus Walleij * This must be called with host->lock held 327a6a6464aSLinus Walleij */ 328cd3ee8c5SLudovic Barre void mmci_write_clkreg(struct mmci_host *host, u32 clk) 3297437cfa5SUlf Hansson { 3307437cfa5SUlf Hansson if (host->clk_reg != clk) { 3317437cfa5SUlf Hansson host->clk_reg = clk; 3327437cfa5SUlf Hansson writel(clk, host->base + MMCICLOCK); 3337437cfa5SUlf Hansson } 3347437cfa5SUlf Hansson } 3357437cfa5SUlf Hansson 3367437cfa5SUlf Hansson /* 3377437cfa5SUlf Hansson * This must be called with host->lock held 3387437cfa5SUlf Hansson */ 339cd3ee8c5SLudovic Barre void mmci_write_pwrreg(struct mmci_host *host, u32 pwr) 3407437cfa5SUlf Hansson { 3417437cfa5SUlf Hansson if (host->pwr_reg != pwr) { 3427437cfa5SUlf Hansson host->pwr_reg = pwr; 3437437cfa5SUlf Hansson writel(pwr, host->base + MMCIPOWER); 3447437cfa5SUlf Hansson } 3457437cfa5SUlf Hansson } 3467437cfa5SUlf Hansson 3477437cfa5SUlf Hansson /* 3487437cfa5SUlf Hansson * This must be called with host->lock held 3497437cfa5SUlf Hansson */ 3509cc639a2SUlf Hansson static void mmci_write_datactrlreg(struct mmci_host *host, u32 datactrl) 3519cc639a2SUlf Hansson { 35249adc0caSLinus Walleij /* Keep busy mode in DPSM if enabled */ 35349adc0caSLinus Walleij datactrl |= host->datactrl_reg & host->variant->busy_dpsm_flag; 35401259620SUlf Hansson 3559cc639a2SUlf Hansson if (host->datactrl_reg != datactrl) { 3569cc639a2SUlf Hansson host->datactrl_reg = datactrl; 3579cc639a2SUlf Hansson writel(datactrl, host->base + MMCIDATACTRL); 3589cc639a2SUlf Hansson } 3599cc639a2SUlf Hansson } 3609cc639a2SUlf Hansson 3619cc639a2SUlf Hansson /* 3629cc639a2SUlf Hansson * This must be called with host->lock held 3639cc639a2SUlf Hansson */ 364a6a6464aSLinus Walleij static void mmci_set_clkreg(struct mmci_host *host, unsigned int desired) 365a6a6464aSLinus Walleij { 3664956e109SRabin Vincent struct variant_data *variant = host->variant; 3674956e109SRabin Vincent u32 clk = variant->clkreg; 368a6a6464aSLinus Walleij 369c58a8509SUlf Hansson /* Make sure cclk reflects the current calculated clock */ 370c58a8509SUlf Hansson host->cclk = 0; 371c58a8509SUlf Hansson 372a6a6464aSLinus Walleij if (desired) { 3733f4e6f7bSSrinivas Kandagatla if (variant->explicit_mclk_control) { 3743f4e6f7bSSrinivas Kandagatla host->cclk = host->mclk; 3753f4e6f7bSSrinivas Kandagatla } else if (desired >= host->mclk) { 376a6a6464aSLinus Walleij clk = MCI_CLK_BYPASS; 377399bc486SLinus Walleij if (variant->st_clkdiv) 378399bc486SLinus Walleij clk |= MCI_ST_UX500_NEG_EDGE; 379a6a6464aSLinus Walleij host->cclk = host->mclk; 380b70a67f9SLinus Walleij } else if (variant->st_clkdiv) { 381b70a67f9SLinus Walleij /* 382b70a67f9SLinus Walleij * DB8500 TRM says f = mclk / (clkdiv + 2) 383b70a67f9SLinus Walleij * => clkdiv = (mclk / f) - 2 384b70a67f9SLinus Walleij * Round the divider up so we don't exceed the max 385b70a67f9SLinus Walleij * frequency 386b70a67f9SLinus Walleij */ 387b70a67f9SLinus Walleij clk = DIV_ROUND_UP(host->mclk, desired) - 2; 388b70a67f9SLinus Walleij if (clk >= 256) 389b70a67f9SLinus Walleij clk = 255; 390b70a67f9SLinus Walleij host->cclk = host->mclk / (clk + 2); 391a6a6464aSLinus Walleij } else { 392b70a67f9SLinus Walleij /* 393b70a67f9SLinus Walleij * PL180 TRM says f = mclk / (2 * (clkdiv + 1)) 394b70a67f9SLinus Walleij * => clkdiv = mclk / (2 * f) - 1 395b70a67f9SLinus Walleij */ 396a6a6464aSLinus Walleij clk = host->mclk / (2 * desired) - 1; 397a6a6464aSLinus Walleij if (clk >= 256) 398a6a6464aSLinus Walleij clk = 255; 399a6a6464aSLinus Walleij host->cclk = host->mclk / (2 * (clk + 1)); 400a6a6464aSLinus Walleij } 4014380c14fSRabin Vincent 4024380c14fSRabin Vincent clk |= variant->clkreg_enable; 403a6a6464aSLinus Walleij clk |= MCI_CLK_ENABLE; 404a6a6464aSLinus Walleij /* This hasn't proven to be worthwhile */ 405a6a6464aSLinus Walleij /* clk |= MCI_CLK_PWRSAVE; */ 406a6a6464aSLinus Walleij } 407a6a6464aSLinus Walleij 408c58a8509SUlf Hansson /* Set actual clock for debug */ 409c58a8509SUlf Hansson host->mmc->actual_clock = host->cclk; 410c58a8509SUlf Hansson 4119e6c82cdSLinus Walleij if (host->mmc->ios.bus_width == MMC_BUS_WIDTH_4) 412771dc157SLinus Walleij clk |= MCI_4BIT_BUS; 413771dc157SLinus Walleij if (host->mmc->ios.bus_width == MMC_BUS_WIDTH_8) 414e1412d85SSrinivas Kandagatla clk |= variant->clkreg_8bit_bus_enable; 4159e6c82cdSLinus Walleij 4166dad6c95SSeungwon Jeon if (host->mmc->ios.timing == MMC_TIMING_UHS_DDR50 || 4176dad6c95SSeungwon Jeon host->mmc->ios.timing == MMC_TIMING_MMC_DDR52) 418e8740644SSrinivas Kandagatla clk |= variant->clkreg_neg_edge_enable; 4196dbb6ee0SUlf Hansson 4207437cfa5SUlf Hansson mmci_write_clkreg(host, clk); 421a6a6464aSLinus Walleij } 422a6a6464aSLinus Walleij 423e2b98d83SBen Dooks static void mmci_dma_release(struct mmci_host *host) 424c3647fdcSLudovic Barre { 425c3647fdcSLudovic Barre if (host->ops && host->ops->dma_release) 426c3647fdcSLudovic Barre host->ops->dma_release(host); 427c3647fdcSLudovic Barre 428c3647fdcSLudovic Barre host->use_dma = false; 429c3647fdcSLudovic Barre } 430c3647fdcSLudovic Barre 431e2b98d83SBen Dooks static void mmci_dma_setup(struct mmci_host *host) 432c3647fdcSLudovic Barre { 433c3647fdcSLudovic Barre if (!host->ops || !host->ops->dma_setup) 434c3647fdcSLudovic Barre return; 435c3647fdcSLudovic Barre 436c3647fdcSLudovic Barre if (host->ops->dma_setup(host)) 437c3647fdcSLudovic Barre return; 438c3647fdcSLudovic Barre 439a813f2a2SLudovic Barre /* initialize pre request cookie */ 440a813f2a2SLudovic Barre host->next_cookie = 1; 441a813f2a2SLudovic Barre 442c3647fdcSLudovic Barre host->use_dma = true; 443c3647fdcSLudovic Barre } 444c3647fdcSLudovic Barre 445e0da1721SLudovic Barre /* 446e0da1721SLudovic Barre * Validate mmc prerequisites 447e0da1721SLudovic Barre */ 448e0da1721SLudovic Barre static int mmci_validate_data(struct mmci_host *host, 449e0da1721SLudovic Barre struct mmc_data *data) 450e0da1721SLudovic Barre { 451e0da1721SLudovic Barre if (!data) 452e0da1721SLudovic Barre return 0; 453e0da1721SLudovic Barre 454e0da1721SLudovic Barre if (!is_power_of_2(data->blksz)) { 455e0da1721SLudovic Barre dev_err(mmc_dev(host->mmc), 456e0da1721SLudovic Barre "unsupported block size (%d bytes)\n", data->blksz); 457e0da1721SLudovic Barre return -EINVAL; 458e0da1721SLudovic Barre } 459e0da1721SLudovic Barre 460e0da1721SLudovic Barre if (host->ops && host->ops->validate_data) 461e0da1721SLudovic Barre return host->ops->validate_data(host, data); 462e0da1721SLudovic Barre 463e0da1721SLudovic Barre return 0; 464e0da1721SLudovic Barre } 465e0da1721SLudovic Barre 466e2b98d83SBen Dooks static int mmci_prep_data(struct mmci_host *host, struct mmc_data *data, bool next) 46747983510SLudovic Barre { 46847983510SLudovic Barre int err; 46947983510SLudovic Barre 47047983510SLudovic Barre if (!host->ops || !host->ops->prep_data) 47147983510SLudovic Barre return 0; 47247983510SLudovic Barre 47347983510SLudovic Barre err = host->ops->prep_data(host, data, next); 47447983510SLudovic Barre 47547983510SLudovic Barre if (next && !err) 47647983510SLudovic Barre data->host_cookie = ++host->next_cookie < 0 ? 47747983510SLudovic Barre 1 : host->next_cookie; 47847983510SLudovic Barre 47947983510SLudovic Barre return err; 48047983510SLudovic Barre } 48147983510SLudovic Barre 482e2b98d83SBen Dooks static void mmci_unprep_data(struct mmci_host *host, struct mmc_data *data, 48347983510SLudovic Barre int err) 48447983510SLudovic Barre { 48547983510SLudovic Barre if (host->ops && host->ops->unprep_data) 48647983510SLudovic Barre host->ops->unprep_data(host, data, err); 48747983510SLudovic Barre 48847983510SLudovic Barre data->host_cookie = 0; 48947983510SLudovic Barre } 49047983510SLudovic Barre 491e2b98d83SBen Dooks static void mmci_get_next_data(struct mmci_host *host, struct mmc_data *data) 49202769968SLudovic Barre { 49302769968SLudovic Barre WARN_ON(data->host_cookie && data->host_cookie != host->next_cookie); 49402769968SLudovic Barre 49502769968SLudovic Barre if (host->ops && host->ops->get_next_data) 49602769968SLudovic Barre host->ops->get_next_data(host, data); 49702769968SLudovic Barre } 49802769968SLudovic Barre 499e2b98d83SBen Dooks static int mmci_dma_start(struct mmci_host *host, unsigned int datactrl) 500135ea30eSLudovic Barre { 501135ea30eSLudovic Barre struct mmc_data *data = host->data; 502135ea30eSLudovic Barre int ret; 503135ea30eSLudovic Barre 504135ea30eSLudovic Barre if (!host->use_dma) 505135ea30eSLudovic Barre return -EINVAL; 506135ea30eSLudovic Barre 507135ea30eSLudovic Barre ret = mmci_prep_data(host, data, false); 508135ea30eSLudovic Barre if (ret) 509135ea30eSLudovic Barre return ret; 510135ea30eSLudovic Barre 511135ea30eSLudovic Barre if (!host->ops || !host->ops->dma_start) 512135ea30eSLudovic Barre return -EINVAL; 513135ea30eSLudovic Barre 514135ea30eSLudovic Barre /* Okay, go for it. */ 515135ea30eSLudovic Barre dev_vdbg(mmc_dev(host->mmc), 516135ea30eSLudovic Barre "Submit MMCI DMA job, sglen %d blksz %04x blks %04x flags %08x\n", 517135ea30eSLudovic Barre data->sg_len, data->blksz, data->blocks, data->flags); 518135ea30eSLudovic Barre 519135ea30eSLudovic Barre host->ops->dma_start(host, &datactrl); 520135ea30eSLudovic Barre 521135ea30eSLudovic Barre /* Trigger the DMA transfer */ 522135ea30eSLudovic Barre mmci_write_datactrlreg(host, datactrl); 523135ea30eSLudovic Barre 524135ea30eSLudovic Barre /* 525135ea30eSLudovic Barre * Let the MMCI say when the data is ended and it's time 526135ea30eSLudovic Barre * to fire next DMA request. When that happens, MMCI will 527135ea30eSLudovic Barre * call mmci_data_end() 528135ea30eSLudovic Barre */ 529135ea30eSLudovic Barre writel(readl(host->base + MMCIMASK0) | MCI_DATAENDMASK, 530135ea30eSLudovic Barre host->base + MMCIMASK0); 531135ea30eSLudovic Barre return 0; 532135ea30eSLudovic Barre } 533135ea30eSLudovic Barre 534e2b98d83SBen Dooks static void mmci_dma_finalize(struct mmci_host *host, struct mmc_data *data) 5355a9f10c3SLudovic Barre { 5365a9f10c3SLudovic Barre if (!host->use_dma) 5375a9f10c3SLudovic Barre return; 5385a9f10c3SLudovic Barre 5395a9f10c3SLudovic Barre if (host->ops && host->ops->dma_finalize) 5405a9f10c3SLudovic Barre host->ops->dma_finalize(host, data); 5415a9f10c3SLudovic Barre } 5425a9f10c3SLudovic Barre 543e2b98d83SBen Dooks static void mmci_dma_error(struct mmci_host *host) 544cfccc6acSLudovic Barre { 545cfccc6acSLudovic Barre if (!host->use_dma) 546cfccc6acSLudovic Barre return; 547cfccc6acSLudovic Barre 548cfccc6acSLudovic Barre if (host->ops && host->ops->dma_error) 549cfccc6acSLudovic Barre host->ops->dma_error(host); 550cfccc6acSLudovic Barre } 551cfccc6acSLudovic Barre 5521c6a0718SPierre Ossman static void 5531c6a0718SPierre Ossman mmci_request_end(struct mmci_host *host, struct mmc_request *mrq) 5541c6a0718SPierre Ossman { 5551c6a0718SPierre Ossman writel(0, host->base + MMCICOMMAND); 5561c6a0718SPierre Ossman 5571c6a0718SPierre Ossman BUG_ON(host->data); 5581c6a0718SPierre Ossman 5591c6a0718SPierre Ossman host->mrq = NULL; 5601c6a0718SPierre Ossman host->cmd = NULL; 5611c6a0718SPierre Ossman 5621c6a0718SPierre Ossman mmc_request_done(host->mmc, mrq); 5631c6a0718SPierre Ossman } 5641c6a0718SPierre Ossman 5652686b4b4SLinus Walleij static void mmci_set_mask1(struct mmci_host *host, unsigned int mask) 5662686b4b4SLinus Walleij { 5672686b4b4SLinus Walleij void __iomem *base = host->base; 5686ea9cdf3SPatrice Chotard struct variant_data *variant = host->variant; 5692686b4b4SLinus Walleij 5702686b4b4SLinus Walleij if (host->singleirq) { 5712686b4b4SLinus Walleij unsigned int mask0 = readl(base + MMCIMASK0); 5722686b4b4SLinus Walleij 57359db5e2dSLudovic Barre mask0 &= ~variant->irq_pio_mask; 5742686b4b4SLinus Walleij mask0 |= mask; 5752686b4b4SLinus Walleij 5762686b4b4SLinus Walleij writel(mask0, base + MMCIMASK0); 5772686b4b4SLinus Walleij } 5782686b4b4SLinus Walleij 5796ea9cdf3SPatrice Chotard if (variant->mmcimask1) 5802686b4b4SLinus Walleij writel(mask, base + MMCIMASK1); 5816ea9cdf3SPatrice Chotard 5826ea9cdf3SPatrice Chotard host->mask1_reg = mask; 5832686b4b4SLinus Walleij } 5842686b4b4SLinus Walleij 5851c6a0718SPierre Ossman static void mmci_stop_data(struct mmci_host *host) 5861c6a0718SPierre Ossman { 5879cc639a2SUlf Hansson mmci_write_datactrlreg(host, 0); 5882686b4b4SLinus Walleij mmci_set_mask1(host, 0); 5891c6a0718SPierre Ossman host->data = NULL; 5901c6a0718SPierre Ossman } 5911c6a0718SPierre Ossman 5924ce1d6cbSRabin Vincent static void mmci_init_sg(struct mmci_host *host, struct mmc_data *data) 5934ce1d6cbSRabin Vincent { 5944ce1d6cbSRabin Vincent unsigned int flags = SG_MITER_ATOMIC; 5954ce1d6cbSRabin Vincent 5964ce1d6cbSRabin Vincent if (data->flags & MMC_DATA_READ) 5974ce1d6cbSRabin Vincent flags |= SG_MITER_TO_SG; 5984ce1d6cbSRabin Vincent else 5994ce1d6cbSRabin Vincent flags |= SG_MITER_FROM_SG; 6004ce1d6cbSRabin Vincent 6014ce1d6cbSRabin Vincent sg_miter_start(&host->sg_miter, data->sg, data->sg_len, flags); 6024ce1d6cbSRabin Vincent } 6034ce1d6cbSRabin Vincent 604b3fb9d64SLudovic Barre static u32 mmci_get_dctrl_cfg(struct mmci_host *host) 605b3fb9d64SLudovic Barre { 606b3fb9d64SLudovic Barre return MCI_DPSM_ENABLE | mmci_dctrl_blksz(host); 607b3fb9d64SLudovic Barre } 608b3fb9d64SLudovic Barre 609b3fb9d64SLudovic Barre static u32 ux500v2_get_dctrl_cfg(struct mmci_host *host) 610b3fb9d64SLudovic Barre { 611b3fb9d64SLudovic Barre return MCI_DPSM_ENABLE | (host->data->blksz << 16); 612b3fb9d64SLudovic Barre } 613b3fb9d64SLudovic Barre 614cb0335b7SLudovic Barre static bool ux500_busy_complete(struct mmci_host *host, u32 status, u32 err_msk) 615cb0335b7SLudovic Barre { 616cb0335b7SLudovic Barre void __iomem *base = host->base; 617cb0335b7SLudovic Barre 618cb0335b7SLudovic Barre /* 619cb0335b7SLudovic Barre * Before unmasking for the busy end IRQ, confirm that the 620cb0335b7SLudovic Barre * command was sent successfully. To keep track of having a 621cb0335b7SLudovic Barre * command in-progress, waiting for busy signaling to end, 622cb0335b7SLudovic Barre * store the status in host->busy_status. 623cb0335b7SLudovic Barre * 624cb0335b7SLudovic Barre * Note that, the card may need a couple of clock cycles before 625cb0335b7SLudovic Barre * it starts signaling busy on DAT0, hence re-read the 626cb0335b7SLudovic Barre * MMCISTATUS register here, to allow the busy bit to be set. 627cb0335b7SLudovic Barre * Potentially we may even need to poll the register for a 628cb0335b7SLudovic Barre * while, to allow it to be set, but tests indicates that it 629cb0335b7SLudovic Barre * isn't needed. 630cb0335b7SLudovic Barre */ 631cb0335b7SLudovic Barre if (!host->busy_status && !(status & err_msk) && 632cb0335b7SLudovic Barre (readl(base + MMCISTATUS) & host->variant->busy_detect_flag)) { 633cb0335b7SLudovic Barre writel(readl(base + MMCIMASK0) | 634cb0335b7SLudovic Barre host->variant->busy_detect_mask, 635cb0335b7SLudovic Barre base + MMCIMASK0); 636cb0335b7SLudovic Barre 637cb0335b7SLudovic Barre host->busy_status = status & (MCI_CMDSENT | MCI_CMDRESPEND); 638cb0335b7SLudovic Barre return false; 639cb0335b7SLudovic Barre } 640cb0335b7SLudovic Barre 641cb0335b7SLudovic Barre /* 642cb0335b7SLudovic Barre * If there is a command in-progress that has been successfully 643cb0335b7SLudovic Barre * sent, then bail out if busy status is set and wait for the 644cb0335b7SLudovic Barre * busy end IRQ. 645cb0335b7SLudovic Barre * 646cb0335b7SLudovic Barre * Note that, the HW triggers an IRQ on both edges while 647cb0335b7SLudovic Barre * monitoring DAT0 for busy completion, but there is only one 648cb0335b7SLudovic Barre * status bit in MMCISTATUS for the busy state. Therefore 649cb0335b7SLudovic Barre * both the start and the end interrupts needs to be cleared, 650cb0335b7SLudovic Barre * one after the other. So, clear the busy start IRQ here. 651cb0335b7SLudovic Barre */ 652cb0335b7SLudovic Barre if (host->busy_status && 653cb0335b7SLudovic Barre (status & host->variant->busy_detect_flag)) { 654cb0335b7SLudovic Barre writel(host->variant->busy_detect_mask, base + MMCICLEAR); 655cb0335b7SLudovic Barre return false; 656cb0335b7SLudovic Barre } 657cb0335b7SLudovic Barre 658cb0335b7SLudovic Barre /* 659cb0335b7SLudovic Barre * If there is a command in-progress that has been successfully 660cb0335b7SLudovic Barre * sent and the busy bit isn't set, it means we have received 661cb0335b7SLudovic Barre * the busy end IRQ. Clear and mask the IRQ, then continue to 662cb0335b7SLudovic Barre * process the command. 663cb0335b7SLudovic Barre */ 664cb0335b7SLudovic Barre if (host->busy_status) { 665cb0335b7SLudovic Barre writel(host->variant->busy_detect_mask, base + MMCICLEAR); 666cb0335b7SLudovic Barre 667cb0335b7SLudovic Barre writel(readl(base + MMCIMASK0) & 668cb0335b7SLudovic Barre ~host->variant->busy_detect_mask, base + MMCIMASK0); 669cb0335b7SLudovic Barre host->busy_status = 0; 670cb0335b7SLudovic Barre } 671cb0335b7SLudovic Barre 672cb0335b7SLudovic Barre return true; 673cb0335b7SLudovic Barre } 674cb0335b7SLudovic Barre 675c8ebae37SRussell King /* 676c8ebae37SRussell King * All the DMA operation mode stuff goes inside this ifdef. 677c8ebae37SRussell King * This assumes that you have a generic DMA device interface, 678c8ebae37SRussell King * no custom DMA interfaces are supported. 679c8ebae37SRussell King */ 680c8ebae37SRussell King #ifdef CONFIG_DMA_ENGINE 681a813f2a2SLudovic Barre struct mmci_dmae_next { 682a813f2a2SLudovic Barre struct dma_async_tx_descriptor *desc; 683a813f2a2SLudovic Barre struct dma_chan *chan; 684a813f2a2SLudovic Barre }; 685a813f2a2SLudovic Barre 686a813f2a2SLudovic Barre struct mmci_dmae_priv { 687a813f2a2SLudovic Barre struct dma_chan *cur; 688a813f2a2SLudovic Barre struct dma_chan *rx_channel; 689a813f2a2SLudovic Barre struct dma_chan *tx_channel; 690a813f2a2SLudovic Barre struct dma_async_tx_descriptor *desc_current; 691a813f2a2SLudovic Barre struct mmci_dmae_next next_data; 692a813f2a2SLudovic Barre }; 693a813f2a2SLudovic Barre 694c3647fdcSLudovic Barre int mmci_dmae_setup(struct mmci_host *host) 695c8ebae37SRussell King { 696c8ebae37SRussell King const char *rxname, *txname; 697a813f2a2SLudovic Barre struct mmci_dmae_priv *dmae; 698c8ebae37SRussell King 699a813f2a2SLudovic Barre dmae = devm_kzalloc(mmc_dev(host->mmc), sizeof(*dmae), GFP_KERNEL); 700a813f2a2SLudovic Barre if (!dmae) 701a813f2a2SLudovic Barre return -ENOMEM; 702c8ebae37SRussell King 703a813f2a2SLudovic Barre host->dma_priv = dmae; 704a813f2a2SLudovic Barre 705a813f2a2SLudovic Barre dmae->rx_channel = dma_request_slave_channel(mmc_dev(host->mmc), 706a813f2a2SLudovic Barre "rx"); 707a813f2a2SLudovic Barre dmae->tx_channel = dma_request_slave_channel(mmc_dev(host->mmc), 708a813f2a2SLudovic Barre "tx"); 70958c7ccbfSPer Forlin 7101fd83f0eSLee Jones /* 7111fd83f0eSLee Jones * If only an RX channel is specified, the driver will 7121fd83f0eSLee Jones * attempt to use it bidirectionally, however if it is 7131fd83f0eSLee Jones * is specified but cannot be located, DMA will be disabled. 7141fd83f0eSLee Jones */ 715a813f2a2SLudovic Barre if (dmae->rx_channel && !dmae->tx_channel) 716a813f2a2SLudovic Barre dmae->tx_channel = dmae->rx_channel; 717c8ebae37SRussell King 718a813f2a2SLudovic Barre if (dmae->rx_channel) 719a813f2a2SLudovic Barre rxname = dma_chan_name(dmae->rx_channel); 720c8ebae37SRussell King else 721c8ebae37SRussell King rxname = "none"; 722c8ebae37SRussell King 723a813f2a2SLudovic Barre if (dmae->tx_channel) 724a813f2a2SLudovic Barre txname = dma_chan_name(dmae->tx_channel); 725c8ebae37SRussell King else 726c8ebae37SRussell King txname = "none"; 727c8ebae37SRussell King 728c8ebae37SRussell King dev_info(mmc_dev(host->mmc), "DMA channels RX %s, TX %s\n", 729c8ebae37SRussell King rxname, txname); 730c8ebae37SRussell King 731c8ebae37SRussell King /* 732c8ebae37SRussell King * Limit the maximum segment size in any SG entry according to 733c8ebae37SRussell King * the parameters of the DMA engine device. 734c8ebae37SRussell King */ 735a813f2a2SLudovic Barre if (dmae->tx_channel) { 736a813f2a2SLudovic Barre struct device *dev = dmae->tx_channel->device->dev; 737c8ebae37SRussell King unsigned int max_seg_size = dma_get_max_seg_size(dev); 738c8ebae37SRussell King 739c8ebae37SRussell King if (max_seg_size < host->mmc->max_seg_size) 740c8ebae37SRussell King host->mmc->max_seg_size = max_seg_size; 741c8ebae37SRussell King } 742a813f2a2SLudovic Barre if (dmae->rx_channel) { 743a813f2a2SLudovic Barre struct device *dev = dmae->rx_channel->device->dev; 744c8ebae37SRussell King unsigned int max_seg_size = dma_get_max_seg_size(dev); 745c8ebae37SRussell King 746c8ebae37SRussell King if (max_seg_size < host->mmc->max_seg_size) 747c8ebae37SRussell King host->mmc->max_seg_size = max_seg_size; 748c8ebae37SRussell King } 7499cb15142SSrinivas Kandagatla 750a813f2a2SLudovic Barre if (!dmae->tx_channel || !dmae->rx_channel) { 751c3647fdcSLudovic Barre mmci_dmae_release(host); 752c3647fdcSLudovic Barre return -EINVAL; 753c3647fdcSLudovic Barre } 754c3647fdcSLudovic Barre 755c3647fdcSLudovic Barre return 0; 756c8ebae37SRussell King } 757c8ebae37SRussell King 758c8ebae37SRussell King /* 7596e0ee714SBill Pemberton * This is used in or so inline it 760c8ebae37SRussell King * so it can be discarded. 761c8ebae37SRussell King */ 762c3647fdcSLudovic Barre void mmci_dmae_release(struct mmci_host *host) 763c8ebae37SRussell King { 764a813f2a2SLudovic Barre struct mmci_dmae_priv *dmae = host->dma_priv; 765a813f2a2SLudovic Barre 766a813f2a2SLudovic Barre if (dmae->rx_channel) 767a813f2a2SLudovic Barre dma_release_channel(dmae->rx_channel); 768a813f2a2SLudovic Barre if (dmae->tx_channel) 769a813f2a2SLudovic Barre dma_release_channel(dmae->tx_channel); 770a813f2a2SLudovic Barre dmae->rx_channel = dmae->tx_channel = NULL; 771c8ebae37SRussell King } 772c8ebae37SRussell King 773c8ebae37SRussell King static void mmci_dma_unmap(struct mmci_host *host, struct mmc_data *data) 774c8ebae37SRussell King { 775a813f2a2SLudovic Barre struct mmci_dmae_priv *dmae = host->dma_priv; 776653a761eSUlf Hansson struct dma_chan *chan; 777653a761eSUlf Hansson 778feeef096SHeiner Kallweit if (data->flags & MMC_DATA_READ) 779a813f2a2SLudovic Barre chan = dmae->rx_channel; 780feeef096SHeiner Kallweit else 781a813f2a2SLudovic Barre chan = dmae->tx_channel; 782653a761eSUlf Hansson 783feeef096SHeiner Kallweit dma_unmap_sg(chan->device->dev, data->sg, data->sg_len, 784feeef096SHeiner Kallweit mmc_get_dma_dir(data)); 785653a761eSUlf Hansson } 786653a761eSUlf Hansson 787cfccc6acSLudovic Barre void mmci_dmae_error(struct mmci_host *host) 7887b2a6d51SLudovic Barre { 789a813f2a2SLudovic Barre struct mmci_dmae_priv *dmae = host->dma_priv; 790a813f2a2SLudovic Barre 791cfccc6acSLudovic Barre if (!dma_inprogress(host)) 792cdea1947SLudovic Barre return; 793cdea1947SLudovic Barre 7947b2a6d51SLudovic Barre dev_err(mmc_dev(host->mmc), "error during DMA transfer!\n"); 795a813f2a2SLudovic Barre dmaengine_terminate_all(dmae->cur); 7967b2a6d51SLudovic Barre host->dma_in_progress = false; 797a813f2a2SLudovic Barre dmae->cur = NULL; 798a813f2a2SLudovic Barre dmae->desc_current = NULL; 7997b2a6d51SLudovic Barre host->data->host_cookie = 0; 8007b2a6d51SLudovic Barre 8017b2a6d51SLudovic Barre mmci_dma_unmap(host, host->data); 8027b2a6d51SLudovic Barre } 8037b2a6d51SLudovic Barre 8045a9f10c3SLudovic Barre void mmci_dmae_finalize(struct mmci_host *host, struct mmc_data *data) 805653a761eSUlf Hansson { 806a813f2a2SLudovic Barre struct mmci_dmae_priv *dmae = host->dma_priv; 807c8ebae37SRussell King u32 status; 808c8ebae37SRussell King int i; 809c8ebae37SRussell King 8105a9f10c3SLudovic Barre if (!dma_inprogress(host)) 811cdea1947SLudovic Barre return; 812cdea1947SLudovic Barre 813c8ebae37SRussell King /* Wait up to 1ms for the DMA to complete */ 814c8ebae37SRussell King for (i = 0; ; i++) { 815c8ebae37SRussell King status = readl(host->base + MMCISTATUS); 816c8ebae37SRussell King if (!(status & MCI_RXDATAAVLBLMASK) || i >= 100) 817c8ebae37SRussell King break; 818c8ebae37SRussell King udelay(10); 819c8ebae37SRussell King } 820c8ebae37SRussell King 821c8ebae37SRussell King /* 822c8ebae37SRussell King * Check to see whether we still have some data left in the FIFO - 823c8ebae37SRussell King * this catches DMA controllers which are unable to monitor the 824c8ebae37SRussell King * DMALBREQ and DMALSREQ signals while allowing us to DMA to non- 825c8ebae37SRussell King * contiguous buffers. On TX, we'll get a FIFO underrun error. 826c8ebae37SRussell King */ 827c8ebae37SRussell King if (status & MCI_RXDATAAVLBLMASK) { 828cfccc6acSLudovic Barre mmci_dma_error(host); 829c8ebae37SRussell King if (!data->error) 830c8ebae37SRussell King data->error = -EIO; 8317b2a6d51SLudovic Barre } else if (!data->host_cookie) { 832653a761eSUlf Hansson mmci_dma_unmap(host, data); 8337b2a6d51SLudovic Barre } 834c8ebae37SRussell King 835c8ebae37SRussell King /* 836c8ebae37SRussell King * Use of DMA with scatter-gather is impossible. 837c8ebae37SRussell King * Give up with DMA and switch back to PIO mode. 838c8ebae37SRussell King */ 839c8ebae37SRussell King if (status & MCI_RXDATAAVLBLMASK) { 840c8ebae37SRussell King dev_err(mmc_dev(host->mmc), "buggy DMA detected. Taking evasive action.\n"); 841c8ebae37SRussell King mmci_dma_release(host); 842c8ebae37SRussell King } 843653a761eSUlf Hansson 844e13934bdSLinus Walleij host->dma_in_progress = false; 845a813f2a2SLudovic Barre dmae->cur = NULL; 846a813f2a2SLudovic Barre dmae->desc_current = NULL; 847c8ebae37SRussell King } 848c8ebae37SRussell King 849653a761eSUlf Hansson /* prepares DMA channel and DMA descriptor, returns non-zero on failure */ 85047983510SLudovic Barre static int _mmci_dmae_prep_data(struct mmci_host *host, struct mmc_data *data, 851653a761eSUlf Hansson struct dma_chan **dma_chan, 852653a761eSUlf Hansson struct dma_async_tx_descriptor **dma_desc) 853c8ebae37SRussell King { 854a813f2a2SLudovic Barre struct mmci_dmae_priv *dmae = host->dma_priv; 855c8ebae37SRussell King struct variant_data *variant = host->variant; 856c8ebae37SRussell King struct dma_slave_config conf = { 857c8ebae37SRussell King .src_addr = host->phybase + MMCIFIFO, 858c8ebae37SRussell King .dst_addr = host->phybase + MMCIFIFO, 859c8ebae37SRussell King .src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES, 860c8ebae37SRussell King .dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES, 861c8ebae37SRussell King .src_maxburst = variant->fifohalfsize >> 2, /* # of words */ 862c8ebae37SRussell King .dst_maxburst = variant->fifohalfsize >> 2, /* # of words */ 863258aea76SViresh Kumar .device_fc = false, 864c8ebae37SRussell King }; 865c8ebae37SRussell King struct dma_chan *chan; 866c8ebae37SRussell King struct dma_device *device; 867c8ebae37SRussell King struct dma_async_tx_descriptor *desc; 868c8ebae37SRussell King int nr_sg; 8699cb15142SSrinivas Kandagatla unsigned long flags = DMA_CTRL_ACK; 870c8ebae37SRussell King 871c8ebae37SRussell King if (data->flags & MMC_DATA_READ) { 87205f5799cSVinod Koul conf.direction = DMA_DEV_TO_MEM; 873a813f2a2SLudovic Barre chan = dmae->rx_channel; 874c8ebae37SRussell King } else { 87505f5799cSVinod Koul conf.direction = DMA_MEM_TO_DEV; 876a813f2a2SLudovic Barre chan = dmae->tx_channel; 877c8ebae37SRussell King } 878c8ebae37SRussell King 879c8ebae37SRussell King /* If there's no DMA channel, fall back to PIO */ 880c8ebae37SRussell King if (!chan) 881c8ebae37SRussell King return -EINVAL; 882c8ebae37SRussell King 883c8ebae37SRussell King /* If less than or equal to the fifo size, don't bother with DMA */ 88458c7ccbfSPer Forlin if (data->blksz * data->blocks <= variant->fifosize) 885c8ebae37SRussell King return -EINVAL; 886c8ebae37SRussell King 887c8ebae37SRussell King device = chan->device; 888feeef096SHeiner Kallweit nr_sg = dma_map_sg(device->dev, data->sg, data->sg_len, 889feeef096SHeiner Kallweit mmc_get_dma_dir(data)); 890c8ebae37SRussell King if (nr_sg == 0) 891c8ebae37SRussell King return -EINVAL; 892c8ebae37SRussell King 8939cb15142SSrinivas Kandagatla if (host->variant->qcom_dml) 8949cb15142SSrinivas Kandagatla flags |= DMA_PREP_INTERRUPT; 8959cb15142SSrinivas Kandagatla 896c8ebae37SRussell King dmaengine_slave_config(chan, &conf); 89716052827SAlexandre Bounine desc = dmaengine_prep_slave_sg(chan, data->sg, nr_sg, 8989cb15142SSrinivas Kandagatla conf.direction, flags); 899c8ebae37SRussell King if (!desc) 900c8ebae37SRussell King goto unmap_exit; 901c8ebae37SRussell King 902653a761eSUlf Hansson *dma_chan = chan; 903653a761eSUlf Hansson *dma_desc = desc; 904c8ebae37SRussell King 90558c7ccbfSPer Forlin return 0; 90658c7ccbfSPer Forlin 90758c7ccbfSPer Forlin unmap_exit: 908feeef096SHeiner Kallweit dma_unmap_sg(device->dev, data->sg, data->sg_len, 909feeef096SHeiner Kallweit mmc_get_dma_dir(data)); 91058c7ccbfSPer Forlin return -ENOMEM; 91158c7ccbfSPer Forlin } 91258c7ccbfSPer Forlin 91347983510SLudovic Barre int mmci_dmae_prep_data(struct mmci_host *host, 914ad7b8918SLudovic Barre struct mmc_data *data, 915ad7b8918SLudovic Barre bool next) 916653a761eSUlf Hansson { 917a813f2a2SLudovic Barre struct mmci_dmae_priv *dmae = host->dma_priv; 918ad7b8918SLudovic Barre struct mmci_dmae_next *nd = &dmae->next_data; 919a813f2a2SLudovic Barre 92047983510SLudovic Barre if (!host->use_dma) 92147983510SLudovic Barre return -EINVAL; 92247983510SLudovic Barre 923ad7b8918SLudovic Barre if (next) 92447983510SLudovic Barre return _mmci_dmae_prep_data(host, data, &nd->chan, &nd->desc); 925653a761eSUlf Hansson /* Check if next job is already prepared. */ 926a813f2a2SLudovic Barre if (dmae->cur && dmae->desc_current) 927653a761eSUlf Hansson return 0; 928653a761eSUlf Hansson 929653a761eSUlf Hansson /* No job were prepared thus do it now. */ 93047983510SLudovic Barre return _mmci_dmae_prep_data(host, data, &dmae->cur, 931a813f2a2SLudovic Barre &dmae->desc_current); 932653a761eSUlf Hansson } 933653a761eSUlf Hansson 934135ea30eSLudovic Barre int mmci_dmae_start(struct mmci_host *host, unsigned int *datactrl) 93558c7ccbfSPer Forlin { 936a813f2a2SLudovic Barre struct mmci_dmae_priv *dmae = host->dma_priv; 93758c7ccbfSPer Forlin 938e13934bdSLinus Walleij host->dma_in_progress = true; 939a813f2a2SLudovic Barre dmaengine_submit(dmae->desc_current); 940a813f2a2SLudovic Barre dma_async_issue_pending(dmae->cur); 941c8ebae37SRussell King 942135ea30eSLudovic Barre *datactrl |= MCI_DPSM_DMAENABLE; 943c8ebae37SRussell King 944c8ebae37SRussell King return 0; 945c8ebae37SRussell King } 94658c7ccbfSPer Forlin 94702769968SLudovic Barre void mmci_dmae_get_next_data(struct mmci_host *host, struct mmc_data *data) 94858c7ccbfSPer Forlin { 949a813f2a2SLudovic Barre struct mmci_dmae_priv *dmae = host->dma_priv; 950a813f2a2SLudovic Barre struct mmci_dmae_next *next = &dmae->next_data; 95158c7ccbfSPer Forlin 952c3647fdcSLudovic Barre if (!host->use_dma) 953c3647fdcSLudovic Barre return; 954c3647fdcSLudovic Barre 955a813f2a2SLudovic Barre WARN_ON(!data->host_cookie && (next->desc || next->chan)); 95658c7ccbfSPer Forlin 957a813f2a2SLudovic Barre dmae->desc_current = next->desc; 958a813f2a2SLudovic Barre dmae->cur = next->chan; 959a813f2a2SLudovic Barre next->desc = NULL; 960a813f2a2SLudovic Barre next->chan = NULL; 96158c7ccbfSPer Forlin } 96258c7ccbfSPer Forlin 96347983510SLudovic Barre void mmci_dmae_unprep_data(struct mmci_host *host, 96447983510SLudovic Barre struct mmc_data *data, int err) 96547983510SLudovic Barre 96658c7ccbfSPer Forlin { 967a813f2a2SLudovic Barre struct mmci_dmae_priv *dmae = host->dma_priv; 96858c7ccbfSPer Forlin 96947983510SLudovic Barre if (!host->use_dma) 97058c7ccbfSPer Forlin return; 97158c7ccbfSPer Forlin 972653a761eSUlf Hansson mmci_dma_unmap(host, data); 973653a761eSUlf Hansson 974653a761eSUlf Hansson if (err) { 975a813f2a2SLudovic Barre struct mmci_dmae_next *next = &dmae->next_data; 976653a761eSUlf Hansson struct dma_chan *chan; 977653a761eSUlf Hansson if (data->flags & MMC_DATA_READ) 978a813f2a2SLudovic Barre chan = dmae->rx_channel; 979653a761eSUlf Hansson else 980a813f2a2SLudovic Barre chan = dmae->tx_channel; 98158c7ccbfSPer Forlin dmaengine_terminate_all(chan); 982653a761eSUlf Hansson 983a813f2a2SLudovic Barre if (dmae->desc_current == next->desc) 984a813f2a2SLudovic Barre dmae->desc_current = NULL; 985b5c16a60SSrinivas Kandagatla 986a813f2a2SLudovic Barre if (dmae->cur == next->chan) { 987e13934bdSLinus Walleij host->dma_in_progress = false; 988a813f2a2SLudovic Barre dmae->cur = NULL; 989e13934bdSLinus Walleij } 990b5c16a60SSrinivas Kandagatla 991a813f2a2SLudovic Barre next->desc = NULL; 992a813f2a2SLudovic Barre next->chan = NULL; 99358c7ccbfSPer Forlin } 99458c7ccbfSPer Forlin } 99558c7ccbfSPer Forlin 996c3647fdcSLudovic Barre static struct mmci_host_ops mmci_variant_ops = { 99747983510SLudovic Barre .prep_data = mmci_dmae_prep_data, 99847983510SLudovic Barre .unprep_data = mmci_dmae_unprep_data, 999b3fb9d64SLudovic Barre .get_datactrl_cfg = mmci_get_dctrl_cfg, 100002769968SLudovic Barre .get_next_data = mmci_dmae_get_next_data, 1001c3647fdcSLudovic Barre .dma_setup = mmci_dmae_setup, 1002c3647fdcSLudovic Barre .dma_release = mmci_dmae_release, 1003135ea30eSLudovic Barre .dma_start = mmci_dmae_start, 10045a9f10c3SLudovic Barre .dma_finalize = mmci_dmae_finalize, 1005cfccc6acSLudovic Barre .dma_error = mmci_dmae_error, 1006c3647fdcSLudovic Barre }; 1007b3fb9d64SLudovic Barre #else 1008b3fb9d64SLudovic Barre static struct mmci_host_ops mmci_variant_ops = { 1009b3fb9d64SLudovic Barre .get_datactrl_cfg = mmci_get_dctrl_cfg, 1010b3fb9d64SLudovic Barre }; 1011b3fb9d64SLudovic Barre #endif 1012c3647fdcSLudovic Barre 1013e2b98d83SBen Dooks static void mmci_variant_init(struct mmci_host *host) 1014c3647fdcSLudovic Barre { 1015c3647fdcSLudovic Barre host->ops = &mmci_variant_ops; 1016c3647fdcSLudovic Barre } 1017b3fb9d64SLudovic Barre 1018cb0335b7SLudovic Barre static void ux500_variant_init(struct mmci_host *host) 1019cb0335b7SLudovic Barre { 1020cb0335b7SLudovic Barre host->ops = &mmci_variant_ops; 1021cb0335b7SLudovic Barre host->ops->busy_complete = ux500_busy_complete; 1022cb0335b7SLudovic Barre } 1023cb0335b7SLudovic Barre 1024e2b98d83SBen Dooks static void ux500v2_variant_init(struct mmci_host *host) 1025b3fb9d64SLudovic Barre { 1026b3fb9d64SLudovic Barre host->ops = &mmci_variant_ops; 1027cb0335b7SLudovic Barre host->ops->busy_complete = ux500_busy_complete; 1028b3fb9d64SLudovic Barre host->ops->get_datactrl_cfg = ux500v2_get_dctrl_cfg; 1029b3fb9d64SLudovic Barre } 1030c8ebae37SRussell King 103147983510SLudovic Barre static void mmci_pre_request(struct mmc_host *mmc, struct mmc_request *mrq) 103247983510SLudovic Barre { 103347983510SLudovic Barre struct mmci_host *host = mmc_priv(mmc); 103447983510SLudovic Barre struct mmc_data *data = mrq->data; 103547983510SLudovic Barre 103647983510SLudovic Barre if (!data) 103747983510SLudovic Barre return; 103847983510SLudovic Barre 103947983510SLudovic Barre WARN_ON(data->host_cookie); 104047983510SLudovic Barre 104147983510SLudovic Barre if (mmci_validate_data(host, data)) 104247983510SLudovic Barre return; 104347983510SLudovic Barre 104447983510SLudovic Barre mmci_prep_data(host, data, true); 104547983510SLudovic Barre } 104647983510SLudovic Barre 104747983510SLudovic Barre static void mmci_post_request(struct mmc_host *mmc, struct mmc_request *mrq, 104847983510SLudovic Barre int err) 104947983510SLudovic Barre { 105047983510SLudovic Barre struct mmci_host *host = mmc_priv(mmc); 105147983510SLudovic Barre struct mmc_data *data = mrq->data; 105247983510SLudovic Barre 105347983510SLudovic Barre if (!data || !data->host_cookie) 105447983510SLudovic Barre return; 105547983510SLudovic Barre 105647983510SLudovic Barre mmci_unprep_data(host, data, err); 105747983510SLudovic Barre } 105847983510SLudovic Barre 10591c6a0718SPierre Ossman static void mmci_start_data(struct mmci_host *host, struct mmc_data *data) 10601c6a0718SPierre Ossman { 10618301bb68SRabin Vincent struct variant_data *variant = host->variant; 10621c6a0718SPierre Ossman unsigned int datactrl, timeout, irqmask; 10631c6a0718SPierre Ossman unsigned long long clks; 10641c6a0718SPierre Ossman void __iomem *base; 10651c6a0718SPierre Ossman 106664de0289SLinus Walleij dev_dbg(mmc_dev(host->mmc), "blksz %04x blks %04x flags %08x\n", 10671c6a0718SPierre Ossman data->blksz, data->blocks, data->flags); 10681c6a0718SPierre Ossman 10691c6a0718SPierre Ossman host->data = data; 1070528320dbSRabin Vincent host->size = data->blksz * data->blocks; 107151d4375dSRussell King data->bytes_xfered = 0; 10721c6a0718SPierre Ossman 10731c6a0718SPierre Ossman clks = (unsigned long long)data->timeout_ns * host->cclk; 1074c4a35769SSrinivas Kandagatla do_div(clks, NSEC_PER_SEC); 10751c6a0718SPierre Ossman 10761c6a0718SPierre Ossman timeout = data->timeout_clks + (unsigned int)clks; 10771c6a0718SPierre Ossman 10781c6a0718SPierre Ossman base = host->base; 10791c6a0718SPierre Ossman writel(timeout, base + MMCIDATATIMER); 10801c6a0718SPierre Ossman writel(host->size, base + MMCIDATALENGTH); 10811c6a0718SPierre Ossman 108241ed65e7SLudovic Barre datactrl = host->ops->get_datactrl_cfg(host); 108341ed65e7SLudovic Barre datactrl |= host->data->flags & MMC_DATA_READ ? MCI_DPSM_DIRECTION : 0; 1084c8ebae37SRussell King 1085c7354133SSrinivas Kandagatla if (host->mmc->card && mmc_card_sdio(host->mmc->card)) { 108606c1a121SUlf Hansson u32 clk; 1087c7354133SSrinivas Kandagatla 10885df014dfSSrinivas Kandagatla datactrl |= variant->datactrl_mask_sdio; 10897258db7eSUlf Hansson 1090c8ebae37SRussell King /* 109170ac0935SUlf Hansson * The ST Micro variant for SDIO small write transfers 109270ac0935SUlf Hansson * needs to have clock H/W flow control disabled, 109370ac0935SUlf Hansson * otherwise the transfer will not start. The threshold 109470ac0935SUlf Hansson * depends on the rate of MCLK. 109506c1a121SUlf Hansson */ 1096c7354133SSrinivas Kandagatla if (variant->st_sdio && data->flags & MMC_DATA_WRITE && 109770ac0935SUlf Hansson (host->size < 8 || 109870ac0935SUlf Hansson (host->size <= 8 && host->mclk > 50000000))) 109906c1a121SUlf Hansson clk = host->clk_reg & ~variant->clkreg_enable; 110006c1a121SUlf Hansson else 110106c1a121SUlf Hansson clk = host->clk_reg | variant->clkreg_enable; 110206c1a121SUlf Hansson 110306c1a121SUlf Hansson mmci_write_clkreg(host, clk); 110406c1a121SUlf Hansson } 110506c1a121SUlf Hansson 11066dad6c95SSeungwon Jeon if (host->mmc->ios.timing == MMC_TIMING_UHS_DDR50 || 11076dad6c95SSeungwon Jeon host->mmc->ios.timing == MMC_TIMING_MMC_DDR52) 1108e17dca2bSSrinivas Kandagatla datactrl |= variant->datactrl_mask_ddrmode; 11096dbb6ee0SUlf Hansson 111006c1a121SUlf Hansson /* 1111c8ebae37SRussell King * Attempt to use DMA operation mode, if this 1112c8ebae37SRussell King * should fail, fall back to PIO mode 1113c8ebae37SRussell King */ 1114135ea30eSLudovic Barre if (!mmci_dma_start(host, datactrl)) 1115c8ebae37SRussell King return; 1116c8ebae37SRussell King 1117c8ebae37SRussell King /* IRQ mode, map the SG list for CPU reading/writing */ 1118c8ebae37SRussell King mmci_init_sg(host, data); 1119c8ebae37SRussell King 1120c8ebae37SRussell King if (data->flags & MMC_DATA_READ) { 11211c6a0718SPierre Ossman irqmask = MCI_RXFIFOHALFFULLMASK; 11221c6a0718SPierre Ossman 11231c6a0718SPierre Ossman /* 1124c4d877c1SRussell King * If we have less than the fifo 'half-full' threshold to 1125c4d877c1SRussell King * transfer, trigger a PIO interrupt as soon as any data 1126c4d877c1SRussell King * is available. 11271c6a0718SPierre Ossman */ 1128c4d877c1SRussell King if (host->size < variant->fifohalfsize) 11291c6a0718SPierre Ossman irqmask |= MCI_RXDATAAVLBLMASK; 11301c6a0718SPierre Ossman } else { 11311c6a0718SPierre Ossman /* 11321c6a0718SPierre Ossman * We don't actually need to include "FIFO empty" here 11331c6a0718SPierre Ossman * since its implicit in "FIFO half empty". 11341c6a0718SPierre Ossman */ 11351c6a0718SPierre Ossman irqmask = MCI_TXFIFOHALFEMPTYMASK; 11361c6a0718SPierre Ossman } 11371c6a0718SPierre Ossman 11389cc639a2SUlf Hansson mmci_write_datactrlreg(host, datactrl); 11391c6a0718SPierre Ossman writel(readl(base + MMCIMASK0) & ~MCI_DATAENDMASK, base + MMCIMASK0); 11402686b4b4SLinus Walleij mmci_set_mask1(host, irqmask); 11411c6a0718SPierre Ossman } 11421c6a0718SPierre Ossman 11431c6a0718SPierre Ossman static void 11441c6a0718SPierre Ossman mmci_start_command(struct mmci_host *host, struct mmc_command *cmd, u32 c) 11451c6a0718SPierre Ossman { 11461c6a0718SPierre Ossman void __iomem *base = host->base; 11478266c585SLudovic Barre unsigned long long clks; 11481c6a0718SPierre Ossman 114964de0289SLinus Walleij dev_dbg(mmc_dev(host->mmc), "op %02x arg %08x flags %08x\n", 11501c6a0718SPierre Ossman cmd->opcode, cmd->arg, cmd->flags); 11511c6a0718SPierre Ossman 11520f244804SLudovic Barre if (readl(base + MMCICOMMAND) & host->variant->cmdreg_cpsm_enable) { 11531c6a0718SPierre Ossman writel(0, base + MMCICOMMAND); 11546adb2a80SSrinivas Kandagatla mmci_reg_delay(host); 11551c6a0718SPierre Ossman } 11561c6a0718SPierre Ossman 1157c8073e52SLudovic Barre if (host->variant->cmdreg_stop && 1158c8073e52SLudovic Barre cmd->opcode == MMC_STOP_TRANSMISSION) 1159c8073e52SLudovic Barre c |= host->variant->cmdreg_stop; 1160c8073e52SLudovic Barre 11610f244804SLudovic Barre c |= cmd->opcode | host->variant->cmdreg_cpsm_enable; 11621c6a0718SPierre Ossman if (cmd->flags & MMC_RSP_PRESENT) { 11631c6a0718SPierre Ossman if (cmd->flags & MMC_RSP_136) 11640f244804SLudovic Barre c |= host->variant->cmdreg_lrsp_crc; 11650f244804SLudovic Barre else if (cmd->flags & MMC_RSP_CRC) 11660f244804SLudovic Barre c |= host->variant->cmdreg_srsp_crc; 11670f244804SLudovic Barre else 11680f244804SLudovic Barre c |= host->variant->cmdreg_srsp; 11691c6a0718SPierre Ossman } 11708266c585SLudovic Barre 11718266c585SLudovic Barre if (host->variant->busy_timeout && cmd->flags & MMC_RSP_BUSY) { 11728266c585SLudovic Barre if (!cmd->busy_timeout) 11738266c585SLudovic Barre cmd->busy_timeout = 10 * MSEC_PER_SEC; 11748266c585SLudovic Barre 11758266c585SLudovic Barre clks = (unsigned long long)cmd->busy_timeout * host->cclk; 11768266c585SLudovic Barre do_div(clks, MSEC_PER_SEC); 11778266c585SLudovic Barre writel_relaxed(clks, host->base + MMCIDATATIMER); 11788266c585SLudovic Barre } 11798266c585SLudovic Barre 11801c6a0718SPierre Ossman if (/*interrupt*/0) 11811c6a0718SPierre Ossman c |= MCI_CPSM_INTERRUPT; 11821c6a0718SPierre Ossman 1183ae7b0061SSrinivas Kandagatla if (mmc_cmd_type(cmd) == MMC_CMD_ADTC) 1184ae7b0061SSrinivas Kandagatla c |= host->variant->data_cmd_enable; 1185ae7b0061SSrinivas Kandagatla 11861c6a0718SPierre Ossman host->cmd = cmd; 11871c6a0718SPierre Ossman 11881c6a0718SPierre Ossman writel(cmd->arg, base + MMCIARGUMENT); 11891c6a0718SPierre Ossman writel(c, base + MMCICOMMAND); 11901c6a0718SPierre Ossman } 11911c6a0718SPierre Ossman 1192e9968c6fSUlf Hansson static void mmci_stop_command(struct mmci_host *host) 1193e9968c6fSUlf Hansson { 1194e9968c6fSUlf Hansson host->stop_abort.error = 0; 1195e9968c6fSUlf Hansson mmci_start_command(host, &host->stop_abort, 0); 1196e9968c6fSUlf Hansson } 1197e9968c6fSUlf Hansson 11981c6a0718SPierre Ossman static void 11991c6a0718SPierre Ossman mmci_data_irq(struct mmci_host *host, struct mmc_data *data, 12001c6a0718SPierre Ossman unsigned int status) 12011c6a0718SPierre Ossman { 1202daf9713cSLudovic Barre unsigned int status_err; 1203daf9713cSLudovic Barre 12041cb9da50SUlf Hansson /* Make sure we have data to handle */ 12051cb9da50SUlf Hansson if (!data) 12061cb9da50SUlf Hansson return; 12071cb9da50SUlf Hansson 1208f20f8f21SLinus Walleij /* First check for errors */ 1209daf9713cSLudovic Barre status_err = status & (host->variant->start_err | 1210daf9713cSLudovic Barre MCI_DATACRCFAIL | MCI_DATATIMEOUT | 1211daf9713cSLudovic Barre MCI_TXUNDERRUN | MCI_RXOVERRUN); 1212daf9713cSLudovic Barre 1213daf9713cSLudovic Barre if (status_err) { 12148cb28155SLinus Walleij u32 remain, success; 1215f20f8f21SLinus Walleij 1216c8ebae37SRussell King /* Terminate the DMA transfer */ 1217cfccc6acSLudovic Barre mmci_dma_error(host); 1218c8ebae37SRussell King 1219c8afc9d5SRussell King /* 1220c8afc9d5SRussell King * Calculate how far we are into the transfer. Note that 1221c8afc9d5SRussell King * the data counter gives the number of bytes transferred 1222c8afc9d5SRussell King * on the MMC bus, not on the host side. On reads, this 1223c8afc9d5SRussell King * can be as much as a FIFO-worth of data ahead. This 1224c8afc9d5SRussell King * matters for FIFO overruns only. 1225c8afc9d5SRussell King */ 1226b79220b3SLudovic Barre if (!host->variant->datacnt_useless) { 1227f5a106d9SLinus Walleij remain = readl(host->base + MMCIDATACNT); 12288cb28155SLinus Walleij success = data->blksz * data->blocks - remain; 1229b79220b3SLudovic Barre } else { 1230b79220b3SLudovic Barre success = 0; 1231b79220b3SLudovic Barre } 12328cb28155SLinus Walleij 1233c8afc9d5SRussell King dev_dbg(mmc_dev(host->mmc), "MCI ERROR IRQ, status 0x%08x at 0x%08x\n", 1234daf9713cSLudovic Barre status_err, success); 1235daf9713cSLudovic Barre if (status_err & MCI_DATACRCFAIL) { 12368cb28155SLinus Walleij /* Last block was not successful */ 1237c8afc9d5SRussell King success -= 1; 123817b0429dSPierre Ossman data->error = -EILSEQ; 1239daf9713cSLudovic Barre } else if (status_err & MCI_DATATIMEOUT) { 124017b0429dSPierre Ossman data->error = -ETIMEDOUT; 1241daf9713cSLudovic Barre } else if (status_err & MCI_STARTBITERR) { 1242757df746SLinus Walleij data->error = -ECOMM; 1243daf9713cSLudovic Barre } else if (status_err & MCI_TXUNDERRUN) { 124417b0429dSPierre Ossman data->error = -EIO; 1245daf9713cSLudovic Barre } else if (status_err & MCI_RXOVERRUN) { 1246c8afc9d5SRussell King if (success > host->variant->fifosize) 1247c8afc9d5SRussell King success -= host->variant->fifosize; 1248c8afc9d5SRussell King else 1249c8afc9d5SRussell King success = 0; 12508cb28155SLinus Walleij data->error = -EIO; 12514ce1d6cbSRabin Vincent } 125251d4375dSRussell King data->bytes_xfered = round_down(success, data->blksz); 12531c6a0718SPierre Ossman } 1254f20f8f21SLinus Walleij 12558cb28155SLinus Walleij if (status & MCI_DATABLOCKEND) 12568cb28155SLinus Walleij dev_err(mmc_dev(host->mmc), "stray MCI_DATABLOCKEND interrupt\n"); 1257f20f8f21SLinus Walleij 1258ccff9b51SRussell King if (status & MCI_DATAEND || data->error) { 1259653a761eSUlf Hansson mmci_dma_finalize(host, data); 1260cdea1947SLudovic Barre 12611c6a0718SPierre Ossman mmci_stop_data(host); 12621c6a0718SPierre Ossman 12638cb28155SLinus Walleij if (!data->error) 12648cb28155SLinus Walleij /* The error clause is handled above, success! */ 126551d4375dSRussell King data->bytes_xfered = data->blksz * data->blocks; 1266f20f8f21SLinus Walleij 1267e9968c6fSUlf Hansson if (!data->stop) { 1268e9968c6fSUlf Hansson if (host->variant->cmdreg_stop && data->error) 1269e9968c6fSUlf Hansson mmci_stop_command(host); 127009b4f706SLudovic Barre else 1271e9968c6fSUlf Hansson mmci_request_end(host, data->mrq); 1272e9968c6fSUlf Hansson } else if (host->mrq->sbc && !data->error) { 1273e9968c6fSUlf Hansson mmci_request_end(host, data->mrq); 1274e9968c6fSUlf Hansson } else { 12751c6a0718SPierre Ossman mmci_start_command(host, data->stop, 0); 12761c6a0718SPierre Ossman } 12771c6a0718SPierre Ossman } 1278e9968c6fSUlf Hansson } 12791c6a0718SPierre Ossman 12801c6a0718SPierre Ossman static void 12811c6a0718SPierre Ossman mmci_cmd_irq(struct mmci_host *host, struct mmc_command *cmd, 12821c6a0718SPierre Ossman unsigned int status) 12831c6a0718SPierre Ossman { 12848266c585SLudovic Barre u32 err_msk = MCI_CMDCRCFAIL | MCI_CMDTIMEOUT; 12851c6a0718SPierre Ossman void __iomem *base = host->base; 1286812513c7SLudovic Barre bool sbc, busy_resp; 1287ad82bfeaSUlf Hansson 1288ad82bfeaSUlf Hansson if (!cmd) 1289ad82bfeaSUlf Hansson return; 1290ad82bfeaSUlf Hansson 1291ad82bfeaSUlf Hansson sbc = (cmd == host->mrq->sbc); 1292812513c7SLudovic Barre busy_resp = !!(cmd->flags & MMC_RSP_BUSY); 1293ad82bfeaSUlf Hansson 129449adc0caSLinus Walleij /* 129549adc0caSLinus Walleij * We need to be one of these interrupts to be considered worth 129649adc0caSLinus Walleij * handling. Note that we tag on any latent IRQs postponed 129749adc0caSLinus Walleij * due to waiting for busy status. 129849adc0caSLinus Walleij */ 12998266c585SLudovic Barre if (host->variant->busy_timeout && busy_resp) 13008266c585SLudovic Barre err_msk |= MCI_DATATIMEOUT; 13018266c585SLudovic Barre 130249adc0caSLinus Walleij if (!((status | host->busy_status) & 13038266c585SLudovic Barre (err_msk | MCI_CMDSENT | MCI_CMDRESPEND))) 1304ad82bfeaSUlf Hansson return; 13058d94b54dSUlf Hansson 1306a9cbd79cSUlf Hansson /* Handle busy detection on DAT0 if the variant supports it. */ 1307cb0335b7SLudovic Barre if (busy_resp && host->variant->busy_detect) 1308cb0335b7SLudovic Barre if (!host->ops->busy_complete(host, status, err_msk)) 13098d94b54dSUlf Hansson return; 13101c6a0718SPierre Ossman 13111c6a0718SPierre Ossman host->cmd = NULL; 13121c6a0718SPierre Ossman 13131c6a0718SPierre Ossman if (status & MCI_CMDTIMEOUT) { 131417b0429dSPierre Ossman cmd->error = -ETIMEDOUT; 13151c6a0718SPierre Ossman } else if (status & MCI_CMDCRCFAIL && cmd->flags & MMC_RSP_CRC) { 131617b0429dSPierre Ossman cmd->error = -EILSEQ; 13178266c585SLudovic Barre } else if (host->variant->busy_timeout && busy_resp && 13188266c585SLudovic Barre status & MCI_DATATIMEOUT) { 13198266c585SLudovic Barre cmd->error = -ETIMEDOUT; 13209047b435SRussell King - ARM Linux } else { 13219047b435SRussell King - ARM Linux cmd->resp[0] = readl(base + MMCIRESPONSE0); 13229047b435SRussell King - ARM Linux cmd->resp[1] = readl(base + MMCIRESPONSE1); 13239047b435SRussell King - ARM Linux cmd->resp[2] = readl(base + MMCIRESPONSE2); 13249047b435SRussell King - ARM Linux cmd->resp[3] = readl(base + MMCIRESPONSE3); 13251c6a0718SPierre Ossman } 13261c6a0718SPierre Ossman 1327024629c6SUlf Hansson if ((!sbc && !cmd->data) || cmd->error) { 13283b6e3c73SUlf Hansson if (host->data) { 13293b6e3c73SUlf Hansson /* Terminate the DMA transfer */ 1330cfccc6acSLudovic Barre mmci_dma_error(host); 13317b2a6d51SLudovic Barre 13321c6a0718SPierre Ossman mmci_stop_data(host); 1333e9968c6fSUlf Hansson if (host->variant->cmdreg_stop && cmd->error) { 1334e9968c6fSUlf Hansson mmci_stop_command(host); 1335e9968c6fSUlf Hansson return; 1336e9968c6fSUlf Hansson } 13373b6e3c73SUlf Hansson } 1338024629c6SUlf Hansson mmci_request_end(host, host->mrq); 1339024629c6SUlf Hansson } else if (sbc) { 1340024629c6SUlf Hansson mmci_start_command(host, host->mrq->cmd, 0); 1341d2141547SLudovic Barre } else if (!host->variant->datactrl_first && 1342d2141547SLudovic Barre !(cmd->data->flags & MMC_DATA_READ)) { 13431c6a0718SPierre Ossman mmci_start_data(host, cmd->data); 13441c6a0718SPierre Ossman } 13451c6a0718SPierre Ossman } 13461c6a0718SPierre Ossman 13479c34b73dSSrinivas Kandagatla static int mmci_get_rx_fifocnt(struct mmci_host *host, u32 status, int remain) 13489c34b73dSSrinivas Kandagatla { 13499c34b73dSSrinivas Kandagatla return remain - (readl(host->base + MMCIFIFOCNT) << 2); 13509c34b73dSSrinivas Kandagatla } 13519c34b73dSSrinivas Kandagatla 13529c34b73dSSrinivas Kandagatla static int mmci_qcom_get_rx_fifocnt(struct mmci_host *host, u32 status, int r) 13539c34b73dSSrinivas Kandagatla { 13549c34b73dSSrinivas Kandagatla /* 13559c34b73dSSrinivas Kandagatla * on qcom SDCC4 only 8 words are used in each burst so only 8 addresses 13569c34b73dSSrinivas Kandagatla * from the fifo range should be used 13579c34b73dSSrinivas Kandagatla */ 13589c34b73dSSrinivas Kandagatla if (status & MCI_RXFIFOHALFFULL) 13599c34b73dSSrinivas Kandagatla return host->variant->fifohalfsize; 13609c34b73dSSrinivas Kandagatla else if (status & MCI_RXDATAAVLBL) 13619c34b73dSSrinivas Kandagatla return 4; 13629c34b73dSSrinivas Kandagatla 13639c34b73dSSrinivas Kandagatla return 0; 13649c34b73dSSrinivas Kandagatla } 13659c34b73dSSrinivas Kandagatla 13661c6a0718SPierre Ossman static int mmci_pio_read(struct mmci_host *host, char *buffer, unsigned int remain) 13671c6a0718SPierre Ossman { 13681c6a0718SPierre Ossman void __iomem *base = host->base; 13691c6a0718SPierre Ossman char *ptr = buffer; 13709c34b73dSSrinivas Kandagatla u32 status = readl(host->base + MMCISTATUS); 137126eed9a5SLinus Walleij int host_remain = host->size; 13721c6a0718SPierre Ossman 13731c6a0718SPierre Ossman do { 13749c34b73dSSrinivas Kandagatla int count = host->get_rx_fifocnt(host, status, host_remain); 13751c6a0718SPierre Ossman 13761c6a0718SPierre Ossman if (count > remain) 13771c6a0718SPierre Ossman count = remain; 13781c6a0718SPierre Ossman 13791c6a0718SPierre Ossman if (count <= 0) 13801c6a0718SPierre Ossman break; 13811c6a0718SPierre Ossman 1382393e5e24SUlf Hansson /* 1383393e5e24SUlf Hansson * SDIO especially may want to send something that is 1384393e5e24SUlf Hansson * not divisible by 4 (as opposed to card sectors 1385393e5e24SUlf Hansson * etc). Therefore make sure to always read the last bytes 1386393e5e24SUlf Hansson * while only doing full 32-bit reads towards the FIFO. 1387393e5e24SUlf Hansson */ 1388393e5e24SUlf Hansson if (unlikely(count & 0x3)) { 1389393e5e24SUlf Hansson if (count < 4) { 1390393e5e24SUlf Hansson unsigned char buf[4]; 13914b85da08SDavide Ciminaghi ioread32_rep(base + MMCIFIFO, buf, 1); 1392393e5e24SUlf Hansson memcpy(ptr, buf, count); 1393393e5e24SUlf Hansson } else { 13944b85da08SDavide Ciminaghi ioread32_rep(base + MMCIFIFO, ptr, count >> 2); 1395393e5e24SUlf Hansson count &= ~0x3; 1396393e5e24SUlf Hansson } 1397393e5e24SUlf Hansson } else { 13984b85da08SDavide Ciminaghi ioread32_rep(base + MMCIFIFO, ptr, count >> 2); 1399393e5e24SUlf Hansson } 14001c6a0718SPierre Ossman 14011c6a0718SPierre Ossman ptr += count; 14021c6a0718SPierre Ossman remain -= count; 140326eed9a5SLinus Walleij host_remain -= count; 14041c6a0718SPierre Ossman 14051c6a0718SPierre Ossman if (remain == 0) 14061c6a0718SPierre Ossman break; 14071c6a0718SPierre Ossman 14081c6a0718SPierre Ossman status = readl(base + MMCISTATUS); 14091c6a0718SPierre Ossman } while (status & MCI_RXDATAAVLBL); 14101c6a0718SPierre Ossman 14111c6a0718SPierre Ossman return ptr - buffer; 14121c6a0718SPierre Ossman } 14131c6a0718SPierre Ossman 14141c6a0718SPierre Ossman static int mmci_pio_write(struct mmci_host *host, char *buffer, unsigned int remain, u32 status) 14151c6a0718SPierre Ossman { 14168301bb68SRabin Vincent struct variant_data *variant = host->variant; 14171c6a0718SPierre Ossman void __iomem *base = host->base; 14181c6a0718SPierre Ossman char *ptr = buffer; 14191c6a0718SPierre Ossman 14201c6a0718SPierre Ossman do { 14211c6a0718SPierre Ossman unsigned int count, maxcnt; 14221c6a0718SPierre Ossman 14238301bb68SRabin Vincent maxcnt = status & MCI_TXFIFOEMPTY ? 14248301bb68SRabin Vincent variant->fifosize : variant->fifohalfsize; 14251c6a0718SPierre Ossman count = min(remain, maxcnt); 14261c6a0718SPierre Ossman 142734177802SLinus Walleij /* 142834177802SLinus Walleij * SDIO especially may want to send something that is 142934177802SLinus Walleij * not divisible by 4 (as opposed to card sectors 143034177802SLinus Walleij * etc), and the FIFO only accept full 32-bit writes. 143134177802SLinus Walleij * So compensate by adding +3 on the count, a single 143234177802SLinus Walleij * byte become a 32bit write, 7 bytes will be two 143334177802SLinus Walleij * 32bit writes etc. 143434177802SLinus Walleij */ 14354b85da08SDavide Ciminaghi iowrite32_rep(base + MMCIFIFO, ptr, (count + 3) >> 2); 14361c6a0718SPierre Ossman 14371c6a0718SPierre Ossman ptr += count; 14381c6a0718SPierre Ossman remain -= count; 14391c6a0718SPierre Ossman 14401c6a0718SPierre Ossman if (remain == 0) 14411c6a0718SPierre Ossman break; 14421c6a0718SPierre Ossman 14431c6a0718SPierre Ossman status = readl(base + MMCISTATUS); 14441c6a0718SPierre Ossman } while (status & MCI_TXFIFOHALFEMPTY); 14451c6a0718SPierre Ossman 14461c6a0718SPierre Ossman return ptr - buffer; 14471c6a0718SPierre Ossman } 14481c6a0718SPierre Ossman 14491c6a0718SPierre Ossman /* 14501c6a0718SPierre Ossman * PIO data transfer IRQ handler. 14511c6a0718SPierre Ossman */ 14521c6a0718SPierre Ossman static irqreturn_t mmci_pio_irq(int irq, void *dev_id) 14531c6a0718SPierre Ossman { 14541c6a0718SPierre Ossman struct mmci_host *host = dev_id; 14554ce1d6cbSRabin Vincent struct sg_mapping_iter *sg_miter = &host->sg_miter; 14568301bb68SRabin Vincent struct variant_data *variant = host->variant; 14571c6a0718SPierre Ossman void __iomem *base = host->base; 14581c6a0718SPierre Ossman u32 status; 14591c6a0718SPierre Ossman 14601c6a0718SPierre Ossman status = readl(base + MMCISTATUS); 14611c6a0718SPierre Ossman 146264de0289SLinus Walleij dev_dbg(mmc_dev(host->mmc), "irq1 (pio) %08x\n", status); 14631c6a0718SPierre Ossman 14641c6a0718SPierre Ossman do { 14651c6a0718SPierre Ossman unsigned int remain, len; 14661c6a0718SPierre Ossman char *buffer; 14671c6a0718SPierre Ossman 14681c6a0718SPierre Ossman /* 14691c6a0718SPierre Ossman * For write, we only need to test the half-empty flag 14701c6a0718SPierre Ossman * here - if the FIFO is completely empty, then by 14711c6a0718SPierre Ossman * definition it is more than half empty. 14721c6a0718SPierre Ossman * 14731c6a0718SPierre Ossman * For read, check for data available. 14741c6a0718SPierre Ossman */ 14751c6a0718SPierre Ossman if (!(status & (MCI_TXFIFOHALFEMPTY|MCI_RXDATAAVLBL))) 14761c6a0718SPierre Ossman break; 14771c6a0718SPierre Ossman 14784ce1d6cbSRabin Vincent if (!sg_miter_next(sg_miter)) 14794ce1d6cbSRabin Vincent break; 14804ce1d6cbSRabin Vincent 14814ce1d6cbSRabin Vincent buffer = sg_miter->addr; 14824ce1d6cbSRabin Vincent remain = sg_miter->length; 14831c6a0718SPierre Ossman 14841c6a0718SPierre Ossman len = 0; 14851c6a0718SPierre Ossman if (status & MCI_RXACTIVE) 14861c6a0718SPierre Ossman len = mmci_pio_read(host, buffer, remain); 14871c6a0718SPierre Ossman if (status & MCI_TXACTIVE) 14881c6a0718SPierre Ossman len = mmci_pio_write(host, buffer, remain, status); 14891c6a0718SPierre Ossman 14904ce1d6cbSRabin Vincent sg_miter->consumed = len; 14911c6a0718SPierre Ossman 14921c6a0718SPierre Ossman host->size -= len; 14931c6a0718SPierre Ossman remain -= len; 14941c6a0718SPierre Ossman 14951c6a0718SPierre Ossman if (remain) 14961c6a0718SPierre Ossman break; 14971c6a0718SPierre Ossman 14981c6a0718SPierre Ossman status = readl(base + MMCISTATUS); 14991c6a0718SPierre Ossman } while (1); 15001c6a0718SPierre Ossman 15014ce1d6cbSRabin Vincent sg_miter_stop(sg_miter); 15024ce1d6cbSRabin Vincent 15031c6a0718SPierre Ossman /* 1504c4d877c1SRussell King * If we have less than the fifo 'half-full' threshold to transfer, 1505c4d877c1SRussell King * trigger a PIO interrupt as soon as any data is available. 15061c6a0718SPierre Ossman */ 1507c4d877c1SRussell King if (status & MCI_RXACTIVE && host->size < variant->fifohalfsize) 15082686b4b4SLinus Walleij mmci_set_mask1(host, MCI_RXDATAAVLBLMASK); 15091c6a0718SPierre Ossman 15101c6a0718SPierre Ossman /* 15111c6a0718SPierre Ossman * If we run out of data, disable the data IRQs; this 15121c6a0718SPierre Ossman * prevents a race where the FIFO becomes empty before 15131c6a0718SPierre Ossman * the chip itself has disabled the data path, and 15141c6a0718SPierre Ossman * stops us racing with our data end IRQ. 15151c6a0718SPierre Ossman */ 15161c6a0718SPierre Ossman if (host->size == 0) { 15172686b4b4SLinus Walleij mmci_set_mask1(host, 0); 15181c6a0718SPierre Ossman writel(readl(base + MMCIMASK0) | MCI_DATAENDMASK, base + MMCIMASK0); 15191c6a0718SPierre Ossman } 15201c6a0718SPierre Ossman 15211c6a0718SPierre Ossman return IRQ_HANDLED; 15221c6a0718SPierre Ossman } 15231c6a0718SPierre Ossman 15241c6a0718SPierre Ossman /* 15251c6a0718SPierre Ossman * Handle completion of command and data transfers. 15261c6a0718SPierre Ossman */ 15271c6a0718SPierre Ossman static irqreturn_t mmci_irq(int irq, void *dev_id) 15281c6a0718SPierre Ossman { 15291c6a0718SPierre Ossman struct mmci_host *host = dev_id; 15301c6a0718SPierre Ossman u32 status; 15311c6a0718SPierre Ossman int ret = 0; 15321c6a0718SPierre Ossman 15331c6a0718SPierre Ossman spin_lock(&host->lock); 15341c6a0718SPierre Ossman 15351c6a0718SPierre Ossman do { 15361c6a0718SPierre Ossman status = readl(host->base + MMCISTATUS); 15372686b4b4SLinus Walleij 15382686b4b4SLinus Walleij if (host->singleirq) { 15396ea9cdf3SPatrice Chotard if (status & host->mask1_reg) 15402686b4b4SLinus Walleij mmci_pio_irq(irq, dev_id); 15412686b4b4SLinus Walleij 154259db5e2dSLudovic Barre status &= ~host->variant->irq_pio_mask; 15432686b4b4SLinus Walleij } 15442686b4b4SLinus Walleij 15458d94b54dSUlf Hansson /* 1546a9cbd79cSUlf Hansson * Busy detection is managed by mmci_cmd_irq(), including to 1547a9cbd79cSUlf Hansson * clear the corresponding IRQ. 15488d94b54dSUlf Hansson */ 15491c6a0718SPierre Ossman status &= readl(host->base + MMCIMASK0); 15505cad24d8SJean-Nicolas Graux if (host->variant->busy_detect) 15515cad24d8SJean-Nicolas Graux writel(status & ~host->variant->busy_detect_mask, 15525cad24d8SJean-Nicolas Graux host->base + MMCICLEAR); 15535cad24d8SJean-Nicolas Graux else 15541c6a0718SPierre Ossman writel(status, host->base + MMCICLEAR); 15551c6a0718SPierre Ossman 155664de0289SLinus Walleij dev_dbg(mmc_dev(host->mmc), "irq0 (data+cmd) %08x\n", status); 15571c6a0718SPierre Ossman 15587878289bSUlf Hansson if (host->variant->reversed_irq_handling) { 15597878289bSUlf Hansson mmci_data_irq(host, host->data, status); 15607878289bSUlf Hansson mmci_cmd_irq(host, host->cmd, status); 15617878289bSUlf Hansson } else { 1562ad82bfeaSUlf Hansson mmci_cmd_irq(host, host->cmd, status); 15631cb9da50SUlf Hansson mmci_data_irq(host, host->data, status); 15647878289bSUlf Hansson } 15651c6a0718SPierre Ossman 156649adc0caSLinus Walleij /* 15678520ce1eSLudovic Barre * Busy detection has been handled by mmci_cmd_irq() above. 15688520ce1eSLudovic Barre * Clear the status bit to prevent polling in IRQ context. 156949adc0caSLinus Walleij */ 15708520ce1eSLudovic Barre if (host->variant->busy_detect_flag) 157149adc0caSLinus Walleij status &= ~host->variant->busy_detect_flag; 15728d94b54dSUlf Hansson 15731c6a0718SPierre Ossman ret = 1; 15741c6a0718SPierre Ossman } while (status); 15751c6a0718SPierre Ossman 15761c6a0718SPierre Ossman spin_unlock(&host->lock); 15771c6a0718SPierre Ossman 15781c6a0718SPierre Ossman return IRQ_RETVAL(ret); 15791c6a0718SPierre Ossman } 15801c6a0718SPierre Ossman 15811c6a0718SPierre Ossman static void mmci_request(struct mmc_host *mmc, struct mmc_request *mrq) 15821c6a0718SPierre Ossman { 15831c6a0718SPierre Ossman struct mmci_host *host = mmc_priv(mmc); 15849e943021SLinus Walleij unsigned long flags; 15851c6a0718SPierre Ossman 15861c6a0718SPierre Ossman WARN_ON(host->mrq != NULL); 15871c6a0718SPierre Ossman 1588653a761eSUlf Hansson mrq->cmd->error = mmci_validate_data(host, mrq->data); 1589653a761eSUlf Hansson if (mrq->cmd->error) { 1590255d01afSPierre Ossman mmc_request_done(mmc, mrq); 1591255d01afSPierre Ossman return; 1592255d01afSPierre Ossman } 1593255d01afSPierre Ossman 15949e943021SLinus Walleij spin_lock_irqsave(&host->lock, flags); 15951c6a0718SPierre Ossman 15961c6a0718SPierre Ossman host->mrq = mrq; 15971c6a0718SPierre Ossman 159858c7ccbfSPer Forlin if (mrq->data) 159958c7ccbfSPer Forlin mmci_get_next_data(host, mrq->data); 160058c7ccbfSPer Forlin 1601d2141547SLudovic Barre if (mrq->data && 1602d2141547SLudovic Barre (host->variant->datactrl_first || mrq->data->flags & MMC_DATA_READ)) 16031c6a0718SPierre Ossman mmci_start_data(host, mrq->data); 16041c6a0718SPierre Ossman 1605024629c6SUlf Hansson if (mrq->sbc) 1606024629c6SUlf Hansson mmci_start_command(host, mrq->sbc, 0); 1607024629c6SUlf Hansson else 16081c6a0718SPierre Ossman mmci_start_command(host, mrq->cmd, 0); 16091c6a0718SPierre Ossman 16109e943021SLinus Walleij spin_unlock_irqrestore(&host->lock, flags); 16111c6a0718SPierre Ossman } 16121c6a0718SPierre Ossman 16138266c585SLudovic Barre static void mmci_set_max_busy_timeout(struct mmc_host *mmc) 16148266c585SLudovic Barre { 16158266c585SLudovic Barre struct mmci_host *host = mmc_priv(mmc); 16168266c585SLudovic Barre u32 max_busy_timeout = 0; 16178266c585SLudovic Barre 16188266c585SLudovic Barre if (!host->variant->busy_detect) 16198266c585SLudovic Barre return; 16208266c585SLudovic Barre 16218266c585SLudovic Barre if (host->variant->busy_timeout && mmc->actual_clock) 16228266c585SLudovic Barre max_busy_timeout = ~0UL / (mmc->actual_clock / MSEC_PER_SEC); 16238266c585SLudovic Barre 16248266c585SLudovic Barre mmc->max_busy_timeout = max_busy_timeout; 16258266c585SLudovic Barre } 16268266c585SLudovic Barre 16271c6a0718SPierre Ossman static void mmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) 16281c6a0718SPierre Ossman { 16291c6a0718SPierre Ossman struct mmci_host *host = mmc_priv(mmc); 16307d72a1d4SUlf Hansson struct variant_data *variant = host->variant; 1631a6a6464aSLinus Walleij u32 pwr = 0; 1632a6a6464aSLinus Walleij unsigned long flags; 1633db90f91fSLee Jones int ret; 16341c6a0718SPierre Ossman 1635bc521818SUlf Hansson if (host->plat->ios_handler && 1636bc521818SUlf Hansson host->plat->ios_handler(mmc_dev(mmc), ios)) 1637bc521818SUlf Hansson dev_err(mmc_dev(mmc), "platform ios_handler failed\n"); 1638bc521818SUlf Hansson 16391c6a0718SPierre Ossman switch (ios->power_mode) { 16401c6a0718SPierre Ossman case MMC_POWER_OFF: 1641599c1d5cSUlf Hansson if (!IS_ERR(mmc->supply.vmmc)) 1642599c1d5cSUlf Hansson mmc_regulator_set_ocr(mmc, mmc->supply.vmmc, 0); 1643237fb5e6SLee Jones 16447c0136efSUlf Hansson if (!IS_ERR(mmc->supply.vqmmc) && host->vqmmc_enabled) { 1645237fb5e6SLee Jones regulator_disable(mmc->supply.vqmmc); 16467c0136efSUlf Hansson host->vqmmc_enabled = false; 16477c0136efSUlf Hansson } 1648237fb5e6SLee Jones 16491c6a0718SPierre Ossman break; 16501c6a0718SPierre Ossman case MMC_POWER_UP: 1651599c1d5cSUlf Hansson if (!IS_ERR(mmc->supply.vmmc)) 1652599c1d5cSUlf Hansson mmc_regulator_set_ocr(mmc, mmc->supply.vmmc, ios->vdd); 1653599c1d5cSUlf Hansson 16547d72a1d4SUlf Hansson /* 16557d72a1d4SUlf Hansson * The ST Micro variant doesn't have the PL180s MCI_PWR_UP 16567d72a1d4SUlf Hansson * and instead uses MCI_PWR_ON so apply whatever value is 16577d72a1d4SUlf Hansson * configured in the variant data. 16587d72a1d4SUlf Hansson */ 16597d72a1d4SUlf Hansson pwr |= variant->pwrreg_powerup; 16607d72a1d4SUlf Hansson 16611c6a0718SPierre Ossman break; 16621c6a0718SPierre Ossman case MMC_POWER_ON: 16637c0136efSUlf Hansson if (!IS_ERR(mmc->supply.vqmmc) && !host->vqmmc_enabled) { 1664db90f91fSLee Jones ret = regulator_enable(mmc->supply.vqmmc); 1665db90f91fSLee Jones if (ret < 0) 1666db90f91fSLee Jones dev_err(mmc_dev(mmc), 1667db90f91fSLee Jones "failed to enable vqmmc regulator\n"); 16687c0136efSUlf Hansson else 16697c0136efSUlf Hansson host->vqmmc_enabled = true; 1670db90f91fSLee Jones } 1671237fb5e6SLee Jones 16721c6a0718SPierre Ossman pwr |= MCI_PWR_ON; 16731c6a0718SPierre Ossman break; 16741c6a0718SPierre Ossman } 16751c6a0718SPierre Ossman 16764d1a3a0dSUlf Hansson if (variant->signal_direction && ios->power_mode != MMC_POWER_OFF) { 16774d1a3a0dSUlf Hansson /* 16784d1a3a0dSUlf Hansson * The ST Micro variant has some additional bits 16794d1a3a0dSUlf Hansson * indicating signal direction for the signals in 16804d1a3a0dSUlf Hansson * the SD/MMC bus and feedback-clock usage. 16814d1a3a0dSUlf Hansson */ 16824593df29SUlf Hansson pwr |= host->pwr_reg_add; 16834d1a3a0dSUlf Hansson 16844d1a3a0dSUlf Hansson if (ios->bus_width == MMC_BUS_WIDTH_4) 16854d1a3a0dSUlf Hansson pwr &= ~MCI_ST_DATA74DIREN; 16864d1a3a0dSUlf Hansson else if (ios->bus_width == MMC_BUS_WIDTH_1) 16874d1a3a0dSUlf Hansson pwr &= (~MCI_ST_DATA74DIREN & 16884d1a3a0dSUlf Hansson ~MCI_ST_DATA31DIREN & 16894d1a3a0dSUlf Hansson ~MCI_ST_DATA2DIREN); 16904d1a3a0dSUlf Hansson } 16914d1a3a0dSUlf Hansson 1692f9bb304cSPatrice Chotard if (variant->opendrain) { 1693f9bb304cSPatrice Chotard if (ios->bus_mode == MMC_BUSMODE_OPENDRAIN) 169411dfb970SPatrice Chotard pwr |= variant->opendrain; 1695f9bb304cSPatrice Chotard } else { 1696f9bb304cSPatrice Chotard /* 1697f9bb304cSPatrice Chotard * If the variant cannot configure the pads by its own, then we 1698f9bb304cSPatrice Chotard * expect the pinctrl to be able to do that for us 1699f9bb304cSPatrice Chotard */ 1700f9bb304cSPatrice Chotard if (ios->bus_mode == MMC_BUSMODE_OPENDRAIN) 1701f9bb304cSPatrice Chotard pinctrl_select_state(host->pinctrl, host->pins_opendrain); 1702f9bb304cSPatrice Chotard else 1703f9bb304cSPatrice Chotard pinctrl_select_state(host->pinctrl, host->pins_default); 1704f9bb304cSPatrice Chotard } 17051c6a0718SPierre Ossman 1706f4670daeSUlf Hansson /* 1707f4670daeSUlf Hansson * If clock = 0 and the variant requires the MMCIPOWER to be used for 1708f4670daeSUlf Hansson * gating the clock, the MCI_PWR_ON bit is cleared. 1709f4670daeSUlf Hansson */ 1710f4670daeSUlf Hansson if (!ios->clock && variant->pwrreg_clkgate) 1711f4670daeSUlf Hansson pwr &= ~MCI_PWR_ON; 1712f4670daeSUlf Hansson 17133f4e6f7bSSrinivas Kandagatla if (host->variant->explicit_mclk_control && 17143f4e6f7bSSrinivas Kandagatla ios->clock != host->clock_cache) { 17153f4e6f7bSSrinivas Kandagatla ret = clk_set_rate(host->clk, ios->clock); 17163f4e6f7bSSrinivas Kandagatla if (ret < 0) 17173f4e6f7bSSrinivas Kandagatla dev_err(mmc_dev(host->mmc), 17183f4e6f7bSSrinivas Kandagatla "Error setting clock rate (%d)\n", ret); 17193f4e6f7bSSrinivas Kandagatla else 17203f4e6f7bSSrinivas Kandagatla host->mclk = clk_get_rate(host->clk); 17213f4e6f7bSSrinivas Kandagatla } 17223f4e6f7bSSrinivas Kandagatla host->clock_cache = ios->clock; 17233f4e6f7bSSrinivas Kandagatla 1724a6a6464aSLinus Walleij spin_lock_irqsave(&host->lock, flags); 1725a6a6464aSLinus Walleij 1726cd3ee8c5SLudovic Barre if (host->ops && host->ops->set_clkreg) 1727cd3ee8c5SLudovic Barre host->ops->set_clkreg(host, ios->clock); 1728cd3ee8c5SLudovic Barre else 1729a6a6464aSLinus Walleij mmci_set_clkreg(host, ios->clock); 1730cd3ee8c5SLudovic Barre 17318266c585SLudovic Barre mmci_set_max_busy_timeout(mmc); 17328266c585SLudovic Barre 1733cd3ee8c5SLudovic Barre if (host->ops && host->ops->set_pwrreg) 1734cd3ee8c5SLudovic Barre host->ops->set_pwrreg(host, pwr); 1735cd3ee8c5SLudovic Barre else 17367437cfa5SUlf Hansson mmci_write_pwrreg(host, pwr); 1737cd3ee8c5SLudovic Barre 1738f829c042SUlf Hansson mmci_reg_delay(host); 1739a6a6464aSLinus Walleij 1740a6a6464aSLinus Walleij spin_unlock_irqrestore(&host->lock, flags); 17411c6a0718SPierre Ossman } 17421c6a0718SPierre Ossman 174389001446SRussell King static int mmci_get_cd(struct mmc_host *mmc) 174489001446SRussell King { 174589001446SRussell King struct mmci_host *host = mmc_priv(mmc); 174629719445SRabin Vincent struct mmci_platform_data *plat = host->plat; 1747d2762090SUlf Hansson unsigned int status = mmc_gpio_get_cd(mmc); 174889001446SRussell King 1749d2762090SUlf Hansson if (status == -ENOSYS) { 17504b8caec0SRabin Vincent if (!plat->status) 17514b8caec0SRabin Vincent return 1; /* Assume always present */ 17524b8caec0SRabin Vincent 175329719445SRabin Vincent status = plat->status(mmc_dev(host->mmc)); 1754d2762090SUlf Hansson } 175574bc8093SRussell King return status; 175689001446SRussell King } 175789001446SRussell King 17580f3ed7f7SUlf Hansson static int mmci_sig_volt_switch(struct mmc_host *mmc, struct mmc_ios *ios) 17590f3ed7f7SUlf Hansson { 17600f3ed7f7SUlf Hansson int ret = 0; 17610f3ed7f7SUlf Hansson 17620f3ed7f7SUlf Hansson if (!IS_ERR(mmc->supply.vqmmc)) { 17630f3ed7f7SUlf Hansson 17640f3ed7f7SUlf Hansson switch (ios->signal_voltage) { 17650f3ed7f7SUlf Hansson case MMC_SIGNAL_VOLTAGE_330: 17660f3ed7f7SUlf Hansson ret = regulator_set_voltage(mmc->supply.vqmmc, 17670f3ed7f7SUlf Hansson 2700000, 3600000); 17680f3ed7f7SUlf Hansson break; 17690f3ed7f7SUlf Hansson case MMC_SIGNAL_VOLTAGE_180: 17700f3ed7f7SUlf Hansson ret = regulator_set_voltage(mmc->supply.vqmmc, 17710f3ed7f7SUlf Hansson 1700000, 1950000); 17720f3ed7f7SUlf Hansson break; 17730f3ed7f7SUlf Hansson case MMC_SIGNAL_VOLTAGE_120: 17740f3ed7f7SUlf Hansson ret = regulator_set_voltage(mmc->supply.vqmmc, 17750f3ed7f7SUlf Hansson 1100000, 1300000); 17760f3ed7f7SUlf Hansson break; 17770f3ed7f7SUlf Hansson } 17780f3ed7f7SUlf Hansson 17790f3ed7f7SUlf Hansson if (ret) 17800f3ed7f7SUlf Hansson dev_warn(mmc_dev(mmc), "Voltage switch failed\n"); 17810f3ed7f7SUlf Hansson } 17820f3ed7f7SUlf Hansson 17830f3ed7f7SUlf Hansson return ret; 17840f3ed7f7SUlf Hansson } 17850f3ed7f7SUlf Hansson 178601259620SUlf Hansson static struct mmc_host_ops mmci_ops = { 17871c6a0718SPierre Ossman .request = mmci_request, 178858c7ccbfSPer Forlin .pre_req = mmci_pre_request, 178958c7ccbfSPer Forlin .post_req = mmci_post_request, 17901c6a0718SPierre Ossman .set_ios = mmci_set_ios, 1791d2762090SUlf Hansson .get_ro = mmc_gpio_get_ro, 179289001446SRussell King .get_cd = mmci_get_cd, 17930f3ed7f7SUlf Hansson .start_signal_voltage_switch = mmci_sig_volt_switch, 17941c6a0718SPierre Ossman }; 17951c6a0718SPierre Ossman 179678f87df2SUlf Hansson static int mmci_of_parse(struct device_node *np, struct mmc_host *mmc) 179778f87df2SUlf Hansson { 17984593df29SUlf Hansson struct mmci_host *host = mmc_priv(mmc); 179978f87df2SUlf Hansson int ret = mmc_of_parse(mmc); 1800000bc9d5SLee Jones 180178f87df2SUlf Hansson if (ret) 180278f87df2SUlf Hansson return ret; 1803000bc9d5SLee Jones 18044593df29SUlf Hansson if (of_get_property(np, "st,sig-dir-dat0", NULL)) 18054593df29SUlf Hansson host->pwr_reg_add |= MCI_ST_DATA0DIREN; 18064593df29SUlf Hansson if (of_get_property(np, "st,sig-dir-dat2", NULL)) 18074593df29SUlf Hansson host->pwr_reg_add |= MCI_ST_DATA2DIREN; 18084593df29SUlf Hansson if (of_get_property(np, "st,sig-dir-dat31", NULL)) 18094593df29SUlf Hansson host->pwr_reg_add |= MCI_ST_DATA31DIREN; 18104593df29SUlf Hansson if (of_get_property(np, "st,sig-dir-dat74", NULL)) 18114593df29SUlf Hansson host->pwr_reg_add |= MCI_ST_DATA74DIREN; 18124593df29SUlf Hansson if (of_get_property(np, "st,sig-dir-cmd", NULL)) 18134593df29SUlf Hansson host->pwr_reg_add |= MCI_ST_CMDDIREN; 18144593df29SUlf Hansson if (of_get_property(np, "st,sig-pin-fbclk", NULL)) 18154593df29SUlf Hansson host->pwr_reg_add |= MCI_ST_FBCLKEN; 181646b723ddSLudovic Barre if (of_get_property(np, "st,sig-dir", NULL)) 181746b723ddSLudovic Barre host->pwr_reg_add |= MCI_STM32_DIRPOL; 181846b723ddSLudovic Barre if (of_get_property(np, "st,neg-edge", NULL)) 181946b723ddSLudovic Barre host->clk_reg_add |= MCI_STM32_CLK_NEGEDGE; 182046b723ddSLudovic Barre if (of_get_property(np, "st,use-ckin", NULL)) 182146b723ddSLudovic Barre host->clk_reg_add |= MCI_STM32_CLK_SELCKIN; 18224593df29SUlf Hansson 1823000bc9d5SLee Jones if (of_get_property(np, "mmc-cap-mmc-highspeed", NULL)) 182478f87df2SUlf Hansson mmc->caps |= MMC_CAP_MMC_HIGHSPEED; 1825000bc9d5SLee Jones if (of_get_property(np, "mmc-cap-sd-highspeed", NULL)) 182678f87df2SUlf Hansson mmc->caps |= MMC_CAP_SD_HIGHSPEED; 1827000bc9d5SLee Jones 182878f87df2SUlf Hansson return 0; 1829000bc9d5SLee Jones } 1830000bc9d5SLee Jones 1831c3be1efdSBill Pemberton static int mmci_probe(struct amba_device *dev, 1832aa25afadSRussell King const struct amba_id *id) 18331c6a0718SPierre Ossman { 18346ef297f8SLinus Walleij struct mmci_platform_data *plat = dev->dev.platform_data; 1835000bc9d5SLee Jones struct device_node *np = dev->dev.of_node; 18364956e109SRabin Vincent struct variant_data *variant = id->data; 18371c6a0718SPierre Ossman struct mmci_host *host; 18381c6a0718SPierre Ossman struct mmc_host *mmc; 18391c6a0718SPierre Ossman int ret; 18401c6a0718SPierre Ossman 1841000bc9d5SLee Jones /* Must have platform data or Device Tree. */ 1842000bc9d5SLee Jones if (!plat && !np) { 1843000bc9d5SLee Jones dev_err(&dev->dev, "No plat data or DT found\n"); 1844000bc9d5SLee Jones return -EINVAL; 18451c6a0718SPierre Ossman } 18461c6a0718SPierre Ossman 1847b9b52918SLee Jones if (!plat) { 1848b9b52918SLee Jones plat = devm_kzalloc(&dev->dev, sizeof(*plat), GFP_KERNEL); 1849b9b52918SLee Jones if (!plat) 1850b9b52918SLee Jones return -ENOMEM; 1851b9b52918SLee Jones } 1852b9b52918SLee Jones 18531c6a0718SPierre Ossman mmc = mmc_alloc_host(sizeof(struct mmci_host), &dev->dev); 1854ef289982SUlf Hansson if (!mmc) 1855ef289982SUlf Hansson return -ENOMEM; 18561c6a0718SPierre Ossman 185778f87df2SUlf Hansson ret = mmci_of_parse(np, mmc); 185878f87df2SUlf Hansson if (ret) 185978f87df2SUlf Hansson goto host_free; 186078f87df2SUlf Hansson 18611c6a0718SPierre Ossman host = mmc_priv(mmc); 18624ea580f1SRabin Vincent host->mmc = mmc; 1863012b7d33SRussell King 1864f9bb304cSPatrice Chotard /* 1865f9bb304cSPatrice Chotard * Some variant (STM32) doesn't have opendrain bit, nevertheless 1866f9bb304cSPatrice Chotard * pins can be set accordingly using pinctrl 1867f9bb304cSPatrice Chotard */ 1868f9bb304cSPatrice Chotard if (!variant->opendrain) { 1869f9bb304cSPatrice Chotard host->pinctrl = devm_pinctrl_get(&dev->dev); 1870f9bb304cSPatrice Chotard if (IS_ERR(host->pinctrl)) { 1871f9bb304cSPatrice Chotard dev_err(&dev->dev, "failed to get pinctrl"); 1872310eb252SWei Yongjun ret = PTR_ERR(host->pinctrl); 1873f9bb304cSPatrice Chotard goto host_free; 1874f9bb304cSPatrice Chotard } 1875f9bb304cSPatrice Chotard 1876f9bb304cSPatrice Chotard host->pins_default = pinctrl_lookup_state(host->pinctrl, 1877f9bb304cSPatrice Chotard PINCTRL_STATE_DEFAULT); 1878f9bb304cSPatrice Chotard if (IS_ERR(host->pins_default)) { 1879f9bb304cSPatrice Chotard dev_err(mmc_dev(mmc), "Can't select default pins\n"); 1880310eb252SWei Yongjun ret = PTR_ERR(host->pins_default); 1881f9bb304cSPatrice Chotard goto host_free; 1882f9bb304cSPatrice Chotard } 1883f9bb304cSPatrice Chotard 1884f9bb304cSPatrice Chotard host->pins_opendrain = pinctrl_lookup_state(host->pinctrl, 1885f9bb304cSPatrice Chotard MMCI_PINCTRL_STATE_OPENDRAIN); 1886f9bb304cSPatrice Chotard if (IS_ERR(host->pins_opendrain)) { 1887f9bb304cSPatrice Chotard dev_err(mmc_dev(mmc), "Can't select opendrain pins\n"); 1888310eb252SWei Yongjun ret = PTR_ERR(host->pins_opendrain); 1889f9bb304cSPatrice Chotard goto host_free; 1890f9bb304cSPatrice Chotard } 1891f9bb304cSPatrice Chotard } 1892f9bb304cSPatrice Chotard 1893012b7d33SRussell King host->hw_designer = amba_manf(dev); 1894012b7d33SRussell King host->hw_revision = amba_rev(dev); 189564de0289SLinus Walleij dev_dbg(mmc_dev(mmc), "designer ID = 0x%02x\n", host->hw_designer); 189664de0289SLinus Walleij dev_dbg(mmc_dev(mmc), "revision = 0x%01x\n", host->hw_revision); 1897012b7d33SRussell King 1898665ba56fSUlf Hansson host->clk = devm_clk_get(&dev->dev, NULL); 18991c6a0718SPierre Ossman if (IS_ERR(host->clk)) { 19001c6a0718SPierre Ossman ret = PTR_ERR(host->clk); 19011c6a0718SPierre Ossman goto host_free; 19021c6a0718SPierre Ossman } 19031c6a0718SPierre Ossman 1904ac940938SJulia Lawall ret = clk_prepare_enable(host->clk); 19051c6a0718SPierre Ossman if (ret) 1906665ba56fSUlf Hansson goto host_free; 19071c6a0718SPierre Ossman 19089c34b73dSSrinivas Kandagatla if (variant->qcom_fifo) 19099c34b73dSSrinivas Kandagatla host->get_rx_fifocnt = mmci_qcom_get_rx_fifocnt; 19109c34b73dSSrinivas Kandagatla else 19119c34b73dSSrinivas Kandagatla host->get_rx_fifocnt = mmci_get_rx_fifocnt; 19129c34b73dSSrinivas Kandagatla 19131c6a0718SPierre Ossman host->plat = plat; 19144956e109SRabin Vincent host->variant = variant; 19151c6a0718SPierre Ossman host->mclk = clk_get_rate(host->clk); 1916c8df9a53SLinus Walleij /* 1917c8df9a53SLinus Walleij * According to the spec, mclk is max 100 MHz, 1918c8df9a53SLinus Walleij * so we try to adjust the clock down to this, 1919c8df9a53SLinus Walleij * (if possible). 1920c8df9a53SLinus Walleij */ 1921dc6500bfSSrinivas Kandagatla if (host->mclk > variant->f_max) { 1922dc6500bfSSrinivas Kandagatla ret = clk_set_rate(host->clk, variant->f_max); 1923c8df9a53SLinus Walleij if (ret < 0) 1924c8df9a53SLinus Walleij goto clk_disable; 1925c8df9a53SLinus Walleij host->mclk = clk_get_rate(host->clk); 192664de0289SLinus Walleij dev_dbg(mmc_dev(mmc), "eventual mclk rate: %u Hz\n", 192764de0289SLinus Walleij host->mclk); 1928c8df9a53SLinus Walleij } 1929ef289982SUlf Hansson 1930c8ebae37SRussell King host->phybase = dev->res.start; 1931ef289982SUlf Hansson host->base = devm_ioremap_resource(&dev->dev, &dev->res); 1932ef289982SUlf Hansson if (IS_ERR(host->base)) { 1933ef289982SUlf Hansson ret = PTR_ERR(host->base); 19341c6a0718SPierre Ossman goto clk_disable; 19351c6a0718SPierre Ossman } 19361c6a0718SPierre Ossman 1937ed9067fdSUlf Hansson if (variant->init) 1938ed9067fdSUlf Hansson variant->init(host); 1939ed9067fdSUlf Hansson 19407f294e49SLinus Walleij /* 19417f294e49SLinus Walleij * The ARM and ST versions of the block have slightly different 19427f294e49SLinus Walleij * clock divider equations which means that the minimum divider 19437f294e49SLinus Walleij * differs too. 19443f4e6f7bSSrinivas Kandagatla * on Qualcomm like controllers get the nearest minimum clock to 100Khz 19457f294e49SLinus Walleij */ 19467f294e49SLinus Walleij if (variant->st_clkdiv) 19477f294e49SLinus Walleij mmc->f_min = DIV_ROUND_UP(host->mclk, 257); 194800e930d8SLudovic Barre else if (variant->stm32_clkdiv) 194900e930d8SLudovic Barre mmc->f_min = DIV_ROUND_UP(host->mclk, 2046); 19503f4e6f7bSSrinivas Kandagatla else if (variant->explicit_mclk_control) 19513f4e6f7bSSrinivas Kandagatla mmc->f_min = clk_round_rate(host->clk, 100000); 19527f294e49SLinus Walleij else 19537f294e49SLinus Walleij mmc->f_min = DIV_ROUND_UP(host->mclk, 512); 1954808d97ccSLinus Walleij /* 195578f87df2SUlf Hansson * If no maximum operating frequency is supplied, fall back to use 195678f87df2SUlf Hansson * the module parameter, which has a (low) default value in case it 195778f87df2SUlf Hansson * is not specified. Either value must not exceed the clock rate into 19585080a08dSUlf Hansson * the block, of course. 1959808d97ccSLinus Walleij */ 196078f87df2SUlf Hansson if (mmc->f_max) 19613f4e6f7bSSrinivas Kandagatla mmc->f_max = variant->explicit_mclk_control ? 19623f4e6f7bSSrinivas Kandagatla min(variant->f_max, mmc->f_max) : 19633f4e6f7bSSrinivas Kandagatla min(host->mclk, mmc->f_max); 1964808d97ccSLinus Walleij else 19653f4e6f7bSSrinivas Kandagatla mmc->f_max = variant->explicit_mclk_control ? 19663f4e6f7bSSrinivas Kandagatla fmax : min(host->mclk, fmax); 19673f4e6f7bSSrinivas Kandagatla 19683f4e6f7bSSrinivas Kandagatla 196964de0289SLinus Walleij dev_dbg(mmc_dev(mmc), "clocking block at %u Hz\n", mmc->f_max); 197064de0289SLinus Walleij 197115878e58SLudovic Barre host->rst = devm_reset_control_get_optional_exclusive(&dev->dev, NULL); 197215878e58SLudovic Barre if (IS_ERR(host->rst)) { 197315878e58SLudovic Barre ret = PTR_ERR(host->rst); 197415878e58SLudovic Barre goto clk_disable; 197515878e58SLudovic Barre } 197615878e58SLudovic Barre 1977599c1d5cSUlf Hansson /* Get regulators and the supported OCR mask */ 19789369c97cSBjorn Andersson ret = mmc_regulator_get_supply(mmc); 197951006952SWolfram Sang if (ret) 19809369c97cSBjorn Andersson goto clk_disable; 19819369c97cSBjorn Andersson 1982599c1d5cSUlf Hansson if (!mmc->ocr_avail) 19831c6a0718SPierre Ossman mmc->ocr_avail = plat->ocr_mask; 1984599c1d5cSUlf Hansson else if (plat->ocr_mask) 1985599c1d5cSUlf Hansson dev_warn(mmc_dev(mmc), "Platform OCR mask is ignored\n"); 1986599c1d5cSUlf Hansson 19879dd8a8b8SUlf Hansson /* We support these capabilities. */ 19889dd8a8b8SUlf Hansson mmc->caps |= MMC_CAP_CMD23; 19899dd8a8b8SUlf Hansson 199049adc0caSLinus Walleij /* 199149adc0caSLinus Walleij * Enable busy detection. 199249adc0caSLinus Walleij */ 19938d94b54dSUlf Hansson if (variant->busy_detect) { 19948d94b54dSUlf Hansson mmci_ops.card_busy = mmci_card_busy; 199549adc0caSLinus Walleij /* 199649adc0caSLinus Walleij * Not all variants have a flag to enable busy detection 199749adc0caSLinus Walleij * in the DPSM, but if they do, set it here. 199849adc0caSLinus Walleij */ 199949adc0caSLinus Walleij if (variant->busy_dpsm_flag) 200049adc0caSLinus Walleij mmci_write_datactrlreg(host, 200149adc0caSLinus Walleij host->variant->busy_dpsm_flag); 20028d94b54dSUlf Hansson mmc->caps |= MMC_CAP_WAIT_WHILE_BUSY; 20038d94b54dSUlf Hansson } 20048d94b54dSUlf Hansson 2005e9968c6fSUlf Hansson /* Prepare a CMD12 - needed to clear the DPSM on some variants. */ 2006e9968c6fSUlf Hansson host->stop_abort.opcode = MMC_STOP_TRANSMISSION; 2007e9968c6fSUlf Hansson host->stop_abort.arg = 0; 2008e9968c6fSUlf Hansson host->stop_abort.flags = MMC_RSP_R1B | MMC_CMD_AC; 2009e9968c6fSUlf Hansson 20108d94b54dSUlf Hansson mmc->ops = &mmci_ops; 20118d94b54dSUlf Hansson 201270be208fSUlf Hansson /* We support these PM capabilities. */ 201378f87df2SUlf Hansson mmc->pm_caps |= MMC_PM_KEEP_POWER; 201470be208fSUlf Hansson 20151c6a0718SPierre Ossman /* 20161c6a0718SPierre Ossman * We can do SGIO 20171c6a0718SPierre Ossman */ 2018a36274e0SMartin K. Petersen mmc->max_segs = NR_SG; 20191c6a0718SPierre Ossman 20201c6a0718SPierre Ossman /* 202108458ef6SRabin Vincent * Since only a certain number of bits are valid in the data length 202208458ef6SRabin Vincent * register, we must ensure that we don't exceed 2^num-1 bytes in a 202308458ef6SRabin Vincent * single request. 20241c6a0718SPierre Ossman */ 202508458ef6SRabin Vincent mmc->max_req_size = (1 << variant->datalength_bits) - 1; 20261c6a0718SPierre Ossman 20271c6a0718SPierre Ossman /* 20281c6a0718SPierre Ossman * Set the maximum segment size. Since we aren't doing DMA 20291c6a0718SPierre Ossman * (yet) we are only limited by the data length register. 20301c6a0718SPierre Ossman */ 20311c6a0718SPierre Ossman mmc->max_seg_size = mmc->max_req_size; 20321c6a0718SPierre Ossman 20331c6a0718SPierre Ossman /* 20341c6a0718SPierre Ossman * Block size can be up to 2048 bytes, but must be a power of two. 20351c6a0718SPierre Ossman */ 2036c931d495SLudovic Barre mmc->max_blk_size = 1 << variant->datactrl_blocksz; 20371c6a0718SPierre Ossman 20381c6a0718SPierre Ossman /* 20398f7f6b7eSWill Deacon * Limit the number of blocks transferred so that we don't overflow 20408f7f6b7eSWill Deacon * the maximum request size. 20411c6a0718SPierre Ossman */ 2042c931d495SLudovic Barre mmc->max_blk_count = mmc->max_req_size >> variant->datactrl_blocksz; 20431c6a0718SPierre Ossman 20441c6a0718SPierre Ossman spin_lock_init(&host->lock); 20451c6a0718SPierre Ossman 20461c6a0718SPierre Ossman writel(0, host->base + MMCIMASK0); 20476ea9cdf3SPatrice Chotard 20486ea9cdf3SPatrice Chotard if (variant->mmcimask1) 20491c6a0718SPierre Ossman writel(0, host->base + MMCIMASK1); 20506ea9cdf3SPatrice Chotard 20511c6a0718SPierre Ossman writel(0xfff, host->base + MMCICLEAR); 20521c6a0718SPierre Ossman 2053ce437aa4SLinus Walleij /* 2054ce437aa4SLinus Walleij * If: 2055ce437aa4SLinus Walleij * - not using DT but using a descriptor table, or 2056ce437aa4SLinus Walleij * - using a table of descriptors ALONGSIDE DT, or 2057ce437aa4SLinus Walleij * look up these descriptors named "cd" and "wp" right here, fail 20589ef986a6SLinus Walleij * silently of these do not exist 2059ce437aa4SLinus Walleij */ 2060ce437aa4SLinus Walleij if (!np) { 206189168b48SLinus Walleij ret = mmc_gpiod_request_cd(mmc, "cd", 0, false, 0, NULL); 2062ce437aa4SLinus Walleij if (ret == -EPROBE_DEFER) 2063ce437aa4SLinus Walleij goto clk_disable; 2064ce437aa4SLinus Walleij 2065a2b760a6SLinus Walleij ret = mmc_gpiod_request_ro(mmc, "wp", 0, 0, NULL); 2066ce437aa4SLinus Walleij if (ret == -EPROBE_DEFER) 2067ce437aa4SLinus Walleij goto clk_disable; 2068ce437aa4SLinus Walleij } 206989001446SRussell King 2070ef289982SUlf Hansson ret = devm_request_irq(&dev->dev, dev->irq[0], mmci_irq, IRQF_SHARED, 2071ef289982SUlf Hansson DRIVER_NAME " (cmd)", host); 20721c6a0718SPierre Ossman if (ret) 2073ef289982SUlf Hansson goto clk_disable; 20741c6a0718SPierre Ossman 2075dfb85185SRussell King if (!dev->irq[1]) 20762686b4b4SLinus Walleij host->singleirq = true; 20772686b4b4SLinus Walleij else { 2078ef289982SUlf Hansson ret = devm_request_irq(&dev->dev, dev->irq[1], mmci_pio_irq, 2079ef289982SUlf Hansson IRQF_SHARED, DRIVER_NAME " (pio)", host); 20801c6a0718SPierre Ossman if (ret) 2081ef289982SUlf Hansson goto clk_disable; 20822686b4b4SLinus Walleij } 20831c6a0718SPierre Ossman 2084daf9713cSLudovic Barre writel(MCI_IRQENABLE | variant->start_err, host->base + MMCIMASK0); 20851c6a0718SPierre Ossman 20861c6a0718SPierre Ossman amba_set_drvdata(dev, mmc); 20871c6a0718SPierre Ossman 2088c8ebae37SRussell King dev_info(&dev->dev, "%s: PL%03x manf %x rev%u at 0x%08llx irq %d,%d (pio)\n", 2089c8ebae37SRussell King mmc_hostname(mmc), amba_part(dev), amba_manf(dev), 2090c8ebae37SRussell King amba_rev(dev), (unsigned long long)dev->res.start, 2091c8ebae37SRussell King dev->irq[0], dev->irq[1]); 2092c8ebae37SRussell King 2093c8ebae37SRussell King mmci_dma_setup(host); 20941c6a0718SPierre Ossman 20952cd976c4SUlf Hansson pm_runtime_set_autosuspend_delay(&dev->dev, 50); 20962cd976c4SUlf Hansson pm_runtime_use_autosuspend(&dev->dev); 20971c3be369SRussell King 20988c11a94dSRussell King mmc_add_host(mmc); 20998c11a94dSRussell King 21006f2d3c89SUlf Hansson pm_runtime_put(&dev->dev); 21011c6a0718SPierre Ossman return 0; 21021c6a0718SPierre Ossman 21031c6a0718SPierre Ossman clk_disable: 2104ac940938SJulia Lawall clk_disable_unprepare(host->clk); 21051c6a0718SPierre Ossman host_free: 21061c6a0718SPierre Ossman mmc_free_host(mmc); 21071c6a0718SPierre Ossman return ret; 21081c6a0718SPierre Ossman } 21091c6a0718SPierre Ossman 21106e0ee714SBill Pemberton static int mmci_remove(struct amba_device *dev) 21111c6a0718SPierre Ossman { 21121c6a0718SPierre Ossman struct mmc_host *mmc = amba_get_drvdata(dev); 21131c6a0718SPierre Ossman 21141c6a0718SPierre Ossman if (mmc) { 21151c6a0718SPierre Ossman struct mmci_host *host = mmc_priv(mmc); 21166ea9cdf3SPatrice Chotard struct variant_data *variant = host->variant; 21171c6a0718SPierre Ossman 21181c3be369SRussell King /* 21191c3be369SRussell King * Undo pm_runtime_put() in probe. We use the _sync 21201c3be369SRussell King * version here so that we can access the primecell. 21211c3be369SRussell King */ 21221c3be369SRussell King pm_runtime_get_sync(&dev->dev); 21231c3be369SRussell King 21241c6a0718SPierre Ossman mmc_remove_host(mmc); 21251c6a0718SPierre Ossman 21261c6a0718SPierre Ossman writel(0, host->base + MMCIMASK0); 21276ea9cdf3SPatrice Chotard 21286ea9cdf3SPatrice Chotard if (variant->mmcimask1) 21291c6a0718SPierre Ossman writel(0, host->base + MMCIMASK1); 21301c6a0718SPierre Ossman 21311c6a0718SPierre Ossman writel(0, host->base + MMCICOMMAND); 21321c6a0718SPierre Ossman writel(0, host->base + MMCIDATACTRL); 21331c6a0718SPierre Ossman 2134c8ebae37SRussell King mmci_dma_release(host); 2135ac940938SJulia Lawall clk_disable_unprepare(host->clk); 21361c6a0718SPierre Ossman mmc_free_host(mmc); 21371c6a0718SPierre Ossman } 21381c6a0718SPierre Ossman 21391c6a0718SPierre Ossman return 0; 21401c6a0718SPierre Ossman } 21411c6a0718SPierre Ossman 2142571dce4fSUlf Hansson #ifdef CONFIG_PM 21431ff44433SUlf Hansson static void mmci_save(struct mmci_host *host) 21441ff44433SUlf Hansson { 21451ff44433SUlf Hansson unsigned long flags; 21461ff44433SUlf Hansson 21471ff44433SUlf Hansson spin_lock_irqsave(&host->lock, flags); 21481ff44433SUlf Hansson 21491ff44433SUlf Hansson writel(0, host->base + MMCIMASK0); 215042dcc89aSUlf Hansson if (host->variant->pwrreg_nopower) { 21511ff44433SUlf Hansson writel(0, host->base + MMCIDATACTRL); 21521ff44433SUlf Hansson writel(0, host->base + MMCIPOWER); 21531ff44433SUlf Hansson writel(0, host->base + MMCICLOCK); 215442dcc89aSUlf Hansson } 21551ff44433SUlf Hansson mmci_reg_delay(host); 21561ff44433SUlf Hansson 21571ff44433SUlf Hansson spin_unlock_irqrestore(&host->lock, flags); 21581ff44433SUlf Hansson } 21591ff44433SUlf Hansson 21601ff44433SUlf Hansson static void mmci_restore(struct mmci_host *host) 21611ff44433SUlf Hansson { 21621ff44433SUlf Hansson unsigned long flags; 21631ff44433SUlf Hansson 21641ff44433SUlf Hansson spin_lock_irqsave(&host->lock, flags); 21651ff44433SUlf Hansson 216642dcc89aSUlf Hansson if (host->variant->pwrreg_nopower) { 21671ff44433SUlf Hansson writel(host->clk_reg, host->base + MMCICLOCK); 21681ff44433SUlf Hansson writel(host->datactrl_reg, host->base + MMCIDATACTRL); 21691ff44433SUlf Hansson writel(host->pwr_reg, host->base + MMCIPOWER); 217042dcc89aSUlf Hansson } 2171daf9713cSLudovic Barre writel(MCI_IRQENABLE | host->variant->start_err, 2172daf9713cSLudovic Barre host->base + MMCIMASK0); 21731ff44433SUlf Hansson mmci_reg_delay(host); 21741ff44433SUlf Hansson 21751ff44433SUlf Hansson spin_unlock_irqrestore(&host->lock, flags); 21761ff44433SUlf Hansson } 21771ff44433SUlf Hansson 21788259293aSUlf Hansson static int mmci_runtime_suspend(struct device *dev) 21798259293aSUlf Hansson { 21808259293aSUlf Hansson struct amba_device *adev = to_amba_device(dev); 21818259293aSUlf Hansson struct mmc_host *mmc = amba_get_drvdata(adev); 21828259293aSUlf Hansson 21838259293aSUlf Hansson if (mmc) { 21848259293aSUlf Hansson struct mmci_host *host = mmc_priv(mmc); 2185e36bd9c6SUlf Hansson pinctrl_pm_select_sleep_state(dev); 21861ff44433SUlf Hansson mmci_save(host); 21878259293aSUlf Hansson clk_disable_unprepare(host->clk); 21888259293aSUlf Hansson } 21898259293aSUlf Hansson 21908259293aSUlf Hansson return 0; 21918259293aSUlf Hansson } 21928259293aSUlf Hansson 21938259293aSUlf Hansson static int mmci_runtime_resume(struct device *dev) 21948259293aSUlf Hansson { 21958259293aSUlf Hansson struct amba_device *adev = to_amba_device(dev); 21968259293aSUlf Hansson struct mmc_host *mmc = amba_get_drvdata(adev); 21978259293aSUlf Hansson 21988259293aSUlf Hansson if (mmc) { 21998259293aSUlf Hansson struct mmci_host *host = mmc_priv(mmc); 22008259293aSUlf Hansson clk_prepare_enable(host->clk); 22011ff44433SUlf Hansson mmci_restore(host); 2202e36bd9c6SUlf Hansson pinctrl_pm_select_default_state(dev); 22038259293aSUlf Hansson } 22048259293aSUlf Hansson 22058259293aSUlf Hansson return 0; 22068259293aSUlf Hansson } 22078259293aSUlf Hansson #endif 22088259293aSUlf Hansson 220948fa7003SUlf Hansson static const struct dev_pm_ops mmci_dev_pm_ops = { 2210f3737fa3SUlf Hansson SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, 2211f3737fa3SUlf Hansson pm_runtime_force_resume) 22126ed23b80SRafael J. Wysocki SET_RUNTIME_PM_OPS(mmci_runtime_suspend, mmci_runtime_resume, NULL) 221348fa7003SUlf Hansson }; 221448fa7003SUlf Hansson 221588411deaSArvind Yadav static const struct amba_id mmci_ids[] = { 22161c6a0718SPierre Ossman { 22171c6a0718SPierre Ossman .id = 0x00041180, 2218768fbc18SPawel Moll .mask = 0xff0fffff, 22194956e109SRabin Vincent .data = &variant_arm, 22201c6a0718SPierre Ossman }, 22211c6a0718SPierre Ossman { 2222768fbc18SPawel Moll .id = 0x01041180, 2223768fbc18SPawel Moll .mask = 0xff0fffff, 2224768fbc18SPawel Moll .data = &variant_arm_extended_fifo, 2225768fbc18SPawel Moll }, 2226768fbc18SPawel Moll { 22273a37298aSPawel Moll .id = 0x02041180, 22283a37298aSPawel Moll .mask = 0xff0fffff, 22293a37298aSPawel Moll .data = &variant_arm_extended_fifo_hwfc, 22303a37298aSPawel Moll }, 22313a37298aSPawel Moll { 22321c6a0718SPierre Ossman .id = 0x00041181, 22331c6a0718SPierre Ossman .mask = 0x000fffff, 22344956e109SRabin Vincent .data = &variant_arm, 22351c6a0718SPierre Ossman }, 2236cc30d60eSLinus Walleij /* ST Micro variants */ 2237cc30d60eSLinus Walleij { 2238cc30d60eSLinus Walleij .id = 0x00180180, 2239cc30d60eSLinus Walleij .mask = 0x00ffffff, 22404956e109SRabin Vincent .data = &variant_u300, 2241cc30d60eSLinus Walleij }, 2242cc30d60eSLinus Walleij { 224334fd4213SLinus Walleij .id = 0x10180180, 224434fd4213SLinus Walleij .mask = 0xf0ffffff, 224534fd4213SLinus Walleij .data = &variant_nomadik, 224634fd4213SLinus Walleij }, 224734fd4213SLinus Walleij { 2248cc30d60eSLinus Walleij .id = 0x00280180, 2249cc30d60eSLinus Walleij .mask = 0x00ffffff, 22500bcb7efdSLinus Walleij .data = &variant_nomadik, 22514956e109SRabin Vincent }, 22524956e109SRabin Vincent { 22534956e109SRabin Vincent .id = 0x00480180, 22541784b157SPhilippe Langlais .mask = 0xf0ffffff, 22554956e109SRabin Vincent .data = &variant_ux500, 2256cc30d60eSLinus Walleij }, 22571784b157SPhilippe Langlais { 22581784b157SPhilippe Langlais .id = 0x10480180, 22591784b157SPhilippe Langlais .mask = 0xf0ffffff, 22601784b157SPhilippe Langlais .data = &variant_ux500v2, 22611784b157SPhilippe Langlais }, 22622a9d6c80SPatrice Chotard { 22632a9d6c80SPatrice Chotard .id = 0x00880180, 22642a9d6c80SPatrice Chotard .mask = 0x00ffffff, 22652a9d6c80SPatrice Chotard .data = &variant_stm32, 22662a9d6c80SPatrice Chotard }, 226746b723ddSLudovic Barre { 226846b723ddSLudovic Barre .id = 0x10153180, 226946b723ddSLudovic Barre .mask = 0xf0ffffff, 227046b723ddSLudovic Barre .data = &variant_stm32_sdmmc, 227146b723ddSLudovic Barre }, 227255b604aeSSrinivas Kandagatla /* Qualcomm variants */ 227355b604aeSSrinivas Kandagatla { 227455b604aeSSrinivas Kandagatla .id = 0x00051180, 227555b604aeSSrinivas Kandagatla .mask = 0x000fffff, 227655b604aeSSrinivas Kandagatla .data = &variant_qcom, 227755b604aeSSrinivas Kandagatla }, 22781c6a0718SPierre Ossman { 0, 0 }, 22791c6a0718SPierre Ossman }; 22801c6a0718SPierre Ossman 22819f99835fSDave Martin MODULE_DEVICE_TABLE(amba, mmci_ids); 22829f99835fSDave Martin 22831c6a0718SPierre Ossman static struct amba_driver mmci_driver = { 22841c6a0718SPierre Ossman .drv = { 22851c6a0718SPierre Ossman .name = DRIVER_NAME, 228648fa7003SUlf Hansson .pm = &mmci_dev_pm_ops, 22871c6a0718SPierre Ossman }, 22881c6a0718SPierre Ossman .probe = mmci_probe, 22890433c143SBill Pemberton .remove = mmci_remove, 22901c6a0718SPierre Ossman .id_table = mmci_ids, 22911c6a0718SPierre Ossman }; 22921c6a0718SPierre Ossman 22939e5ed094Sviresh kumar module_amba_driver(mmci_driver); 22941c6a0718SPierre Ossman 22951c6a0718SPierre Ossman module_param(fmax, uint, 0444); 22961c6a0718SPierre Ossman 22971c6a0718SPierre Ossman MODULE_DESCRIPTION("ARM PrimeCell PL180/181 Multimedia Card Interface driver"); 22981c6a0718SPierre Ossman MODULE_LICENSE("GPL"); 2299