11c6a0718SPierre Ossman /* 270f10482SPierre Ossman * linux/drivers/mmc/host/mmci.c - ARM PrimeCell MMCI PL180/1 driver 31c6a0718SPierre Ossman * 41c6a0718SPierre Ossman * Copyright (C) 2003 Deep Blue Solutions, Ltd, All Rights Reserved. 5c8ebae37SRussell King * Copyright (C) 2010 ST-Ericsson SA 61c6a0718SPierre Ossman * 71c6a0718SPierre Ossman * This program is free software; you can redistribute it and/or modify 81c6a0718SPierre Ossman * it under the terms of the GNU General Public License version 2 as 91c6a0718SPierre Ossman * published by the Free Software Foundation. 101c6a0718SPierre Ossman */ 111c6a0718SPierre Ossman #include <linux/module.h> 121c6a0718SPierre Ossman #include <linux/moduleparam.h> 131c6a0718SPierre Ossman #include <linux/init.h> 141c6a0718SPierre Ossman #include <linux/ioport.h> 151c6a0718SPierre Ossman #include <linux/device.h> 16ef289982SUlf Hansson #include <linux/io.h> 171c6a0718SPierre Ossman #include <linux/interrupt.h> 18613b152cSRussell King #include <linux/kernel.h> 19000bc9d5SLee Jones #include <linux/slab.h> 201c6a0718SPierre Ossman #include <linux/delay.h> 211c6a0718SPierre Ossman #include <linux/err.h> 221c6a0718SPierre Ossman #include <linux/highmem.h> 23019a5f56SNicolas Pitre #include <linux/log2.h> 24c8073e52SLudovic Barre #include <linux/mmc/mmc.h> 2570be208fSUlf Hansson #include <linux/mmc/pm.h> 261c6a0718SPierre Ossman #include <linux/mmc/host.h> 2734177802SLinus Walleij #include <linux/mmc/card.h> 28d2762090SUlf Hansson #include <linux/mmc/slot-gpio.h> 291c6a0718SPierre Ossman #include <linux/amba/bus.h> 301c6a0718SPierre Ossman #include <linux/clk.h> 31bd6dee6fSJens Axboe #include <linux/scatterlist.h> 329ef986a6SLinus Walleij #include <linux/of.h> 3334e84f39SLinus Walleij #include <linux/regulator/consumer.h> 34c8ebae37SRussell King #include <linux/dmaengine.h> 35c8ebae37SRussell King #include <linux/dma-mapping.h> 36c8ebae37SRussell King #include <linux/amba/mmci.h> 371c3be369SRussell King #include <linux/pm_runtime.h> 38258aea76SViresh Kumar #include <linux/types.h> 39a9a83785SLinus Walleij #include <linux/pinctrl/consumer.h> 4015878e58SLudovic Barre #include <linux/reset.h> 411c6a0718SPierre Ossman 421c6a0718SPierre Ossman #include <asm/div64.h> 431c6a0718SPierre Ossman #include <asm/io.h> 441c6a0718SPierre Ossman 451c6a0718SPierre Ossman #include "mmci.h" 461c6a0718SPierre Ossman 471c6a0718SPierre Ossman #define DRIVER_NAME "mmci-pl18x" 481c6a0718SPierre Ossman 4971953e0eSUlf Hansson static void mmci_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, 1745db3eee7SLinus Walleij .datactrl_mask_sdio = MCI_DPSM_ST_SDIOEN, 175c7354133SSrinivas Kandagatla .st_sdio = true, 176b70a67f9SLinus Walleij .st_clkdiv = true, 1777d72a1d4SUlf Hansson .pwrreg_powerup = MCI_PWR_ON, 178dc6500bfSSrinivas Kandagatla .f_max = 100000000, 1794d1a3a0dSUlf Hansson .signal_direction = true, 180f4670daeSUlf Hansson .pwrreg_clkgate = true, 18101259620SUlf Hansson .busy_detect = true, 18249adc0caSLinus Walleij .busy_dpsm_flag = MCI_DPSM_ST_BUSYMODE, 18349adc0caSLinus Walleij .busy_detect_flag = MCI_ST_CARDBUSY, 18449adc0caSLinus Walleij .busy_detect_mask = MCI_ST_BUSYENDMASK, 1851ff44433SUlf Hansson .pwrreg_nopower = true, 1866ea9cdf3SPatrice Chotard .mmcimask1 = true, 18759db5e2dSLudovic Barre .irq_pio_mask = MCI_IRQ_PIO_MASK, 1887f7b5503SPatrice Chotard .start_err = MCI_STARTBITERR, 18911dfb970SPatrice Chotard .opendrain = MCI_OD, 190c3647fdcSLudovic Barre .init = mmci_variant_init, 1914956e109SRabin Vincent }; 192b70a67f9SLinus Walleij 1931784b157SPhilippe Langlais static struct variant_data variant_ux500v2 = { 1941784b157SPhilippe Langlais .fifosize = 30 * 4, 1951784b157SPhilippe Langlais .fifohalfsize = 8 * 4, 1961784b157SPhilippe Langlais .clkreg = MCI_CLK_ENABLE, 1971784b157SPhilippe Langlais .clkreg_enable = MCI_ST_UX500_HWFCEN, 198e1412d85SSrinivas Kandagatla .clkreg_8bit_bus_enable = MCI_ST_8BIT_BUS, 199e8740644SSrinivas Kandagatla .clkreg_neg_edge_enable = MCI_ST_UX500_NEG_EDGE, 2000f244804SLudovic Barre .cmdreg_cpsm_enable = MCI_CPSM_ENABLE, 2010f244804SLudovic Barre .cmdreg_lrsp_crc = MCI_CPSM_RESPONSE | MCI_CPSM_LONGRSP, 2020f244804SLudovic Barre .cmdreg_srsp_crc = MCI_CPSM_RESPONSE, 2030f244804SLudovic Barre .cmdreg_srsp = MCI_CPSM_RESPONSE, 2045db3eee7SLinus Walleij .datactrl_mask_ddrmode = MCI_DPSM_ST_DDRMODE, 2051784b157SPhilippe Langlais .datalength_bits = 24, 206c931d495SLudovic Barre .datactrl_blocksz = 11, 2075db3eee7SLinus Walleij .datactrl_mask_sdio = MCI_DPSM_ST_SDIOEN, 208c7354133SSrinivas Kandagatla .st_sdio = true, 2091784b157SPhilippe Langlais .st_clkdiv = true, 2107d72a1d4SUlf Hansson .pwrreg_powerup = MCI_PWR_ON, 211dc6500bfSSrinivas Kandagatla .f_max = 100000000, 2124d1a3a0dSUlf Hansson .signal_direction = true, 213f4670daeSUlf Hansson .pwrreg_clkgate = true, 21401259620SUlf Hansson .busy_detect = true, 21549adc0caSLinus Walleij .busy_dpsm_flag = MCI_DPSM_ST_BUSYMODE, 21649adc0caSLinus Walleij .busy_detect_flag = MCI_ST_CARDBUSY, 21749adc0caSLinus Walleij .busy_detect_mask = MCI_ST_BUSYENDMASK, 2181ff44433SUlf Hansson .pwrreg_nopower = true, 2196ea9cdf3SPatrice Chotard .mmcimask1 = true, 22059db5e2dSLudovic Barre .irq_pio_mask = MCI_IRQ_PIO_MASK, 2217f7b5503SPatrice Chotard .start_err = MCI_STARTBITERR, 22211dfb970SPatrice Chotard .opendrain = MCI_OD, 223b3fb9d64SLudovic Barre .init = ux500v2_variant_init, 2241784b157SPhilippe Langlais }; 2251784b157SPhilippe Langlais 2262a9d6c80SPatrice Chotard static struct variant_data variant_stm32 = { 2272a9d6c80SPatrice Chotard .fifosize = 32 * 4, 2282a9d6c80SPatrice Chotard .fifohalfsize = 8 * 4, 2292a9d6c80SPatrice Chotard .clkreg = MCI_CLK_ENABLE, 2302a9d6c80SPatrice Chotard .clkreg_enable = MCI_ST_UX500_HWFCEN, 2312a9d6c80SPatrice Chotard .clkreg_8bit_bus_enable = MCI_ST_8BIT_BUS, 2322a9d6c80SPatrice Chotard .clkreg_neg_edge_enable = MCI_ST_UX500_NEG_EDGE, 2330f244804SLudovic Barre .cmdreg_cpsm_enable = MCI_CPSM_ENABLE, 2340f244804SLudovic Barre .cmdreg_lrsp_crc = MCI_CPSM_RESPONSE | MCI_CPSM_LONGRSP, 2350f244804SLudovic Barre .cmdreg_srsp_crc = MCI_CPSM_RESPONSE, 2360f244804SLudovic Barre .cmdreg_srsp = MCI_CPSM_RESPONSE, 23759db5e2dSLudovic Barre .irq_pio_mask = MCI_IRQ_PIO_MASK, 2382a9d6c80SPatrice Chotard .datalength_bits = 24, 239c931d495SLudovic Barre .datactrl_blocksz = 11, 2402a9d6c80SPatrice Chotard .datactrl_mask_sdio = MCI_DPSM_ST_SDIOEN, 2412a9d6c80SPatrice Chotard .st_sdio = true, 2422a9d6c80SPatrice Chotard .st_clkdiv = true, 2432a9d6c80SPatrice Chotard .pwrreg_powerup = MCI_PWR_ON, 2442a9d6c80SPatrice Chotard .f_max = 48000000, 2452a9d6c80SPatrice Chotard .pwrreg_clkgate = true, 2462a9d6c80SPatrice Chotard .pwrreg_nopower = true, 247c3647fdcSLudovic Barre .init = mmci_variant_init, 2482a9d6c80SPatrice Chotard }; 2492a9d6c80SPatrice Chotard 25046b723ddSLudovic Barre static struct variant_data variant_stm32_sdmmc = { 25146b723ddSLudovic Barre .fifosize = 16 * 4, 25246b723ddSLudovic Barre .fifohalfsize = 8 * 4, 25346b723ddSLudovic Barre .f_max = 208000000, 25446b723ddSLudovic Barre .stm32_clkdiv = true, 25546b723ddSLudovic Barre .cmdreg_cpsm_enable = MCI_CPSM_STM32_ENABLE, 25646b723ddSLudovic Barre .cmdreg_lrsp_crc = MCI_CPSM_STM32_LRSP_CRC, 25746b723ddSLudovic Barre .cmdreg_srsp_crc = MCI_CPSM_STM32_SRSP_CRC, 25846b723ddSLudovic Barre .cmdreg_srsp = MCI_CPSM_STM32_SRSP, 259c8073e52SLudovic Barre .cmdreg_stop = MCI_CPSM_STM32_CMDSTOP, 26046b723ddSLudovic Barre .data_cmd_enable = MCI_CPSM_STM32_CMDTRANS, 26146b723ddSLudovic Barre .irq_pio_mask = MCI_IRQ_PIO_STM32_MASK, 26246b723ddSLudovic Barre .datactrl_first = true, 26346b723ddSLudovic Barre .datacnt_useless = true, 26446b723ddSLudovic Barre .datalength_bits = 25, 26546b723ddSLudovic Barre .datactrl_blocksz = 14, 26646b723ddSLudovic Barre .stm32_idmabsize_mask = GENMASK(12, 5), 26746b723ddSLudovic Barre .init = sdmmc_variant_init, 26846b723ddSLudovic Barre }; 26946b723ddSLudovic Barre 27055b604aeSSrinivas Kandagatla static struct variant_data variant_qcom = { 27155b604aeSSrinivas Kandagatla .fifosize = 16 * 4, 27255b604aeSSrinivas Kandagatla .fifohalfsize = 8 * 4, 27355b604aeSSrinivas Kandagatla .clkreg = MCI_CLK_ENABLE, 27455b604aeSSrinivas Kandagatla .clkreg_enable = MCI_QCOM_CLK_FLOWENA | 27555b604aeSSrinivas Kandagatla MCI_QCOM_CLK_SELECT_IN_FBCLK, 27655b604aeSSrinivas Kandagatla .clkreg_8bit_bus_enable = MCI_QCOM_CLK_WIDEBUS_8, 27755b604aeSSrinivas Kandagatla .datactrl_mask_ddrmode = MCI_QCOM_CLK_SELECT_IN_DDR_MODE, 2780f244804SLudovic Barre .cmdreg_cpsm_enable = MCI_CPSM_ENABLE, 2790f244804SLudovic Barre .cmdreg_lrsp_crc = MCI_CPSM_RESPONSE | MCI_CPSM_LONGRSP, 2800f244804SLudovic Barre .cmdreg_srsp_crc = MCI_CPSM_RESPONSE, 2810f244804SLudovic Barre .cmdreg_srsp = MCI_CPSM_RESPONSE, 2825db3eee7SLinus Walleij .data_cmd_enable = MCI_CPSM_QCOM_DATCMD, 28355b604aeSSrinivas Kandagatla .datalength_bits = 24, 284c931d495SLudovic Barre .datactrl_blocksz = 11, 28555b604aeSSrinivas Kandagatla .pwrreg_powerup = MCI_PWR_UP, 28655b604aeSSrinivas Kandagatla .f_max = 208000000, 28755b604aeSSrinivas Kandagatla .explicit_mclk_control = true, 28855b604aeSSrinivas Kandagatla .qcom_fifo = true, 2899cb15142SSrinivas Kandagatla .qcom_dml = true, 2906ea9cdf3SPatrice Chotard .mmcimask1 = true, 29159db5e2dSLudovic Barre .irq_pio_mask = MCI_IRQ_PIO_MASK, 2927f7b5503SPatrice Chotard .start_err = MCI_STARTBITERR, 29311dfb970SPatrice Chotard .opendrain = MCI_ROD, 29429aba07aSUlf Hansson .init = qcom_variant_init, 29555b604aeSSrinivas Kandagatla }; 29655b604aeSSrinivas Kandagatla 29749adc0caSLinus Walleij /* Busy detection for the ST Micro variant */ 29801259620SUlf Hansson static int mmci_card_busy(struct mmc_host *mmc) 29901259620SUlf Hansson { 30001259620SUlf Hansson struct mmci_host *host = mmc_priv(mmc); 30101259620SUlf Hansson unsigned long flags; 30201259620SUlf Hansson int busy = 0; 30301259620SUlf Hansson 30401259620SUlf Hansson spin_lock_irqsave(&host->lock, flags); 30549adc0caSLinus Walleij if (readl(host->base + MMCISTATUS) & host->variant->busy_detect_flag) 30601259620SUlf Hansson busy = 1; 30701259620SUlf Hansson spin_unlock_irqrestore(&host->lock, flags); 30801259620SUlf Hansson 30901259620SUlf Hansson return busy; 31001259620SUlf Hansson } 31101259620SUlf Hansson 312f829c042SUlf Hansson static void mmci_reg_delay(struct mmci_host *host) 313f829c042SUlf Hansson { 314f829c042SUlf Hansson /* 315f829c042SUlf Hansson * According to the spec, at least three feedback clock cycles 316f829c042SUlf Hansson * of max 52 MHz must pass between two writes to the MMCICLOCK reg. 317f829c042SUlf Hansson * Three MCLK clock cycles must pass between two MMCIPOWER reg writes. 318f829c042SUlf Hansson * Worst delay time during card init is at 100 kHz => 30 us. 319f829c042SUlf Hansson * Worst delay time when up and running is at 25 MHz => 120 ns. 320f829c042SUlf Hansson */ 321f829c042SUlf Hansson if (host->cclk < 25000000) 322f829c042SUlf Hansson udelay(30); 323f829c042SUlf Hansson else 324f829c042SUlf Hansson ndelay(120); 325f829c042SUlf Hansson } 326f829c042SUlf Hansson 327653a761eSUlf Hansson /* 328a6a6464aSLinus Walleij * This must be called with host->lock held 329a6a6464aSLinus Walleij */ 330cd3ee8c5SLudovic Barre void mmci_write_clkreg(struct mmci_host *host, u32 clk) 3317437cfa5SUlf Hansson { 3327437cfa5SUlf Hansson if (host->clk_reg != clk) { 3337437cfa5SUlf Hansson host->clk_reg = clk; 3347437cfa5SUlf Hansson writel(clk, host->base + MMCICLOCK); 3357437cfa5SUlf Hansson } 3367437cfa5SUlf Hansson } 3377437cfa5SUlf Hansson 3387437cfa5SUlf Hansson /* 3397437cfa5SUlf Hansson * This must be called with host->lock held 3407437cfa5SUlf Hansson */ 341cd3ee8c5SLudovic Barre void mmci_write_pwrreg(struct mmci_host *host, u32 pwr) 3427437cfa5SUlf Hansson { 3437437cfa5SUlf Hansson if (host->pwr_reg != pwr) { 3447437cfa5SUlf Hansson host->pwr_reg = pwr; 3457437cfa5SUlf Hansson writel(pwr, host->base + MMCIPOWER); 3467437cfa5SUlf Hansson } 3477437cfa5SUlf Hansson } 3487437cfa5SUlf Hansson 3497437cfa5SUlf Hansson /* 3507437cfa5SUlf Hansson * This must be called with host->lock held 3517437cfa5SUlf Hansson */ 3529cc639a2SUlf Hansson static void mmci_write_datactrlreg(struct mmci_host *host, u32 datactrl) 3539cc639a2SUlf Hansson { 35449adc0caSLinus Walleij /* Keep busy mode in DPSM if enabled */ 35549adc0caSLinus Walleij datactrl |= host->datactrl_reg & host->variant->busy_dpsm_flag; 35601259620SUlf Hansson 3579cc639a2SUlf Hansson if (host->datactrl_reg != datactrl) { 3589cc639a2SUlf Hansson host->datactrl_reg = datactrl; 3599cc639a2SUlf Hansson writel(datactrl, host->base + MMCIDATACTRL); 3609cc639a2SUlf Hansson } 3619cc639a2SUlf Hansson } 3629cc639a2SUlf Hansson 3639cc639a2SUlf Hansson /* 3649cc639a2SUlf Hansson * This must be called with host->lock held 3659cc639a2SUlf Hansson */ 366a6a6464aSLinus Walleij static void mmci_set_clkreg(struct mmci_host *host, unsigned int desired) 367a6a6464aSLinus Walleij { 3684956e109SRabin Vincent struct variant_data *variant = host->variant; 3694956e109SRabin Vincent u32 clk = variant->clkreg; 370a6a6464aSLinus Walleij 371c58a8509SUlf Hansson /* Make sure cclk reflects the current calculated clock */ 372c58a8509SUlf Hansson host->cclk = 0; 373c58a8509SUlf Hansson 374a6a6464aSLinus Walleij if (desired) { 3753f4e6f7bSSrinivas Kandagatla if (variant->explicit_mclk_control) { 3763f4e6f7bSSrinivas Kandagatla host->cclk = host->mclk; 3773f4e6f7bSSrinivas Kandagatla } else if (desired >= host->mclk) { 378a6a6464aSLinus Walleij clk = MCI_CLK_BYPASS; 379399bc486SLinus Walleij if (variant->st_clkdiv) 380399bc486SLinus Walleij clk |= MCI_ST_UX500_NEG_EDGE; 381a6a6464aSLinus Walleij host->cclk = host->mclk; 382b70a67f9SLinus Walleij } else if (variant->st_clkdiv) { 383b70a67f9SLinus Walleij /* 384b70a67f9SLinus Walleij * DB8500 TRM says f = mclk / (clkdiv + 2) 385b70a67f9SLinus Walleij * => clkdiv = (mclk / f) - 2 386b70a67f9SLinus Walleij * Round the divider up so we don't exceed the max 387b70a67f9SLinus Walleij * frequency 388b70a67f9SLinus Walleij */ 389b70a67f9SLinus Walleij clk = DIV_ROUND_UP(host->mclk, desired) - 2; 390b70a67f9SLinus Walleij if (clk >= 256) 391b70a67f9SLinus Walleij clk = 255; 392b70a67f9SLinus Walleij host->cclk = host->mclk / (clk + 2); 393a6a6464aSLinus Walleij } else { 394b70a67f9SLinus Walleij /* 395b70a67f9SLinus Walleij * PL180 TRM says f = mclk / (2 * (clkdiv + 1)) 396b70a67f9SLinus Walleij * => clkdiv = mclk / (2 * f) - 1 397b70a67f9SLinus Walleij */ 398a6a6464aSLinus Walleij clk = host->mclk / (2 * desired) - 1; 399a6a6464aSLinus Walleij if (clk >= 256) 400a6a6464aSLinus Walleij clk = 255; 401a6a6464aSLinus Walleij host->cclk = host->mclk / (2 * (clk + 1)); 402a6a6464aSLinus Walleij } 4034380c14fSRabin Vincent 4044380c14fSRabin Vincent clk |= variant->clkreg_enable; 405a6a6464aSLinus Walleij clk |= MCI_CLK_ENABLE; 406a6a6464aSLinus Walleij /* This hasn't proven to be worthwhile */ 407a6a6464aSLinus Walleij /* clk |= MCI_CLK_PWRSAVE; */ 408a6a6464aSLinus Walleij } 409a6a6464aSLinus Walleij 410c58a8509SUlf Hansson /* Set actual clock for debug */ 411c58a8509SUlf Hansson host->mmc->actual_clock = host->cclk; 412c58a8509SUlf Hansson 4139e6c82cdSLinus Walleij if (host->mmc->ios.bus_width == MMC_BUS_WIDTH_4) 414771dc157SLinus Walleij clk |= MCI_4BIT_BUS; 415771dc157SLinus Walleij if (host->mmc->ios.bus_width == MMC_BUS_WIDTH_8) 416e1412d85SSrinivas Kandagatla clk |= variant->clkreg_8bit_bus_enable; 4179e6c82cdSLinus Walleij 4186dad6c95SSeungwon Jeon if (host->mmc->ios.timing == MMC_TIMING_UHS_DDR50 || 4196dad6c95SSeungwon Jeon host->mmc->ios.timing == MMC_TIMING_MMC_DDR52) 420e8740644SSrinivas Kandagatla clk |= variant->clkreg_neg_edge_enable; 4216dbb6ee0SUlf Hansson 4227437cfa5SUlf Hansson mmci_write_clkreg(host, clk); 423a6a6464aSLinus Walleij } 424a6a6464aSLinus Walleij 425c3647fdcSLudovic Barre void mmci_dma_release(struct mmci_host *host) 426c3647fdcSLudovic Barre { 427c3647fdcSLudovic Barre if (host->ops && host->ops->dma_release) 428c3647fdcSLudovic Barre host->ops->dma_release(host); 429c3647fdcSLudovic Barre 430c3647fdcSLudovic Barre host->use_dma = false; 431c3647fdcSLudovic Barre } 432c3647fdcSLudovic Barre 433c3647fdcSLudovic Barre void mmci_dma_setup(struct mmci_host *host) 434c3647fdcSLudovic Barre { 435c3647fdcSLudovic Barre if (!host->ops || !host->ops->dma_setup) 436c3647fdcSLudovic Barre return; 437c3647fdcSLudovic Barre 438c3647fdcSLudovic Barre if (host->ops->dma_setup(host)) 439c3647fdcSLudovic Barre return; 440c3647fdcSLudovic Barre 441a813f2a2SLudovic Barre /* initialize pre request cookie */ 442a813f2a2SLudovic Barre host->next_cookie = 1; 443a813f2a2SLudovic Barre 444c3647fdcSLudovic Barre host->use_dma = true; 445c3647fdcSLudovic Barre } 446c3647fdcSLudovic Barre 447e0da1721SLudovic Barre /* 448e0da1721SLudovic Barre * Validate mmc prerequisites 449e0da1721SLudovic Barre */ 450e0da1721SLudovic Barre static int mmci_validate_data(struct mmci_host *host, 451e0da1721SLudovic Barre struct mmc_data *data) 452e0da1721SLudovic Barre { 453e0da1721SLudovic Barre if (!data) 454e0da1721SLudovic Barre return 0; 455e0da1721SLudovic Barre 456e0da1721SLudovic Barre if (!is_power_of_2(data->blksz)) { 457e0da1721SLudovic Barre dev_err(mmc_dev(host->mmc), 458e0da1721SLudovic Barre "unsupported block size (%d bytes)\n", data->blksz); 459e0da1721SLudovic Barre return -EINVAL; 460e0da1721SLudovic Barre } 461e0da1721SLudovic Barre 462e0da1721SLudovic Barre if (host->ops && host->ops->validate_data) 463e0da1721SLudovic Barre return host->ops->validate_data(host, data); 464e0da1721SLudovic Barre 465e0da1721SLudovic Barre return 0; 466e0da1721SLudovic Barre } 467e0da1721SLudovic Barre 46847983510SLudovic Barre int mmci_prep_data(struct mmci_host *host, struct mmc_data *data, bool next) 46947983510SLudovic Barre { 47047983510SLudovic Barre int err; 47147983510SLudovic Barre 47247983510SLudovic Barre if (!host->ops || !host->ops->prep_data) 47347983510SLudovic Barre return 0; 47447983510SLudovic Barre 47547983510SLudovic Barre err = host->ops->prep_data(host, data, next); 47647983510SLudovic Barre 47747983510SLudovic Barre if (next && !err) 47847983510SLudovic Barre data->host_cookie = ++host->next_cookie < 0 ? 47947983510SLudovic Barre 1 : host->next_cookie; 48047983510SLudovic Barre 48147983510SLudovic Barre return err; 48247983510SLudovic Barre } 48347983510SLudovic Barre 48447983510SLudovic Barre void mmci_unprep_data(struct mmci_host *host, struct mmc_data *data, 48547983510SLudovic Barre int err) 48647983510SLudovic Barre { 48747983510SLudovic Barre if (host->ops && host->ops->unprep_data) 48847983510SLudovic Barre host->ops->unprep_data(host, data, err); 48947983510SLudovic Barre 49047983510SLudovic Barre data->host_cookie = 0; 49147983510SLudovic Barre } 49247983510SLudovic Barre 49302769968SLudovic Barre void mmci_get_next_data(struct mmci_host *host, struct mmc_data *data) 49402769968SLudovic Barre { 49502769968SLudovic Barre WARN_ON(data->host_cookie && data->host_cookie != host->next_cookie); 49602769968SLudovic Barre 49702769968SLudovic Barre if (host->ops && host->ops->get_next_data) 49802769968SLudovic Barre host->ops->get_next_data(host, data); 49902769968SLudovic Barre } 50002769968SLudovic Barre 501135ea30eSLudovic Barre int mmci_dma_start(struct mmci_host *host, unsigned int datactrl) 502135ea30eSLudovic Barre { 503135ea30eSLudovic Barre struct mmc_data *data = host->data; 504135ea30eSLudovic Barre int ret; 505135ea30eSLudovic Barre 506135ea30eSLudovic Barre if (!host->use_dma) 507135ea30eSLudovic Barre return -EINVAL; 508135ea30eSLudovic Barre 509135ea30eSLudovic Barre ret = mmci_prep_data(host, data, false); 510135ea30eSLudovic Barre if (ret) 511135ea30eSLudovic Barre return ret; 512135ea30eSLudovic Barre 513135ea30eSLudovic Barre if (!host->ops || !host->ops->dma_start) 514135ea30eSLudovic Barre return -EINVAL; 515135ea30eSLudovic Barre 516135ea30eSLudovic Barre /* Okay, go for it. */ 517135ea30eSLudovic Barre dev_vdbg(mmc_dev(host->mmc), 518135ea30eSLudovic Barre "Submit MMCI DMA job, sglen %d blksz %04x blks %04x flags %08x\n", 519135ea30eSLudovic Barre data->sg_len, data->blksz, data->blocks, data->flags); 520135ea30eSLudovic Barre 521135ea30eSLudovic Barre host->ops->dma_start(host, &datactrl); 522135ea30eSLudovic Barre 523135ea30eSLudovic Barre /* Trigger the DMA transfer */ 524135ea30eSLudovic Barre mmci_write_datactrlreg(host, datactrl); 525135ea30eSLudovic Barre 526135ea30eSLudovic Barre /* 527135ea30eSLudovic Barre * Let the MMCI say when the data is ended and it's time 528135ea30eSLudovic Barre * to fire next DMA request. When that happens, MMCI will 529135ea30eSLudovic Barre * call mmci_data_end() 530135ea30eSLudovic Barre */ 531135ea30eSLudovic Barre writel(readl(host->base + MMCIMASK0) | MCI_DATAENDMASK, 532135ea30eSLudovic Barre host->base + MMCIMASK0); 533135ea30eSLudovic Barre return 0; 534135ea30eSLudovic Barre } 535135ea30eSLudovic Barre 5365a9f10c3SLudovic Barre void mmci_dma_finalize(struct mmci_host *host, struct mmc_data *data) 5375a9f10c3SLudovic Barre { 5385a9f10c3SLudovic Barre if (!host->use_dma) 5395a9f10c3SLudovic Barre return; 5405a9f10c3SLudovic Barre 5415a9f10c3SLudovic Barre if (host->ops && host->ops->dma_finalize) 5425a9f10c3SLudovic Barre host->ops->dma_finalize(host, data); 5435a9f10c3SLudovic Barre } 5445a9f10c3SLudovic Barre 545cfccc6acSLudovic Barre void mmci_dma_error(struct mmci_host *host) 546cfccc6acSLudovic Barre { 547cfccc6acSLudovic Barre if (!host->use_dma) 548cfccc6acSLudovic Barre return; 549cfccc6acSLudovic Barre 550cfccc6acSLudovic Barre if (host->ops && host->ops->dma_error) 551cfccc6acSLudovic Barre host->ops->dma_error(host); 552cfccc6acSLudovic Barre } 553cfccc6acSLudovic Barre 5541c6a0718SPierre Ossman static void 5551c6a0718SPierre Ossman mmci_request_end(struct mmci_host *host, struct mmc_request *mrq) 5561c6a0718SPierre Ossman { 5571c6a0718SPierre Ossman writel(0, host->base + MMCICOMMAND); 5581c6a0718SPierre Ossman 5591c6a0718SPierre Ossman BUG_ON(host->data); 5601c6a0718SPierre Ossman 5611c6a0718SPierre Ossman host->mrq = NULL; 5621c6a0718SPierre Ossman host->cmd = NULL; 5631c6a0718SPierre Ossman 5641c6a0718SPierre Ossman mmc_request_done(host->mmc, mrq); 5651c6a0718SPierre Ossman } 5661c6a0718SPierre Ossman 5672686b4b4SLinus Walleij static void mmci_set_mask1(struct mmci_host *host, unsigned int mask) 5682686b4b4SLinus Walleij { 5692686b4b4SLinus Walleij void __iomem *base = host->base; 5706ea9cdf3SPatrice Chotard struct variant_data *variant = host->variant; 5712686b4b4SLinus Walleij 5722686b4b4SLinus Walleij if (host->singleirq) { 5732686b4b4SLinus Walleij unsigned int mask0 = readl(base + MMCIMASK0); 5742686b4b4SLinus Walleij 57559db5e2dSLudovic Barre mask0 &= ~variant->irq_pio_mask; 5762686b4b4SLinus Walleij mask0 |= mask; 5772686b4b4SLinus Walleij 5782686b4b4SLinus Walleij writel(mask0, base + MMCIMASK0); 5792686b4b4SLinus Walleij } 5802686b4b4SLinus Walleij 5816ea9cdf3SPatrice Chotard if (variant->mmcimask1) 5822686b4b4SLinus Walleij writel(mask, base + MMCIMASK1); 5836ea9cdf3SPatrice Chotard 5846ea9cdf3SPatrice Chotard host->mask1_reg = mask; 5852686b4b4SLinus Walleij } 5862686b4b4SLinus Walleij 5871c6a0718SPierre Ossman static void mmci_stop_data(struct mmci_host *host) 5881c6a0718SPierre Ossman { 5899cc639a2SUlf Hansson mmci_write_datactrlreg(host, 0); 5902686b4b4SLinus Walleij mmci_set_mask1(host, 0); 5911c6a0718SPierre Ossman host->data = NULL; 5921c6a0718SPierre Ossman } 5931c6a0718SPierre Ossman 5944ce1d6cbSRabin Vincent static void mmci_init_sg(struct mmci_host *host, struct mmc_data *data) 5954ce1d6cbSRabin Vincent { 5964ce1d6cbSRabin Vincent unsigned int flags = SG_MITER_ATOMIC; 5974ce1d6cbSRabin Vincent 5984ce1d6cbSRabin Vincent if (data->flags & MMC_DATA_READ) 5994ce1d6cbSRabin Vincent flags |= SG_MITER_TO_SG; 6004ce1d6cbSRabin Vincent else 6014ce1d6cbSRabin Vincent flags |= SG_MITER_FROM_SG; 6024ce1d6cbSRabin Vincent 6034ce1d6cbSRabin Vincent sg_miter_start(&host->sg_miter, data->sg, data->sg_len, flags); 6044ce1d6cbSRabin Vincent } 6054ce1d6cbSRabin Vincent 606b3fb9d64SLudovic Barre static u32 mmci_get_dctrl_cfg(struct mmci_host *host) 607b3fb9d64SLudovic Barre { 608b3fb9d64SLudovic Barre return MCI_DPSM_ENABLE | mmci_dctrl_blksz(host); 609b3fb9d64SLudovic Barre } 610b3fb9d64SLudovic Barre 611b3fb9d64SLudovic Barre static u32 ux500v2_get_dctrl_cfg(struct mmci_host *host) 612b3fb9d64SLudovic Barre { 613b3fb9d64SLudovic Barre return MCI_DPSM_ENABLE | (host->data->blksz << 16); 614b3fb9d64SLudovic Barre } 615b3fb9d64SLudovic Barre 616c8ebae37SRussell King /* 617c8ebae37SRussell King * All the DMA operation mode stuff goes inside this ifdef. 618c8ebae37SRussell King * This assumes that you have a generic DMA device interface, 619c8ebae37SRussell King * no custom DMA interfaces are supported. 620c8ebae37SRussell King */ 621c8ebae37SRussell King #ifdef CONFIG_DMA_ENGINE 622a813f2a2SLudovic Barre struct mmci_dmae_next { 623a813f2a2SLudovic Barre struct dma_async_tx_descriptor *desc; 624a813f2a2SLudovic Barre struct dma_chan *chan; 625a813f2a2SLudovic Barre }; 626a813f2a2SLudovic Barre 627a813f2a2SLudovic Barre struct mmci_dmae_priv { 628a813f2a2SLudovic Barre struct dma_chan *cur; 629a813f2a2SLudovic Barre struct dma_chan *rx_channel; 630a813f2a2SLudovic Barre struct dma_chan *tx_channel; 631a813f2a2SLudovic Barre struct dma_async_tx_descriptor *desc_current; 632a813f2a2SLudovic Barre struct mmci_dmae_next next_data; 633a813f2a2SLudovic Barre }; 634a813f2a2SLudovic Barre 635c3647fdcSLudovic Barre int mmci_dmae_setup(struct mmci_host *host) 636c8ebae37SRussell King { 637c8ebae37SRussell King const char *rxname, *txname; 638a813f2a2SLudovic Barre struct mmci_dmae_priv *dmae; 639c8ebae37SRussell King 640a813f2a2SLudovic Barre dmae = devm_kzalloc(mmc_dev(host->mmc), sizeof(*dmae), GFP_KERNEL); 641a813f2a2SLudovic Barre if (!dmae) 642a813f2a2SLudovic Barre return -ENOMEM; 643c8ebae37SRussell King 644a813f2a2SLudovic Barre host->dma_priv = dmae; 645a813f2a2SLudovic Barre 646a813f2a2SLudovic Barre dmae->rx_channel = dma_request_slave_channel(mmc_dev(host->mmc), 647a813f2a2SLudovic Barre "rx"); 648a813f2a2SLudovic Barre dmae->tx_channel = dma_request_slave_channel(mmc_dev(host->mmc), 649a813f2a2SLudovic Barre "tx"); 65058c7ccbfSPer Forlin 6511fd83f0eSLee Jones /* 6521fd83f0eSLee Jones * If only an RX channel is specified, the driver will 6531fd83f0eSLee Jones * attempt to use it bidirectionally, however if it is 6541fd83f0eSLee Jones * is specified but cannot be located, DMA will be disabled. 6551fd83f0eSLee Jones */ 656a813f2a2SLudovic Barre if (dmae->rx_channel && !dmae->tx_channel) 657a813f2a2SLudovic Barre dmae->tx_channel = dmae->rx_channel; 658c8ebae37SRussell King 659a813f2a2SLudovic Barre if (dmae->rx_channel) 660a813f2a2SLudovic Barre rxname = dma_chan_name(dmae->rx_channel); 661c8ebae37SRussell King else 662c8ebae37SRussell King rxname = "none"; 663c8ebae37SRussell King 664a813f2a2SLudovic Barre if (dmae->tx_channel) 665a813f2a2SLudovic Barre txname = dma_chan_name(dmae->tx_channel); 666c8ebae37SRussell King else 667c8ebae37SRussell King txname = "none"; 668c8ebae37SRussell King 669c8ebae37SRussell King dev_info(mmc_dev(host->mmc), "DMA channels RX %s, TX %s\n", 670c8ebae37SRussell King rxname, txname); 671c8ebae37SRussell King 672c8ebae37SRussell King /* 673c8ebae37SRussell King * Limit the maximum segment size in any SG entry according to 674c8ebae37SRussell King * the parameters of the DMA engine device. 675c8ebae37SRussell King */ 676a813f2a2SLudovic Barre if (dmae->tx_channel) { 677a813f2a2SLudovic Barre struct device *dev = dmae->tx_channel->device->dev; 678c8ebae37SRussell King unsigned int max_seg_size = dma_get_max_seg_size(dev); 679c8ebae37SRussell King 680c8ebae37SRussell King if (max_seg_size < host->mmc->max_seg_size) 681c8ebae37SRussell King host->mmc->max_seg_size = max_seg_size; 682c8ebae37SRussell King } 683a813f2a2SLudovic Barre if (dmae->rx_channel) { 684a813f2a2SLudovic Barre struct device *dev = dmae->rx_channel->device->dev; 685c8ebae37SRussell King unsigned int max_seg_size = dma_get_max_seg_size(dev); 686c8ebae37SRussell King 687c8ebae37SRussell King if (max_seg_size < host->mmc->max_seg_size) 688c8ebae37SRussell King host->mmc->max_seg_size = max_seg_size; 689c8ebae37SRussell King } 6909cb15142SSrinivas Kandagatla 691a813f2a2SLudovic Barre if (!dmae->tx_channel || !dmae->rx_channel) { 692c3647fdcSLudovic Barre mmci_dmae_release(host); 693c3647fdcSLudovic Barre return -EINVAL; 694c3647fdcSLudovic Barre } 695c3647fdcSLudovic Barre 696c3647fdcSLudovic Barre return 0; 697c8ebae37SRussell King } 698c8ebae37SRussell King 699c8ebae37SRussell King /* 7006e0ee714SBill Pemberton * This is used in or so inline it 701c8ebae37SRussell King * so it can be discarded. 702c8ebae37SRussell King */ 703c3647fdcSLudovic Barre void mmci_dmae_release(struct mmci_host *host) 704c8ebae37SRussell King { 705a813f2a2SLudovic Barre struct mmci_dmae_priv *dmae = host->dma_priv; 706a813f2a2SLudovic Barre 707a813f2a2SLudovic Barre if (dmae->rx_channel) 708a813f2a2SLudovic Barre dma_release_channel(dmae->rx_channel); 709a813f2a2SLudovic Barre if (dmae->tx_channel) 710a813f2a2SLudovic Barre dma_release_channel(dmae->tx_channel); 711a813f2a2SLudovic Barre dmae->rx_channel = dmae->tx_channel = NULL; 712c8ebae37SRussell King } 713c8ebae37SRussell King 714c8ebae37SRussell King static void mmci_dma_unmap(struct mmci_host *host, struct mmc_data *data) 715c8ebae37SRussell King { 716a813f2a2SLudovic Barre struct mmci_dmae_priv *dmae = host->dma_priv; 717653a761eSUlf Hansson struct dma_chan *chan; 718653a761eSUlf Hansson 719feeef096SHeiner Kallweit if (data->flags & MMC_DATA_READ) 720a813f2a2SLudovic Barre chan = dmae->rx_channel; 721feeef096SHeiner Kallweit else 722a813f2a2SLudovic Barre chan = dmae->tx_channel; 723653a761eSUlf Hansson 724feeef096SHeiner Kallweit dma_unmap_sg(chan->device->dev, data->sg, data->sg_len, 725feeef096SHeiner Kallweit mmc_get_dma_dir(data)); 726653a761eSUlf Hansson } 727653a761eSUlf Hansson 728cfccc6acSLudovic Barre void mmci_dmae_error(struct mmci_host *host) 7297b2a6d51SLudovic Barre { 730a813f2a2SLudovic Barre struct mmci_dmae_priv *dmae = host->dma_priv; 731a813f2a2SLudovic Barre 732cfccc6acSLudovic Barre if (!dma_inprogress(host)) 733cdea1947SLudovic Barre return; 734cdea1947SLudovic Barre 7357b2a6d51SLudovic Barre dev_err(mmc_dev(host->mmc), "error during DMA transfer!\n"); 736a813f2a2SLudovic Barre dmaengine_terminate_all(dmae->cur); 7377b2a6d51SLudovic Barre host->dma_in_progress = false; 738a813f2a2SLudovic Barre dmae->cur = NULL; 739a813f2a2SLudovic Barre dmae->desc_current = NULL; 7407b2a6d51SLudovic Barre host->data->host_cookie = 0; 7417b2a6d51SLudovic Barre 7427b2a6d51SLudovic Barre mmci_dma_unmap(host, host->data); 7437b2a6d51SLudovic Barre } 7447b2a6d51SLudovic Barre 7455a9f10c3SLudovic Barre void mmci_dmae_finalize(struct mmci_host *host, struct mmc_data *data) 746653a761eSUlf Hansson { 747a813f2a2SLudovic Barre struct mmci_dmae_priv *dmae = host->dma_priv; 748c8ebae37SRussell King u32 status; 749c8ebae37SRussell King int i; 750c8ebae37SRussell King 7515a9f10c3SLudovic Barre if (!dma_inprogress(host)) 752cdea1947SLudovic Barre return; 753cdea1947SLudovic Barre 754c8ebae37SRussell King /* Wait up to 1ms for the DMA to complete */ 755c8ebae37SRussell King for (i = 0; ; i++) { 756c8ebae37SRussell King status = readl(host->base + MMCISTATUS); 757c8ebae37SRussell King if (!(status & MCI_RXDATAAVLBLMASK) || i >= 100) 758c8ebae37SRussell King break; 759c8ebae37SRussell King udelay(10); 760c8ebae37SRussell King } 761c8ebae37SRussell King 762c8ebae37SRussell King /* 763c8ebae37SRussell King * Check to see whether we still have some data left in the FIFO - 764c8ebae37SRussell King * this catches DMA controllers which are unable to monitor the 765c8ebae37SRussell King * DMALBREQ and DMALSREQ signals while allowing us to DMA to non- 766c8ebae37SRussell King * contiguous buffers. On TX, we'll get a FIFO underrun error. 767c8ebae37SRussell King */ 768c8ebae37SRussell King if (status & MCI_RXDATAAVLBLMASK) { 769cfccc6acSLudovic Barre mmci_dma_error(host); 770c8ebae37SRussell King if (!data->error) 771c8ebae37SRussell King data->error = -EIO; 7727b2a6d51SLudovic Barre } else if (!data->host_cookie) { 773653a761eSUlf Hansson mmci_dma_unmap(host, data); 7747b2a6d51SLudovic Barre } 775c8ebae37SRussell King 776c8ebae37SRussell King /* 777c8ebae37SRussell King * Use of DMA with scatter-gather is impossible. 778c8ebae37SRussell King * Give up with DMA and switch back to PIO mode. 779c8ebae37SRussell King */ 780c8ebae37SRussell King if (status & MCI_RXDATAAVLBLMASK) { 781c8ebae37SRussell King dev_err(mmc_dev(host->mmc), "buggy DMA detected. Taking evasive action.\n"); 782c8ebae37SRussell King mmci_dma_release(host); 783c8ebae37SRussell King } 784653a761eSUlf Hansson 785e13934bdSLinus Walleij host->dma_in_progress = false; 786a813f2a2SLudovic Barre dmae->cur = NULL; 787a813f2a2SLudovic Barre dmae->desc_current = NULL; 788c8ebae37SRussell King } 789c8ebae37SRussell King 790653a761eSUlf Hansson /* prepares DMA channel and DMA descriptor, returns non-zero on failure */ 79147983510SLudovic Barre static int _mmci_dmae_prep_data(struct mmci_host *host, struct mmc_data *data, 792653a761eSUlf Hansson struct dma_chan **dma_chan, 793653a761eSUlf Hansson struct dma_async_tx_descriptor **dma_desc) 794c8ebae37SRussell King { 795a813f2a2SLudovic Barre struct mmci_dmae_priv *dmae = host->dma_priv; 796c8ebae37SRussell King struct variant_data *variant = host->variant; 797c8ebae37SRussell King struct dma_slave_config conf = { 798c8ebae37SRussell King .src_addr = host->phybase + MMCIFIFO, 799c8ebae37SRussell King .dst_addr = host->phybase + MMCIFIFO, 800c8ebae37SRussell King .src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES, 801c8ebae37SRussell King .dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES, 802c8ebae37SRussell King .src_maxburst = variant->fifohalfsize >> 2, /* # of words */ 803c8ebae37SRussell King .dst_maxburst = variant->fifohalfsize >> 2, /* # of words */ 804258aea76SViresh Kumar .device_fc = false, 805c8ebae37SRussell King }; 806c8ebae37SRussell King struct dma_chan *chan; 807c8ebae37SRussell King struct dma_device *device; 808c8ebae37SRussell King struct dma_async_tx_descriptor *desc; 809c8ebae37SRussell King int nr_sg; 8109cb15142SSrinivas Kandagatla unsigned long flags = DMA_CTRL_ACK; 811c8ebae37SRussell King 812c8ebae37SRussell King if (data->flags & MMC_DATA_READ) { 81305f5799cSVinod Koul conf.direction = DMA_DEV_TO_MEM; 814a813f2a2SLudovic Barre chan = dmae->rx_channel; 815c8ebae37SRussell King } else { 81605f5799cSVinod Koul conf.direction = DMA_MEM_TO_DEV; 817a813f2a2SLudovic Barre chan = dmae->tx_channel; 818c8ebae37SRussell King } 819c8ebae37SRussell King 820c8ebae37SRussell King /* If there's no DMA channel, fall back to PIO */ 821c8ebae37SRussell King if (!chan) 822c8ebae37SRussell King return -EINVAL; 823c8ebae37SRussell King 824c8ebae37SRussell King /* If less than or equal to the fifo size, don't bother with DMA */ 82558c7ccbfSPer Forlin if (data->blksz * data->blocks <= variant->fifosize) 826c8ebae37SRussell King return -EINVAL; 827c8ebae37SRussell King 828c8ebae37SRussell King device = chan->device; 829feeef096SHeiner Kallweit nr_sg = dma_map_sg(device->dev, data->sg, data->sg_len, 830feeef096SHeiner Kallweit mmc_get_dma_dir(data)); 831c8ebae37SRussell King if (nr_sg == 0) 832c8ebae37SRussell King return -EINVAL; 833c8ebae37SRussell King 8349cb15142SSrinivas Kandagatla if (host->variant->qcom_dml) 8359cb15142SSrinivas Kandagatla flags |= DMA_PREP_INTERRUPT; 8369cb15142SSrinivas Kandagatla 837c8ebae37SRussell King dmaengine_slave_config(chan, &conf); 83816052827SAlexandre Bounine desc = dmaengine_prep_slave_sg(chan, data->sg, nr_sg, 8399cb15142SSrinivas Kandagatla conf.direction, flags); 840c8ebae37SRussell King if (!desc) 841c8ebae37SRussell King goto unmap_exit; 842c8ebae37SRussell King 843653a761eSUlf Hansson *dma_chan = chan; 844653a761eSUlf Hansson *dma_desc = desc; 845c8ebae37SRussell King 84658c7ccbfSPer Forlin return 0; 84758c7ccbfSPer Forlin 84858c7ccbfSPer Forlin unmap_exit: 849feeef096SHeiner Kallweit dma_unmap_sg(device->dev, data->sg, data->sg_len, 850feeef096SHeiner Kallweit mmc_get_dma_dir(data)); 85158c7ccbfSPer Forlin return -ENOMEM; 85258c7ccbfSPer Forlin } 85358c7ccbfSPer Forlin 85447983510SLudovic Barre int mmci_dmae_prep_data(struct mmci_host *host, 855ad7b8918SLudovic Barre struct mmc_data *data, 856ad7b8918SLudovic Barre bool next) 857653a761eSUlf Hansson { 858a813f2a2SLudovic Barre struct mmci_dmae_priv *dmae = host->dma_priv; 859ad7b8918SLudovic Barre struct mmci_dmae_next *nd = &dmae->next_data; 860a813f2a2SLudovic Barre 86147983510SLudovic Barre if (!host->use_dma) 86247983510SLudovic Barre return -EINVAL; 86347983510SLudovic Barre 864ad7b8918SLudovic Barre if (next) 86547983510SLudovic Barre return _mmci_dmae_prep_data(host, data, &nd->chan, &nd->desc); 866653a761eSUlf Hansson /* Check if next job is already prepared. */ 867a813f2a2SLudovic Barre if (dmae->cur && dmae->desc_current) 868653a761eSUlf Hansson return 0; 869653a761eSUlf Hansson 870653a761eSUlf Hansson /* No job were prepared thus do it now. */ 87147983510SLudovic Barre return _mmci_dmae_prep_data(host, data, &dmae->cur, 872a813f2a2SLudovic Barre &dmae->desc_current); 873653a761eSUlf Hansson } 874653a761eSUlf Hansson 875135ea30eSLudovic Barre int mmci_dmae_start(struct mmci_host *host, unsigned int *datactrl) 87658c7ccbfSPer Forlin { 877a813f2a2SLudovic Barre struct mmci_dmae_priv *dmae = host->dma_priv; 87858c7ccbfSPer Forlin 879e13934bdSLinus Walleij host->dma_in_progress = true; 880a813f2a2SLudovic Barre dmaengine_submit(dmae->desc_current); 881a813f2a2SLudovic Barre dma_async_issue_pending(dmae->cur); 882c8ebae37SRussell King 883135ea30eSLudovic Barre *datactrl |= MCI_DPSM_DMAENABLE; 884c8ebae37SRussell King 885c8ebae37SRussell King return 0; 886c8ebae37SRussell King } 88758c7ccbfSPer Forlin 88802769968SLudovic Barre void mmci_dmae_get_next_data(struct mmci_host *host, struct mmc_data *data) 88958c7ccbfSPer Forlin { 890a813f2a2SLudovic Barre struct mmci_dmae_priv *dmae = host->dma_priv; 891a813f2a2SLudovic Barre struct mmci_dmae_next *next = &dmae->next_data; 89258c7ccbfSPer Forlin 893c3647fdcSLudovic Barre if (!host->use_dma) 894c3647fdcSLudovic Barre return; 895c3647fdcSLudovic Barre 896a813f2a2SLudovic Barre WARN_ON(!data->host_cookie && (next->desc || next->chan)); 89758c7ccbfSPer Forlin 898a813f2a2SLudovic Barre dmae->desc_current = next->desc; 899a813f2a2SLudovic Barre dmae->cur = next->chan; 900a813f2a2SLudovic Barre next->desc = NULL; 901a813f2a2SLudovic Barre next->chan = NULL; 90258c7ccbfSPer Forlin } 90358c7ccbfSPer Forlin 90447983510SLudovic Barre void mmci_dmae_unprep_data(struct mmci_host *host, 90547983510SLudovic Barre struct mmc_data *data, int err) 90647983510SLudovic Barre 90758c7ccbfSPer Forlin { 908a813f2a2SLudovic Barre struct mmci_dmae_priv *dmae = host->dma_priv; 90958c7ccbfSPer Forlin 91047983510SLudovic Barre if (!host->use_dma) 91158c7ccbfSPer Forlin return; 91258c7ccbfSPer Forlin 913653a761eSUlf Hansson mmci_dma_unmap(host, data); 914653a761eSUlf Hansson 915653a761eSUlf Hansson if (err) { 916a813f2a2SLudovic Barre struct mmci_dmae_next *next = &dmae->next_data; 917653a761eSUlf Hansson struct dma_chan *chan; 918653a761eSUlf Hansson if (data->flags & MMC_DATA_READ) 919a813f2a2SLudovic Barre chan = dmae->rx_channel; 920653a761eSUlf Hansson else 921a813f2a2SLudovic Barre chan = dmae->tx_channel; 92258c7ccbfSPer Forlin dmaengine_terminate_all(chan); 923653a761eSUlf Hansson 924a813f2a2SLudovic Barre if (dmae->desc_current == next->desc) 925a813f2a2SLudovic Barre dmae->desc_current = NULL; 926b5c16a60SSrinivas Kandagatla 927a813f2a2SLudovic Barre if (dmae->cur == next->chan) { 928e13934bdSLinus Walleij host->dma_in_progress = false; 929a813f2a2SLudovic Barre dmae->cur = NULL; 930e13934bdSLinus Walleij } 931b5c16a60SSrinivas Kandagatla 932a813f2a2SLudovic Barre next->desc = NULL; 933a813f2a2SLudovic Barre next->chan = NULL; 93458c7ccbfSPer Forlin } 93558c7ccbfSPer Forlin } 93658c7ccbfSPer Forlin 937c3647fdcSLudovic Barre static struct mmci_host_ops mmci_variant_ops = { 93847983510SLudovic Barre .prep_data = mmci_dmae_prep_data, 93947983510SLudovic Barre .unprep_data = mmci_dmae_unprep_data, 940b3fb9d64SLudovic Barre .get_datactrl_cfg = mmci_get_dctrl_cfg, 94102769968SLudovic Barre .get_next_data = mmci_dmae_get_next_data, 942c3647fdcSLudovic Barre .dma_setup = mmci_dmae_setup, 943c3647fdcSLudovic Barre .dma_release = mmci_dmae_release, 944135ea30eSLudovic Barre .dma_start = mmci_dmae_start, 9455a9f10c3SLudovic Barre .dma_finalize = mmci_dmae_finalize, 946cfccc6acSLudovic Barre .dma_error = mmci_dmae_error, 947c3647fdcSLudovic Barre }; 948b3fb9d64SLudovic Barre #else 949b3fb9d64SLudovic Barre static struct mmci_host_ops mmci_variant_ops = { 950b3fb9d64SLudovic Barre .get_datactrl_cfg = mmci_get_dctrl_cfg, 951b3fb9d64SLudovic Barre }; 952b3fb9d64SLudovic Barre #endif 953c3647fdcSLudovic Barre 954c3647fdcSLudovic Barre void mmci_variant_init(struct mmci_host *host) 955c3647fdcSLudovic Barre { 956c3647fdcSLudovic Barre host->ops = &mmci_variant_ops; 957c3647fdcSLudovic Barre } 958b3fb9d64SLudovic Barre 959b3fb9d64SLudovic Barre void ux500v2_variant_init(struct mmci_host *host) 960b3fb9d64SLudovic Barre { 961b3fb9d64SLudovic Barre host->ops = &mmci_variant_ops; 962b3fb9d64SLudovic Barre host->ops->get_datactrl_cfg = ux500v2_get_dctrl_cfg; 963b3fb9d64SLudovic Barre } 964c8ebae37SRussell King 96547983510SLudovic Barre static void mmci_pre_request(struct mmc_host *mmc, struct mmc_request *mrq) 96647983510SLudovic Barre { 96747983510SLudovic Barre struct mmci_host *host = mmc_priv(mmc); 96847983510SLudovic Barre struct mmc_data *data = mrq->data; 96947983510SLudovic Barre 97047983510SLudovic Barre if (!data) 97147983510SLudovic Barre return; 97247983510SLudovic Barre 97347983510SLudovic Barre WARN_ON(data->host_cookie); 97447983510SLudovic Barre 97547983510SLudovic Barre if (mmci_validate_data(host, data)) 97647983510SLudovic Barre return; 97747983510SLudovic Barre 97847983510SLudovic Barre mmci_prep_data(host, data, true); 97947983510SLudovic Barre } 98047983510SLudovic Barre 98147983510SLudovic Barre static void mmci_post_request(struct mmc_host *mmc, struct mmc_request *mrq, 98247983510SLudovic Barre int err) 98347983510SLudovic Barre { 98447983510SLudovic Barre struct mmci_host *host = mmc_priv(mmc); 98547983510SLudovic Barre struct mmc_data *data = mrq->data; 98647983510SLudovic Barre 98747983510SLudovic Barre if (!data || !data->host_cookie) 98847983510SLudovic Barre return; 98947983510SLudovic Barre 99047983510SLudovic Barre mmci_unprep_data(host, data, err); 99147983510SLudovic Barre } 99247983510SLudovic Barre 9931c6a0718SPierre Ossman static void mmci_start_data(struct mmci_host *host, struct mmc_data *data) 9941c6a0718SPierre Ossman { 9958301bb68SRabin Vincent struct variant_data *variant = host->variant; 9961c6a0718SPierre Ossman unsigned int datactrl, timeout, irqmask; 9971c6a0718SPierre Ossman unsigned long long clks; 9981c6a0718SPierre Ossman void __iomem *base; 9991c6a0718SPierre Ossman 100064de0289SLinus Walleij dev_dbg(mmc_dev(host->mmc), "blksz %04x blks %04x flags %08x\n", 10011c6a0718SPierre Ossman data->blksz, data->blocks, data->flags); 10021c6a0718SPierre Ossman 10031c6a0718SPierre Ossman host->data = data; 1004528320dbSRabin Vincent host->size = data->blksz * data->blocks; 100551d4375dSRussell King data->bytes_xfered = 0; 10061c6a0718SPierre Ossman 10071c6a0718SPierre Ossman clks = (unsigned long long)data->timeout_ns * host->cclk; 1008c4a35769SSrinivas Kandagatla do_div(clks, NSEC_PER_SEC); 10091c6a0718SPierre Ossman 10101c6a0718SPierre Ossman timeout = data->timeout_clks + (unsigned int)clks; 10111c6a0718SPierre Ossman 10121c6a0718SPierre Ossman base = host->base; 10131c6a0718SPierre Ossman writel(timeout, base + MMCIDATATIMER); 10141c6a0718SPierre Ossman writel(host->size, base + MMCIDATALENGTH); 10151c6a0718SPierre Ossman 101641ed65e7SLudovic Barre datactrl = host->ops->get_datactrl_cfg(host); 101741ed65e7SLudovic Barre datactrl |= host->data->flags & MMC_DATA_READ ? MCI_DPSM_DIRECTION : 0; 1018c8ebae37SRussell King 1019c7354133SSrinivas Kandagatla if (host->mmc->card && mmc_card_sdio(host->mmc->card)) { 102006c1a121SUlf Hansson u32 clk; 1021c7354133SSrinivas Kandagatla 10225df014dfSSrinivas Kandagatla datactrl |= variant->datactrl_mask_sdio; 10237258db7eSUlf Hansson 1024c8ebae37SRussell King /* 102570ac0935SUlf Hansson * The ST Micro variant for SDIO small write transfers 102670ac0935SUlf Hansson * needs to have clock H/W flow control disabled, 102770ac0935SUlf Hansson * otherwise the transfer will not start. The threshold 102870ac0935SUlf Hansson * depends on the rate of MCLK. 102906c1a121SUlf Hansson */ 1030c7354133SSrinivas Kandagatla if (variant->st_sdio && data->flags & MMC_DATA_WRITE && 103170ac0935SUlf Hansson (host->size < 8 || 103270ac0935SUlf Hansson (host->size <= 8 && host->mclk > 50000000))) 103306c1a121SUlf Hansson clk = host->clk_reg & ~variant->clkreg_enable; 103406c1a121SUlf Hansson else 103506c1a121SUlf Hansson clk = host->clk_reg | variant->clkreg_enable; 103606c1a121SUlf Hansson 103706c1a121SUlf Hansson mmci_write_clkreg(host, clk); 103806c1a121SUlf Hansson } 103906c1a121SUlf Hansson 10406dad6c95SSeungwon Jeon if (host->mmc->ios.timing == MMC_TIMING_UHS_DDR50 || 10416dad6c95SSeungwon Jeon host->mmc->ios.timing == MMC_TIMING_MMC_DDR52) 1042e17dca2bSSrinivas Kandagatla datactrl |= variant->datactrl_mask_ddrmode; 10436dbb6ee0SUlf Hansson 104406c1a121SUlf Hansson /* 1045c8ebae37SRussell King * Attempt to use DMA operation mode, if this 1046c8ebae37SRussell King * should fail, fall back to PIO mode 1047c8ebae37SRussell King */ 1048135ea30eSLudovic Barre if (!mmci_dma_start(host, datactrl)) 1049c8ebae37SRussell King return; 1050c8ebae37SRussell King 1051c8ebae37SRussell King /* IRQ mode, map the SG list for CPU reading/writing */ 1052c8ebae37SRussell King mmci_init_sg(host, data); 1053c8ebae37SRussell King 1054c8ebae37SRussell King if (data->flags & MMC_DATA_READ) { 10551c6a0718SPierre Ossman irqmask = MCI_RXFIFOHALFFULLMASK; 10561c6a0718SPierre Ossman 10571c6a0718SPierre Ossman /* 1058c4d877c1SRussell King * If we have less than the fifo 'half-full' threshold to 1059c4d877c1SRussell King * transfer, trigger a PIO interrupt as soon as any data 1060c4d877c1SRussell King * is available. 10611c6a0718SPierre Ossman */ 1062c4d877c1SRussell King if (host->size < variant->fifohalfsize) 10631c6a0718SPierre Ossman irqmask |= MCI_RXDATAAVLBLMASK; 10641c6a0718SPierre Ossman } else { 10651c6a0718SPierre Ossman /* 10661c6a0718SPierre Ossman * We don't actually need to include "FIFO empty" here 10671c6a0718SPierre Ossman * since its implicit in "FIFO half empty". 10681c6a0718SPierre Ossman */ 10691c6a0718SPierre Ossman irqmask = MCI_TXFIFOHALFEMPTYMASK; 10701c6a0718SPierre Ossman } 10711c6a0718SPierre Ossman 10729cc639a2SUlf Hansson mmci_write_datactrlreg(host, datactrl); 10731c6a0718SPierre Ossman writel(readl(base + MMCIMASK0) & ~MCI_DATAENDMASK, base + MMCIMASK0); 10742686b4b4SLinus Walleij mmci_set_mask1(host, irqmask); 10751c6a0718SPierre Ossman } 10761c6a0718SPierre Ossman 10771c6a0718SPierre Ossman static void 10781c6a0718SPierre Ossman mmci_start_command(struct mmci_host *host, struct mmc_command *cmd, u32 c) 10791c6a0718SPierre Ossman { 10801c6a0718SPierre Ossman void __iomem *base = host->base; 10811c6a0718SPierre Ossman 108264de0289SLinus Walleij dev_dbg(mmc_dev(host->mmc), "op %02x arg %08x flags %08x\n", 10831c6a0718SPierre Ossman cmd->opcode, cmd->arg, cmd->flags); 10841c6a0718SPierre Ossman 10850f244804SLudovic Barre if (readl(base + MMCICOMMAND) & host->variant->cmdreg_cpsm_enable) { 10861c6a0718SPierre Ossman writel(0, base + MMCICOMMAND); 10876adb2a80SSrinivas Kandagatla mmci_reg_delay(host); 10881c6a0718SPierre Ossman } 10891c6a0718SPierre Ossman 1090c8073e52SLudovic Barre if (host->variant->cmdreg_stop && 1091c8073e52SLudovic Barre cmd->opcode == MMC_STOP_TRANSMISSION) 1092c8073e52SLudovic Barre c |= host->variant->cmdreg_stop; 1093c8073e52SLudovic Barre 10940f244804SLudovic Barre c |= cmd->opcode | host->variant->cmdreg_cpsm_enable; 10951c6a0718SPierre Ossman if (cmd->flags & MMC_RSP_PRESENT) { 10961c6a0718SPierre Ossman if (cmd->flags & MMC_RSP_136) 10970f244804SLudovic Barre c |= host->variant->cmdreg_lrsp_crc; 10980f244804SLudovic Barre else if (cmd->flags & MMC_RSP_CRC) 10990f244804SLudovic Barre c |= host->variant->cmdreg_srsp_crc; 11000f244804SLudovic Barre else 11010f244804SLudovic Barre c |= host->variant->cmdreg_srsp; 11021c6a0718SPierre Ossman } 11031c6a0718SPierre Ossman if (/*interrupt*/0) 11041c6a0718SPierre Ossman c |= MCI_CPSM_INTERRUPT; 11051c6a0718SPierre Ossman 1106ae7b0061SSrinivas Kandagatla if (mmc_cmd_type(cmd) == MMC_CMD_ADTC) 1107ae7b0061SSrinivas Kandagatla c |= host->variant->data_cmd_enable; 1108ae7b0061SSrinivas Kandagatla 11091c6a0718SPierre Ossman host->cmd = cmd; 11101c6a0718SPierre Ossman 11111c6a0718SPierre Ossman writel(cmd->arg, base + MMCIARGUMENT); 11121c6a0718SPierre Ossman writel(c, base + MMCICOMMAND); 11131c6a0718SPierre Ossman } 11141c6a0718SPierre Ossman 1115e9968c6fSUlf Hansson static void mmci_stop_command(struct mmci_host *host) 1116e9968c6fSUlf Hansson { 1117e9968c6fSUlf Hansson host->stop_abort.error = 0; 1118e9968c6fSUlf Hansson mmci_start_command(host, &host->stop_abort, 0); 1119e9968c6fSUlf Hansson } 1120e9968c6fSUlf Hansson 11211c6a0718SPierre Ossman static void 11221c6a0718SPierre Ossman mmci_data_irq(struct mmci_host *host, struct mmc_data *data, 11231c6a0718SPierre Ossman unsigned int status) 11241c6a0718SPierre Ossman { 1125daf9713cSLudovic Barre unsigned int status_err; 1126daf9713cSLudovic Barre 11271cb9da50SUlf Hansson /* Make sure we have data to handle */ 11281cb9da50SUlf Hansson if (!data) 11291cb9da50SUlf Hansson return; 11301cb9da50SUlf Hansson 1131f20f8f21SLinus Walleij /* First check for errors */ 1132daf9713cSLudovic Barre status_err = status & (host->variant->start_err | 1133daf9713cSLudovic Barre MCI_DATACRCFAIL | MCI_DATATIMEOUT | 1134daf9713cSLudovic Barre MCI_TXUNDERRUN | MCI_RXOVERRUN); 1135daf9713cSLudovic Barre 1136daf9713cSLudovic Barre if (status_err) { 11378cb28155SLinus Walleij u32 remain, success; 1138f20f8f21SLinus Walleij 1139c8ebae37SRussell King /* Terminate the DMA transfer */ 1140cfccc6acSLudovic Barre mmci_dma_error(host); 1141c8ebae37SRussell King 1142c8afc9d5SRussell King /* 1143c8afc9d5SRussell King * Calculate how far we are into the transfer. Note that 1144c8afc9d5SRussell King * the data counter gives the number of bytes transferred 1145c8afc9d5SRussell King * on the MMC bus, not on the host side. On reads, this 1146c8afc9d5SRussell King * can be as much as a FIFO-worth of data ahead. This 1147c8afc9d5SRussell King * matters for FIFO overruns only. 1148c8afc9d5SRussell King */ 1149b79220b3SLudovic Barre if (!host->variant->datacnt_useless) { 1150f5a106d9SLinus Walleij remain = readl(host->base + MMCIDATACNT); 11518cb28155SLinus Walleij success = data->blksz * data->blocks - remain; 1152b79220b3SLudovic Barre } else { 1153b79220b3SLudovic Barre success = 0; 1154b79220b3SLudovic Barre } 11558cb28155SLinus Walleij 1156c8afc9d5SRussell King dev_dbg(mmc_dev(host->mmc), "MCI ERROR IRQ, status 0x%08x at 0x%08x\n", 1157daf9713cSLudovic Barre status_err, success); 1158daf9713cSLudovic Barre if (status_err & MCI_DATACRCFAIL) { 11598cb28155SLinus Walleij /* Last block was not successful */ 1160c8afc9d5SRussell King success -= 1; 116117b0429dSPierre Ossman data->error = -EILSEQ; 1162daf9713cSLudovic Barre } else if (status_err & MCI_DATATIMEOUT) { 116317b0429dSPierre Ossman data->error = -ETIMEDOUT; 1164daf9713cSLudovic Barre } else if (status_err & MCI_STARTBITERR) { 1165757df746SLinus Walleij data->error = -ECOMM; 1166daf9713cSLudovic Barre } else if (status_err & MCI_TXUNDERRUN) { 116717b0429dSPierre Ossman data->error = -EIO; 1168daf9713cSLudovic Barre } else if (status_err & MCI_RXOVERRUN) { 1169c8afc9d5SRussell King if (success > host->variant->fifosize) 1170c8afc9d5SRussell King success -= host->variant->fifosize; 1171c8afc9d5SRussell King else 1172c8afc9d5SRussell King success = 0; 11738cb28155SLinus Walleij data->error = -EIO; 11744ce1d6cbSRabin Vincent } 117551d4375dSRussell King data->bytes_xfered = round_down(success, data->blksz); 11761c6a0718SPierre Ossman } 1177f20f8f21SLinus Walleij 11788cb28155SLinus Walleij if (status & MCI_DATABLOCKEND) 11798cb28155SLinus Walleij dev_err(mmc_dev(host->mmc), "stray MCI_DATABLOCKEND interrupt\n"); 1180f20f8f21SLinus Walleij 1181ccff9b51SRussell King if (status & MCI_DATAEND || data->error) { 1182653a761eSUlf Hansson mmci_dma_finalize(host, data); 1183cdea1947SLudovic Barre 11841c6a0718SPierre Ossman mmci_stop_data(host); 11851c6a0718SPierre Ossman 11868cb28155SLinus Walleij if (!data->error) 11878cb28155SLinus Walleij /* The error clause is handled above, success! */ 118851d4375dSRussell King data->bytes_xfered = data->blksz * data->blocks; 1189f20f8f21SLinus Walleij 1190e9968c6fSUlf Hansson if (!data->stop) { 1191e9968c6fSUlf Hansson if (host->variant->cmdreg_stop && data->error) 1192e9968c6fSUlf Hansson mmci_stop_command(host); 119309b4f706SLudovic Barre else 1194e9968c6fSUlf Hansson mmci_request_end(host, data->mrq); 1195e9968c6fSUlf Hansson } else if (host->mrq->sbc && !data->error) { 1196e9968c6fSUlf Hansson mmci_request_end(host, data->mrq); 1197e9968c6fSUlf Hansson } else { 11981c6a0718SPierre Ossman mmci_start_command(host, data->stop, 0); 11991c6a0718SPierre Ossman } 12001c6a0718SPierre Ossman } 1201e9968c6fSUlf Hansson } 12021c6a0718SPierre Ossman 12031c6a0718SPierre Ossman static void 12041c6a0718SPierre Ossman mmci_cmd_irq(struct mmci_host *host, struct mmc_command *cmd, 12051c6a0718SPierre Ossman unsigned int status) 12061c6a0718SPierre Ossman { 12071c6a0718SPierre Ossman void __iomem *base = host->base; 120849adc0caSLinus Walleij bool sbc; 1209ad82bfeaSUlf Hansson 1210ad82bfeaSUlf Hansson if (!cmd) 1211ad82bfeaSUlf Hansson return; 1212ad82bfeaSUlf Hansson 1213ad82bfeaSUlf Hansson sbc = (cmd == host->mrq->sbc); 1214ad82bfeaSUlf Hansson 121549adc0caSLinus Walleij /* 121649adc0caSLinus Walleij * We need to be one of these interrupts to be considered worth 121749adc0caSLinus Walleij * handling. Note that we tag on any latent IRQs postponed 121849adc0caSLinus Walleij * due to waiting for busy status. 121949adc0caSLinus Walleij */ 122049adc0caSLinus Walleij if (!((status|host->busy_status) & 122149adc0caSLinus Walleij (MCI_CMDCRCFAIL|MCI_CMDTIMEOUT|MCI_CMDSENT|MCI_CMDRESPEND))) 1222ad82bfeaSUlf Hansson return; 12238d94b54dSUlf Hansson 122449adc0caSLinus Walleij /* 122549adc0caSLinus Walleij * ST Micro variant: handle busy detection. 122649adc0caSLinus Walleij */ 122749adc0caSLinus Walleij if (host->variant->busy_detect) { 122849adc0caSLinus Walleij bool busy_resp = !!(cmd->flags & MMC_RSP_BUSY); 122949adc0caSLinus Walleij 123049adc0caSLinus Walleij /* We are busy with a command, return */ 123149adc0caSLinus Walleij if (host->busy_status && 123249adc0caSLinus Walleij (status & host->variant->busy_detect_flag)) 12338d94b54dSUlf Hansson return; 12348d94b54dSUlf Hansson 123549adc0caSLinus Walleij /* 123649adc0caSLinus Walleij * We were not busy, but we now got a busy response on 123749adc0caSLinus Walleij * something that was not an error, and we double-check 123849adc0caSLinus Walleij * that the special busy status bit is still set before 123949adc0caSLinus Walleij * proceeding. 124049adc0caSLinus Walleij */ 12418d94b54dSUlf Hansson if (!host->busy_status && busy_resp && 12428d94b54dSUlf Hansson !(status & (MCI_CMDCRCFAIL|MCI_CMDTIMEOUT)) && 124349adc0caSLinus Walleij (readl(base + MMCISTATUS) & host->variant->busy_detect_flag)) { 12445cad24d8SJean-Nicolas Graux 12455cad24d8SJean-Nicolas Graux /* Clear the busy start IRQ */ 12465cad24d8SJean-Nicolas Graux writel(host->variant->busy_detect_mask, 12475cad24d8SJean-Nicolas Graux host->base + MMCICLEAR); 12485cad24d8SJean-Nicolas Graux 12495cad24d8SJean-Nicolas Graux /* Unmask the busy end IRQ */ 125049adc0caSLinus Walleij writel(readl(base + MMCIMASK0) | 125149adc0caSLinus Walleij host->variant->busy_detect_mask, 12528d94b54dSUlf Hansson base + MMCIMASK0); 125349adc0caSLinus Walleij /* 125449adc0caSLinus Walleij * Now cache the last response status code (until 125549adc0caSLinus Walleij * the busy bit goes low), and return. 125649adc0caSLinus Walleij */ 125749adc0caSLinus Walleij host->busy_status = 125849adc0caSLinus Walleij status & (MCI_CMDSENT|MCI_CMDRESPEND); 12598d94b54dSUlf Hansson return; 12608d94b54dSUlf Hansson } 12618d94b54dSUlf Hansson 126249adc0caSLinus Walleij /* 126349adc0caSLinus Walleij * At this point we are not busy with a command, we have 12645cad24d8SJean-Nicolas Graux * not received a new busy request, clear and mask the busy 12655cad24d8SJean-Nicolas Graux * end IRQ and fall through to process the IRQ. 126649adc0caSLinus Walleij */ 12678d94b54dSUlf Hansson if (host->busy_status) { 12685cad24d8SJean-Nicolas Graux 12695cad24d8SJean-Nicolas Graux writel(host->variant->busy_detect_mask, 12705cad24d8SJean-Nicolas Graux host->base + MMCICLEAR); 12715cad24d8SJean-Nicolas Graux 127249adc0caSLinus Walleij writel(readl(base + MMCIMASK0) & 127349adc0caSLinus Walleij ~host->variant->busy_detect_mask, 12748d94b54dSUlf Hansson base + MMCIMASK0); 12758d94b54dSUlf Hansson host->busy_status = 0; 12768d94b54dSUlf Hansson } 127749adc0caSLinus Walleij } 12781c6a0718SPierre Ossman 12791c6a0718SPierre Ossman host->cmd = NULL; 12801c6a0718SPierre Ossman 12811c6a0718SPierre Ossman if (status & MCI_CMDTIMEOUT) { 128217b0429dSPierre Ossman cmd->error = -ETIMEDOUT; 12831c6a0718SPierre Ossman } else if (status & MCI_CMDCRCFAIL && cmd->flags & MMC_RSP_CRC) { 128417b0429dSPierre Ossman cmd->error = -EILSEQ; 12859047b435SRussell King - ARM Linux } else { 12869047b435SRussell King - ARM Linux cmd->resp[0] = readl(base + MMCIRESPONSE0); 12879047b435SRussell King - ARM Linux cmd->resp[1] = readl(base + MMCIRESPONSE1); 12889047b435SRussell King - ARM Linux cmd->resp[2] = readl(base + MMCIRESPONSE2); 12899047b435SRussell King - ARM Linux cmd->resp[3] = readl(base + MMCIRESPONSE3); 12901c6a0718SPierre Ossman } 12911c6a0718SPierre Ossman 1292024629c6SUlf Hansson if ((!sbc && !cmd->data) || cmd->error) { 12933b6e3c73SUlf Hansson if (host->data) { 12943b6e3c73SUlf Hansson /* Terminate the DMA transfer */ 1295cfccc6acSLudovic Barre mmci_dma_error(host); 12967b2a6d51SLudovic Barre 12971c6a0718SPierre Ossman mmci_stop_data(host); 1298e9968c6fSUlf Hansson if (host->variant->cmdreg_stop && cmd->error) { 1299e9968c6fSUlf Hansson mmci_stop_command(host); 1300e9968c6fSUlf Hansson return; 1301e9968c6fSUlf Hansson } 13023b6e3c73SUlf Hansson } 1303024629c6SUlf Hansson mmci_request_end(host, host->mrq); 1304024629c6SUlf Hansson } else if (sbc) { 1305024629c6SUlf Hansson mmci_start_command(host, host->mrq->cmd, 0); 1306d2141547SLudovic Barre } else if (!host->variant->datactrl_first && 1307d2141547SLudovic Barre !(cmd->data->flags & MMC_DATA_READ)) { 13081c6a0718SPierre Ossman mmci_start_data(host, cmd->data); 13091c6a0718SPierre Ossman } 13101c6a0718SPierre Ossman } 13111c6a0718SPierre Ossman 13129c34b73dSSrinivas Kandagatla static int mmci_get_rx_fifocnt(struct mmci_host *host, u32 status, int remain) 13139c34b73dSSrinivas Kandagatla { 13149c34b73dSSrinivas Kandagatla return remain - (readl(host->base + MMCIFIFOCNT) << 2); 13159c34b73dSSrinivas Kandagatla } 13169c34b73dSSrinivas Kandagatla 13179c34b73dSSrinivas Kandagatla static int mmci_qcom_get_rx_fifocnt(struct mmci_host *host, u32 status, int r) 13189c34b73dSSrinivas Kandagatla { 13199c34b73dSSrinivas Kandagatla /* 13209c34b73dSSrinivas Kandagatla * on qcom SDCC4 only 8 words are used in each burst so only 8 addresses 13219c34b73dSSrinivas Kandagatla * from the fifo range should be used 13229c34b73dSSrinivas Kandagatla */ 13239c34b73dSSrinivas Kandagatla if (status & MCI_RXFIFOHALFFULL) 13249c34b73dSSrinivas Kandagatla return host->variant->fifohalfsize; 13259c34b73dSSrinivas Kandagatla else if (status & MCI_RXDATAAVLBL) 13269c34b73dSSrinivas Kandagatla return 4; 13279c34b73dSSrinivas Kandagatla 13289c34b73dSSrinivas Kandagatla return 0; 13299c34b73dSSrinivas Kandagatla } 13309c34b73dSSrinivas Kandagatla 13311c6a0718SPierre Ossman static int mmci_pio_read(struct mmci_host *host, char *buffer, unsigned int remain) 13321c6a0718SPierre Ossman { 13331c6a0718SPierre Ossman void __iomem *base = host->base; 13341c6a0718SPierre Ossman char *ptr = buffer; 13359c34b73dSSrinivas Kandagatla u32 status = readl(host->base + MMCISTATUS); 133626eed9a5SLinus Walleij int host_remain = host->size; 13371c6a0718SPierre Ossman 13381c6a0718SPierre Ossman do { 13399c34b73dSSrinivas Kandagatla int count = host->get_rx_fifocnt(host, status, host_remain); 13401c6a0718SPierre Ossman 13411c6a0718SPierre Ossman if (count > remain) 13421c6a0718SPierre Ossman count = remain; 13431c6a0718SPierre Ossman 13441c6a0718SPierre Ossman if (count <= 0) 13451c6a0718SPierre Ossman break; 13461c6a0718SPierre Ossman 1347393e5e24SUlf Hansson /* 1348393e5e24SUlf Hansson * SDIO especially may want to send something that is 1349393e5e24SUlf Hansson * not divisible by 4 (as opposed to card sectors 1350393e5e24SUlf Hansson * etc). Therefore make sure to always read the last bytes 1351393e5e24SUlf Hansson * while only doing full 32-bit reads towards the FIFO. 1352393e5e24SUlf Hansson */ 1353393e5e24SUlf Hansson if (unlikely(count & 0x3)) { 1354393e5e24SUlf Hansson if (count < 4) { 1355393e5e24SUlf Hansson unsigned char buf[4]; 13564b85da08SDavide Ciminaghi ioread32_rep(base + MMCIFIFO, buf, 1); 1357393e5e24SUlf Hansson memcpy(ptr, buf, count); 1358393e5e24SUlf Hansson } else { 13594b85da08SDavide Ciminaghi ioread32_rep(base + MMCIFIFO, ptr, count >> 2); 1360393e5e24SUlf Hansson count &= ~0x3; 1361393e5e24SUlf Hansson } 1362393e5e24SUlf Hansson } else { 13634b85da08SDavide Ciminaghi ioread32_rep(base + MMCIFIFO, ptr, count >> 2); 1364393e5e24SUlf Hansson } 13651c6a0718SPierre Ossman 13661c6a0718SPierre Ossman ptr += count; 13671c6a0718SPierre Ossman remain -= count; 136826eed9a5SLinus Walleij host_remain -= count; 13691c6a0718SPierre Ossman 13701c6a0718SPierre Ossman if (remain == 0) 13711c6a0718SPierre Ossman break; 13721c6a0718SPierre Ossman 13731c6a0718SPierre Ossman status = readl(base + MMCISTATUS); 13741c6a0718SPierre Ossman } while (status & MCI_RXDATAAVLBL); 13751c6a0718SPierre Ossman 13761c6a0718SPierre Ossman return ptr - buffer; 13771c6a0718SPierre Ossman } 13781c6a0718SPierre Ossman 13791c6a0718SPierre Ossman static int mmci_pio_write(struct mmci_host *host, char *buffer, unsigned int remain, u32 status) 13801c6a0718SPierre Ossman { 13818301bb68SRabin Vincent struct variant_data *variant = host->variant; 13821c6a0718SPierre Ossman void __iomem *base = host->base; 13831c6a0718SPierre Ossman char *ptr = buffer; 13841c6a0718SPierre Ossman 13851c6a0718SPierre Ossman do { 13861c6a0718SPierre Ossman unsigned int count, maxcnt; 13871c6a0718SPierre Ossman 13888301bb68SRabin Vincent maxcnt = status & MCI_TXFIFOEMPTY ? 13898301bb68SRabin Vincent variant->fifosize : variant->fifohalfsize; 13901c6a0718SPierre Ossman count = min(remain, maxcnt); 13911c6a0718SPierre Ossman 139234177802SLinus Walleij /* 139334177802SLinus Walleij * SDIO especially may want to send something that is 139434177802SLinus Walleij * not divisible by 4 (as opposed to card sectors 139534177802SLinus Walleij * etc), and the FIFO only accept full 32-bit writes. 139634177802SLinus Walleij * So compensate by adding +3 on the count, a single 139734177802SLinus Walleij * byte become a 32bit write, 7 bytes will be two 139834177802SLinus Walleij * 32bit writes etc. 139934177802SLinus Walleij */ 14004b85da08SDavide Ciminaghi iowrite32_rep(base + MMCIFIFO, ptr, (count + 3) >> 2); 14011c6a0718SPierre Ossman 14021c6a0718SPierre Ossman ptr += count; 14031c6a0718SPierre Ossman remain -= count; 14041c6a0718SPierre Ossman 14051c6a0718SPierre Ossman if (remain == 0) 14061c6a0718SPierre Ossman break; 14071c6a0718SPierre Ossman 14081c6a0718SPierre Ossman status = readl(base + MMCISTATUS); 14091c6a0718SPierre Ossman } while (status & MCI_TXFIFOHALFEMPTY); 14101c6a0718SPierre Ossman 14111c6a0718SPierre Ossman return ptr - buffer; 14121c6a0718SPierre Ossman } 14131c6a0718SPierre Ossman 14141c6a0718SPierre Ossman /* 14151c6a0718SPierre Ossman * PIO data transfer IRQ handler. 14161c6a0718SPierre Ossman */ 14171c6a0718SPierre Ossman static irqreturn_t mmci_pio_irq(int irq, void *dev_id) 14181c6a0718SPierre Ossman { 14191c6a0718SPierre Ossman struct mmci_host *host = dev_id; 14204ce1d6cbSRabin Vincent struct sg_mapping_iter *sg_miter = &host->sg_miter; 14218301bb68SRabin Vincent struct variant_data *variant = host->variant; 14221c6a0718SPierre Ossman void __iomem *base = host->base; 14231c6a0718SPierre Ossman u32 status; 14241c6a0718SPierre Ossman 14251c6a0718SPierre Ossman status = readl(base + MMCISTATUS); 14261c6a0718SPierre Ossman 142764de0289SLinus Walleij dev_dbg(mmc_dev(host->mmc), "irq1 (pio) %08x\n", status); 14281c6a0718SPierre Ossman 14291c6a0718SPierre Ossman do { 14301c6a0718SPierre Ossman unsigned int remain, len; 14311c6a0718SPierre Ossman char *buffer; 14321c6a0718SPierre Ossman 14331c6a0718SPierre Ossman /* 14341c6a0718SPierre Ossman * For write, we only need to test the half-empty flag 14351c6a0718SPierre Ossman * here - if the FIFO is completely empty, then by 14361c6a0718SPierre Ossman * definition it is more than half empty. 14371c6a0718SPierre Ossman * 14381c6a0718SPierre Ossman * For read, check for data available. 14391c6a0718SPierre Ossman */ 14401c6a0718SPierre Ossman if (!(status & (MCI_TXFIFOHALFEMPTY|MCI_RXDATAAVLBL))) 14411c6a0718SPierre Ossman break; 14421c6a0718SPierre Ossman 14434ce1d6cbSRabin Vincent if (!sg_miter_next(sg_miter)) 14444ce1d6cbSRabin Vincent break; 14454ce1d6cbSRabin Vincent 14464ce1d6cbSRabin Vincent buffer = sg_miter->addr; 14474ce1d6cbSRabin Vincent remain = sg_miter->length; 14481c6a0718SPierre Ossman 14491c6a0718SPierre Ossman len = 0; 14501c6a0718SPierre Ossman if (status & MCI_RXACTIVE) 14511c6a0718SPierre Ossman len = mmci_pio_read(host, buffer, remain); 14521c6a0718SPierre Ossman if (status & MCI_TXACTIVE) 14531c6a0718SPierre Ossman len = mmci_pio_write(host, buffer, remain, status); 14541c6a0718SPierre Ossman 14554ce1d6cbSRabin Vincent sg_miter->consumed = len; 14561c6a0718SPierre Ossman 14571c6a0718SPierre Ossman host->size -= len; 14581c6a0718SPierre Ossman remain -= len; 14591c6a0718SPierre Ossman 14601c6a0718SPierre Ossman if (remain) 14611c6a0718SPierre Ossman break; 14621c6a0718SPierre Ossman 14631c6a0718SPierre Ossman status = readl(base + MMCISTATUS); 14641c6a0718SPierre Ossman } while (1); 14651c6a0718SPierre Ossman 14664ce1d6cbSRabin Vincent sg_miter_stop(sg_miter); 14674ce1d6cbSRabin Vincent 14681c6a0718SPierre Ossman /* 1469c4d877c1SRussell King * If we have less than the fifo 'half-full' threshold to transfer, 1470c4d877c1SRussell King * trigger a PIO interrupt as soon as any data is available. 14711c6a0718SPierre Ossman */ 1472c4d877c1SRussell King if (status & MCI_RXACTIVE && host->size < variant->fifohalfsize) 14732686b4b4SLinus Walleij mmci_set_mask1(host, MCI_RXDATAAVLBLMASK); 14741c6a0718SPierre Ossman 14751c6a0718SPierre Ossman /* 14761c6a0718SPierre Ossman * If we run out of data, disable the data IRQs; this 14771c6a0718SPierre Ossman * prevents a race where the FIFO becomes empty before 14781c6a0718SPierre Ossman * the chip itself has disabled the data path, and 14791c6a0718SPierre Ossman * stops us racing with our data end IRQ. 14801c6a0718SPierre Ossman */ 14811c6a0718SPierre Ossman if (host->size == 0) { 14822686b4b4SLinus Walleij mmci_set_mask1(host, 0); 14831c6a0718SPierre Ossman writel(readl(base + MMCIMASK0) | MCI_DATAENDMASK, base + MMCIMASK0); 14841c6a0718SPierre Ossman } 14851c6a0718SPierre Ossman 14861c6a0718SPierre Ossman return IRQ_HANDLED; 14871c6a0718SPierre Ossman } 14881c6a0718SPierre Ossman 14891c6a0718SPierre Ossman /* 14901c6a0718SPierre Ossman * Handle completion of command and data transfers. 14911c6a0718SPierre Ossman */ 14921c6a0718SPierre Ossman static irqreturn_t mmci_irq(int irq, void *dev_id) 14931c6a0718SPierre Ossman { 14941c6a0718SPierre Ossman struct mmci_host *host = dev_id; 14951c6a0718SPierre Ossman u32 status; 14961c6a0718SPierre Ossman int ret = 0; 14971c6a0718SPierre Ossman 14981c6a0718SPierre Ossman spin_lock(&host->lock); 14991c6a0718SPierre Ossman 15001c6a0718SPierre Ossman do { 15011c6a0718SPierre Ossman status = readl(host->base + MMCISTATUS); 15022686b4b4SLinus Walleij 15032686b4b4SLinus Walleij if (host->singleirq) { 15046ea9cdf3SPatrice Chotard if (status & host->mask1_reg) 15052686b4b4SLinus Walleij mmci_pio_irq(irq, dev_id); 15062686b4b4SLinus Walleij 150759db5e2dSLudovic Barre status &= ~host->variant->irq_pio_mask; 15082686b4b4SLinus Walleij } 15092686b4b4SLinus Walleij 15108d94b54dSUlf Hansson /* 15115cad24d8SJean-Nicolas Graux * We intentionally clear the MCI_ST_CARDBUSY IRQ (if it's 15125cad24d8SJean-Nicolas Graux * enabled) in mmci_cmd_irq() function where ST Micro busy 15135cad24d8SJean-Nicolas Graux * detection variant is handled. Considering the HW seems to be 15145cad24d8SJean-Nicolas Graux * triggering the IRQ on both edges while monitoring DAT0 for 15155cad24d8SJean-Nicolas Graux * busy completion and that same status bit is used to monitor 15165cad24d8SJean-Nicolas Graux * start and end of busy detection, special care must be taken 15175cad24d8SJean-Nicolas Graux * to make sure that both start and end interrupts are always 15185cad24d8SJean-Nicolas Graux * cleared one after the other. 15198d94b54dSUlf Hansson */ 15201c6a0718SPierre Ossman status &= readl(host->base + MMCIMASK0); 15215cad24d8SJean-Nicolas Graux if (host->variant->busy_detect) 15225cad24d8SJean-Nicolas Graux writel(status & ~host->variant->busy_detect_mask, 15235cad24d8SJean-Nicolas Graux host->base + MMCICLEAR); 15245cad24d8SJean-Nicolas Graux else 15251c6a0718SPierre Ossman writel(status, host->base + MMCICLEAR); 15261c6a0718SPierre Ossman 152764de0289SLinus Walleij dev_dbg(mmc_dev(host->mmc), "irq0 (data+cmd) %08x\n", status); 15281c6a0718SPierre Ossman 15297878289bSUlf Hansson if (host->variant->reversed_irq_handling) { 15307878289bSUlf Hansson mmci_data_irq(host, host->data, status); 15317878289bSUlf Hansson mmci_cmd_irq(host, host->cmd, status); 15327878289bSUlf Hansson } else { 1533ad82bfeaSUlf Hansson mmci_cmd_irq(host, host->cmd, status); 15341cb9da50SUlf Hansson mmci_data_irq(host, host->data, status); 15357878289bSUlf Hansson } 15361c6a0718SPierre Ossman 153749adc0caSLinus Walleij /* 153849adc0caSLinus Walleij * Don't poll for busy completion in irq context. 153949adc0caSLinus Walleij */ 154049adc0caSLinus Walleij if (host->variant->busy_detect && host->busy_status) 154149adc0caSLinus Walleij status &= ~host->variant->busy_detect_flag; 15428d94b54dSUlf Hansson 15431c6a0718SPierre Ossman ret = 1; 15441c6a0718SPierre Ossman } while (status); 15451c6a0718SPierre Ossman 15461c6a0718SPierre Ossman spin_unlock(&host->lock); 15471c6a0718SPierre Ossman 15481c6a0718SPierre Ossman return IRQ_RETVAL(ret); 15491c6a0718SPierre Ossman } 15501c6a0718SPierre Ossman 15511c6a0718SPierre Ossman static void mmci_request(struct mmc_host *mmc, struct mmc_request *mrq) 15521c6a0718SPierre Ossman { 15531c6a0718SPierre Ossman struct mmci_host *host = mmc_priv(mmc); 15549e943021SLinus Walleij unsigned long flags; 15551c6a0718SPierre Ossman 15561c6a0718SPierre Ossman WARN_ON(host->mrq != NULL); 15571c6a0718SPierre Ossman 1558653a761eSUlf Hansson mrq->cmd->error = mmci_validate_data(host, mrq->data); 1559653a761eSUlf Hansson if (mrq->cmd->error) { 1560255d01afSPierre Ossman mmc_request_done(mmc, mrq); 1561255d01afSPierre Ossman return; 1562255d01afSPierre Ossman } 1563255d01afSPierre Ossman 15649e943021SLinus Walleij spin_lock_irqsave(&host->lock, flags); 15651c6a0718SPierre Ossman 15661c6a0718SPierre Ossman host->mrq = mrq; 15671c6a0718SPierre Ossman 156858c7ccbfSPer Forlin if (mrq->data) 156958c7ccbfSPer Forlin mmci_get_next_data(host, mrq->data); 157058c7ccbfSPer Forlin 1571d2141547SLudovic Barre if (mrq->data && 1572d2141547SLudovic Barre (host->variant->datactrl_first || mrq->data->flags & MMC_DATA_READ)) 15731c6a0718SPierre Ossman mmci_start_data(host, mrq->data); 15741c6a0718SPierre Ossman 1575024629c6SUlf Hansson if (mrq->sbc) 1576024629c6SUlf Hansson mmci_start_command(host, mrq->sbc, 0); 1577024629c6SUlf Hansson else 15781c6a0718SPierre Ossman mmci_start_command(host, mrq->cmd, 0); 15791c6a0718SPierre Ossman 15809e943021SLinus Walleij spin_unlock_irqrestore(&host->lock, flags); 15811c6a0718SPierre Ossman } 15821c6a0718SPierre Ossman 15831c6a0718SPierre Ossman static void mmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) 15841c6a0718SPierre Ossman { 15851c6a0718SPierre Ossman struct mmci_host *host = mmc_priv(mmc); 15867d72a1d4SUlf Hansson struct variant_data *variant = host->variant; 1587a6a6464aSLinus Walleij u32 pwr = 0; 1588a6a6464aSLinus Walleij unsigned long flags; 1589db90f91fSLee Jones int ret; 15901c6a0718SPierre Ossman 1591bc521818SUlf Hansson if (host->plat->ios_handler && 1592bc521818SUlf Hansson host->plat->ios_handler(mmc_dev(mmc), ios)) 1593bc521818SUlf Hansson dev_err(mmc_dev(mmc), "platform ios_handler failed\n"); 1594bc521818SUlf Hansson 15951c6a0718SPierre Ossman switch (ios->power_mode) { 15961c6a0718SPierre Ossman case MMC_POWER_OFF: 1597599c1d5cSUlf Hansson if (!IS_ERR(mmc->supply.vmmc)) 1598599c1d5cSUlf Hansson mmc_regulator_set_ocr(mmc, mmc->supply.vmmc, 0); 1599237fb5e6SLee Jones 16007c0136efSUlf Hansson if (!IS_ERR(mmc->supply.vqmmc) && host->vqmmc_enabled) { 1601237fb5e6SLee Jones regulator_disable(mmc->supply.vqmmc); 16027c0136efSUlf Hansson host->vqmmc_enabled = false; 16037c0136efSUlf Hansson } 1604237fb5e6SLee Jones 16051c6a0718SPierre Ossman break; 16061c6a0718SPierre Ossman case MMC_POWER_UP: 1607599c1d5cSUlf Hansson if (!IS_ERR(mmc->supply.vmmc)) 1608599c1d5cSUlf Hansson mmc_regulator_set_ocr(mmc, mmc->supply.vmmc, ios->vdd); 1609599c1d5cSUlf Hansson 16107d72a1d4SUlf Hansson /* 16117d72a1d4SUlf Hansson * The ST Micro variant doesn't have the PL180s MCI_PWR_UP 16127d72a1d4SUlf Hansson * and instead uses MCI_PWR_ON so apply whatever value is 16137d72a1d4SUlf Hansson * configured in the variant data. 16147d72a1d4SUlf Hansson */ 16157d72a1d4SUlf Hansson pwr |= variant->pwrreg_powerup; 16167d72a1d4SUlf Hansson 16171c6a0718SPierre Ossman break; 16181c6a0718SPierre Ossman case MMC_POWER_ON: 16197c0136efSUlf Hansson if (!IS_ERR(mmc->supply.vqmmc) && !host->vqmmc_enabled) { 1620db90f91fSLee Jones ret = regulator_enable(mmc->supply.vqmmc); 1621db90f91fSLee Jones if (ret < 0) 1622db90f91fSLee Jones dev_err(mmc_dev(mmc), 1623db90f91fSLee Jones "failed to enable vqmmc regulator\n"); 16247c0136efSUlf Hansson else 16257c0136efSUlf Hansson host->vqmmc_enabled = true; 1626db90f91fSLee Jones } 1627237fb5e6SLee Jones 16281c6a0718SPierre Ossman pwr |= MCI_PWR_ON; 16291c6a0718SPierre Ossman break; 16301c6a0718SPierre Ossman } 16311c6a0718SPierre Ossman 16324d1a3a0dSUlf Hansson if (variant->signal_direction && ios->power_mode != MMC_POWER_OFF) { 16334d1a3a0dSUlf Hansson /* 16344d1a3a0dSUlf Hansson * The ST Micro variant has some additional bits 16354d1a3a0dSUlf Hansson * indicating signal direction for the signals in 16364d1a3a0dSUlf Hansson * the SD/MMC bus and feedback-clock usage. 16374d1a3a0dSUlf Hansson */ 16384593df29SUlf Hansson pwr |= host->pwr_reg_add; 16394d1a3a0dSUlf Hansson 16404d1a3a0dSUlf Hansson if (ios->bus_width == MMC_BUS_WIDTH_4) 16414d1a3a0dSUlf Hansson pwr &= ~MCI_ST_DATA74DIREN; 16424d1a3a0dSUlf Hansson else if (ios->bus_width == MMC_BUS_WIDTH_1) 16434d1a3a0dSUlf Hansson pwr &= (~MCI_ST_DATA74DIREN & 16444d1a3a0dSUlf Hansson ~MCI_ST_DATA31DIREN & 16454d1a3a0dSUlf Hansson ~MCI_ST_DATA2DIREN); 16464d1a3a0dSUlf Hansson } 16474d1a3a0dSUlf Hansson 1648f9bb304cSPatrice Chotard if (variant->opendrain) { 1649f9bb304cSPatrice Chotard if (ios->bus_mode == MMC_BUSMODE_OPENDRAIN) 165011dfb970SPatrice Chotard pwr |= variant->opendrain; 1651f9bb304cSPatrice Chotard } else { 1652f9bb304cSPatrice Chotard /* 1653f9bb304cSPatrice Chotard * If the variant cannot configure the pads by its own, then we 1654f9bb304cSPatrice Chotard * expect the pinctrl to be able to do that for us 1655f9bb304cSPatrice Chotard */ 1656f9bb304cSPatrice Chotard if (ios->bus_mode == MMC_BUSMODE_OPENDRAIN) 1657f9bb304cSPatrice Chotard pinctrl_select_state(host->pinctrl, host->pins_opendrain); 1658f9bb304cSPatrice Chotard else 1659f9bb304cSPatrice Chotard pinctrl_select_state(host->pinctrl, host->pins_default); 1660f9bb304cSPatrice Chotard } 16611c6a0718SPierre Ossman 1662f4670daeSUlf Hansson /* 1663f4670daeSUlf Hansson * If clock = 0 and the variant requires the MMCIPOWER to be used for 1664f4670daeSUlf Hansson * gating the clock, the MCI_PWR_ON bit is cleared. 1665f4670daeSUlf Hansson */ 1666f4670daeSUlf Hansson if (!ios->clock && variant->pwrreg_clkgate) 1667f4670daeSUlf Hansson pwr &= ~MCI_PWR_ON; 1668f4670daeSUlf Hansson 16693f4e6f7bSSrinivas Kandagatla if (host->variant->explicit_mclk_control && 16703f4e6f7bSSrinivas Kandagatla ios->clock != host->clock_cache) { 16713f4e6f7bSSrinivas Kandagatla ret = clk_set_rate(host->clk, ios->clock); 16723f4e6f7bSSrinivas Kandagatla if (ret < 0) 16733f4e6f7bSSrinivas Kandagatla dev_err(mmc_dev(host->mmc), 16743f4e6f7bSSrinivas Kandagatla "Error setting clock rate (%d)\n", ret); 16753f4e6f7bSSrinivas Kandagatla else 16763f4e6f7bSSrinivas Kandagatla host->mclk = clk_get_rate(host->clk); 16773f4e6f7bSSrinivas Kandagatla } 16783f4e6f7bSSrinivas Kandagatla host->clock_cache = ios->clock; 16793f4e6f7bSSrinivas Kandagatla 1680a6a6464aSLinus Walleij spin_lock_irqsave(&host->lock, flags); 1681a6a6464aSLinus Walleij 1682cd3ee8c5SLudovic Barre if (host->ops && host->ops->set_clkreg) 1683cd3ee8c5SLudovic Barre host->ops->set_clkreg(host, ios->clock); 1684cd3ee8c5SLudovic Barre else 1685a6a6464aSLinus Walleij mmci_set_clkreg(host, ios->clock); 1686cd3ee8c5SLudovic Barre 1687cd3ee8c5SLudovic Barre if (host->ops && host->ops->set_pwrreg) 1688cd3ee8c5SLudovic Barre host->ops->set_pwrreg(host, pwr); 1689cd3ee8c5SLudovic Barre else 16907437cfa5SUlf Hansson mmci_write_pwrreg(host, pwr); 1691cd3ee8c5SLudovic Barre 1692f829c042SUlf Hansson mmci_reg_delay(host); 1693a6a6464aSLinus Walleij 1694a6a6464aSLinus Walleij spin_unlock_irqrestore(&host->lock, flags); 16951c6a0718SPierre Ossman } 16961c6a0718SPierre Ossman 169789001446SRussell King static int mmci_get_cd(struct mmc_host *mmc) 169889001446SRussell King { 169989001446SRussell King struct mmci_host *host = mmc_priv(mmc); 170029719445SRabin Vincent struct mmci_platform_data *plat = host->plat; 1701d2762090SUlf Hansson unsigned int status = mmc_gpio_get_cd(mmc); 170289001446SRussell King 1703d2762090SUlf Hansson if (status == -ENOSYS) { 17044b8caec0SRabin Vincent if (!plat->status) 17054b8caec0SRabin Vincent return 1; /* Assume always present */ 17064b8caec0SRabin Vincent 170729719445SRabin Vincent status = plat->status(mmc_dev(host->mmc)); 1708d2762090SUlf Hansson } 170974bc8093SRussell King return status; 171089001446SRussell King } 171189001446SRussell King 17120f3ed7f7SUlf Hansson static int mmci_sig_volt_switch(struct mmc_host *mmc, struct mmc_ios *ios) 17130f3ed7f7SUlf Hansson { 17140f3ed7f7SUlf Hansson int ret = 0; 17150f3ed7f7SUlf Hansson 17160f3ed7f7SUlf Hansson if (!IS_ERR(mmc->supply.vqmmc)) { 17170f3ed7f7SUlf Hansson 17180f3ed7f7SUlf Hansson switch (ios->signal_voltage) { 17190f3ed7f7SUlf Hansson case MMC_SIGNAL_VOLTAGE_330: 17200f3ed7f7SUlf Hansson ret = regulator_set_voltage(mmc->supply.vqmmc, 17210f3ed7f7SUlf Hansson 2700000, 3600000); 17220f3ed7f7SUlf Hansson break; 17230f3ed7f7SUlf Hansson case MMC_SIGNAL_VOLTAGE_180: 17240f3ed7f7SUlf Hansson ret = regulator_set_voltage(mmc->supply.vqmmc, 17250f3ed7f7SUlf Hansson 1700000, 1950000); 17260f3ed7f7SUlf Hansson break; 17270f3ed7f7SUlf Hansson case MMC_SIGNAL_VOLTAGE_120: 17280f3ed7f7SUlf Hansson ret = regulator_set_voltage(mmc->supply.vqmmc, 17290f3ed7f7SUlf Hansson 1100000, 1300000); 17300f3ed7f7SUlf Hansson break; 17310f3ed7f7SUlf Hansson } 17320f3ed7f7SUlf Hansson 17330f3ed7f7SUlf Hansson if (ret) 17340f3ed7f7SUlf Hansson dev_warn(mmc_dev(mmc), "Voltage switch failed\n"); 17350f3ed7f7SUlf Hansson } 17360f3ed7f7SUlf Hansson 17370f3ed7f7SUlf Hansson return ret; 17380f3ed7f7SUlf Hansson } 17390f3ed7f7SUlf Hansson 174001259620SUlf Hansson static struct mmc_host_ops mmci_ops = { 17411c6a0718SPierre Ossman .request = mmci_request, 174258c7ccbfSPer Forlin .pre_req = mmci_pre_request, 174358c7ccbfSPer Forlin .post_req = mmci_post_request, 17441c6a0718SPierre Ossman .set_ios = mmci_set_ios, 1745d2762090SUlf Hansson .get_ro = mmc_gpio_get_ro, 174689001446SRussell King .get_cd = mmci_get_cd, 17470f3ed7f7SUlf Hansson .start_signal_voltage_switch = mmci_sig_volt_switch, 17481c6a0718SPierre Ossman }; 17491c6a0718SPierre Ossman 175078f87df2SUlf Hansson static int mmci_of_parse(struct device_node *np, struct mmc_host *mmc) 175178f87df2SUlf Hansson { 17524593df29SUlf Hansson struct mmci_host *host = mmc_priv(mmc); 175378f87df2SUlf Hansson int ret = mmc_of_parse(mmc); 1754000bc9d5SLee Jones 175578f87df2SUlf Hansson if (ret) 175678f87df2SUlf Hansson return ret; 1757000bc9d5SLee Jones 17584593df29SUlf Hansson if (of_get_property(np, "st,sig-dir-dat0", NULL)) 17594593df29SUlf Hansson host->pwr_reg_add |= MCI_ST_DATA0DIREN; 17604593df29SUlf Hansson if (of_get_property(np, "st,sig-dir-dat2", NULL)) 17614593df29SUlf Hansson host->pwr_reg_add |= MCI_ST_DATA2DIREN; 17624593df29SUlf Hansson if (of_get_property(np, "st,sig-dir-dat31", NULL)) 17634593df29SUlf Hansson host->pwr_reg_add |= MCI_ST_DATA31DIREN; 17644593df29SUlf Hansson if (of_get_property(np, "st,sig-dir-dat74", NULL)) 17654593df29SUlf Hansson host->pwr_reg_add |= MCI_ST_DATA74DIREN; 17664593df29SUlf Hansson if (of_get_property(np, "st,sig-dir-cmd", NULL)) 17674593df29SUlf Hansson host->pwr_reg_add |= MCI_ST_CMDDIREN; 17684593df29SUlf Hansson if (of_get_property(np, "st,sig-pin-fbclk", NULL)) 17694593df29SUlf Hansson host->pwr_reg_add |= MCI_ST_FBCLKEN; 177046b723ddSLudovic Barre if (of_get_property(np, "st,sig-dir", NULL)) 177146b723ddSLudovic Barre host->pwr_reg_add |= MCI_STM32_DIRPOL; 177246b723ddSLudovic Barre if (of_get_property(np, "st,neg-edge", NULL)) 177346b723ddSLudovic Barre host->clk_reg_add |= MCI_STM32_CLK_NEGEDGE; 177446b723ddSLudovic Barre if (of_get_property(np, "st,use-ckin", NULL)) 177546b723ddSLudovic Barre host->clk_reg_add |= MCI_STM32_CLK_SELCKIN; 17764593df29SUlf Hansson 1777000bc9d5SLee Jones if (of_get_property(np, "mmc-cap-mmc-highspeed", NULL)) 177878f87df2SUlf Hansson mmc->caps |= MMC_CAP_MMC_HIGHSPEED; 1779000bc9d5SLee Jones if (of_get_property(np, "mmc-cap-sd-highspeed", NULL)) 178078f87df2SUlf Hansson mmc->caps |= MMC_CAP_SD_HIGHSPEED; 1781000bc9d5SLee Jones 178278f87df2SUlf Hansson return 0; 1783000bc9d5SLee Jones } 1784000bc9d5SLee Jones 1785c3be1efdSBill Pemberton static int mmci_probe(struct amba_device *dev, 1786aa25afadSRussell King const struct amba_id *id) 17871c6a0718SPierre Ossman { 17886ef297f8SLinus Walleij struct mmci_platform_data *plat = dev->dev.platform_data; 1789000bc9d5SLee Jones struct device_node *np = dev->dev.of_node; 17904956e109SRabin Vincent struct variant_data *variant = id->data; 17911c6a0718SPierre Ossman struct mmci_host *host; 17921c6a0718SPierre Ossman struct mmc_host *mmc; 17931c6a0718SPierre Ossman int ret; 17941c6a0718SPierre Ossman 1795000bc9d5SLee Jones /* Must have platform data or Device Tree. */ 1796000bc9d5SLee Jones if (!plat && !np) { 1797000bc9d5SLee Jones dev_err(&dev->dev, "No plat data or DT found\n"); 1798000bc9d5SLee Jones return -EINVAL; 17991c6a0718SPierre Ossman } 18001c6a0718SPierre Ossman 1801b9b52918SLee Jones if (!plat) { 1802b9b52918SLee Jones plat = devm_kzalloc(&dev->dev, sizeof(*plat), GFP_KERNEL); 1803b9b52918SLee Jones if (!plat) 1804b9b52918SLee Jones return -ENOMEM; 1805b9b52918SLee Jones } 1806b9b52918SLee Jones 18071c6a0718SPierre Ossman mmc = mmc_alloc_host(sizeof(struct mmci_host), &dev->dev); 1808ef289982SUlf Hansson if (!mmc) 1809ef289982SUlf Hansson return -ENOMEM; 18101c6a0718SPierre Ossman 181178f87df2SUlf Hansson ret = mmci_of_parse(np, mmc); 181278f87df2SUlf Hansson if (ret) 181378f87df2SUlf Hansson goto host_free; 181478f87df2SUlf Hansson 18151c6a0718SPierre Ossman host = mmc_priv(mmc); 18164ea580f1SRabin Vincent host->mmc = mmc; 1817012b7d33SRussell King 1818f9bb304cSPatrice Chotard /* 1819f9bb304cSPatrice Chotard * Some variant (STM32) doesn't have opendrain bit, nevertheless 1820f9bb304cSPatrice Chotard * pins can be set accordingly using pinctrl 1821f9bb304cSPatrice Chotard */ 1822f9bb304cSPatrice Chotard if (!variant->opendrain) { 1823f9bb304cSPatrice Chotard host->pinctrl = devm_pinctrl_get(&dev->dev); 1824f9bb304cSPatrice Chotard if (IS_ERR(host->pinctrl)) { 1825f9bb304cSPatrice Chotard dev_err(&dev->dev, "failed to get pinctrl"); 1826310eb252SWei Yongjun ret = PTR_ERR(host->pinctrl); 1827f9bb304cSPatrice Chotard goto host_free; 1828f9bb304cSPatrice Chotard } 1829f9bb304cSPatrice Chotard 1830f9bb304cSPatrice Chotard host->pins_default = pinctrl_lookup_state(host->pinctrl, 1831f9bb304cSPatrice Chotard PINCTRL_STATE_DEFAULT); 1832f9bb304cSPatrice Chotard if (IS_ERR(host->pins_default)) { 1833f9bb304cSPatrice Chotard dev_err(mmc_dev(mmc), "Can't select default pins\n"); 1834310eb252SWei Yongjun ret = PTR_ERR(host->pins_default); 1835f9bb304cSPatrice Chotard goto host_free; 1836f9bb304cSPatrice Chotard } 1837f9bb304cSPatrice Chotard 1838f9bb304cSPatrice Chotard host->pins_opendrain = pinctrl_lookup_state(host->pinctrl, 1839f9bb304cSPatrice Chotard MMCI_PINCTRL_STATE_OPENDRAIN); 1840f9bb304cSPatrice Chotard if (IS_ERR(host->pins_opendrain)) { 1841f9bb304cSPatrice Chotard dev_err(mmc_dev(mmc), "Can't select opendrain pins\n"); 1842310eb252SWei Yongjun ret = PTR_ERR(host->pins_opendrain); 1843f9bb304cSPatrice Chotard goto host_free; 1844f9bb304cSPatrice Chotard } 1845f9bb304cSPatrice Chotard } 1846f9bb304cSPatrice Chotard 1847012b7d33SRussell King host->hw_designer = amba_manf(dev); 1848012b7d33SRussell King host->hw_revision = amba_rev(dev); 184964de0289SLinus Walleij dev_dbg(mmc_dev(mmc), "designer ID = 0x%02x\n", host->hw_designer); 185064de0289SLinus Walleij dev_dbg(mmc_dev(mmc), "revision = 0x%01x\n", host->hw_revision); 1851012b7d33SRussell King 1852665ba56fSUlf Hansson host->clk = devm_clk_get(&dev->dev, NULL); 18531c6a0718SPierre Ossman if (IS_ERR(host->clk)) { 18541c6a0718SPierre Ossman ret = PTR_ERR(host->clk); 18551c6a0718SPierre Ossman goto host_free; 18561c6a0718SPierre Ossman } 18571c6a0718SPierre Ossman 1858ac940938SJulia Lawall ret = clk_prepare_enable(host->clk); 18591c6a0718SPierre Ossman if (ret) 1860665ba56fSUlf Hansson goto host_free; 18611c6a0718SPierre Ossman 18629c34b73dSSrinivas Kandagatla if (variant->qcom_fifo) 18639c34b73dSSrinivas Kandagatla host->get_rx_fifocnt = mmci_qcom_get_rx_fifocnt; 18649c34b73dSSrinivas Kandagatla else 18659c34b73dSSrinivas Kandagatla host->get_rx_fifocnt = mmci_get_rx_fifocnt; 18669c34b73dSSrinivas Kandagatla 18671c6a0718SPierre Ossman host->plat = plat; 18684956e109SRabin Vincent host->variant = variant; 18691c6a0718SPierre Ossman host->mclk = clk_get_rate(host->clk); 1870c8df9a53SLinus Walleij /* 1871c8df9a53SLinus Walleij * According to the spec, mclk is max 100 MHz, 1872c8df9a53SLinus Walleij * so we try to adjust the clock down to this, 1873c8df9a53SLinus Walleij * (if possible). 1874c8df9a53SLinus Walleij */ 1875dc6500bfSSrinivas Kandagatla if (host->mclk > variant->f_max) { 1876dc6500bfSSrinivas Kandagatla ret = clk_set_rate(host->clk, variant->f_max); 1877c8df9a53SLinus Walleij if (ret < 0) 1878c8df9a53SLinus Walleij goto clk_disable; 1879c8df9a53SLinus Walleij host->mclk = clk_get_rate(host->clk); 188064de0289SLinus Walleij dev_dbg(mmc_dev(mmc), "eventual mclk rate: %u Hz\n", 188164de0289SLinus Walleij host->mclk); 1882c8df9a53SLinus Walleij } 1883ef289982SUlf Hansson 1884c8ebae37SRussell King host->phybase = dev->res.start; 1885ef289982SUlf Hansson host->base = devm_ioremap_resource(&dev->dev, &dev->res); 1886ef289982SUlf Hansson if (IS_ERR(host->base)) { 1887ef289982SUlf Hansson ret = PTR_ERR(host->base); 18881c6a0718SPierre Ossman goto clk_disable; 18891c6a0718SPierre Ossman } 18901c6a0718SPierre Ossman 1891ed9067fdSUlf Hansson if (variant->init) 1892ed9067fdSUlf Hansson variant->init(host); 1893ed9067fdSUlf Hansson 18947f294e49SLinus Walleij /* 18957f294e49SLinus Walleij * The ARM and ST versions of the block have slightly different 18967f294e49SLinus Walleij * clock divider equations which means that the minimum divider 18977f294e49SLinus Walleij * differs too. 18983f4e6f7bSSrinivas Kandagatla * on Qualcomm like controllers get the nearest minimum clock to 100Khz 18997f294e49SLinus Walleij */ 19007f294e49SLinus Walleij if (variant->st_clkdiv) 19017f294e49SLinus Walleij mmc->f_min = DIV_ROUND_UP(host->mclk, 257); 190200e930d8SLudovic Barre else if (variant->stm32_clkdiv) 190300e930d8SLudovic Barre mmc->f_min = DIV_ROUND_UP(host->mclk, 2046); 19043f4e6f7bSSrinivas Kandagatla else if (variant->explicit_mclk_control) 19053f4e6f7bSSrinivas Kandagatla mmc->f_min = clk_round_rate(host->clk, 100000); 19067f294e49SLinus Walleij else 19077f294e49SLinus Walleij mmc->f_min = DIV_ROUND_UP(host->mclk, 512); 1908808d97ccSLinus Walleij /* 190978f87df2SUlf Hansson * If no maximum operating frequency is supplied, fall back to use 191078f87df2SUlf Hansson * the module parameter, which has a (low) default value in case it 191178f87df2SUlf Hansson * is not specified. Either value must not exceed the clock rate into 19125080a08dSUlf Hansson * the block, of course. 1913808d97ccSLinus Walleij */ 191478f87df2SUlf Hansson if (mmc->f_max) 19153f4e6f7bSSrinivas Kandagatla mmc->f_max = variant->explicit_mclk_control ? 19163f4e6f7bSSrinivas Kandagatla min(variant->f_max, mmc->f_max) : 19173f4e6f7bSSrinivas Kandagatla min(host->mclk, mmc->f_max); 1918808d97ccSLinus Walleij else 19193f4e6f7bSSrinivas Kandagatla mmc->f_max = variant->explicit_mclk_control ? 19203f4e6f7bSSrinivas Kandagatla fmax : min(host->mclk, fmax); 19213f4e6f7bSSrinivas Kandagatla 19223f4e6f7bSSrinivas Kandagatla 192364de0289SLinus Walleij dev_dbg(mmc_dev(mmc), "clocking block at %u Hz\n", mmc->f_max); 192464de0289SLinus Walleij 192515878e58SLudovic Barre host->rst = devm_reset_control_get_optional_exclusive(&dev->dev, NULL); 192615878e58SLudovic Barre if (IS_ERR(host->rst)) { 192715878e58SLudovic Barre ret = PTR_ERR(host->rst); 192815878e58SLudovic Barre goto clk_disable; 192915878e58SLudovic Barre } 193015878e58SLudovic Barre 1931599c1d5cSUlf Hansson /* Get regulators and the supported OCR mask */ 19329369c97cSBjorn Andersson ret = mmc_regulator_get_supply(mmc); 193351006952SWolfram Sang if (ret) 19349369c97cSBjorn Andersson goto clk_disable; 19359369c97cSBjorn Andersson 1936599c1d5cSUlf Hansson if (!mmc->ocr_avail) 19371c6a0718SPierre Ossman mmc->ocr_avail = plat->ocr_mask; 1938599c1d5cSUlf Hansson else if (plat->ocr_mask) 1939599c1d5cSUlf Hansson dev_warn(mmc_dev(mmc), "Platform OCR mask is ignored\n"); 1940599c1d5cSUlf Hansson 19419dd8a8b8SUlf Hansson /* We support these capabilities. */ 19429dd8a8b8SUlf Hansson mmc->caps |= MMC_CAP_CMD23; 19439dd8a8b8SUlf Hansson 194449adc0caSLinus Walleij /* 194549adc0caSLinus Walleij * Enable busy detection. 194649adc0caSLinus Walleij */ 19478d94b54dSUlf Hansson if (variant->busy_detect) { 19488d94b54dSUlf Hansson mmci_ops.card_busy = mmci_card_busy; 194949adc0caSLinus Walleij /* 195049adc0caSLinus Walleij * Not all variants have a flag to enable busy detection 195149adc0caSLinus Walleij * in the DPSM, but if they do, set it here. 195249adc0caSLinus Walleij */ 195349adc0caSLinus Walleij if (variant->busy_dpsm_flag) 195449adc0caSLinus Walleij mmci_write_datactrlreg(host, 195549adc0caSLinus Walleij host->variant->busy_dpsm_flag); 19568d94b54dSUlf Hansson mmc->caps |= MMC_CAP_WAIT_WHILE_BUSY; 19578d94b54dSUlf Hansson mmc->max_busy_timeout = 0; 19588d94b54dSUlf Hansson } 19598d94b54dSUlf Hansson 1960e9968c6fSUlf Hansson /* Prepare a CMD12 - needed to clear the DPSM on some variants. */ 1961e9968c6fSUlf Hansson host->stop_abort.opcode = MMC_STOP_TRANSMISSION; 1962e9968c6fSUlf Hansson host->stop_abort.arg = 0; 1963e9968c6fSUlf Hansson host->stop_abort.flags = MMC_RSP_R1B | MMC_CMD_AC; 1964e9968c6fSUlf Hansson 19658d94b54dSUlf Hansson mmc->ops = &mmci_ops; 19668d94b54dSUlf Hansson 196770be208fSUlf Hansson /* We support these PM capabilities. */ 196878f87df2SUlf Hansson mmc->pm_caps |= MMC_PM_KEEP_POWER; 196970be208fSUlf Hansson 19701c6a0718SPierre Ossman /* 19711c6a0718SPierre Ossman * We can do SGIO 19721c6a0718SPierre Ossman */ 1973a36274e0SMartin K. Petersen mmc->max_segs = NR_SG; 19741c6a0718SPierre Ossman 19751c6a0718SPierre Ossman /* 197608458ef6SRabin Vincent * Since only a certain number of bits are valid in the data length 197708458ef6SRabin Vincent * register, we must ensure that we don't exceed 2^num-1 bytes in a 197808458ef6SRabin Vincent * single request. 19791c6a0718SPierre Ossman */ 198008458ef6SRabin Vincent mmc->max_req_size = (1 << variant->datalength_bits) - 1; 19811c6a0718SPierre Ossman 19821c6a0718SPierre Ossman /* 19831c6a0718SPierre Ossman * Set the maximum segment size. Since we aren't doing DMA 19841c6a0718SPierre Ossman * (yet) we are only limited by the data length register. 19851c6a0718SPierre Ossman */ 19861c6a0718SPierre Ossman mmc->max_seg_size = mmc->max_req_size; 19871c6a0718SPierre Ossman 19881c6a0718SPierre Ossman /* 19891c6a0718SPierre Ossman * Block size can be up to 2048 bytes, but must be a power of two. 19901c6a0718SPierre Ossman */ 1991c931d495SLudovic Barre mmc->max_blk_size = 1 << variant->datactrl_blocksz; 19921c6a0718SPierre Ossman 19931c6a0718SPierre Ossman /* 19948f7f6b7eSWill Deacon * Limit the number of blocks transferred so that we don't overflow 19958f7f6b7eSWill Deacon * the maximum request size. 19961c6a0718SPierre Ossman */ 1997c931d495SLudovic Barre mmc->max_blk_count = mmc->max_req_size >> variant->datactrl_blocksz; 19981c6a0718SPierre Ossman 19991c6a0718SPierre Ossman spin_lock_init(&host->lock); 20001c6a0718SPierre Ossman 20011c6a0718SPierre Ossman writel(0, host->base + MMCIMASK0); 20026ea9cdf3SPatrice Chotard 20036ea9cdf3SPatrice Chotard if (variant->mmcimask1) 20041c6a0718SPierre Ossman writel(0, host->base + MMCIMASK1); 20056ea9cdf3SPatrice Chotard 20061c6a0718SPierre Ossman writel(0xfff, host->base + MMCICLEAR); 20071c6a0718SPierre Ossman 2008ce437aa4SLinus Walleij /* 2009ce437aa4SLinus Walleij * If: 2010ce437aa4SLinus Walleij * - not using DT but using a descriptor table, or 2011ce437aa4SLinus Walleij * - using a table of descriptors ALONGSIDE DT, or 2012ce437aa4SLinus Walleij * look up these descriptors named "cd" and "wp" right here, fail 20139ef986a6SLinus Walleij * silently of these do not exist 2014ce437aa4SLinus Walleij */ 2015ce437aa4SLinus Walleij if (!np) { 201689168b48SLinus Walleij ret = mmc_gpiod_request_cd(mmc, "cd", 0, false, 0, NULL); 2017ce437aa4SLinus Walleij if (ret == -EPROBE_DEFER) 2018ce437aa4SLinus Walleij goto clk_disable; 2019ce437aa4SLinus Walleij 2020a2b760a6SLinus Walleij ret = mmc_gpiod_request_ro(mmc, "wp", 0, 0, NULL); 2021ce437aa4SLinus Walleij if (ret == -EPROBE_DEFER) 2022ce437aa4SLinus Walleij goto clk_disable; 2023ce437aa4SLinus Walleij } 202489001446SRussell King 2025ef289982SUlf Hansson ret = devm_request_irq(&dev->dev, dev->irq[0], mmci_irq, IRQF_SHARED, 2026ef289982SUlf Hansson DRIVER_NAME " (cmd)", host); 20271c6a0718SPierre Ossman if (ret) 2028ef289982SUlf Hansson goto clk_disable; 20291c6a0718SPierre Ossman 2030dfb85185SRussell King if (!dev->irq[1]) 20312686b4b4SLinus Walleij host->singleirq = true; 20322686b4b4SLinus Walleij else { 2033ef289982SUlf Hansson ret = devm_request_irq(&dev->dev, dev->irq[1], mmci_pio_irq, 2034ef289982SUlf Hansson IRQF_SHARED, DRIVER_NAME " (pio)", host); 20351c6a0718SPierre Ossman if (ret) 2036ef289982SUlf Hansson goto clk_disable; 20372686b4b4SLinus Walleij } 20381c6a0718SPierre Ossman 2039daf9713cSLudovic Barre writel(MCI_IRQENABLE | variant->start_err, host->base + MMCIMASK0); 20401c6a0718SPierre Ossman 20411c6a0718SPierre Ossman amba_set_drvdata(dev, mmc); 20421c6a0718SPierre Ossman 2043c8ebae37SRussell King dev_info(&dev->dev, "%s: PL%03x manf %x rev%u at 0x%08llx irq %d,%d (pio)\n", 2044c8ebae37SRussell King mmc_hostname(mmc), amba_part(dev), amba_manf(dev), 2045c8ebae37SRussell King amba_rev(dev), (unsigned long long)dev->res.start, 2046c8ebae37SRussell King dev->irq[0], dev->irq[1]); 2047c8ebae37SRussell King 2048c8ebae37SRussell King mmci_dma_setup(host); 20491c6a0718SPierre Ossman 20502cd976c4SUlf Hansson pm_runtime_set_autosuspend_delay(&dev->dev, 50); 20512cd976c4SUlf Hansson pm_runtime_use_autosuspend(&dev->dev); 20521c3be369SRussell King 20538c11a94dSRussell King mmc_add_host(mmc); 20548c11a94dSRussell King 20556f2d3c89SUlf Hansson pm_runtime_put(&dev->dev); 20561c6a0718SPierre Ossman return 0; 20571c6a0718SPierre Ossman 20581c6a0718SPierre Ossman clk_disable: 2059ac940938SJulia Lawall clk_disable_unprepare(host->clk); 20601c6a0718SPierre Ossman host_free: 20611c6a0718SPierre Ossman mmc_free_host(mmc); 20621c6a0718SPierre Ossman return ret; 20631c6a0718SPierre Ossman } 20641c6a0718SPierre Ossman 20656e0ee714SBill Pemberton static int mmci_remove(struct amba_device *dev) 20661c6a0718SPierre Ossman { 20671c6a0718SPierre Ossman struct mmc_host *mmc = amba_get_drvdata(dev); 20681c6a0718SPierre Ossman 20691c6a0718SPierre Ossman if (mmc) { 20701c6a0718SPierre Ossman struct mmci_host *host = mmc_priv(mmc); 20716ea9cdf3SPatrice Chotard struct variant_data *variant = host->variant; 20721c6a0718SPierre Ossman 20731c3be369SRussell King /* 20741c3be369SRussell King * Undo pm_runtime_put() in probe. We use the _sync 20751c3be369SRussell King * version here so that we can access the primecell. 20761c3be369SRussell King */ 20771c3be369SRussell King pm_runtime_get_sync(&dev->dev); 20781c3be369SRussell King 20791c6a0718SPierre Ossman mmc_remove_host(mmc); 20801c6a0718SPierre Ossman 20811c6a0718SPierre Ossman writel(0, host->base + MMCIMASK0); 20826ea9cdf3SPatrice Chotard 20836ea9cdf3SPatrice Chotard if (variant->mmcimask1) 20841c6a0718SPierre Ossman writel(0, host->base + MMCIMASK1); 20851c6a0718SPierre Ossman 20861c6a0718SPierre Ossman writel(0, host->base + MMCICOMMAND); 20871c6a0718SPierre Ossman writel(0, host->base + MMCIDATACTRL); 20881c6a0718SPierre Ossman 2089c8ebae37SRussell King mmci_dma_release(host); 2090ac940938SJulia Lawall clk_disable_unprepare(host->clk); 20911c6a0718SPierre Ossman mmc_free_host(mmc); 20921c6a0718SPierre Ossman } 20931c6a0718SPierre Ossman 20941c6a0718SPierre Ossman return 0; 20951c6a0718SPierre Ossman } 20961c6a0718SPierre Ossman 2097571dce4fSUlf Hansson #ifdef CONFIG_PM 20981ff44433SUlf Hansson static void mmci_save(struct mmci_host *host) 20991ff44433SUlf Hansson { 21001ff44433SUlf Hansson unsigned long flags; 21011ff44433SUlf Hansson 21021ff44433SUlf Hansson spin_lock_irqsave(&host->lock, flags); 21031ff44433SUlf Hansson 21041ff44433SUlf Hansson writel(0, host->base + MMCIMASK0); 210542dcc89aSUlf Hansson if (host->variant->pwrreg_nopower) { 21061ff44433SUlf Hansson writel(0, host->base + MMCIDATACTRL); 21071ff44433SUlf Hansson writel(0, host->base + MMCIPOWER); 21081ff44433SUlf Hansson writel(0, host->base + MMCICLOCK); 210942dcc89aSUlf Hansson } 21101ff44433SUlf Hansson mmci_reg_delay(host); 21111ff44433SUlf Hansson 21121ff44433SUlf Hansson spin_unlock_irqrestore(&host->lock, flags); 21131ff44433SUlf Hansson } 21141ff44433SUlf Hansson 21151ff44433SUlf Hansson static void mmci_restore(struct mmci_host *host) 21161ff44433SUlf Hansson { 21171ff44433SUlf Hansson unsigned long flags; 21181ff44433SUlf Hansson 21191ff44433SUlf Hansson spin_lock_irqsave(&host->lock, flags); 21201ff44433SUlf Hansson 212142dcc89aSUlf Hansson if (host->variant->pwrreg_nopower) { 21221ff44433SUlf Hansson writel(host->clk_reg, host->base + MMCICLOCK); 21231ff44433SUlf Hansson writel(host->datactrl_reg, host->base + MMCIDATACTRL); 21241ff44433SUlf Hansson writel(host->pwr_reg, host->base + MMCIPOWER); 212542dcc89aSUlf Hansson } 2126daf9713cSLudovic Barre writel(MCI_IRQENABLE | host->variant->start_err, 2127daf9713cSLudovic Barre host->base + MMCIMASK0); 21281ff44433SUlf Hansson mmci_reg_delay(host); 21291ff44433SUlf Hansson 21301ff44433SUlf Hansson spin_unlock_irqrestore(&host->lock, flags); 21311ff44433SUlf Hansson } 21321ff44433SUlf Hansson 21338259293aSUlf Hansson static int mmci_runtime_suspend(struct device *dev) 21348259293aSUlf Hansson { 21358259293aSUlf Hansson struct amba_device *adev = to_amba_device(dev); 21368259293aSUlf Hansson struct mmc_host *mmc = amba_get_drvdata(adev); 21378259293aSUlf Hansson 21388259293aSUlf Hansson if (mmc) { 21398259293aSUlf Hansson struct mmci_host *host = mmc_priv(mmc); 2140e36bd9c6SUlf Hansson pinctrl_pm_select_sleep_state(dev); 21411ff44433SUlf Hansson mmci_save(host); 21428259293aSUlf Hansson clk_disable_unprepare(host->clk); 21438259293aSUlf Hansson } 21448259293aSUlf Hansson 21458259293aSUlf Hansson return 0; 21468259293aSUlf Hansson } 21478259293aSUlf Hansson 21488259293aSUlf Hansson static int mmci_runtime_resume(struct device *dev) 21498259293aSUlf Hansson { 21508259293aSUlf Hansson struct amba_device *adev = to_amba_device(dev); 21518259293aSUlf Hansson struct mmc_host *mmc = amba_get_drvdata(adev); 21528259293aSUlf Hansson 21538259293aSUlf Hansson if (mmc) { 21548259293aSUlf Hansson struct mmci_host *host = mmc_priv(mmc); 21558259293aSUlf Hansson clk_prepare_enable(host->clk); 21561ff44433SUlf Hansson mmci_restore(host); 2157e36bd9c6SUlf Hansson pinctrl_pm_select_default_state(dev); 21588259293aSUlf Hansson } 21598259293aSUlf Hansson 21608259293aSUlf Hansson return 0; 21618259293aSUlf Hansson } 21628259293aSUlf Hansson #endif 21638259293aSUlf Hansson 216448fa7003SUlf Hansson static const struct dev_pm_ops mmci_dev_pm_ops = { 2165f3737fa3SUlf Hansson SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, 2166f3737fa3SUlf Hansson pm_runtime_force_resume) 21676ed23b80SRafael J. Wysocki SET_RUNTIME_PM_OPS(mmci_runtime_suspend, mmci_runtime_resume, NULL) 216848fa7003SUlf Hansson }; 216948fa7003SUlf Hansson 217088411deaSArvind Yadav static const struct amba_id mmci_ids[] = { 21711c6a0718SPierre Ossman { 21721c6a0718SPierre Ossman .id = 0x00041180, 2173768fbc18SPawel Moll .mask = 0xff0fffff, 21744956e109SRabin Vincent .data = &variant_arm, 21751c6a0718SPierre Ossman }, 21761c6a0718SPierre Ossman { 2177768fbc18SPawel Moll .id = 0x01041180, 2178768fbc18SPawel Moll .mask = 0xff0fffff, 2179768fbc18SPawel Moll .data = &variant_arm_extended_fifo, 2180768fbc18SPawel Moll }, 2181768fbc18SPawel Moll { 21823a37298aSPawel Moll .id = 0x02041180, 21833a37298aSPawel Moll .mask = 0xff0fffff, 21843a37298aSPawel Moll .data = &variant_arm_extended_fifo_hwfc, 21853a37298aSPawel Moll }, 21863a37298aSPawel Moll { 21871c6a0718SPierre Ossman .id = 0x00041181, 21881c6a0718SPierre Ossman .mask = 0x000fffff, 21894956e109SRabin Vincent .data = &variant_arm, 21901c6a0718SPierre Ossman }, 2191cc30d60eSLinus Walleij /* ST Micro variants */ 2192cc30d60eSLinus Walleij { 2193cc30d60eSLinus Walleij .id = 0x00180180, 2194cc30d60eSLinus Walleij .mask = 0x00ffffff, 21954956e109SRabin Vincent .data = &variant_u300, 2196cc30d60eSLinus Walleij }, 2197cc30d60eSLinus Walleij { 219834fd4213SLinus Walleij .id = 0x10180180, 219934fd4213SLinus Walleij .mask = 0xf0ffffff, 220034fd4213SLinus Walleij .data = &variant_nomadik, 220134fd4213SLinus Walleij }, 220234fd4213SLinus Walleij { 2203cc30d60eSLinus Walleij .id = 0x00280180, 2204cc30d60eSLinus Walleij .mask = 0x00ffffff, 22050bcb7efdSLinus Walleij .data = &variant_nomadik, 22064956e109SRabin Vincent }, 22074956e109SRabin Vincent { 22084956e109SRabin Vincent .id = 0x00480180, 22091784b157SPhilippe Langlais .mask = 0xf0ffffff, 22104956e109SRabin Vincent .data = &variant_ux500, 2211cc30d60eSLinus Walleij }, 22121784b157SPhilippe Langlais { 22131784b157SPhilippe Langlais .id = 0x10480180, 22141784b157SPhilippe Langlais .mask = 0xf0ffffff, 22151784b157SPhilippe Langlais .data = &variant_ux500v2, 22161784b157SPhilippe Langlais }, 22172a9d6c80SPatrice Chotard { 22182a9d6c80SPatrice Chotard .id = 0x00880180, 22192a9d6c80SPatrice Chotard .mask = 0x00ffffff, 22202a9d6c80SPatrice Chotard .data = &variant_stm32, 22212a9d6c80SPatrice Chotard }, 222246b723ddSLudovic Barre { 222346b723ddSLudovic Barre .id = 0x10153180, 222446b723ddSLudovic Barre .mask = 0xf0ffffff, 222546b723ddSLudovic Barre .data = &variant_stm32_sdmmc, 222646b723ddSLudovic Barre }, 222755b604aeSSrinivas Kandagatla /* Qualcomm variants */ 222855b604aeSSrinivas Kandagatla { 222955b604aeSSrinivas Kandagatla .id = 0x00051180, 223055b604aeSSrinivas Kandagatla .mask = 0x000fffff, 223155b604aeSSrinivas Kandagatla .data = &variant_qcom, 223255b604aeSSrinivas Kandagatla }, 22331c6a0718SPierre Ossman { 0, 0 }, 22341c6a0718SPierre Ossman }; 22351c6a0718SPierre Ossman 22369f99835fSDave Martin MODULE_DEVICE_TABLE(amba, mmci_ids); 22379f99835fSDave Martin 22381c6a0718SPierre Ossman static struct amba_driver mmci_driver = { 22391c6a0718SPierre Ossman .drv = { 22401c6a0718SPierre Ossman .name = DRIVER_NAME, 224148fa7003SUlf Hansson .pm = &mmci_dev_pm_ops, 22421c6a0718SPierre Ossman }, 22431c6a0718SPierre Ossman .probe = mmci_probe, 22440433c143SBill Pemberton .remove = mmci_remove, 22451c6a0718SPierre Ossman .id_table = mmci_ids, 22461c6a0718SPierre Ossman }; 22471c6a0718SPierre Ossman 22489e5ed094Sviresh kumar module_amba_driver(mmci_driver); 22491c6a0718SPierre Ossman 22501c6a0718SPierre Ossman module_param(fmax, uint, 0444); 22511c6a0718SPierre Ossman 22521c6a0718SPierre Ossman MODULE_DESCRIPTION("ARM PrimeCell PL180/181 Multimedia Card Interface driver"); 22531c6a0718SPierre Ossman MODULE_LICENSE("GPL"); 2254