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> 2575773165SLudovic Barre #include <linux/mmc/sd.h> 26d2762090SUlf Hansson #include <linux/mmc/slot-gpio.h> 271c6a0718SPierre Ossman #include <linux/amba/bus.h> 281c6a0718SPierre Ossman #include <linux/clk.h> 29bd6dee6fSJens Axboe #include <linux/scatterlist.h> 309ef986a6SLinus Walleij #include <linux/of.h> 3134e84f39SLinus Walleij #include <linux/regulator/consumer.h> 32c8ebae37SRussell King #include <linux/dmaengine.h> 33c8ebae37SRussell King #include <linux/dma-mapping.h> 34c8ebae37SRussell King #include <linux/amba/mmci.h> 351c3be369SRussell King #include <linux/pm_runtime.h> 36258aea76SViresh Kumar #include <linux/types.h> 37a9a83785SLinus Walleij #include <linux/pinctrl/consumer.h> 3815878e58SLudovic Barre #include <linux/reset.h> 396351cac9SMarek Vasut #include <linux/gpio/consumer.h> 401c6a0718SPierre Ossman 411c6a0718SPierre Ossman #include <asm/div64.h> 421c6a0718SPierre Ossman #include <asm/io.h> 431c6a0718SPierre Ossman 441c6a0718SPierre Ossman #include "mmci.h" 451c6a0718SPierre Ossman 461c6a0718SPierre Ossman #define DRIVER_NAME "mmci-pl18x" 471c6a0718SPierre Ossman 4871953e0eSUlf Hansson static void mmci_variant_init(struct mmci_host *host); 49cb0335b7SLudovic Barre static void ux500_variant_init(struct mmci_host *host); 50b3fb9d64SLudovic Barre static void ux500v2_variant_init(struct mmci_host *host); 51c3647fdcSLudovic Barre 521c6a0718SPierre Ossman static unsigned int fmax = 515633; 531c6a0718SPierre Ossman 544956e109SRabin Vincent static struct variant_data variant_arm = { 558301bb68SRabin Vincent .fifosize = 16 * 4, 568301bb68SRabin Vincent .fifohalfsize = 8 * 4, 570f244804SLudovic Barre .cmdreg_cpsm_enable = MCI_CPSM_ENABLE, 580f244804SLudovic Barre .cmdreg_lrsp_crc = MCI_CPSM_RESPONSE | MCI_CPSM_LONGRSP, 590f244804SLudovic Barre .cmdreg_srsp_crc = MCI_CPSM_RESPONSE, 600f244804SLudovic Barre .cmdreg_srsp = MCI_CPSM_RESPONSE, 6108458ef6SRabin Vincent .datalength_bits = 16, 62c931d495SLudovic Barre .datactrl_blocksz = 11, 637d72a1d4SUlf Hansson .pwrreg_powerup = MCI_PWR_UP, 64dc6500bfSSrinivas Kandagatla .f_max = 100000000, 657878289bSUlf Hansson .reversed_irq_handling = true, 666ea9cdf3SPatrice Chotard .mmcimask1 = true, 6759db5e2dSLudovic Barre .irq_pio_mask = MCI_IRQ_PIO_MASK, 687f7b5503SPatrice Chotard .start_err = MCI_STARTBITERR, 6911dfb970SPatrice Chotard .opendrain = MCI_ROD, 70c3647fdcSLudovic Barre .init = mmci_variant_init, 714956e109SRabin Vincent }; 724956e109SRabin Vincent 73768fbc18SPawel Moll static struct variant_data variant_arm_extended_fifo = { 74768fbc18SPawel Moll .fifosize = 128 * 4, 75768fbc18SPawel Moll .fifohalfsize = 64 * 4, 760f244804SLudovic Barre .cmdreg_cpsm_enable = MCI_CPSM_ENABLE, 770f244804SLudovic Barre .cmdreg_lrsp_crc = MCI_CPSM_RESPONSE | MCI_CPSM_LONGRSP, 780f244804SLudovic Barre .cmdreg_srsp_crc = MCI_CPSM_RESPONSE, 790f244804SLudovic Barre .cmdreg_srsp = MCI_CPSM_RESPONSE, 80768fbc18SPawel Moll .datalength_bits = 16, 81c931d495SLudovic Barre .datactrl_blocksz = 11, 827d72a1d4SUlf Hansson .pwrreg_powerup = MCI_PWR_UP, 83dc6500bfSSrinivas Kandagatla .f_max = 100000000, 846ea9cdf3SPatrice Chotard .mmcimask1 = true, 8559db5e2dSLudovic Barre .irq_pio_mask = MCI_IRQ_PIO_MASK, 867f7b5503SPatrice Chotard .start_err = MCI_STARTBITERR, 8711dfb970SPatrice Chotard .opendrain = MCI_ROD, 88c3647fdcSLudovic Barre .init = mmci_variant_init, 89768fbc18SPawel Moll }; 90768fbc18SPawel Moll 913a37298aSPawel Moll static struct variant_data variant_arm_extended_fifo_hwfc = { 923a37298aSPawel Moll .fifosize = 128 * 4, 933a37298aSPawel Moll .fifohalfsize = 64 * 4, 943a37298aSPawel Moll .clkreg_enable = MCI_ARM_HWFCEN, 950f244804SLudovic Barre .cmdreg_cpsm_enable = MCI_CPSM_ENABLE, 960f244804SLudovic Barre .cmdreg_lrsp_crc = MCI_CPSM_RESPONSE | MCI_CPSM_LONGRSP, 970f244804SLudovic Barre .cmdreg_srsp_crc = MCI_CPSM_RESPONSE, 980f244804SLudovic Barre .cmdreg_srsp = MCI_CPSM_RESPONSE, 993a37298aSPawel Moll .datalength_bits = 16, 100c931d495SLudovic Barre .datactrl_blocksz = 11, 1013a37298aSPawel Moll .pwrreg_powerup = MCI_PWR_UP, 102dc6500bfSSrinivas Kandagatla .f_max = 100000000, 1036ea9cdf3SPatrice Chotard .mmcimask1 = true, 10459db5e2dSLudovic Barre .irq_pio_mask = MCI_IRQ_PIO_MASK, 1057f7b5503SPatrice Chotard .start_err = MCI_STARTBITERR, 10611dfb970SPatrice Chotard .opendrain = MCI_ROD, 107c3647fdcSLudovic Barre .init = mmci_variant_init, 1083a37298aSPawel Moll }; 1093a37298aSPawel Moll 1104956e109SRabin Vincent static struct variant_data variant_u300 = { 1118301bb68SRabin Vincent .fifosize = 16 * 4, 1128301bb68SRabin Vincent .fifohalfsize = 8 * 4, 11349ac215eSLinus Walleij .clkreg_enable = MCI_ST_U300_HWFCEN, 114e1412d85SSrinivas Kandagatla .clkreg_8bit_bus_enable = MCI_ST_8BIT_BUS, 1150f244804SLudovic Barre .cmdreg_cpsm_enable = MCI_CPSM_ENABLE, 1160f244804SLudovic Barre .cmdreg_lrsp_crc = MCI_CPSM_RESPONSE | MCI_CPSM_LONGRSP, 1170f244804SLudovic Barre .cmdreg_srsp_crc = MCI_CPSM_RESPONSE, 1180f244804SLudovic Barre .cmdreg_srsp = MCI_CPSM_RESPONSE, 11908458ef6SRabin Vincent .datalength_bits = 16, 120c931d495SLudovic Barre .datactrl_blocksz = 11, 1215db3eee7SLinus Walleij .datactrl_mask_sdio = MCI_DPSM_ST_SDIOEN, 122c7354133SSrinivas Kandagatla .st_sdio = true, 1237d72a1d4SUlf Hansson .pwrreg_powerup = MCI_PWR_ON, 124dc6500bfSSrinivas Kandagatla .f_max = 100000000, 1254d1a3a0dSUlf Hansson .signal_direction = true, 126f4670daeSUlf Hansson .pwrreg_clkgate = true, 1271ff44433SUlf Hansson .pwrreg_nopower = true, 1286ea9cdf3SPatrice Chotard .mmcimask1 = true, 12959db5e2dSLudovic Barre .irq_pio_mask = MCI_IRQ_PIO_MASK, 1307f7b5503SPatrice Chotard .start_err = MCI_STARTBITERR, 13111dfb970SPatrice Chotard .opendrain = MCI_OD, 132c3647fdcSLudovic Barre .init = mmci_variant_init, 1334956e109SRabin Vincent }; 1344956e109SRabin Vincent 13534fd4213SLinus Walleij static struct variant_data variant_nomadik = { 13634fd4213SLinus Walleij .fifosize = 16 * 4, 13734fd4213SLinus Walleij .fifohalfsize = 8 * 4, 13834fd4213SLinus Walleij .clkreg = MCI_CLK_ENABLE, 139f5abc767SLinus Walleij .clkreg_8bit_bus_enable = MCI_ST_8BIT_BUS, 1400f244804SLudovic Barre .cmdreg_cpsm_enable = MCI_CPSM_ENABLE, 1410f244804SLudovic Barre .cmdreg_lrsp_crc = MCI_CPSM_RESPONSE | MCI_CPSM_LONGRSP, 1420f244804SLudovic Barre .cmdreg_srsp_crc = MCI_CPSM_RESPONSE, 1430f244804SLudovic Barre .cmdreg_srsp = MCI_CPSM_RESPONSE, 14434fd4213SLinus Walleij .datalength_bits = 24, 145c931d495SLudovic Barre .datactrl_blocksz = 11, 1465db3eee7SLinus Walleij .datactrl_mask_sdio = MCI_DPSM_ST_SDIOEN, 147c7354133SSrinivas Kandagatla .st_sdio = true, 14834fd4213SLinus Walleij .st_clkdiv = true, 14934fd4213SLinus Walleij .pwrreg_powerup = MCI_PWR_ON, 150dc6500bfSSrinivas Kandagatla .f_max = 100000000, 15134fd4213SLinus Walleij .signal_direction = true, 152f4670daeSUlf Hansson .pwrreg_clkgate = true, 1531ff44433SUlf Hansson .pwrreg_nopower = true, 1546ea9cdf3SPatrice Chotard .mmcimask1 = true, 15559db5e2dSLudovic Barre .irq_pio_mask = MCI_IRQ_PIO_MASK, 1567f7b5503SPatrice Chotard .start_err = MCI_STARTBITERR, 15711dfb970SPatrice Chotard .opendrain = MCI_OD, 158c3647fdcSLudovic Barre .init = mmci_variant_init, 15934fd4213SLinus Walleij }; 16034fd4213SLinus Walleij 1614956e109SRabin Vincent static struct variant_data variant_ux500 = { 1628301bb68SRabin Vincent .fifosize = 30 * 4, 1638301bb68SRabin Vincent .fifohalfsize = 8 * 4, 1644956e109SRabin Vincent .clkreg = MCI_CLK_ENABLE, 16549ac215eSLinus Walleij .clkreg_enable = MCI_ST_UX500_HWFCEN, 166e1412d85SSrinivas Kandagatla .clkreg_8bit_bus_enable = MCI_ST_8BIT_BUS, 167e8740644SSrinivas Kandagatla .clkreg_neg_edge_enable = MCI_ST_UX500_NEG_EDGE, 1680f244804SLudovic Barre .cmdreg_cpsm_enable = MCI_CPSM_ENABLE, 1690f244804SLudovic Barre .cmdreg_lrsp_crc = MCI_CPSM_RESPONSE | MCI_CPSM_LONGRSP, 1700f244804SLudovic Barre .cmdreg_srsp_crc = MCI_CPSM_RESPONSE, 1710f244804SLudovic Barre .cmdreg_srsp = MCI_CPSM_RESPONSE, 17208458ef6SRabin Vincent .datalength_bits = 24, 173c931d495SLudovic Barre .datactrl_blocksz = 11, 1742253ed4bSLinus Walleij .datactrl_any_blocksz = true, 1752253ed4bSLinus Walleij .dma_power_of_2 = true, 1765db3eee7SLinus Walleij .datactrl_mask_sdio = MCI_DPSM_ST_SDIOEN, 177c7354133SSrinivas Kandagatla .st_sdio = true, 178b70a67f9SLinus Walleij .st_clkdiv = true, 1797d72a1d4SUlf Hansson .pwrreg_powerup = MCI_PWR_ON, 180dc6500bfSSrinivas Kandagatla .f_max = 100000000, 1814d1a3a0dSUlf Hansson .signal_direction = true, 182f4670daeSUlf Hansson .pwrreg_clkgate = true, 18301259620SUlf Hansson .busy_detect = true, 18449adc0caSLinus Walleij .busy_dpsm_flag = MCI_DPSM_ST_BUSYMODE, 18549adc0caSLinus Walleij .busy_detect_flag = MCI_ST_CARDBUSY, 18649adc0caSLinus Walleij .busy_detect_mask = MCI_ST_BUSYENDMASK, 1871ff44433SUlf Hansson .pwrreg_nopower = true, 1886ea9cdf3SPatrice Chotard .mmcimask1 = true, 18959db5e2dSLudovic Barre .irq_pio_mask = MCI_IRQ_PIO_MASK, 1907f7b5503SPatrice Chotard .start_err = MCI_STARTBITERR, 19111dfb970SPatrice Chotard .opendrain = MCI_OD, 192cb0335b7SLudovic Barre .init = ux500_variant_init, 1934956e109SRabin Vincent }; 194b70a67f9SLinus Walleij 1951784b157SPhilippe Langlais static struct variant_data variant_ux500v2 = { 1961784b157SPhilippe Langlais .fifosize = 30 * 4, 1971784b157SPhilippe Langlais .fifohalfsize = 8 * 4, 1981784b157SPhilippe Langlais .clkreg = MCI_CLK_ENABLE, 1991784b157SPhilippe Langlais .clkreg_enable = MCI_ST_UX500_HWFCEN, 200e1412d85SSrinivas Kandagatla .clkreg_8bit_bus_enable = MCI_ST_8BIT_BUS, 201e8740644SSrinivas Kandagatla .clkreg_neg_edge_enable = MCI_ST_UX500_NEG_EDGE, 2020f244804SLudovic Barre .cmdreg_cpsm_enable = MCI_CPSM_ENABLE, 2030f244804SLudovic Barre .cmdreg_lrsp_crc = MCI_CPSM_RESPONSE | MCI_CPSM_LONGRSP, 2040f244804SLudovic Barre .cmdreg_srsp_crc = MCI_CPSM_RESPONSE, 2050f244804SLudovic Barre .cmdreg_srsp = MCI_CPSM_RESPONSE, 2065db3eee7SLinus Walleij .datactrl_mask_ddrmode = MCI_DPSM_ST_DDRMODE, 2071784b157SPhilippe Langlais .datalength_bits = 24, 208c931d495SLudovic Barre .datactrl_blocksz = 11, 2092253ed4bSLinus Walleij .datactrl_any_blocksz = true, 2102253ed4bSLinus Walleij .dma_power_of_2 = true, 2115db3eee7SLinus Walleij .datactrl_mask_sdio = MCI_DPSM_ST_SDIOEN, 212c7354133SSrinivas Kandagatla .st_sdio = true, 2131784b157SPhilippe Langlais .st_clkdiv = true, 2147d72a1d4SUlf Hansson .pwrreg_powerup = MCI_PWR_ON, 215dc6500bfSSrinivas Kandagatla .f_max = 100000000, 2164d1a3a0dSUlf Hansson .signal_direction = true, 217f4670daeSUlf Hansson .pwrreg_clkgate = true, 21801259620SUlf Hansson .busy_detect = true, 21949adc0caSLinus Walleij .busy_dpsm_flag = MCI_DPSM_ST_BUSYMODE, 22049adc0caSLinus Walleij .busy_detect_flag = MCI_ST_CARDBUSY, 22149adc0caSLinus Walleij .busy_detect_mask = MCI_ST_BUSYENDMASK, 2221ff44433SUlf Hansson .pwrreg_nopower = true, 2236ea9cdf3SPatrice Chotard .mmcimask1 = true, 22459db5e2dSLudovic Barre .irq_pio_mask = MCI_IRQ_PIO_MASK, 2257f7b5503SPatrice Chotard .start_err = MCI_STARTBITERR, 22611dfb970SPatrice Chotard .opendrain = MCI_OD, 227b3fb9d64SLudovic Barre .init = ux500v2_variant_init, 2281784b157SPhilippe Langlais }; 2291784b157SPhilippe Langlais 2302a9d6c80SPatrice Chotard static struct variant_data variant_stm32 = { 2312a9d6c80SPatrice Chotard .fifosize = 32 * 4, 2322a9d6c80SPatrice Chotard .fifohalfsize = 8 * 4, 2332a9d6c80SPatrice Chotard .clkreg = MCI_CLK_ENABLE, 2342a9d6c80SPatrice Chotard .clkreg_enable = MCI_ST_UX500_HWFCEN, 2352a9d6c80SPatrice Chotard .clkreg_8bit_bus_enable = MCI_ST_8BIT_BUS, 2362a9d6c80SPatrice Chotard .clkreg_neg_edge_enable = MCI_ST_UX500_NEG_EDGE, 2370f244804SLudovic Barre .cmdreg_cpsm_enable = MCI_CPSM_ENABLE, 2380f244804SLudovic Barre .cmdreg_lrsp_crc = MCI_CPSM_RESPONSE | MCI_CPSM_LONGRSP, 2390f244804SLudovic Barre .cmdreg_srsp_crc = MCI_CPSM_RESPONSE, 2400f244804SLudovic Barre .cmdreg_srsp = MCI_CPSM_RESPONSE, 24159db5e2dSLudovic Barre .irq_pio_mask = MCI_IRQ_PIO_MASK, 2422a9d6c80SPatrice Chotard .datalength_bits = 24, 243c931d495SLudovic Barre .datactrl_blocksz = 11, 2442a9d6c80SPatrice Chotard .datactrl_mask_sdio = MCI_DPSM_ST_SDIOEN, 2452a9d6c80SPatrice Chotard .st_sdio = true, 2462a9d6c80SPatrice Chotard .st_clkdiv = true, 2472a9d6c80SPatrice Chotard .pwrreg_powerup = MCI_PWR_ON, 2482a9d6c80SPatrice Chotard .f_max = 48000000, 2492a9d6c80SPatrice Chotard .pwrreg_clkgate = true, 2502a9d6c80SPatrice Chotard .pwrreg_nopower = true, 251c3647fdcSLudovic Barre .init = mmci_variant_init, 2522a9d6c80SPatrice Chotard }; 2532a9d6c80SPatrice Chotard 25446b723ddSLudovic Barre static struct variant_data variant_stm32_sdmmc = { 25546b723ddSLudovic Barre .fifosize = 16 * 4, 25646b723ddSLudovic Barre .fifohalfsize = 8 * 4, 25746b723ddSLudovic Barre .f_max = 208000000, 25846b723ddSLudovic Barre .stm32_clkdiv = true, 25946b723ddSLudovic Barre .cmdreg_cpsm_enable = MCI_CPSM_STM32_ENABLE, 26046b723ddSLudovic Barre .cmdreg_lrsp_crc = MCI_CPSM_STM32_LRSP_CRC, 26146b723ddSLudovic Barre .cmdreg_srsp_crc = MCI_CPSM_STM32_SRSP_CRC, 26246b723ddSLudovic Barre .cmdreg_srsp = MCI_CPSM_STM32_SRSP, 263c8073e52SLudovic Barre .cmdreg_stop = MCI_CPSM_STM32_CMDSTOP, 26446b723ddSLudovic Barre .data_cmd_enable = MCI_CPSM_STM32_CMDTRANS, 26546b723ddSLudovic Barre .irq_pio_mask = MCI_IRQ_PIO_STM32_MASK, 26646b723ddSLudovic Barre .datactrl_first = true, 26746b723ddSLudovic Barre .datacnt_useless = true, 26846b723ddSLudovic Barre .datalength_bits = 25, 26946b723ddSLudovic Barre .datactrl_blocksz = 14, 2702253ed4bSLinus Walleij .datactrl_any_blocksz = true, 27181a77ee9SLudovic Barre .datactrl_mask_sdio = MCI_DPSM_ST_SDIOEN, 27246b723ddSLudovic Barre .stm32_idmabsize_mask = GENMASK(12, 5), 2730e68de6aSLudovic Barre .busy_timeout = true, 2740e68de6aSLudovic Barre .busy_detect = true, 2750e68de6aSLudovic Barre .busy_detect_flag = MCI_STM32_BUSYD0, 2760e68de6aSLudovic Barre .busy_detect_mask = MCI_STM32_BUSYD0ENDMASK, 27746b723ddSLudovic Barre .init = sdmmc_variant_init, 27846b723ddSLudovic Barre }; 27946b723ddSLudovic Barre 2807a2a98beSLudovic Barre static struct variant_data variant_stm32_sdmmcv2 = { 2817a2a98beSLudovic Barre .fifosize = 16 * 4, 2827a2a98beSLudovic Barre .fifohalfsize = 8 * 4, 2834481ab60SYann Gautier .f_max = 267000000, 2847a2a98beSLudovic Barre .stm32_clkdiv = true, 2857a2a98beSLudovic Barre .cmdreg_cpsm_enable = MCI_CPSM_STM32_ENABLE, 2867a2a98beSLudovic Barre .cmdreg_lrsp_crc = MCI_CPSM_STM32_LRSP_CRC, 2877a2a98beSLudovic Barre .cmdreg_srsp_crc = MCI_CPSM_STM32_SRSP_CRC, 2887a2a98beSLudovic Barre .cmdreg_srsp = MCI_CPSM_STM32_SRSP, 2897a2a98beSLudovic Barre .cmdreg_stop = MCI_CPSM_STM32_CMDSTOP, 2907a2a98beSLudovic Barre .data_cmd_enable = MCI_CPSM_STM32_CMDTRANS, 2917a2a98beSLudovic Barre .irq_pio_mask = MCI_IRQ_PIO_STM32_MASK, 2927a2a98beSLudovic Barre .datactrl_first = true, 2937a2a98beSLudovic Barre .datacnt_useless = true, 2947a2a98beSLudovic Barre .datalength_bits = 25, 2957a2a98beSLudovic Barre .datactrl_blocksz = 14, 2967a2a98beSLudovic Barre .datactrl_any_blocksz = true, 29781a77ee9SLudovic Barre .datactrl_mask_sdio = MCI_DPSM_ST_SDIOEN, 2987a2a98beSLudovic Barre .stm32_idmabsize_mask = GENMASK(16, 5), 2997a2a98beSLudovic Barre .dma_lli = true, 3007a2a98beSLudovic Barre .busy_timeout = true, 3017a2a98beSLudovic Barre .busy_detect = true, 3027a2a98beSLudovic Barre .busy_detect_flag = MCI_STM32_BUSYD0, 3037a2a98beSLudovic Barre .busy_detect_mask = MCI_STM32_BUSYD0ENDMASK, 3047a2a98beSLudovic Barre .init = sdmmc_variant_init, 3057a2a98beSLudovic Barre }; 3067a2a98beSLudovic Barre 30755b604aeSSrinivas Kandagatla static struct variant_data variant_qcom = { 30855b604aeSSrinivas Kandagatla .fifosize = 16 * 4, 30955b604aeSSrinivas Kandagatla .fifohalfsize = 8 * 4, 31055b604aeSSrinivas Kandagatla .clkreg = MCI_CLK_ENABLE, 31155b604aeSSrinivas Kandagatla .clkreg_enable = MCI_QCOM_CLK_FLOWENA | 31255b604aeSSrinivas Kandagatla MCI_QCOM_CLK_SELECT_IN_FBCLK, 31355b604aeSSrinivas Kandagatla .clkreg_8bit_bus_enable = MCI_QCOM_CLK_WIDEBUS_8, 31455b604aeSSrinivas Kandagatla .datactrl_mask_ddrmode = MCI_QCOM_CLK_SELECT_IN_DDR_MODE, 3150f244804SLudovic Barre .cmdreg_cpsm_enable = MCI_CPSM_ENABLE, 3160f244804SLudovic Barre .cmdreg_lrsp_crc = MCI_CPSM_RESPONSE | MCI_CPSM_LONGRSP, 3170f244804SLudovic Barre .cmdreg_srsp_crc = MCI_CPSM_RESPONSE, 3180f244804SLudovic Barre .cmdreg_srsp = MCI_CPSM_RESPONSE, 3195db3eee7SLinus Walleij .data_cmd_enable = MCI_CPSM_QCOM_DATCMD, 32055b604aeSSrinivas Kandagatla .datalength_bits = 24, 321c931d495SLudovic Barre .datactrl_blocksz = 11, 3222253ed4bSLinus Walleij .datactrl_any_blocksz = true, 32355b604aeSSrinivas Kandagatla .pwrreg_powerup = MCI_PWR_UP, 32455b604aeSSrinivas Kandagatla .f_max = 208000000, 32555b604aeSSrinivas Kandagatla .explicit_mclk_control = true, 32655b604aeSSrinivas Kandagatla .qcom_fifo = true, 3279cb15142SSrinivas Kandagatla .qcom_dml = true, 3286ea9cdf3SPatrice Chotard .mmcimask1 = true, 32959db5e2dSLudovic Barre .irq_pio_mask = MCI_IRQ_PIO_MASK, 3307f7b5503SPatrice Chotard .start_err = MCI_STARTBITERR, 33111dfb970SPatrice Chotard .opendrain = MCI_ROD, 33229aba07aSUlf Hansson .init = qcom_variant_init, 33355b604aeSSrinivas Kandagatla }; 33455b604aeSSrinivas Kandagatla 33549adc0caSLinus Walleij /* Busy detection for the ST Micro variant */ 33601259620SUlf Hansson static int mmci_card_busy(struct mmc_host *mmc) 33701259620SUlf Hansson { 33801259620SUlf Hansson struct mmci_host *host = mmc_priv(mmc); 33901259620SUlf Hansson unsigned long flags; 34001259620SUlf Hansson int busy = 0; 34101259620SUlf Hansson 34201259620SUlf Hansson spin_lock_irqsave(&host->lock, flags); 34349adc0caSLinus Walleij if (readl(host->base + MMCISTATUS) & host->variant->busy_detect_flag) 34401259620SUlf Hansson busy = 1; 34501259620SUlf Hansson spin_unlock_irqrestore(&host->lock, flags); 34601259620SUlf Hansson 34701259620SUlf Hansson return busy; 34801259620SUlf Hansson } 34901259620SUlf Hansson 350f829c042SUlf Hansson static void mmci_reg_delay(struct mmci_host *host) 351f829c042SUlf Hansson { 352f829c042SUlf Hansson /* 353f829c042SUlf Hansson * According to the spec, at least three feedback clock cycles 354f829c042SUlf Hansson * of max 52 MHz must pass between two writes to the MMCICLOCK reg. 355f829c042SUlf Hansson * Three MCLK clock cycles must pass between two MMCIPOWER reg writes. 356f829c042SUlf Hansson * Worst delay time during card init is at 100 kHz => 30 us. 357f829c042SUlf Hansson * Worst delay time when up and running is at 25 MHz => 120 ns. 358f829c042SUlf Hansson */ 359f829c042SUlf Hansson if (host->cclk < 25000000) 360f829c042SUlf Hansson udelay(30); 361f829c042SUlf Hansson else 362f829c042SUlf Hansson ndelay(120); 363f829c042SUlf Hansson } 364f829c042SUlf Hansson 365653a761eSUlf Hansson /* 366a6a6464aSLinus Walleij * This must be called with host->lock held 367a6a6464aSLinus Walleij */ 368cd3ee8c5SLudovic Barre void mmci_write_clkreg(struct mmci_host *host, u32 clk) 3697437cfa5SUlf Hansson { 3707437cfa5SUlf Hansson if (host->clk_reg != clk) { 3717437cfa5SUlf Hansson host->clk_reg = clk; 3727437cfa5SUlf Hansson writel(clk, host->base + MMCICLOCK); 3737437cfa5SUlf Hansson } 3747437cfa5SUlf Hansson } 3757437cfa5SUlf Hansson 3767437cfa5SUlf Hansson /* 3777437cfa5SUlf Hansson * This must be called with host->lock held 3787437cfa5SUlf Hansson */ 379cd3ee8c5SLudovic Barre void mmci_write_pwrreg(struct mmci_host *host, u32 pwr) 3807437cfa5SUlf Hansson { 3817437cfa5SUlf Hansson if (host->pwr_reg != pwr) { 3827437cfa5SUlf Hansson host->pwr_reg = pwr; 3837437cfa5SUlf Hansson writel(pwr, host->base + MMCIPOWER); 3847437cfa5SUlf Hansson } 3857437cfa5SUlf Hansson } 3867437cfa5SUlf Hansson 3877437cfa5SUlf Hansson /* 3887437cfa5SUlf Hansson * This must be called with host->lock held 3897437cfa5SUlf Hansson */ 3909cc639a2SUlf Hansson static void mmci_write_datactrlreg(struct mmci_host *host, u32 datactrl) 3919cc639a2SUlf Hansson { 39249adc0caSLinus Walleij /* Keep busy mode in DPSM if enabled */ 39349adc0caSLinus Walleij datactrl |= host->datactrl_reg & host->variant->busy_dpsm_flag; 39401259620SUlf Hansson 3959cc639a2SUlf Hansson if (host->datactrl_reg != datactrl) { 3969cc639a2SUlf Hansson host->datactrl_reg = datactrl; 3979cc639a2SUlf Hansson writel(datactrl, host->base + MMCIDATACTRL); 3989cc639a2SUlf Hansson } 3999cc639a2SUlf Hansson } 4009cc639a2SUlf Hansson 4019cc639a2SUlf Hansson /* 4029cc639a2SUlf Hansson * This must be called with host->lock held 4039cc639a2SUlf Hansson */ 404a6a6464aSLinus Walleij static void mmci_set_clkreg(struct mmci_host *host, unsigned int desired) 405a6a6464aSLinus Walleij { 4064956e109SRabin Vincent struct variant_data *variant = host->variant; 4074956e109SRabin Vincent u32 clk = variant->clkreg; 408a6a6464aSLinus Walleij 409c58a8509SUlf Hansson /* Make sure cclk reflects the current calculated clock */ 410c58a8509SUlf Hansson host->cclk = 0; 411c58a8509SUlf Hansson 412a6a6464aSLinus Walleij if (desired) { 4133f4e6f7bSSrinivas Kandagatla if (variant->explicit_mclk_control) { 4143f4e6f7bSSrinivas Kandagatla host->cclk = host->mclk; 4153f4e6f7bSSrinivas Kandagatla } else if (desired >= host->mclk) { 416a6a6464aSLinus Walleij clk = MCI_CLK_BYPASS; 417399bc486SLinus Walleij if (variant->st_clkdiv) 418399bc486SLinus Walleij clk |= MCI_ST_UX500_NEG_EDGE; 419a6a6464aSLinus Walleij host->cclk = host->mclk; 420b70a67f9SLinus Walleij } else if (variant->st_clkdiv) { 421b70a67f9SLinus Walleij /* 422b70a67f9SLinus Walleij * DB8500 TRM says f = mclk / (clkdiv + 2) 423b70a67f9SLinus Walleij * => clkdiv = (mclk / f) - 2 424b70a67f9SLinus Walleij * Round the divider up so we don't exceed the max 425b70a67f9SLinus Walleij * frequency 426b70a67f9SLinus Walleij */ 427b70a67f9SLinus Walleij clk = DIV_ROUND_UP(host->mclk, desired) - 2; 428b70a67f9SLinus Walleij if (clk >= 256) 429b70a67f9SLinus Walleij clk = 255; 430b70a67f9SLinus Walleij host->cclk = host->mclk / (clk + 2); 431a6a6464aSLinus Walleij } else { 432b70a67f9SLinus Walleij /* 433b70a67f9SLinus Walleij * PL180 TRM says f = mclk / (2 * (clkdiv + 1)) 434b70a67f9SLinus Walleij * => clkdiv = mclk / (2 * f) - 1 435b70a67f9SLinus Walleij */ 436a6a6464aSLinus Walleij clk = host->mclk / (2 * desired) - 1; 437a6a6464aSLinus Walleij if (clk >= 256) 438a6a6464aSLinus Walleij clk = 255; 439a6a6464aSLinus Walleij host->cclk = host->mclk / (2 * (clk + 1)); 440a6a6464aSLinus Walleij } 4414380c14fSRabin Vincent 4424380c14fSRabin Vincent clk |= variant->clkreg_enable; 443a6a6464aSLinus Walleij clk |= MCI_CLK_ENABLE; 444a6a6464aSLinus Walleij /* This hasn't proven to be worthwhile */ 445a6a6464aSLinus Walleij /* clk |= MCI_CLK_PWRSAVE; */ 446a6a6464aSLinus Walleij } 447a6a6464aSLinus Walleij 448c58a8509SUlf Hansson /* Set actual clock for debug */ 449c58a8509SUlf Hansson host->mmc->actual_clock = host->cclk; 450c58a8509SUlf Hansson 4519e6c82cdSLinus Walleij if (host->mmc->ios.bus_width == MMC_BUS_WIDTH_4) 452771dc157SLinus Walleij clk |= MCI_4BIT_BUS; 453771dc157SLinus Walleij if (host->mmc->ios.bus_width == MMC_BUS_WIDTH_8) 454e1412d85SSrinivas Kandagatla clk |= variant->clkreg_8bit_bus_enable; 4559e6c82cdSLinus Walleij 4566dad6c95SSeungwon Jeon if (host->mmc->ios.timing == MMC_TIMING_UHS_DDR50 || 4576dad6c95SSeungwon Jeon host->mmc->ios.timing == MMC_TIMING_MMC_DDR52) 458e8740644SSrinivas Kandagatla clk |= variant->clkreg_neg_edge_enable; 4596dbb6ee0SUlf Hansson 4607437cfa5SUlf Hansson mmci_write_clkreg(host, clk); 461a6a6464aSLinus Walleij } 462a6a6464aSLinus Walleij 463e2b98d83SBen Dooks static void mmci_dma_release(struct mmci_host *host) 464c3647fdcSLudovic Barre { 465c3647fdcSLudovic Barre if (host->ops && host->ops->dma_release) 466c3647fdcSLudovic Barre host->ops->dma_release(host); 467c3647fdcSLudovic Barre 468c3647fdcSLudovic Barre host->use_dma = false; 469c3647fdcSLudovic Barre } 470c3647fdcSLudovic Barre 471e2b98d83SBen Dooks static void mmci_dma_setup(struct mmci_host *host) 472c3647fdcSLudovic Barre { 473c3647fdcSLudovic Barre if (!host->ops || !host->ops->dma_setup) 474c3647fdcSLudovic Barre return; 475c3647fdcSLudovic Barre 476c3647fdcSLudovic Barre if (host->ops->dma_setup(host)) 477c3647fdcSLudovic Barre return; 478c3647fdcSLudovic Barre 479a813f2a2SLudovic Barre /* initialize pre request cookie */ 480a813f2a2SLudovic Barre host->next_cookie = 1; 481a813f2a2SLudovic Barre 482c3647fdcSLudovic Barre host->use_dma = true; 483c3647fdcSLudovic Barre } 484c3647fdcSLudovic Barre 485e0da1721SLudovic Barre /* 486e0da1721SLudovic Barre * Validate mmc prerequisites 487e0da1721SLudovic Barre */ 488e0da1721SLudovic Barre static int mmci_validate_data(struct mmci_host *host, 489e0da1721SLudovic Barre struct mmc_data *data) 490e0da1721SLudovic Barre { 4912253ed4bSLinus Walleij struct variant_data *variant = host->variant; 4922253ed4bSLinus Walleij 493e0da1721SLudovic Barre if (!data) 494e0da1721SLudovic Barre return 0; 4952253ed4bSLinus Walleij if (!is_power_of_2(data->blksz) && !variant->datactrl_any_blocksz) { 496e0da1721SLudovic Barre dev_err(mmc_dev(host->mmc), 497e0da1721SLudovic Barre "unsupported block size (%d bytes)\n", data->blksz); 498e0da1721SLudovic Barre return -EINVAL; 499e0da1721SLudovic Barre } 500e0da1721SLudovic Barre 501e0da1721SLudovic Barre if (host->ops && host->ops->validate_data) 502e0da1721SLudovic Barre return host->ops->validate_data(host, data); 503e0da1721SLudovic Barre 504e0da1721SLudovic Barre return 0; 505e0da1721SLudovic Barre } 506e0da1721SLudovic Barre 507e2b98d83SBen Dooks static int mmci_prep_data(struct mmci_host *host, struct mmc_data *data, bool next) 50847983510SLudovic Barre { 50947983510SLudovic Barre int err; 51047983510SLudovic Barre 51147983510SLudovic Barre if (!host->ops || !host->ops->prep_data) 51247983510SLudovic Barre return 0; 51347983510SLudovic Barre 51447983510SLudovic Barre err = host->ops->prep_data(host, data, next); 51547983510SLudovic Barre 51647983510SLudovic Barre if (next && !err) 51747983510SLudovic Barre data->host_cookie = ++host->next_cookie < 0 ? 51847983510SLudovic Barre 1 : host->next_cookie; 51947983510SLudovic Barre 52047983510SLudovic Barre return err; 52147983510SLudovic Barre } 52247983510SLudovic Barre 523e2b98d83SBen Dooks static void mmci_unprep_data(struct mmci_host *host, struct mmc_data *data, 52447983510SLudovic Barre int err) 52547983510SLudovic Barre { 52647983510SLudovic Barre if (host->ops && host->ops->unprep_data) 52747983510SLudovic Barre host->ops->unprep_data(host, data, err); 52847983510SLudovic Barre 52947983510SLudovic Barre data->host_cookie = 0; 53047983510SLudovic Barre } 53147983510SLudovic Barre 532e2b98d83SBen Dooks static void mmci_get_next_data(struct mmci_host *host, struct mmc_data *data) 53302769968SLudovic Barre { 53402769968SLudovic Barre WARN_ON(data->host_cookie && data->host_cookie != host->next_cookie); 53502769968SLudovic Barre 53602769968SLudovic Barre if (host->ops && host->ops->get_next_data) 53702769968SLudovic Barre host->ops->get_next_data(host, data); 53802769968SLudovic Barre } 53902769968SLudovic Barre 540e2b98d83SBen Dooks static int mmci_dma_start(struct mmci_host *host, unsigned int datactrl) 541135ea30eSLudovic Barre { 542135ea30eSLudovic Barre struct mmc_data *data = host->data; 543135ea30eSLudovic Barre int ret; 544135ea30eSLudovic Barre 545135ea30eSLudovic Barre if (!host->use_dma) 546135ea30eSLudovic Barre return -EINVAL; 547135ea30eSLudovic Barre 548135ea30eSLudovic Barre ret = mmci_prep_data(host, data, false); 549135ea30eSLudovic Barre if (ret) 550135ea30eSLudovic Barre return ret; 551135ea30eSLudovic Barre 552135ea30eSLudovic Barre if (!host->ops || !host->ops->dma_start) 553135ea30eSLudovic Barre return -EINVAL; 554135ea30eSLudovic Barre 555135ea30eSLudovic Barre /* Okay, go for it. */ 556135ea30eSLudovic Barre dev_vdbg(mmc_dev(host->mmc), 557135ea30eSLudovic Barre "Submit MMCI DMA job, sglen %d blksz %04x blks %04x flags %08x\n", 558135ea30eSLudovic Barre data->sg_len, data->blksz, data->blocks, data->flags); 559135ea30eSLudovic Barre 5602253ed4bSLinus Walleij ret = host->ops->dma_start(host, &datactrl); 5612253ed4bSLinus Walleij if (ret) 5622253ed4bSLinus Walleij return ret; 563135ea30eSLudovic Barre 564135ea30eSLudovic Barre /* Trigger the DMA transfer */ 565135ea30eSLudovic Barre mmci_write_datactrlreg(host, datactrl); 566135ea30eSLudovic Barre 567135ea30eSLudovic Barre /* 568135ea30eSLudovic Barre * Let the MMCI say when the data is ended and it's time 569135ea30eSLudovic Barre * to fire next DMA request. When that happens, MMCI will 570135ea30eSLudovic Barre * call mmci_data_end() 571135ea30eSLudovic Barre */ 572135ea30eSLudovic Barre writel(readl(host->base + MMCIMASK0) | MCI_DATAENDMASK, 573135ea30eSLudovic Barre host->base + MMCIMASK0); 574135ea30eSLudovic Barre return 0; 575135ea30eSLudovic Barre } 576135ea30eSLudovic Barre 577e2b98d83SBen Dooks static void mmci_dma_finalize(struct mmci_host *host, struct mmc_data *data) 5785a9f10c3SLudovic Barre { 5795a9f10c3SLudovic Barre if (!host->use_dma) 5805a9f10c3SLudovic Barre return; 5815a9f10c3SLudovic Barre 5825a9f10c3SLudovic Barre if (host->ops && host->ops->dma_finalize) 5835a9f10c3SLudovic Barre host->ops->dma_finalize(host, data); 5845a9f10c3SLudovic Barre } 5855a9f10c3SLudovic Barre 586e2b98d83SBen Dooks static void mmci_dma_error(struct mmci_host *host) 587cfccc6acSLudovic Barre { 588cfccc6acSLudovic Barre if (!host->use_dma) 589cfccc6acSLudovic Barre return; 590cfccc6acSLudovic Barre 591cfccc6acSLudovic Barre if (host->ops && host->ops->dma_error) 592cfccc6acSLudovic Barre host->ops->dma_error(host); 593cfccc6acSLudovic Barre } 594cfccc6acSLudovic Barre 5951c6a0718SPierre Ossman static void 5961c6a0718SPierre Ossman mmci_request_end(struct mmci_host *host, struct mmc_request *mrq) 5971c6a0718SPierre Ossman { 5981c6a0718SPierre Ossman writel(0, host->base + MMCICOMMAND); 5991c6a0718SPierre Ossman 6001c6a0718SPierre Ossman BUG_ON(host->data); 6011c6a0718SPierre Ossman 6021c6a0718SPierre Ossman host->mrq = NULL; 6031c6a0718SPierre Ossman host->cmd = NULL; 6041c6a0718SPierre Ossman 6051c6a0718SPierre Ossman mmc_request_done(host->mmc, mrq); 6061c6a0718SPierre Ossman } 6071c6a0718SPierre Ossman 6082686b4b4SLinus Walleij static void mmci_set_mask1(struct mmci_host *host, unsigned int mask) 6092686b4b4SLinus Walleij { 6102686b4b4SLinus Walleij void __iomem *base = host->base; 6116ea9cdf3SPatrice Chotard struct variant_data *variant = host->variant; 6122686b4b4SLinus Walleij 6132686b4b4SLinus Walleij if (host->singleirq) { 6142686b4b4SLinus Walleij unsigned int mask0 = readl(base + MMCIMASK0); 6152686b4b4SLinus Walleij 61659db5e2dSLudovic Barre mask0 &= ~variant->irq_pio_mask; 6172686b4b4SLinus Walleij mask0 |= mask; 6182686b4b4SLinus Walleij 6192686b4b4SLinus Walleij writel(mask0, base + MMCIMASK0); 6202686b4b4SLinus Walleij } 6212686b4b4SLinus Walleij 6226ea9cdf3SPatrice Chotard if (variant->mmcimask1) 6232686b4b4SLinus Walleij writel(mask, base + MMCIMASK1); 6246ea9cdf3SPatrice Chotard 6256ea9cdf3SPatrice Chotard host->mask1_reg = mask; 6262686b4b4SLinus Walleij } 6272686b4b4SLinus Walleij 6281c6a0718SPierre Ossman static void mmci_stop_data(struct mmci_host *host) 6291c6a0718SPierre Ossman { 6309cc639a2SUlf Hansson mmci_write_datactrlreg(host, 0); 6312686b4b4SLinus Walleij mmci_set_mask1(host, 0); 6321c6a0718SPierre Ossman host->data = NULL; 6331c6a0718SPierre Ossman } 6341c6a0718SPierre Ossman 6354ce1d6cbSRabin Vincent static void mmci_init_sg(struct mmci_host *host, struct mmc_data *data) 6364ce1d6cbSRabin Vincent { 6374ce1d6cbSRabin Vincent unsigned int flags = SG_MITER_ATOMIC; 6384ce1d6cbSRabin Vincent 6394ce1d6cbSRabin Vincent if (data->flags & MMC_DATA_READ) 6404ce1d6cbSRabin Vincent flags |= SG_MITER_TO_SG; 6414ce1d6cbSRabin Vincent else 6424ce1d6cbSRabin Vincent flags |= SG_MITER_FROM_SG; 6434ce1d6cbSRabin Vincent 6444ce1d6cbSRabin Vincent sg_miter_start(&host->sg_miter, data->sg, data->sg_len, flags); 6454ce1d6cbSRabin Vincent } 6464ce1d6cbSRabin Vincent 647b3fb9d64SLudovic Barre static u32 mmci_get_dctrl_cfg(struct mmci_host *host) 648b3fb9d64SLudovic Barre { 649b3fb9d64SLudovic Barre return MCI_DPSM_ENABLE | mmci_dctrl_blksz(host); 650b3fb9d64SLudovic Barre } 651b3fb9d64SLudovic Barre 652b3fb9d64SLudovic Barre static u32 ux500v2_get_dctrl_cfg(struct mmci_host *host) 653b3fb9d64SLudovic Barre { 654b3fb9d64SLudovic Barre return MCI_DPSM_ENABLE | (host->data->blksz << 16); 655b3fb9d64SLudovic Barre } 656b3fb9d64SLudovic Barre 657cb0335b7SLudovic Barre static bool ux500_busy_complete(struct mmci_host *host, u32 status, u32 err_msk) 658cb0335b7SLudovic Barre { 659cb0335b7SLudovic Barre void __iomem *base = host->base; 660cb0335b7SLudovic Barre 661cb0335b7SLudovic Barre /* 662cb0335b7SLudovic Barre * Before unmasking for the busy end IRQ, confirm that the 663cb0335b7SLudovic Barre * command was sent successfully. To keep track of having a 664cb0335b7SLudovic Barre * command in-progress, waiting for busy signaling to end, 665cb0335b7SLudovic Barre * store the status in host->busy_status. 666cb0335b7SLudovic Barre * 667cb0335b7SLudovic Barre * Note that, the card may need a couple of clock cycles before 668cb0335b7SLudovic Barre * it starts signaling busy on DAT0, hence re-read the 669cb0335b7SLudovic Barre * MMCISTATUS register here, to allow the busy bit to be set. 670cb0335b7SLudovic Barre * Potentially we may even need to poll the register for a 671cb0335b7SLudovic Barre * while, to allow it to be set, but tests indicates that it 672cb0335b7SLudovic Barre * isn't needed. 673cb0335b7SLudovic Barre */ 674cb0335b7SLudovic Barre if (!host->busy_status && !(status & err_msk) && 675cb0335b7SLudovic Barre (readl(base + MMCISTATUS) & host->variant->busy_detect_flag)) { 676cb0335b7SLudovic Barre writel(readl(base + MMCIMASK0) | 677cb0335b7SLudovic Barre host->variant->busy_detect_mask, 678cb0335b7SLudovic Barre base + MMCIMASK0); 679cb0335b7SLudovic Barre 680cb0335b7SLudovic Barre host->busy_status = status & (MCI_CMDSENT | MCI_CMDRESPEND); 681cb0335b7SLudovic Barre return false; 682cb0335b7SLudovic Barre } 683cb0335b7SLudovic Barre 684cb0335b7SLudovic Barre /* 685cb0335b7SLudovic Barre * If there is a command in-progress that has been successfully 686cb0335b7SLudovic Barre * sent, then bail out if busy status is set and wait for the 687cb0335b7SLudovic Barre * busy end IRQ. 688cb0335b7SLudovic Barre * 689cb0335b7SLudovic Barre * Note that, the HW triggers an IRQ on both edges while 690cb0335b7SLudovic Barre * monitoring DAT0 for busy completion, but there is only one 691cb0335b7SLudovic Barre * status bit in MMCISTATUS for the busy state. Therefore 692cb0335b7SLudovic Barre * both the start and the end interrupts needs to be cleared, 693cb0335b7SLudovic Barre * one after the other. So, clear the busy start IRQ here. 694cb0335b7SLudovic Barre */ 695cb0335b7SLudovic Barre if (host->busy_status && 696cb0335b7SLudovic Barre (status & host->variant->busy_detect_flag)) { 697cb0335b7SLudovic Barre writel(host->variant->busy_detect_mask, base + MMCICLEAR); 698cb0335b7SLudovic Barre return false; 699cb0335b7SLudovic Barre } 700cb0335b7SLudovic Barre 701cb0335b7SLudovic Barre /* 702cb0335b7SLudovic Barre * If there is a command in-progress that has been successfully 703cb0335b7SLudovic Barre * sent and the busy bit isn't set, it means we have received 704cb0335b7SLudovic Barre * the busy end IRQ. Clear and mask the IRQ, then continue to 705cb0335b7SLudovic Barre * process the command. 706cb0335b7SLudovic Barre */ 707cb0335b7SLudovic Barre if (host->busy_status) { 708cb0335b7SLudovic Barre writel(host->variant->busy_detect_mask, base + MMCICLEAR); 709cb0335b7SLudovic Barre 710cb0335b7SLudovic Barre writel(readl(base + MMCIMASK0) & 711cb0335b7SLudovic Barre ~host->variant->busy_detect_mask, base + MMCIMASK0); 712cb0335b7SLudovic Barre host->busy_status = 0; 713cb0335b7SLudovic Barre } 714cb0335b7SLudovic Barre 715cb0335b7SLudovic Barre return true; 716cb0335b7SLudovic Barre } 717cb0335b7SLudovic Barre 718c8ebae37SRussell King /* 719c8ebae37SRussell King * All the DMA operation mode stuff goes inside this ifdef. 720c8ebae37SRussell King * This assumes that you have a generic DMA device interface, 721c8ebae37SRussell King * no custom DMA interfaces are supported. 722c8ebae37SRussell King */ 723c8ebae37SRussell King #ifdef CONFIG_DMA_ENGINE 724a813f2a2SLudovic Barre struct mmci_dmae_next { 725a813f2a2SLudovic Barre struct dma_async_tx_descriptor *desc; 726a813f2a2SLudovic Barre struct dma_chan *chan; 727a813f2a2SLudovic Barre }; 728a813f2a2SLudovic Barre 729a813f2a2SLudovic Barre struct mmci_dmae_priv { 730a813f2a2SLudovic Barre struct dma_chan *cur; 731a813f2a2SLudovic Barre struct dma_chan *rx_channel; 732a813f2a2SLudovic Barre struct dma_chan *tx_channel; 733a813f2a2SLudovic Barre struct dma_async_tx_descriptor *desc_current; 734a813f2a2SLudovic Barre struct mmci_dmae_next next_data; 735a813f2a2SLudovic Barre }; 736a813f2a2SLudovic Barre 737c3647fdcSLudovic Barre int mmci_dmae_setup(struct mmci_host *host) 738c8ebae37SRussell King { 739c8ebae37SRussell King const char *rxname, *txname; 740a813f2a2SLudovic Barre struct mmci_dmae_priv *dmae; 741c8ebae37SRussell King 742a813f2a2SLudovic Barre dmae = devm_kzalloc(mmc_dev(host->mmc), sizeof(*dmae), GFP_KERNEL); 743a813f2a2SLudovic Barre if (!dmae) 744a813f2a2SLudovic Barre return -ENOMEM; 745c8ebae37SRussell King 746a813f2a2SLudovic Barre host->dma_priv = dmae; 747a813f2a2SLudovic Barre 748716d0205SPeter Ujfalusi dmae->rx_channel = dma_request_chan(mmc_dev(host->mmc), "rx"); 749716d0205SPeter Ujfalusi if (IS_ERR(dmae->rx_channel)) { 750716d0205SPeter Ujfalusi int ret = PTR_ERR(dmae->rx_channel); 751716d0205SPeter Ujfalusi dmae->rx_channel = NULL; 752716d0205SPeter Ujfalusi return ret; 753716d0205SPeter Ujfalusi } 754716d0205SPeter Ujfalusi 755716d0205SPeter Ujfalusi dmae->tx_channel = dma_request_chan(mmc_dev(host->mmc), "tx"); 756716d0205SPeter Ujfalusi if (IS_ERR(dmae->tx_channel)) { 757716d0205SPeter Ujfalusi if (PTR_ERR(dmae->tx_channel) == -EPROBE_DEFER) 758716d0205SPeter Ujfalusi dev_warn(mmc_dev(host->mmc), 759716d0205SPeter Ujfalusi "Deferred probe for TX channel ignored\n"); 760716d0205SPeter Ujfalusi dmae->tx_channel = NULL; 761716d0205SPeter Ujfalusi } 76258c7ccbfSPer Forlin 7631fd83f0eSLee Jones /* 7641fd83f0eSLee Jones * If only an RX channel is specified, the driver will 7651fd83f0eSLee Jones * attempt to use it bidirectionally, however if it is 7661fd83f0eSLee Jones * is specified but cannot be located, DMA will be disabled. 7671fd83f0eSLee Jones */ 768a813f2a2SLudovic Barre if (dmae->rx_channel && !dmae->tx_channel) 769a813f2a2SLudovic Barre dmae->tx_channel = dmae->rx_channel; 770c8ebae37SRussell King 771a813f2a2SLudovic Barre if (dmae->rx_channel) 772a813f2a2SLudovic Barre rxname = dma_chan_name(dmae->rx_channel); 773c8ebae37SRussell King else 774c8ebae37SRussell King rxname = "none"; 775c8ebae37SRussell King 776a813f2a2SLudovic Barre if (dmae->tx_channel) 777a813f2a2SLudovic Barre txname = dma_chan_name(dmae->tx_channel); 778c8ebae37SRussell King else 779c8ebae37SRussell King txname = "none"; 780c8ebae37SRussell King 781c8ebae37SRussell King dev_info(mmc_dev(host->mmc), "DMA channels RX %s, TX %s\n", 782c8ebae37SRussell King rxname, txname); 783c8ebae37SRussell King 784c8ebae37SRussell King /* 785c8ebae37SRussell King * Limit the maximum segment size in any SG entry according to 786c8ebae37SRussell King * the parameters of the DMA engine device. 787c8ebae37SRussell King */ 788a813f2a2SLudovic Barre if (dmae->tx_channel) { 789a813f2a2SLudovic Barre struct device *dev = dmae->tx_channel->device->dev; 790c8ebae37SRussell King unsigned int max_seg_size = dma_get_max_seg_size(dev); 791c8ebae37SRussell King 792c8ebae37SRussell King if (max_seg_size < host->mmc->max_seg_size) 793c8ebae37SRussell King host->mmc->max_seg_size = max_seg_size; 794c8ebae37SRussell King } 795a813f2a2SLudovic Barre if (dmae->rx_channel) { 796a813f2a2SLudovic Barre struct device *dev = dmae->rx_channel->device->dev; 797c8ebae37SRussell King unsigned int max_seg_size = dma_get_max_seg_size(dev); 798c8ebae37SRussell King 799c8ebae37SRussell King if (max_seg_size < host->mmc->max_seg_size) 800c8ebae37SRussell King host->mmc->max_seg_size = max_seg_size; 801c8ebae37SRussell King } 8029cb15142SSrinivas Kandagatla 803a813f2a2SLudovic Barre if (!dmae->tx_channel || !dmae->rx_channel) { 804c3647fdcSLudovic Barre mmci_dmae_release(host); 805c3647fdcSLudovic Barre return -EINVAL; 806c3647fdcSLudovic Barre } 807c3647fdcSLudovic Barre 808c3647fdcSLudovic Barre return 0; 809c8ebae37SRussell King } 810c8ebae37SRussell King 811c8ebae37SRussell King /* 8126e0ee714SBill Pemberton * This is used in or so inline it 813c8ebae37SRussell King * so it can be discarded. 814c8ebae37SRussell King */ 815c3647fdcSLudovic Barre void mmci_dmae_release(struct mmci_host *host) 816c8ebae37SRussell King { 817a813f2a2SLudovic Barre struct mmci_dmae_priv *dmae = host->dma_priv; 818a813f2a2SLudovic Barre 819a813f2a2SLudovic Barre if (dmae->rx_channel) 820a813f2a2SLudovic Barre dma_release_channel(dmae->rx_channel); 821a813f2a2SLudovic Barre if (dmae->tx_channel) 822a813f2a2SLudovic Barre dma_release_channel(dmae->tx_channel); 823a813f2a2SLudovic Barre dmae->rx_channel = dmae->tx_channel = NULL; 824c8ebae37SRussell King } 825c8ebae37SRussell King 826c8ebae37SRussell King static void mmci_dma_unmap(struct mmci_host *host, struct mmc_data *data) 827c8ebae37SRussell King { 828a813f2a2SLudovic Barre struct mmci_dmae_priv *dmae = host->dma_priv; 829653a761eSUlf Hansson struct dma_chan *chan; 830653a761eSUlf Hansson 831feeef096SHeiner Kallweit if (data->flags & MMC_DATA_READ) 832a813f2a2SLudovic Barre chan = dmae->rx_channel; 833feeef096SHeiner Kallweit else 834a813f2a2SLudovic Barre chan = dmae->tx_channel; 835653a761eSUlf Hansson 836feeef096SHeiner Kallweit dma_unmap_sg(chan->device->dev, data->sg, data->sg_len, 837feeef096SHeiner Kallweit mmc_get_dma_dir(data)); 838653a761eSUlf Hansson } 839653a761eSUlf Hansson 840cfccc6acSLudovic Barre void mmci_dmae_error(struct mmci_host *host) 8417b2a6d51SLudovic Barre { 842a813f2a2SLudovic Barre struct mmci_dmae_priv *dmae = host->dma_priv; 843a813f2a2SLudovic Barre 844cfccc6acSLudovic Barre if (!dma_inprogress(host)) 845cdea1947SLudovic Barre return; 846cdea1947SLudovic Barre 8477b2a6d51SLudovic Barre dev_err(mmc_dev(host->mmc), "error during DMA transfer!\n"); 848a813f2a2SLudovic Barre dmaengine_terminate_all(dmae->cur); 8497b2a6d51SLudovic Barre host->dma_in_progress = false; 850a813f2a2SLudovic Barre dmae->cur = NULL; 851a813f2a2SLudovic Barre dmae->desc_current = NULL; 8527b2a6d51SLudovic Barre host->data->host_cookie = 0; 8537b2a6d51SLudovic Barre 8547b2a6d51SLudovic Barre mmci_dma_unmap(host, host->data); 8557b2a6d51SLudovic Barre } 8567b2a6d51SLudovic Barre 8575a9f10c3SLudovic Barre void mmci_dmae_finalize(struct mmci_host *host, struct mmc_data *data) 858653a761eSUlf Hansson { 859a813f2a2SLudovic Barre struct mmci_dmae_priv *dmae = host->dma_priv; 860c8ebae37SRussell King u32 status; 861c8ebae37SRussell King int i; 862c8ebae37SRussell King 8635a9f10c3SLudovic Barre if (!dma_inprogress(host)) 864cdea1947SLudovic Barre return; 865cdea1947SLudovic Barre 866c8ebae37SRussell King /* Wait up to 1ms for the DMA to complete */ 867c8ebae37SRussell King for (i = 0; ; i++) { 868c8ebae37SRussell King status = readl(host->base + MMCISTATUS); 869c8ebae37SRussell King if (!(status & MCI_RXDATAAVLBLMASK) || i >= 100) 870c8ebae37SRussell King break; 871c8ebae37SRussell King udelay(10); 872c8ebae37SRussell King } 873c8ebae37SRussell King 874c8ebae37SRussell King /* 875c8ebae37SRussell King * Check to see whether we still have some data left in the FIFO - 876c8ebae37SRussell King * this catches DMA controllers which are unable to monitor the 877c8ebae37SRussell King * DMALBREQ and DMALSREQ signals while allowing us to DMA to non- 878c8ebae37SRussell King * contiguous buffers. On TX, we'll get a FIFO underrun error. 879c8ebae37SRussell King */ 880c8ebae37SRussell King if (status & MCI_RXDATAAVLBLMASK) { 881cfccc6acSLudovic Barre mmci_dma_error(host); 882c8ebae37SRussell King if (!data->error) 883c8ebae37SRussell King data->error = -EIO; 8847b2a6d51SLudovic Barre } else if (!data->host_cookie) { 885653a761eSUlf Hansson mmci_dma_unmap(host, data); 8867b2a6d51SLudovic Barre } 887c8ebae37SRussell King 888c8ebae37SRussell King /* 889c8ebae37SRussell King * Use of DMA with scatter-gather is impossible. 890c8ebae37SRussell King * Give up with DMA and switch back to PIO mode. 891c8ebae37SRussell King */ 892c8ebae37SRussell King if (status & MCI_RXDATAAVLBLMASK) { 893c8ebae37SRussell King dev_err(mmc_dev(host->mmc), "buggy DMA detected. Taking evasive action.\n"); 894c8ebae37SRussell King mmci_dma_release(host); 895c8ebae37SRussell King } 896653a761eSUlf Hansson 897e13934bdSLinus Walleij host->dma_in_progress = false; 898a813f2a2SLudovic Barre dmae->cur = NULL; 899a813f2a2SLudovic Barre dmae->desc_current = NULL; 900c8ebae37SRussell King } 901c8ebae37SRussell King 902653a761eSUlf Hansson /* prepares DMA channel and DMA descriptor, returns non-zero on failure */ 90347983510SLudovic Barre static int _mmci_dmae_prep_data(struct mmci_host *host, struct mmc_data *data, 904653a761eSUlf Hansson struct dma_chan **dma_chan, 905653a761eSUlf Hansson struct dma_async_tx_descriptor **dma_desc) 906c8ebae37SRussell King { 907a813f2a2SLudovic Barre struct mmci_dmae_priv *dmae = host->dma_priv; 908c8ebae37SRussell King struct variant_data *variant = host->variant; 909c8ebae37SRussell King struct dma_slave_config conf = { 910c8ebae37SRussell King .src_addr = host->phybase + MMCIFIFO, 911c8ebae37SRussell King .dst_addr = host->phybase + MMCIFIFO, 912c8ebae37SRussell King .src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES, 913c8ebae37SRussell King .dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES, 914c8ebae37SRussell King .src_maxburst = variant->fifohalfsize >> 2, /* # of words */ 915c8ebae37SRussell King .dst_maxburst = variant->fifohalfsize >> 2, /* # of words */ 916258aea76SViresh Kumar .device_fc = false, 917c8ebae37SRussell King }; 918c8ebae37SRussell King struct dma_chan *chan; 919c8ebae37SRussell King struct dma_device *device; 920c8ebae37SRussell King struct dma_async_tx_descriptor *desc; 921c8ebae37SRussell King int nr_sg; 9229cb15142SSrinivas Kandagatla unsigned long flags = DMA_CTRL_ACK; 923c8ebae37SRussell King 924c8ebae37SRussell King if (data->flags & MMC_DATA_READ) { 92505f5799cSVinod Koul conf.direction = DMA_DEV_TO_MEM; 926a813f2a2SLudovic Barre chan = dmae->rx_channel; 927c8ebae37SRussell King } else { 92805f5799cSVinod Koul conf.direction = DMA_MEM_TO_DEV; 929a813f2a2SLudovic Barre chan = dmae->tx_channel; 930c8ebae37SRussell King } 931c8ebae37SRussell King 932c8ebae37SRussell King /* If there's no DMA channel, fall back to PIO */ 933c8ebae37SRussell King if (!chan) 934c8ebae37SRussell King return -EINVAL; 935c8ebae37SRussell King 936c8ebae37SRussell King /* If less than or equal to the fifo size, don't bother with DMA */ 93758c7ccbfSPer Forlin if (data->blksz * data->blocks <= variant->fifosize) 938c8ebae37SRussell King return -EINVAL; 939c8ebae37SRussell King 9402253ed4bSLinus Walleij /* 9412253ed4bSLinus Walleij * This is necessary to get SDIO working on the Ux500. We do not yet 9422253ed4bSLinus Walleij * know if this is a bug in: 9432253ed4bSLinus Walleij * - The Ux500 DMA controller (DMA40) 9442253ed4bSLinus Walleij * - The MMCI DMA interface on the Ux500 9452253ed4bSLinus Walleij * some power of two blocks (such as 64 bytes) are sent regularly 9462253ed4bSLinus Walleij * during SDIO traffic and those work fine so for these we enable DMA 9472253ed4bSLinus Walleij * transfers. 9482253ed4bSLinus Walleij */ 9492253ed4bSLinus Walleij if (host->variant->dma_power_of_2 && !is_power_of_2(data->blksz)) 9502253ed4bSLinus Walleij return -EINVAL; 9512253ed4bSLinus Walleij 952c8ebae37SRussell King device = chan->device; 953feeef096SHeiner Kallweit nr_sg = dma_map_sg(device->dev, data->sg, data->sg_len, 954feeef096SHeiner Kallweit mmc_get_dma_dir(data)); 955c8ebae37SRussell King if (nr_sg == 0) 956c8ebae37SRussell King return -EINVAL; 957c8ebae37SRussell King 9589cb15142SSrinivas Kandagatla if (host->variant->qcom_dml) 9599cb15142SSrinivas Kandagatla flags |= DMA_PREP_INTERRUPT; 9609cb15142SSrinivas Kandagatla 961c8ebae37SRussell King dmaengine_slave_config(chan, &conf); 96216052827SAlexandre Bounine desc = dmaengine_prep_slave_sg(chan, data->sg, nr_sg, 9639cb15142SSrinivas Kandagatla conf.direction, flags); 964c8ebae37SRussell King if (!desc) 965c8ebae37SRussell King goto unmap_exit; 966c8ebae37SRussell King 967653a761eSUlf Hansson *dma_chan = chan; 968653a761eSUlf Hansson *dma_desc = desc; 969c8ebae37SRussell King 97058c7ccbfSPer Forlin return 0; 97158c7ccbfSPer Forlin 97258c7ccbfSPer Forlin unmap_exit: 973feeef096SHeiner Kallweit dma_unmap_sg(device->dev, data->sg, data->sg_len, 974feeef096SHeiner Kallweit mmc_get_dma_dir(data)); 97558c7ccbfSPer Forlin return -ENOMEM; 97658c7ccbfSPer Forlin } 97758c7ccbfSPer Forlin 97847983510SLudovic Barre int mmci_dmae_prep_data(struct mmci_host *host, 979ad7b8918SLudovic Barre struct mmc_data *data, 980ad7b8918SLudovic Barre bool next) 981653a761eSUlf Hansson { 982a813f2a2SLudovic Barre struct mmci_dmae_priv *dmae = host->dma_priv; 983ad7b8918SLudovic Barre struct mmci_dmae_next *nd = &dmae->next_data; 984a813f2a2SLudovic Barre 98547983510SLudovic Barre if (!host->use_dma) 98647983510SLudovic Barre return -EINVAL; 98747983510SLudovic Barre 988ad7b8918SLudovic Barre if (next) 98947983510SLudovic Barre return _mmci_dmae_prep_data(host, data, &nd->chan, &nd->desc); 990653a761eSUlf Hansson /* Check if next job is already prepared. */ 991a813f2a2SLudovic Barre if (dmae->cur && dmae->desc_current) 992653a761eSUlf Hansson return 0; 993653a761eSUlf Hansson 994653a761eSUlf Hansson /* No job were prepared thus do it now. */ 99547983510SLudovic Barre return _mmci_dmae_prep_data(host, data, &dmae->cur, 996a813f2a2SLudovic Barre &dmae->desc_current); 997653a761eSUlf Hansson } 998653a761eSUlf Hansson 999135ea30eSLudovic Barre int mmci_dmae_start(struct mmci_host *host, unsigned int *datactrl) 100058c7ccbfSPer Forlin { 1001a813f2a2SLudovic Barre struct mmci_dmae_priv *dmae = host->dma_priv; 10022253ed4bSLinus Walleij int ret; 100358c7ccbfSPer Forlin 1004e13934bdSLinus Walleij host->dma_in_progress = true; 10052253ed4bSLinus Walleij ret = dma_submit_error(dmaengine_submit(dmae->desc_current)); 10062253ed4bSLinus Walleij if (ret < 0) { 10072253ed4bSLinus Walleij host->dma_in_progress = false; 10082253ed4bSLinus Walleij return ret; 10092253ed4bSLinus Walleij } 1010a813f2a2SLudovic Barre dma_async_issue_pending(dmae->cur); 1011c8ebae37SRussell King 1012135ea30eSLudovic Barre *datactrl |= MCI_DPSM_DMAENABLE; 1013c8ebae37SRussell King 1014c8ebae37SRussell King return 0; 1015c8ebae37SRussell King } 101658c7ccbfSPer Forlin 101702769968SLudovic Barre void mmci_dmae_get_next_data(struct mmci_host *host, struct mmc_data *data) 101858c7ccbfSPer Forlin { 1019a813f2a2SLudovic Barre struct mmci_dmae_priv *dmae = host->dma_priv; 1020a813f2a2SLudovic Barre struct mmci_dmae_next *next = &dmae->next_data; 102158c7ccbfSPer Forlin 1022c3647fdcSLudovic Barre if (!host->use_dma) 1023c3647fdcSLudovic Barre return; 1024c3647fdcSLudovic Barre 1025a813f2a2SLudovic Barre WARN_ON(!data->host_cookie && (next->desc || next->chan)); 102658c7ccbfSPer Forlin 1027a813f2a2SLudovic Barre dmae->desc_current = next->desc; 1028a813f2a2SLudovic Barre dmae->cur = next->chan; 1029a813f2a2SLudovic Barre next->desc = NULL; 1030a813f2a2SLudovic Barre next->chan = NULL; 103158c7ccbfSPer Forlin } 103258c7ccbfSPer Forlin 103347983510SLudovic Barre void mmci_dmae_unprep_data(struct mmci_host *host, 103447983510SLudovic Barre struct mmc_data *data, int err) 103547983510SLudovic Barre 103658c7ccbfSPer Forlin { 1037a813f2a2SLudovic Barre struct mmci_dmae_priv *dmae = host->dma_priv; 103858c7ccbfSPer Forlin 103947983510SLudovic Barre if (!host->use_dma) 104058c7ccbfSPer Forlin return; 104158c7ccbfSPer Forlin 1042653a761eSUlf Hansson mmci_dma_unmap(host, data); 1043653a761eSUlf Hansson 1044653a761eSUlf Hansson if (err) { 1045a813f2a2SLudovic Barre struct mmci_dmae_next *next = &dmae->next_data; 1046653a761eSUlf Hansson struct dma_chan *chan; 1047653a761eSUlf Hansson if (data->flags & MMC_DATA_READ) 1048a813f2a2SLudovic Barre chan = dmae->rx_channel; 1049653a761eSUlf Hansson else 1050a813f2a2SLudovic Barre chan = dmae->tx_channel; 105158c7ccbfSPer Forlin dmaengine_terminate_all(chan); 1052653a761eSUlf Hansson 1053a813f2a2SLudovic Barre if (dmae->desc_current == next->desc) 1054a813f2a2SLudovic Barre dmae->desc_current = NULL; 1055b5c16a60SSrinivas Kandagatla 1056a813f2a2SLudovic Barre if (dmae->cur == next->chan) { 1057e13934bdSLinus Walleij host->dma_in_progress = false; 1058a813f2a2SLudovic Barre dmae->cur = NULL; 1059e13934bdSLinus Walleij } 1060b5c16a60SSrinivas Kandagatla 1061a813f2a2SLudovic Barre next->desc = NULL; 1062a813f2a2SLudovic Barre next->chan = NULL; 106358c7ccbfSPer Forlin } 106458c7ccbfSPer Forlin } 106558c7ccbfSPer Forlin 1066c3647fdcSLudovic Barre static struct mmci_host_ops mmci_variant_ops = { 106747983510SLudovic Barre .prep_data = mmci_dmae_prep_data, 106847983510SLudovic Barre .unprep_data = mmci_dmae_unprep_data, 1069b3fb9d64SLudovic Barre .get_datactrl_cfg = mmci_get_dctrl_cfg, 107002769968SLudovic Barre .get_next_data = mmci_dmae_get_next_data, 1071c3647fdcSLudovic Barre .dma_setup = mmci_dmae_setup, 1072c3647fdcSLudovic Barre .dma_release = mmci_dmae_release, 1073135ea30eSLudovic Barre .dma_start = mmci_dmae_start, 10745a9f10c3SLudovic Barre .dma_finalize = mmci_dmae_finalize, 1075cfccc6acSLudovic Barre .dma_error = mmci_dmae_error, 1076c3647fdcSLudovic Barre }; 1077b3fb9d64SLudovic Barre #else 1078b3fb9d64SLudovic Barre static struct mmci_host_ops mmci_variant_ops = { 1079b3fb9d64SLudovic Barre .get_datactrl_cfg = mmci_get_dctrl_cfg, 1080b3fb9d64SLudovic Barre }; 1081b3fb9d64SLudovic Barre #endif 1082c3647fdcSLudovic Barre 1083e2b98d83SBen Dooks static void mmci_variant_init(struct mmci_host *host) 1084c3647fdcSLudovic Barre { 1085c3647fdcSLudovic Barre host->ops = &mmci_variant_ops; 1086c3647fdcSLudovic Barre } 1087b3fb9d64SLudovic Barre 1088cb0335b7SLudovic Barre static void ux500_variant_init(struct mmci_host *host) 1089cb0335b7SLudovic Barre { 1090cb0335b7SLudovic Barre host->ops = &mmci_variant_ops; 1091cb0335b7SLudovic Barre host->ops->busy_complete = ux500_busy_complete; 1092cb0335b7SLudovic Barre } 1093cb0335b7SLudovic Barre 1094e2b98d83SBen Dooks static void ux500v2_variant_init(struct mmci_host *host) 1095b3fb9d64SLudovic Barre { 1096b3fb9d64SLudovic Barre host->ops = &mmci_variant_ops; 1097cb0335b7SLudovic Barre host->ops->busy_complete = ux500_busy_complete; 1098b3fb9d64SLudovic Barre host->ops->get_datactrl_cfg = ux500v2_get_dctrl_cfg; 1099b3fb9d64SLudovic Barre } 1100c8ebae37SRussell King 110147983510SLudovic Barre static void mmci_pre_request(struct mmc_host *mmc, struct mmc_request *mrq) 110247983510SLudovic Barre { 110347983510SLudovic Barre struct mmci_host *host = mmc_priv(mmc); 110447983510SLudovic Barre struct mmc_data *data = mrq->data; 110547983510SLudovic Barre 110647983510SLudovic Barre if (!data) 110747983510SLudovic Barre return; 110847983510SLudovic Barre 110947983510SLudovic Barre WARN_ON(data->host_cookie); 111047983510SLudovic Barre 111147983510SLudovic Barre if (mmci_validate_data(host, data)) 111247983510SLudovic Barre return; 111347983510SLudovic Barre 111447983510SLudovic Barre mmci_prep_data(host, data, true); 111547983510SLudovic Barre } 111647983510SLudovic Barre 111747983510SLudovic Barre static void mmci_post_request(struct mmc_host *mmc, struct mmc_request *mrq, 111847983510SLudovic Barre int err) 111947983510SLudovic Barre { 112047983510SLudovic Barre struct mmci_host *host = mmc_priv(mmc); 112147983510SLudovic Barre struct mmc_data *data = mrq->data; 112247983510SLudovic Barre 112347983510SLudovic Barre if (!data || !data->host_cookie) 112447983510SLudovic Barre return; 112547983510SLudovic Barre 112647983510SLudovic Barre mmci_unprep_data(host, data, err); 112747983510SLudovic Barre } 112847983510SLudovic Barre 11291c6a0718SPierre Ossman static void mmci_start_data(struct mmci_host *host, struct mmc_data *data) 11301c6a0718SPierre Ossman { 11318301bb68SRabin Vincent struct variant_data *variant = host->variant; 11321c6a0718SPierre Ossman unsigned int datactrl, timeout, irqmask; 11331c6a0718SPierre Ossman unsigned long long clks; 11341c6a0718SPierre Ossman void __iomem *base; 11351c6a0718SPierre Ossman 113664de0289SLinus Walleij dev_dbg(mmc_dev(host->mmc), "blksz %04x blks %04x flags %08x\n", 11371c6a0718SPierre Ossman data->blksz, data->blocks, data->flags); 11381c6a0718SPierre Ossman 11391c6a0718SPierre Ossman host->data = data; 1140528320dbSRabin Vincent host->size = data->blksz * data->blocks; 114151d4375dSRussell King data->bytes_xfered = 0; 11421c6a0718SPierre Ossman 11431c6a0718SPierre Ossman clks = (unsigned long long)data->timeout_ns * host->cclk; 1144c4a35769SSrinivas Kandagatla do_div(clks, NSEC_PER_SEC); 11451c6a0718SPierre Ossman 11461c6a0718SPierre Ossman timeout = data->timeout_clks + (unsigned int)clks; 11471c6a0718SPierre Ossman 11481c6a0718SPierre Ossman base = host->base; 11491c6a0718SPierre Ossman writel(timeout, base + MMCIDATATIMER); 11501c6a0718SPierre Ossman writel(host->size, base + MMCIDATALENGTH); 11511c6a0718SPierre Ossman 115241ed65e7SLudovic Barre datactrl = host->ops->get_datactrl_cfg(host); 115341ed65e7SLudovic Barre datactrl |= host->data->flags & MMC_DATA_READ ? MCI_DPSM_DIRECTION : 0; 1154c8ebae37SRussell King 1155c7354133SSrinivas Kandagatla if (host->mmc->card && mmc_card_sdio(host->mmc->card)) { 115606c1a121SUlf Hansson u32 clk; 1157c7354133SSrinivas Kandagatla 11585df014dfSSrinivas Kandagatla datactrl |= variant->datactrl_mask_sdio; 11597258db7eSUlf Hansson 1160c8ebae37SRussell King /* 116170ac0935SUlf Hansson * The ST Micro variant for SDIO small write transfers 116270ac0935SUlf Hansson * needs to have clock H/W flow control disabled, 116370ac0935SUlf Hansson * otherwise the transfer will not start. The threshold 116470ac0935SUlf Hansson * depends on the rate of MCLK. 116506c1a121SUlf Hansson */ 1166c7354133SSrinivas Kandagatla if (variant->st_sdio && data->flags & MMC_DATA_WRITE && 116770ac0935SUlf Hansson (host->size < 8 || 116870ac0935SUlf Hansson (host->size <= 8 && host->mclk > 50000000))) 116906c1a121SUlf Hansson clk = host->clk_reg & ~variant->clkreg_enable; 117006c1a121SUlf Hansson else 117106c1a121SUlf Hansson clk = host->clk_reg | variant->clkreg_enable; 117206c1a121SUlf Hansson 117306c1a121SUlf Hansson mmci_write_clkreg(host, clk); 117406c1a121SUlf Hansson } 117506c1a121SUlf Hansson 11766dad6c95SSeungwon Jeon if (host->mmc->ios.timing == MMC_TIMING_UHS_DDR50 || 11776dad6c95SSeungwon Jeon host->mmc->ios.timing == MMC_TIMING_MMC_DDR52) 1178e17dca2bSSrinivas Kandagatla datactrl |= variant->datactrl_mask_ddrmode; 11796dbb6ee0SUlf Hansson 118006c1a121SUlf Hansson /* 1181c8ebae37SRussell King * Attempt to use DMA operation mode, if this 1182c8ebae37SRussell King * should fail, fall back to PIO mode 1183c8ebae37SRussell King */ 1184135ea30eSLudovic Barre if (!mmci_dma_start(host, datactrl)) 1185c8ebae37SRussell King return; 1186c8ebae37SRussell King 1187c8ebae37SRussell King /* IRQ mode, map the SG list for CPU reading/writing */ 1188c8ebae37SRussell King mmci_init_sg(host, data); 1189c8ebae37SRussell King 1190c8ebae37SRussell King if (data->flags & MMC_DATA_READ) { 11911c6a0718SPierre Ossman irqmask = MCI_RXFIFOHALFFULLMASK; 11921c6a0718SPierre Ossman 11931c6a0718SPierre Ossman /* 1194c4d877c1SRussell King * If we have less than the fifo 'half-full' threshold to 1195c4d877c1SRussell King * transfer, trigger a PIO interrupt as soon as any data 1196c4d877c1SRussell King * is available. 11971c6a0718SPierre Ossman */ 1198c4d877c1SRussell King if (host->size < variant->fifohalfsize) 11991c6a0718SPierre Ossman irqmask |= MCI_RXDATAAVLBLMASK; 12001c6a0718SPierre Ossman } else { 12011c6a0718SPierre Ossman /* 12021c6a0718SPierre Ossman * We don't actually need to include "FIFO empty" here 12031c6a0718SPierre Ossman * since its implicit in "FIFO half empty". 12041c6a0718SPierre Ossman */ 12051c6a0718SPierre Ossman irqmask = MCI_TXFIFOHALFEMPTYMASK; 12061c6a0718SPierre Ossman } 12071c6a0718SPierre Ossman 12089cc639a2SUlf Hansson mmci_write_datactrlreg(host, datactrl); 12091c6a0718SPierre Ossman writel(readl(base + MMCIMASK0) & ~MCI_DATAENDMASK, base + MMCIMASK0); 12102686b4b4SLinus Walleij mmci_set_mask1(host, irqmask); 12111c6a0718SPierre Ossman } 12121c6a0718SPierre Ossman 12131c6a0718SPierre Ossman static void 12141c6a0718SPierre Ossman mmci_start_command(struct mmci_host *host, struct mmc_command *cmd, u32 c) 12151c6a0718SPierre Ossman { 12161c6a0718SPierre Ossman void __iomem *base = host->base; 12178266c585SLudovic Barre unsigned long long clks; 12181c6a0718SPierre Ossman 121964de0289SLinus Walleij dev_dbg(mmc_dev(host->mmc), "op %02x arg %08x flags %08x\n", 12201c6a0718SPierre Ossman cmd->opcode, cmd->arg, cmd->flags); 12211c6a0718SPierre Ossman 12220f244804SLudovic Barre if (readl(base + MMCICOMMAND) & host->variant->cmdreg_cpsm_enable) { 12231c6a0718SPierre Ossman writel(0, base + MMCICOMMAND); 12246adb2a80SSrinivas Kandagatla mmci_reg_delay(host); 12251c6a0718SPierre Ossman } 12261c6a0718SPierre Ossman 1227c8073e52SLudovic Barre if (host->variant->cmdreg_stop && 1228c8073e52SLudovic Barre cmd->opcode == MMC_STOP_TRANSMISSION) 1229c8073e52SLudovic Barre c |= host->variant->cmdreg_stop; 1230c8073e52SLudovic Barre 12310f244804SLudovic Barre c |= cmd->opcode | host->variant->cmdreg_cpsm_enable; 12321c6a0718SPierre Ossman if (cmd->flags & MMC_RSP_PRESENT) { 12331c6a0718SPierre Ossman if (cmd->flags & MMC_RSP_136) 12340f244804SLudovic Barre c |= host->variant->cmdreg_lrsp_crc; 12350f244804SLudovic Barre else if (cmd->flags & MMC_RSP_CRC) 12360f244804SLudovic Barre c |= host->variant->cmdreg_srsp_crc; 12370f244804SLudovic Barre else 12380f244804SLudovic Barre c |= host->variant->cmdreg_srsp; 12391c6a0718SPierre Ossman } 12408266c585SLudovic Barre 12418266c585SLudovic Barre if (host->variant->busy_timeout && cmd->flags & MMC_RSP_BUSY) { 12428266c585SLudovic Barre if (!cmd->busy_timeout) 12438266c585SLudovic Barre cmd->busy_timeout = 10 * MSEC_PER_SEC; 12448266c585SLudovic Barre 1245774514bfSYann Gautier if (cmd->busy_timeout > host->mmc->max_busy_timeout) 1246774514bfSYann Gautier clks = (unsigned long long)host->mmc->max_busy_timeout * host->cclk; 1247774514bfSYann Gautier else 12488266c585SLudovic Barre clks = (unsigned long long)cmd->busy_timeout * host->cclk; 1249774514bfSYann Gautier 12508266c585SLudovic Barre do_div(clks, MSEC_PER_SEC); 12518266c585SLudovic Barre writel_relaxed(clks, host->base + MMCIDATATIMER); 12528266c585SLudovic Barre } 12538266c585SLudovic Barre 125475773165SLudovic Barre if (host->ops->pre_sig_volt_switch && cmd->opcode == SD_SWITCH_VOLTAGE) 125575773165SLudovic Barre host->ops->pre_sig_volt_switch(host); 125675773165SLudovic Barre 12571c6a0718SPierre Ossman if (/*interrupt*/0) 12581c6a0718SPierre Ossman c |= MCI_CPSM_INTERRUPT; 12591c6a0718SPierre Ossman 1260ae7b0061SSrinivas Kandagatla if (mmc_cmd_type(cmd) == MMC_CMD_ADTC) 1261ae7b0061SSrinivas Kandagatla c |= host->variant->data_cmd_enable; 1262ae7b0061SSrinivas Kandagatla 12631c6a0718SPierre Ossman host->cmd = cmd; 12641c6a0718SPierre Ossman 12651c6a0718SPierre Ossman writel(cmd->arg, base + MMCIARGUMENT); 12661c6a0718SPierre Ossman writel(c, base + MMCICOMMAND); 12671c6a0718SPierre Ossman } 12681c6a0718SPierre Ossman 1269e9968c6fSUlf Hansson static void mmci_stop_command(struct mmci_host *host) 1270e9968c6fSUlf Hansson { 1271e9968c6fSUlf Hansson host->stop_abort.error = 0; 1272e9968c6fSUlf Hansson mmci_start_command(host, &host->stop_abort, 0); 1273e9968c6fSUlf Hansson } 1274e9968c6fSUlf Hansson 12751c6a0718SPierre Ossman static void 12761c6a0718SPierre Ossman mmci_data_irq(struct mmci_host *host, struct mmc_data *data, 12771c6a0718SPierre Ossman unsigned int status) 12781c6a0718SPierre Ossman { 1279daf9713cSLudovic Barre unsigned int status_err; 1280daf9713cSLudovic Barre 12811cb9da50SUlf Hansson /* Make sure we have data to handle */ 12821cb9da50SUlf Hansson if (!data) 12831cb9da50SUlf Hansson return; 12841cb9da50SUlf Hansson 1285f20f8f21SLinus Walleij /* First check for errors */ 1286daf9713cSLudovic Barre status_err = status & (host->variant->start_err | 1287daf9713cSLudovic Barre MCI_DATACRCFAIL | MCI_DATATIMEOUT | 1288daf9713cSLudovic Barre MCI_TXUNDERRUN | MCI_RXOVERRUN); 1289daf9713cSLudovic Barre 1290daf9713cSLudovic Barre if (status_err) { 12918cb28155SLinus Walleij u32 remain, success; 1292f20f8f21SLinus Walleij 1293c8ebae37SRussell King /* Terminate the DMA transfer */ 1294cfccc6acSLudovic Barre mmci_dma_error(host); 1295c8ebae37SRussell King 1296c8afc9d5SRussell King /* 1297c8afc9d5SRussell King * Calculate how far we are into the transfer. Note that 1298c8afc9d5SRussell King * the data counter gives the number of bytes transferred 1299c8afc9d5SRussell King * on the MMC bus, not on the host side. On reads, this 1300c8afc9d5SRussell King * can be as much as a FIFO-worth of data ahead. This 1301c8afc9d5SRussell King * matters for FIFO overruns only. 1302c8afc9d5SRussell King */ 1303b79220b3SLudovic Barre if (!host->variant->datacnt_useless) { 1304f5a106d9SLinus Walleij remain = readl(host->base + MMCIDATACNT); 13058cb28155SLinus Walleij success = data->blksz * data->blocks - remain; 1306b79220b3SLudovic Barre } else { 1307b79220b3SLudovic Barre success = 0; 1308b79220b3SLudovic Barre } 13098cb28155SLinus Walleij 1310c8afc9d5SRussell King dev_dbg(mmc_dev(host->mmc), "MCI ERROR IRQ, status 0x%08x at 0x%08x\n", 1311daf9713cSLudovic Barre status_err, success); 1312daf9713cSLudovic Barre if (status_err & MCI_DATACRCFAIL) { 13138cb28155SLinus Walleij /* Last block was not successful */ 1314c8afc9d5SRussell King success -= 1; 131517b0429dSPierre Ossman data->error = -EILSEQ; 1316daf9713cSLudovic Barre } else if (status_err & MCI_DATATIMEOUT) { 131717b0429dSPierre Ossman data->error = -ETIMEDOUT; 1318daf9713cSLudovic Barre } else if (status_err & MCI_STARTBITERR) { 1319757df746SLinus Walleij data->error = -ECOMM; 1320daf9713cSLudovic Barre } else if (status_err & MCI_TXUNDERRUN) { 132117b0429dSPierre Ossman data->error = -EIO; 1322daf9713cSLudovic Barre } else if (status_err & MCI_RXOVERRUN) { 1323c8afc9d5SRussell King if (success > host->variant->fifosize) 1324c8afc9d5SRussell King success -= host->variant->fifosize; 1325c8afc9d5SRussell King else 1326c8afc9d5SRussell King success = 0; 13278cb28155SLinus Walleij data->error = -EIO; 13284ce1d6cbSRabin Vincent } 132951d4375dSRussell King data->bytes_xfered = round_down(success, data->blksz); 13301c6a0718SPierre Ossman } 1331f20f8f21SLinus Walleij 13328cb28155SLinus Walleij if (status & MCI_DATABLOCKEND) 13338cb28155SLinus Walleij dev_err(mmc_dev(host->mmc), "stray MCI_DATABLOCKEND interrupt\n"); 1334f20f8f21SLinus Walleij 1335ccff9b51SRussell King if (status & MCI_DATAEND || data->error) { 1336653a761eSUlf Hansson mmci_dma_finalize(host, data); 1337cdea1947SLudovic Barre 13381c6a0718SPierre Ossman mmci_stop_data(host); 13391c6a0718SPierre Ossman 13408cb28155SLinus Walleij if (!data->error) 13418cb28155SLinus Walleij /* The error clause is handled above, success! */ 134251d4375dSRussell King data->bytes_xfered = data->blksz * data->blocks; 1343f20f8f21SLinus Walleij 1344e9968c6fSUlf Hansson if (!data->stop) { 1345e9968c6fSUlf Hansson if (host->variant->cmdreg_stop && data->error) 1346e9968c6fSUlf Hansson mmci_stop_command(host); 134709b4f706SLudovic Barre else 1348e9968c6fSUlf Hansson mmci_request_end(host, data->mrq); 1349e9968c6fSUlf Hansson } else if (host->mrq->sbc && !data->error) { 1350e9968c6fSUlf Hansson mmci_request_end(host, data->mrq); 1351e9968c6fSUlf Hansson } else { 13521c6a0718SPierre Ossman mmci_start_command(host, data->stop, 0); 13531c6a0718SPierre Ossman } 13541c6a0718SPierre Ossman } 1355e9968c6fSUlf Hansson } 13561c6a0718SPierre Ossman 13571c6a0718SPierre Ossman static void 13581c6a0718SPierre Ossman mmci_cmd_irq(struct mmci_host *host, struct mmc_command *cmd, 13591c6a0718SPierre Ossman unsigned int status) 13601c6a0718SPierre Ossman { 13618266c585SLudovic Barre u32 err_msk = MCI_CMDCRCFAIL | MCI_CMDTIMEOUT; 13621c6a0718SPierre Ossman void __iomem *base = host->base; 1363812513c7SLudovic Barre bool sbc, busy_resp; 1364ad82bfeaSUlf Hansson 1365ad82bfeaSUlf Hansson if (!cmd) 1366ad82bfeaSUlf Hansson return; 1367ad82bfeaSUlf Hansson 1368ad82bfeaSUlf Hansson sbc = (cmd == host->mrq->sbc); 1369812513c7SLudovic Barre busy_resp = !!(cmd->flags & MMC_RSP_BUSY); 1370ad82bfeaSUlf Hansson 137149adc0caSLinus Walleij /* 137249adc0caSLinus Walleij * We need to be one of these interrupts to be considered worth 137349adc0caSLinus Walleij * handling. Note that we tag on any latent IRQs postponed 137449adc0caSLinus Walleij * due to waiting for busy status. 137549adc0caSLinus Walleij */ 13768266c585SLudovic Barre if (host->variant->busy_timeout && busy_resp) 13778266c585SLudovic Barre err_msk |= MCI_DATATIMEOUT; 13788266c585SLudovic Barre 137949adc0caSLinus Walleij if (!((status | host->busy_status) & 13808266c585SLudovic Barre (err_msk | MCI_CMDSENT | MCI_CMDRESPEND))) 1381ad82bfeaSUlf Hansson return; 13828d94b54dSUlf Hansson 1383a9cbd79cSUlf Hansson /* Handle busy detection on DAT0 if the variant supports it. */ 1384cb0335b7SLudovic Barre if (busy_resp && host->variant->busy_detect) 1385cb0335b7SLudovic Barre if (!host->ops->busy_complete(host, status, err_msk)) 13868d94b54dSUlf Hansson return; 13871c6a0718SPierre Ossman 13881c6a0718SPierre Ossman host->cmd = NULL; 13891c6a0718SPierre Ossman 13901c6a0718SPierre Ossman if (status & MCI_CMDTIMEOUT) { 139117b0429dSPierre Ossman cmd->error = -ETIMEDOUT; 13921c6a0718SPierre Ossman } else if (status & MCI_CMDCRCFAIL && cmd->flags & MMC_RSP_CRC) { 139317b0429dSPierre Ossman cmd->error = -EILSEQ; 13948266c585SLudovic Barre } else if (host->variant->busy_timeout && busy_resp && 13958266c585SLudovic Barre status & MCI_DATATIMEOUT) { 13968266c585SLudovic Barre cmd->error = -ETIMEDOUT; 1397546b73abSLinus Walleij /* 1398546b73abSLinus Walleij * This will wake up mmci_irq_thread() which will issue 1399546b73abSLinus Walleij * a hardware reset of the MMCI block. 1400546b73abSLinus Walleij */ 1401ee157abeSLudovic Barre host->irq_action = IRQ_WAKE_THREAD; 14029047b435SRussell King - ARM Linux } else { 14039047b435SRussell King - ARM Linux cmd->resp[0] = readl(base + MMCIRESPONSE0); 14049047b435SRussell King - ARM Linux cmd->resp[1] = readl(base + MMCIRESPONSE1); 14059047b435SRussell King - ARM Linux cmd->resp[2] = readl(base + MMCIRESPONSE2); 14069047b435SRussell King - ARM Linux cmd->resp[3] = readl(base + MMCIRESPONSE3); 14071c6a0718SPierre Ossman } 14081c6a0718SPierre Ossman 1409024629c6SUlf Hansson if ((!sbc && !cmd->data) || cmd->error) { 14103b6e3c73SUlf Hansson if (host->data) { 14113b6e3c73SUlf Hansson /* Terminate the DMA transfer */ 1412cfccc6acSLudovic Barre mmci_dma_error(host); 14137b2a6d51SLudovic Barre 14141c6a0718SPierre Ossman mmci_stop_data(host); 1415e9968c6fSUlf Hansson if (host->variant->cmdreg_stop && cmd->error) { 1416e9968c6fSUlf Hansson mmci_stop_command(host); 1417e9968c6fSUlf Hansson return; 1418e9968c6fSUlf Hansson } 14193b6e3c73SUlf Hansson } 1420ee157abeSLudovic Barre 1421ee157abeSLudovic Barre if (host->irq_action != IRQ_WAKE_THREAD) 1422024629c6SUlf Hansson mmci_request_end(host, host->mrq); 1423ee157abeSLudovic Barre 1424024629c6SUlf Hansson } else if (sbc) { 1425024629c6SUlf Hansson mmci_start_command(host, host->mrq->cmd, 0); 1426d2141547SLudovic Barre } else if (!host->variant->datactrl_first && 1427d2141547SLudovic Barre !(cmd->data->flags & MMC_DATA_READ)) { 14281c6a0718SPierre Ossman mmci_start_data(host, cmd->data); 14291c6a0718SPierre Ossman } 14301c6a0718SPierre Ossman } 14311c6a0718SPierre Ossman 14329c34b73dSSrinivas Kandagatla static int mmci_get_rx_fifocnt(struct mmci_host *host, u32 status, int remain) 14339c34b73dSSrinivas Kandagatla { 14349c34b73dSSrinivas Kandagatla return remain - (readl(host->base + MMCIFIFOCNT) << 2); 14359c34b73dSSrinivas Kandagatla } 14369c34b73dSSrinivas Kandagatla 14379c34b73dSSrinivas Kandagatla static int mmci_qcom_get_rx_fifocnt(struct mmci_host *host, u32 status, int r) 14389c34b73dSSrinivas Kandagatla { 14399c34b73dSSrinivas Kandagatla /* 14409c34b73dSSrinivas Kandagatla * on qcom SDCC4 only 8 words are used in each burst so only 8 addresses 14419c34b73dSSrinivas Kandagatla * from the fifo range should be used 14429c34b73dSSrinivas Kandagatla */ 14439c34b73dSSrinivas Kandagatla if (status & MCI_RXFIFOHALFFULL) 14449c34b73dSSrinivas Kandagatla return host->variant->fifohalfsize; 14459c34b73dSSrinivas Kandagatla else if (status & MCI_RXDATAAVLBL) 14469c34b73dSSrinivas Kandagatla return 4; 14479c34b73dSSrinivas Kandagatla 14489c34b73dSSrinivas Kandagatla return 0; 14499c34b73dSSrinivas Kandagatla } 14509c34b73dSSrinivas Kandagatla 14511c6a0718SPierre Ossman static int mmci_pio_read(struct mmci_host *host, char *buffer, unsigned int remain) 14521c6a0718SPierre Ossman { 14531c6a0718SPierre Ossman void __iomem *base = host->base; 14541c6a0718SPierre Ossman char *ptr = buffer; 14559c34b73dSSrinivas Kandagatla u32 status = readl(host->base + MMCISTATUS); 145626eed9a5SLinus Walleij int host_remain = host->size; 14571c6a0718SPierre Ossman 14581c6a0718SPierre Ossman do { 14599c34b73dSSrinivas Kandagatla int count = host->get_rx_fifocnt(host, status, host_remain); 14601c6a0718SPierre Ossman 14611c6a0718SPierre Ossman if (count > remain) 14621c6a0718SPierre Ossman count = remain; 14631c6a0718SPierre Ossman 14641c6a0718SPierre Ossman if (count <= 0) 14651c6a0718SPierre Ossman break; 14661c6a0718SPierre Ossman 1467393e5e24SUlf Hansson /* 1468393e5e24SUlf Hansson * SDIO especially may want to send something that is 1469393e5e24SUlf Hansson * not divisible by 4 (as opposed to card sectors 1470393e5e24SUlf Hansson * etc). Therefore make sure to always read the last bytes 1471393e5e24SUlf Hansson * while only doing full 32-bit reads towards the FIFO. 1472393e5e24SUlf Hansson */ 1473393e5e24SUlf Hansson if (unlikely(count & 0x3)) { 1474393e5e24SUlf Hansson if (count < 4) { 1475393e5e24SUlf Hansson unsigned char buf[4]; 14764b85da08SDavide Ciminaghi ioread32_rep(base + MMCIFIFO, buf, 1); 1477393e5e24SUlf Hansson memcpy(ptr, buf, count); 1478393e5e24SUlf Hansson } else { 14794b85da08SDavide Ciminaghi ioread32_rep(base + MMCIFIFO, ptr, count >> 2); 1480393e5e24SUlf Hansson count &= ~0x3; 1481393e5e24SUlf Hansson } 1482393e5e24SUlf Hansson } else { 14834b85da08SDavide Ciminaghi ioread32_rep(base + MMCIFIFO, ptr, count >> 2); 1484393e5e24SUlf Hansson } 14851c6a0718SPierre Ossman 14861c6a0718SPierre Ossman ptr += count; 14871c6a0718SPierre Ossman remain -= count; 148826eed9a5SLinus Walleij host_remain -= count; 14891c6a0718SPierre Ossman 14901c6a0718SPierre Ossman if (remain == 0) 14911c6a0718SPierre Ossman break; 14921c6a0718SPierre Ossman 14931c6a0718SPierre Ossman status = readl(base + MMCISTATUS); 14941c6a0718SPierre Ossman } while (status & MCI_RXDATAAVLBL); 14951c6a0718SPierre Ossman 14961c6a0718SPierre Ossman return ptr - buffer; 14971c6a0718SPierre Ossman } 14981c6a0718SPierre Ossman 14991c6a0718SPierre Ossman static int mmci_pio_write(struct mmci_host *host, char *buffer, unsigned int remain, u32 status) 15001c6a0718SPierre Ossman { 15018301bb68SRabin Vincent struct variant_data *variant = host->variant; 15021c6a0718SPierre Ossman void __iomem *base = host->base; 15031c6a0718SPierre Ossman char *ptr = buffer; 15041c6a0718SPierre Ossman 15051c6a0718SPierre Ossman do { 15061c6a0718SPierre Ossman unsigned int count, maxcnt; 15071c6a0718SPierre Ossman 15088301bb68SRabin Vincent maxcnt = status & MCI_TXFIFOEMPTY ? 15098301bb68SRabin Vincent variant->fifosize : variant->fifohalfsize; 15101c6a0718SPierre Ossman count = min(remain, maxcnt); 15111c6a0718SPierre Ossman 151234177802SLinus Walleij /* 151334177802SLinus Walleij * SDIO especially may want to send something that is 151434177802SLinus Walleij * not divisible by 4 (as opposed to card sectors 151534177802SLinus Walleij * etc), and the FIFO only accept full 32-bit writes. 151634177802SLinus Walleij * So compensate by adding +3 on the count, a single 151734177802SLinus Walleij * byte become a 32bit write, 7 bytes will be two 151834177802SLinus Walleij * 32bit writes etc. 151934177802SLinus Walleij */ 15204b85da08SDavide Ciminaghi iowrite32_rep(base + MMCIFIFO, ptr, (count + 3) >> 2); 15211c6a0718SPierre Ossman 15221c6a0718SPierre Ossman ptr += count; 15231c6a0718SPierre Ossman remain -= count; 15241c6a0718SPierre Ossman 15251c6a0718SPierre Ossman if (remain == 0) 15261c6a0718SPierre Ossman break; 15271c6a0718SPierre Ossman 15281c6a0718SPierre Ossman status = readl(base + MMCISTATUS); 15291c6a0718SPierre Ossman } while (status & MCI_TXFIFOHALFEMPTY); 15301c6a0718SPierre Ossman 15311c6a0718SPierre Ossman return ptr - buffer; 15321c6a0718SPierre Ossman } 15331c6a0718SPierre Ossman 15341c6a0718SPierre Ossman /* 15351c6a0718SPierre Ossman * PIO data transfer IRQ handler. 15361c6a0718SPierre Ossman */ 15371c6a0718SPierre Ossman static irqreturn_t mmci_pio_irq(int irq, void *dev_id) 15381c6a0718SPierre Ossman { 15391c6a0718SPierre Ossman struct mmci_host *host = dev_id; 15404ce1d6cbSRabin Vincent struct sg_mapping_iter *sg_miter = &host->sg_miter; 15418301bb68SRabin Vincent struct variant_data *variant = host->variant; 15421c6a0718SPierre Ossman void __iomem *base = host->base; 15431c6a0718SPierre Ossman u32 status; 15441c6a0718SPierre Ossman 15451c6a0718SPierre Ossman status = readl(base + MMCISTATUS); 15461c6a0718SPierre Ossman 154764de0289SLinus Walleij dev_dbg(mmc_dev(host->mmc), "irq1 (pio) %08x\n", status); 15481c6a0718SPierre Ossman 15491c6a0718SPierre Ossman do { 15501c6a0718SPierre Ossman unsigned int remain, len; 15511c6a0718SPierre Ossman char *buffer; 15521c6a0718SPierre Ossman 15531c6a0718SPierre Ossman /* 15541c6a0718SPierre Ossman * For write, we only need to test the half-empty flag 15551c6a0718SPierre Ossman * here - if the FIFO is completely empty, then by 15561c6a0718SPierre Ossman * definition it is more than half empty. 15571c6a0718SPierre Ossman * 15581c6a0718SPierre Ossman * For read, check for data available. 15591c6a0718SPierre Ossman */ 15601c6a0718SPierre Ossman if (!(status & (MCI_TXFIFOHALFEMPTY|MCI_RXDATAAVLBL))) 15611c6a0718SPierre Ossman break; 15621c6a0718SPierre Ossman 15634ce1d6cbSRabin Vincent if (!sg_miter_next(sg_miter)) 15644ce1d6cbSRabin Vincent break; 15654ce1d6cbSRabin Vincent 15664ce1d6cbSRabin Vincent buffer = sg_miter->addr; 15674ce1d6cbSRabin Vincent remain = sg_miter->length; 15681c6a0718SPierre Ossman 15691c6a0718SPierre Ossman len = 0; 15701c6a0718SPierre Ossman if (status & MCI_RXACTIVE) 15711c6a0718SPierre Ossman len = mmci_pio_read(host, buffer, remain); 15721c6a0718SPierre Ossman if (status & MCI_TXACTIVE) 15731c6a0718SPierre Ossman len = mmci_pio_write(host, buffer, remain, status); 15741c6a0718SPierre Ossman 15754ce1d6cbSRabin Vincent sg_miter->consumed = len; 15761c6a0718SPierre Ossman 15771c6a0718SPierre Ossman host->size -= len; 15781c6a0718SPierre Ossman remain -= len; 15791c6a0718SPierre Ossman 15801c6a0718SPierre Ossman if (remain) 15811c6a0718SPierre Ossman break; 15821c6a0718SPierre Ossman 15831c6a0718SPierre Ossman status = readl(base + MMCISTATUS); 15841c6a0718SPierre Ossman } while (1); 15851c6a0718SPierre Ossman 15864ce1d6cbSRabin Vincent sg_miter_stop(sg_miter); 15874ce1d6cbSRabin Vincent 15881c6a0718SPierre Ossman /* 1589c4d877c1SRussell King * If we have less than the fifo 'half-full' threshold to transfer, 1590c4d877c1SRussell King * trigger a PIO interrupt as soon as any data is available. 15911c6a0718SPierre Ossman */ 1592c4d877c1SRussell King if (status & MCI_RXACTIVE && host->size < variant->fifohalfsize) 15932686b4b4SLinus Walleij mmci_set_mask1(host, MCI_RXDATAAVLBLMASK); 15941c6a0718SPierre Ossman 15951c6a0718SPierre Ossman /* 15961c6a0718SPierre Ossman * If we run out of data, disable the data IRQs; this 15971c6a0718SPierre Ossman * prevents a race where the FIFO becomes empty before 15981c6a0718SPierre Ossman * the chip itself has disabled the data path, and 15991c6a0718SPierre Ossman * stops us racing with our data end IRQ. 16001c6a0718SPierre Ossman */ 16011c6a0718SPierre Ossman if (host->size == 0) { 16022686b4b4SLinus Walleij mmci_set_mask1(host, 0); 16031c6a0718SPierre Ossman writel(readl(base + MMCIMASK0) | MCI_DATAENDMASK, base + MMCIMASK0); 16041c6a0718SPierre Ossman } 16051c6a0718SPierre Ossman 16061c6a0718SPierre Ossman return IRQ_HANDLED; 16071c6a0718SPierre Ossman } 16081c6a0718SPierre Ossman 16091c6a0718SPierre Ossman /* 16101c6a0718SPierre Ossman * Handle completion of command and data transfers. 16111c6a0718SPierre Ossman */ 16121c6a0718SPierre Ossman static irqreturn_t mmci_irq(int irq, void *dev_id) 16131c6a0718SPierre Ossman { 16141c6a0718SPierre Ossman struct mmci_host *host = dev_id; 16151c6a0718SPierre Ossman u32 status; 16161c6a0718SPierre Ossman 16171c6a0718SPierre Ossman spin_lock(&host->lock); 1618ee157abeSLudovic Barre host->irq_action = IRQ_HANDLED; 16191c6a0718SPierre Ossman 16201c6a0718SPierre Ossman do { 16211c6a0718SPierre Ossman status = readl(host->base + MMCISTATUS); 1622*f7ad7504SLinus Walleij if (!status) 1623*f7ad7504SLinus Walleij break; 16242686b4b4SLinus Walleij 16252686b4b4SLinus Walleij if (host->singleirq) { 16266ea9cdf3SPatrice Chotard if (status & host->mask1_reg) 16272686b4b4SLinus Walleij mmci_pio_irq(irq, dev_id); 16282686b4b4SLinus Walleij 162959db5e2dSLudovic Barre status &= ~host->variant->irq_pio_mask; 16302686b4b4SLinus Walleij } 16312686b4b4SLinus Walleij 16328d94b54dSUlf Hansson /* 1633a9cbd79cSUlf Hansson * Busy detection is managed by mmci_cmd_irq(), including to 1634a9cbd79cSUlf Hansson * clear the corresponding IRQ. 16358d94b54dSUlf Hansson */ 16361c6a0718SPierre Ossman status &= readl(host->base + MMCIMASK0); 16375cad24d8SJean-Nicolas Graux if (host->variant->busy_detect) 16385cad24d8SJean-Nicolas Graux writel(status & ~host->variant->busy_detect_mask, 16395cad24d8SJean-Nicolas Graux host->base + MMCICLEAR); 16405cad24d8SJean-Nicolas Graux else 16411c6a0718SPierre Ossman writel(status, host->base + MMCICLEAR); 16421c6a0718SPierre Ossman 164364de0289SLinus Walleij dev_dbg(mmc_dev(host->mmc), "irq0 (data+cmd) %08x\n", status); 16441c6a0718SPierre Ossman 16457878289bSUlf Hansson if (host->variant->reversed_irq_handling) { 16467878289bSUlf Hansson mmci_data_irq(host, host->data, status); 16477878289bSUlf Hansson mmci_cmd_irq(host, host->cmd, status); 16487878289bSUlf Hansson } else { 1649ad82bfeaSUlf Hansson mmci_cmd_irq(host, host->cmd, status); 16501cb9da50SUlf Hansson mmci_data_irq(host, host->data, status); 16517878289bSUlf Hansson } 16521c6a0718SPierre Ossman 165349adc0caSLinus Walleij /* 16548520ce1eSLudovic Barre * Busy detection has been handled by mmci_cmd_irq() above. 16558520ce1eSLudovic Barre * Clear the status bit to prevent polling in IRQ context. 165649adc0caSLinus Walleij */ 16578520ce1eSLudovic Barre if (host->variant->busy_detect_flag) 165849adc0caSLinus Walleij status &= ~host->variant->busy_detect_flag; 16598d94b54dSUlf Hansson 16601c6a0718SPierre Ossman } while (status); 16611c6a0718SPierre Ossman 16621c6a0718SPierre Ossman spin_unlock(&host->lock); 16631c6a0718SPierre Ossman 1664ee157abeSLudovic Barre return host->irq_action; 1665ee157abeSLudovic Barre } 1666ee157abeSLudovic Barre 1667ee157abeSLudovic Barre /* 1668ee157abeSLudovic Barre * mmci_irq_thread() - A threaded IRQ handler that manages a reset of the HW. 1669ee157abeSLudovic Barre * 1670ee157abeSLudovic Barre * A reset is needed for some variants, where a datatimeout for a R1B request 1671ee157abeSLudovic Barre * causes the DPSM to stay busy (non-functional). 1672ee157abeSLudovic Barre */ 1673ee157abeSLudovic Barre static irqreturn_t mmci_irq_thread(int irq, void *dev_id) 1674ee157abeSLudovic Barre { 1675ee157abeSLudovic Barre struct mmci_host *host = dev_id; 1676ee157abeSLudovic Barre unsigned long flags; 1677ee157abeSLudovic Barre 1678ee157abeSLudovic Barre if (host->rst) { 1679ee157abeSLudovic Barre reset_control_assert(host->rst); 1680ee157abeSLudovic Barre udelay(2); 1681ee157abeSLudovic Barre reset_control_deassert(host->rst); 1682ee157abeSLudovic Barre } 1683ee157abeSLudovic Barre 1684ee157abeSLudovic Barre spin_lock_irqsave(&host->lock, flags); 1685ee157abeSLudovic Barre writel(host->clk_reg, host->base + MMCICLOCK); 1686ee157abeSLudovic Barre writel(host->pwr_reg, host->base + MMCIPOWER); 1687ee157abeSLudovic Barre writel(MCI_IRQENABLE | host->variant->start_err, 1688ee157abeSLudovic Barre host->base + MMCIMASK0); 1689ee157abeSLudovic Barre 1690ee157abeSLudovic Barre host->irq_action = IRQ_HANDLED; 1691ee157abeSLudovic Barre mmci_request_end(host, host->mrq); 1692ee157abeSLudovic Barre spin_unlock_irqrestore(&host->lock, flags); 1693ee157abeSLudovic Barre 1694ee157abeSLudovic Barre return host->irq_action; 16951c6a0718SPierre Ossman } 16961c6a0718SPierre Ossman 16971c6a0718SPierre Ossman static void mmci_request(struct mmc_host *mmc, struct mmc_request *mrq) 16981c6a0718SPierre Ossman { 16991c6a0718SPierre Ossman struct mmci_host *host = mmc_priv(mmc); 17009e943021SLinus Walleij unsigned long flags; 17011c6a0718SPierre Ossman 17021c6a0718SPierre Ossman WARN_ON(host->mrq != NULL); 17031c6a0718SPierre Ossman 1704653a761eSUlf Hansson mrq->cmd->error = mmci_validate_data(host, mrq->data); 1705653a761eSUlf Hansson if (mrq->cmd->error) { 1706255d01afSPierre Ossman mmc_request_done(mmc, mrq); 1707255d01afSPierre Ossman return; 1708255d01afSPierre Ossman } 1709255d01afSPierre Ossman 17109e943021SLinus Walleij spin_lock_irqsave(&host->lock, flags); 17111c6a0718SPierre Ossman 17121c6a0718SPierre Ossman host->mrq = mrq; 17131c6a0718SPierre Ossman 171458c7ccbfSPer Forlin if (mrq->data) 171558c7ccbfSPer Forlin mmci_get_next_data(host, mrq->data); 171658c7ccbfSPer Forlin 1717d2141547SLudovic Barre if (mrq->data && 1718d2141547SLudovic Barre (host->variant->datactrl_first || mrq->data->flags & MMC_DATA_READ)) 17191c6a0718SPierre Ossman mmci_start_data(host, mrq->data); 17201c6a0718SPierre Ossman 1721024629c6SUlf Hansson if (mrq->sbc) 1722024629c6SUlf Hansson mmci_start_command(host, mrq->sbc, 0); 1723024629c6SUlf Hansson else 17241c6a0718SPierre Ossman mmci_start_command(host, mrq->cmd, 0); 17251c6a0718SPierre Ossman 17269e943021SLinus Walleij spin_unlock_irqrestore(&host->lock, flags); 17271c6a0718SPierre Ossman } 17281c6a0718SPierre Ossman 17298266c585SLudovic Barre static void mmci_set_max_busy_timeout(struct mmc_host *mmc) 17308266c585SLudovic Barre { 17318266c585SLudovic Barre struct mmci_host *host = mmc_priv(mmc); 17328266c585SLudovic Barre u32 max_busy_timeout = 0; 17338266c585SLudovic Barre 17348266c585SLudovic Barre if (!host->variant->busy_detect) 17358266c585SLudovic Barre return; 17368266c585SLudovic Barre 17378266c585SLudovic Barre if (host->variant->busy_timeout && mmc->actual_clock) 17388266c585SLudovic Barre max_busy_timeout = ~0UL / (mmc->actual_clock / MSEC_PER_SEC); 17398266c585SLudovic Barre 17408266c585SLudovic Barre mmc->max_busy_timeout = max_busy_timeout; 17418266c585SLudovic Barre } 17428266c585SLudovic Barre 17431c6a0718SPierre Ossman static void mmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) 17441c6a0718SPierre Ossman { 17451c6a0718SPierre Ossman struct mmci_host *host = mmc_priv(mmc); 17467d72a1d4SUlf Hansson struct variant_data *variant = host->variant; 1747a6a6464aSLinus Walleij u32 pwr = 0; 1748a6a6464aSLinus Walleij unsigned long flags; 1749db90f91fSLee Jones int ret; 17501c6a0718SPierre Ossman 1751bc521818SUlf Hansson if (host->plat->ios_handler && 1752bc521818SUlf Hansson host->plat->ios_handler(mmc_dev(mmc), ios)) 1753bc521818SUlf Hansson dev_err(mmc_dev(mmc), "platform ios_handler failed\n"); 1754bc521818SUlf Hansson 17551c6a0718SPierre Ossman switch (ios->power_mode) { 17561c6a0718SPierre Ossman case MMC_POWER_OFF: 1757599c1d5cSUlf Hansson if (!IS_ERR(mmc->supply.vmmc)) 1758599c1d5cSUlf Hansson mmc_regulator_set_ocr(mmc, mmc->supply.vmmc, 0); 1759237fb5e6SLee Jones 17607c0136efSUlf Hansson if (!IS_ERR(mmc->supply.vqmmc) && host->vqmmc_enabled) { 1761237fb5e6SLee Jones regulator_disable(mmc->supply.vqmmc); 17627c0136efSUlf Hansson host->vqmmc_enabled = false; 17637c0136efSUlf Hansson } 1764237fb5e6SLee Jones 17651c6a0718SPierre Ossman break; 17661c6a0718SPierre Ossman case MMC_POWER_UP: 1767599c1d5cSUlf Hansson if (!IS_ERR(mmc->supply.vmmc)) 1768599c1d5cSUlf Hansson mmc_regulator_set_ocr(mmc, mmc->supply.vmmc, ios->vdd); 1769599c1d5cSUlf Hansson 17707d72a1d4SUlf Hansson /* 17717d72a1d4SUlf Hansson * The ST Micro variant doesn't have the PL180s MCI_PWR_UP 17727d72a1d4SUlf Hansson * and instead uses MCI_PWR_ON so apply whatever value is 17737d72a1d4SUlf Hansson * configured in the variant data. 17747d72a1d4SUlf Hansson */ 17757d72a1d4SUlf Hansson pwr |= variant->pwrreg_powerup; 17767d72a1d4SUlf Hansson 17771c6a0718SPierre Ossman break; 17781c6a0718SPierre Ossman case MMC_POWER_ON: 17797c0136efSUlf Hansson if (!IS_ERR(mmc->supply.vqmmc) && !host->vqmmc_enabled) { 1780db90f91fSLee Jones ret = regulator_enable(mmc->supply.vqmmc); 1781db90f91fSLee Jones if (ret < 0) 1782db90f91fSLee Jones dev_err(mmc_dev(mmc), 1783db90f91fSLee Jones "failed to enable vqmmc regulator\n"); 17847c0136efSUlf Hansson else 17857c0136efSUlf Hansson host->vqmmc_enabled = true; 1786db90f91fSLee Jones } 1787237fb5e6SLee Jones 17881c6a0718SPierre Ossman pwr |= MCI_PWR_ON; 17891c6a0718SPierre Ossman break; 17901c6a0718SPierre Ossman } 17911c6a0718SPierre Ossman 17924d1a3a0dSUlf Hansson if (variant->signal_direction && ios->power_mode != MMC_POWER_OFF) { 17934d1a3a0dSUlf Hansson /* 17944d1a3a0dSUlf Hansson * The ST Micro variant has some additional bits 17954d1a3a0dSUlf Hansson * indicating signal direction for the signals in 17964d1a3a0dSUlf Hansson * the SD/MMC bus and feedback-clock usage. 17974d1a3a0dSUlf Hansson */ 17984593df29SUlf Hansson pwr |= host->pwr_reg_add; 17994d1a3a0dSUlf Hansson 18004d1a3a0dSUlf Hansson if (ios->bus_width == MMC_BUS_WIDTH_4) 18014d1a3a0dSUlf Hansson pwr &= ~MCI_ST_DATA74DIREN; 18024d1a3a0dSUlf Hansson else if (ios->bus_width == MMC_BUS_WIDTH_1) 18034d1a3a0dSUlf Hansson pwr &= (~MCI_ST_DATA74DIREN & 18044d1a3a0dSUlf Hansson ~MCI_ST_DATA31DIREN & 18054d1a3a0dSUlf Hansson ~MCI_ST_DATA2DIREN); 18064d1a3a0dSUlf Hansson } 18074d1a3a0dSUlf Hansson 1808f9bb304cSPatrice Chotard if (variant->opendrain) { 1809f9bb304cSPatrice Chotard if (ios->bus_mode == MMC_BUSMODE_OPENDRAIN) 181011dfb970SPatrice Chotard pwr |= variant->opendrain; 1811f9bb304cSPatrice Chotard } else { 1812f9bb304cSPatrice Chotard /* 1813f9bb304cSPatrice Chotard * If the variant cannot configure the pads by its own, then we 1814f9bb304cSPatrice Chotard * expect the pinctrl to be able to do that for us 1815f9bb304cSPatrice Chotard */ 1816f9bb304cSPatrice Chotard if (ios->bus_mode == MMC_BUSMODE_OPENDRAIN) 1817f9bb304cSPatrice Chotard pinctrl_select_state(host->pinctrl, host->pins_opendrain); 1818f9bb304cSPatrice Chotard else 181905344ffeSUlf Hansson pinctrl_select_default_state(mmc_dev(mmc)); 1820f9bb304cSPatrice Chotard } 18211c6a0718SPierre Ossman 1822f4670daeSUlf Hansson /* 1823f4670daeSUlf Hansson * If clock = 0 and the variant requires the MMCIPOWER to be used for 1824f4670daeSUlf Hansson * gating the clock, the MCI_PWR_ON bit is cleared. 1825f4670daeSUlf Hansson */ 1826f4670daeSUlf Hansson if (!ios->clock && variant->pwrreg_clkgate) 1827f4670daeSUlf Hansson pwr &= ~MCI_PWR_ON; 1828f4670daeSUlf Hansson 18293f4e6f7bSSrinivas Kandagatla if (host->variant->explicit_mclk_control && 18303f4e6f7bSSrinivas Kandagatla ios->clock != host->clock_cache) { 18313f4e6f7bSSrinivas Kandagatla ret = clk_set_rate(host->clk, ios->clock); 18323f4e6f7bSSrinivas Kandagatla if (ret < 0) 18333f4e6f7bSSrinivas Kandagatla dev_err(mmc_dev(host->mmc), 18343f4e6f7bSSrinivas Kandagatla "Error setting clock rate (%d)\n", ret); 18353f4e6f7bSSrinivas Kandagatla else 18363f4e6f7bSSrinivas Kandagatla host->mclk = clk_get_rate(host->clk); 18373f4e6f7bSSrinivas Kandagatla } 18383f4e6f7bSSrinivas Kandagatla host->clock_cache = ios->clock; 18393f4e6f7bSSrinivas Kandagatla 1840a6a6464aSLinus Walleij spin_lock_irqsave(&host->lock, flags); 1841a6a6464aSLinus Walleij 1842cd3ee8c5SLudovic Barre if (host->ops && host->ops->set_clkreg) 1843cd3ee8c5SLudovic Barre host->ops->set_clkreg(host, ios->clock); 1844cd3ee8c5SLudovic Barre else 1845a6a6464aSLinus Walleij mmci_set_clkreg(host, ios->clock); 1846cd3ee8c5SLudovic Barre 18478266c585SLudovic Barre mmci_set_max_busy_timeout(mmc); 18488266c585SLudovic Barre 1849cd3ee8c5SLudovic Barre if (host->ops && host->ops->set_pwrreg) 1850cd3ee8c5SLudovic Barre host->ops->set_pwrreg(host, pwr); 1851cd3ee8c5SLudovic Barre else 18527437cfa5SUlf Hansson mmci_write_pwrreg(host, pwr); 1853cd3ee8c5SLudovic Barre 1854f829c042SUlf Hansson mmci_reg_delay(host); 1855a6a6464aSLinus Walleij 1856a6a6464aSLinus Walleij spin_unlock_irqrestore(&host->lock, flags); 18571c6a0718SPierre Ossman } 18581c6a0718SPierre Ossman 185989001446SRussell King static int mmci_get_cd(struct mmc_host *mmc) 186089001446SRussell King { 186189001446SRussell King struct mmci_host *host = mmc_priv(mmc); 186229719445SRabin Vincent struct mmci_platform_data *plat = host->plat; 1863d2762090SUlf Hansson unsigned int status = mmc_gpio_get_cd(mmc); 186489001446SRussell King 1865d2762090SUlf Hansson if (status == -ENOSYS) { 18664b8caec0SRabin Vincent if (!plat->status) 18674b8caec0SRabin Vincent return 1; /* Assume always present */ 18684b8caec0SRabin Vincent 186929719445SRabin Vincent status = plat->status(mmc_dev(host->mmc)); 1870d2762090SUlf Hansson } 187174bc8093SRussell King return status; 187289001446SRussell King } 187389001446SRussell King 18740f3ed7f7SUlf Hansson static int mmci_sig_volt_switch(struct mmc_host *mmc, struct mmc_ios *ios) 18750f3ed7f7SUlf Hansson { 187675773165SLudovic Barre struct mmci_host *host = mmc_priv(mmc); 18773e09a81eSMarek Vasut int ret; 18780f3ed7f7SUlf Hansson 18793e09a81eSMarek Vasut ret = mmc_regulator_set_vqmmc(mmc, ios); 18800f3ed7f7SUlf Hansson 188175773165SLudovic Barre if (!ret && host->ops && host->ops->post_sig_volt_switch) 188275773165SLudovic Barre ret = host->ops->post_sig_volt_switch(host, ios); 18833e09a81eSMarek Vasut else if (ret) 18843e09a81eSMarek Vasut ret = 0; 188575773165SLudovic Barre 18863e09a81eSMarek Vasut if (ret < 0) 18870f3ed7f7SUlf Hansson dev_warn(mmc_dev(mmc), "Voltage switch failed\n"); 18880f3ed7f7SUlf Hansson 18890f3ed7f7SUlf Hansson return ret; 18900f3ed7f7SUlf Hansson } 18910f3ed7f7SUlf Hansson 189201259620SUlf Hansson static struct mmc_host_ops mmci_ops = { 18931c6a0718SPierre Ossman .request = mmci_request, 189458c7ccbfSPer Forlin .pre_req = mmci_pre_request, 189558c7ccbfSPer Forlin .post_req = mmci_post_request, 18961c6a0718SPierre Ossman .set_ios = mmci_set_ios, 1897d2762090SUlf Hansson .get_ro = mmc_gpio_get_ro, 189889001446SRussell King .get_cd = mmci_get_cd, 18990f3ed7f7SUlf Hansson .start_signal_voltage_switch = mmci_sig_volt_switch, 19001c6a0718SPierre Ossman }; 19011c6a0718SPierre Ossman 19026351cac9SMarek Vasut static void mmci_probe_level_translator(struct mmc_host *mmc) 19036351cac9SMarek Vasut { 19046351cac9SMarek Vasut struct device *dev = mmc_dev(mmc); 19056351cac9SMarek Vasut struct mmci_host *host = mmc_priv(mmc); 19066351cac9SMarek Vasut struct gpio_desc *cmd_gpio; 19076351cac9SMarek Vasut struct gpio_desc *ck_gpio; 19086351cac9SMarek Vasut struct gpio_desc *ckin_gpio; 19096351cac9SMarek Vasut int clk_hi, clk_lo; 19106351cac9SMarek Vasut 19116351cac9SMarek Vasut /* 19126351cac9SMarek Vasut * Assume the level translator is present if st,use-ckin is set. 19136351cac9SMarek Vasut * This is to cater for DTs which do not implement this test. 19146351cac9SMarek Vasut */ 19156351cac9SMarek Vasut host->clk_reg_add |= MCI_STM32_CLK_SELCKIN; 19166351cac9SMarek Vasut 19176351cac9SMarek Vasut cmd_gpio = gpiod_get(dev, "st,cmd", GPIOD_OUT_HIGH); 19186351cac9SMarek Vasut if (IS_ERR(cmd_gpio)) 19196351cac9SMarek Vasut goto exit_cmd; 19206351cac9SMarek Vasut 19216351cac9SMarek Vasut ck_gpio = gpiod_get(dev, "st,ck", GPIOD_OUT_HIGH); 19226351cac9SMarek Vasut if (IS_ERR(ck_gpio)) 19236351cac9SMarek Vasut goto exit_ck; 19246351cac9SMarek Vasut 19256351cac9SMarek Vasut ckin_gpio = gpiod_get(dev, "st,ckin", GPIOD_IN); 19266351cac9SMarek Vasut if (IS_ERR(ckin_gpio)) 19276351cac9SMarek Vasut goto exit_ckin; 19286351cac9SMarek Vasut 19296351cac9SMarek Vasut /* All GPIOs are valid, test whether level translator works */ 19306351cac9SMarek Vasut 19316351cac9SMarek Vasut /* Sample CKIN */ 19326351cac9SMarek Vasut clk_hi = !!gpiod_get_value(ckin_gpio); 19336351cac9SMarek Vasut 19346351cac9SMarek Vasut /* Set CK low */ 19356351cac9SMarek Vasut gpiod_set_value(ck_gpio, 0); 19366351cac9SMarek Vasut 19376351cac9SMarek Vasut /* Sample CKIN */ 19386351cac9SMarek Vasut clk_lo = !!gpiod_get_value(ckin_gpio); 19396351cac9SMarek Vasut 19406351cac9SMarek Vasut /* Tristate all */ 19416351cac9SMarek Vasut gpiod_direction_input(cmd_gpio); 19426351cac9SMarek Vasut gpiod_direction_input(ck_gpio); 19436351cac9SMarek Vasut 19446351cac9SMarek Vasut /* Level translator is present if CK signal is propagated to CKIN */ 19456351cac9SMarek Vasut if (!clk_hi || clk_lo) { 19466351cac9SMarek Vasut host->clk_reg_add &= ~MCI_STM32_CLK_SELCKIN; 19476351cac9SMarek Vasut dev_warn(dev, 19486351cac9SMarek Vasut "Level translator inoperable, CK signal not detected on CKIN, disabling.\n"); 19496351cac9SMarek Vasut } 19506351cac9SMarek Vasut 19516351cac9SMarek Vasut gpiod_put(ckin_gpio); 19526351cac9SMarek Vasut 19536351cac9SMarek Vasut exit_ckin: 19546351cac9SMarek Vasut gpiod_put(ck_gpio); 19556351cac9SMarek Vasut exit_ck: 19566351cac9SMarek Vasut gpiod_put(cmd_gpio); 19576351cac9SMarek Vasut exit_cmd: 19586351cac9SMarek Vasut pinctrl_select_default_state(dev); 19596351cac9SMarek Vasut } 19606351cac9SMarek Vasut 196178f87df2SUlf Hansson static int mmci_of_parse(struct device_node *np, struct mmc_host *mmc) 196278f87df2SUlf Hansson { 19634593df29SUlf Hansson struct mmci_host *host = mmc_priv(mmc); 196478f87df2SUlf Hansson int ret = mmc_of_parse(mmc); 1965000bc9d5SLee Jones 196678f87df2SUlf Hansson if (ret) 196778f87df2SUlf Hansson return ret; 1968000bc9d5SLee Jones 19694593df29SUlf Hansson if (of_get_property(np, "st,sig-dir-dat0", NULL)) 19704593df29SUlf Hansson host->pwr_reg_add |= MCI_ST_DATA0DIREN; 19714593df29SUlf Hansson if (of_get_property(np, "st,sig-dir-dat2", NULL)) 19724593df29SUlf Hansson host->pwr_reg_add |= MCI_ST_DATA2DIREN; 19734593df29SUlf Hansson if (of_get_property(np, "st,sig-dir-dat31", NULL)) 19744593df29SUlf Hansson host->pwr_reg_add |= MCI_ST_DATA31DIREN; 19754593df29SUlf Hansson if (of_get_property(np, "st,sig-dir-dat74", NULL)) 19764593df29SUlf Hansson host->pwr_reg_add |= MCI_ST_DATA74DIREN; 19774593df29SUlf Hansson if (of_get_property(np, "st,sig-dir-cmd", NULL)) 19784593df29SUlf Hansson host->pwr_reg_add |= MCI_ST_CMDDIREN; 19794593df29SUlf Hansson if (of_get_property(np, "st,sig-pin-fbclk", NULL)) 19804593df29SUlf Hansson host->pwr_reg_add |= MCI_ST_FBCLKEN; 198146b723ddSLudovic Barre if (of_get_property(np, "st,sig-dir", NULL)) 198246b723ddSLudovic Barre host->pwr_reg_add |= MCI_STM32_DIRPOL; 198346b723ddSLudovic Barre if (of_get_property(np, "st,neg-edge", NULL)) 198446b723ddSLudovic Barre host->clk_reg_add |= MCI_STM32_CLK_NEGEDGE; 198546b723ddSLudovic Barre if (of_get_property(np, "st,use-ckin", NULL)) 19866351cac9SMarek Vasut mmci_probe_level_translator(mmc); 19874593df29SUlf Hansson 1988000bc9d5SLee Jones if (of_get_property(np, "mmc-cap-mmc-highspeed", NULL)) 198978f87df2SUlf Hansson mmc->caps |= MMC_CAP_MMC_HIGHSPEED; 1990000bc9d5SLee Jones if (of_get_property(np, "mmc-cap-sd-highspeed", NULL)) 199178f87df2SUlf Hansson mmc->caps |= MMC_CAP_SD_HIGHSPEED; 1992000bc9d5SLee Jones 199378f87df2SUlf Hansson return 0; 1994000bc9d5SLee Jones } 1995000bc9d5SLee Jones 1996c3be1efdSBill Pemberton static int mmci_probe(struct amba_device *dev, 1997aa25afadSRussell King const struct amba_id *id) 19981c6a0718SPierre Ossman { 19996ef297f8SLinus Walleij struct mmci_platform_data *plat = dev->dev.platform_data; 2000000bc9d5SLee Jones struct device_node *np = dev->dev.of_node; 20014956e109SRabin Vincent struct variant_data *variant = id->data; 20021c6a0718SPierre Ossman struct mmci_host *host; 20031c6a0718SPierre Ossman struct mmc_host *mmc; 20041c6a0718SPierre Ossman int ret; 20051c6a0718SPierre Ossman 2006000bc9d5SLee Jones /* Must have platform data or Device Tree. */ 2007000bc9d5SLee Jones if (!plat && !np) { 2008000bc9d5SLee Jones dev_err(&dev->dev, "No plat data or DT found\n"); 2009000bc9d5SLee Jones return -EINVAL; 20101c6a0718SPierre Ossman } 20111c6a0718SPierre Ossman 2012b9b52918SLee Jones if (!plat) { 2013b9b52918SLee Jones plat = devm_kzalloc(&dev->dev, sizeof(*plat), GFP_KERNEL); 2014b9b52918SLee Jones if (!plat) 2015b9b52918SLee Jones return -ENOMEM; 2016b9b52918SLee Jones } 2017b9b52918SLee Jones 20181c6a0718SPierre Ossman mmc = mmc_alloc_host(sizeof(struct mmci_host), &dev->dev); 2019ef289982SUlf Hansson if (!mmc) 2020ef289982SUlf Hansson return -ENOMEM; 20211c6a0718SPierre Ossman 20221c6a0718SPierre Ossman host = mmc_priv(mmc); 20234ea580f1SRabin Vincent host->mmc = mmc; 20247b9716a0SLudovic Barre host->mmc_ops = &mmci_ops; 20257b9716a0SLudovic Barre mmc->ops = &mmci_ops; 2026012b7d33SRussell King 20276351cac9SMarek Vasut ret = mmci_of_parse(np, mmc); 20286351cac9SMarek Vasut if (ret) 20296351cac9SMarek Vasut goto host_free; 20306351cac9SMarek Vasut 2031f9bb304cSPatrice Chotard /* 2032f9bb304cSPatrice Chotard * Some variant (STM32) doesn't have opendrain bit, nevertheless 2033f9bb304cSPatrice Chotard * pins can be set accordingly using pinctrl 2034f9bb304cSPatrice Chotard */ 2035f9bb304cSPatrice Chotard if (!variant->opendrain) { 2036f9bb304cSPatrice Chotard host->pinctrl = devm_pinctrl_get(&dev->dev); 2037f9bb304cSPatrice Chotard if (IS_ERR(host->pinctrl)) { 2038f9bb304cSPatrice Chotard dev_err(&dev->dev, "failed to get pinctrl"); 2039310eb252SWei Yongjun ret = PTR_ERR(host->pinctrl); 2040f9bb304cSPatrice Chotard goto host_free; 2041f9bb304cSPatrice Chotard } 2042f9bb304cSPatrice Chotard 2043f9bb304cSPatrice Chotard host->pins_opendrain = pinctrl_lookup_state(host->pinctrl, 2044f9bb304cSPatrice Chotard MMCI_PINCTRL_STATE_OPENDRAIN); 2045f9bb304cSPatrice Chotard if (IS_ERR(host->pins_opendrain)) { 2046f9bb304cSPatrice Chotard dev_err(mmc_dev(mmc), "Can't select opendrain pins\n"); 2047310eb252SWei Yongjun ret = PTR_ERR(host->pins_opendrain); 2048f9bb304cSPatrice Chotard goto host_free; 2049f9bb304cSPatrice Chotard } 2050f9bb304cSPatrice Chotard } 2051f9bb304cSPatrice Chotard 2052012b7d33SRussell King host->hw_designer = amba_manf(dev); 2053012b7d33SRussell King host->hw_revision = amba_rev(dev); 205464de0289SLinus Walleij dev_dbg(mmc_dev(mmc), "designer ID = 0x%02x\n", host->hw_designer); 205564de0289SLinus Walleij dev_dbg(mmc_dev(mmc), "revision = 0x%01x\n", host->hw_revision); 2056012b7d33SRussell King 2057665ba56fSUlf Hansson host->clk = devm_clk_get(&dev->dev, NULL); 20581c6a0718SPierre Ossman if (IS_ERR(host->clk)) { 20591c6a0718SPierre Ossman ret = PTR_ERR(host->clk); 20601c6a0718SPierre Ossman goto host_free; 20611c6a0718SPierre Ossman } 20621c6a0718SPierre Ossman 2063ac940938SJulia Lawall ret = clk_prepare_enable(host->clk); 20641c6a0718SPierre Ossman if (ret) 2065665ba56fSUlf Hansson goto host_free; 20661c6a0718SPierre Ossman 20679c34b73dSSrinivas Kandagatla if (variant->qcom_fifo) 20689c34b73dSSrinivas Kandagatla host->get_rx_fifocnt = mmci_qcom_get_rx_fifocnt; 20699c34b73dSSrinivas Kandagatla else 20709c34b73dSSrinivas Kandagatla host->get_rx_fifocnt = mmci_get_rx_fifocnt; 20719c34b73dSSrinivas Kandagatla 20721c6a0718SPierre Ossman host->plat = plat; 20734956e109SRabin Vincent host->variant = variant; 20741c6a0718SPierre Ossman host->mclk = clk_get_rate(host->clk); 2075c8df9a53SLinus Walleij /* 2076c8df9a53SLinus Walleij * According to the spec, mclk is max 100 MHz, 2077c8df9a53SLinus Walleij * so we try to adjust the clock down to this, 2078c8df9a53SLinus Walleij * (if possible). 2079c8df9a53SLinus Walleij */ 2080dc6500bfSSrinivas Kandagatla if (host->mclk > variant->f_max) { 2081dc6500bfSSrinivas Kandagatla ret = clk_set_rate(host->clk, variant->f_max); 2082c8df9a53SLinus Walleij if (ret < 0) 2083c8df9a53SLinus Walleij goto clk_disable; 2084c8df9a53SLinus Walleij host->mclk = clk_get_rate(host->clk); 208564de0289SLinus Walleij dev_dbg(mmc_dev(mmc), "eventual mclk rate: %u Hz\n", 208664de0289SLinus Walleij host->mclk); 2087c8df9a53SLinus Walleij } 2088ef289982SUlf Hansson 2089c8ebae37SRussell King host->phybase = dev->res.start; 2090ef289982SUlf Hansson host->base = devm_ioremap_resource(&dev->dev, &dev->res); 2091ef289982SUlf Hansson if (IS_ERR(host->base)) { 2092ef289982SUlf Hansson ret = PTR_ERR(host->base); 20931c6a0718SPierre Ossman goto clk_disable; 20941c6a0718SPierre Ossman } 20951c6a0718SPierre Ossman 2096ed9067fdSUlf Hansson if (variant->init) 2097ed9067fdSUlf Hansson variant->init(host); 2098ed9067fdSUlf Hansson 20997f294e49SLinus Walleij /* 21007f294e49SLinus Walleij * The ARM and ST versions of the block have slightly different 21017f294e49SLinus Walleij * clock divider equations which means that the minimum divider 21027f294e49SLinus Walleij * differs too. 21033f4e6f7bSSrinivas Kandagatla * on Qualcomm like controllers get the nearest minimum clock to 100Khz 21047f294e49SLinus Walleij */ 21057f294e49SLinus Walleij if (variant->st_clkdiv) 21067f294e49SLinus Walleij mmc->f_min = DIV_ROUND_UP(host->mclk, 257); 210700e930d8SLudovic Barre else if (variant->stm32_clkdiv) 210800e930d8SLudovic Barre mmc->f_min = DIV_ROUND_UP(host->mclk, 2046); 21093f4e6f7bSSrinivas Kandagatla else if (variant->explicit_mclk_control) 21103f4e6f7bSSrinivas Kandagatla mmc->f_min = clk_round_rate(host->clk, 100000); 21117f294e49SLinus Walleij else 21127f294e49SLinus Walleij mmc->f_min = DIV_ROUND_UP(host->mclk, 512); 2113808d97ccSLinus Walleij /* 211478f87df2SUlf Hansson * If no maximum operating frequency is supplied, fall back to use 211578f87df2SUlf Hansson * the module parameter, which has a (low) default value in case it 211678f87df2SUlf Hansson * is not specified. Either value must not exceed the clock rate into 21175080a08dSUlf Hansson * the block, of course. 2118808d97ccSLinus Walleij */ 211978f87df2SUlf Hansson if (mmc->f_max) 21203f4e6f7bSSrinivas Kandagatla mmc->f_max = variant->explicit_mclk_control ? 21213f4e6f7bSSrinivas Kandagatla min(variant->f_max, mmc->f_max) : 21223f4e6f7bSSrinivas Kandagatla min(host->mclk, mmc->f_max); 2123808d97ccSLinus Walleij else 21243f4e6f7bSSrinivas Kandagatla mmc->f_max = variant->explicit_mclk_control ? 21253f4e6f7bSSrinivas Kandagatla fmax : min(host->mclk, fmax); 21263f4e6f7bSSrinivas Kandagatla 21273f4e6f7bSSrinivas Kandagatla 212864de0289SLinus Walleij dev_dbg(mmc_dev(mmc), "clocking block at %u Hz\n", mmc->f_max); 212964de0289SLinus Walleij 213015878e58SLudovic Barre host->rst = devm_reset_control_get_optional_exclusive(&dev->dev, NULL); 213115878e58SLudovic Barre if (IS_ERR(host->rst)) { 213215878e58SLudovic Barre ret = PTR_ERR(host->rst); 213315878e58SLudovic Barre goto clk_disable; 213415878e58SLudovic Barre } 2135575cf104SLinus Walleij ret = reset_control_deassert(host->rst); 2136575cf104SLinus Walleij if (ret) 2137575cf104SLinus Walleij dev_err(mmc_dev(mmc), "failed to de-assert reset\n"); 213815878e58SLudovic Barre 2139599c1d5cSUlf Hansson /* Get regulators and the supported OCR mask */ 21409369c97cSBjorn Andersson ret = mmc_regulator_get_supply(mmc); 214151006952SWolfram Sang if (ret) 21429369c97cSBjorn Andersson goto clk_disable; 21439369c97cSBjorn Andersson 2144599c1d5cSUlf Hansson if (!mmc->ocr_avail) 21451c6a0718SPierre Ossman mmc->ocr_avail = plat->ocr_mask; 2146599c1d5cSUlf Hansson else if (plat->ocr_mask) 2147599c1d5cSUlf Hansson dev_warn(mmc_dev(mmc), "Platform OCR mask is ignored\n"); 2148599c1d5cSUlf Hansson 21499dd8a8b8SUlf Hansson /* We support these capabilities. */ 21509dd8a8b8SUlf Hansson mmc->caps |= MMC_CAP_CMD23; 21519dd8a8b8SUlf Hansson 215249adc0caSLinus Walleij /* 215349adc0caSLinus Walleij * Enable busy detection. 215449adc0caSLinus Walleij */ 21558d94b54dSUlf Hansson if (variant->busy_detect) { 21568d94b54dSUlf Hansson mmci_ops.card_busy = mmci_card_busy; 215749adc0caSLinus Walleij /* 215849adc0caSLinus Walleij * Not all variants have a flag to enable busy detection 215949adc0caSLinus Walleij * in the DPSM, but if they do, set it here. 216049adc0caSLinus Walleij */ 216149adc0caSLinus Walleij if (variant->busy_dpsm_flag) 216249adc0caSLinus Walleij mmci_write_datactrlreg(host, 216349adc0caSLinus Walleij host->variant->busy_dpsm_flag); 21648d94b54dSUlf Hansson mmc->caps |= MMC_CAP_WAIT_WHILE_BUSY; 21658d94b54dSUlf Hansson } 21668d94b54dSUlf Hansson 2167774514bfSYann Gautier /* Variants with mandatory busy timeout in HW needs R1B responses. */ 2168774514bfSYann Gautier if (variant->busy_timeout) 2169774514bfSYann Gautier mmc->caps |= MMC_CAP_NEED_RSP_BUSY; 2170774514bfSYann Gautier 2171e9968c6fSUlf Hansson /* Prepare a CMD12 - needed to clear the DPSM on some variants. */ 2172e9968c6fSUlf Hansson host->stop_abort.opcode = MMC_STOP_TRANSMISSION; 2173e9968c6fSUlf Hansson host->stop_abort.arg = 0; 2174e9968c6fSUlf Hansson host->stop_abort.flags = MMC_RSP_R1B | MMC_CMD_AC; 2175e9968c6fSUlf Hansson 217670be208fSUlf Hansson /* We support these PM capabilities. */ 217778f87df2SUlf Hansson mmc->pm_caps |= MMC_PM_KEEP_POWER; 217870be208fSUlf Hansson 21791c6a0718SPierre Ossman /* 21801c6a0718SPierre Ossman * We can do SGIO 21811c6a0718SPierre Ossman */ 2182a36274e0SMartin K. Petersen mmc->max_segs = NR_SG; 21831c6a0718SPierre Ossman 21841c6a0718SPierre Ossman /* 218508458ef6SRabin Vincent * Since only a certain number of bits are valid in the data length 218608458ef6SRabin Vincent * register, we must ensure that we don't exceed 2^num-1 bytes in a 218708458ef6SRabin Vincent * single request. 21881c6a0718SPierre Ossman */ 218908458ef6SRabin Vincent mmc->max_req_size = (1 << variant->datalength_bits) - 1; 21901c6a0718SPierre Ossman 21911c6a0718SPierre Ossman /* 21921c6a0718SPierre Ossman * Set the maximum segment size. Since we aren't doing DMA 21931c6a0718SPierre Ossman * (yet) we are only limited by the data length register. 21941c6a0718SPierre Ossman */ 21951c6a0718SPierre Ossman mmc->max_seg_size = mmc->max_req_size; 21961c6a0718SPierre Ossman 21971c6a0718SPierre Ossman /* 21981c6a0718SPierre Ossman * Block size can be up to 2048 bytes, but must be a power of two. 21991c6a0718SPierre Ossman */ 2200c931d495SLudovic Barre mmc->max_blk_size = 1 << variant->datactrl_blocksz; 22011c6a0718SPierre Ossman 22021c6a0718SPierre Ossman /* 22038f7f6b7eSWill Deacon * Limit the number of blocks transferred so that we don't overflow 22048f7f6b7eSWill Deacon * the maximum request size. 22051c6a0718SPierre Ossman */ 2206c931d495SLudovic Barre mmc->max_blk_count = mmc->max_req_size >> variant->datactrl_blocksz; 22071c6a0718SPierre Ossman 22081c6a0718SPierre Ossman spin_lock_init(&host->lock); 22091c6a0718SPierre Ossman 22101c6a0718SPierre Ossman writel(0, host->base + MMCIMASK0); 22116ea9cdf3SPatrice Chotard 22126ea9cdf3SPatrice Chotard if (variant->mmcimask1) 22131c6a0718SPierre Ossman writel(0, host->base + MMCIMASK1); 22146ea9cdf3SPatrice Chotard 22151c6a0718SPierre Ossman writel(0xfff, host->base + MMCICLEAR); 22161c6a0718SPierre Ossman 2217ce437aa4SLinus Walleij /* 2218ce437aa4SLinus Walleij * If: 2219ce437aa4SLinus Walleij * - not using DT but using a descriptor table, or 2220ce437aa4SLinus Walleij * - using a table of descriptors ALONGSIDE DT, or 2221ce437aa4SLinus Walleij * look up these descriptors named "cd" and "wp" right here, fail 22229ef986a6SLinus Walleij * silently of these do not exist 2223ce437aa4SLinus Walleij */ 2224ce437aa4SLinus Walleij if (!np) { 2225d0052ad9SMichał Mirosław ret = mmc_gpiod_request_cd(mmc, "cd", 0, false, 0); 2226ce437aa4SLinus Walleij if (ret == -EPROBE_DEFER) 2227ce437aa4SLinus Walleij goto clk_disable; 2228ce437aa4SLinus Walleij 2229d0052ad9SMichał Mirosław ret = mmc_gpiod_request_ro(mmc, "wp", 0, 0); 2230ce437aa4SLinus Walleij if (ret == -EPROBE_DEFER) 2231ce437aa4SLinus Walleij goto clk_disable; 2232ce437aa4SLinus Walleij } 223389001446SRussell King 2234ee157abeSLudovic Barre ret = devm_request_threaded_irq(&dev->dev, dev->irq[0], mmci_irq, 2235ee157abeSLudovic Barre mmci_irq_thread, IRQF_SHARED, 2236ef289982SUlf Hansson DRIVER_NAME " (cmd)", host); 22371c6a0718SPierre Ossman if (ret) 2238ef289982SUlf Hansson goto clk_disable; 22391c6a0718SPierre Ossman 2240dfb85185SRussell King if (!dev->irq[1]) 22412686b4b4SLinus Walleij host->singleirq = true; 22422686b4b4SLinus Walleij else { 2243ef289982SUlf Hansson ret = devm_request_irq(&dev->dev, dev->irq[1], mmci_pio_irq, 2244ef289982SUlf Hansson IRQF_SHARED, DRIVER_NAME " (pio)", host); 22451c6a0718SPierre Ossman if (ret) 2246ef289982SUlf Hansson goto clk_disable; 22472686b4b4SLinus Walleij } 22481c6a0718SPierre Ossman 2249daf9713cSLudovic Barre writel(MCI_IRQENABLE | variant->start_err, host->base + MMCIMASK0); 22501c6a0718SPierre Ossman 22511c6a0718SPierre Ossman amba_set_drvdata(dev, mmc); 22521c6a0718SPierre Ossman 2253c8ebae37SRussell King dev_info(&dev->dev, "%s: PL%03x manf %x rev%u at 0x%08llx irq %d,%d (pio)\n", 2254c8ebae37SRussell King mmc_hostname(mmc), amba_part(dev), amba_manf(dev), 2255c8ebae37SRussell King amba_rev(dev), (unsigned long long)dev->res.start, 2256c8ebae37SRussell King dev->irq[0], dev->irq[1]); 2257c8ebae37SRussell King 2258c8ebae37SRussell King mmci_dma_setup(host); 22591c6a0718SPierre Ossman 22602cd976c4SUlf Hansson pm_runtime_set_autosuspend_delay(&dev->dev, 50); 22612cd976c4SUlf Hansson pm_runtime_use_autosuspend(&dev->dev); 22621c3be369SRussell King 22638c11a94dSRussell King mmc_add_host(mmc); 22648c11a94dSRussell King 22656f2d3c89SUlf Hansson pm_runtime_put(&dev->dev); 22661c6a0718SPierre Ossman return 0; 22671c6a0718SPierre Ossman 22681c6a0718SPierre Ossman clk_disable: 2269ac940938SJulia Lawall clk_disable_unprepare(host->clk); 22701c6a0718SPierre Ossman host_free: 22711c6a0718SPierre Ossman mmc_free_host(mmc); 22721c6a0718SPierre Ossman return ret; 22731c6a0718SPierre Ossman } 22741c6a0718SPierre Ossman 22753fd269e7SUwe Kleine-König static void mmci_remove(struct amba_device *dev) 22761c6a0718SPierre Ossman { 22771c6a0718SPierre Ossman struct mmc_host *mmc = amba_get_drvdata(dev); 22781c6a0718SPierre Ossman 22791c6a0718SPierre Ossman if (mmc) { 22801c6a0718SPierre Ossman struct mmci_host *host = mmc_priv(mmc); 22816ea9cdf3SPatrice Chotard struct variant_data *variant = host->variant; 22821c6a0718SPierre Ossman 22831c3be369SRussell King /* 22841c3be369SRussell King * Undo pm_runtime_put() in probe. We use the _sync 22851c3be369SRussell King * version here so that we can access the primecell. 22861c3be369SRussell King */ 22871c3be369SRussell King pm_runtime_get_sync(&dev->dev); 22881c3be369SRussell King 22891c6a0718SPierre Ossman mmc_remove_host(mmc); 22901c6a0718SPierre Ossman 22911c6a0718SPierre Ossman writel(0, host->base + MMCIMASK0); 22926ea9cdf3SPatrice Chotard 22936ea9cdf3SPatrice Chotard if (variant->mmcimask1) 22941c6a0718SPierre Ossman writel(0, host->base + MMCIMASK1); 22951c6a0718SPierre Ossman 22961c6a0718SPierre Ossman writel(0, host->base + MMCICOMMAND); 22971c6a0718SPierre Ossman writel(0, host->base + MMCIDATACTRL); 22981c6a0718SPierre Ossman 2299c8ebae37SRussell King mmci_dma_release(host); 2300ac940938SJulia Lawall clk_disable_unprepare(host->clk); 23011c6a0718SPierre Ossman mmc_free_host(mmc); 23021c6a0718SPierre Ossman } 23031c6a0718SPierre Ossman } 23041c6a0718SPierre Ossman 2305571dce4fSUlf Hansson #ifdef CONFIG_PM 23061ff44433SUlf Hansson static void mmci_save(struct mmci_host *host) 23071ff44433SUlf Hansson { 23081ff44433SUlf Hansson unsigned long flags; 23091ff44433SUlf Hansson 23101ff44433SUlf Hansson spin_lock_irqsave(&host->lock, flags); 23111ff44433SUlf Hansson 23121ff44433SUlf Hansson writel(0, host->base + MMCIMASK0); 231342dcc89aSUlf Hansson if (host->variant->pwrreg_nopower) { 23141ff44433SUlf Hansson writel(0, host->base + MMCIDATACTRL); 23151ff44433SUlf Hansson writel(0, host->base + MMCIPOWER); 23161ff44433SUlf Hansson writel(0, host->base + MMCICLOCK); 231742dcc89aSUlf Hansson } 23181ff44433SUlf Hansson mmci_reg_delay(host); 23191ff44433SUlf Hansson 23201ff44433SUlf Hansson spin_unlock_irqrestore(&host->lock, flags); 23211ff44433SUlf Hansson } 23221ff44433SUlf Hansson 23231ff44433SUlf Hansson static void mmci_restore(struct mmci_host *host) 23241ff44433SUlf Hansson { 23251ff44433SUlf Hansson unsigned long flags; 23261ff44433SUlf Hansson 23271ff44433SUlf Hansson spin_lock_irqsave(&host->lock, flags); 23281ff44433SUlf Hansson 232942dcc89aSUlf Hansson if (host->variant->pwrreg_nopower) { 23301ff44433SUlf Hansson writel(host->clk_reg, host->base + MMCICLOCK); 23311ff44433SUlf Hansson writel(host->datactrl_reg, host->base + MMCIDATACTRL); 23321ff44433SUlf Hansson writel(host->pwr_reg, host->base + MMCIPOWER); 233342dcc89aSUlf Hansson } 2334daf9713cSLudovic Barre writel(MCI_IRQENABLE | host->variant->start_err, 2335daf9713cSLudovic Barre host->base + MMCIMASK0); 23361ff44433SUlf Hansson mmci_reg_delay(host); 23371ff44433SUlf Hansson 23381ff44433SUlf Hansson spin_unlock_irqrestore(&host->lock, flags); 23391ff44433SUlf Hansson } 23401ff44433SUlf Hansson 23418259293aSUlf Hansson static int mmci_runtime_suspend(struct device *dev) 23428259293aSUlf Hansson { 23438259293aSUlf Hansson struct amba_device *adev = to_amba_device(dev); 23448259293aSUlf Hansson struct mmc_host *mmc = amba_get_drvdata(adev); 23458259293aSUlf Hansson 23468259293aSUlf Hansson if (mmc) { 23478259293aSUlf Hansson struct mmci_host *host = mmc_priv(mmc); 2348e36bd9c6SUlf Hansson pinctrl_pm_select_sleep_state(dev); 23491ff44433SUlf Hansson mmci_save(host); 23508259293aSUlf Hansson clk_disable_unprepare(host->clk); 23518259293aSUlf Hansson } 23528259293aSUlf Hansson 23538259293aSUlf Hansson return 0; 23548259293aSUlf Hansson } 23558259293aSUlf Hansson 23568259293aSUlf Hansson static int mmci_runtime_resume(struct device *dev) 23578259293aSUlf Hansson { 23588259293aSUlf Hansson struct amba_device *adev = to_amba_device(dev); 23598259293aSUlf Hansson struct mmc_host *mmc = amba_get_drvdata(adev); 23608259293aSUlf Hansson 23618259293aSUlf Hansson if (mmc) { 23628259293aSUlf Hansson struct mmci_host *host = mmc_priv(mmc); 23638259293aSUlf Hansson clk_prepare_enable(host->clk); 23641ff44433SUlf Hansson mmci_restore(host); 236505344ffeSUlf Hansson pinctrl_select_default_state(dev); 23668259293aSUlf Hansson } 23678259293aSUlf Hansson 23688259293aSUlf Hansson return 0; 23698259293aSUlf Hansson } 23708259293aSUlf Hansson #endif 23718259293aSUlf Hansson 237248fa7003SUlf Hansson static const struct dev_pm_ops mmci_dev_pm_ops = { 2373f3737fa3SUlf Hansson SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, 2374f3737fa3SUlf Hansson pm_runtime_force_resume) 23756ed23b80SRafael J. Wysocki SET_RUNTIME_PM_OPS(mmci_runtime_suspend, mmci_runtime_resume, NULL) 237648fa7003SUlf Hansson }; 237748fa7003SUlf Hansson 237888411deaSArvind Yadav static const struct amba_id mmci_ids[] = { 23791c6a0718SPierre Ossman { 23801c6a0718SPierre Ossman .id = 0x00041180, 2381768fbc18SPawel Moll .mask = 0xff0fffff, 23824956e109SRabin Vincent .data = &variant_arm, 23831c6a0718SPierre Ossman }, 23841c6a0718SPierre Ossman { 2385768fbc18SPawel Moll .id = 0x01041180, 2386768fbc18SPawel Moll .mask = 0xff0fffff, 2387768fbc18SPawel Moll .data = &variant_arm_extended_fifo, 2388768fbc18SPawel Moll }, 2389768fbc18SPawel Moll { 23903a37298aSPawel Moll .id = 0x02041180, 23913a37298aSPawel Moll .mask = 0xff0fffff, 23923a37298aSPawel Moll .data = &variant_arm_extended_fifo_hwfc, 23933a37298aSPawel Moll }, 23943a37298aSPawel Moll { 23951c6a0718SPierre Ossman .id = 0x00041181, 23961c6a0718SPierre Ossman .mask = 0x000fffff, 23974956e109SRabin Vincent .data = &variant_arm, 23981c6a0718SPierre Ossman }, 2399cc30d60eSLinus Walleij /* ST Micro variants */ 2400cc30d60eSLinus Walleij { 2401cc30d60eSLinus Walleij .id = 0x00180180, 2402cc30d60eSLinus Walleij .mask = 0x00ffffff, 24034956e109SRabin Vincent .data = &variant_u300, 2404cc30d60eSLinus Walleij }, 2405cc30d60eSLinus Walleij { 240634fd4213SLinus Walleij .id = 0x10180180, 240734fd4213SLinus Walleij .mask = 0xf0ffffff, 240834fd4213SLinus Walleij .data = &variant_nomadik, 240934fd4213SLinus Walleij }, 241034fd4213SLinus Walleij { 2411cc30d60eSLinus Walleij .id = 0x00280180, 2412cc30d60eSLinus Walleij .mask = 0x00ffffff, 24130bcb7efdSLinus Walleij .data = &variant_nomadik, 24144956e109SRabin Vincent }, 24154956e109SRabin Vincent { 24164956e109SRabin Vincent .id = 0x00480180, 24171784b157SPhilippe Langlais .mask = 0xf0ffffff, 24184956e109SRabin Vincent .data = &variant_ux500, 2419cc30d60eSLinus Walleij }, 24201784b157SPhilippe Langlais { 24211784b157SPhilippe Langlais .id = 0x10480180, 24221784b157SPhilippe Langlais .mask = 0xf0ffffff, 24231784b157SPhilippe Langlais .data = &variant_ux500v2, 24241784b157SPhilippe Langlais }, 24252a9d6c80SPatrice Chotard { 24262a9d6c80SPatrice Chotard .id = 0x00880180, 24272a9d6c80SPatrice Chotard .mask = 0x00ffffff, 24282a9d6c80SPatrice Chotard .data = &variant_stm32, 24292a9d6c80SPatrice Chotard }, 243046b723ddSLudovic Barre { 243146b723ddSLudovic Barre .id = 0x10153180, 243246b723ddSLudovic Barre .mask = 0xf0ffffff, 243346b723ddSLudovic Barre .data = &variant_stm32_sdmmc, 243446b723ddSLudovic Barre }, 24357a2a98beSLudovic Barre { 24367a2a98beSLudovic Barre .id = 0x00253180, 24377a2a98beSLudovic Barre .mask = 0xf0ffffff, 24387a2a98beSLudovic Barre .data = &variant_stm32_sdmmcv2, 24397a2a98beSLudovic Barre }, 24405471fe8bSYann Gautier { 24415471fe8bSYann Gautier .id = 0x20253180, 24425471fe8bSYann Gautier .mask = 0xf0ffffff, 24435471fe8bSYann Gautier .data = &variant_stm32_sdmmcv2, 24445471fe8bSYann Gautier }, 244555b604aeSSrinivas Kandagatla /* Qualcomm variants */ 244655b604aeSSrinivas Kandagatla { 244755b604aeSSrinivas Kandagatla .id = 0x00051180, 244855b604aeSSrinivas Kandagatla .mask = 0x000fffff, 244955b604aeSSrinivas Kandagatla .data = &variant_qcom, 245055b604aeSSrinivas Kandagatla }, 24511c6a0718SPierre Ossman { 0, 0 }, 24521c6a0718SPierre Ossman }; 24531c6a0718SPierre Ossman 24549f99835fSDave Martin MODULE_DEVICE_TABLE(amba, mmci_ids); 24559f99835fSDave Martin 24561c6a0718SPierre Ossman static struct amba_driver mmci_driver = { 24571c6a0718SPierre Ossman .drv = { 24581c6a0718SPierre Ossman .name = DRIVER_NAME, 245948fa7003SUlf Hansson .pm = &mmci_dev_pm_ops, 24601c6a0718SPierre Ossman }, 24611c6a0718SPierre Ossman .probe = mmci_probe, 24620433c143SBill Pemberton .remove = mmci_remove, 24631c6a0718SPierre Ossman .id_table = mmci_ids, 24641c6a0718SPierre Ossman }; 24651c6a0718SPierre Ossman 24669e5ed094Sviresh kumar module_amba_driver(mmci_driver); 24671c6a0718SPierre Ossman 24681c6a0718SPierre Ossman module_param(fmax, uint, 0444); 24691c6a0718SPierre Ossman 24701c6a0718SPierre Ossman MODULE_DESCRIPTION("ARM PrimeCell PL180/181 Multimedia Card Interface driver"); 24711c6a0718SPierre Ossman MODULE_LICENSE("GPL"); 2472