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> 2470be208fSUlf Hansson #include <linux/mmc/pm.h> 251c6a0718SPierre Ossman #include <linux/mmc/host.h> 2634177802SLinus Walleij #include <linux/mmc/card.h> 27d2762090SUlf Hansson #include <linux/mmc/slot-gpio.h> 281c6a0718SPierre Ossman #include <linux/amba/bus.h> 291c6a0718SPierre Ossman #include <linux/clk.h> 30bd6dee6fSJens Axboe #include <linux/scatterlist.h> 319ef986a6SLinus Walleij #include <linux/of.h> 3234e84f39SLinus Walleij #include <linux/regulator/consumer.h> 33c8ebae37SRussell King #include <linux/dmaengine.h> 34c8ebae37SRussell King #include <linux/dma-mapping.h> 35c8ebae37SRussell King #include <linux/amba/mmci.h> 361c3be369SRussell King #include <linux/pm_runtime.h> 37258aea76SViresh Kumar #include <linux/types.h> 38a9a83785SLinus Walleij #include <linux/pinctrl/consumer.h> 391c6a0718SPierre Ossman 401c6a0718SPierre Ossman #include <asm/div64.h> 411c6a0718SPierre Ossman #include <asm/io.h> 421c6a0718SPierre Ossman 431c6a0718SPierre Ossman #include "mmci.h" 449cb15142SSrinivas Kandagatla #include "mmci_qcom_dml.h" 451c6a0718SPierre Ossman 461c6a0718SPierre Ossman #define DRIVER_NAME "mmci-pl18x" 471c6a0718SPierre Ossman 48c3647fdcSLudovic Barre #ifdef CONFIG_DMA_ENGINE 49c3647fdcSLudovic Barre void mmci_variant_init(struct mmci_host *host); 50c3647fdcSLudovic Barre #else 51c3647fdcSLudovic Barre static inline void mmci_variant_init(struct mmci_host *host) {} 52c3647fdcSLudovic Barre #endif 53c3647fdcSLudovic Barre 541c6a0718SPierre Ossman static unsigned int fmax = 515633; 551c6a0718SPierre Ossman 564956e109SRabin Vincent static struct variant_data variant_arm = { 578301bb68SRabin Vincent .fifosize = 16 * 4, 588301bb68SRabin Vincent .fifohalfsize = 8 * 4, 590f244804SLudovic Barre .cmdreg_cpsm_enable = MCI_CPSM_ENABLE, 600f244804SLudovic Barre .cmdreg_lrsp_crc = MCI_CPSM_RESPONSE | MCI_CPSM_LONGRSP, 610f244804SLudovic Barre .cmdreg_srsp_crc = MCI_CPSM_RESPONSE, 620f244804SLudovic Barre .cmdreg_srsp = MCI_CPSM_RESPONSE, 6308458ef6SRabin Vincent .datalength_bits = 16, 64c931d495SLudovic Barre .datactrl_blocksz = 11, 659b279941SLudovic Barre .datactrl_dpsm_enable = MCI_DPSM_ENABLE, 667d72a1d4SUlf Hansson .pwrreg_powerup = MCI_PWR_UP, 67dc6500bfSSrinivas Kandagatla .f_max = 100000000, 687878289bSUlf Hansson .reversed_irq_handling = true, 696ea9cdf3SPatrice Chotard .mmcimask1 = true, 7059db5e2dSLudovic Barre .irq_pio_mask = MCI_IRQ_PIO_MASK, 717f7b5503SPatrice Chotard .start_err = MCI_STARTBITERR, 7211dfb970SPatrice Chotard .opendrain = MCI_ROD, 73c3647fdcSLudovic Barre .init = mmci_variant_init, 744956e109SRabin Vincent }; 754956e109SRabin Vincent 76768fbc18SPawel Moll static struct variant_data variant_arm_extended_fifo = { 77768fbc18SPawel Moll .fifosize = 128 * 4, 78768fbc18SPawel Moll .fifohalfsize = 64 * 4, 790f244804SLudovic Barre .cmdreg_cpsm_enable = MCI_CPSM_ENABLE, 800f244804SLudovic Barre .cmdreg_lrsp_crc = MCI_CPSM_RESPONSE | MCI_CPSM_LONGRSP, 810f244804SLudovic Barre .cmdreg_srsp_crc = MCI_CPSM_RESPONSE, 820f244804SLudovic Barre .cmdreg_srsp = MCI_CPSM_RESPONSE, 83768fbc18SPawel Moll .datalength_bits = 16, 84c931d495SLudovic Barre .datactrl_blocksz = 11, 859b279941SLudovic Barre .datactrl_dpsm_enable = MCI_DPSM_ENABLE, 867d72a1d4SUlf Hansson .pwrreg_powerup = MCI_PWR_UP, 87dc6500bfSSrinivas Kandagatla .f_max = 100000000, 886ea9cdf3SPatrice Chotard .mmcimask1 = true, 8959db5e2dSLudovic Barre .irq_pio_mask = MCI_IRQ_PIO_MASK, 907f7b5503SPatrice Chotard .start_err = MCI_STARTBITERR, 9111dfb970SPatrice Chotard .opendrain = MCI_ROD, 92c3647fdcSLudovic Barre .init = mmci_variant_init, 93768fbc18SPawel Moll }; 94768fbc18SPawel Moll 953a37298aSPawel Moll static struct variant_data variant_arm_extended_fifo_hwfc = { 963a37298aSPawel Moll .fifosize = 128 * 4, 973a37298aSPawel Moll .fifohalfsize = 64 * 4, 983a37298aSPawel Moll .clkreg_enable = MCI_ARM_HWFCEN, 990f244804SLudovic Barre .cmdreg_cpsm_enable = MCI_CPSM_ENABLE, 1000f244804SLudovic Barre .cmdreg_lrsp_crc = MCI_CPSM_RESPONSE | MCI_CPSM_LONGRSP, 1010f244804SLudovic Barre .cmdreg_srsp_crc = MCI_CPSM_RESPONSE, 1020f244804SLudovic Barre .cmdreg_srsp = MCI_CPSM_RESPONSE, 1033a37298aSPawel Moll .datalength_bits = 16, 104c931d495SLudovic Barre .datactrl_blocksz = 11, 1059b279941SLudovic Barre .datactrl_dpsm_enable = MCI_DPSM_ENABLE, 1063a37298aSPawel Moll .pwrreg_powerup = MCI_PWR_UP, 107dc6500bfSSrinivas Kandagatla .f_max = 100000000, 1086ea9cdf3SPatrice Chotard .mmcimask1 = true, 10959db5e2dSLudovic Barre .irq_pio_mask = MCI_IRQ_PIO_MASK, 1107f7b5503SPatrice Chotard .start_err = MCI_STARTBITERR, 11111dfb970SPatrice Chotard .opendrain = MCI_ROD, 112c3647fdcSLudovic Barre .init = mmci_variant_init, 1133a37298aSPawel Moll }; 1143a37298aSPawel Moll 1154956e109SRabin Vincent static struct variant_data variant_u300 = { 1168301bb68SRabin Vincent .fifosize = 16 * 4, 1178301bb68SRabin Vincent .fifohalfsize = 8 * 4, 11849ac215eSLinus Walleij .clkreg_enable = MCI_ST_U300_HWFCEN, 119e1412d85SSrinivas Kandagatla .clkreg_8bit_bus_enable = MCI_ST_8BIT_BUS, 1200f244804SLudovic Barre .cmdreg_cpsm_enable = MCI_CPSM_ENABLE, 1210f244804SLudovic Barre .cmdreg_lrsp_crc = MCI_CPSM_RESPONSE | MCI_CPSM_LONGRSP, 1220f244804SLudovic Barre .cmdreg_srsp_crc = MCI_CPSM_RESPONSE, 1230f244804SLudovic Barre .cmdreg_srsp = MCI_CPSM_RESPONSE, 12408458ef6SRabin Vincent .datalength_bits = 16, 125c931d495SLudovic Barre .datactrl_blocksz = 11, 1269b279941SLudovic Barre .datactrl_dpsm_enable = MCI_DPSM_ENABLE, 1275db3eee7SLinus Walleij .datactrl_mask_sdio = MCI_DPSM_ST_SDIOEN, 128c7354133SSrinivas Kandagatla .st_sdio = true, 1297d72a1d4SUlf Hansson .pwrreg_powerup = MCI_PWR_ON, 130dc6500bfSSrinivas Kandagatla .f_max = 100000000, 1314d1a3a0dSUlf Hansson .signal_direction = true, 132f4670daeSUlf Hansson .pwrreg_clkgate = true, 1331ff44433SUlf Hansson .pwrreg_nopower = true, 1346ea9cdf3SPatrice Chotard .mmcimask1 = true, 13559db5e2dSLudovic Barre .irq_pio_mask = MCI_IRQ_PIO_MASK, 1367f7b5503SPatrice Chotard .start_err = MCI_STARTBITERR, 13711dfb970SPatrice Chotard .opendrain = MCI_OD, 138c3647fdcSLudovic Barre .init = mmci_variant_init, 1394956e109SRabin Vincent }; 1404956e109SRabin Vincent 14134fd4213SLinus Walleij static struct variant_data variant_nomadik = { 14234fd4213SLinus Walleij .fifosize = 16 * 4, 14334fd4213SLinus Walleij .fifohalfsize = 8 * 4, 14434fd4213SLinus Walleij .clkreg = MCI_CLK_ENABLE, 145f5abc767SLinus Walleij .clkreg_8bit_bus_enable = MCI_ST_8BIT_BUS, 1460f244804SLudovic Barre .cmdreg_cpsm_enable = MCI_CPSM_ENABLE, 1470f244804SLudovic Barre .cmdreg_lrsp_crc = MCI_CPSM_RESPONSE | MCI_CPSM_LONGRSP, 1480f244804SLudovic Barre .cmdreg_srsp_crc = MCI_CPSM_RESPONSE, 1490f244804SLudovic Barre .cmdreg_srsp = MCI_CPSM_RESPONSE, 15034fd4213SLinus Walleij .datalength_bits = 24, 151c931d495SLudovic Barre .datactrl_blocksz = 11, 1529b279941SLudovic Barre .datactrl_dpsm_enable = MCI_DPSM_ENABLE, 1535db3eee7SLinus Walleij .datactrl_mask_sdio = MCI_DPSM_ST_SDIOEN, 154c7354133SSrinivas Kandagatla .st_sdio = true, 15534fd4213SLinus Walleij .st_clkdiv = true, 15634fd4213SLinus Walleij .pwrreg_powerup = MCI_PWR_ON, 157dc6500bfSSrinivas Kandagatla .f_max = 100000000, 15834fd4213SLinus Walleij .signal_direction = true, 159f4670daeSUlf Hansson .pwrreg_clkgate = true, 1601ff44433SUlf Hansson .pwrreg_nopower = true, 1616ea9cdf3SPatrice Chotard .mmcimask1 = true, 16259db5e2dSLudovic Barre .irq_pio_mask = MCI_IRQ_PIO_MASK, 1637f7b5503SPatrice Chotard .start_err = MCI_STARTBITERR, 16411dfb970SPatrice Chotard .opendrain = MCI_OD, 165c3647fdcSLudovic Barre .init = mmci_variant_init, 16634fd4213SLinus Walleij }; 16734fd4213SLinus Walleij 1684956e109SRabin Vincent static struct variant_data variant_ux500 = { 1698301bb68SRabin Vincent .fifosize = 30 * 4, 1708301bb68SRabin Vincent .fifohalfsize = 8 * 4, 1714956e109SRabin Vincent .clkreg = MCI_CLK_ENABLE, 17249ac215eSLinus Walleij .clkreg_enable = MCI_ST_UX500_HWFCEN, 173e1412d85SSrinivas Kandagatla .clkreg_8bit_bus_enable = MCI_ST_8BIT_BUS, 174e8740644SSrinivas Kandagatla .clkreg_neg_edge_enable = MCI_ST_UX500_NEG_EDGE, 1750f244804SLudovic Barre .cmdreg_cpsm_enable = MCI_CPSM_ENABLE, 1760f244804SLudovic Barre .cmdreg_lrsp_crc = MCI_CPSM_RESPONSE | MCI_CPSM_LONGRSP, 1770f244804SLudovic Barre .cmdreg_srsp_crc = MCI_CPSM_RESPONSE, 1780f244804SLudovic Barre .cmdreg_srsp = MCI_CPSM_RESPONSE, 17908458ef6SRabin Vincent .datalength_bits = 24, 180c931d495SLudovic Barre .datactrl_blocksz = 11, 1819b279941SLudovic Barre .datactrl_dpsm_enable = MCI_DPSM_ENABLE, 1825db3eee7SLinus Walleij .datactrl_mask_sdio = MCI_DPSM_ST_SDIOEN, 183c7354133SSrinivas Kandagatla .st_sdio = true, 184b70a67f9SLinus Walleij .st_clkdiv = true, 1857d72a1d4SUlf Hansson .pwrreg_powerup = MCI_PWR_ON, 186dc6500bfSSrinivas Kandagatla .f_max = 100000000, 1874d1a3a0dSUlf Hansson .signal_direction = true, 188f4670daeSUlf Hansson .pwrreg_clkgate = true, 18901259620SUlf Hansson .busy_detect = true, 19049adc0caSLinus Walleij .busy_dpsm_flag = MCI_DPSM_ST_BUSYMODE, 19149adc0caSLinus Walleij .busy_detect_flag = MCI_ST_CARDBUSY, 19249adc0caSLinus Walleij .busy_detect_mask = MCI_ST_BUSYENDMASK, 1931ff44433SUlf Hansson .pwrreg_nopower = true, 1946ea9cdf3SPatrice Chotard .mmcimask1 = true, 19559db5e2dSLudovic Barre .irq_pio_mask = MCI_IRQ_PIO_MASK, 1967f7b5503SPatrice Chotard .start_err = MCI_STARTBITERR, 19711dfb970SPatrice Chotard .opendrain = MCI_OD, 198c3647fdcSLudovic Barre .init = mmci_variant_init, 1994956e109SRabin Vincent }; 200b70a67f9SLinus Walleij 2011784b157SPhilippe Langlais static struct variant_data variant_ux500v2 = { 2021784b157SPhilippe Langlais .fifosize = 30 * 4, 2031784b157SPhilippe Langlais .fifohalfsize = 8 * 4, 2041784b157SPhilippe Langlais .clkreg = MCI_CLK_ENABLE, 2051784b157SPhilippe Langlais .clkreg_enable = MCI_ST_UX500_HWFCEN, 206e1412d85SSrinivas Kandagatla .clkreg_8bit_bus_enable = MCI_ST_8BIT_BUS, 207e8740644SSrinivas Kandagatla .clkreg_neg_edge_enable = MCI_ST_UX500_NEG_EDGE, 2080f244804SLudovic Barre .cmdreg_cpsm_enable = MCI_CPSM_ENABLE, 2090f244804SLudovic Barre .cmdreg_lrsp_crc = MCI_CPSM_RESPONSE | MCI_CPSM_LONGRSP, 2100f244804SLudovic Barre .cmdreg_srsp_crc = MCI_CPSM_RESPONSE, 2110f244804SLudovic Barre .cmdreg_srsp = MCI_CPSM_RESPONSE, 2125db3eee7SLinus Walleij .datactrl_mask_ddrmode = MCI_DPSM_ST_DDRMODE, 2131784b157SPhilippe Langlais .datalength_bits = 24, 214c931d495SLudovic Barre .datactrl_blocksz = 11, 2159b279941SLudovic Barre .datactrl_dpsm_enable = MCI_DPSM_ENABLE, 2165db3eee7SLinus Walleij .datactrl_mask_sdio = MCI_DPSM_ST_SDIOEN, 217c7354133SSrinivas Kandagatla .st_sdio = true, 2181784b157SPhilippe Langlais .st_clkdiv = true, 2191784b157SPhilippe Langlais .blksz_datactrl16 = true, 2207d72a1d4SUlf Hansson .pwrreg_powerup = MCI_PWR_ON, 221dc6500bfSSrinivas Kandagatla .f_max = 100000000, 2224d1a3a0dSUlf Hansson .signal_direction = true, 223f4670daeSUlf Hansson .pwrreg_clkgate = true, 22401259620SUlf Hansson .busy_detect = true, 22549adc0caSLinus Walleij .busy_dpsm_flag = MCI_DPSM_ST_BUSYMODE, 22649adc0caSLinus Walleij .busy_detect_flag = MCI_ST_CARDBUSY, 22749adc0caSLinus Walleij .busy_detect_mask = MCI_ST_BUSYENDMASK, 2281ff44433SUlf Hansson .pwrreg_nopower = true, 2296ea9cdf3SPatrice Chotard .mmcimask1 = true, 23059db5e2dSLudovic Barre .irq_pio_mask = MCI_IRQ_PIO_MASK, 2317f7b5503SPatrice Chotard .start_err = MCI_STARTBITERR, 23211dfb970SPatrice Chotard .opendrain = MCI_OD, 233c3647fdcSLudovic Barre .init = mmci_variant_init, 2341784b157SPhilippe Langlais }; 2351784b157SPhilippe Langlais 2362a9d6c80SPatrice Chotard static struct variant_data variant_stm32 = { 2372a9d6c80SPatrice Chotard .fifosize = 32 * 4, 2382a9d6c80SPatrice Chotard .fifohalfsize = 8 * 4, 2392a9d6c80SPatrice Chotard .clkreg = MCI_CLK_ENABLE, 2402a9d6c80SPatrice Chotard .clkreg_enable = MCI_ST_UX500_HWFCEN, 2412a9d6c80SPatrice Chotard .clkreg_8bit_bus_enable = MCI_ST_8BIT_BUS, 2422a9d6c80SPatrice Chotard .clkreg_neg_edge_enable = MCI_ST_UX500_NEG_EDGE, 2430f244804SLudovic Barre .cmdreg_cpsm_enable = MCI_CPSM_ENABLE, 2440f244804SLudovic Barre .cmdreg_lrsp_crc = MCI_CPSM_RESPONSE | MCI_CPSM_LONGRSP, 2450f244804SLudovic Barre .cmdreg_srsp_crc = MCI_CPSM_RESPONSE, 2460f244804SLudovic Barre .cmdreg_srsp = MCI_CPSM_RESPONSE, 24759db5e2dSLudovic Barre .irq_pio_mask = MCI_IRQ_PIO_MASK, 2482a9d6c80SPatrice Chotard .datalength_bits = 24, 249c931d495SLudovic Barre .datactrl_blocksz = 11, 2509b279941SLudovic Barre .datactrl_dpsm_enable = MCI_DPSM_ENABLE, 2512a9d6c80SPatrice Chotard .datactrl_mask_sdio = MCI_DPSM_ST_SDIOEN, 2522a9d6c80SPatrice Chotard .st_sdio = true, 2532a9d6c80SPatrice Chotard .st_clkdiv = true, 2542a9d6c80SPatrice Chotard .pwrreg_powerup = MCI_PWR_ON, 2552a9d6c80SPatrice Chotard .f_max = 48000000, 2562a9d6c80SPatrice Chotard .pwrreg_clkgate = true, 2572a9d6c80SPatrice Chotard .pwrreg_nopower = true, 258c3647fdcSLudovic Barre .init = mmci_variant_init, 2592a9d6c80SPatrice Chotard }; 2602a9d6c80SPatrice Chotard 26155b604aeSSrinivas Kandagatla static struct variant_data variant_qcom = { 26255b604aeSSrinivas Kandagatla .fifosize = 16 * 4, 26355b604aeSSrinivas Kandagatla .fifohalfsize = 8 * 4, 26455b604aeSSrinivas Kandagatla .clkreg = MCI_CLK_ENABLE, 26555b604aeSSrinivas Kandagatla .clkreg_enable = MCI_QCOM_CLK_FLOWENA | 26655b604aeSSrinivas Kandagatla MCI_QCOM_CLK_SELECT_IN_FBCLK, 26755b604aeSSrinivas Kandagatla .clkreg_8bit_bus_enable = MCI_QCOM_CLK_WIDEBUS_8, 26855b604aeSSrinivas Kandagatla .datactrl_mask_ddrmode = MCI_QCOM_CLK_SELECT_IN_DDR_MODE, 2690f244804SLudovic Barre .cmdreg_cpsm_enable = MCI_CPSM_ENABLE, 2700f244804SLudovic Barre .cmdreg_lrsp_crc = MCI_CPSM_RESPONSE | MCI_CPSM_LONGRSP, 2710f244804SLudovic Barre .cmdreg_srsp_crc = MCI_CPSM_RESPONSE, 2720f244804SLudovic Barre .cmdreg_srsp = MCI_CPSM_RESPONSE, 2735db3eee7SLinus Walleij .data_cmd_enable = MCI_CPSM_QCOM_DATCMD, 27455b604aeSSrinivas Kandagatla .blksz_datactrl4 = true, 27555b604aeSSrinivas Kandagatla .datalength_bits = 24, 276c931d495SLudovic Barre .datactrl_blocksz = 11, 2779b279941SLudovic Barre .datactrl_dpsm_enable = MCI_DPSM_ENABLE, 27855b604aeSSrinivas Kandagatla .pwrreg_powerup = MCI_PWR_UP, 27955b604aeSSrinivas Kandagatla .f_max = 208000000, 28055b604aeSSrinivas Kandagatla .explicit_mclk_control = true, 28155b604aeSSrinivas Kandagatla .qcom_fifo = true, 2829cb15142SSrinivas Kandagatla .qcom_dml = true, 2836ea9cdf3SPatrice Chotard .mmcimask1 = true, 28459db5e2dSLudovic Barre .irq_pio_mask = MCI_IRQ_PIO_MASK, 2857f7b5503SPatrice Chotard .start_err = MCI_STARTBITERR, 28611dfb970SPatrice Chotard .opendrain = MCI_ROD, 28729aba07aSUlf Hansson .init = qcom_variant_init, 28855b604aeSSrinivas Kandagatla }; 28955b604aeSSrinivas Kandagatla 29049adc0caSLinus Walleij /* Busy detection for the ST Micro variant */ 29101259620SUlf Hansson static int mmci_card_busy(struct mmc_host *mmc) 29201259620SUlf Hansson { 29301259620SUlf Hansson struct mmci_host *host = mmc_priv(mmc); 29401259620SUlf Hansson unsigned long flags; 29501259620SUlf Hansson int busy = 0; 29601259620SUlf Hansson 29701259620SUlf Hansson spin_lock_irqsave(&host->lock, flags); 29849adc0caSLinus Walleij if (readl(host->base + MMCISTATUS) & host->variant->busy_detect_flag) 29901259620SUlf Hansson busy = 1; 30001259620SUlf Hansson spin_unlock_irqrestore(&host->lock, flags); 30101259620SUlf Hansson 30201259620SUlf Hansson return busy; 30301259620SUlf Hansson } 30401259620SUlf Hansson 305f829c042SUlf Hansson static void mmci_reg_delay(struct mmci_host *host) 306f829c042SUlf Hansson { 307f829c042SUlf Hansson /* 308f829c042SUlf Hansson * According to the spec, at least three feedback clock cycles 309f829c042SUlf Hansson * of max 52 MHz must pass between two writes to the MMCICLOCK reg. 310f829c042SUlf Hansson * Three MCLK clock cycles must pass between two MMCIPOWER reg writes. 311f829c042SUlf Hansson * Worst delay time during card init is at 100 kHz => 30 us. 312f829c042SUlf Hansson * Worst delay time when up and running is at 25 MHz => 120 ns. 313f829c042SUlf Hansson */ 314f829c042SUlf Hansson if (host->cclk < 25000000) 315f829c042SUlf Hansson udelay(30); 316f829c042SUlf Hansson else 317f829c042SUlf Hansson ndelay(120); 318f829c042SUlf Hansson } 319f829c042SUlf Hansson 320653a761eSUlf Hansson /* 321a6a6464aSLinus Walleij * This must be called with host->lock held 322a6a6464aSLinus Walleij */ 323cd3ee8c5SLudovic Barre void mmci_write_clkreg(struct mmci_host *host, u32 clk) 3247437cfa5SUlf Hansson { 3257437cfa5SUlf Hansson if (host->clk_reg != clk) { 3267437cfa5SUlf Hansson host->clk_reg = clk; 3277437cfa5SUlf Hansson writel(clk, host->base + MMCICLOCK); 3287437cfa5SUlf Hansson } 3297437cfa5SUlf Hansson } 3307437cfa5SUlf Hansson 3317437cfa5SUlf Hansson /* 3327437cfa5SUlf Hansson * This must be called with host->lock held 3337437cfa5SUlf Hansson */ 334cd3ee8c5SLudovic Barre void mmci_write_pwrreg(struct mmci_host *host, u32 pwr) 3357437cfa5SUlf Hansson { 3367437cfa5SUlf Hansson if (host->pwr_reg != pwr) { 3377437cfa5SUlf Hansson host->pwr_reg = pwr; 3387437cfa5SUlf Hansson writel(pwr, host->base + MMCIPOWER); 3397437cfa5SUlf Hansson } 3407437cfa5SUlf Hansson } 3417437cfa5SUlf Hansson 3427437cfa5SUlf Hansson /* 3437437cfa5SUlf Hansson * This must be called with host->lock held 3447437cfa5SUlf Hansson */ 3459cc639a2SUlf Hansson static void mmci_write_datactrlreg(struct mmci_host *host, u32 datactrl) 3469cc639a2SUlf Hansson { 34749adc0caSLinus Walleij /* Keep busy mode in DPSM if enabled */ 34849adc0caSLinus Walleij datactrl |= host->datactrl_reg & host->variant->busy_dpsm_flag; 34901259620SUlf Hansson 3509cc639a2SUlf Hansson if (host->datactrl_reg != datactrl) { 3519cc639a2SUlf Hansson host->datactrl_reg = datactrl; 3529cc639a2SUlf Hansson writel(datactrl, host->base + MMCIDATACTRL); 3539cc639a2SUlf Hansson } 3549cc639a2SUlf Hansson } 3559cc639a2SUlf Hansson 3569cc639a2SUlf Hansson /* 3579cc639a2SUlf Hansson * This must be called with host->lock held 3589cc639a2SUlf Hansson */ 359a6a6464aSLinus Walleij static void mmci_set_clkreg(struct mmci_host *host, unsigned int desired) 360a6a6464aSLinus Walleij { 3614956e109SRabin Vincent struct variant_data *variant = host->variant; 3624956e109SRabin Vincent u32 clk = variant->clkreg; 363a6a6464aSLinus Walleij 364c58a8509SUlf Hansson /* Make sure cclk reflects the current calculated clock */ 365c58a8509SUlf Hansson host->cclk = 0; 366c58a8509SUlf Hansson 367a6a6464aSLinus Walleij if (desired) { 3683f4e6f7bSSrinivas Kandagatla if (variant->explicit_mclk_control) { 3693f4e6f7bSSrinivas Kandagatla host->cclk = host->mclk; 3703f4e6f7bSSrinivas Kandagatla } else if (desired >= host->mclk) { 371a6a6464aSLinus Walleij clk = MCI_CLK_BYPASS; 372399bc486SLinus Walleij if (variant->st_clkdiv) 373399bc486SLinus Walleij clk |= MCI_ST_UX500_NEG_EDGE; 374a6a6464aSLinus Walleij host->cclk = host->mclk; 375b70a67f9SLinus Walleij } else if (variant->st_clkdiv) { 376b70a67f9SLinus Walleij /* 377b70a67f9SLinus Walleij * DB8500 TRM says f = mclk / (clkdiv + 2) 378b70a67f9SLinus Walleij * => clkdiv = (mclk / f) - 2 379b70a67f9SLinus Walleij * Round the divider up so we don't exceed the max 380b70a67f9SLinus Walleij * frequency 381b70a67f9SLinus Walleij */ 382b70a67f9SLinus Walleij clk = DIV_ROUND_UP(host->mclk, desired) - 2; 383b70a67f9SLinus Walleij if (clk >= 256) 384b70a67f9SLinus Walleij clk = 255; 385b70a67f9SLinus Walleij host->cclk = host->mclk / (clk + 2); 386a6a6464aSLinus Walleij } else { 387b70a67f9SLinus Walleij /* 388b70a67f9SLinus Walleij * PL180 TRM says f = mclk / (2 * (clkdiv + 1)) 389b70a67f9SLinus Walleij * => clkdiv = mclk / (2 * f) - 1 390b70a67f9SLinus Walleij */ 391a6a6464aSLinus Walleij clk = host->mclk / (2 * desired) - 1; 392a6a6464aSLinus Walleij if (clk >= 256) 393a6a6464aSLinus Walleij clk = 255; 394a6a6464aSLinus Walleij host->cclk = host->mclk / (2 * (clk + 1)); 395a6a6464aSLinus Walleij } 3964380c14fSRabin Vincent 3974380c14fSRabin Vincent clk |= variant->clkreg_enable; 398a6a6464aSLinus Walleij clk |= MCI_CLK_ENABLE; 399a6a6464aSLinus Walleij /* This hasn't proven to be worthwhile */ 400a6a6464aSLinus Walleij /* clk |= MCI_CLK_PWRSAVE; */ 401a6a6464aSLinus Walleij } 402a6a6464aSLinus Walleij 403c58a8509SUlf Hansson /* Set actual clock for debug */ 404c58a8509SUlf Hansson host->mmc->actual_clock = host->cclk; 405c58a8509SUlf Hansson 4069e6c82cdSLinus Walleij if (host->mmc->ios.bus_width == MMC_BUS_WIDTH_4) 407771dc157SLinus Walleij clk |= MCI_4BIT_BUS; 408771dc157SLinus Walleij if (host->mmc->ios.bus_width == MMC_BUS_WIDTH_8) 409e1412d85SSrinivas Kandagatla clk |= variant->clkreg_8bit_bus_enable; 4109e6c82cdSLinus Walleij 4116dad6c95SSeungwon Jeon if (host->mmc->ios.timing == MMC_TIMING_UHS_DDR50 || 4126dad6c95SSeungwon Jeon host->mmc->ios.timing == MMC_TIMING_MMC_DDR52) 413e8740644SSrinivas Kandagatla clk |= variant->clkreg_neg_edge_enable; 4146dbb6ee0SUlf Hansson 4157437cfa5SUlf Hansson mmci_write_clkreg(host, clk); 416a6a6464aSLinus Walleij } 417a6a6464aSLinus Walleij 418c3647fdcSLudovic Barre void mmci_dma_release(struct mmci_host *host) 419c3647fdcSLudovic Barre { 420c3647fdcSLudovic Barre if (host->ops && host->ops->dma_release) 421c3647fdcSLudovic Barre host->ops->dma_release(host); 422c3647fdcSLudovic Barre 423c3647fdcSLudovic Barre host->use_dma = false; 424c3647fdcSLudovic Barre } 425c3647fdcSLudovic Barre 426c3647fdcSLudovic Barre void mmci_dma_setup(struct mmci_host *host) 427c3647fdcSLudovic Barre { 428c3647fdcSLudovic Barre if (!host->ops || !host->ops->dma_setup) 429c3647fdcSLudovic Barre return; 430c3647fdcSLudovic Barre 431c3647fdcSLudovic Barre if (host->ops->dma_setup(host)) 432c3647fdcSLudovic Barre return; 433c3647fdcSLudovic Barre 434a813f2a2SLudovic Barre /* initialize pre request cookie */ 435a813f2a2SLudovic Barre host->next_cookie = 1; 436a813f2a2SLudovic Barre 437c3647fdcSLudovic Barre host->use_dma = true; 438c3647fdcSLudovic Barre } 439c3647fdcSLudovic Barre 440e0da1721SLudovic Barre /* 441e0da1721SLudovic Barre * Validate mmc prerequisites 442e0da1721SLudovic Barre */ 443e0da1721SLudovic Barre static int mmci_validate_data(struct mmci_host *host, 444e0da1721SLudovic Barre struct mmc_data *data) 445e0da1721SLudovic Barre { 446e0da1721SLudovic Barre if (!data) 447e0da1721SLudovic Barre return 0; 448e0da1721SLudovic Barre 449e0da1721SLudovic Barre if (!is_power_of_2(data->blksz)) { 450e0da1721SLudovic Barre dev_err(mmc_dev(host->mmc), 451e0da1721SLudovic Barre "unsupported block size (%d bytes)\n", data->blksz); 452e0da1721SLudovic Barre return -EINVAL; 453e0da1721SLudovic Barre } 454e0da1721SLudovic Barre 455e0da1721SLudovic Barre if (host->ops && host->ops->validate_data) 456e0da1721SLudovic Barre return host->ops->validate_data(host, data); 457e0da1721SLudovic Barre 458e0da1721SLudovic Barre return 0; 459e0da1721SLudovic Barre } 460e0da1721SLudovic Barre 46147983510SLudovic Barre int mmci_prep_data(struct mmci_host *host, struct mmc_data *data, bool next) 46247983510SLudovic Barre { 46347983510SLudovic Barre int err; 46447983510SLudovic Barre 46547983510SLudovic Barre if (!host->ops || !host->ops->prep_data) 46647983510SLudovic Barre return 0; 46747983510SLudovic Barre 46847983510SLudovic Barre err = host->ops->prep_data(host, data, next); 46947983510SLudovic Barre 47047983510SLudovic Barre if (next && !err) 47147983510SLudovic Barre data->host_cookie = ++host->next_cookie < 0 ? 47247983510SLudovic Barre 1 : host->next_cookie; 47347983510SLudovic Barre 47447983510SLudovic Barre return err; 47547983510SLudovic Barre } 47647983510SLudovic Barre 47747983510SLudovic Barre void mmci_unprep_data(struct mmci_host *host, struct mmc_data *data, 47847983510SLudovic Barre int err) 47947983510SLudovic Barre { 48047983510SLudovic Barre if (host->ops && host->ops->unprep_data) 48147983510SLudovic Barre host->ops->unprep_data(host, data, err); 48247983510SLudovic Barre 48347983510SLudovic Barre data->host_cookie = 0; 48447983510SLudovic Barre } 48547983510SLudovic Barre 48602769968SLudovic Barre void mmci_get_next_data(struct mmci_host *host, struct mmc_data *data) 48702769968SLudovic Barre { 48802769968SLudovic Barre WARN_ON(data->host_cookie && data->host_cookie != host->next_cookie); 48902769968SLudovic Barre 49002769968SLudovic Barre if (host->ops && host->ops->get_next_data) 49102769968SLudovic Barre host->ops->get_next_data(host, data); 49202769968SLudovic Barre } 49302769968SLudovic Barre 494135ea30eSLudovic Barre int mmci_dma_start(struct mmci_host *host, unsigned int datactrl) 495135ea30eSLudovic Barre { 496135ea30eSLudovic Barre struct mmc_data *data = host->data; 497135ea30eSLudovic Barre int ret; 498135ea30eSLudovic Barre 499135ea30eSLudovic Barre if (!host->use_dma) 500135ea30eSLudovic Barre return -EINVAL; 501135ea30eSLudovic Barre 502135ea30eSLudovic Barre ret = mmci_prep_data(host, data, false); 503135ea30eSLudovic Barre if (ret) 504135ea30eSLudovic Barre return ret; 505135ea30eSLudovic Barre 506135ea30eSLudovic Barre if (!host->ops || !host->ops->dma_start) 507135ea30eSLudovic Barre return -EINVAL; 508135ea30eSLudovic Barre 509135ea30eSLudovic Barre /* Okay, go for it. */ 510135ea30eSLudovic Barre dev_vdbg(mmc_dev(host->mmc), 511135ea30eSLudovic Barre "Submit MMCI DMA job, sglen %d blksz %04x blks %04x flags %08x\n", 512135ea30eSLudovic Barre data->sg_len, data->blksz, data->blocks, data->flags); 513135ea30eSLudovic Barre 514135ea30eSLudovic Barre host->ops->dma_start(host, &datactrl); 515135ea30eSLudovic Barre 516135ea30eSLudovic Barre /* Trigger the DMA transfer */ 517135ea30eSLudovic Barre mmci_write_datactrlreg(host, datactrl); 518135ea30eSLudovic Barre 519135ea30eSLudovic Barre /* 520135ea30eSLudovic Barre * Let the MMCI say when the data is ended and it's time 521135ea30eSLudovic Barre * to fire next DMA request. When that happens, MMCI will 522135ea30eSLudovic Barre * call mmci_data_end() 523135ea30eSLudovic Barre */ 524135ea30eSLudovic Barre writel(readl(host->base + MMCIMASK0) | MCI_DATAENDMASK, 525135ea30eSLudovic Barre host->base + MMCIMASK0); 526135ea30eSLudovic Barre return 0; 527135ea30eSLudovic Barre } 528135ea30eSLudovic Barre 5295a9f10c3SLudovic Barre void mmci_dma_finalize(struct mmci_host *host, struct mmc_data *data) 5305a9f10c3SLudovic Barre { 5315a9f10c3SLudovic Barre if (!host->use_dma) 5325a9f10c3SLudovic Barre return; 5335a9f10c3SLudovic Barre 5345a9f10c3SLudovic Barre if (host->ops && host->ops->dma_finalize) 5355a9f10c3SLudovic Barre host->ops->dma_finalize(host, data); 5365a9f10c3SLudovic Barre } 5375a9f10c3SLudovic Barre 538cfccc6acSLudovic Barre void mmci_dma_error(struct mmci_host *host) 539cfccc6acSLudovic Barre { 540cfccc6acSLudovic Barre if (!host->use_dma) 541cfccc6acSLudovic Barre return; 542cfccc6acSLudovic Barre 543cfccc6acSLudovic Barre if (host->ops && host->ops->dma_error) 544cfccc6acSLudovic Barre host->ops->dma_error(host); 545cfccc6acSLudovic Barre } 546cfccc6acSLudovic Barre 5471c6a0718SPierre Ossman static void 5481c6a0718SPierre Ossman mmci_request_end(struct mmci_host *host, struct mmc_request *mrq) 5491c6a0718SPierre Ossman { 5501c6a0718SPierre Ossman writel(0, host->base + MMCICOMMAND); 5511c6a0718SPierre Ossman 5521c6a0718SPierre Ossman BUG_ON(host->data); 5531c6a0718SPierre Ossman 5541c6a0718SPierre Ossman host->mrq = NULL; 5551c6a0718SPierre Ossman host->cmd = NULL; 5561c6a0718SPierre Ossman 5571c6a0718SPierre Ossman mmc_request_done(host->mmc, mrq); 5581c6a0718SPierre Ossman } 5591c6a0718SPierre Ossman 5602686b4b4SLinus Walleij static void mmci_set_mask1(struct mmci_host *host, unsigned int mask) 5612686b4b4SLinus Walleij { 5622686b4b4SLinus Walleij void __iomem *base = host->base; 5636ea9cdf3SPatrice Chotard struct variant_data *variant = host->variant; 5642686b4b4SLinus Walleij 5652686b4b4SLinus Walleij if (host->singleirq) { 5662686b4b4SLinus Walleij unsigned int mask0 = readl(base + MMCIMASK0); 5672686b4b4SLinus Walleij 56859db5e2dSLudovic Barre mask0 &= ~variant->irq_pio_mask; 5692686b4b4SLinus Walleij mask0 |= mask; 5702686b4b4SLinus Walleij 5712686b4b4SLinus Walleij writel(mask0, base + MMCIMASK0); 5722686b4b4SLinus Walleij } 5732686b4b4SLinus Walleij 5746ea9cdf3SPatrice Chotard if (variant->mmcimask1) 5752686b4b4SLinus Walleij writel(mask, base + MMCIMASK1); 5766ea9cdf3SPatrice Chotard 5776ea9cdf3SPatrice Chotard host->mask1_reg = mask; 5782686b4b4SLinus Walleij } 5792686b4b4SLinus Walleij 5801c6a0718SPierre Ossman static void mmci_stop_data(struct mmci_host *host) 5811c6a0718SPierre Ossman { 5829cc639a2SUlf Hansson mmci_write_datactrlreg(host, 0); 5832686b4b4SLinus Walleij mmci_set_mask1(host, 0); 5841c6a0718SPierre Ossman host->data = NULL; 5851c6a0718SPierre Ossman } 5861c6a0718SPierre Ossman 5874ce1d6cbSRabin Vincent static void mmci_init_sg(struct mmci_host *host, struct mmc_data *data) 5884ce1d6cbSRabin Vincent { 5894ce1d6cbSRabin Vincent unsigned int flags = SG_MITER_ATOMIC; 5904ce1d6cbSRabin Vincent 5914ce1d6cbSRabin Vincent if (data->flags & MMC_DATA_READ) 5924ce1d6cbSRabin Vincent flags |= SG_MITER_TO_SG; 5934ce1d6cbSRabin Vincent else 5944ce1d6cbSRabin Vincent flags |= SG_MITER_FROM_SG; 5954ce1d6cbSRabin Vincent 5964ce1d6cbSRabin Vincent sg_miter_start(&host->sg_miter, data->sg, data->sg_len, flags); 5974ce1d6cbSRabin Vincent } 5984ce1d6cbSRabin Vincent 599c8ebae37SRussell King /* 600c8ebae37SRussell King * All the DMA operation mode stuff goes inside this ifdef. 601c8ebae37SRussell King * This assumes that you have a generic DMA device interface, 602c8ebae37SRussell King * no custom DMA interfaces are supported. 603c8ebae37SRussell King */ 604c8ebae37SRussell King #ifdef CONFIG_DMA_ENGINE 605a813f2a2SLudovic Barre struct mmci_dmae_next { 606a813f2a2SLudovic Barre struct dma_async_tx_descriptor *desc; 607a813f2a2SLudovic Barre struct dma_chan *chan; 608a813f2a2SLudovic Barre }; 609a813f2a2SLudovic Barre 610a813f2a2SLudovic Barre struct mmci_dmae_priv { 611a813f2a2SLudovic Barre struct dma_chan *cur; 612a813f2a2SLudovic Barre struct dma_chan *rx_channel; 613a813f2a2SLudovic Barre struct dma_chan *tx_channel; 614a813f2a2SLudovic Barre struct dma_async_tx_descriptor *desc_current; 615a813f2a2SLudovic Barre struct mmci_dmae_next next_data; 616a813f2a2SLudovic Barre }; 617a813f2a2SLudovic Barre 618c3647fdcSLudovic Barre int mmci_dmae_setup(struct mmci_host *host) 619c8ebae37SRussell King { 620c8ebae37SRussell King const char *rxname, *txname; 621a813f2a2SLudovic Barre struct mmci_dmae_priv *dmae; 622c8ebae37SRussell King 623a813f2a2SLudovic Barre dmae = devm_kzalloc(mmc_dev(host->mmc), sizeof(*dmae), GFP_KERNEL); 624a813f2a2SLudovic Barre if (!dmae) 625a813f2a2SLudovic Barre return -ENOMEM; 626c8ebae37SRussell King 627a813f2a2SLudovic Barre host->dma_priv = dmae; 628a813f2a2SLudovic Barre 629a813f2a2SLudovic Barre dmae->rx_channel = dma_request_slave_channel(mmc_dev(host->mmc), 630a813f2a2SLudovic Barre "rx"); 631a813f2a2SLudovic Barre dmae->tx_channel = dma_request_slave_channel(mmc_dev(host->mmc), 632a813f2a2SLudovic Barre "tx"); 63358c7ccbfSPer Forlin 6341fd83f0eSLee Jones /* 6351fd83f0eSLee Jones * If only an RX channel is specified, the driver will 6361fd83f0eSLee Jones * attempt to use it bidirectionally, however if it is 6371fd83f0eSLee Jones * is specified but cannot be located, DMA will be disabled. 6381fd83f0eSLee Jones */ 639a813f2a2SLudovic Barre if (dmae->rx_channel && !dmae->tx_channel) 640a813f2a2SLudovic Barre dmae->tx_channel = dmae->rx_channel; 641c8ebae37SRussell King 642a813f2a2SLudovic Barre if (dmae->rx_channel) 643a813f2a2SLudovic Barre rxname = dma_chan_name(dmae->rx_channel); 644c8ebae37SRussell King else 645c8ebae37SRussell King rxname = "none"; 646c8ebae37SRussell King 647a813f2a2SLudovic Barre if (dmae->tx_channel) 648a813f2a2SLudovic Barre txname = dma_chan_name(dmae->tx_channel); 649c8ebae37SRussell King else 650c8ebae37SRussell King txname = "none"; 651c8ebae37SRussell King 652c8ebae37SRussell King dev_info(mmc_dev(host->mmc), "DMA channels RX %s, TX %s\n", 653c8ebae37SRussell King rxname, txname); 654c8ebae37SRussell King 655c8ebae37SRussell King /* 656c8ebae37SRussell King * Limit the maximum segment size in any SG entry according to 657c8ebae37SRussell King * the parameters of the DMA engine device. 658c8ebae37SRussell King */ 659a813f2a2SLudovic Barre if (dmae->tx_channel) { 660a813f2a2SLudovic Barre struct device *dev = dmae->tx_channel->device->dev; 661c8ebae37SRussell King unsigned int max_seg_size = dma_get_max_seg_size(dev); 662c8ebae37SRussell King 663c8ebae37SRussell King if (max_seg_size < host->mmc->max_seg_size) 664c8ebae37SRussell King host->mmc->max_seg_size = max_seg_size; 665c8ebae37SRussell King } 666a813f2a2SLudovic Barre if (dmae->rx_channel) { 667a813f2a2SLudovic Barre struct device *dev = dmae->rx_channel->device->dev; 668c8ebae37SRussell King unsigned int max_seg_size = dma_get_max_seg_size(dev); 669c8ebae37SRussell King 670c8ebae37SRussell King if (max_seg_size < host->mmc->max_seg_size) 671c8ebae37SRussell King host->mmc->max_seg_size = max_seg_size; 672c8ebae37SRussell King } 6739cb15142SSrinivas Kandagatla 674a813f2a2SLudovic Barre if (!dmae->tx_channel || !dmae->rx_channel) { 675c3647fdcSLudovic Barre mmci_dmae_release(host); 676c3647fdcSLudovic Barre return -EINVAL; 677c3647fdcSLudovic Barre } 678c3647fdcSLudovic Barre 679c3647fdcSLudovic Barre return 0; 680c8ebae37SRussell King } 681c8ebae37SRussell King 682c8ebae37SRussell King /* 6836e0ee714SBill Pemberton * This is used in or so inline it 684c8ebae37SRussell King * so it can be discarded. 685c8ebae37SRussell King */ 686c3647fdcSLudovic Barre void mmci_dmae_release(struct mmci_host *host) 687c8ebae37SRussell King { 688a813f2a2SLudovic Barre struct mmci_dmae_priv *dmae = host->dma_priv; 689a813f2a2SLudovic Barre 690a813f2a2SLudovic Barre if (dmae->rx_channel) 691a813f2a2SLudovic Barre dma_release_channel(dmae->rx_channel); 692a813f2a2SLudovic Barre if (dmae->tx_channel) 693a813f2a2SLudovic Barre dma_release_channel(dmae->tx_channel); 694a813f2a2SLudovic Barre dmae->rx_channel = dmae->tx_channel = NULL; 695c8ebae37SRussell King } 696c8ebae37SRussell King 697c8ebae37SRussell King static void mmci_dma_unmap(struct mmci_host *host, struct mmc_data *data) 698c8ebae37SRussell King { 699a813f2a2SLudovic Barre struct mmci_dmae_priv *dmae = host->dma_priv; 700653a761eSUlf Hansson struct dma_chan *chan; 701653a761eSUlf Hansson 702feeef096SHeiner Kallweit if (data->flags & MMC_DATA_READ) 703a813f2a2SLudovic Barre chan = dmae->rx_channel; 704feeef096SHeiner Kallweit else 705a813f2a2SLudovic Barre chan = dmae->tx_channel; 706653a761eSUlf Hansson 707feeef096SHeiner Kallweit dma_unmap_sg(chan->device->dev, data->sg, data->sg_len, 708feeef096SHeiner Kallweit mmc_get_dma_dir(data)); 709653a761eSUlf Hansson } 710653a761eSUlf Hansson 711cfccc6acSLudovic Barre void mmci_dmae_error(struct mmci_host *host) 7127b2a6d51SLudovic Barre { 713a813f2a2SLudovic Barre struct mmci_dmae_priv *dmae = host->dma_priv; 714a813f2a2SLudovic Barre 715cfccc6acSLudovic Barre if (!dma_inprogress(host)) 716cdea1947SLudovic Barre return; 717cdea1947SLudovic Barre 7187b2a6d51SLudovic Barre dev_err(mmc_dev(host->mmc), "error during DMA transfer!\n"); 719a813f2a2SLudovic Barre dmaengine_terminate_all(dmae->cur); 7207b2a6d51SLudovic Barre host->dma_in_progress = false; 721a813f2a2SLudovic Barre dmae->cur = NULL; 722a813f2a2SLudovic Barre dmae->desc_current = NULL; 7237b2a6d51SLudovic Barre host->data->host_cookie = 0; 7247b2a6d51SLudovic Barre 7257b2a6d51SLudovic Barre mmci_dma_unmap(host, host->data); 7267b2a6d51SLudovic Barre } 7277b2a6d51SLudovic Barre 7285a9f10c3SLudovic Barre void mmci_dmae_finalize(struct mmci_host *host, struct mmc_data *data) 729653a761eSUlf Hansson { 730a813f2a2SLudovic Barre struct mmci_dmae_priv *dmae = host->dma_priv; 731c8ebae37SRussell King u32 status; 732c8ebae37SRussell King int i; 733c8ebae37SRussell King 7345a9f10c3SLudovic Barre if (!dma_inprogress(host)) 735cdea1947SLudovic Barre return; 736cdea1947SLudovic Barre 737c8ebae37SRussell King /* Wait up to 1ms for the DMA to complete */ 738c8ebae37SRussell King for (i = 0; ; i++) { 739c8ebae37SRussell King status = readl(host->base + MMCISTATUS); 740c8ebae37SRussell King if (!(status & MCI_RXDATAAVLBLMASK) || i >= 100) 741c8ebae37SRussell King break; 742c8ebae37SRussell King udelay(10); 743c8ebae37SRussell King } 744c8ebae37SRussell King 745c8ebae37SRussell King /* 746c8ebae37SRussell King * Check to see whether we still have some data left in the FIFO - 747c8ebae37SRussell King * this catches DMA controllers which are unable to monitor the 748c8ebae37SRussell King * DMALBREQ and DMALSREQ signals while allowing us to DMA to non- 749c8ebae37SRussell King * contiguous buffers. On TX, we'll get a FIFO underrun error. 750c8ebae37SRussell King */ 751c8ebae37SRussell King if (status & MCI_RXDATAAVLBLMASK) { 752cfccc6acSLudovic Barre mmci_dma_error(host); 753c8ebae37SRussell King if (!data->error) 754c8ebae37SRussell King data->error = -EIO; 7557b2a6d51SLudovic Barre } else if (!data->host_cookie) { 756653a761eSUlf Hansson mmci_dma_unmap(host, data); 7577b2a6d51SLudovic Barre } 758c8ebae37SRussell King 759c8ebae37SRussell King /* 760c8ebae37SRussell King * Use of DMA with scatter-gather is impossible. 761c8ebae37SRussell King * Give up with DMA and switch back to PIO mode. 762c8ebae37SRussell King */ 763c8ebae37SRussell King if (status & MCI_RXDATAAVLBLMASK) { 764c8ebae37SRussell King dev_err(mmc_dev(host->mmc), "buggy DMA detected. Taking evasive action.\n"); 765c8ebae37SRussell King mmci_dma_release(host); 766c8ebae37SRussell King } 767653a761eSUlf Hansson 768e13934bdSLinus Walleij host->dma_in_progress = false; 769a813f2a2SLudovic Barre dmae->cur = NULL; 770a813f2a2SLudovic Barre dmae->desc_current = NULL; 771c8ebae37SRussell King } 772c8ebae37SRussell King 773653a761eSUlf Hansson /* prepares DMA channel and DMA descriptor, returns non-zero on failure */ 77447983510SLudovic Barre static int _mmci_dmae_prep_data(struct mmci_host *host, struct mmc_data *data, 775653a761eSUlf Hansson struct dma_chan **dma_chan, 776653a761eSUlf Hansson struct dma_async_tx_descriptor **dma_desc) 777c8ebae37SRussell King { 778a813f2a2SLudovic Barre struct mmci_dmae_priv *dmae = host->dma_priv; 779c8ebae37SRussell King struct variant_data *variant = host->variant; 780c8ebae37SRussell King struct dma_slave_config conf = { 781c8ebae37SRussell King .src_addr = host->phybase + MMCIFIFO, 782c8ebae37SRussell King .dst_addr = host->phybase + MMCIFIFO, 783c8ebae37SRussell King .src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES, 784c8ebae37SRussell King .dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES, 785c8ebae37SRussell King .src_maxburst = variant->fifohalfsize >> 2, /* # of words */ 786c8ebae37SRussell King .dst_maxburst = variant->fifohalfsize >> 2, /* # of words */ 787258aea76SViresh Kumar .device_fc = false, 788c8ebae37SRussell King }; 789c8ebae37SRussell King struct dma_chan *chan; 790c8ebae37SRussell King struct dma_device *device; 791c8ebae37SRussell King struct dma_async_tx_descriptor *desc; 792c8ebae37SRussell King int nr_sg; 7939cb15142SSrinivas Kandagatla unsigned long flags = DMA_CTRL_ACK; 794c8ebae37SRussell King 795c8ebae37SRussell King if (data->flags & MMC_DATA_READ) { 79605f5799cSVinod Koul conf.direction = DMA_DEV_TO_MEM; 797a813f2a2SLudovic Barre chan = dmae->rx_channel; 798c8ebae37SRussell King } else { 79905f5799cSVinod Koul conf.direction = DMA_MEM_TO_DEV; 800a813f2a2SLudovic Barre chan = dmae->tx_channel; 801c8ebae37SRussell King } 802c8ebae37SRussell King 803c8ebae37SRussell King /* If there's no DMA channel, fall back to PIO */ 804c8ebae37SRussell King if (!chan) 805c8ebae37SRussell King return -EINVAL; 806c8ebae37SRussell King 807c8ebae37SRussell King /* If less than or equal to the fifo size, don't bother with DMA */ 80858c7ccbfSPer Forlin if (data->blksz * data->blocks <= variant->fifosize) 809c8ebae37SRussell King return -EINVAL; 810c8ebae37SRussell King 811c8ebae37SRussell King device = chan->device; 812feeef096SHeiner Kallweit nr_sg = dma_map_sg(device->dev, data->sg, data->sg_len, 813feeef096SHeiner Kallweit mmc_get_dma_dir(data)); 814c8ebae37SRussell King if (nr_sg == 0) 815c8ebae37SRussell King return -EINVAL; 816c8ebae37SRussell King 8179cb15142SSrinivas Kandagatla if (host->variant->qcom_dml) 8189cb15142SSrinivas Kandagatla flags |= DMA_PREP_INTERRUPT; 8199cb15142SSrinivas Kandagatla 820c8ebae37SRussell King dmaengine_slave_config(chan, &conf); 82116052827SAlexandre Bounine desc = dmaengine_prep_slave_sg(chan, data->sg, nr_sg, 8229cb15142SSrinivas Kandagatla conf.direction, flags); 823c8ebae37SRussell King if (!desc) 824c8ebae37SRussell King goto unmap_exit; 825c8ebae37SRussell King 826653a761eSUlf Hansson *dma_chan = chan; 827653a761eSUlf Hansson *dma_desc = desc; 828c8ebae37SRussell King 82958c7ccbfSPer Forlin return 0; 83058c7ccbfSPer Forlin 83158c7ccbfSPer Forlin unmap_exit: 832feeef096SHeiner Kallweit dma_unmap_sg(device->dev, data->sg, data->sg_len, 833feeef096SHeiner Kallweit mmc_get_dma_dir(data)); 83458c7ccbfSPer Forlin return -ENOMEM; 83558c7ccbfSPer Forlin } 83658c7ccbfSPer Forlin 83747983510SLudovic Barre int mmci_dmae_prep_data(struct mmci_host *host, 838ad7b8918SLudovic Barre struct mmc_data *data, 839ad7b8918SLudovic Barre bool next) 840653a761eSUlf Hansson { 841a813f2a2SLudovic Barre struct mmci_dmae_priv *dmae = host->dma_priv; 842ad7b8918SLudovic Barre struct mmci_dmae_next *nd = &dmae->next_data; 843a813f2a2SLudovic Barre 84447983510SLudovic Barre if (!host->use_dma) 84547983510SLudovic Barre return -EINVAL; 84647983510SLudovic Barre 847ad7b8918SLudovic Barre if (next) 84847983510SLudovic Barre return _mmci_dmae_prep_data(host, data, &nd->chan, &nd->desc); 849653a761eSUlf Hansson /* Check if next job is already prepared. */ 850a813f2a2SLudovic Barre if (dmae->cur && dmae->desc_current) 851653a761eSUlf Hansson return 0; 852653a761eSUlf Hansson 853653a761eSUlf Hansson /* No job were prepared thus do it now. */ 85447983510SLudovic Barre return _mmci_dmae_prep_data(host, data, &dmae->cur, 855a813f2a2SLudovic Barre &dmae->desc_current); 856653a761eSUlf Hansson } 857653a761eSUlf Hansson 858135ea30eSLudovic Barre int mmci_dmae_start(struct mmci_host *host, unsigned int *datactrl) 85958c7ccbfSPer Forlin { 860a813f2a2SLudovic Barre struct mmci_dmae_priv *dmae = host->dma_priv; 86158c7ccbfSPer Forlin struct mmc_data *data = host->data; 86258c7ccbfSPer Forlin 863e13934bdSLinus Walleij host->dma_in_progress = true; 864a813f2a2SLudovic Barre dmaengine_submit(dmae->desc_current); 865a813f2a2SLudovic Barre dma_async_issue_pending(dmae->cur); 866c8ebae37SRussell King 8679cb15142SSrinivas Kandagatla if (host->variant->qcom_dml) 8689cb15142SSrinivas Kandagatla dml_start_xfer(host, data); 8699cb15142SSrinivas Kandagatla 870135ea30eSLudovic Barre *datactrl |= MCI_DPSM_DMAENABLE; 871c8ebae37SRussell King 872c8ebae37SRussell King return 0; 873c8ebae37SRussell King } 87458c7ccbfSPer Forlin 87502769968SLudovic Barre void mmci_dmae_get_next_data(struct mmci_host *host, struct mmc_data *data) 87658c7ccbfSPer Forlin { 877a813f2a2SLudovic Barre struct mmci_dmae_priv *dmae = host->dma_priv; 878a813f2a2SLudovic Barre struct mmci_dmae_next *next = &dmae->next_data; 87958c7ccbfSPer Forlin 880c3647fdcSLudovic Barre if (!host->use_dma) 881c3647fdcSLudovic Barre return; 882c3647fdcSLudovic Barre 883a813f2a2SLudovic Barre WARN_ON(!data->host_cookie && (next->desc || next->chan)); 88458c7ccbfSPer Forlin 885a813f2a2SLudovic Barre dmae->desc_current = next->desc; 886a813f2a2SLudovic Barre dmae->cur = next->chan; 887a813f2a2SLudovic Barre next->desc = NULL; 888a813f2a2SLudovic Barre next->chan = NULL; 88958c7ccbfSPer Forlin } 89058c7ccbfSPer Forlin 89147983510SLudovic Barre void mmci_dmae_unprep_data(struct mmci_host *host, 89247983510SLudovic Barre struct mmc_data *data, int err) 89347983510SLudovic Barre 89458c7ccbfSPer Forlin { 895a813f2a2SLudovic Barre struct mmci_dmae_priv *dmae = host->dma_priv; 89658c7ccbfSPer Forlin 89747983510SLudovic Barre if (!host->use_dma) 89858c7ccbfSPer Forlin return; 89958c7ccbfSPer Forlin 900653a761eSUlf Hansson mmci_dma_unmap(host, data); 901653a761eSUlf Hansson 902653a761eSUlf Hansson if (err) { 903a813f2a2SLudovic Barre struct mmci_dmae_next *next = &dmae->next_data; 904653a761eSUlf Hansson struct dma_chan *chan; 905653a761eSUlf Hansson if (data->flags & MMC_DATA_READ) 906a813f2a2SLudovic Barre chan = dmae->rx_channel; 907653a761eSUlf Hansson else 908a813f2a2SLudovic Barre chan = dmae->tx_channel; 90958c7ccbfSPer Forlin dmaengine_terminate_all(chan); 910653a761eSUlf Hansson 911a813f2a2SLudovic Barre if (dmae->desc_current == next->desc) 912a813f2a2SLudovic Barre dmae->desc_current = NULL; 913b5c16a60SSrinivas Kandagatla 914a813f2a2SLudovic Barre if (dmae->cur == next->chan) { 915e13934bdSLinus Walleij host->dma_in_progress = false; 916a813f2a2SLudovic Barre dmae->cur = NULL; 917e13934bdSLinus Walleij } 918b5c16a60SSrinivas Kandagatla 919a813f2a2SLudovic Barre next->desc = NULL; 920a813f2a2SLudovic Barre next->chan = NULL; 92158c7ccbfSPer Forlin } 92258c7ccbfSPer Forlin } 92358c7ccbfSPer Forlin 924c3647fdcSLudovic Barre static struct mmci_host_ops mmci_variant_ops = { 92547983510SLudovic Barre .prep_data = mmci_dmae_prep_data, 92647983510SLudovic Barre .unprep_data = mmci_dmae_unprep_data, 92702769968SLudovic Barre .get_next_data = mmci_dmae_get_next_data, 928c3647fdcSLudovic Barre .dma_setup = mmci_dmae_setup, 929c3647fdcSLudovic Barre .dma_release = mmci_dmae_release, 930135ea30eSLudovic Barre .dma_start = mmci_dmae_start, 9315a9f10c3SLudovic Barre .dma_finalize = mmci_dmae_finalize, 932cfccc6acSLudovic Barre .dma_error = mmci_dmae_error, 933c3647fdcSLudovic Barre }; 934c3647fdcSLudovic Barre 935c3647fdcSLudovic Barre void mmci_variant_init(struct mmci_host *host) 936c3647fdcSLudovic Barre { 937c3647fdcSLudovic Barre host->ops = &mmci_variant_ops; 938c3647fdcSLudovic Barre } 939c8ebae37SRussell King #endif 940c8ebae37SRussell King 94147983510SLudovic Barre static void mmci_pre_request(struct mmc_host *mmc, struct mmc_request *mrq) 94247983510SLudovic Barre { 94347983510SLudovic Barre struct mmci_host *host = mmc_priv(mmc); 94447983510SLudovic Barre struct mmc_data *data = mrq->data; 94547983510SLudovic Barre 94647983510SLudovic Barre if (!data) 94747983510SLudovic Barre return; 94847983510SLudovic Barre 94947983510SLudovic Barre WARN_ON(data->host_cookie); 95047983510SLudovic Barre 95147983510SLudovic Barre if (mmci_validate_data(host, data)) 95247983510SLudovic Barre return; 95347983510SLudovic Barre 95447983510SLudovic Barre mmci_prep_data(host, data, true); 95547983510SLudovic Barre } 95647983510SLudovic Barre 95747983510SLudovic Barre static void mmci_post_request(struct mmc_host *mmc, struct mmc_request *mrq, 95847983510SLudovic Barre int err) 95947983510SLudovic Barre { 96047983510SLudovic Barre struct mmci_host *host = mmc_priv(mmc); 96147983510SLudovic Barre struct mmc_data *data = mrq->data; 96247983510SLudovic Barre 96347983510SLudovic Barre if (!data || !data->host_cookie) 96447983510SLudovic Barre return; 96547983510SLudovic Barre 96647983510SLudovic Barre mmci_unprep_data(host, data, err); 96747983510SLudovic Barre } 96847983510SLudovic Barre 9691c6a0718SPierre Ossman static void mmci_start_data(struct mmci_host *host, struct mmc_data *data) 9701c6a0718SPierre Ossman { 9718301bb68SRabin Vincent struct variant_data *variant = host->variant; 9721c6a0718SPierre Ossman unsigned int datactrl, timeout, irqmask; 9731c6a0718SPierre Ossman unsigned long long clks; 9741c6a0718SPierre Ossman void __iomem *base; 9751c6a0718SPierre Ossman int blksz_bits; 9761c6a0718SPierre Ossman 97764de0289SLinus Walleij dev_dbg(mmc_dev(host->mmc), "blksz %04x blks %04x flags %08x\n", 9781c6a0718SPierre Ossman data->blksz, data->blocks, data->flags); 9791c6a0718SPierre Ossman 9801c6a0718SPierre Ossman host->data = data; 981528320dbSRabin Vincent host->size = data->blksz * data->blocks; 98251d4375dSRussell King data->bytes_xfered = 0; 9831c6a0718SPierre Ossman 9841c6a0718SPierre Ossman clks = (unsigned long long)data->timeout_ns * host->cclk; 985c4a35769SSrinivas Kandagatla do_div(clks, NSEC_PER_SEC); 9861c6a0718SPierre Ossman 9871c6a0718SPierre Ossman timeout = data->timeout_clks + (unsigned int)clks; 9881c6a0718SPierre Ossman 9891c6a0718SPierre Ossman base = host->base; 9901c6a0718SPierre Ossman writel(timeout, base + MMCIDATATIMER); 9911c6a0718SPierre Ossman writel(host->size, base + MMCIDATALENGTH); 9921c6a0718SPierre Ossman 9931c6a0718SPierre Ossman blksz_bits = ffs(data->blksz) - 1; 9941c6a0718SPierre Ossman BUG_ON(1 << blksz_bits != data->blksz); 9951c6a0718SPierre Ossman 9961784b157SPhilippe Langlais if (variant->blksz_datactrl16) 9979b279941SLudovic Barre datactrl = variant->datactrl_dpsm_enable | (data->blksz << 16); 998ff783233SSrinivas Kandagatla else if (variant->blksz_datactrl4) 9999b279941SLudovic Barre datactrl = variant->datactrl_dpsm_enable | (data->blksz << 4); 10001784b157SPhilippe Langlais else 10019b279941SLudovic Barre datactrl = variant->datactrl_dpsm_enable | blksz_bits << 4; 1002c8ebae37SRussell King 1003c8ebae37SRussell King if (data->flags & MMC_DATA_READ) 10041c6a0718SPierre Ossman datactrl |= MCI_DPSM_DIRECTION; 1005c8ebae37SRussell King 1006c7354133SSrinivas Kandagatla if (host->mmc->card && mmc_card_sdio(host->mmc->card)) { 100706c1a121SUlf Hansson u32 clk; 1008c7354133SSrinivas Kandagatla 10095df014dfSSrinivas Kandagatla datactrl |= variant->datactrl_mask_sdio; 10107258db7eSUlf Hansson 1011c8ebae37SRussell King /* 101270ac0935SUlf Hansson * The ST Micro variant for SDIO small write transfers 101370ac0935SUlf Hansson * needs to have clock H/W flow control disabled, 101470ac0935SUlf Hansson * otherwise the transfer will not start. The threshold 101570ac0935SUlf Hansson * depends on the rate of MCLK. 101606c1a121SUlf Hansson */ 1017c7354133SSrinivas Kandagatla if (variant->st_sdio && data->flags & MMC_DATA_WRITE && 101870ac0935SUlf Hansson (host->size < 8 || 101970ac0935SUlf Hansson (host->size <= 8 && host->mclk > 50000000))) 102006c1a121SUlf Hansson clk = host->clk_reg & ~variant->clkreg_enable; 102106c1a121SUlf Hansson else 102206c1a121SUlf Hansson clk = host->clk_reg | variant->clkreg_enable; 102306c1a121SUlf Hansson 102406c1a121SUlf Hansson mmci_write_clkreg(host, clk); 102506c1a121SUlf Hansson } 102606c1a121SUlf Hansson 10276dad6c95SSeungwon Jeon if (host->mmc->ios.timing == MMC_TIMING_UHS_DDR50 || 10286dad6c95SSeungwon Jeon host->mmc->ios.timing == MMC_TIMING_MMC_DDR52) 1029e17dca2bSSrinivas Kandagatla datactrl |= variant->datactrl_mask_ddrmode; 10306dbb6ee0SUlf Hansson 103106c1a121SUlf Hansson /* 1032c8ebae37SRussell King * Attempt to use DMA operation mode, if this 1033c8ebae37SRussell King * should fail, fall back to PIO mode 1034c8ebae37SRussell King */ 1035135ea30eSLudovic Barre if (!mmci_dma_start(host, datactrl)) 1036c8ebae37SRussell King return; 1037c8ebae37SRussell King 1038c8ebae37SRussell King /* IRQ mode, map the SG list for CPU reading/writing */ 1039c8ebae37SRussell King mmci_init_sg(host, data); 1040c8ebae37SRussell King 1041c8ebae37SRussell King if (data->flags & MMC_DATA_READ) { 10421c6a0718SPierre Ossman irqmask = MCI_RXFIFOHALFFULLMASK; 10431c6a0718SPierre Ossman 10441c6a0718SPierre Ossman /* 1045c4d877c1SRussell King * If we have less than the fifo 'half-full' threshold to 1046c4d877c1SRussell King * transfer, trigger a PIO interrupt as soon as any data 1047c4d877c1SRussell King * is available. 10481c6a0718SPierre Ossman */ 1049c4d877c1SRussell King if (host->size < variant->fifohalfsize) 10501c6a0718SPierre Ossman irqmask |= MCI_RXDATAAVLBLMASK; 10511c6a0718SPierre Ossman } else { 10521c6a0718SPierre Ossman /* 10531c6a0718SPierre Ossman * We don't actually need to include "FIFO empty" here 10541c6a0718SPierre Ossman * since its implicit in "FIFO half empty". 10551c6a0718SPierre Ossman */ 10561c6a0718SPierre Ossman irqmask = MCI_TXFIFOHALFEMPTYMASK; 10571c6a0718SPierre Ossman } 10581c6a0718SPierre Ossman 10599cc639a2SUlf Hansson mmci_write_datactrlreg(host, datactrl); 10601c6a0718SPierre Ossman writel(readl(base + MMCIMASK0) & ~MCI_DATAENDMASK, base + MMCIMASK0); 10612686b4b4SLinus Walleij mmci_set_mask1(host, irqmask); 10621c6a0718SPierre Ossman } 10631c6a0718SPierre Ossman 10641c6a0718SPierre Ossman static void 10651c6a0718SPierre Ossman mmci_start_command(struct mmci_host *host, struct mmc_command *cmd, u32 c) 10661c6a0718SPierre Ossman { 10671c6a0718SPierre Ossman void __iomem *base = host->base; 10681c6a0718SPierre Ossman 106964de0289SLinus Walleij dev_dbg(mmc_dev(host->mmc), "op %02x arg %08x flags %08x\n", 10701c6a0718SPierre Ossman cmd->opcode, cmd->arg, cmd->flags); 10711c6a0718SPierre Ossman 10720f244804SLudovic Barre if (readl(base + MMCICOMMAND) & host->variant->cmdreg_cpsm_enable) { 10731c6a0718SPierre Ossman writel(0, base + MMCICOMMAND); 10746adb2a80SSrinivas Kandagatla mmci_reg_delay(host); 10751c6a0718SPierre Ossman } 10761c6a0718SPierre Ossman 10770f244804SLudovic Barre c |= cmd->opcode | host->variant->cmdreg_cpsm_enable; 10781c6a0718SPierre Ossman if (cmd->flags & MMC_RSP_PRESENT) { 10791c6a0718SPierre Ossman if (cmd->flags & MMC_RSP_136) 10800f244804SLudovic Barre c |= host->variant->cmdreg_lrsp_crc; 10810f244804SLudovic Barre else if (cmd->flags & MMC_RSP_CRC) 10820f244804SLudovic Barre c |= host->variant->cmdreg_srsp_crc; 10830f244804SLudovic Barre else 10840f244804SLudovic Barre c |= host->variant->cmdreg_srsp; 10851c6a0718SPierre Ossman } 10861c6a0718SPierre Ossman if (/*interrupt*/0) 10871c6a0718SPierre Ossman c |= MCI_CPSM_INTERRUPT; 10881c6a0718SPierre Ossman 1089ae7b0061SSrinivas Kandagatla if (mmc_cmd_type(cmd) == MMC_CMD_ADTC) 1090ae7b0061SSrinivas Kandagatla c |= host->variant->data_cmd_enable; 1091ae7b0061SSrinivas Kandagatla 10921c6a0718SPierre Ossman host->cmd = cmd; 10931c6a0718SPierre Ossman 10941c6a0718SPierre Ossman writel(cmd->arg, base + MMCIARGUMENT); 10951c6a0718SPierre Ossman writel(c, base + MMCICOMMAND); 10961c6a0718SPierre Ossman } 10971c6a0718SPierre Ossman 10981c6a0718SPierre Ossman static void 10991c6a0718SPierre Ossman mmci_data_irq(struct mmci_host *host, struct mmc_data *data, 11001c6a0718SPierre Ossman unsigned int status) 11011c6a0718SPierre Ossman { 1102daf9713cSLudovic Barre unsigned int status_err; 1103daf9713cSLudovic Barre 11041cb9da50SUlf Hansson /* Make sure we have data to handle */ 11051cb9da50SUlf Hansson if (!data) 11061cb9da50SUlf Hansson return; 11071cb9da50SUlf Hansson 1108f20f8f21SLinus Walleij /* First check for errors */ 1109daf9713cSLudovic Barre status_err = status & (host->variant->start_err | 1110daf9713cSLudovic Barre MCI_DATACRCFAIL | MCI_DATATIMEOUT | 1111daf9713cSLudovic Barre MCI_TXUNDERRUN | MCI_RXOVERRUN); 1112daf9713cSLudovic Barre 1113daf9713cSLudovic Barre if (status_err) { 11148cb28155SLinus Walleij u32 remain, success; 1115f20f8f21SLinus Walleij 1116c8ebae37SRussell King /* Terminate the DMA transfer */ 1117cfccc6acSLudovic Barre mmci_dma_error(host); 1118c8ebae37SRussell King 1119c8afc9d5SRussell King /* 1120c8afc9d5SRussell King * Calculate how far we are into the transfer. Note that 1121c8afc9d5SRussell King * the data counter gives the number of bytes transferred 1122c8afc9d5SRussell King * on the MMC bus, not on the host side. On reads, this 1123c8afc9d5SRussell King * can be as much as a FIFO-worth of data ahead. This 1124c8afc9d5SRussell King * matters for FIFO overruns only. 1125c8afc9d5SRussell King */ 1126f5a106d9SLinus Walleij remain = readl(host->base + MMCIDATACNT); 11278cb28155SLinus Walleij success = data->blksz * data->blocks - remain; 11288cb28155SLinus Walleij 1129c8afc9d5SRussell King dev_dbg(mmc_dev(host->mmc), "MCI ERROR IRQ, status 0x%08x at 0x%08x\n", 1130daf9713cSLudovic Barre status_err, success); 1131daf9713cSLudovic Barre if (status_err & MCI_DATACRCFAIL) { 11328cb28155SLinus Walleij /* Last block was not successful */ 1133c8afc9d5SRussell King success -= 1; 113417b0429dSPierre Ossman data->error = -EILSEQ; 1135daf9713cSLudovic Barre } else if (status_err & MCI_DATATIMEOUT) { 113617b0429dSPierre Ossman data->error = -ETIMEDOUT; 1137daf9713cSLudovic Barre } else if (status_err & MCI_STARTBITERR) { 1138757df746SLinus Walleij data->error = -ECOMM; 1139daf9713cSLudovic Barre } else if (status_err & MCI_TXUNDERRUN) { 114017b0429dSPierre Ossman data->error = -EIO; 1141daf9713cSLudovic Barre } else if (status_err & MCI_RXOVERRUN) { 1142c8afc9d5SRussell King if (success > host->variant->fifosize) 1143c8afc9d5SRussell King success -= host->variant->fifosize; 1144c8afc9d5SRussell King else 1145c8afc9d5SRussell King success = 0; 11468cb28155SLinus Walleij data->error = -EIO; 11474ce1d6cbSRabin Vincent } 114851d4375dSRussell King data->bytes_xfered = round_down(success, data->blksz); 11491c6a0718SPierre Ossman } 1150f20f8f21SLinus Walleij 11518cb28155SLinus Walleij if (status & MCI_DATABLOCKEND) 11528cb28155SLinus Walleij dev_err(mmc_dev(host->mmc), "stray MCI_DATABLOCKEND interrupt\n"); 1153f20f8f21SLinus Walleij 1154ccff9b51SRussell King if (status & MCI_DATAEND || data->error) { 1155653a761eSUlf Hansson mmci_dma_finalize(host, data); 1156cdea1947SLudovic Barre 11571c6a0718SPierre Ossman mmci_stop_data(host); 11581c6a0718SPierre Ossman 11598cb28155SLinus Walleij if (!data->error) 11608cb28155SLinus Walleij /* The error clause is handled above, success! */ 116151d4375dSRussell King data->bytes_xfered = data->blksz * data->blocks; 1162f20f8f21SLinus Walleij 1163024629c6SUlf Hansson if (!data->stop || host->mrq->sbc) { 11641c6a0718SPierre Ossman mmci_request_end(host, data->mrq); 11651c6a0718SPierre Ossman } else { 11661c6a0718SPierre Ossman mmci_start_command(host, data->stop, 0); 11671c6a0718SPierre Ossman } 11681c6a0718SPierre Ossman } 11691c6a0718SPierre Ossman } 11701c6a0718SPierre Ossman 11711c6a0718SPierre Ossman static void 11721c6a0718SPierre Ossman mmci_cmd_irq(struct mmci_host *host, struct mmc_command *cmd, 11731c6a0718SPierre Ossman unsigned int status) 11741c6a0718SPierre Ossman { 11751c6a0718SPierre Ossman void __iomem *base = host->base; 117649adc0caSLinus Walleij bool sbc; 1177ad82bfeaSUlf Hansson 1178ad82bfeaSUlf Hansson if (!cmd) 1179ad82bfeaSUlf Hansson return; 1180ad82bfeaSUlf Hansson 1181ad82bfeaSUlf Hansson sbc = (cmd == host->mrq->sbc); 1182ad82bfeaSUlf Hansson 118349adc0caSLinus Walleij /* 118449adc0caSLinus Walleij * We need to be one of these interrupts to be considered worth 118549adc0caSLinus Walleij * handling. Note that we tag on any latent IRQs postponed 118649adc0caSLinus Walleij * due to waiting for busy status. 118749adc0caSLinus Walleij */ 118849adc0caSLinus Walleij if (!((status|host->busy_status) & 118949adc0caSLinus Walleij (MCI_CMDCRCFAIL|MCI_CMDTIMEOUT|MCI_CMDSENT|MCI_CMDRESPEND))) 1190ad82bfeaSUlf Hansson return; 11918d94b54dSUlf Hansson 119249adc0caSLinus Walleij /* 119349adc0caSLinus Walleij * ST Micro variant: handle busy detection. 119449adc0caSLinus Walleij */ 119549adc0caSLinus Walleij if (host->variant->busy_detect) { 119649adc0caSLinus Walleij bool busy_resp = !!(cmd->flags & MMC_RSP_BUSY); 119749adc0caSLinus Walleij 119849adc0caSLinus Walleij /* We are busy with a command, return */ 119949adc0caSLinus Walleij if (host->busy_status && 120049adc0caSLinus Walleij (status & host->variant->busy_detect_flag)) 12018d94b54dSUlf Hansson return; 12028d94b54dSUlf Hansson 120349adc0caSLinus Walleij /* 120449adc0caSLinus Walleij * We were not busy, but we now got a busy response on 120549adc0caSLinus Walleij * something that was not an error, and we double-check 120649adc0caSLinus Walleij * that the special busy status bit is still set before 120749adc0caSLinus Walleij * proceeding. 120849adc0caSLinus Walleij */ 12098d94b54dSUlf Hansson if (!host->busy_status && busy_resp && 12108d94b54dSUlf Hansson !(status & (MCI_CMDCRCFAIL|MCI_CMDTIMEOUT)) && 121149adc0caSLinus Walleij (readl(base + MMCISTATUS) & host->variant->busy_detect_flag)) { 12125cad24d8SJean-Nicolas Graux 12135cad24d8SJean-Nicolas Graux /* Clear the busy start IRQ */ 12145cad24d8SJean-Nicolas Graux writel(host->variant->busy_detect_mask, 12155cad24d8SJean-Nicolas Graux host->base + MMCICLEAR); 12165cad24d8SJean-Nicolas Graux 12175cad24d8SJean-Nicolas Graux /* Unmask the busy end IRQ */ 121849adc0caSLinus Walleij writel(readl(base + MMCIMASK0) | 121949adc0caSLinus Walleij host->variant->busy_detect_mask, 12208d94b54dSUlf Hansson base + MMCIMASK0); 122149adc0caSLinus Walleij /* 122249adc0caSLinus Walleij * Now cache the last response status code (until 122349adc0caSLinus Walleij * the busy bit goes low), and return. 122449adc0caSLinus Walleij */ 122549adc0caSLinus Walleij host->busy_status = 122649adc0caSLinus Walleij status & (MCI_CMDSENT|MCI_CMDRESPEND); 12278d94b54dSUlf Hansson return; 12288d94b54dSUlf Hansson } 12298d94b54dSUlf Hansson 123049adc0caSLinus Walleij /* 123149adc0caSLinus Walleij * At this point we are not busy with a command, we have 12325cad24d8SJean-Nicolas Graux * not received a new busy request, clear and mask the busy 12335cad24d8SJean-Nicolas Graux * end IRQ and fall through to process the IRQ. 123449adc0caSLinus Walleij */ 12358d94b54dSUlf Hansson if (host->busy_status) { 12365cad24d8SJean-Nicolas Graux 12375cad24d8SJean-Nicolas Graux writel(host->variant->busy_detect_mask, 12385cad24d8SJean-Nicolas Graux host->base + MMCICLEAR); 12395cad24d8SJean-Nicolas Graux 124049adc0caSLinus Walleij writel(readl(base + MMCIMASK0) & 124149adc0caSLinus Walleij ~host->variant->busy_detect_mask, 12428d94b54dSUlf Hansson base + MMCIMASK0); 12438d94b54dSUlf Hansson host->busy_status = 0; 12448d94b54dSUlf Hansson } 124549adc0caSLinus Walleij } 12461c6a0718SPierre Ossman 12471c6a0718SPierre Ossman host->cmd = NULL; 12481c6a0718SPierre Ossman 12491c6a0718SPierre Ossman if (status & MCI_CMDTIMEOUT) { 125017b0429dSPierre Ossman cmd->error = -ETIMEDOUT; 12511c6a0718SPierre Ossman } else if (status & MCI_CMDCRCFAIL && cmd->flags & MMC_RSP_CRC) { 125217b0429dSPierre Ossman cmd->error = -EILSEQ; 12539047b435SRussell King - ARM Linux } else { 12549047b435SRussell King - ARM Linux cmd->resp[0] = readl(base + MMCIRESPONSE0); 12559047b435SRussell King - ARM Linux cmd->resp[1] = readl(base + MMCIRESPONSE1); 12569047b435SRussell King - ARM Linux cmd->resp[2] = readl(base + MMCIRESPONSE2); 12579047b435SRussell King - ARM Linux cmd->resp[3] = readl(base + MMCIRESPONSE3); 12581c6a0718SPierre Ossman } 12591c6a0718SPierre Ossman 1260024629c6SUlf Hansson if ((!sbc && !cmd->data) || cmd->error) { 12613b6e3c73SUlf Hansson if (host->data) { 12623b6e3c73SUlf Hansson /* Terminate the DMA transfer */ 1263cfccc6acSLudovic Barre mmci_dma_error(host); 12647b2a6d51SLudovic Barre 12651c6a0718SPierre Ossman mmci_stop_data(host); 12663b6e3c73SUlf Hansson } 1267024629c6SUlf Hansson mmci_request_end(host, host->mrq); 1268024629c6SUlf Hansson } else if (sbc) { 1269024629c6SUlf Hansson mmci_start_command(host, host->mrq->cmd, 0); 1270d2141547SLudovic Barre } else if (!host->variant->datactrl_first && 1271d2141547SLudovic Barre !(cmd->data->flags & MMC_DATA_READ)) { 12721c6a0718SPierre Ossman mmci_start_data(host, cmd->data); 12731c6a0718SPierre Ossman } 12741c6a0718SPierre Ossman } 12751c6a0718SPierre Ossman 12769c34b73dSSrinivas Kandagatla static int mmci_get_rx_fifocnt(struct mmci_host *host, u32 status, int remain) 12779c34b73dSSrinivas Kandagatla { 12789c34b73dSSrinivas Kandagatla return remain - (readl(host->base + MMCIFIFOCNT) << 2); 12799c34b73dSSrinivas Kandagatla } 12809c34b73dSSrinivas Kandagatla 12819c34b73dSSrinivas Kandagatla static int mmci_qcom_get_rx_fifocnt(struct mmci_host *host, u32 status, int r) 12829c34b73dSSrinivas Kandagatla { 12839c34b73dSSrinivas Kandagatla /* 12849c34b73dSSrinivas Kandagatla * on qcom SDCC4 only 8 words are used in each burst so only 8 addresses 12859c34b73dSSrinivas Kandagatla * from the fifo range should be used 12869c34b73dSSrinivas Kandagatla */ 12879c34b73dSSrinivas Kandagatla if (status & MCI_RXFIFOHALFFULL) 12889c34b73dSSrinivas Kandagatla return host->variant->fifohalfsize; 12899c34b73dSSrinivas Kandagatla else if (status & MCI_RXDATAAVLBL) 12909c34b73dSSrinivas Kandagatla return 4; 12919c34b73dSSrinivas Kandagatla 12929c34b73dSSrinivas Kandagatla return 0; 12939c34b73dSSrinivas Kandagatla } 12949c34b73dSSrinivas Kandagatla 12951c6a0718SPierre Ossman static int mmci_pio_read(struct mmci_host *host, char *buffer, unsigned int remain) 12961c6a0718SPierre Ossman { 12971c6a0718SPierre Ossman void __iomem *base = host->base; 12981c6a0718SPierre Ossman char *ptr = buffer; 12999c34b73dSSrinivas Kandagatla u32 status = readl(host->base + MMCISTATUS); 130026eed9a5SLinus Walleij int host_remain = host->size; 13011c6a0718SPierre Ossman 13021c6a0718SPierre Ossman do { 13039c34b73dSSrinivas Kandagatla int count = host->get_rx_fifocnt(host, status, host_remain); 13041c6a0718SPierre Ossman 13051c6a0718SPierre Ossman if (count > remain) 13061c6a0718SPierre Ossman count = remain; 13071c6a0718SPierre Ossman 13081c6a0718SPierre Ossman if (count <= 0) 13091c6a0718SPierre Ossman break; 13101c6a0718SPierre Ossman 1311393e5e24SUlf Hansson /* 1312393e5e24SUlf Hansson * SDIO especially may want to send something that is 1313393e5e24SUlf Hansson * not divisible by 4 (as opposed to card sectors 1314393e5e24SUlf Hansson * etc). Therefore make sure to always read the last bytes 1315393e5e24SUlf Hansson * while only doing full 32-bit reads towards the FIFO. 1316393e5e24SUlf Hansson */ 1317393e5e24SUlf Hansson if (unlikely(count & 0x3)) { 1318393e5e24SUlf Hansson if (count < 4) { 1319393e5e24SUlf Hansson unsigned char buf[4]; 13204b85da08SDavide Ciminaghi ioread32_rep(base + MMCIFIFO, buf, 1); 1321393e5e24SUlf Hansson memcpy(ptr, buf, count); 1322393e5e24SUlf Hansson } else { 13234b85da08SDavide Ciminaghi ioread32_rep(base + MMCIFIFO, ptr, count >> 2); 1324393e5e24SUlf Hansson count &= ~0x3; 1325393e5e24SUlf Hansson } 1326393e5e24SUlf Hansson } else { 13274b85da08SDavide Ciminaghi ioread32_rep(base + MMCIFIFO, ptr, count >> 2); 1328393e5e24SUlf Hansson } 13291c6a0718SPierre Ossman 13301c6a0718SPierre Ossman ptr += count; 13311c6a0718SPierre Ossman remain -= count; 133226eed9a5SLinus Walleij host_remain -= count; 13331c6a0718SPierre Ossman 13341c6a0718SPierre Ossman if (remain == 0) 13351c6a0718SPierre Ossman break; 13361c6a0718SPierre Ossman 13371c6a0718SPierre Ossman status = readl(base + MMCISTATUS); 13381c6a0718SPierre Ossman } while (status & MCI_RXDATAAVLBL); 13391c6a0718SPierre Ossman 13401c6a0718SPierre Ossman return ptr - buffer; 13411c6a0718SPierre Ossman } 13421c6a0718SPierre Ossman 13431c6a0718SPierre Ossman static int mmci_pio_write(struct mmci_host *host, char *buffer, unsigned int remain, u32 status) 13441c6a0718SPierre Ossman { 13458301bb68SRabin Vincent struct variant_data *variant = host->variant; 13461c6a0718SPierre Ossman void __iomem *base = host->base; 13471c6a0718SPierre Ossman char *ptr = buffer; 13481c6a0718SPierre Ossman 13491c6a0718SPierre Ossman do { 13501c6a0718SPierre Ossman unsigned int count, maxcnt; 13511c6a0718SPierre Ossman 13528301bb68SRabin Vincent maxcnt = status & MCI_TXFIFOEMPTY ? 13538301bb68SRabin Vincent variant->fifosize : variant->fifohalfsize; 13541c6a0718SPierre Ossman count = min(remain, maxcnt); 13551c6a0718SPierre Ossman 135634177802SLinus Walleij /* 135734177802SLinus Walleij * SDIO especially may want to send something that is 135834177802SLinus Walleij * not divisible by 4 (as opposed to card sectors 135934177802SLinus Walleij * etc), and the FIFO only accept full 32-bit writes. 136034177802SLinus Walleij * So compensate by adding +3 on the count, a single 136134177802SLinus Walleij * byte become a 32bit write, 7 bytes will be two 136234177802SLinus Walleij * 32bit writes etc. 136334177802SLinus Walleij */ 13644b85da08SDavide Ciminaghi iowrite32_rep(base + MMCIFIFO, ptr, (count + 3) >> 2); 13651c6a0718SPierre Ossman 13661c6a0718SPierre Ossman ptr += count; 13671c6a0718SPierre Ossman remain -= count; 13681c6a0718SPierre Ossman 13691c6a0718SPierre Ossman if (remain == 0) 13701c6a0718SPierre Ossman break; 13711c6a0718SPierre Ossman 13721c6a0718SPierre Ossman status = readl(base + MMCISTATUS); 13731c6a0718SPierre Ossman } while (status & MCI_TXFIFOHALFEMPTY); 13741c6a0718SPierre Ossman 13751c6a0718SPierre Ossman return ptr - buffer; 13761c6a0718SPierre Ossman } 13771c6a0718SPierre Ossman 13781c6a0718SPierre Ossman /* 13791c6a0718SPierre Ossman * PIO data transfer IRQ handler. 13801c6a0718SPierre Ossman */ 13811c6a0718SPierre Ossman static irqreturn_t mmci_pio_irq(int irq, void *dev_id) 13821c6a0718SPierre Ossman { 13831c6a0718SPierre Ossman struct mmci_host *host = dev_id; 13844ce1d6cbSRabin Vincent struct sg_mapping_iter *sg_miter = &host->sg_miter; 13858301bb68SRabin Vincent struct variant_data *variant = host->variant; 13861c6a0718SPierre Ossman void __iomem *base = host->base; 13871c6a0718SPierre Ossman u32 status; 13881c6a0718SPierre Ossman 13891c6a0718SPierre Ossman status = readl(base + MMCISTATUS); 13901c6a0718SPierre Ossman 139164de0289SLinus Walleij dev_dbg(mmc_dev(host->mmc), "irq1 (pio) %08x\n", status); 13921c6a0718SPierre Ossman 13931c6a0718SPierre Ossman do { 13941c6a0718SPierre Ossman unsigned int remain, len; 13951c6a0718SPierre Ossman char *buffer; 13961c6a0718SPierre Ossman 13971c6a0718SPierre Ossman /* 13981c6a0718SPierre Ossman * For write, we only need to test the half-empty flag 13991c6a0718SPierre Ossman * here - if the FIFO is completely empty, then by 14001c6a0718SPierre Ossman * definition it is more than half empty. 14011c6a0718SPierre Ossman * 14021c6a0718SPierre Ossman * For read, check for data available. 14031c6a0718SPierre Ossman */ 14041c6a0718SPierre Ossman if (!(status & (MCI_TXFIFOHALFEMPTY|MCI_RXDATAAVLBL))) 14051c6a0718SPierre Ossman break; 14061c6a0718SPierre Ossman 14074ce1d6cbSRabin Vincent if (!sg_miter_next(sg_miter)) 14084ce1d6cbSRabin Vincent break; 14094ce1d6cbSRabin Vincent 14104ce1d6cbSRabin Vincent buffer = sg_miter->addr; 14114ce1d6cbSRabin Vincent remain = sg_miter->length; 14121c6a0718SPierre Ossman 14131c6a0718SPierre Ossman len = 0; 14141c6a0718SPierre Ossman if (status & MCI_RXACTIVE) 14151c6a0718SPierre Ossman len = mmci_pio_read(host, buffer, remain); 14161c6a0718SPierre Ossman if (status & MCI_TXACTIVE) 14171c6a0718SPierre Ossman len = mmci_pio_write(host, buffer, remain, status); 14181c6a0718SPierre Ossman 14194ce1d6cbSRabin Vincent sg_miter->consumed = len; 14201c6a0718SPierre Ossman 14211c6a0718SPierre Ossman host->size -= len; 14221c6a0718SPierre Ossman remain -= len; 14231c6a0718SPierre Ossman 14241c6a0718SPierre Ossman if (remain) 14251c6a0718SPierre Ossman break; 14261c6a0718SPierre Ossman 14271c6a0718SPierre Ossman status = readl(base + MMCISTATUS); 14281c6a0718SPierre Ossman } while (1); 14291c6a0718SPierre Ossman 14304ce1d6cbSRabin Vincent sg_miter_stop(sg_miter); 14314ce1d6cbSRabin Vincent 14321c6a0718SPierre Ossman /* 1433c4d877c1SRussell King * If we have less than the fifo 'half-full' threshold to transfer, 1434c4d877c1SRussell King * trigger a PIO interrupt as soon as any data is available. 14351c6a0718SPierre Ossman */ 1436c4d877c1SRussell King if (status & MCI_RXACTIVE && host->size < variant->fifohalfsize) 14372686b4b4SLinus Walleij mmci_set_mask1(host, MCI_RXDATAAVLBLMASK); 14381c6a0718SPierre Ossman 14391c6a0718SPierre Ossman /* 14401c6a0718SPierre Ossman * If we run out of data, disable the data IRQs; this 14411c6a0718SPierre Ossman * prevents a race where the FIFO becomes empty before 14421c6a0718SPierre Ossman * the chip itself has disabled the data path, and 14431c6a0718SPierre Ossman * stops us racing with our data end IRQ. 14441c6a0718SPierre Ossman */ 14451c6a0718SPierre Ossman if (host->size == 0) { 14462686b4b4SLinus Walleij mmci_set_mask1(host, 0); 14471c6a0718SPierre Ossman writel(readl(base + MMCIMASK0) | MCI_DATAENDMASK, base + MMCIMASK0); 14481c6a0718SPierre Ossman } 14491c6a0718SPierre Ossman 14501c6a0718SPierre Ossman return IRQ_HANDLED; 14511c6a0718SPierre Ossman } 14521c6a0718SPierre Ossman 14531c6a0718SPierre Ossman /* 14541c6a0718SPierre Ossman * Handle completion of command and data transfers. 14551c6a0718SPierre Ossman */ 14561c6a0718SPierre Ossman static irqreturn_t mmci_irq(int irq, void *dev_id) 14571c6a0718SPierre Ossman { 14581c6a0718SPierre Ossman struct mmci_host *host = dev_id; 14591c6a0718SPierre Ossman u32 status; 14601c6a0718SPierre Ossman int ret = 0; 14611c6a0718SPierre Ossman 14621c6a0718SPierre Ossman spin_lock(&host->lock); 14631c6a0718SPierre Ossman 14641c6a0718SPierre Ossman do { 14651c6a0718SPierre Ossman status = readl(host->base + MMCISTATUS); 14662686b4b4SLinus Walleij 14672686b4b4SLinus Walleij if (host->singleirq) { 14686ea9cdf3SPatrice Chotard if (status & host->mask1_reg) 14692686b4b4SLinus Walleij mmci_pio_irq(irq, dev_id); 14702686b4b4SLinus Walleij 147159db5e2dSLudovic Barre status &= ~host->variant->irq_pio_mask; 14722686b4b4SLinus Walleij } 14732686b4b4SLinus Walleij 14748d94b54dSUlf Hansson /* 14755cad24d8SJean-Nicolas Graux * We intentionally clear the MCI_ST_CARDBUSY IRQ (if it's 14765cad24d8SJean-Nicolas Graux * enabled) in mmci_cmd_irq() function where ST Micro busy 14775cad24d8SJean-Nicolas Graux * detection variant is handled. Considering the HW seems to be 14785cad24d8SJean-Nicolas Graux * triggering the IRQ on both edges while monitoring DAT0 for 14795cad24d8SJean-Nicolas Graux * busy completion and that same status bit is used to monitor 14805cad24d8SJean-Nicolas Graux * start and end of busy detection, special care must be taken 14815cad24d8SJean-Nicolas Graux * to make sure that both start and end interrupts are always 14825cad24d8SJean-Nicolas Graux * cleared one after the other. 14838d94b54dSUlf Hansson */ 14841c6a0718SPierre Ossman status &= readl(host->base + MMCIMASK0); 14855cad24d8SJean-Nicolas Graux if (host->variant->busy_detect) 14865cad24d8SJean-Nicolas Graux writel(status & ~host->variant->busy_detect_mask, 14875cad24d8SJean-Nicolas Graux host->base + MMCICLEAR); 14885cad24d8SJean-Nicolas Graux else 14891c6a0718SPierre Ossman writel(status, host->base + MMCICLEAR); 14901c6a0718SPierre Ossman 149164de0289SLinus Walleij dev_dbg(mmc_dev(host->mmc), "irq0 (data+cmd) %08x\n", status); 14921c6a0718SPierre Ossman 14937878289bSUlf Hansson if (host->variant->reversed_irq_handling) { 14947878289bSUlf Hansson mmci_data_irq(host, host->data, status); 14957878289bSUlf Hansson mmci_cmd_irq(host, host->cmd, status); 14967878289bSUlf Hansson } else { 1497ad82bfeaSUlf Hansson mmci_cmd_irq(host, host->cmd, status); 14981cb9da50SUlf Hansson mmci_data_irq(host, host->data, status); 14997878289bSUlf Hansson } 15001c6a0718SPierre Ossman 150149adc0caSLinus Walleij /* 150249adc0caSLinus Walleij * Don't poll for busy completion in irq context. 150349adc0caSLinus Walleij */ 150449adc0caSLinus Walleij if (host->variant->busy_detect && host->busy_status) 150549adc0caSLinus Walleij status &= ~host->variant->busy_detect_flag; 15068d94b54dSUlf Hansson 15071c6a0718SPierre Ossman ret = 1; 15081c6a0718SPierre Ossman } while (status); 15091c6a0718SPierre Ossman 15101c6a0718SPierre Ossman spin_unlock(&host->lock); 15111c6a0718SPierre Ossman 15121c6a0718SPierre Ossman return IRQ_RETVAL(ret); 15131c6a0718SPierre Ossman } 15141c6a0718SPierre Ossman 15151c6a0718SPierre Ossman static void mmci_request(struct mmc_host *mmc, struct mmc_request *mrq) 15161c6a0718SPierre Ossman { 15171c6a0718SPierre Ossman struct mmci_host *host = mmc_priv(mmc); 15189e943021SLinus Walleij unsigned long flags; 15191c6a0718SPierre Ossman 15201c6a0718SPierre Ossman WARN_ON(host->mrq != NULL); 15211c6a0718SPierre Ossman 1522653a761eSUlf Hansson mrq->cmd->error = mmci_validate_data(host, mrq->data); 1523653a761eSUlf Hansson if (mrq->cmd->error) { 1524255d01afSPierre Ossman mmc_request_done(mmc, mrq); 1525255d01afSPierre Ossman return; 1526255d01afSPierre Ossman } 1527255d01afSPierre Ossman 15289e943021SLinus Walleij spin_lock_irqsave(&host->lock, flags); 15291c6a0718SPierre Ossman 15301c6a0718SPierre Ossman host->mrq = mrq; 15311c6a0718SPierre Ossman 153258c7ccbfSPer Forlin if (mrq->data) 153358c7ccbfSPer Forlin mmci_get_next_data(host, mrq->data); 153458c7ccbfSPer Forlin 1535d2141547SLudovic Barre if (mrq->data && 1536d2141547SLudovic Barre (host->variant->datactrl_first || mrq->data->flags & MMC_DATA_READ)) 15371c6a0718SPierre Ossman mmci_start_data(host, mrq->data); 15381c6a0718SPierre Ossman 1539024629c6SUlf Hansson if (mrq->sbc) 1540024629c6SUlf Hansson mmci_start_command(host, mrq->sbc, 0); 1541024629c6SUlf Hansson else 15421c6a0718SPierre Ossman mmci_start_command(host, mrq->cmd, 0); 15431c6a0718SPierre Ossman 15449e943021SLinus Walleij spin_unlock_irqrestore(&host->lock, flags); 15451c6a0718SPierre Ossman } 15461c6a0718SPierre Ossman 15471c6a0718SPierre Ossman static void mmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) 15481c6a0718SPierre Ossman { 15491c6a0718SPierre Ossman struct mmci_host *host = mmc_priv(mmc); 15507d72a1d4SUlf Hansson struct variant_data *variant = host->variant; 1551a6a6464aSLinus Walleij u32 pwr = 0; 1552a6a6464aSLinus Walleij unsigned long flags; 1553db90f91fSLee Jones int ret; 15541c6a0718SPierre Ossman 1555bc521818SUlf Hansson if (host->plat->ios_handler && 1556bc521818SUlf Hansson host->plat->ios_handler(mmc_dev(mmc), ios)) 1557bc521818SUlf Hansson dev_err(mmc_dev(mmc), "platform ios_handler failed\n"); 1558bc521818SUlf Hansson 15591c6a0718SPierre Ossman switch (ios->power_mode) { 15601c6a0718SPierre Ossman case MMC_POWER_OFF: 1561599c1d5cSUlf Hansson if (!IS_ERR(mmc->supply.vmmc)) 1562599c1d5cSUlf Hansson mmc_regulator_set_ocr(mmc, mmc->supply.vmmc, 0); 1563237fb5e6SLee Jones 15647c0136efSUlf Hansson if (!IS_ERR(mmc->supply.vqmmc) && host->vqmmc_enabled) { 1565237fb5e6SLee Jones regulator_disable(mmc->supply.vqmmc); 15667c0136efSUlf Hansson host->vqmmc_enabled = false; 15677c0136efSUlf Hansson } 1568237fb5e6SLee Jones 15691c6a0718SPierre Ossman break; 15701c6a0718SPierre Ossman case MMC_POWER_UP: 1571599c1d5cSUlf Hansson if (!IS_ERR(mmc->supply.vmmc)) 1572599c1d5cSUlf Hansson mmc_regulator_set_ocr(mmc, mmc->supply.vmmc, ios->vdd); 1573599c1d5cSUlf Hansson 15747d72a1d4SUlf Hansson /* 15757d72a1d4SUlf Hansson * The ST Micro variant doesn't have the PL180s MCI_PWR_UP 15767d72a1d4SUlf Hansson * and instead uses MCI_PWR_ON so apply whatever value is 15777d72a1d4SUlf Hansson * configured in the variant data. 15787d72a1d4SUlf Hansson */ 15797d72a1d4SUlf Hansson pwr |= variant->pwrreg_powerup; 15807d72a1d4SUlf Hansson 15811c6a0718SPierre Ossman break; 15821c6a0718SPierre Ossman case MMC_POWER_ON: 15837c0136efSUlf Hansson if (!IS_ERR(mmc->supply.vqmmc) && !host->vqmmc_enabled) { 1584db90f91fSLee Jones ret = regulator_enable(mmc->supply.vqmmc); 1585db90f91fSLee Jones if (ret < 0) 1586db90f91fSLee Jones dev_err(mmc_dev(mmc), 1587db90f91fSLee Jones "failed to enable vqmmc regulator\n"); 15887c0136efSUlf Hansson else 15897c0136efSUlf Hansson host->vqmmc_enabled = true; 1590db90f91fSLee Jones } 1591237fb5e6SLee Jones 15921c6a0718SPierre Ossman pwr |= MCI_PWR_ON; 15931c6a0718SPierre Ossman break; 15941c6a0718SPierre Ossman } 15951c6a0718SPierre Ossman 15964d1a3a0dSUlf Hansson if (variant->signal_direction && ios->power_mode != MMC_POWER_OFF) { 15974d1a3a0dSUlf Hansson /* 15984d1a3a0dSUlf Hansson * The ST Micro variant has some additional bits 15994d1a3a0dSUlf Hansson * indicating signal direction for the signals in 16004d1a3a0dSUlf Hansson * the SD/MMC bus and feedback-clock usage. 16014d1a3a0dSUlf Hansson */ 16024593df29SUlf Hansson pwr |= host->pwr_reg_add; 16034d1a3a0dSUlf Hansson 16044d1a3a0dSUlf Hansson if (ios->bus_width == MMC_BUS_WIDTH_4) 16054d1a3a0dSUlf Hansson pwr &= ~MCI_ST_DATA74DIREN; 16064d1a3a0dSUlf Hansson else if (ios->bus_width == MMC_BUS_WIDTH_1) 16074d1a3a0dSUlf Hansson pwr &= (~MCI_ST_DATA74DIREN & 16084d1a3a0dSUlf Hansson ~MCI_ST_DATA31DIREN & 16094d1a3a0dSUlf Hansson ~MCI_ST_DATA2DIREN); 16104d1a3a0dSUlf Hansson } 16114d1a3a0dSUlf Hansson 1612f9bb304cSPatrice Chotard if (variant->opendrain) { 1613f9bb304cSPatrice Chotard if (ios->bus_mode == MMC_BUSMODE_OPENDRAIN) 161411dfb970SPatrice Chotard pwr |= variant->opendrain; 1615f9bb304cSPatrice Chotard } else { 1616f9bb304cSPatrice Chotard /* 1617f9bb304cSPatrice Chotard * If the variant cannot configure the pads by its own, then we 1618f9bb304cSPatrice Chotard * expect the pinctrl to be able to do that for us 1619f9bb304cSPatrice Chotard */ 1620f9bb304cSPatrice Chotard if (ios->bus_mode == MMC_BUSMODE_OPENDRAIN) 1621f9bb304cSPatrice Chotard pinctrl_select_state(host->pinctrl, host->pins_opendrain); 1622f9bb304cSPatrice Chotard else 1623f9bb304cSPatrice Chotard pinctrl_select_state(host->pinctrl, host->pins_default); 1624f9bb304cSPatrice Chotard } 16251c6a0718SPierre Ossman 1626f4670daeSUlf Hansson /* 1627f4670daeSUlf Hansson * If clock = 0 and the variant requires the MMCIPOWER to be used for 1628f4670daeSUlf Hansson * gating the clock, the MCI_PWR_ON bit is cleared. 1629f4670daeSUlf Hansson */ 1630f4670daeSUlf Hansson if (!ios->clock && variant->pwrreg_clkgate) 1631f4670daeSUlf Hansson pwr &= ~MCI_PWR_ON; 1632f4670daeSUlf Hansson 16333f4e6f7bSSrinivas Kandagatla if (host->variant->explicit_mclk_control && 16343f4e6f7bSSrinivas Kandagatla ios->clock != host->clock_cache) { 16353f4e6f7bSSrinivas Kandagatla ret = clk_set_rate(host->clk, ios->clock); 16363f4e6f7bSSrinivas Kandagatla if (ret < 0) 16373f4e6f7bSSrinivas Kandagatla dev_err(mmc_dev(host->mmc), 16383f4e6f7bSSrinivas Kandagatla "Error setting clock rate (%d)\n", ret); 16393f4e6f7bSSrinivas Kandagatla else 16403f4e6f7bSSrinivas Kandagatla host->mclk = clk_get_rate(host->clk); 16413f4e6f7bSSrinivas Kandagatla } 16423f4e6f7bSSrinivas Kandagatla host->clock_cache = ios->clock; 16433f4e6f7bSSrinivas Kandagatla 1644a6a6464aSLinus Walleij spin_lock_irqsave(&host->lock, flags); 1645a6a6464aSLinus Walleij 1646cd3ee8c5SLudovic Barre if (host->ops && host->ops->set_clkreg) 1647cd3ee8c5SLudovic Barre host->ops->set_clkreg(host, ios->clock); 1648cd3ee8c5SLudovic Barre else 1649a6a6464aSLinus Walleij mmci_set_clkreg(host, ios->clock); 1650cd3ee8c5SLudovic Barre 1651cd3ee8c5SLudovic Barre if (host->ops && host->ops->set_pwrreg) 1652cd3ee8c5SLudovic Barre host->ops->set_pwrreg(host, pwr); 1653cd3ee8c5SLudovic Barre else 16547437cfa5SUlf Hansson mmci_write_pwrreg(host, pwr); 1655cd3ee8c5SLudovic Barre 1656f829c042SUlf Hansson mmci_reg_delay(host); 1657a6a6464aSLinus Walleij 1658a6a6464aSLinus Walleij spin_unlock_irqrestore(&host->lock, flags); 16591c6a0718SPierre Ossman } 16601c6a0718SPierre Ossman 166189001446SRussell King static int mmci_get_cd(struct mmc_host *mmc) 166289001446SRussell King { 166389001446SRussell King struct mmci_host *host = mmc_priv(mmc); 166429719445SRabin Vincent struct mmci_platform_data *plat = host->plat; 1665d2762090SUlf Hansson unsigned int status = mmc_gpio_get_cd(mmc); 166689001446SRussell King 1667d2762090SUlf Hansson if (status == -ENOSYS) { 16684b8caec0SRabin Vincent if (!plat->status) 16694b8caec0SRabin Vincent return 1; /* Assume always present */ 16704b8caec0SRabin Vincent 167129719445SRabin Vincent status = plat->status(mmc_dev(host->mmc)); 1672d2762090SUlf Hansson } 167374bc8093SRussell King return status; 167489001446SRussell King } 167589001446SRussell King 16760f3ed7f7SUlf Hansson static int mmci_sig_volt_switch(struct mmc_host *mmc, struct mmc_ios *ios) 16770f3ed7f7SUlf Hansson { 16780f3ed7f7SUlf Hansson int ret = 0; 16790f3ed7f7SUlf Hansson 16800f3ed7f7SUlf Hansson if (!IS_ERR(mmc->supply.vqmmc)) { 16810f3ed7f7SUlf Hansson 16820f3ed7f7SUlf Hansson switch (ios->signal_voltage) { 16830f3ed7f7SUlf Hansson case MMC_SIGNAL_VOLTAGE_330: 16840f3ed7f7SUlf Hansson ret = regulator_set_voltage(mmc->supply.vqmmc, 16850f3ed7f7SUlf Hansson 2700000, 3600000); 16860f3ed7f7SUlf Hansson break; 16870f3ed7f7SUlf Hansson case MMC_SIGNAL_VOLTAGE_180: 16880f3ed7f7SUlf Hansson ret = regulator_set_voltage(mmc->supply.vqmmc, 16890f3ed7f7SUlf Hansson 1700000, 1950000); 16900f3ed7f7SUlf Hansson break; 16910f3ed7f7SUlf Hansson case MMC_SIGNAL_VOLTAGE_120: 16920f3ed7f7SUlf Hansson ret = regulator_set_voltage(mmc->supply.vqmmc, 16930f3ed7f7SUlf Hansson 1100000, 1300000); 16940f3ed7f7SUlf Hansson break; 16950f3ed7f7SUlf Hansson } 16960f3ed7f7SUlf Hansson 16970f3ed7f7SUlf Hansson if (ret) 16980f3ed7f7SUlf Hansson dev_warn(mmc_dev(mmc), "Voltage switch failed\n"); 16990f3ed7f7SUlf Hansson } 17000f3ed7f7SUlf Hansson 17010f3ed7f7SUlf Hansson return ret; 17020f3ed7f7SUlf Hansson } 17030f3ed7f7SUlf Hansson 170401259620SUlf Hansson static struct mmc_host_ops mmci_ops = { 17051c6a0718SPierre Ossman .request = mmci_request, 170658c7ccbfSPer Forlin .pre_req = mmci_pre_request, 170758c7ccbfSPer Forlin .post_req = mmci_post_request, 17081c6a0718SPierre Ossman .set_ios = mmci_set_ios, 1709d2762090SUlf Hansson .get_ro = mmc_gpio_get_ro, 171089001446SRussell King .get_cd = mmci_get_cd, 17110f3ed7f7SUlf Hansson .start_signal_voltage_switch = mmci_sig_volt_switch, 17121c6a0718SPierre Ossman }; 17131c6a0718SPierre Ossman 171478f87df2SUlf Hansson static int mmci_of_parse(struct device_node *np, struct mmc_host *mmc) 171578f87df2SUlf Hansson { 17164593df29SUlf Hansson struct mmci_host *host = mmc_priv(mmc); 171778f87df2SUlf Hansson int ret = mmc_of_parse(mmc); 1718000bc9d5SLee Jones 171978f87df2SUlf Hansson if (ret) 172078f87df2SUlf Hansson return ret; 1721000bc9d5SLee Jones 17224593df29SUlf Hansson if (of_get_property(np, "st,sig-dir-dat0", NULL)) 17234593df29SUlf Hansson host->pwr_reg_add |= MCI_ST_DATA0DIREN; 17244593df29SUlf Hansson if (of_get_property(np, "st,sig-dir-dat2", NULL)) 17254593df29SUlf Hansson host->pwr_reg_add |= MCI_ST_DATA2DIREN; 17264593df29SUlf Hansson if (of_get_property(np, "st,sig-dir-dat31", NULL)) 17274593df29SUlf Hansson host->pwr_reg_add |= MCI_ST_DATA31DIREN; 17284593df29SUlf Hansson if (of_get_property(np, "st,sig-dir-dat74", NULL)) 17294593df29SUlf Hansson host->pwr_reg_add |= MCI_ST_DATA74DIREN; 17304593df29SUlf Hansson if (of_get_property(np, "st,sig-dir-cmd", NULL)) 17314593df29SUlf Hansson host->pwr_reg_add |= MCI_ST_CMDDIREN; 17324593df29SUlf Hansson if (of_get_property(np, "st,sig-pin-fbclk", NULL)) 17334593df29SUlf Hansson host->pwr_reg_add |= MCI_ST_FBCLKEN; 17344593df29SUlf Hansson 1735000bc9d5SLee Jones if (of_get_property(np, "mmc-cap-mmc-highspeed", NULL)) 173678f87df2SUlf Hansson mmc->caps |= MMC_CAP_MMC_HIGHSPEED; 1737000bc9d5SLee Jones if (of_get_property(np, "mmc-cap-sd-highspeed", NULL)) 173878f87df2SUlf Hansson mmc->caps |= MMC_CAP_SD_HIGHSPEED; 1739000bc9d5SLee Jones 174078f87df2SUlf Hansson return 0; 1741000bc9d5SLee Jones } 1742000bc9d5SLee Jones 1743c3be1efdSBill Pemberton static int mmci_probe(struct amba_device *dev, 1744aa25afadSRussell King const struct amba_id *id) 17451c6a0718SPierre Ossman { 17466ef297f8SLinus Walleij struct mmci_platform_data *plat = dev->dev.platform_data; 1747000bc9d5SLee Jones struct device_node *np = dev->dev.of_node; 17484956e109SRabin Vincent struct variant_data *variant = id->data; 17491c6a0718SPierre Ossman struct mmci_host *host; 17501c6a0718SPierre Ossman struct mmc_host *mmc; 17511c6a0718SPierre Ossman int ret; 17521c6a0718SPierre Ossman 1753000bc9d5SLee Jones /* Must have platform data or Device Tree. */ 1754000bc9d5SLee Jones if (!plat && !np) { 1755000bc9d5SLee Jones dev_err(&dev->dev, "No plat data or DT found\n"); 1756000bc9d5SLee Jones return -EINVAL; 17571c6a0718SPierre Ossman } 17581c6a0718SPierre Ossman 1759b9b52918SLee Jones if (!plat) { 1760b9b52918SLee Jones plat = devm_kzalloc(&dev->dev, sizeof(*plat), GFP_KERNEL); 1761b9b52918SLee Jones if (!plat) 1762b9b52918SLee Jones return -ENOMEM; 1763b9b52918SLee Jones } 1764b9b52918SLee Jones 17651c6a0718SPierre Ossman mmc = mmc_alloc_host(sizeof(struct mmci_host), &dev->dev); 1766ef289982SUlf Hansson if (!mmc) 1767ef289982SUlf Hansson return -ENOMEM; 17681c6a0718SPierre Ossman 176978f87df2SUlf Hansson ret = mmci_of_parse(np, mmc); 177078f87df2SUlf Hansson if (ret) 177178f87df2SUlf Hansson goto host_free; 177278f87df2SUlf Hansson 17731c6a0718SPierre Ossman host = mmc_priv(mmc); 17744ea580f1SRabin Vincent host->mmc = mmc; 1775012b7d33SRussell King 1776f9bb304cSPatrice Chotard /* 1777f9bb304cSPatrice Chotard * Some variant (STM32) doesn't have opendrain bit, nevertheless 1778f9bb304cSPatrice Chotard * pins can be set accordingly using pinctrl 1779f9bb304cSPatrice Chotard */ 1780f9bb304cSPatrice Chotard if (!variant->opendrain) { 1781f9bb304cSPatrice Chotard host->pinctrl = devm_pinctrl_get(&dev->dev); 1782f9bb304cSPatrice Chotard if (IS_ERR(host->pinctrl)) { 1783f9bb304cSPatrice Chotard dev_err(&dev->dev, "failed to get pinctrl"); 1784310eb252SWei Yongjun ret = PTR_ERR(host->pinctrl); 1785f9bb304cSPatrice Chotard goto host_free; 1786f9bb304cSPatrice Chotard } 1787f9bb304cSPatrice Chotard 1788f9bb304cSPatrice Chotard host->pins_default = pinctrl_lookup_state(host->pinctrl, 1789f9bb304cSPatrice Chotard PINCTRL_STATE_DEFAULT); 1790f9bb304cSPatrice Chotard if (IS_ERR(host->pins_default)) { 1791f9bb304cSPatrice Chotard dev_err(mmc_dev(mmc), "Can't select default pins\n"); 1792310eb252SWei Yongjun ret = PTR_ERR(host->pins_default); 1793f9bb304cSPatrice Chotard goto host_free; 1794f9bb304cSPatrice Chotard } 1795f9bb304cSPatrice Chotard 1796f9bb304cSPatrice Chotard host->pins_opendrain = pinctrl_lookup_state(host->pinctrl, 1797f9bb304cSPatrice Chotard MMCI_PINCTRL_STATE_OPENDRAIN); 1798f9bb304cSPatrice Chotard if (IS_ERR(host->pins_opendrain)) { 1799f9bb304cSPatrice Chotard dev_err(mmc_dev(mmc), "Can't select opendrain pins\n"); 1800310eb252SWei Yongjun ret = PTR_ERR(host->pins_opendrain); 1801f9bb304cSPatrice Chotard goto host_free; 1802f9bb304cSPatrice Chotard } 1803f9bb304cSPatrice Chotard } 1804f9bb304cSPatrice Chotard 1805012b7d33SRussell King host->hw_designer = amba_manf(dev); 1806012b7d33SRussell King host->hw_revision = amba_rev(dev); 180764de0289SLinus Walleij dev_dbg(mmc_dev(mmc), "designer ID = 0x%02x\n", host->hw_designer); 180864de0289SLinus Walleij dev_dbg(mmc_dev(mmc), "revision = 0x%01x\n", host->hw_revision); 1809012b7d33SRussell King 1810665ba56fSUlf Hansson host->clk = devm_clk_get(&dev->dev, NULL); 18111c6a0718SPierre Ossman if (IS_ERR(host->clk)) { 18121c6a0718SPierre Ossman ret = PTR_ERR(host->clk); 18131c6a0718SPierre Ossman goto host_free; 18141c6a0718SPierre Ossman } 18151c6a0718SPierre Ossman 1816ac940938SJulia Lawall ret = clk_prepare_enable(host->clk); 18171c6a0718SPierre Ossman if (ret) 1818665ba56fSUlf Hansson goto host_free; 18191c6a0718SPierre Ossman 18209c34b73dSSrinivas Kandagatla if (variant->qcom_fifo) 18219c34b73dSSrinivas Kandagatla host->get_rx_fifocnt = mmci_qcom_get_rx_fifocnt; 18229c34b73dSSrinivas Kandagatla else 18239c34b73dSSrinivas Kandagatla host->get_rx_fifocnt = mmci_get_rx_fifocnt; 18249c34b73dSSrinivas Kandagatla 18251c6a0718SPierre Ossman host->plat = plat; 18264956e109SRabin Vincent host->variant = variant; 18271c6a0718SPierre Ossman host->mclk = clk_get_rate(host->clk); 1828c8df9a53SLinus Walleij /* 1829c8df9a53SLinus Walleij * According to the spec, mclk is max 100 MHz, 1830c8df9a53SLinus Walleij * so we try to adjust the clock down to this, 1831c8df9a53SLinus Walleij * (if possible). 1832c8df9a53SLinus Walleij */ 1833dc6500bfSSrinivas Kandagatla if (host->mclk > variant->f_max) { 1834dc6500bfSSrinivas Kandagatla ret = clk_set_rate(host->clk, variant->f_max); 1835c8df9a53SLinus Walleij if (ret < 0) 1836c8df9a53SLinus Walleij goto clk_disable; 1837c8df9a53SLinus Walleij host->mclk = clk_get_rate(host->clk); 183864de0289SLinus Walleij dev_dbg(mmc_dev(mmc), "eventual mclk rate: %u Hz\n", 183964de0289SLinus Walleij host->mclk); 1840c8df9a53SLinus Walleij } 1841ef289982SUlf Hansson 1842c8ebae37SRussell King host->phybase = dev->res.start; 1843ef289982SUlf Hansson host->base = devm_ioremap_resource(&dev->dev, &dev->res); 1844ef289982SUlf Hansson if (IS_ERR(host->base)) { 1845ef289982SUlf Hansson ret = PTR_ERR(host->base); 18461c6a0718SPierre Ossman goto clk_disable; 18471c6a0718SPierre Ossman } 18481c6a0718SPierre Ossman 1849ed9067fdSUlf Hansson if (variant->init) 1850ed9067fdSUlf Hansson variant->init(host); 1851ed9067fdSUlf Hansson 18527f294e49SLinus Walleij /* 18537f294e49SLinus Walleij * The ARM and ST versions of the block have slightly different 18547f294e49SLinus Walleij * clock divider equations which means that the minimum divider 18557f294e49SLinus Walleij * differs too. 18563f4e6f7bSSrinivas Kandagatla * on Qualcomm like controllers get the nearest minimum clock to 100Khz 18577f294e49SLinus Walleij */ 18587f294e49SLinus Walleij if (variant->st_clkdiv) 18597f294e49SLinus Walleij mmc->f_min = DIV_ROUND_UP(host->mclk, 257); 18603f4e6f7bSSrinivas Kandagatla else if (variant->explicit_mclk_control) 18613f4e6f7bSSrinivas Kandagatla mmc->f_min = clk_round_rate(host->clk, 100000); 18627f294e49SLinus Walleij else 18637f294e49SLinus Walleij mmc->f_min = DIV_ROUND_UP(host->mclk, 512); 1864808d97ccSLinus Walleij /* 186578f87df2SUlf Hansson * If no maximum operating frequency is supplied, fall back to use 186678f87df2SUlf Hansson * the module parameter, which has a (low) default value in case it 186778f87df2SUlf Hansson * is not specified. Either value must not exceed the clock rate into 18685080a08dSUlf Hansson * the block, of course. 1869808d97ccSLinus Walleij */ 187078f87df2SUlf Hansson if (mmc->f_max) 18713f4e6f7bSSrinivas Kandagatla mmc->f_max = variant->explicit_mclk_control ? 18723f4e6f7bSSrinivas Kandagatla min(variant->f_max, mmc->f_max) : 18733f4e6f7bSSrinivas Kandagatla min(host->mclk, mmc->f_max); 1874808d97ccSLinus Walleij else 18753f4e6f7bSSrinivas Kandagatla mmc->f_max = variant->explicit_mclk_control ? 18763f4e6f7bSSrinivas Kandagatla fmax : min(host->mclk, fmax); 18773f4e6f7bSSrinivas Kandagatla 18783f4e6f7bSSrinivas Kandagatla 187964de0289SLinus Walleij dev_dbg(mmc_dev(mmc), "clocking block at %u Hz\n", mmc->f_max); 188064de0289SLinus Walleij 1881599c1d5cSUlf Hansson /* Get regulators and the supported OCR mask */ 18829369c97cSBjorn Andersson ret = mmc_regulator_get_supply(mmc); 188351006952SWolfram Sang if (ret) 18849369c97cSBjorn Andersson goto clk_disable; 18859369c97cSBjorn Andersson 1886599c1d5cSUlf Hansson if (!mmc->ocr_avail) 18871c6a0718SPierre Ossman mmc->ocr_avail = plat->ocr_mask; 1888599c1d5cSUlf Hansson else if (plat->ocr_mask) 1889599c1d5cSUlf Hansson dev_warn(mmc_dev(mmc), "Platform OCR mask is ignored\n"); 1890599c1d5cSUlf Hansson 18919dd8a8b8SUlf Hansson /* We support these capabilities. */ 18929dd8a8b8SUlf Hansson mmc->caps |= MMC_CAP_CMD23; 18939dd8a8b8SUlf Hansson 189449adc0caSLinus Walleij /* 189549adc0caSLinus Walleij * Enable busy detection. 189649adc0caSLinus Walleij */ 18978d94b54dSUlf Hansson if (variant->busy_detect) { 18988d94b54dSUlf Hansson mmci_ops.card_busy = mmci_card_busy; 189949adc0caSLinus Walleij /* 190049adc0caSLinus Walleij * Not all variants have a flag to enable busy detection 190149adc0caSLinus Walleij * in the DPSM, but if they do, set it here. 190249adc0caSLinus Walleij */ 190349adc0caSLinus Walleij if (variant->busy_dpsm_flag) 190449adc0caSLinus Walleij mmci_write_datactrlreg(host, 190549adc0caSLinus Walleij host->variant->busy_dpsm_flag); 19068d94b54dSUlf Hansson mmc->caps |= MMC_CAP_WAIT_WHILE_BUSY; 19078d94b54dSUlf Hansson mmc->max_busy_timeout = 0; 19088d94b54dSUlf Hansson } 19098d94b54dSUlf Hansson 19108d94b54dSUlf Hansson mmc->ops = &mmci_ops; 19118d94b54dSUlf Hansson 191270be208fSUlf Hansson /* We support these PM capabilities. */ 191378f87df2SUlf Hansson mmc->pm_caps |= MMC_PM_KEEP_POWER; 191470be208fSUlf Hansson 19151c6a0718SPierre Ossman /* 19161c6a0718SPierre Ossman * We can do SGIO 19171c6a0718SPierre Ossman */ 1918a36274e0SMartin K. Petersen mmc->max_segs = NR_SG; 19191c6a0718SPierre Ossman 19201c6a0718SPierre Ossman /* 192108458ef6SRabin Vincent * Since only a certain number of bits are valid in the data length 192208458ef6SRabin Vincent * register, we must ensure that we don't exceed 2^num-1 bytes in a 192308458ef6SRabin Vincent * single request. 19241c6a0718SPierre Ossman */ 192508458ef6SRabin Vincent mmc->max_req_size = (1 << variant->datalength_bits) - 1; 19261c6a0718SPierre Ossman 19271c6a0718SPierre Ossman /* 19281c6a0718SPierre Ossman * Set the maximum segment size. Since we aren't doing DMA 19291c6a0718SPierre Ossman * (yet) we are only limited by the data length register. 19301c6a0718SPierre Ossman */ 19311c6a0718SPierre Ossman mmc->max_seg_size = mmc->max_req_size; 19321c6a0718SPierre Ossman 19331c6a0718SPierre Ossman /* 19341c6a0718SPierre Ossman * Block size can be up to 2048 bytes, but must be a power of two. 19351c6a0718SPierre Ossman */ 1936c931d495SLudovic Barre mmc->max_blk_size = 1 << variant->datactrl_blocksz; 19371c6a0718SPierre Ossman 19381c6a0718SPierre Ossman /* 19398f7f6b7eSWill Deacon * Limit the number of blocks transferred so that we don't overflow 19408f7f6b7eSWill Deacon * the maximum request size. 19411c6a0718SPierre Ossman */ 1942c931d495SLudovic Barre mmc->max_blk_count = mmc->max_req_size >> variant->datactrl_blocksz; 19431c6a0718SPierre Ossman 19441c6a0718SPierre Ossman spin_lock_init(&host->lock); 19451c6a0718SPierre Ossman 19461c6a0718SPierre Ossman writel(0, host->base + MMCIMASK0); 19476ea9cdf3SPatrice Chotard 19486ea9cdf3SPatrice Chotard if (variant->mmcimask1) 19491c6a0718SPierre Ossman writel(0, host->base + MMCIMASK1); 19506ea9cdf3SPatrice Chotard 19511c6a0718SPierre Ossman writel(0xfff, host->base + MMCICLEAR); 19521c6a0718SPierre Ossman 1953ce437aa4SLinus Walleij /* 1954ce437aa4SLinus Walleij * If: 1955ce437aa4SLinus Walleij * - not using DT but using a descriptor table, or 1956ce437aa4SLinus Walleij * - using a table of descriptors ALONGSIDE DT, or 1957ce437aa4SLinus Walleij * look up these descriptors named "cd" and "wp" right here, fail 19589ef986a6SLinus Walleij * silently of these do not exist 1959ce437aa4SLinus Walleij */ 1960ce437aa4SLinus Walleij if (!np) { 196189168b48SLinus Walleij ret = mmc_gpiod_request_cd(mmc, "cd", 0, false, 0, NULL); 1962ce437aa4SLinus Walleij if (ret == -EPROBE_DEFER) 1963ce437aa4SLinus Walleij goto clk_disable; 1964ce437aa4SLinus Walleij 196589168b48SLinus Walleij ret = mmc_gpiod_request_ro(mmc, "wp", 0, false, 0, NULL); 1966ce437aa4SLinus Walleij if (ret == -EPROBE_DEFER) 1967ce437aa4SLinus Walleij goto clk_disable; 1968ce437aa4SLinus Walleij } 196989001446SRussell King 1970ef289982SUlf Hansson ret = devm_request_irq(&dev->dev, dev->irq[0], mmci_irq, IRQF_SHARED, 1971ef289982SUlf Hansson DRIVER_NAME " (cmd)", host); 19721c6a0718SPierre Ossman if (ret) 1973ef289982SUlf Hansson goto clk_disable; 19741c6a0718SPierre Ossman 1975dfb85185SRussell King if (!dev->irq[1]) 19762686b4b4SLinus Walleij host->singleirq = true; 19772686b4b4SLinus Walleij else { 1978ef289982SUlf Hansson ret = devm_request_irq(&dev->dev, dev->irq[1], mmci_pio_irq, 1979ef289982SUlf Hansson IRQF_SHARED, DRIVER_NAME " (pio)", host); 19801c6a0718SPierre Ossman if (ret) 1981ef289982SUlf Hansson goto clk_disable; 19822686b4b4SLinus Walleij } 19831c6a0718SPierre Ossman 1984daf9713cSLudovic Barre writel(MCI_IRQENABLE | variant->start_err, host->base + MMCIMASK0); 19851c6a0718SPierre Ossman 19861c6a0718SPierre Ossman amba_set_drvdata(dev, mmc); 19871c6a0718SPierre Ossman 1988c8ebae37SRussell King dev_info(&dev->dev, "%s: PL%03x manf %x rev%u at 0x%08llx irq %d,%d (pio)\n", 1989c8ebae37SRussell King mmc_hostname(mmc), amba_part(dev), amba_manf(dev), 1990c8ebae37SRussell King amba_rev(dev), (unsigned long long)dev->res.start, 1991c8ebae37SRussell King dev->irq[0], dev->irq[1]); 1992c8ebae37SRussell King 1993c8ebae37SRussell King mmci_dma_setup(host); 19941c6a0718SPierre Ossman 19952cd976c4SUlf Hansson pm_runtime_set_autosuspend_delay(&dev->dev, 50); 19962cd976c4SUlf Hansson pm_runtime_use_autosuspend(&dev->dev); 19971c3be369SRussell King 19988c11a94dSRussell King mmc_add_host(mmc); 19998c11a94dSRussell King 20006f2d3c89SUlf Hansson pm_runtime_put(&dev->dev); 20011c6a0718SPierre Ossman return 0; 20021c6a0718SPierre Ossman 20031c6a0718SPierre Ossman clk_disable: 2004ac940938SJulia Lawall clk_disable_unprepare(host->clk); 20051c6a0718SPierre Ossman host_free: 20061c6a0718SPierre Ossman mmc_free_host(mmc); 20071c6a0718SPierre Ossman return ret; 20081c6a0718SPierre Ossman } 20091c6a0718SPierre Ossman 20106e0ee714SBill Pemberton static int mmci_remove(struct amba_device *dev) 20111c6a0718SPierre Ossman { 20121c6a0718SPierre Ossman struct mmc_host *mmc = amba_get_drvdata(dev); 20131c6a0718SPierre Ossman 20141c6a0718SPierre Ossman if (mmc) { 20151c6a0718SPierre Ossman struct mmci_host *host = mmc_priv(mmc); 20166ea9cdf3SPatrice Chotard struct variant_data *variant = host->variant; 20171c6a0718SPierre Ossman 20181c3be369SRussell King /* 20191c3be369SRussell King * Undo pm_runtime_put() in probe. We use the _sync 20201c3be369SRussell King * version here so that we can access the primecell. 20211c3be369SRussell King */ 20221c3be369SRussell King pm_runtime_get_sync(&dev->dev); 20231c3be369SRussell King 20241c6a0718SPierre Ossman mmc_remove_host(mmc); 20251c6a0718SPierre Ossman 20261c6a0718SPierre Ossman writel(0, host->base + MMCIMASK0); 20276ea9cdf3SPatrice Chotard 20286ea9cdf3SPatrice Chotard if (variant->mmcimask1) 20291c6a0718SPierre Ossman writel(0, host->base + MMCIMASK1); 20301c6a0718SPierre Ossman 20311c6a0718SPierre Ossman writel(0, host->base + MMCICOMMAND); 20321c6a0718SPierre Ossman writel(0, host->base + MMCIDATACTRL); 20331c6a0718SPierre Ossman 2034c8ebae37SRussell King mmci_dma_release(host); 2035ac940938SJulia Lawall clk_disable_unprepare(host->clk); 20361c6a0718SPierre Ossman mmc_free_host(mmc); 20371c6a0718SPierre Ossman } 20381c6a0718SPierre Ossman 20391c6a0718SPierre Ossman return 0; 20401c6a0718SPierre Ossman } 20411c6a0718SPierre Ossman 2042571dce4fSUlf Hansson #ifdef CONFIG_PM 20431ff44433SUlf Hansson static void mmci_save(struct mmci_host *host) 20441ff44433SUlf Hansson { 20451ff44433SUlf Hansson unsigned long flags; 20461ff44433SUlf Hansson 20471ff44433SUlf Hansson spin_lock_irqsave(&host->lock, flags); 20481ff44433SUlf Hansson 20491ff44433SUlf Hansson writel(0, host->base + MMCIMASK0); 205042dcc89aSUlf Hansson if (host->variant->pwrreg_nopower) { 20511ff44433SUlf Hansson writel(0, host->base + MMCIDATACTRL); 20521ff44433SUlf Hansson writel(0, host->base + MMCIPOWER); 20531ff44433SUlf Hansson writel(0, host->base + MMCICLOCK); 205442dcc89aSUlf Hansson } 20551ff44433SUlf Hansson mmci_reg_delay(host); 20561ff44433SUlf Hansson 20571ff44433SUlf Hansson spin_unlock_irqrestore(&host->lock, flags); 20581ff44433SUlf Hansson } 20591ff44433SUlf Hansson 20601ff44433SUlf Hansson static void mmci_restore(struct mmci_host *host) 20611ff44433SUlf Hansson { 20621ff44433SUlf Hansson unsigned long flags; 20631ff44433SUlf Hansson 20641ff44433SUlf Hansson spin_lock_irqsave(&host->lock, flags); 20651ff44433SUlf Hansson 206642dcc89aSUlf Hansson if (host->variant->pwrreg_nopower) { 20671ff44433SUlf Hansson writel(host->clk_reg, host->base + MMCICLOCK); 20681ff44433SUlf Hansson writel(host->datactrl_reg, host->base + MMCIDATACTRL); 20691ff44433SUlf Hansson writel(host->pwr_reg, host->base + MMCIPOWER); 207042dcc89aSUlf Hansson } 2071daf9713cSLudovic Barre writel(MCI_IRQENABLE | host->variant->start_err, 2072daf9713cSLudovic Barre host->base + MMCIMASK0); 20731ff44433SUlf Hansson mmci_reg_delay(host); 20741ff44433SUlf Hansson 20751ff44433SUlf Hansson spin_unlock_irqrestore(&host->lock, flags); 20761ff44433SUlf Hansson } 20771ff44433SUlf Hansson 20788259293aSUlf Hansson static int mmci_runtime_suspend(struct device *dev) 20798259293aSUlf Hansson { 20808259293aSUlf Hansson struct amba_device *adev = to_amba_device(dev); 20818259293aSUlf Hansson struct mmc_host *mmc = amba_get_drvdata(adev); 20828259293aSUlf Hansson 20838259293aSUlf Hansson if (mmc) { 20848259293aSUlf Hansson struct mmci_host *host = mmc_priv(mmc); 2085e36bd9c6SUlf Hansson pinctrl_pm_select_sleep_state(dev); 20861ff44433SUlf Hansson mmci_save(host); 20878259293aSUlf Hansson clk_disable_unprepare(host->clk); 20888259293aSUlf Hansson } 20898259293aSUlf Hansson 20908259293aSUlf Hansson return 0; 20918259293aSUlf Hansson } 20928259293aSUlf Hansson 20938259293aSUlf Hansson static int mmci_runtime_resume(struct device *dev) 20948259293aSUlf Hansson { 20958259293aSUlf Hansson struct amba_device *adev = to_amba_device(dev); 20968259293aSUlf Hansson struct mmc_host *mmc = amba_get_drvdata(adev); 20978259293aSUlf Hansson 20988259293aSUlf Hansson if (mmc) { 20998259293aSUlf Hansson struct mmci_host *host = mmc_priv(mmc); 21008259293aSUlf Hansson clk_prepare_enable(host->clk); 21011ff44433SUlf Hansson mmci_restore(host); 2102e36bd9c6SUlf Hansson pinctrl_pm_select_default_state(dev); 21038259293aSUlf Hansson } 21048259293aSUlf Hansson 21058259293aSUlf Hansson return 0; 21068259293aSUlf Hansson } 21078259293aSUlf Hansson #endif 21088259293aSUlf Hansson 210948fa7003SUlf Hansson static const struct dev_pm_ops mmci_dev_pm_ops = { 2110f3737fa3SUlf Hansson SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, 2111f3737fa3SUlf Hansson pm_runtime_force_resume) 21126ed23b80SRafael J. Wysocki SET_RUNTIME_PM_OPS(mmci_runtime_suspend, mmci_runtime_resume, NULL) 211348fa7003SUlf Hansson }; 211448fa7003SUlf Hansson 211588411deaSArvind Yadav static const struct amba_id mmci_ids[] = { 21161c6a0718SPierre Ossman { 21171c6a0718SPierre Ossman .id = 0x00041180, 2118768fbc18SPawel Moll .mask = 0xff0fffff, 21194956e109SRabin Vincent .data = &variant_arm, 21201c6a0718SPierre Ossman }, 21211c6a0718SPierre Ossman { 2122768fbc18SPawel Moll .id = 0x01041180, 2123768fbc18SPawel Moll .mask = 0xff0fffff, 2124768fbc18SPawel Moll .data = &variant_arm_extended_fifo, 2125768fbc18SPawel Moll }, 2126768fbc18SPawel Moll { 21273a37298aSPawel Moll .id = 0x02041180, 21283a37298aSPawel Moll .mask = 0xff0fffff, 21293a37298aSPawel Moll .data = &variant_arm_extended_fifo_hwfc, 21303a37298aSPawel Moll }, 21313a37298aSPawel Moll { 21321c6a0718SPierre Ossman .id = 0x00041181, 21331c6a0718SPierre Ossman .mask = 0x000fffff, 21344956e109SRabin Vincent .data = &variant_arm, 21351c6a0718SPierre Ossman }, 2136cc30d60eSLinus Walleij /* ST Micro variants */ 2137cc30d60eSLinus Walleij { 2138cc30d60eSLinus Walleij .id = 0x00180180, 2139cc30d60eSLinus Walleij .mask = 0x00ffffff, 21404956e109SRabin Vincent .data = &variant_u300, 2141cc30d60eSLinus Walleij }, 2142cc30d60eSLinus Walleij { 214334fd4213SLinus Walleij .id = 0x10180180, 214434fd4213SLinus Walleij .mask = 0xf0ffffff, 214534fd4213SLinus Walleij .data = &variant_nomadik, 214634fd4213SLinus Walleij }, 214734fd4213SLinus Walleij { 2148cc30d60eSLinus Walleij .id = 0x00280180, 2149cc30d60eSLinus Walleij .mask = 0x00ffffff, 21500bcb7efdSLinus Walleij .data = &variant_nomadik, 21514956e109SRabin Vincent }, 21524956e109SRabin Vincent { 21534956e109SRabin Vincent .id = 0x00480180, 21541784b157SPhilippe Langlais .mask = 0xf0ffffff, 21554956e109SRabin Vincent .data = &variant_ux500, 2156cc30d60eSLinus Walleij }, 21571784b157SPhilippe Langlais { 21581784b157SPhilippe Langlais .id = 0x10480180, 21591784b157SPhilippe Langlais .mask = 0xf0ffffff, 21601784b157SPhilippe Langlais .data = &variant_ux500v2, 21611784b157SPhilippe Langlais }, 21622a9d6c80SPatrice Chotard { 21632a9d6c80SPatrice Chotard .id = 0x00880180, 21642a9d6c80SPatrice Chotard .mask = 0x00ffffff, 21652a9d6c80SPatrice Chotard .data = &variant_stm32, 21662a9d6c80SPatrice Chotard }, 216755b604aeSSrinivas Kandagatla /* Qualcomm variants */ 216855b604aeSSrinivas Kandagatla { 216955b604aeSSrinivas Kandagatla .id = 0x00051180, 217055b604aeSSrinivas Kandagatla .mask = 0x000fffff, 217155b604aeSSrinivas Kandagatla .data = &variant_qcom, 217255b604aeSSrinivas Kandagatla }, 21731c6a0718SPierre Ossman { 0, 0 }, 21741c6a0718SPierre Ossman }; 21751c6a0718SPierre Ossman 21769f99835fSDave Martin MODULE_DEVICE_TABLE(amba, mmci_ids); 21779f99835fSDave Martin 21781c6a0718SPierre Ossman static struct amba_driver mmci_driver = { 21791c6a0718SPierre Ossman .drv = { 21801c6a0718SPierre Ossman .name = DRIVER_NAME, 218148fa7003SUlf Hansson .pm = &mmci_dev_pm_ops, 21821c6a0718SPierre Ossman }, 21831c6a0718SPierre Ossman .probe = mmci_probe, 21840433c143SBill Pemberton .remove = mmci_remove, 21851c6a0718SPierre Ossman .id_table = mmci_ids, 21861c6a0718SPierre Ossman }; 21871c6a0718SPierre Ossman 21889e5ed094Sviresh kumar module_amba_driver(mmci_driver); 21891c6a0718SPierre Ossman 21901c6a0718SPierre Ossman module_param(fmax, uint, 0444); 21911c6a0718SPierre Ossman 21921c6a0718SPierre Ossman MODULE_DESCRIPTION("ARM PrimeCell PL180/181 Multimedia Card Interface driver"); 21931c6a0718SPierre Ossman MODULE_LICENSE("GPL"); 2194