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> 3189001446SRussell King #include <linux/gpio.h> 329a597016SLee Jones #include <linux/of_gpio.h> 3334e84f39SLinus Walleij #include <linux/regulator/consumer.h> 34c8ebae37SRussell King #include <linux/dmaengine.h> 35c8ebae37SRussell King #include <linux/dma-mapping.h> 36c8ebae37SRussell King #include <linux/amba/mmci.h> 371c3be369SRussell King #include <linux/pm_runtime.h> 38258aea76SViresh Kumar #include <linux/types.h> 39a9a83785SLinus Walleij #include <linux/pinctrl/consumer.h> 401c6a0718SPierre Ossman 411c6a0718SPierre Ossman #include <asm/div64.h> 421c6a0718SPierre Ossman #include <asm/io.h> 431c6a0718SPierre Ossman #include <asm/sizes.h> 441c6a0718SPierre Ossman 451c6a0718SPierre Ossman #include "mmci.h" 461c6a0718SPierre Ossman 471c6a0718SPierre Ossman #define DRIVER_NAME "mmci-pl18x" 481c6a0718SPierre Ossman 491c6a0718SPierre Ossman static unsigned int fmax = 515633; 501c6a0718SPierre Ossman 514956e109SRabin Vincent /** 524956e109SRabin Vincent * struct variant_data - MMCI variant-specific quirks 534956e109SRabin Vincent * @clkreg: default value for MCICLOCK register 544380c14fSRabin Vincent * @clkreg_enable: enable value for MMCICLOCK register 5508458ef6SRabin Vincent * @datalength_bits: number of bits in the MMCIDATALENGTH register 568301bb68SRabin Vincent * @fifosize: number of bytes that can be written when MMCI_TXFIFOEMPTY 578301bb68SRabin Vincent * is asserted (likewise for RX) 588301bb68SRabin Vincent * @fifohalfsize: number of bytes that can be written when MCI_TXFIFOHALFEMPTY 598301bb68SRabin Vincent * is asserted (likewise for RX) 6034177802SLinus Walleij * @sdio: variant supports SDIO 61b70a67f9SLinus Walleij * @st_clkdiv: true if using a ST-specific clock divider algorithm 621784b157SPhilippe Langlais * @blksz_datactrl16: true if Block size is at b16..b30 position in datactrl register 637d72a1d4SUlf Hansson * @pwrreg_powerup: power up value for MMCIPOWER register 644d1a3a0dSUlf Hansson * @signal_direction: input/out direction of bus signals can be indicated 65f4670daeSUlf Hansson * @pwrreg_clkgate: MMCIPOWER register must be used to gate the clock 6601259620SUlf Hansson * @busy_detect: true if busy detection on dat0 is supported 671ff44433SUlf Hansson * @pwrreg_nopower: bits in MMCIPOWER don't controls ext. power supply 684956e109SRabin Vincent */ 694956e109SRabin Vincent struct variant_data { 704956e109SRabin Vincent unsigned int clkreg; 714380c14fSRabin Vincent unsigned int clkreg_enable; 7208458ef6SRabin Vincent unsigned int datalength_bits; 738301bb68SRabin Vincent unsigned int fifosize; 748301bb68SRabin Vincent unsigned int fifohalfsize; 7534177802SLinus Walleij bool sdio; 76b70a67f9SLinus Walleij bool st_clkdiv; 771784b157SPhilippe Langlais bool blksz_datactrl16; 787d72a1d4SUlf Hansson u32 pwrreg_powerup; 794d1a3a0dSUlf Hansson bool signal_direction; 80f4670daeSUlf Hansson bool pwrreg_clkgate; 8101259620SUlf Hansson bool busy_detect; 821ff44433SUlf Hansson bool pwrreg_nopower; 834956e109SRabin Vincent }; 844956e109SRabin Vincent 854956e109SRabin Vincent static struct variant_data variant_arm = { 868301bb68SRabin Vincent .fifosize = 16 * 4, 878301bb68SRabin Vincent .fifohalfsize = 8 * 4, 8808458ef6SRabin Vincent .datalength_bits = 16, 897d72a1d4SUlf Hansson .pwrreg_powerup = MCI_PWR_UP, 904956e109SRabin Vincent }; 914956e109SRabin Vincent 92768fbc18SPawel Moll static struct variant_data variant_arm_extended_fifo = { 93768fbc18SPawel Moll .fifosize = 128 * 4, 94768fbc18SPawel Moll .fifohalfsize = 64 * 4, 95768fbc18SPawel Moll .datalength_bits = 16, 967d72a1d4SUlf Hansson .pwrreg_powerup = MCI_PWR_UP, 97768fbc18SPawel Moll }; 98768fbc18SPawel Moll 993a37298aSPawel Moll static struct variant_data variant_arm_extended_fifo_hwfc = { 1003a37298aSPawel Moll .fifosize = 128 * 4, 1013a37298aSPawel Moll .fifohalfsize = 64 * 4, 1023a37298aSPawel Moll .clkreg_enable = MCI_ARM_HWFCEN, 1033a37298aSPawel Moll .datalength_bits = 16, 1043a37298aSPawel Moll .pwrreg_powerup = MCI_PWR_UP, 1053a37298aSPawel Moll }; 1063a37298aSPawel Moll 1074956e109SRabin Vincent static struct variant_data variant_u300 = { 1088301bb68SRabin Vincent .fifosize = 16 * 4, 1098301bb68SRabin Vincent .fifohalfsize = 8 * 4, 11049ac215eSLinus Walleij .clkreg_enable = MCI_ST_U300_HWFCEN, 11108458ef6SRabin Vincent .datalength_bits = 16, 11234177802SLinus Walleij .sdio = true, 1137d72a1d4SUlf Hansson .pwrreg_powerup = MCI_PWR_ON, 1144d1a3a0dSUlf Hansson .signal_direction = true, 115f4670daeSUlf Hansson .pwrreg_clkgate = true, 1161ff44433SUlf Hansson .pwrreg_nopower = true, 1174956e109SRabin Vincent }; 1184956e109SRabin Vincent 11934fd4213SLinus Walleij static struct variant_data variant_nomadik = { 12034fd4213SLinus Walleij .fifosize = 16 * 4, 12134fd4213SLinus Walleij .fifohalfsize = 8 * 4, 12234fd4213SLinus Walleij .clkreg = MCI_CLK_ENABLE, 12334fd4213SLinus Walleij .datalength_bits = 24, 12434fd4213SLinus Walleij .sdio = true, 12534fd4213SLinus Walleij .st_clkdiv = true, 12634fd4213SLinus Walleij .pwrreg_powerup = MCI_PWR_ON, 12734fd4213SLinus Walleij .signal_direction = true, 128f4670daeSUlf Hansson .pwrreg_clkgate = true, 1291ff44433SUlf Hansson .pwrreg_nopower = true, 13034fd4213SLinus Walleij }; 13134fd4213SLinus Walleij 1324956e109SRabin Vincent static struct variant_data variant_ux500 = { 1338301bb68SRabin Vincent .fifosize = 30 * 4, 1348301bb68SRabin Vincent .fifohalfsize = 8 * 4, 1354956e109SRabin Vincent .clkreg = MCI_CLK_ENABLE, 13649ac215eSLinus Walleij .clkreg_enable = MCI_ST_UX500_HWFCEN, 13708458ef6SRabin Vincent .datalength_bits = 24, 13834177802SLinus Walleij .sdio = true, 139b70a67f9SLinus Walleij .st_clkdiv = true, 1407d72a1d4SUlf Hansson .pwrreg_powerup = MCI_PWR_ON, 1414d1a3a0dSUlf Hansson .signal_direction = true, 142f4670daeSUlf Hansson .pwrreg_clkgate = true, 14301259620SUlf Hansson .busy_detect = true, 1441ff44433SUlf Hansson .pwrreg_nopower = true, 1454956e109SRabin Vincent }; 146b70a67f9SLinus Walleij 1471784b157SPhilippe Langlais static struct variant_data variant_ux500v2 = { 1481784b157SPhilippe Langlais .fifosize = 30 * 4, 1491784b157SPhilippe Langlais .fifohalfsize = 8 * 4, 1501784b157SPhilippe Langlais .clkreg = MCI_CLK_ENABLE, 1511784b157SPhilippe Langlais .clkreg_enable = MCI_ST_UX500_HWFCEN, 1521784b157SPhilippe Langlais .datalength_bits = 24, 1531784b157SPhilippe Langlais .sdio = true, 1541784b157SPhilippe Langlais .st_clkdiv = true, 1551784b157SPhilippe Langlais .blksz_datactrl16 = true, 1567d72a1d4SUlf Hansson .pwrreg_powerup = MCI_PWR_ON, 1574d1a3a0dSUlf Hansson .signal_direction = true, 158f4670daeSUlf Hansson .pwrreg_clkgate = true, 15901259620SUlf Hansson .busy_detect = true, 1601ff44433SUlf Hansson .pwrreg_nopower = true, 1611784b157SPhilippe Langlais }; 1621784b157SPhilippe Langlais 16301259620SUlf Hansson static int mmci_card_busy(struct mmc_host *mmc) 16401259620SUlf Hansson { 16501259620SUlf Hansson struct mmci_host *host = mmc_priv(mmc); 16601259620SUlf Hansson unsigned long flags; 16701259620SUlf Hansson int busy = 0; 16801259620SUlf Hansson 16901259620SUlf Hansson pm_runtime_get_sync(mmc_dev(mmc)); 17001259620SUlf Hansson 17101259620SUlf Hansson spin_lock_irqsave(&host->lock, flags); 17201259620SUlf Hansson if (readl(host->base + MMCISTATUS) & MCI_ST_CARDBUSY) 17301259620SUlf Hansson busy = 1; 17401259620SUlf Hansson spin_unlock_irqrestore(&host->lock, flags); 17501259620SUlf Hansson 17601259620SUlf Hansson pm_runtime_mark_last_busy(mmc_dev(mmc)); 17701259620SUlf Hansson pm_runtime_put_autosuspend(mmc_dev(mmc)); 17801259620SUlf Hansson 17901259620SUlf Hansson return busy; 18001259620SUlf Hansson } 18101259620SUlf Hansson 182a6a6464aSLinus Walleij /* 183653a761eSUlf Hansson * Validate mmc prerequisites 184653a761eSUlf Hansson */ 185653a761eSUlf Hansson static int mmci_validate_data(struct mmci_host *host, 186653a761eSUlf Hansson struct mmc_data *data) 187653a761eSUlf Hansson { 188653a761eSUlf Hansson if (!data) 189653a761eSUlf Hansson return 0; 190653a761eSUlf Hansson 191653a761eSUlf Hansson if (!is_power_of_2(data->blksz)) { 192653a761eSUlf Hansson dev_err(mmc_dev(host->mmc), 193653a761eSUlf Hansson "unsupported block size (%d bytes)\n", data->blksz); 194653a761eSUlf Hansson return -EINVAL; 195653a761eSUlf Hansson } 196653a761eSUlf Hansson 197653a761eSUlf Hansson return 0; 198653a761eSUlf Hansson } 199653a761eSUlf Hansson 200f829c042SUlf Hansson static void mmci_reg_delay(struct mmci_host *host) 201f829c042SUlf Hansson { 202f829c042SUlf Hansson /* 203f829c042SUlf Hansson * According to the spec, at least three feedback clock cycles 204f829c042SUlf Hansson * of max 52 MHz must pass between two writes to the MMCICLOCK reg. 205f829c042SUlf Hansson * Three MCLK clock cycles must pass between two MMCIPOWER reg writes. 206f829c042SUlf Hansson * Worst delay time during card init is at 100 kHz => 30 us. 207f829c042SUlf Hansson * Worst delay time when up and running is at 25 MHz => 120 ns. 208f829c042SUlf Hansson */ 209f829c042SUlf Hansson if (host->cclk < 25000000) 210f829c042SUlf Hansson udelay(30); 211f829c042SUlf Hansson else 212f829c042SUlf Hansson ndelay(120); 213f829c042SUlf Hansson } 214f829c042SUlf Hansson 215653a761eSUlf Hansson /* 216a6a6464aSLinus Walleij * This must be called with host->lock held 217a6a6464aSLinus Walleij */ 2187437cfa5SUlf Hansson static void mmci_write_clkreg(struct mmci_host *host, u32 clk) 2197437cfa5SUlf Hansson { 2207437cfa5SUlf Hansson if (host->clk_reg != clk) { 2217437cfa5SUlf Hansson host->clk_reg = clk; 2227437cfa5SUlf Hansson writel(clk, host->base + MMCICLOCK); 2237437cfa5SUlf Hansson } 2247437cfa5SUlf Hansson } 2257437cfa5SUlf Hansson 2267437cfa5SUlf Hansson /* 2277437cfa5SUlf Hansson * This must be called with host->lock held 2287437cfa5SUlf Hansson */ 2297437cfa5SUlf Hansson static void mmci_write_pwrreg(struct mmci_host *host, u32 pwr) 2307437cfa5SUlf Hansson { 2317437cfa5SUlf Hansson if (host->pwr_reg != pwr) { 2327437cfa5SUlf Hansson host->pwr_reg = pwr; 2337437cfa5SUlf Hansson writel(pwr, host->base + MMCIPOWER); 2347437cfa5SUlf Hansson } 2357437cfa5SUlf Hansson } 2367437cfa5SUlf Hansson 2377437cfa5SUlf Hansson /* 2387437cfa5SUlf Hansson * This must be called with host->lock held 2397437cfa5SUlf Hansson */ 2409cc639a2SUlf Hansson static void mmci_write_datactrlreg(struct mmci_host *host, u32 datactrl) 2419cc639a2SUlf Hansson { 24201259620SUlf Hansson /* Keep ST Micro busy mode if enabled */ 24301259620SUlf Hansson datactrl |= host->datactrl_reg & MCI_ST_DPSM_BUSYMODE; 24401259620SUlf Hansson 2459cc639a2SUlf Hansson if (host->datactrl_reg != datactrl) { 2469cc639a2SUlf Hansson host->datactrl_reg = datactrl; 2479cc639a2SUlf Hansson writel(datactrl, host->base + MMCIDATACTRL); 2489cc639a2SUlf Hansson } 2499cc639a2SUlf Hansson } 2509cc639a2SUlf Hansson 2519cc639a2SUlf Hansson /* 2529cc639a2SUlf Hansson * This must be called with host->lock held 2539cc639a2SUlf Hansson */ 254a6a6464aSLinus Walleij static void mmci_set_clkreg(struct mmci_host *host, unsigned int desired) 255a6a6464aSLinus Walleij { 2564956e109SRabin Vincent struct variant_data *variant = host->variant; 2574956e109SRabin Vincent u32 clk = variant->clkreg; 258a6a6464aSLinus Walleij 259c58a8509SUlf Hansson /* Make sure cclk reflects the current calculated clock */ 260c58a8509SUlf Hansson host->cclk = 0; 261c58a8509SUlf Hansson 262a6a6464aSLinus Walleij if (desired) { 263a6a6464aSLinus Walleij if (desired >= host->mclk) { 264a6a6464aSLinus Walleij clk = MCI_CLK_BYPASS; 265399bc486SLinus Walleij if (variant->st_clkdiv) 266399bc486SLinus Walleij clk |= MCI_ST_UX500_NEG_EDGE; 267a6a6464aSLinus Walleij host->cclk = host->mclk; 268b70a67f9SLinus Walleij } else if (variant->st_clkdiv) { 269b70a67f9SLinus Walleij /* 270b70a67f9SLinus Walleij * DB8500 TRM says f = mclk / (clkdiv + 2) 271b70a67f9SLinus Walleij * => clkdiv = (mclk / f) - 2 272b70a67f9SLinus Walleij * Round the divider up so we don't exceed the max 273b70a67f9SLinus Walleij * frequency 274b70a67f9SLinus Walleij */ 275b70a67f9SLinus Walleij clk = DIV_ROUND_UP(host->mclk, desired) - 2; 276b70a67f9SLinus Walleij if (clk >= 256) 277b70a67f9SLinus Walleij clk = 255; 278b70a67f9SLinus Walleij host->cclk = host->mclk / (clk + 2); 279a6a6464aSLinus Walleij } else { 280b70a67f9SLinus Walleij /* 281b70a67f9SLinus Walleij * PL180 TRM says f = mclk / (2 * (clkdiv + 1)) 282b70a67f9SLinus Walleij * => clkdiv = mclk / (2 * f) - 1 283b70a67f9SLinus Walleij */ 284a6a6464aSLinus Walleij clk = host->mclk / (2 * desired) - 1; 285a6a6464aSLinus Walleij if (clk >= 256) 286a6a6464aSLinus Walleij clk = 255; 287a6a6464aSLinus Walleij host->cclk = host->mclk / (2 * (clk + 1)); 288a6a6464aSLinus Walleij } 2894380c14fSRabin Vincent 2904380c14fSRabin Vincent clk |= variant->clkreg_enable; 291a6a6464aSLinus Walleij clk |= MCI_CLK_ENABLE; 292a6a6464aSLinus Walleij /* This hasn't proven to be worthwhile */ 293a6a6464aSLinus Walleij /* clk |= MCI_CLK_PWRSAVE; */ 294a6a6464aSLinus Walleij } 295a6a6464aSLinus Walleij 296c58a8509SUlf Hansson /* Set actual clock for debug */ 297c58a8509SUlf Hansson host->mmc->actual_clock = host->cclk; 298c58a8509SUlf Hansson 2999e6c82cdSLinus Walleij if (host->mmc->ios.bus_width == MMC_BUS_WIDTH_4) 300771dc157SLinus Walleij clk |= MCI_4BIT_BUS; 301771dc157SLinus Walleij if (host->mmc->ios.bus_width == MMC_BUS_WIDTH_8) 302771dc157SLinus Walleij clk |= MCI_ST_8BIT_BUS; 3039e6c82cdSLinus Walleij 3046dbb6ee0SUlf Hansson if (host->mmc->ios.timing == MMC_TIMING_UHS_DDR50) 3056dbb6ee0SUlf Hansson clk |= MCI_ST_UX500_NEG_EDGE; 3066dbb6ee0SUlf Hansson 3077437cfa5SUlf Hansson mmci_write_clkreg(host, clk); 308a6a6464aSLinus Walleij } 309a6a6464aSLinus Walleij 3101c6a0718SPierre Ossman static void 3111c6a0718SPierre Ossman mmci_request_end(struct mmci_host *host, struct mmc_request *mrq) 3121c6a0718SPierre Ossman { 3131c6a0718SPierre Ossman writel(0, host->base + MMCICOMMAND); 3141c6a0718SPierre Ossman 3151c6a0718SPierre Ossman BUG_ON(host->data); 3161c6a0718SPierre Ossman 3171c6a0718SPierre Ossman host->mrq = NULL; 3181c6a0718SPierre Ossman host->cmd = NULL; 3191c6a0718SPierre Ossman 3201c6a0718SPierre Ossman mmc_request_done(host->mmc, mrq); 3212cd976c4SUlf Hansson 3222cd976c4SUlf Hansson pm_runtime_mark_last_busy(mmc_dev(host->mmc)); 3232cd976c4SUlf Hansson pm_runtime_put_autosuspend(mmc_dev(host->mmc)); 3241c6a0718SPierre Ossman } 3251c6a0718SPierre Ossman 3262686b4b4SLinus Walleij static void mmci_set_mask1(struct mmci_host *host, unsigned int mask) 3272686b4b4SLinus Walleij { 3282686b4b4SLinus Walleij void __iomem *base = host->base; 3292686b4b4SLinus Walleij 3302686b4b4SLinus Walleij if (host->singleirq) { 3312686b4b4SLinus Walleij unsigned int mask0 = readl(base + MMCIMASK0); 3322686b4b4SLinus Walleij 3332686b4b4SLinus Walleij mask0 &= ~MCI_IRQ1MASK; 3342686b4b4SLinus Walleij mask0 |= mask; 3352686b4b4SLinus Walleij 3362686b4b4SLinus Walleij writel(mask0, base + MMCIMASK0); 3372686b4b4SLinus Walleij } 3382686b4b4SLinus Walleij 3392686b4b4SLinus Walleij writel(mask, base + MMCIMASK1); 3402686b4b4SLinus Walleij } 3412686b4b4SLinus Walleij 3421c6a0718SPierre Ossman static void mmci_stop_data(struct mmci_host *host) 3431c6a0718SPierre Ossman { 3449cc639a2SUlf Hansson mmci_write_datactrlreg(host, 0); 3452686b4b4SLinus Walleij mmci_set_mask1(host, 0); 3461c6a0718SPierre Ossman host->data = NULL; 3471c6a0718SPierre Ossman } 3481c6a0718SPierre Ossman 3494ce1d6cbSRabin Vincent static void mmci_init_sg(struct mmci_host *host, struct mmc_data *data) 3504ce1d6cbSRabin Vincent { 3514ce1d6cbSRabin Vincent unsigned int flags = SG_MITER_ATOMIC; 3524ce1d6cbSRabin Vincent 3534ce1d6cbSRabin Vincent if (data->flags & MMC_DATA_READ) 3544ce1d6cbSRabin Vincent flags |= SG_MITER_TO_SG; 3554ce1d6cbSRabin Vincent else 3564ce1d6cbSRabin Vincent flags |= SG_MITER_FROM_SG; 3574ce1d6cbSRabin Vincent 3584ce1d6cbSRabin Vincent sg_miter_start(&host->sg_miter, data->sg, data->sg_len, flags); 3594ce1d6cbSRabin Vincent } 3604ce1d6cbSRabin Vincent 361c8ebae37SRussell King /* 362c8ebae37SRussell King * All the DMA operation mode stuff goes inside this ifdef. 363c8ebae37SRussell King * This assumes that you have a generic DMA device interface, 364c8ebae37SRussell King * no custom DMA interfaces are supported. 365c8ebae37SRussell King */ 366c8ebae37SRussell King #ifdef CONFIG_DMA_ENGINE 367c3be1efdSBill Pemberton static void mmci_dma_setup(struct mmci_host *host) 368c8ebae37SRussell King { 369c8ebae37SRussell King struct mmci_platform_data *plat = host->plat; 370c8ebae37SRussell King const char *rxname, *txname; 371c8ebae37SRussell King dma_cap_mask_t mask; 372c8ebae37SRussell King 3731fd83f0eSLee Jones host->dma_rx_channel = dma_request_slave_channel(mmc_dev(host->mmc), "rx"); 3741fd83f0eSLee Jones host->dma_tx_channel = dma_request_slave_channel(mmc_dev(host->mmc), "tx"); 375c8ebae37SRussell King 37658c7ccbfSPer Forlin /* initialize pre request cookie */ 37758c7ccbfSPer Forlin host->next_data.cookie = 1; 37858c7ccbfSPer Forlin 379c8ebae37SRussell King /* Try to acquire a generic DMA engine slave channel */ 380c8ebae37SRussell King dma_cap_zero(mask); 381c8ebae37SRussell King dma_cap_set(DMA_SLAVE, mask); 382c8ebae37SRussell King 3831fd83f0eSLee Jones if (plat && plat->dma_filter) { 3841fd83f0eSLee Jones if (!host->dma_rx_channel && plat->dma_rx_param) { 385c8ebae37SRussell King host->dma_rx_channel = dma_request_channel(mask, 386c8ebae37SRussell King plat->dma_filter, 387c8ebae37SRussell King plat->dma_rx_param); 388c8ebae37SRussell King /* E.g if no DMA hardware is present */ 389c8ebae37SRussell King if (!host->dma_rx_channel) 390c8ebae37SRussell King dev_err(mmc_dev(host->mmc), "no RX DMA channel\n"); 391c8ebae37SRussell King } 392c8ebae37SRussell King 3931fd83f0eSLee Jones if (!host->dma_tx_channel && plat->dma_tx_param) { 394c8ebae37SRussell King host->dma_tx_channel = dma_request_channel(mask, 395c8ebae37SRussell King plat->dma_filter, 396c8ebae37SRussell King plat->dma_tx_param); 397c8ebae37SRussell King if (!host->dma_tx_channel) 398c8ebae37SRussell King dev_warn(mmc_dev(host->mmc), "no TX DMA channel\n"); 399c8ebae37SRussell King } 4001fd83f0eSLee Jones } 4011fd83f0eSLee Jones 4021fd83f0eSLee Jones /* 4031fd83f0eSLee Jones * If only an RX channel is specified, the driver will 4041fd83f0eSLee Jones * attempt to use it bidirectionally, however if it is 4051fd83f0eSLee Jones * is specified but cannot be located, DMA will be disabled. 4061fd83f0eSLee Jones */ 4071fd83f0eSLee Jones if (host->dma_rx_channel && !host->dma_tx_channel) 4081fd83f0eSLee Jones host->dma_tx_channel = host->dma_rx_channel; 409c8ebae37SRussell King 410c8ebae37SRussell King if (host->dma_rx_channel) 411c8ebae37SRussell King rxname = dma_chan_name(host->dma_rx_channel); 412c8ebae37SRussell King else 413c8ebae37SRussell King rxname = "none"; 414c8ebae37SRussell King 415c8ebae37SRussell King if (host->dma_tx_channel) 416c8ebae37SRussell King txname = dma_chan_name(host->dma_tx_channel); 417c8ebae37SRussell King else 418c8ebae37SRussell King txname = "none"; 419c8ebae37SRussell King 420c8ebae37SRussell King dev_info(mmc_dev(host->mmc), "DMA channels RX %s, TX %s\n", 421c8ebae37SRussell King rxname, txname); 422c8ebae37SRussell King 423c8ebae37SRussell King /* 424c8ebae37SRussell King * Limit the maximum segment size in any SG entry according to 425c8ebae37SRussell King * the parameters of the DMA engine device. 426c8ebae37SRussell King */ 427c8ebae37SRussell King if (host->dma_tx_channel) { 428c8ebae37SRussell King struct device *dev = host->dma_tx_channel->device->dev; 429c8ebae37SRussell King unsigned int max_seg_size = dma_get_max_seg_size(dev); 430c8ebae37SRussell King 431c8ebae37SRussell King if (max_seg_size < host->mmc->max_seg_size) 432c8ebae37SRussell King host->mmc->max_seg_size = max_seg_size; 433c8ebae37SRussell King } 434c8ebae37SRussell King if (host->dma_rx_channel) { 435c8ebae37SRussell King struct device *dev = host->dma_rx_channel->device->dev; 436c8ebae37SRussell King unsigned int max_seg_size = dma_get_max_seg_size(dev); 437c8ebae37SRussell King 438c8ebae37SRussell King if (max_seg_size < host->mmc->max_seg_size) 439c8ebae37SRussell King host->mmc->max_seg_size = max_seg_size; 440c8ebae37SRussell King } 441c8ebae37SRussell King } 442c8ebae37SRussell King 443c8ebae37SRussell King /* 4446e0ee714SBill Pemberton * This is used in or so inline it 445c8ebae37SRussell King * so it can be discarded. 446c8ebae37SRussell King */ 447c8ebae37SRussell King static inline void mmci_dma_release(struct mmci_host *host) 448c8ebae37SRussell King { 449c8ebae37SRussell King struct mmci_platform_data *plat = host->plat; 450c8ebae37SRussell King 451c8ebae37SRussell King if (host->dma_rx_channel) 452c8ebae37SRussell King dma_release_channel(host->dma_rx_channel); 453c8ebae37SRussell King if (host->dma_tx_channel && plat->dma_tx_param) 454c8ebae37SRussell King dma_release_channel(host->dma_tx_channel); 455c8ebae37SRussell King host->dma_rx_channel = host->dma_tx_channel = NULL; 456c8ebae37SRussell King } 457c8ebae37SRussell King 458653a761eSUlf Hansson static void mmci_dma_data_error(struct mmci_host *host) 459653a761eSUlf Hansson { 460653a761eSUlf Hansson dev_err(mmc_dev(host->mmc), "error during DMA transfer!\n"); 461653a761eSUlf Hansson dmaengine_terminate_all(host->dma_current); 462653a761eSUlf Hansson host->dma_current = NULL; 463653a761eSUlf Hansson host->dma_desc_current = NULL; 464653a761eSUlf Hansson host->data->host_cookie = 0; 465653a761eSUlf Hansson } 466653a761eSUlf Hansson 467c8ebae37SRussell King static void mmci_dma_unmap(struct mmci_host *host, struct mmc_data *data) 468c8ebae37SRussell King { 469653a761eSUlf Hansson struct dma_chan *chan; 470c8ebae37SRussell King enum dma_data_direction dir; 471653a761eSUlf Hansson 472653a761eSUlf Hansson if (data->flags & MMC_DATA_READ) { 473653a761eSUlf Hansson dir = DMA_FROM_DEVICE; 474653a761eSUlf Hansson chan = host->dma_rx_channel; 475653a761eSUlf Hansson } else { 476653a761eSUlf Hansson dir = DMA_TO_DEVICE; 477653a761eSUlf Hansson chan = host->dma_tx_channel; 478653a761eSUlf Hansson } 479653a761eSUlf Hansson 480653a761eSUlf Hansson dma_unmap_sg(chan->device->dev, data->sg, data->sg_len, dir); 481653a761eSUlf Hansson } 482653a761eSUlf Hansson 483653a761eSUlf Hansson static void mmci_dma_finalize(struct mmci_host *host, struct mmc_data *data) 484653a761eSUlf Hansson { 485c8ebae37SRussell King u32 status; 486c8ebae37SRussell King int i; 487c8ebae37SRussell King 488c8ebae37SRussell King /* Wait up to 1ms for the DMA to complete */ 489c8ebae37SRussell King for (i = 0; ; i++) { 490c8ebae37SRussell King status = readl(host->base + MMCISTATUS); 491c8ebae37SRussell King if (!(status & MCI_RXDATAAVLBLMASK) || i >= 100) 492c8ebae37SRussell King break; 493c8ebae37SRussell King udelay(10); 494c8ebae37SRussell King } 495c8ebae37SRussell King 496c8ebae37SRussell King /* 497c8ebae37SRussell King * Check to see whether we still have some data left in the FIFO - 498c8ebae37SRussell King * this catches DMA controllers which are unable to monitor the 499c8ebae37SRussell King * DMALBREQ and DMALSREQ signals while allowing us to DMA to non- 500c8ebae37SRussell King * contiguous buffers. On TX, we'll get a FIFO underrun error. 501c8ebae37SRussell King */ 502c8ebae37SRussell King if (status & MCI_RXDATAAVLBLMASK) { 503653a761eSUlf Hansson mmci_dma_data_error(host); 504c8ebae37SRussell King if (!data->error) 505c8ebae37SRussell King data->error = -EIO; 506c8ebae37SRussell King } 507c8ebae37SRussell King 50858c7ccbfSPer Forlin if (!data->host_cookie) 509653a761eSUlf Hansson mmci_dma_unmap(host, data); 510c8ebae37SRussell King 511c8ebae37SRussell King /* 512c8ebae37SRussell King * Use of DMA with scatter-gather is impossible. 513c8ebae37SRussell King * Give up with DMA and switch back to PIO mode. 514c8ebae37SRussell King */ 515c8ebae37SRussell King if (status & MCI_RXDATAAVLBLMASK) { 516c8ebae37SRussell King dev_err(mmc_dev(host->mmc), "buggy DMA detected. Taking evasive action.\n"); 517c8ebae37SRussell King mmci_dma_release(host); 518c8ebae37SRussell King } 519653a761eSUlf Hansson 520653a761eSUlf Hansson host->dma_current = NULL; 521653a761eSUlf Hansson host->dma_desc_current = NULL; 522c8ebae37SRussell King } 523c8ebae37SRussell King 524653a761eSUlf Hansson /* prepares DMA channel and DMA descriptor, returns non-zero on failure */ 525653a761eSUlf Hansson static int __mmci_dma_prep_data(struct mmci_host *host, struct mmc_data *data, 526653a761eSUlf Hansson struct dma_chan **dma_chan, 527653a761eSUlf Hansson struct dma_async_tx_descriptor **dma_desc) 528c8ebae37SRussell King { 529c8ebae37SRussell King struct variant_data *variant = host->variant; 530c8ebae37SRussell King struct dma_slave_config conf = { 531c8ebae37SRussell King .src_addr = host->phybase + MMCIFIFO, 532c8ebae37SRussell King .dst_addr = host->phybase + MMCIFIFO, 533c8ebae37SRussell King .src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES, 534c8ebae37SRussell King .dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES, 535c8ebae37SRussell King .src_maxburst = variant->fifohalfsize >> 2, /* # of words */ 536c8ebae37SRussell King .dst_maxburst = variant->fifohalfsize >> 2, /* # of words */ 537258aea76SViresh Kumar .device_fc = false, 538c8ebae37SRussell King }; 539c8ebae37SRussell King struct dma_chan *chan; 540c8ebae37SRussell King struct dma_device *device; 541c8ebae37SRussell King struct dma_async_tx_descriptor *desc; 54205f5799cSVinod Koul enum dma_data_direction buffer_dirn; 543c8ebae37SRussell King int nr_sg; 544c8ebae37SRussell King 545c8ebae37SRussell King if (data->flags & MMC_DATA_READ) { 54605f5799cSVinod Koul conf.direction = DMA_DEV_TO_MEM; 54705f5799cSVinod Koul buffer_dirn = DMA_FROM_DEVICE; 548c8ebae37SRussell King chan = host->dma_rx_channel; 549c8ebae37SRussell King } else { 55005f5799cSVinod Koul conf.direction = DMA_MEM_TO_DEV; 55105f5799cSVinod Koul buffer_dirn = DMA_TO_DEVICE; 552c8ebae37SRussell King chan = host->dma_tx_channel; 553c8ebae37SRussell King } 554c8ebae37SRussell King 555c8ebae37SRussell King /* If there's no DMA channel, fall back to PIO */ 556c8ebae37SRussell King if (!chan) 557c8ebae37SRussell King return -EINVAL; 558c8ebae37SRussell King 559c8ebae37SRussell King /* If less than or equal to the fifo size, don't bother with DMA */ 56058c7ccbfSPer Forlin if (data->blksz * data->blocks <= variant->fifosize) 561c8ebae37SRussell King return -EINVAL; 562c8ebae37SRussell King 563c8ebae37SRussell King device = chan->device; 56405f5799cSVinod Koul nr_sg = dma_map_sg(device->dev, data->sg, data->sg_len, buffer_dirn); 565c8ebae37SRussell King if (nr_sg == 0) 566c8ebae37SRussell King return -EINVAL; 567c8ebae37SRussell King 568c8ebae37SRussell King dmaengine_slave_config(chan, &conf); 56916052827SAlexandre Bounine desc = dmaengine_prep_slave_sg(chan, data->sg, nr_sg, 570c8ebae37SRussell King conf.direction, DMA_CTRL_ACK); 571c8ebae37SRussell King if (!desc) 572c8ebae37SRussell King goto unmap_exit; 573c8ebae37SRussell King 574653a761eSUlf Hansson *dma_chan = chan; 575653a761eSUlf Hansson *dma_desc = desc; 576c8ebae37SRussell King 57758c7ccbfSPer Forlin return 0; 57858c7ccbfSPer Forlin 57958c7ccbfSPer Forlin unmap_exit: 58005f5799cSVinod Koul dma_unmap_sg(device->dev, data->sg, data->sg_len, buffer_dirn); 58158c7ccbfSPer Forlin return -ENOMEM; 58258c7ccbfSPer Forlin } 58358c7ccbfSPer Forlin 584653a761eSUlf Hansson static inline int mmci_dma_prep_data(struct mmci_host *host, 585653a761eSUlf Hansson struct mmc_data *data) 586653a761eSUlf Hansson { 587653a761eSUlf Hansson /* Check if next job is already prepared. */ 588653a761eSUlf Hansson if (host->dma_current && host->dma_desc_current) 589653a761eSUlf Hansson return 0; 590653a761eSUlf Hansson 591653a761eSUlf Hansson /* No job were prepared thus do it now. */ 592653a761eSUlf Hansson return __mmci_dma_prep_data(host, data, &host->dma_current, 593653a761eSUlf Hansson &host->dma_desc_current); 594653a761eSUlf Hansson } 595653a761eSUlf Hansson 596653a761eSUlf Hansson static inline int mmci_dma_prep_next(struct mmci_host *host, 597653a761eSUlf Hansson struct mmc_data *data) 598653a761eSUlf Hansson { 599653a761eSUlf Hansson struct mmci_host_next *nd = &host->next_data; 600653a761eSUlf Hansson return __mmci_dma_prep_data(host, data, &nd->dma_chan, &nd->dma_desc); 601653a761eSUlf Hansson } 602653a761eSUlf Hansson 60358c7ccbfSPer Forlin static int mmci_dma_start_data(struct mmci_host *host, unsigned int datactrl) 60458c7ccbfSPer Forlin { 60558c7ccbfSPer Forlin int ret; 60658c7ccbfSPer Forlin struct mmc_data *data = host->data; 60758c7ccbfSPer Forlin 608653a761eSUlf Hansson ret = mmci_dma_prep_data(host, host->data); 60958c7ccbfSPer Forlin if (ret) 61058c7ccbfSPer Forlin return ret; 61158c7ccbfSPer Forlin 61258c7ccbfSPer Forlin /* Okay, go for it. */ 613c8ebae37SRussell King dev_vdbg(mmc_dev(host->mmc), 614c8ebae37SRussell King "Submit MMCI DMA job, sglen %d blksz %04x blks %04x flags %08x\n", 615c8ebae37SRussell King data->sg_len, data->blksz, data->blocks, data->flags); 61658c7ccbfSPer Forlin dmaengine_submit(host->dma_desc_current); 61758c7ccbfSPer Forlin dma_async_issue_pending(host->dma_current); 618c8ebae37SRussell King 619c8ebae37SRussell King datactrl |= MCI_DPSM_DMAENABLE; 620c8ebae37SRussell King 621c8ebae37SRussell King /* Trigger the DMA transfer */ 6229cc639a2SUlf Hansson mmci_write_datactrlreg(host, datactrl); 623c8ebae37SRussell King 624c8ebae37SRussell King /* 625c8ebae37SRussell King * Let the MMCI say when the data is ended and it's time 626c8ebae37SRussell King * to fire next DMA request. When that happens, MMCI will 627c8ebae37SRussell King * call mmci_data_end() 628c8ebae37SRussell King */ 629c8ebae37SRussell King writel(readl(host->base + MMCIMASK0) | MCI_DATAENDMASK, 630c8ebae37SRussell King host->base + MMCIMASK0); 631c8ebae37SRussell King return 0; 632c8ebae37SRussell King } 63358c7ccbfSPer Forlin 63458c7ccbfSPer Forlin static void mmci_get_next_data(struct mmci_host *host, struct mmc_data *data) 63558c7ccbfSPer Forlin { 63658c7ccbfSPer Forlin struct mmci_host_next *next = &host->next_data; 63758c7ccbfSPer Forlin 638653a761eSUlf Hansson WARN_ON(data->host_cookie && data->host_cookie != next->cookie); 639653a761eSUlf Hansson WARN_ON(!data->host_cookie && (next->dma_desc || next->dma_chan)); 64058c7ccbfSPer Forlin 64158c7ccbfSPer Forlin host->dma_desc_current = next->dma_desc; 64258c7ccbfSPer Forlin host->dma_current = next->dma_chan; 64358c7ccbfSPer Forlin next->dma_desc = NULL; 64458c7ccbfSPer Forlin next->dma_chan = NULL; 64558c7ccbfSPer Forlin } 64658c7ccbfSPer Forlin 64758c7ccbfSPer Forlin static void mmci_pre_request(struct mmc_host *mmc, struct mmc_request *mrq, 64858c7ccbfSPer Forlin bool is_first_req) 64958c7ccbfSPer Forlin { 65058c7ccbfSPer Forlin struct mmci_host *host = mmc_priv(mmc); 65158c7ccbfSPer Forlin struct mmc_data *data = mrq->data; 65258c7ccbfSPer Forlin struct mmci_host_next *nd = &host->next_data; 65358c7ccbfSPer Forlin 65458c7ccbfSPer Forlin if (!data) 65558c7ccbfSPer Forlin return; 65658c7ccbfSPer Forlin 657653a761eSUlf Hansson BUG_ON(data->host_cookie); 65858c7ccbfSPer Forlin 659653a761eSUlf Hansson if (mmci_validate_data(host, data)) 660653a761eSUlf Hansson return; 661653a761eSUlf Hansson 662653a761eSUlf Hansson if (!mmci_dma_prep_next(host, data)) 66358c7ccbfSPer Forlin data->host_cookie = ++nd->cookie < 0 ? 1 : nd->cookie; 66458c7ccbfSPer Forlin } 66558c7ccbfSPer Forlin 66658c7ccbfSPer Forlin static void mmci_post_request(struct mmc_host *mmc, struct mmc_request *mrq, 66758c7ccbfSPer Forlin int err) 66858c7ccbfSPer Forlin { 66958c7ccbfSPer Forlin struct mmci_host *host = mmc_priv(mmc); 67058c7ccbfSPer Forlin struct mmc_data *data = mrq->data; 67158c7ccbfSPer Forlin 672653a761eSUlf Hansson if (!data || !data->host_cookie) 67358c7ccbfSPer Forlin return; 67458c7ccbfSPer Forlin 675653a761eSUlf Hansson mmci_dma_unmap(host, data); 676653a761eSUlf Hansson 677653a761eSUlf Hansson if (err) { 678653a761eSUlf Hansson struct mmci_host_next *next = &host->next_data; 679653a761eSUlf Hansson struct dma_chan *chan; 680653a761eSUlf Hansson if (data->flags & MMC_DATA_READ) 68158c7ccbfSPer Forlin chan = host->dma_rx_channel; 682653a761eSUlf Hansson else 68358c7ccbfSPer Forlin chan = host->dma_tx_channel; 68458c7ccbfSPer Forlin dmaengine_terminate_all(chan); 685653a761eSUlf Hansson 686653a761eSUlf Hansson next->dma_desc = NULL; 687653a761eSUlf Hansson next->dma_chan = NULL; 68858c7ccbfSPer Forlin } 68958c7ccbfSPer Forlin } 69058c7ccbfSPer Forlin 691c8ebae37SRussell King #else 692c8ebae37SRussell King /* Blank functions if the DMA engine is not available */ 69358c7ccbfSPer Forlin static void mmci_get_next_data(struct mmci_host *host, struct mmc_data *data) 69458c7ccbfSPer Forlin { 69558c7ccbfSPer Forlin } 696c8ebae37SRussell King static inline void mmci_dma_setup(struct mmci_host *host) 697c8ebae37SRussell King { 698c8ebae37SRussell King } 699c8ebae37SRussell King 700c8ebae37SRussell King static inline void mmci_dma_release(struct mmci_host *host) 701c8ebae37SRussell King { 702c8ebae37SRussell King } 703c8ebae37SRussell King 704c8ebae37SRussell King static inline void mmci_dma_unmap(struct mmci_host *host, struct mmc_data *data) 705c8ebae37SRussell King { 706c8ebae37SRussell King } 707c8ebae37SRussell King 708653a761eSUlf Hansson static inline void mmci_dma_finalize(struct mmci_host *host, 709653a761eSUlf Hansson struct mmc_data *data) 710653a761eSUlf Hansson { 711653a761eSUlf Hansson } 712653a761eSUlf Hansson 713c8ebae37SRussell King static inline void mmci_dma_data_error(struct mmci_host *host) 714c8ebae37SRussell King { 715c8ebae37SRussell King } 716c8ebae37SRussell King 717c8ebae37SRussell King static inline int mmci_dma_start_data(struct mmci_host *host, unsigned int datactrl) 718c8ebae37SRussell King { 719c8ebae37SRussell King return -ENOSYS; 720c8ebae37SRussell King } 72158c7ccbfSPer Forlin 72258c7ccbfSPer Forlin #define mmci_pre_request NULL 72358c7ccbfSPer Forlin #define mmci_post_request NULL 72458c7ccbfSPer Forlin 725c8ebae37SRussell King #endif 726c8ebae37SRussell King 7271c6a0718SPierre Ossman static void mmci_start_data(struct mmci_host *host, struct mmc_data *data) 7281c6a0718SPierre Ossman { 7298301bb68SRabin Vincent struct variant_data *variant = host->variant; 7301c6a0718SPierre Ossman unsigned int datactrl, timeout, irqmask; 7311c6a0718SPierre Ossman unsigned long long clks; 7321c6a0718SPierre Ossman void __iomem *base; 7331c6a0718SPierre Ossman int blksz_bits; 7341c6a0718SPierre Ossman 73564de0289SLinus Walleij dev_dbg(mmc_dev(host->mmc), "blksz %04x blks %04x flags %08x\n", 7361c6a0718SPierre Ossman data->blksz, data->blocks, data->flags); 7371c6a0718SPierre Ossman 7381c6a0718SPierre Ossman host->data = data; 739528320dbSRabin Vincent host->size = data->blksz * data->blocks; 74051d4375dSRussell King data->bytes_xfered = 0; 7411c6a0718SPierre Ossman 7421c6a0718SPierre Ossman clks = (unsigned long long)data->timeout_ns * host->cclk; 7431c6a0718SPierre Ossman do_div(clks, 1000000000UL); 7441c6a0718SPierre Ossman 7451c6a0718SPierre Ossman timeout = data->timeout_clks + (unsigned int)clks; 7461c6a0718SPierre Ossman 7471c6a0718SPierre Ossman base = host->base; 7481c6a0718SPierre Ossman writel(timeout, base + MMCIDATATIMER); 7491c6a0718SPierre Ossman writel(host->size, base + MMCIDATALENGTH); 7501c6a0718SPierre Ossman 7511c6a0718SPierre Ossman blksz_bits = ffs(data->blksz) - 1; 7521c6a0718SPierre Ossman BUG_ON(1 << blksz_bits != data->blksz); 7531c6a0718SPierre Ossman 7541784b157SPhilippe Langlais if (variant->blksz_datactrl16) 7551784b157SPhilippe Langlais datactrl = MCI_DPSM_ENABLE | (data->blksz << 16); 7561784b157SPhilippe Langlais else 7571c6a0718SPierre Ossman datactrl = MCI_DPSM_ENABLE | blksz_bits << 4; 758c8ebae37SRussell King 759c8ebae37SRussell King if (data->flags & MMC_DATA_READ) 7601c6a0718SPierre Ossman datactrl |= MCI_DPSM_DIRECTION; 761c8ebae37SRussell King 7627258db7eSUlf Hansson /* The ST Micro variants has a special bit to enable SDIO */ 7637258db7eSUlf Hansson if (variant->sdio && host->mmc->card) 76406c1a121SUlf Hansson if (mmc_card_sdio(host->mmc->card)) { 76506c1a121SUlf Hansson /* 76606c1a121SUlf Hansson * The ST Micro variants has a special bit 76706c1a121SUlf Hansson * to enable SDIO. 76806c1a121SUlf Hansson */ 76906c1a121SUlf Hansson u32 clk; 77006c1a121SUlf Hansson 7717258db7eSUlf Hansson datactrl |= MCI_ST_DPSM_SDIOEN; 7727258db7eSUlf Hansson 773c8ebae37SRussell King /* 77470ac0935SUlf Hansson * The ST Micro variant for SDIO small write transfers 77570ac0935SUlf Hansson * needs to have clock H/W flow control disabled, 77670ac0935SUlf Hansson * otherwise the transfer will not start. The threshold 77770ac0935SUlf Hansson * depends on the rate of MCLK. 77806c1a121SUlf Hansson */ 77970ac0935SUlf Hansson if (data->flags & MMC_DATA_WRITE && 78070ac0935SUlf Hansson (host->size < 8 || 78170ac0935SUlf Hansson (host->size <= 8 && host->mclk > 50000000))) 78206c1a121SUlf Hansson clk = host->clk_reg & ~variant->clkreg_enable; 78306c1a121SUlf Hansson else 78406c1a121SUlf Hansson clk = host->clk_reg | variant->clkreg_enable; 78506c1a121SUlf Hansson 78606c1a121SUlf Hansson mmci_write_clkreg(host, clk); 78706c1a121SUlf Hansson } 78806c1a121SUlf Hansson 7896dbb6ee0SUlf Hansson if (host->mmc->ios.timing == MMC_TIMING_UHS_DDR50) 7906dbb6ee0SUlf Hansson datactrl |= MCI_ST_DPSM_DDRMODE; 7916dbb6ee0SUlf Hansson 79206c1a121SUlf Hansson /* 793c8ebae37SRussell King * Attempt to use DMA operation mode, if this 794c8ebae37SRussell King * should fail, fall back to PIO mode 795c8ebae37SRussell King */ 796c8ebae37SRussell King if (!mmci_dma_start_data(host, datactrl)) 797c8ebae37SRussell King return; 798c8ebae37SRussell King 799c8ebae37SRussell King /* IRQ mode, map the SG list for CPU reading/writing */ 800c8ebae37SRussell King mmci_init_sg(host, data); 801c8ebae37SRussell King 802c8ebae37SRussell King if (data->flags & MMC_DATA_READ) { 8031c6a0718SPierre Ossman irqmask = MCI_RXFIFOHALFFULLMASK; 8041c6a0718SPierre Ossman 8051c6a0718SPierre Ossman /* 806c4d877c1SRussell King * If we have less than the fifo 'half-full' threshold to 807c4d877c1SRussell King * transfer, trigger a PIO interrupt as soon as any data 808c4d877c1SRussell King * is available. 8091c6a0718SPierre Ossman */ 810c4d877c1SRussell King if (host->size < variant->fifohalfsize) 8111c6a0718SPierre Ossman irqmask |= MCI_RXDATAAVLBLMASK; 8121c6a0718SPierre Ossman } else { 8131c6a0718SPierre Ossman /* 8141c6a0718SPierre Ossman * We don't actually need to include "FIFO empty" here 8151c6a0718SPierre Ossman * since its implicit in "FIFO half empty". 8161c6a0718SPierre Ossman */ 8171c6a0718SPierre Ossman irqmask = MCI_TXFIFOHALFEMPTYMASK; 8181c6a0718SPierre Ossman } 8191c6a0718SPierre Ossman 8209cc639a2SUlf Hansson mmci_write_datactrlreg(host, datactrl); 8211c6a0718SPierre Ossman writel(readl(base + MMCIMASK0) & ~MCI_DATAENDMASK, base + MMCIMASK0); 8222686b4b4SLinus Walleij mmci_set_mask1(host, irqmask); 8231c6a0718SPierre Ossman } 8241c6a0718SPierre Ossman 8251c6a0718SPierre Ossman static void 8261c6a0718SPierre Ossman mmci_start_command(struct mmci_host *host, struct mmc_command *cmd, u32 c) 8271c6a0718SPierre Ossman { 8281c6a0718SPierre Ossman void __iomem *base = host->base; 8291c6a0718SPierre Ossman 83064de0289SLinus Walleij dev_dbg(mmc_dev(host->mmc), "op %02x arg %08x flags %08x\n", 8311c6a0718SPierre Ossman cmd->opcode, cmd->arg, cmd->flags); 8321c6a0718SPierre Ossman 8331c6a0718SPierre Ossman if (readl(base + MMCICOMMAND) & MCI_CPSM_ENABLE) { 8341c6a0718SPierre Ossman writel(0, base + MMCICOMMAND); 8351c6a0718SPierre Ossman udelay(1); 8361c6a0718SPierre Ossman } 8371c6a0718SPierre Ossman 8381c6a0718SPierre Ossman c |= cmd->opcode | MCI_CPSM_ENABLE; 8391c6a0718SPierre Ossman if (cmd->flags & MMC_RSP_PRESENT) { 8401c6a0718SPierre Ossman if (cmd->flags & MMC_RSP_136) 8411c6a0718SPierre Ossman c |= MCI_CPSM_LONGRSP; 8421c6a0718SPierre Ossman c |= MCI_CPSM_RESPONSE; 8431c6a0718SPierre Ossman } 8441c6a0718SPierre Ossman if (/*interrupt*/0) 8451c6a0718SPierre Ossman c |= MCI_CPSM_INTERRUPT; 8461c6a0718SPierre Ossman 8471c6a0718SPierre Ossman host->cmd = cmd; 8481c6a0718SPierre Ossman 8491c6a0718SPierre Ossman writel(cmd->arg, base + MMCIARGUMENT); 8501c6a0718SPierre Ossman writel(c, base + MMCICOMMAND); 8511c6a0718SPierre Ossman } 8521c6a0718SPierre Ossman 8531c6a0718SPierre Ossman static void 8541c6a0718SPierre Ossman mmci_data_irq(struct mmci_host *host, struct mmc_data *data, 8551c6a0718SPierre Ossman unsigned int status) 8561c6a0718SPierre Ossman { 857f20f8f21SLinus Walleij /* First check for errors */ 858b63038d6SUlf Hansson if (status & (MCI_DATACRCFAIL|MCI_DATATIMEOUT|MCI_STARTBITERR| 859b63038d6SUlf Hansson MCI_TXUNDERRUN|MCI_RXOVERRUN)) { 8608cb28155SLinus Walleij u32 remain, success; 861f20f8f21SLinus Walleij 862c8ebae37SRussell King /* Terminate the DMA transfer */ 863653a761eSUlf Hansson if (dma_inprogress(host)) { 864c8ebae37SRussell King mmci_dma_data_error(host); 865653a761eSUlf Hansson mmci_dma_unmap(host, data); 866653a761eSUlf Hansson } 867c8ebae37SRussell King 868c8afc9d5SRussell King /* 869c8afc9d5SRussell King * Calculate how far we are into the transfer. Note that 870c8afc9d5SRussell King * the data counter gives the number of bytes transferred 871c8afc9d5SRussell King * on the MMC bus, not on the host side. On reads, this 872c8afc9d5SRussell King * can be as much as a FIFO-worth of data ahead. This 873c8afc9d5SRussell King * matters for FIFO overruns only. 874c8afc9d5SRussell King */ 875f5a106d9SLinus Walleij remain = readl(host->base + MMCIDATACNT); 8768cb28155SLinus Walleij success = data->blksz * data->blocks - remain; 8778cb28155SLinus Walleij 878c8afc9d5SRussell King dev_dbg(mmc_dev(host->mmc), "MCI ERROR IRQ, status 0x%08x at 0x%08x\n", 879c8afc9d5SRussell King status, success); 8808cb28155SLinus Walleij if (status & MCI_DATACRCFAIL) { 8818cb28155SLinus Walleij /* Last block was not successful */ 882c8afc9d5SRussell King success -= 1; 88317b0429dSPierre Ossman data->error = -EILSEQ; 8848cb28155SLinus Walleij } else if (status & MCI_DATATIMEOUT) { 88517b0429dSPierre Ossman data->error = -ETIMEDOUT; 886757df746SLinus Walleij } else if (status & MCI_STARTBITERR) { 887757df746SLinus Walleij data->error = -ECOMM; 888c8afc9d5SRussell King } else if (status & MCI_TXUNDERRUN) { 88917b0429dSPierre Ossman data->error = -EIO; 890c8afc9d5SRussell King } else if (status & MCI_RXOVERRUN) { 891c8afc9d5SRussell King if (success > host->variant->fifosize) 892c8afc9d5SRussell King success -= host->variant->fifosize; 893c8afc9d5SRussell King else 894c8afc9d5SRussell King success = 0; 8958cb28155SLinus Walleij data->error = -EIO; 8964ce1d6cbSRabin Vincent } 89751d4375dSRussell King data->bytes_xfered = round_down(success, data->blksz); 8981c6a0718SPierre Ossman } 899f20f8f21SLinus Walleij 9008cb28155SLinus Walleij if (status & MCI_DATABLOCKEND) 9018cb28155SLinus Walleij dev_err(mmc_dev(host->mmc), "stray MCI_DATABLOCKEND interrupt\n"); 902f20f8f21SLinus Walleij 903ccff9b51SRussell King if (status & MCI_DATAEND || data->error) { 904c8ebae37SRussell King if (dma_inprogress(host)) 905653a761eSUlf Hansson mmci_dma_finalize(host, data); 9061c6a0718SPierre Ossman mmci_stop_data(host); 9071c6a0718SPierre Ossman 9088cb28155SLinus Walleij if (!data->error) 9098cb28155SLinus Walleij /* The error clause is handled above, success! */ 91051d4375dSRussell King data->bytes_xfered = data->blksz * data->blocks; 911f20f8f21SLinus Walleij 912024629c6SUlf Hansson if (!data->stop || host->mrq->sbc) { 9131c6a0718SPierre Ossman mmci_request_end(host, data->mrq); 9141c6a0718SPierre Ossman } else { 9151c6a0718SPierre Ossman mmci_start_command(host, data->stop, 0); 9161c6a0718SPierre Ossman } 9171c6a0718SPierre Ossman } 9181c6a0718SPierre Ossman } 9191c6a0718SPierre Ossman 9201c6a0718SPierre Ossman static void 9211c6a0718SPierre Ossman mmci_cmd_irq(struct mmci_host *host, struct mmc_command *cmd, 9221c6a0718SPierre Ossman unsigned int status) 9231c6a0718SPierre Ossman { 9241c6a0718SPierre Ossman void __iomem *base = host->base; 925024629c6SUlf Hansson bool sbc = (cmd == host->mrq->sbc); 9268d94b54dSUlf Hansson bool busy_resp = host->variant->busy_detect && 9278d94b54dSUlf Hansson (cmd->flags & MMC_RSP_BUSY); 9288d94b54dSUlf Hansson 9298d94b54dSUlf Hansson /* Check if we need to wait for busy completion. */ 9308d94b54dSUlf Hansson if (host->busy_status && (status & MCI_ST_CARDBUSY)) 9318d94b54dSUlf Hansson return; 9328d94b54dSUlf Hansson 9338d94b54dSUlf Hansson /* Enable busy completion if needed and supported. */ 9348d94b54dSUlf Hansson if (!host->busy_status && busy_resp && 9358d94b54dSUlf Hansson !(status & (MCI_CMDCRCFAIL|MCI_CMDTIMEOUT)) && 9368d94b54dSUlf Hansson (readl(base + MMCISTATUS) & MCI_ST_CARDBUSY)) { 9378d94b54dSUlf Hansson writel(readl(base + MMCIMASK0) | MCI_ST_BUSYEND, 9388d94b54dSUlf Hansson base + MMCIMASK0); 9398d94b54dSUlf Hansson host->busy_status = status & (MCI_CMDSENT|MCI_CMDRESPEND); 9408d94b54dSUlf Hansson return; 9418d94b54dSUlf Hansson } 9428d94b54dSUlf Hansson 9438d94b54dSUlf Hansson /* At busy completion, mask the IRQ and complete the request. */ 9448d94b54dSUlf Hansson if (host->busy_status) { 9458d94b54dSUlf Hansson writel(readl(base + MMCIMASK0) & ~MCI_ST_BUSYEND, 9468d94b54dSUlf Hansson base + MMCIMASK0); 9478d94b54dSUlf Hansson host->busy_status = 0; 9488d94b54dSUlf Hansson } 9491c6a0718SPierre Ossman 9501c6a0718SPierre Ossman host->cmd = NULL; 9511c6a0718SPierre Ossman 9521c6a0718SPierre Ossman if (status & MCI_CMDTIMEOUT) { 95317b0429dSPierre Ossman cmd->error = -ETIMEDOUT; 9541c6a0718SPierre Ossman } else if (status & MCI_CMDCRCFAIL && cmd->flags & MMC_RSP_CRC) { 95517b0429dSPierre Ossman cmd->error = -EILSEQ; 9569047b435SRussell King - ARM Linux } else { 9579047b435SRussell King - ARM Linux cmd->resp[0] = readl(base + MMCIRESPONSE0); 9589047b435SRussell King - ARM Linux cmd->resp[1] = readl(base + MMCIRESPONSE1); 9599047b435SRussell King - ARM Linux cmd->resp[2] = readl(base + MMCIRESPONSE2); 9609047b435SRussell King - ARM Linux cmd->resp[3] = readl(base + MMCIRESPONSE3); 9611c6a0718SPierre Ossman } 9621c6a0718SPierre Ossman 963024629c6SUlf Hansson if ((!sbc && !cmd->data) || cmd->error) { 9643b6e3c73SUlf Hansson if (host->data) { 9653b6e3c73SUlf Hansson /* Terminate the DMA transfer */ 966653a761eSUlf Hansson if (dma_inprogress(host)) { 9673b6e3c73SUlf Hansson mmci_dma_data_error(host); 968653a761eSUlf Hansson mmci_dma_unmap(host, host->data); 969653a761eSUlf Hansson } 9701c6a0718SPierre Ossman mmci_stop_data(host); 9713b6e3c73SUlf Hansson } 972024629c6SUlf Hansson mmci_request_end(host, host->mrq); 973024629c6SUlf Hansson } else if (sbc) { 974024629c6SUlf Hansson mmci_start_command(host, host->mrq->cmd, 0); 9751c6a0718SPierre Ossman } else if (!(cmd->data->flags & MMC_DATA_READ)) { 9761c6a0718SPierre Ossman mmci_start_data(host, cmd->data); 9771c6a0718SPierre Ossman } 9781c6a0718SPierre Ossman } 9791c6a0718SPierre Ossman 9801c6a0718SPierre Ossman static int mmci_pio_read(struct mmci_host *host, char *buffer, unsigned int remain) 9811c6a0718SPierre Ossman { 9821c6a0718SPierre Ossman void __iomem *base = host->base; 9831c6a0718SPierre Ossman char *ptr = buffer; 9841c6a0718SPierre Ossman u32 status; 98526eed9a5SLinus Walleij int host_remain = host->size; 9861c6a0718SPierre Ossman 9871c6a0718SPierre Ossman do { 98826eed9a5SLinus Walleij int count = host_remain - (readl(base + MMCIFIFOCNT) << 2); 9891c6a0718SPierre Ossman 9901c6a0718SPierre Ossman if (count > remain) 9911c6a0718SPierre Ossman count = remain; 9921c6a0718SPierre Ossman 9931c6a0718SPierre Ossman if (count <= 0) 9941c6a0718SPierre Ossman break; 9951c6a0718SPierre Ossman 996393e5e24SUlf Hansson /* 997393e5e24SUlf Hansson * SDIO especially may want to send something that is 998393e5e24SUlf Hansson * not divisible by 4 (as opposed to card sectors 999393e5e24SUlf Hansson * etc). Therefore make sure to always read the last bytes 1000393e5e24SUlf Hansson * while only doing full 32-bit reads towards the FIFO. 1001393e5e24SUlf Hansson */ 1002393e5e24SUlf Hansson if (unlikely(count & 0x3)) { 1003393e5e24SUlf Hansson if (count < 4) { 1004393e5e24SUlf Hansson unsigned char buf[4]; 10054b85da08SDavide Ciminaghi ioread32_rep(base + MMCIFIFO, buf, 1); 1006393e5e24SUlf Hansson memcpy(ptr, buf, count); 1007393e5e24SUlf Hansson } else { 10084b85da08SDavide Ciminaghi ioread32_rep(base + MMCIFIFO, ptr, count >> 2); 1009393e5e24SUlf Hansson count &= ~0x3; 1010393e5e24SUlf Hansson } 1011393e5e24SUlf Hansson } else { 10124b85da08SDavide Ciminaghi ioread32_rep(base + MMCIFIFO, ptr, count >> 2); 1013393e5e24SUlf Hansson } 10141c6a0718SPierre Ossman 10151c6a0718SPierre Ossman ptr += count; 10161c6a0718SPierre Ossman remain -= count; 101726eed9a5SLinus Walleij host_remain -= count; 10181c6a0718SPierre Ossman 10191c6a0718SPierre Ossman if (remain == 0) 10201c6a0718SPierre Ossman break; 10211c6a0718SPierre Ossman 10221c6a0718SPierre Ossman status = readl(base + MMCISTATUS); 10231c6a0718SPierre Ossman } while (status & MCI_RXDATAAVLBL); 10241c6a0718SPierre Ossman 10251c6a0718SPierre Ossman return ptr - buffer; 10261c6a0718SPierre Ossman } 10271c6a0718SPierre Ossman 10281c6a0718SPierre Ossman static int mmci_pio_write(struct mmci_host *host, char *buffer, unsigned int remain, u32 status) 10291c6a0718SPierre Ossman { 10308301bb68SRabin Vincent struct variant_data *variant = host->variant; 10311c6a0718SPierre Ossman void __iomem *base = host->base; 10321c6a0718SPierre Ossman char *ptr = buffer; 10331c6a0718SPierre Ossman 10341c6a0718SPierre Ossman do { 10351c6a0718SPierre Ossman unsigned int count, maxcnt; 10361c6a0718SPierre Ossman 10378301bb68SRabin Vincent maxcnt = status & MCI_TXFIFOEMPTY ? 10388301bb68SRabin Vincent variant->fifosize : variant->fifohalfsize; 10391c6a0718SPierre Ossman count = min(remain, maxcnt); 10401c6a0718SPierre Ossman 104134177802SLinus Walleij /* 104234177802SLinus Walleij * SDIO especially may want to send something that is 104334177802SLinus Walleij * not divisible by 4 (as opposed to card sectors 104434177802SLinus Walleij * etc), and the FIFO only accept full 32-bit writes. 104534177802SLinus Walleij * So compensate by adding +3 on the count, a single 104634177802SLinus Walleij * byte become a 32bit write, 7 bytes will be two 104734177802SLinus Walleij * 32bit writes etc. 104834177802SLinus Walleij */ 10494b85da08SDavide Ciminaghi iowrite32_rep(base + MMCIFIFO, ptr, (count + 3) >> 2); 10501c6a0718SPierre Ossman 10511c6a0718SPierre Ossman ptr += count; 10521c6a0718SPierre Ossman remain -= count; 10531c6a0718SPierre Ossman 10541c6a0718SPierre Ossman if (remain == 0) 10551c6a0718SPierre Ossman break; 10561c6a0718SPierre Ossman 10571c6a0718SPierre Ossman status = readl(base + MMCISTATUS); 10581c6a0718SPierre Ossman } while (status & MCI_TXFIFOHALFEMPTY); 10591c6a0718SPierre Ossman 10601c6a0718SPierre Ossman return ptr - buffer; 10611c6a0718SPierre Ossman } 10621c6a0718SPierre Ossman 10631c6a0718SPierre Ossman /* 10641c6a0718SPierre Ossman * PIO data transfer IRQ handler. 10651c6a0718SPierre Ossman */ 10661c6a0718SPierre Ossman static irqreturn_t mmci_pio_irq(int irq, void *dev_id) 10671c6a0718SPierre Ossman { 10681c6a0718SPierre Ossman struct mmci_host *host = dev_id; 10694ce1d6cbSRabin Vincent struct sg_mapping_iter *sg_miter = &host->sg_miter; 10708301bb68SRabin Vincent struct variant_data *variant = host->variant; 10711c6a0718SPierre Ossman void __iomem *base = host->base; 10724ce1d6cbSRabin Vincent unsigned long flags; 10731c6a0718SPierre Ossman u32 status; 10741c6a0718SPierre Ossman 10751c6a0718SPierre Ossman status = readl(base + MMCISTATUS); 10761c6a0718SPierre Ossman 107764de0289SLinus Walleij dev_dbg(mmc_dev(host->mmc), "irq1 (pio) %08x\n", status); 10781c6a0718SPierre Ossman 10794ce1d6cbSRabin Vincent local_irq_save(flags); 10804ce1d6cbSRabin Vincent 10811c6a0718SPierre Ossman do { 10821c6a0718SPierre Ossman unsigned int remain, len; 10831c6a0718SPierre Ossman char *buffer; 10841c6a0718SPierre Ossman 10851c6a0718SPierre Ossman /* 10861c6a0718SPierre Ossman * For write, we only need to test the half-empty flag 10871c6a0718SPierre Ossman * here - if the FIFO is completely empty, then by 10881c6a0718SPierre Ossman * definition it is more than half empty. 10891c6a0718SPierre Ossman * 10901c6a0718SPierre Ossman * For read, check for data available. 10911c6a0718SPierre Ossman */ 10921c6a0718SPierre Ossman if (!(status & (MCI_TXFIFOHALFEMPTY|MCI_RXDATAAVLBL))) 10931c6a0718SPierre Ossman break; 10941c6a0718SPierre Ossman 10954ce1d6cbSRabin Vincent if (!sg_miter_next(sg_miter)) 10964ce1d6cbSRabin Vincent break; 10974ce1d6cbSRabin Vincent 10984ce1d6cbSRabin Vincent buffer = sg_miter->addr; 10994ce1d6cbSRabin Vincent remain = sg_miter->length; 11001c6a0718SPierre Ossman 11011c6a0718SPierre Ossman len = 0; 11021c6a0718SPierre Ossman if (status & MCI_RXACTIVE) 11031c6a0718SPierre Ossman len = mmci_pio_read(host, buffer, remain); 11041c6a0718SPierre Ossman if (status & MCI_TXACTIVE) 11051c6a0718SPierre Ossman len = mmci_pio_write(host, buffer, remain, status); 11061c6a0718SPierre Ossman 11074ce1d6cbSRabin Vincent sg_miter->consumed = len; 11081c6a0718SPierre Ossman 11091c6a0718SPierre Ossman host->size -= len; 11101c6a0718SPierre Ossman remain -= len; 11111c6a0718SPierre Ossman 11121c6a0718SPierre Ossman if (remain) 11131c6a0718SPierre Ossman break; 11141c6a0718SPierre Ossman 11151c6a0718SPierre Ossman status = readl(base + MMCISTATUS); 11161c6a0718SPierre Ossman } while (1); 11171c6a0718SPierre Ossman 11184ce1d6cbSRabin Vincent sg_miter_stop(sg_miter); 11194ce1d6cbSRabin Vincent 11204ce1d6cbSRabin Vincent local_irq_restore(flags); 11214ce1d6cbSRabin Vincent 11221c6a0718SPierre Ossman /* 1123c4d877c1SRussell King * If we have less than the fifo 'half-full' threshold to transfer, 1124c4d877c1SRussell King * trigger a PIO interrupt as soon as any data is available. 11251c6a0718SPierre Ossman */ 1126c4d877c1SRussell King if (status & MCI_RXACTIVE && host->size < variant->fifohalfsize) 11272686b4b4SLinus Walleij mmci_set_mask1(host, MCI_RXDATAAVLBLMASK); 11281c6a0718SPierre Ossman 11291c6a0718SPierre Ossman /* 11301c6a0718SPierre Ossman * If we run out of data, disable the data IRQs; this 11311c6a0718SPierre Ossman * prevents a race where the FIFO becomes empty before 11321c6a0718SPierre Ossman * the chip itself has disabled the data path, and 11331c6a0718SPierre Ossman * stops us racing with our data end IRQ. 11341c6a0718SPierre Ossman */ 11351c6a0718SPierre Ossman if (host->size == 0) { 11362686b4b4SLinus Walleij mmci_set_mask1(host, 0); 11371c6a0718SPierre Ossman writel(readl(base + MMCIMASK0) | MCI_DATAENDMASK, base + MMCIMASK0); 11381c6a0718SPierre Ossman } 11391c6a0718SPierre Ossman 11401c6a0718SPierre Ossman return IRQ_HANDLED; 11411c6a0718SPierre Ossman } 11421c6a0718SPierre Ossman 11431c6a0718SPierre Ossman /* 11441c6a0718SPierre Ossman * Handle completion of command and data transfers. 11451c6a0718SPierre Ossman */ 11461c6a0718SPierre Ossman static irqreturn_t mmci_irq(int irq, void *dev_id) 11471c6a0718SPierre Ossman { 11481c6a0718SPierre Ossman struct mmci_host *host = dev_id; 11491c6a0718SPierre Ossman u32 status; 11501c6a0718SPierre Ossman int ret = 0; 11511c6a0718SPierre Ossman 11521c6a0718SPierre Ossman spin_lock(&host->lock); 11531c6a0718SPierre Ossman 11541c6a0718SPierre Ossman do { 11551c6a0718SPierre Ossman struct mmc_command *cmd; 11561c6a0718SPierre Ossman struct mmc_data *data; 11571c6a0718SPierre Ossman 11581c6a0718SPierre Ossman status = readl(host->base + MMCISTATUS); 11592686b4b4SLinus Walleij 11602686b4b4SLinus Walleij if (host->singleirq) { 11612686b4b4SLinus Walleij if (status & readl(host->base + MMCIMASK1)) 11622686b4b4SLinus Walleij mmci_pio_irq(irq, dev_id); 11632686b4b4SLinus Walleij 11642686b4b4SLinus Walleij status &= ~MCI_IRQ1MASK; 11652686b4b4SLinus Walleij } 11662686b4b4SLinus Walleij 11678d94b54dSUlf Hansson /* 11688d94b54dSUlf Hansson * We intentionally clear the MCI_ST_CARDBUSY IRQ here (if it's 11698d94b54dSUlf Hansson * enabled) since the HW seems to be triggering the IRQ on both 11708d94b54dSUlf Hansson * edges while monitoring DAT0 for busy completion. 11718d94b54dSUlf Hansson */ 11721c6a0718SPierre Ossman status &= readl(host->base + MMCIMASK0); 11731c6a0718SPierre Ossman writel(status, host->base + MMCICLEAR); 11741c6a0718SPierre Ossman 117564de0289SLinus Walleij dev_dbg(mmc_dev(host->mmc), "irq0 (data+cmd) %08x\n", status); 11761c6a0718SPierre Ossman 1177e7f3d222SUlf Hansson cmd = host->cmd; 11788d94b54dSUlf Hansson if ((status|host->busy_status) & (MCI_CMDCRCFAIL|MCI_CMDTIMEOUT| 11798d94b54dSUlf Hansson MCI_CMDSENT|MCI_CMDRESPEND) && cmd) 1180e7f3d222SUlf Hansson mmci_cmd_irq(host, cmd, status); 1181e7f3d222SUlf Hansson 11821c6a0718SPierre Ossman data = host->data; 1183b63038d6SUlf Hansson if (status & (MCI_DATACRCFAIL|MCI_DATATIMEOUT|MCI_STARTBITERR| 1184b63038d6SUlf Hansson MCI_TXUNDERRUN|MCI_RXOVERRUN|MCI_DATAEND| 1185b63038d6SUlf Hansson MCI_DATABLOCKEND) && data) 11861c6a0718SPierre Ossman mmci_data_irq(host, data, status); 11871c6a0718SPierre Ossman 11888d94b54dSUlf Hansson /* Don't poll for busy completion in irq context. */ 11898d94b54dSUlf Hansson if (host->busy_status) 11908d94b54dSUlf Hansson status &= ~MCI_ST_CARDBUSY; 11918d94b54dSUlf Hansson 11921c6a0718SPierre Ossman ret = 1; 11931c6a0718SPierre Ossman } while (status); 11941c6a0718SPierre Ossman 11951c6a0718SPierre Ossman spin_unlock(&host->lock); 11961c6a0718SPierre Ossman 11971c6a0718SPierre Ossman return IRQ_RETVAL(ret); 11981c6a0718SPierre Ossman } 11991c6a0718SPierre Ossman 12001c6a0718SPierre Ossman static void mmci_request(struct mmc_host *mmc, struct mmc_request *mrq) 12011c6a0718SPierre Ossman { 12021c6a0718SPierre Ossman struct mmci_host *host = mmc_priv(mmc); 12039e943021SLinus Walleij unsigned long flags; 12041c6a0718SPierre Ossman 12051c6a0718SPierre Ossman WARN_ON(host->mrq != NULL); 12061c6a0718SPierre Ossman 1207653a761eSUlf Hansson mrq->cmd->error = mmci_validate_data(host, mrq->data); 1208653a761eSUlf Hansson if (mrq->cmd->error) { 1209255d01afSPierre Ossman mmc_request_done(mmc, mrq); 1210255d01afSPierre Ossman return; 1211255d01afSPierre Ossman } 1212255d01afSPierre Ossman 12131c3be369SRussell King pm_runtime_get_sync(mmc_dev(mmc)); 12141c3be369SRussell King 12159e943021SLinus Walleij spin_lock_irqsave(&host->lock, flags); 12161c6a0718SPierre Ossman 12171c6a0718SPierre Ossman host->mrq = mrq; 12181c6a0718SPierre Ossman 121958c7ccbfSPer Forlin if (mrq->data) 122058c7ccbfSPer Forlin mmci_get_next_data(host, mrq->data); 122158c7ccbfSPer Forlin 12221c6a0718SPierre Ossman if (mrq->data && mrq->data->flags & MMC_DATA_READ) 12231c6a0718SPierre Ossman mmci_start_data(host, mrq->data); 12241c6a0718SPierre Ossman 1225024629c6SUlf Hansson if (mrq->sbc) 1226024629c6SUlf Hansson mmci_start_command(host, mrq->sbc, 0); 1227024629c6SUlf Hansson else 12281c6a0718SPierre Ossman mmci_start_command(host, mrq->cmd, 0); 12291c6a0718SPierre Ossman 12309e943021SLinus Walleij spin_unlock_irqrestore(&host->lock, flags); 12311c6a0718SPierre Ossman } 12321c6a0718SPierre Ossman 12331c6a0718SPierre Ossman static void mmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) 12341c6a0718SPierre Ossman { 12351c6a0718SPierre Ossman struct mmci_host *host = mmc_priv(mmc); 12367d72a1d4SUlf Hansson struct variant_data *variant = host->variant; 1237a6a6464aSLinus Walleij u32 pwr = 0; 1238a6a6464aSLinus Walleij unsigned long flags; 1239db90f91fSLee Jones int ret; 12401c6a0718SPierre Ossman 12412cd976c4SUlf Hansson pm_runtime_get_sync(mmc_dev(mmc)); 12422cd976c4SUlf Hansson 1243bc521818SUlf Hansson if (host->plat->ios_handler && 1244bc521818SUlf Hansson host->plat->ios_handler(mmc_dev(mmc), ios)) 1245bc521818SUlf Hansson dev_err(mmc_dev(mmc), "platform ios_handler failed\n"); 1246bc521818SUlf Hansson 12471c6a0718SPierre Ossman switch (ios->power_mode) { 12481c6a0718SPierre Ossman case MMC_POWER_OFF: 1249599c1d5cSUlf Hansson if (!IS_ERR(mmc->supply.vmmc)) 1250599c1d5cSUlf Hansson mmc_regulator_set_ocr(mmc, mmc->supply.vmmc, 0); 1251237fb5e6SLee Jones 12527c0136efSUlf Hansson if (!IS_ERR(mmc->supply.vqmmc) && host->vqmmc_enabled) { 1253237fb5e6SLee Jones regulator_disable(mmc->supply.vqmmc); 12547c0136efSUlf Hansson host->vqmmc_enabled = false; 12557c0136efSUlf Hansson } 1256237fb5e6SLee Jones 12571c6a0718SPierre Ossman break; 12581c6a0718SPierre Ossman case MMC_POWER_UP: 1259599c1d5cSUlf Hansson if (!IS_ERR(mmc->supply.vmmc)) 1260599c1d5cSUlf Hansson mmc_regulator_set_ocr(mmc, mmc->supply.vmmc, ios->vdd); 1261599c1d5cSUlf Hansson 12627d72a1d4SUlf Hansson /* 12637d72a1d4SUlf Hansson * The ST Micro variant doesn't have the PL180s MCI_PWR_UP 12647d72a1d4SUlf Hansson * and instead uses MCI_PWR_ON so apply whatever value is 12657d72a1d4SUlf Hansson * configured in the variant data. 12667d72a1d4SUlf Hansson */ 12677d72a1d4SUlf Hansson pwr |= variant->pwrreg_powerup; 12687d72a1d4SUlf Hansson 12691c6a0718SPierre Ossman break; 12701c6a0718SPierre Ossman case MMC_POWER_ON: 12717c0136efSUlf Hansson if (!IS_ERR(mmc->supply.vqmmc) && !host->vqmmc_enabled) { 1272db90f91fSLee Jones ret = regulator_enable(mmc->supply.vqmmc); 1273db90f91fSLee Jones if (ret < 0) 1274db90f91fSLee Jones dev_err(mmc_dev(mmc), 1275db90f91fSLee Jones "failed to enable vqmmc regulator\n"); 12767c0136efSUlf Hansson else 12777c0136efSUlf Hansson host->vqmmc_enabled = true; 1278db90f91fSLee Jones } 1279237fb5e6SLee Jones 12801c6a0718SPierre Ossman pwr |= MCI_PWR_ON; 12811c6a0718SPierre Ossman break; 12821c6a0718SPierre Ossman } 12831c6a0718SPierre Ossman 12844d1a3a0dSUlf Hansson if (variant->signal_direction && ios->power_mode != MMC_POWER_OFF) { 12854d1a3a0dSUlf Hansson /* 12864d1a3a0dSUlf Hansson * The ST Micro variant has some additional bits 12874d1a3a0dSUlf Hansson * indicating signal direction for the signals in 12884d1a3a0dSUlf Hansson * the SD/MMC bus and feedback-clock usage. 12894d1a3a0dSUlf Hansson */ 12904d1a3a0dSUlf Hansson pwr |= host->plat->sigdir; 12914d1a3a0dSUlf Hansson 12924d1a3a0dSUlf Hansson if (ios->bus_width == MMC_BUS_WIDTH_4) 12934d1a3a0dSUlf Hansson pwr &= ~MCI_ST_DATA74DIREN; 12944d1a3a0dSUlf Hansson else if (ios->bus_width == MMC_BUS_WIDTH_1) 12954d1a3a0dSUlf Hansson pwr &= (~MCI_ST_DATA74DIREN & 12964d1a3a0dSUlf Hansson ~MCI_ST_DATA31DIREN & 12974d1a3a0dSUlf Hansson ~MCI_ST_DATA2DIREN); 12984d1a3a0dSUlf Hansson } 12994d1a3a0dSUlf Hansson 1300cc30d60eSLinus Walleij if (ios->bus_mode == MMC_BUSMODE_OPENDRAIN) { 1301f17a1f06SLinus Walleij if (host->hw_designer != AMBA_VENDOR_ST) 13021c6a0718SPierre Ossman pwr |= MCI_ROD; 1303cc30d60eSLinus Walleij else { 1304cc30d60eSLinus Walleij /* 1305cc30d60eSLinus Walleij * The ST Micro variant use the ROD bit for something 1306cc30d60eSLinus Walleij * else and only has OD (Open Drain). 1307cc30d60eSLinus Walleij */ 1308cc30d60eSLinus Walleij pwr |= MCI_OD; 1309cc30d60eSLinus Walleij } 1310cc30d60eSLinus Walleij } 13111c6a0718SPierre Ossman 1312f4670daeSUlf Hansson /* 1313f4670daeSUlf Hansson * If clock = 0 and the variant requires the MMCIPOWER to be used for 1314f4670daeSUlf Hansson * gating the clock, the MCI_PWR_ON bit is cleared. 1315f4670daeSUlf Hansson */ 1316f4670daeSUlf Hansson if (!ios->clock && variant->pwrreg_clkgate) 1317f4670daeSUlf Hansson pwr &= ~MCI_PWR_ON; 1318f4670daeSUlf Hansson 1319a6a6464aSLinus Walleij spin_lock_irqsave(&host->lock, flags); 1320a6a6464aSLinus Walleij 1321a6a6464aSLinus Walleij mmci_set_clkreg(host, ios->clock); 13227437cfa5SUlf Hansson mmci_write_pwrreg(host, pwr); 1323f829c042SUlf Hansson mmci_reg_delay(host); 1324a6a6464aSLinus Walleij 1325a6a6464aSLinus Walleij spin_unlock_irqrestore(&host->lock, flags); 13262cd976c4SUlf Hansson 13272cd976c4SUlf Hansson pm_runtime_mark_last_busy(mmc_dev(mmc)); 13282cd976c4SUlf Hansson pm_runtime_put_autosuspend(mmc_dev(mmc)); 13291c6a0718SPierre Ossman } 13301c6a0718SPierre Ossman 133189001446SRussell King static int mmci_get_cd(struct mmc_host *mmc) 133289001446SRussell King { 133389001446SRussell King struct mmci_host *host = mmc_priv(mmc); 133429719445SRabin Vincent struct mmci_platform_data *plat = host->plat; 1335d2762090SUlf Hansson unsigned int status = mmc_gpio_get_cd(mmc); 133689001446SRussell King 1337d2762090SUlf Hansson if (status == -ENOSYS) { 13384b8caec0SRabin Vincent if (!plat->status) 13394b8caec0SRabin Vincent return 1; /* Assume always present */ 13404b8caec0SRabin Vincent 134129719445SRabin Vincent status = plat->status(mmc_dev(host->mmc)); 1342d2762090SUlf Hansson } 134374bc8093SRussell King return status; 134489001446SRussell King } 134589001446SRussell King 13460f3ed7f7SUlf Hansson static int mmci_sig_volt_switch(struct mmc_host *mmc, struct mmc_ios *ios) 13470f3ed7f7SUlf Hansson { 13480f3ed7f7SUlf Hansson int ret = 0; 13490f3ed7f7SUlf Hansson 13500f3ed7f7SUlf Hansson if (!IS_ERR(mmc->supply.vqmmc)) { 13510f3ed7f7SUlf Hansson 13520f3ed7f7SUlf Hansson pm_runtime_get_sync(mmc_dev(mmc)); 13530f3ed7f7SUlf Hansson 13540f3ed7f7SUlf Hansson switch (ios->signal_voltage) { 13550f3ed7f7SUlf Hansson case MMC_SIGNAL_VOLTAGE_330: 13560f3ed7f7SUlf Hansson ret = regulator_set_voltage(mmc->supply.vqmmc, 13570f3ed7f7SUlf Hansson 2700000, 3600000); 13580f3ed7f7SUlf Hansson break; 13590f3ed7f7SUlf Hansson case MMC_SIGNAL_VOLTAGE_180: 13600f3ed7f7SUlf Hansson ret = regulator_set_voltage(mmc->supply.vqmmc, 13610f3ed7f7SUlf Hansson 1700000, 1950000); 13620f3ed7f7SUlf Hansson break; 13630f3ed7f7SUlf Hansson case MMC_SIGNAL_VOLTAGE_120: 13640f3ed7f7SUlf Hansson ret = regulator_set_voltage(mmc->supply.vqmmc, 13650f3ed7f7SUlf Hansson 1100000, 1300000); 13660f3ed7f7SUlf Hansson break; 13670f3ed7f7SUlf Hansson } 13680f3ed7f7SUlf Hansson 13690f3ed7f7SUlf Hansson if (ret) 13700f3ed7f7SUlf Hansson dev_warn(mmc_dev(mmc), "Voltage switch failed\n"); 13710f3ed7f7SUlf Hansson 13720f3ed7f7SUlf Hansson pm_runtime_mark_last_busy(mmc_dev(mmc)); 13730f3ed7f7SUlf Hansson pm_runtime_put_autosuspend(mmc_dev(mmc)); 13740f3ed7f7SUlf Hansson } 13750f3ed7f7SUlf Hansson 13760f3ed7f7SUlf Hansson return ret; 13770f3ed7f7SUlf Hansson } 13780f3ed7f7SUlf Hansson 137901259620SUlf Hansson static struct mmc_host_ops mmci_ops = { 13801c6a0718SPierre Ossman .request = mmci_request, 138158c7ccbfSPer Forlin .pre_req = mmci_pre_request, 138258c7ccbfSPer Forlin .post_req = mmci_post_request, 13831c6a0718SPierre Ossman .set_ios = mmci_set_ios, 1384d2762090SUlf Hansson .get_ro = mmc_gpio_get_ro, 138589001446SRussell King .get_cd = mmci_get_cd, 13860f3ed7f7SUlf Hansson .start_signal_voltage_switch = mmci_sig_volt_switch, 13871c6a0718SPierre Ossman }; 13881c6a0718SPierre Ossman 1389000bc9d5SLee Jones static void mmci_dt_populate_generic_pdata(struct device_node *np, 1390000bc9d5SLee Jones struct mmci_platform_data *pdata) 1391000bc9d5SLee Jones { 1392ae94cafeSUlf Hansson if (of_get_property(np, "st,sig-dir-dat0", NULL)) 1393ae94cafeSUlf Hansson pdata->sigdir |= MCI_ST_DATA0DIREN; 1394ae94cafeSUlf Hansson if (of_get_property(np, "st,sig-dir-dat2", NULL)) 1395ae94cafeSUlf Hansson pdata->sigdir |= MCI_ST_DATA2DIREN; 1396ae94cafeSUlf Hansson if (of_get_property(np, "st,sig-dir-dat31", NULL)) 1397ae94cafeSUlf Hansson pdata->sigdir |= MCI_ST_DATA31DIREN; 1398ae94cafeSUlf Hansson if (of_get_property(np, "st,sig-dir-dat74", NULL)) 1399ae94cafeSUlf Hansson pdata->sigdir |= MCI_ST_DATA74DIREN; 1400ae94cafeSUlf Hansson if (of_get_property(np, "st,sig-dir-cmd", NULL)) 1401ae94cafeSUlf Hansson pdata->sigdir |= MCI_ST_CMDDIREN; 14021a7e99c1SUlf Hansson if (of_get_property(np, "st,sig-pin-fbclk", NULL)) 14031a7e99c1SUlf Hansson pdata->sigdir |= MCI_ST_FBCLKEN; 140478f87df2SUlf Hansson } 1405ae94cafeSUlf Hansson 140678f87df2SUlf Hansson static int mmci_of_parse(struct device_node *np, struct mmc_host *mmc) 140778f87df2SUlf Hansson { 140878f87df2SUlf Hansson int ret = mmc_of_parse(mmc); 1409000bc9d5SLee Jones 141078f87df2SUlf Hansson if (ret) 141178f87df2SUlf Hansson return ret; 1412000bc9d5SLee Jones 1413000bc9d5SLee Jones if (of_get_property(np, "mmc-cap-mmc-highspeed", NULL)) 141478f87df2SUlf Hansson mmc->caps |= MMC_CAP_MMC_HIGHSPEED; 1415000bc9d5SLee Jones if (of_get_property(np, "mmc-cap-sd-highspeed", NULL)) 141678f87df2SUlf Hansson mmc->caps |= MMC_CAP_SD_HIGHSPEED; 1417000bc9d5SLee Jones 141878f87df2SUlf Hansson return 0; 1419000bc9d5SLee Jones } 1420000bc9d5SLee Jones 1421c3be1efdSBill Pemberton static int mmci_probe(struct amba_device *dev, 1422aa25afadSRussell King const struct amba_id *id) 14231c6a0718SPierre Ossman { 14246ef297f8SLinus Walleij struct mmci_platform_data *plat = dev->dev.platform_data; 1425000bc9d5SLee Jones struct device_node *np = dev->dev.of_node; 14264956e109SRabin Vincent struct variant_data *variant = id->data; 14271c6a0718SPierre Ossman struct mmci_host *host; 14281c6a0718SPierre Ossman struct mmc_host *mmc; 14291c6a0718SPierre Ossman int ret; 14301c6a0718SPierre Ossman 1431000bc9d5SLee Jones /* Must have platform data or Device Tree. */ 1432000bc9d5SLee Jones if (!plat && !np) { 1433000bc9d5SLee Jones dev_err(&dev->dev, "No plat data or DT found\n"); 1434000bc9d5SLee Jones return -EINVAL; 14351c6a0718SPierre Ossman } 14361c6a0718SPierre Ossman 1437b9b52918SLee Jones if (!plat) { 1438b9b52918SLee Jones plat = devm_kzalloc(&dev->dev, sizeof(*plat), GFP_KERNEL); 1439b9b52918SLee Jones if (!plat) 1440b9b52918SLee Jones return -ENOMEM; 1441b9b52918SLee Jones } 1442b9b52918SLee Jones 1443000bc9d5SLee Jones if (np) 1444000bc9d5SLee Jones mmci_dt_populate_generic_pdata(np, plat); 1445000bc9d5SLee Jones 14461c6a0718SPierre Ossman mmc = mmc_alloc_host(sizeof(struct mmci_host), &dev->dev); 1447ef289982SUlf Hansson if (!mmc) 1448ef289982SUlf Hansson return -ENOMEM; 14491c6a0718SPierre Ossman 145078f87df2SUlf Hansson ret = mmci_of_parse(np, mmc); 145178f87df2SUlf Hansson if (ret) 145278f87df2SUlf Hansson goto host_free; 145378f87df2SUlf Hansson 14541c6a0718SPierre Ossman host = mmc_priv(mmc); 14554ea580f1SRabin Vincent host->mmc = mmc; 1456012b7d33SRussell King 1457012b7d33SRussell King host->hw_designer = amba_manf(dev); 1458012b7d33SRussell King host->hw_revision = amba_rev(dev); 145964de0289SLinus Walleij dev_dbg(mmc_dev(mmc), "designer ID = 0x%02x\n", host->hw_designer); 146064de0289SLinus Walleij dev_dbg(mmc_dev(mmc), "revision = 0x%01x\n", host->hw_revision); 1461012b7d33SRussell King 1462665ba56fSUlf Hansson host->clk = devm_clk_get(&dev->dev, NULL); 14631c6a0718SPierre Ossman if (IS_ERR(host->clk)) { 14641c6a0718SPierre Ossman ret = PTR_ERR(host->clk); 14651c6a0718SPierre Ossman goto host_free; 14661c6a0718SPierre Ossman } 14671c6a0718SPierre Ossman 1468ac940938SJulia Lawall ret = clk_prepare_enable(host->clk); 14691c6a0718SPierre Ossman if (ret) 1470665ba56fSUlf Hansson goto host_free; 14711c6a0718SPierre Ossman 14721c6a0718SPierre Ossman host->plat = plat; 14734956e109SRabin Vincent host->variant = variant; 14741c6a0718SPierre Ossman host->mclk = clk_get_rate(host->clk); 1475c8df9a53SLinus Walleij /* 1476c8df9a53SLinus Walleij * According to the spec, mclk is max 100 MHz, 1477c8df9a53SLinus Walleij * so we try to adjust the clock down to this, 1478c8df9a53SLinus Walleij * (if possible). 1479c8df9a53SLinus Walleij */ 1480c8df9a53SLinus Walleij if (host->mclk > 100000000) { 1481c8df9a53SLinus Walleij ret = clk_set_rate(host->clk, 100000000); 1482c8df9a53SLinus Walleij if (ret < 0) 1483c8df9a53SLinus Walleij goto clk_disable; 1484c8df9a53SLinus Walleij host->mclk = clk_get_rate(host->clk); 148564de0289SLinus Walleij dev_dbg(mmc_dev(mmc), "eventual mclk rate: %u Hz\n", 148664de0289SLinus Walleij host->mclk); 1487c8df9a53SLinus Walleij } 1488ef289982SUlf Hansson 1489c8ebae37SRussell King host->phybase = dev->res.start; 1490ef289982SUlf Hansson host->base = devm_ioremap_resource(&dev->dev, &dev->res); 1491ef289982SUlf Hansson if (IS_ERR(host->base)) { 1492ef289982SUlf Hansson ret = PTR_ERR(host->base); 14931c6a0718SPierre Ossman goto clk_disable; 14941c6a0718SPierre Ossman } 14951c6a0718SPierre Ossman 14967f294e49SLinus Walleij /* 14977f294e49SLinus Walleij * The ARM and ST versions of the block have slightly different 14987f294e49SLinus Walleij * clock divider equations which means that the minimum divider 14997f294e49SLinus Walleij * differs too. 15007f294e49SLinus Walleij */ 15017f294e49SLinus Walleij if (variant->st_clkdiv) 15027f294e49SLinus Walleij mmc->f_min = DIV_ROUND_UP(host->mclk, 257); 15037f294e49SLinus Walleij else 15047f294e49SLinus Walleij mmc->f_min = DIV_ROUND_UP(host->mclk, 512); 1505808d97ccSLinus Walleij /* 150678f87df2SUlf Hansson * If no maximum operating frequency is supplied, fall back to use 150778f87df2SUlf Hansson * the module parameter, which has a (low) default value in case it 150878f87df2SUlf Hansson * is not specified. Either value must not exceed the clock rate into 150978f87df2SUlf Hansson * the block, of course. Also note that DT takes precedence over 151078f87df2SUlf Hansson * platform data. 1511808d97ccSLinus Walleij */ 151278f87df2SUlf Hansson if (mmc->f_max) 151378f87df2SUlf Hansson mmc->f_max = min(host->mclk, mmc->f_max); 151478f87df2SUlf Hansson else if (plat->f_max) 1515808d97ccSLinus Walleij mmc->f_max = min(host->mclk, plat->f_max); 1516808d97ccSLinus Walleij else 15171c6a0718SPierre Ossman mmc->f_max = min(host->mclk, fmax); 151864de0289SLinus Walleij dev_dbg(mmc_dev(mmc), "clocking block at %u Hz\n", mmc->f_max); 151964de0289SLinus Walleij 1520599c1d5cSUlf Hansson /* Get regulators and the supported OCR mask */ 1521599c1d5cSUlf Hansson mmc_regulator_get_supply(mmc); 1522599c1d5cSUlf Hansson if (!mmc->ocr_avail) 15231c6a0718SPierre Ossman mmc->ocr_avail = plat->ocr_mask; 1524599c1d5cSUlf Hansson else if (plat->ocr_mask) 1525599c1d5cSUlf Hansson dev_warn(mmc_dev(mmc), "Platform OCR mask is ignored\n"); 1526599c1d5cSUlf Hansson 152778f87df2SUlf Hansson /* DT takes precedence over platform data. */ 152878f87df2SUlf Hansson mmc->caps = np ? mmc->caps : plat->capabilities; 152978f87df2SUlf Hansson mmc->caps2 = np ? mmc->caps2 : plat->capabilities2; 153078f87df2SUlf Hansson if (!np) { 1531d2762090SUlf Hansson if (!plat->cd_invert) 1532d2762090SUlf Hansson mmc->caps2 |= MMC_CAP2_CD_ACTIVE_HIGH; 1533d2762090SUlf Hansson mmc->caps2 |= MMC_CAP2_RO_ACTIVE_HIGH; 153478f87df2SUlf Hansson } 15351c6a0718SPierre Ossman 15368d94b54dSUlf Hansson if (variant->busy_detect) { 15378d94b54dSUlf Hansson mmci_ops.card_busy = mmci_card_busy; 15388d94b54dSUlf Hansson mmci_write_datactrlreg(host, MCI_ST_DPSM_BUSYMODE); 15398d94b54dSUlf Hansson mmc->caps |= MMC_CAP_WAIT_WHILE_BUSY; 15408d94b54dSUlf Hansson mmc->max_busy_timeout = 0; 15418d94b54dSUlf Hansson } 15428d94b54dSUlf Hansson 15438d94b54dSUlf Hansson mmc->ops = &mmci_ops; 15448d94b54dSUlf Hansson 154570be208fSUlf Hansson /* We support these PM capabilities. */ 154678f87df2SUlf Hansson mmc->pm_caps |= MMC_PM_KEEP_POWER; 154770be208fSUlf Hansson 15481c6a0718SPierre Ossman /* 15491c6a0718SPierre Ossman * We can do SGIO 15501c6a0718SPierre Ossman */ 1551a36274e0SMartin K. Petersen mmc->max_segs = NR_SG; 15521c6a0718SPierre Ossman 15531c6a0718SPierre Ossman /* 155408458ef6SRabin Vincent * Since only a certain number of bits are valid in the data length 155508458ef6SRabin Vincent * register, we must ensure that we don't exceed 2^num-1 bytes in a 155608458ef6SRabin Vincent * single request. 15571c6a0718SPierre Ossman */ 155808458ef6SRabin Vincent mmc->max_req_size = (1 << variant->datalength_bits) - 1; 15591c6a0718SPierre Ossman 15601c6a0718SPierre Ossman /* 15611c6a0718SPierre Ossman * Set the maximum segment size. Since we aren't doing DMA 15621c6a0718SPierre Ossman * (yet) we are only limited by the data length register. 15631c6a0718SPierre Ossman */ 15641c6a0718SPierre Ossman mmc->max_seg_size = mmc->max_req_size; 15651c6a0718SPierre Ossman 15661c6a0718SPierre Ossman /* 15671c6a0718SPierre Ossman * Block size can be up to 2048 bytes, but must be a power of two. 15681c6a0718SPierre Ossman */ 15698f7f6b7eSWill Deacon mmc->max_blk_size = 1 << 11; 15701c6a0718SPierre Ossman 15711c6a0718SPierre Ossman /* 15728f7f6b7eSWill Deacon * Limit the number of blocks transferred so that we don't overflow 15738f7f6b7eSWill Deacon * the maximum request size. 15741c6a0718SPierre Ossman */ 15758f7f6b7eSWill Deacon mmc->max_blk_count = mmc->max_req_size >> 11; 15761c6a0718SPierre Ossman 15771c6a0718SPierre Ossman spin_lock_init(&host->lock); 15781c6a0718SPierre Ossman 15791c6a0718SPierre Ossman writel(0, host->base + MMCIMASK0); 15801c6a0718SPierre Ossman writel(0, host->base + MMCIMASK1); 15811c6a0718SPierre Ossman writel(0xfff, host->base + MMCICLEAR); 15821c6a0718SPierre Ossman 158378f87df2SUlf Hansson /* If DT, cd/wp gpios must be supplied through it. */ 158478f87df2SUlf Hansson if (!np && gpio_is_valid(plat->gpio_cd)) { 1585d2762090SUlf Hansson ret = mmc_gpio_request_cd(mmc, plat->gpio_cd, 0); 1586d2762090SUlf Hansson if (ret) 1587ef289982SUlf Hansson goto clk_disable; 158889001446SRussell King } 158978f87df2SUlf Hansson if (!np && gpio_is_valid(plat->gpio_wp)) { 1590d2762090SUlf Hansson ret = mmc_gpio_request_ro(mmc, plat->gpio_wp); 1591d2762090SUlf Hansson if (ret) 1592ef289982SUlf Hansson goto clk_disable; 159389001446SRussell King } 159489001446SRussell King 1595ef289982SUlf Hansson ret = devm_request_irq(&dev->dev, dev->irq[0], mmci_irq, IRQF_SHARED, 1596ef289982SUlf Hansson DRIVER_NAME " (cmd)", host); 15971c6a0718SPierre Ossman if (ret) 1598ef289982SUlf Hansson goto clk_disable; 15991c6a0718SPierre Ossman 1600dfb85185SRussell King if (!dev->irq[1]) 16012686b4b4SLinus Walleij host->singleirq = true; 16022686b4b4SLinus Walleij else { 1603ef289982SUlf Hansson ret = devm_request_irq(&dev->dev, dev->irq[1], mmci_pio_irq, 1604ef289982SUlf Hansson IRQF_SHARED, DRIVER_NAME " (pio)", host); 16051c6a0718SPierre Ossman if (ret) 1606ef289982SUlf Hansson goto clk_disable; 16072686b4b4SLinus Walleij } 16081c6a0718SPierre Ossman 16098cb28155SLinus Walleij writel(MCI_IRQENABLE, host->base + MMCIMASK0); 16101c6a0718SPierre Ossman 16111c6a0718SPierre Ossman amba_set_drvdata(dev, mmc); 16121c6a0718SPierre Ossman 1613c8ebae37SRussell King dev_info(&dev->dev, "%s: PL%03x manf %x rev%u at 0x%08llx irq %d,%d (pio)\n", 1614c8ebae37SRussell King mmc_hostname(mmc), amba_part(dev), amba_manf(dev), 1615c8ebae37SRussell King amba_rev(dev), (unsigned long long)dev->res.start, 1616c8ebae37SRussell King dev->irq[0], dev->irq[1]); 1617c8ebae37SRussell King 1618c8ebae37SRussell King mmci_dma_setup(host); 16191c6a0718SPierre Ossman 16202cd976c4SUlf Hansson pm_runtime_set_autosuspend_delay(&dev->dev, 50); 16212cd976c4SUlf Hansson pm_runtime_use_autosuspend(&dev->dev); 16221c3be369SRussell King pm_runtime_put(&dev->dev); 16231c3be369SRussell King 16248c11a94dSRussell King mmc_add_host(mmc); 16258c11a94dSRussell King 16261c6a0718SPierre Ossman return 0; 16271c6a0718SPierre Ossman 16281c6a0718SPierre Ossman clk_disable: 1629ac940938SJulia Lawall clk_disable_unprepare(host->clk); 16301c6a0718SPierre Ossman host_free: 16311c6a0718SPierre Ossman mmc_free_host(mmc); 16321c6a0718SPierre Ossman return ret; 16331c6a0718SPierre Ossman } 16341c6a0718SPierre Ossman 16356e0ee714SBill Pemberton static int mmci_remove(struct amba_device *dev) 16361c6a0718SPierre Ossman { 16371c6a0718SPierre Ossman struct mmc_host *mmc = amba_get_drvdata(dev); 16381c6a0718SPierre Ossman 16391c6a0718SPierre Ossman if (mmc) { 16401c6a0718SPierre Ossman struct mmci_host *host = mmc_priv(mmc); 16411c6a0718SPierre Ossman 16421c3be369SRussell King /* 16431c3be369SRussell King * Undo pm_runtime_put() in probe. We use the _sync 16441c3be369SRussell King * version here so that we can access the primecell. 16451c3be369SRussell King */ 16461c3be369SRussell King pm_runtime_get_sync(&dev->dev); 16471c3be369SRussell King 16481c6a0718SPierre Ossman mmc_remove_host(mmc); 16491c6a0718SPierre Ossman 16501c6a0718SPierre Ossman writel(0, host->base + MMCIMASK0); 16511c6a0718SPierre Ossman writel(0, host->base + MMCIMASK1); 16521c6a0718SPierre Ossman 16531c6a0718SPierre Ossman writel(0, host->base + MMCICOMMAND); 16541c6a0718SPierre Ossman writel(0, host->base + MMCIDATACTRL); 16551c6a0718SPierre Ossman 1656c8ebae37SRussell King mmci_dma_release(host); 1657ac940938SJulia Lawall clk_disable_unprepare(host->clk); 16581c6a0718SPierre Ossman mmc_free_host(mmc); 16591c6a0718SPierre Ossman } 16601c6a0718SPierre Ossman 16611c6a0718SPierre Ossman return 0; 16621c6a0718SPierre Ossman } 16631c6a0718SPierre Ossman 1664571dce4fSUlf Hansson #ifdef CONFIG_PM 16651ff44433SUlf Hansson static void mmci_save(struct mmci_host *host) 16661ff44433SUlf Hansson { 16671ff44433SUlf Hansson unsigned long flags; 16681ff44433SUlf Hansson 16691ff44433SUlf Hansson spin_lock_irqsave(&host->lock, flags); 16701ff44433SUlf Hansson 16711ff44433SUlf Hansson writel(0, host->base + MMCIMASK0); 167242dcc89aSUlf Hansson if (host->variant->pwrreg_nopower) { 16731ff44433SUlf Hansson writel(0, host->base + MMCIDATACTRL); 16741ff44433SUlf Hansson writel(0, host->base + MMCIPOWER); 16751ff44433SUlf Hansson writel(0, host->base + MMCICLOCK); 167642dcc89aSUlf Hansson } 16771ff44433SUlf Hansson mmci_reg_delay(host); 16781ff44433SUlf Hansson 16791ff44433SUlf Hansson spin_unlock_irqrestore(&host->lock, flags); 16801ff44433SUlf Hansson } 16811ff44433SUlf Hansson 16821ff44433SUlf Hansson static void mmci_restore(struct mmci_host *host) 16831ff44433SUlf Hansson { 16841ff44433SUlf Hansson unsigned long flags; 16851ff44433SUlf Hansson 16861ff44433SUlf Hansson spin_lock_irqsave(&host->lock, flags); 16871ff44433SUlf Hansson 168842dcc89aSUlf Hansson if (host->variant->pwrreg_nopower) { 16891ff44433SUlf Hansson writel(host->clk_reg, host->base + MMCICLOCK); 16901ff44433SUlf Hansson writel(host->datactrl_reg, host->base + MMCIDATACTRL); 16911ff44433SUlf Hansson writel(host->pwr_reg, host->base + MMCIPOWER); 169242dcc89aSUlf Hansson } 16931ff44433SUlf Hansson writel(MCI_IRQENABLE, host->base + MMCIMASK0); 16941ff44433SUlf Hansson mmci_reg_delay(host); 16951ff44433SUlf Hansson 16961ff44433SUlf Hansson spin_unlock_irqrestore(&host->lock, flags); 16971ff44433SUlf Hansson } 16981ff44433SUlf Hansson 16998259293aSUlf Hansson static int mmci_runtime_suspend(struct device *dev) 17008259293aSUlf Hansson { 17018259293aSUlf Hansson struct amba_device *adev = to_amba_device(dev); 17028259293aSUlf Hansson struct mmc_host *mmc = amba_get_drvdata(adev); 17038259293aSUlf Hansson 17048259293aSUlf Hansson if (mmc) { 17058259293aSUlf Hansson struct mmci_host *host = mmc_priv(mmc); 1706e36bd9c6SUlf Hansson pinctrl_pm_select_sleep_state(dev); 17071ff44433SUlf Hansson mmci_save(host); 17088259293aSUlf Hansson clk_disable_unprepare(host->clk); 17098259293aSUlf Hansson } 17108259293aSUlf Hansson 17118259293aSUlf Hansson return 0; 17128259293aSUlf Hansson } 17138259293aSUlf Hansson 17148259293aSUlf Hansson static int mmci_runtime_resume(struct device *dev) 17158259293aSUlf Hansson { 17168259293aSUlf Hansson struct amba_device *adev = to_amba_device(dev); 17178259293aSUlf Hansson struct mmc_host *mmc = amba_get_drvdata(adev); 17188259293aSUlf Hansson 17198259293aSUlf Hansson if (mmc) { 17208259293aSUlf Hansson struct mmci_host *host = mmc_priv(mmc); 17218259293aSUlf Hansson clk_prepare_enable(host->clk); 17221ff44433SUlf Hansson mmci_restore(host); 1723e36bd9c6SUlf Hansson pinctrl_pm_select_default_state(dev); 17248259293aSUlf Hansson } 17258259293aSUlf Hansson 17268259293aSUlf Hansson return 0; 17278259293aSUlf Hansson } 17288259293aSUlf Hansson #endif 17298259293aSUlf Hansson 173048fa7003SUlf Hansson static const struct dev_pm_ops mmci_dev_pm_ops = { 1731f3737fa3SUlf Hansson SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, 1732f3737fa3SUlf Hansson pm_runtime_force_resume) 1733571dce4fSUlf Hansson SET_PM_RUNTIME_PM_OPS(mmci_runtime_suspend, mmci_runtime_resume, NULL) 173448fa7003SUlf Hansson }; 173548fa7003SUlf Hansson 17361c6a0718SPierre Ossman static struct amba_id mmci_ids[] = { 17371c6a0718SPierre Ossman { 17381c6a0718SPierre Ossman .id = 0x00041180, 1739768fbc18SPawel Moll .mask = 0xff0fffff, 17404956e109SRabin Vincent .data = &variant_arm, 17411c6a0718SPierre Ossman }, 17421c6a0718SPierre Ossman { 1743768fbc18SPawel Moll .id = 0x01041180, 1744768fbc18SPawel Moll .mask = 0xff0fffff, 1745768fbc18SPawel Moll .data = &variant_arm_extended_fifo, 1746768fbc18SPawel Moll }, 1747768fbc18SPawel Moll { 17483a37298aSPawel Moll .id = 0x02041180, 17493a37298aSPawel Moll .mask = 0xff0fffff, 17503a37298aSPawel Moll .data = &variant_arm_extended_fifo_hwfc, 17513a37298aSPawel Moll }, 17523a37298aSPawel Moll { 17531c6a0718SPierre Ossman .id = 0x00041181, 17541c6a0718SPierre Ossman .mask = 0x000fffff, 17554956e109SRabin Vincent .data = &variant_arm, 17561c6a0718SPierre Ossman }, 1757cc30d60eSLinus Walleij /* ST Micro variants */ 1758cc30d60eSLinus Walleij { 1759cc30d60eSLinus Walleij .id = 0x00180180, 1760cc30d60eSLinus Walleij .mask = 0x00ffffff, 17614956e109SRabin Vincent .data = &variant_u300, 1762cc30d60eSLinus Walleij }, 1763cc30d60eSLinus Walleij { 176434fd4213SLinus Walleij .id = 0x10180180, 176534fd4213SLinus Walleij .mask = 0xf0ffffff, 176634fd4213SLinus Walleij .data = &variant_nomadik, 176734fd4213SLinus Walleij }, 176834fd4213SLinus Walleij { 1769cc30d60eSLinus Walleij .id = 0x00280180, 1770cc30d60eSLinus Walleij .mask = 0x00ffffff, 17714956e109SRabin Vincent .data = &variant_u300, 17724956e109SRabin Vincent }, 17734956e109SRabin Vincent { 17744956e109SRabin Vincent .id = 0x00480180, 17751784b157SPhilippe Langlais .mask = 0xf0ffffff, 17764956e109SRabin Vincent .data = &variant_ux500, 1777cc30d60eSLinus Walleij }, 17781784b157SPhilippe Langlais { 17791784b157SPhilippe Langlais .id = 0x10480180, 17801784b157SPhilippe Langlais .mask = 0xf0ffffff, 17811784b157SPhilippe Langlais .data = &variant_ux500v2, 17821784b157SPhilippe Langlais }, 17831c6a0718SPierre Ossman { 0, 0 }, 17841c6a0718SPierre Ossman }; 17851c6a0718SPierre Ossman 17869f99835fSDave Martin MODULE_DEVICE_TABLE(amba, mmci_ids); 17879f99835fSDave Martin 17881c6a0718SPierre Ossman static struct amba_driver mmci_driver = { 17891c6a0718SPierre Ossman .drv = { 17901c6a0718SPierre Ossman .name = DRIVER_NAME, 179148fa7003SUlf Hansson .pm = &mmci_dev_pm_ops, 17921c6a0718SPierre Ossman }, 17931c6a0718SPierre Ossman .probe = mmci_probe, 17940433c143SBill Pemberton .remove = mmci_remove, 17951c6a0718SPierre Ossman .id_table = mmci_ids, 17961c6a0718SPierre Ossman }; 17971c6a0718SPierre Ossman 17989e5ed094Sviresh kumar module_amba_driver(mmci_driver); 17991c6a0718SPierre Ossman 18001c6a0718SPierre Ossman module_param(fmax, uint, 0444); 18011c6a0718SPierre Ossman 18021c6a0718SPierre Ossman MODULE_DESCRIPTION("ARM PrimeCell PL180/181 Multimedia Card Interface driver"); 18031c6a0718SPierre Ossman MODULE_LICENSE("GPL"); 1804