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, 5908458ef6SRabin Vincent .datalength_bits = 16, 607d72a1d4SUlf Hansson .pwrreg_powerup = MCI_PWR_UP, 61dc6500bfSSrinivas Kandagatla .f_max = 100000000, 627878289bSUlf Hansson .reversed_irq_handling = true, 636ea9cdf3SPatrice Chotard .mmcimask1 = true, 647f7b5503SPatrice Chotard .start_err = MCI_STARTBITERR, 6511dfb970SPatrice Chotard .opendrain = MCI_ROD, 66c3647fdcSLudovic Barre .init = mmci_variant_init, 674956e109SRabin Vincent }; 684956e109SRabin Vincent 69768fbc18SPawel Moll static struct variant_data variant_arm_extended_fifo = { 70768fbc18SPawel Moll .fifosize = 128 * 4, 71768fbc18SPawel Moll .fifohalfsize = 64 * 4, 72768fbc18SPawel Moll .datalength_bits = 16, 737d72a1d4SUlf Hansson .pwrreg_powerup = MCI_PWR_UP, 74dc6500bfSSrinivas Kandagatla .f_max = 100000000, 756ea9cdf3SPatrice Chotard .mmcimask1 = true, 767f7b5503SPatrice Chotard .start_err = MCI_STARTBITERR, 7711dfb970SPatrice Chotard .opendrain = MCI_ROD, 78c3647fdcSLudovic Barre .init = mmci_variant_init, 79768fbc18SPawel Moll }; 80768fbc18SPawel Moll 813a37298aSPawel Moll static struct variant_data variant_arm_extended_fifo_hwfc = { 823a37298aSPawel Moll .fifosize = 128 * 4, 833a37298aSPawel Moll .fifohalfsize = 64 * 4, 843a37298aSPawel Moll .clkreg_enable = MCI_ARM_HWFCEN, 853a37298aSPawel Moll .datalength_bits = 16, 863a37298aSPawel Moll .pwrreg_powerup = MCI_PWR_UP, 87dc6500bfSSrinivas Kandagatla .f_max = 100000000, 886ea9cdf3SPatrice Chotard .mmcimask1 = true, 897f7b5503SPatrice Chotard .start_err = MCI_STARTBITERR, 9011dfb970SPatrice Chotard .opendrain = MCI_ROD, 91c3647fdcSLudovic Barre .init = mmci_variant_init, 923a37298aSPawel Moll }; 933a37298aSPawel Moll 944956e109SRabin Vincent static struct variant_data variant_u300 = { 958301bb68SRabin Vincent .fifosize = 16 * 4, 968301bb68SRabin Vincent .fifohalfsize = 8 * 4, 9749ac215eSLinus Walleij .clkreg_enable = MCI_ST_U300_HWFCEN, 98e1412d85SSrinivas Kandagatla .clkreg_8bit_bus_enable = MCI_ST_8BIT_BUS, 9908458ef6SRabin Vincent .datalength_bits = 16, 1005db3eee7SLinus Walleij .datactrl_mask_sdio = MCI_DPSM_ST_SDIOEN, 101c7354133SSrinivas Kandagatla .st_sdio = true, 1027d72a1d4SUlf Hansson .pwrreg_powerup = MCI_PWR_ON, 103dc6500bfSSrinivas Kandagatla .f_max = 100000000, 1044d1a3a0dSUlf Hansson .signal_direction = true, 105f4670daeSUlf Hansson .pwrreg_clkgate = true, 1061ff44433SUlf Hansson .pwrreg_nopower = true, 1076ea9cdf3SPatrice Chotard .mmcimask1 = true, 1087f7b5503SPatrice Chotard .start_err = MCI_STARTBITERR, 10911dfb970SPatrice Chotard .opendrain = MCI_OD, 110c3647fdcSLudovic Barre .init = mmci_variant_init, 1114956e109SRabin Vincent }; 1124956e109SRabin Vincent 11334fd4213SLinus Walleij static struct variant_data variant_nomadik = { 11434fd4213SLinus Walleij .fifosize = 16 * 4, 11534fd4213SLinus Walleij .fifohalfsize = 8 * 4, 11634fd4213SLinus Walleij .clkreg = MCI_CLK_ENABLE, 117f5abc767SLinus Walleij .clkreg_8bit_bus_enable = MCI_ST_8BIT_BUS, 11834fd4213SLinus Walleij .datalength_bits = 24, 1195db3eee7SLinus Walleij .datactrl_mask_sdio = MCI_DPSM_ST_SDIOEN, 120c7354133SSrinivas Kandagatla .st_sdio = true, 12134fd4213SLinus Walleij .st_clkdiv = true, 12234fd4213SLinus Walleij .pwrreg_powerup = MCI_PWR_ON, 123dc6500bfSSrinivas Kandagatla .f_max = 100000000, 12434fd4213SLinus Walleij .signal_direction = true, 125f4670daeSUlf Hansson .pwrreg_clkgate = true, 1261ff44433SUlf Hansson .pwrreg_nopower = true, 1276ea9cdf3SPatrice Chotard .mmcimask1 = true, 1287f7b5503SPatrice Chotard .start_err = MCI_STARTBITERR, 12911dfb970SPatrice Chotard .opendrain = MCI_OD, 130c3647fdcSLudovic Barre .init = mmci_variant_init, 13134fd4213SLinus Walleij }; 13234fd4213SLinus Walleij 1334956e109SRabin Vincent static struct variant_data variant_ux500 = { 1348301bb68SRabin Vincent .fifosize = 30 * 4, 1358301bb68SRabin Vincent .fifohalfsize = 8 * 4, 1364956e109SRabin Vincent .clkreg = MCI_CLK_ENABLE, 13749ac215eSLinus Walleij .clkreg_enable = MCI_ST_UX500_HWFCEN, 138e1412d85SSrinivas Kandagatla .clkreg_8bit_bus_enable = MCI_ST_8BIT_BUS, 139e8740644SSrinivas Kandagatla .clkreg_neg_edge_enable = MCI_ST_UX500_NEG_EDGE, 14008458ef6SRabin Vincent .datalength_bits = 24, 1415db3eee7SLinus Walleij .datactrl_mask_sdio = MCI_DPSM_ST_SDIOEN, 142c7354133SSrinivas Kandagatla .st_sdio = true, 143b70a67f9SLinus Walleij .st_clkdiv = true, 1447d72a1d4SUlf Hansson .pwrreg_powerup = MCI_PWR_ON, 145dc6500bfSSrinivas Kandagatla .f_max = 100000000, 1464d1a3a0dSUlf Hansson .signal_direction = true, 147f4670daeSUlf Hansson .pwrreg_clkgate = true, 14801259620SUlf Hansson .busy_detect = true, 14949adc0caSLinus Walleij .busy_dpsm_flag = MCI_DPSM_ST_BUSYMODE, 15049adc0caSLinus Walleij .busy_detect_flag = MCI_ST_CARDBUSY, 15149adc0caSLinus Walleij .busy_detect_mask = MCI_ST_BUSYENDMASK, 1521ff44433SUlf Hansson .pwrreg_nopower = true, 1536ea9cdf3SPatrice Chotard .mmcimask1 = true, 1547f7b5503SPatrice Chotard .start_err = MCI_STARTBITERR, 15511dfb970SPatrice Chotard .opendrain = MCI_OD, 156c3647fdcSLudovic Barre .init = mmci_variant_init, 1574956e109SRabin Vincent }; 158b70a67f9SLinus Walleij 1591784b157SPhilippe Langlais static struct variant_data variant_ux500v2 = { 1601784b157SPhilippe Langlais .fifosize = 30 * 4, 1611784b157SPhilippe Langlais .fifohalfsize = 8 * 4, 1621784b157SPhilippe Langlais .clkreg = MCI_CLK_ENABLE, 1631784b157SPhilippe Langlais .clkreg_enable = MCI_ST_UX500_HWFCEN, 164e1412d85SSrinivas Kandagatla .clkreg_8bit_bus_enable = MCI_ST_8BIT_BUS, 165e8740644SSrinivas Kandagatla .clkreg_neg_edge_enable = MCI_ST_UX500_NEG_EDGE, 1665db3eee7SLinus Walleij .datactrl_mask_ddrmode = MCI_DPSM_ST_DDRMODE, 1671784b157SPhilippe Langlais .datalength_bits = 24, 1685db3eee7SLinus Walleij .datactrl_mask_sdio = MCI_DPSM_ST_SDIOEN, 169c7354133SSrinivas Kandagatla .st_sdio = true, 1701784b157SPhilippe Langlais .st_clkdiv = true, 1711784b157SPhilippe Langlais .blksz_datactrl16 = true, 1727d72a1d4SUlf Hansson .pwrreg_powerup = MCI_PWR_ON, 173dc6500bfSSrinivas Kandagatla .f_max = 100000000, 1744d1a3a0dSUlf Hansson .signal_direction = true, 175f4670daeSUlf Hansson .pwrreg_clkgate = true, 17601259620SUlf Hansson .busy_detect = true, 17749adc0caSLinus Walleij .busy_dpsm_flag = MCI_DPSM_ST_BUSYMODE, 17849adc0caSLinus Walleij .busy_detect_flag = MCI_ST_CARDBUSY, 17949adc0caSLinus Walleij .busy_detect_mask = MCI_ST_BUSYENDMASK, 1801ff44433SUlf Hansson .pwrreg_nopower = true, 1816ea9cdf3SPatrice Chotard .mmcimask1 = true, 1827f7b5503SPatrice Chotard .start_err = MCI_STARTBITERR, 18311dfb970SPatrice Chotard .opendrain = MCI_OD, 184c3647fdcSLudovic Barre .init = mmci_variant_init, 1851784b157SPhilippe Langlais }; 1861784b157SPhilippe Langlais 1872a9d6c80SPatrice Chotard static struct variant_data variant_stm32 = { 1882a9d6c80SPatrice Chotard .fifosize = 32 * 4, 1892a9d6c80SPatrice Chotard .fifohalfsize = 8 * 4, 1902a9d6c80SPatrice Chotard .clkreg = MCI_CLK_ENABLE, 1912a9d6c80SPatrice Chotard .clkreg_enable = MCI_ST_UX500_HWFCEN, 1922a9d6c80SPatrice Chotard .clkreg_8bit_bus_enable = MCI_ST_8BIT_BUS, 1932a9d6c80SPatrice Chotard .clkreg_neg_edge_enable = MCI_ST_UX500_NEG_EDGE, 1942a9d6c80SPatrice Chotard .datalength_bits = 24, 1952a9d6c80SPatrice Chotard .datactrl_mask_sdio = MCI_DPSM_ST_SDIOEN, 1962a9d6c80SPatrice Chotard .st_sdio = true, 1972a9d6c80SPatrice Chotard .st_clkdiv = true, 1982a9d6c80SPatrice Chotard .pwrreg_powerup = MCI_PWR_ON, 1992a9d6c80SPatrice Chotard .f_max = 48000000, 2002a9d6c80SPatrice Chotard .pwrreg_clkgate = true, 2012a9d6c80SPatrice Chotard .pwrreg_nopower = true, 202c3647fdcSLudovic Barre .init = mmci_variant_init, 2032a9d6c80SPatrice Chotard }; 2042a9d6c80SPatrice Chotard 20555b604aeSSrinivas Kandagatla static struct variant_data variant_qcom = { 20655b604aeSSrinivas Kandagatla .fifosize = 16 * 4, 20755b604aeSSrinivas Kandagatla .fifohalfsize = 8 * 4, 20855b604aeSSrinivas Kandagatla .clkreg = MCI_CLK_ENABLE, 20955b604aeSSrinivas Kandagatla .clkreg_enable = MCI_QCOM_CLK_FLOWENA | 21055b604aeSSrinivas Kandagatla MCI_QCOM_CLK_SELECT_IN_FBCLK, 21155b604aeSSrinivas Kandagatla .clkreg_8bit_bus_enable = MCI_QCOM_CLK_WIDEBUS_8, 21255b604aeSSrinivas Kandagatla .datactrl_mask_ddrmode = MCI_QCOM_CLK_SELECT_IN_DDR_MODE, 2135db3eee7SLinus Walleij .data_cmd_enable = MCI_CPSM_QCOM_DATCMD, 21455b604aeSSrinivas Kandagatla .blksz_datactrl4 = true, 21555b604aeSSrinivas Kandagatla .datalength_bits = 24, 21655b604aeSSrinivas Kandagatla .pwrreg_powerup = MCI_PWR_UP, 21755b604aeSSrinivas Kandagatla .f_max = 208000000, 21855b604aeSSrinivas Kandagatla .explicit_mclk_control = true, 21955b604aeSSrinivas Kandagatla .qcom_fifo = true, 2209cb15142SSrinivas Kandagatla .qcom_dml = true, 2216ea9cdf3SPatrice Chotard .mmcimask1 = true, 2227f7b5503SPatrice Chotard .start_err = MCI_STARTBITERR, 22311dfb970SPatrice Chotard .opendrain = MCI_ROD, 22429aba07aSUlf Hansson .init = qcom_variant_init, 22555b604aeSSrinivas Kandagatla }; 22655b604aeSSrinivas Kandagatla 22749adc0caSLinus Walleij /* Busy detection for the ST Micro variant */ 22801259620SUlf Hansson static int mmci_card_busy(struct mmc_host *mmc) 22901259620SUlf Hansson { 23001259620SUlf Hansson struct mmci_host *host = mmc_priv(mmc); 23101259620SUlf Hansson unsigned long flags; 23201259620SUlf Hansson int busy = 0; 23301259620SUlf Hansson 23401259620SUlf Hansson spin_lock_irqsave(&host->lock, flags); 23549adc0caSLinus Walleij if (readl(host->base + MMCISTATUS) & host->variant->busy_detect_flag) 23601259620SUlf Hansson busy = 1; 23701259620SUlf Hansson spin_unlock_irqrestore(&host->lock, flags); 23801259620SUlf Hansson 23901259620SUlf Hansson return busy; 24001259620SUlf Hansson } 24101259620SUlf Hansson 242a6a6464aSLinus Walleij /* 243653a761eSUlf Hansson * Validate mmc prerequisites 244653a761eSUlf Hansson */ 245653a761eSUlf Hansson static int mmci_validate_data(struct mmci_host *host, 246653a761eSUlf Hansson struct mmc_data *data) 247653a761eSUlf Hansson { 248653a761eSUlf Hansson if (!data) 249653a761eSUlf Hansson return 0; 250653a761eSUlf Hansson 251653a761eSUlf Hansson if (!is_power_of_2(data->blksz)) { 252653a761eSUlf Hansson dev_err(mmc_dev(host->mmc), 253653a761eSUlf Hansson "unsupported block size (%d bytes)\n", data->blksz); 254653a761eSUlf Hansson return -EINVAL; 255653a761eSUlf Hansson } 256653a761eSUlf Hansson 257653a761eSUlf Hansson return 0; 258653a761eSUlf Hansson } 259653a761eSUlf Hansson 260f829c042SUlf Hansson static void mmci_reg_delay(struct mmci_host *host) 261f829c042SUlf Hansson { 262f829c042SUlf Hansson /* 263f829c042SUlf Hansson * According to the spec, at least three feedback clock cycles 264f829c042SUlf Hansson * of max 52 MHz must pass between two writes to the MMCICLOCK reg. 265f829c042SUlf Hansson * Three MCLK clock cycles must pass between two MMCIPOWER reg writes. 266f829c042SUlf Hansson * Worst delay time during card init is at 100 kHz => 30 us. 267f829c042SUlf Hansson * Worst delay time when up and running is at 25 MHz => 120 ns. 268f829c042SUlf Hansson */ 269f829c042SUlf Hansson if (host->cclk < 25000000) 270f829c042SUlf Hansson udelay(30); 271f829c042SUlf Hansson else 272f829c042SUlf Hansson ndelay(120); 273f829c042SUlf Hansson } 274f829c042SUlf Hansson 275653a761eSUlf Hansson /* 276a6a6464aSLinus Walleij * This must be called with host->lock held 277a6a6464aSLinus Walleij */ 2787437cfa5SUlf Hansson static void mmci_write_clkreg(struct mmci_host *host, u32 clk) 2797437cfa5SUlf Hansson { 2807437cfa5SUlf Hansson if (host->clk_reg != clk) { 2817437cfa5SUlf Hansson host->clk_reg = clk; 2827437cfa5SUlf Hansson writel(clk, host->base + MMCICLOCK); 2837437cfa5SUlf Hansson } 2847437cfa5SUlf Hansson } 2857437cfa5SUlf Hansson 2867437cfa5SUlf Hansson /* 2877437cfa5SUlf Hansson * This must be called with host->lock held 2887437cfa5SUlf Hansson */ 2897437cfa5SUlf Hansson static void mmci_write_pwrreg(struct mmci_host *host, u32 pwr) 2907437cfa5SUlf Hansson { 2917437cfa5SUlf Hansson if (host->pwr_reg != pwr) { 2927437cfa5SUlf Hansson host->pwr_reg = pwr; 2937437cfa5SUlf Hansson writel(pwr, host->base + MMCIPOWER); 2947437cfa5SUlf Hansson } 2957437cfa5SUlf Hansson } 2967437cfa5SUlf Hansson 2977437cfa5SUlf Hansson /* 2987437cfa5SUlf Hansson * This must be called with host->lock held 2997437cfa5SUlf Hansson */ 3009cc639a2SUlf Hansson static void mmci_write_datactrlreg(struct mmci_host *host, u32 datactrl) 3019cc639a2SUlf Hansson { 30249adc0caSLinus Walleij /* Keep busy mode in DPSM if enabled */ 30349adc0caSLinus Walleij datactrl |= host->datactrl_reg & host->variant->busy_dpsm_flag; 30401259620SUlf Hansson 3059cc639a2SUlf Hansson if (host->datactrl_reg != datactrl) { 3069cc639a2SUlf Hansson host->datactrl_reg = datactrl; 3079cc639a2SUlf Hansson writel(datactrl, host->base + MMCIDATACTRL); 3089cc639a2SUlf Hansson } 3099cc639a2SUlf Hansson } 3109cc639a2SUlf Hansson 3119cc639a2SUlf Hansson /* 3129cc639a2SUlf Hansson * This must be called with host->lock held 3139cc639a2SUlf Hansson */ 314a6a6464aSLinus Walleij static void mmci_set_clkreg(struct mmci_host *host, unsigned int desired) 315a6a6464aSLinus Walleij { 3164956e109SRabin Vincent struct variant_data *variant = host->variant; 3174956e109SRabin Vincent u32 clk = variant->clkreg; 318a6a6464aSLinus Walleij 319c58a8509SUlf Hansson /* Make sure cclk reflects the current calculated clock */ 320c58a8509SUlf Hansson host->cclk = 0; 321c58a8509SUlf Hansson 322a6a6464aSLinus Walleij if (desired) { 3233f4e6f7bSSrinivas Kandagatla if (variant->explicit_mclk_control) { 3243f4e6f7bSSrinivas Kandagatla host->cclk = host->mclk; 3253f4e6f7bSSrinivas Kandagatla } else if (desired >= host->mclk) { 326a6a6464aSLinus Walleij clk = MCI_CLK_BYPASS; 327399bc486SLinus Walleij if (variant->st_clkdiv) 328399bc486SLinus Walleij clk |= MCI_ST_UX500_NEG_EDGE; 329a6a6464aSLinus Walleij host->cclk = host->mclk; 330b70a67f9SLinus Walleij } else if (variant->st_clkdiv) { 331b70a67f9SLinus Walleij /* 332b70a67f9SLinus Walleij * DB8500 TRM says f = mclk / (clkdiv + 2) 333b70a67f9SLinus Walleij * => clkdiv = (mclk / f) - 2 334b70a67f9SLinus Walleij * Round the divider up so we don't exceed the max 335b70a67f9SLinus Walleij * frequency 336b70a67f9SLinus Walleij */ 337b70a67f9SLinus Walleij clk = DIV_ROUND_UP(host->mclk, desired) - 2; 338b70a67f9SLinus Walleij if (clk >= 256) 339b70a67f9SLinus Walleij clk = 255; 340b70a67f9SLinus Walleij host->cclk = host->mclk / (clk + 2); 341a6a6464aSLinus Walleij } else { 342b70a67f9SLinus Walleij /* 343b70a67f9SLinus Walleij * PL180 TRM says f = mclk / (2 * (clkdiv + 1)) 344b70a67f9SLinus Walleij * => clkdiv = mclk / (2 * f) - 1 345b70a67f9SLinus Walleij */ 346a6a6464aSLinus Walleij clk = host->mclk / (2 * desired) - 1; 347a6a6464aSLinus Walleij if (clk >= 256) 348a6a6464aSLinus Walleij clk = 255; 349a6a6464aSLinus Walleij host->cclk = host->mclk / (2 * (clk + 1)); 350a6a6464aSLinus Walleij } 3514380c14fSRabin Vincent 3524380c14fSRabin Vincent clk |= variant->clkreg_enable; 353a6a6464aSLinus Walleij clk |= MCI_CLK_ENABLE; 354a6a6464aSLinus Walleij /* This hasn't proven to be worthwhile */ 355a6a6464aSLinus Walleij /* clk |= MCI_CLK_PWRSAVE; */ 356a6a6464aSLinus Walleij } 357a6a6464aSLinus Walleij 358c58a8509SUlf Hansson /* Set actual clock for debug */ 359c58a8509SUlf Hansson host->mmc->actual_clock = host->cclk; 360c58a8509SUlf Hansson 3619e6c82cdSLinus Walleij if (host->mmc->ios.bus_width == MMC_BUS_WIDTH_4) 362771dc157SLinus Walleij clk |= MCI_4BIT_BUS; 363771dc157SLinus Walleij if (host->mmc->ios.bus_width == MMC_BUS_WIDTH_8) 364e1412d85SSrinivas Kandagatla clk |= variant->clkreg_8bit_bus_enable; 3659e6c82cdSLinus Walleij 3666dad6c95SSeungwon Jeon if (host->mmc->ios.timing == MMC_TIMING_UHS_DDR50 || 3676dad6c95SSeungwon Jeon host->mmc->ios.timing == MMC_TIMING_MMC_DDR52) 368e8740644SSrinivas Kandagatla clk |= variant->clkreg_neg_edge_enable; 3696dbb6ee0SUlf Hansson 3707437cfa5SUlf Hansson mmci_write_clkreg(host, clk); 371a6a6464aSLinus Walleij } 372a6a6464aSLinus Walleij 373c3647fdcSLudovic Barre void mmci_dma_release(struct mmci_host *host) 374c3647fdcSLudovic Barre { 375c3647fdcSLudovic Barre if (host->ops && host->ops->dma_release) 376c3647fdcSLudovic Barre host->ops->dma_release(host); 377c3647fdcSLudovic Barre 378c3647fdcSLudovic Barre host->use_dma = false; 379c3647fdcSLudovic Barre } 380c3647fdcSLudovic Barre 381c3647fdcSLudovic Barre void mmci_dma_setup(struct mmci_host *host) 382c3647fdcSLudovic Barre { 383c3647fdcSLudovic Barre if (!host->ops || !host->ops->dma_setup) 384c3647fdcSLudovic Barre return; 385c3647fdcSLudovic Barre 386c3647fdcSLudovic Barre if (host->ops->dma_setup(host)) 387c3647fdcSLudovic Barre return; 388c3647fdcSLudovic Barre 389a813f2a2SLudovic Barre /* initialize pre request cookie */ 390a813f2a2SLudovic Barre host->next_cookie = 1; 391a813f2a2SLudovic Barre 392c3647fdcSLudovic Barre host->use_dma = true; 393c3647fdcSLudovic Barre } 394c3647fdcSLudovic Barre 39547983510SLudovic Barre int mmci_prep_data(struct mmci_host *host, struct mmc_data *data, bool next) 39647983510SLudovic Barre { 39747983510SLudovic Barre int err; 39847983510SLudovic Barre 39947983510SLudovic Barre if (!host->ops || !host->ops->prep_data) 40047983510SLudovic Barre return 0; 40147983510SLudovic Barre 40247983510SLudovic Barre err = host->ops->prep_data(host, data, next); 40347983510SLudovic Barre 40447983510SLudovic Barre if (next && !err) 40547983510SLudovic Barre data->host_cookie = ++host->next_cookie < 0 ? 40647983510SLudovic Barre 1 : host->next_cookie; 40747983510SLudovic Barre 40847983510SLudovic Barre return err; 40947983510SLudovic Barre } 41047983510SLudovic Barre 41147983510SLudovic Barre void mmci_unprep_data(struct mmci_host *host, struct mmc_data *data, 41247983510SLudovic Barre int err) 41347983510SLudovic Barre { 41447983510SLudovic Barre if (host->ops && host->ops->unprep_data) 41547983510SLudovic Barre host->ops->unprep_data(host, data, err); 41647983510SLudovic Barre 41747983510SLudovic Barre data->host_cookie = 0; 41847983510SLudovic Barre } 41947983510SLudovic Barre 4201c6a0718SPierre Ossman static void 4211c6a0718SPierre Ossman mmci_request_end(struct mmci_host *host, struct mmc_request *mrq) 4221c6a0718SPierre Ossman { 4231c6a0718SPierre Ossman writel(0, host->base + MMCICOMMAND); 4241c6a0718SPierre Ossman 4251c6a0718SPierre Ossman BUG_ON(host->data); 4261c6a0718SPierre Ossman 4271c6a0718SPierre Ossman host->mrq = NULL; 4281c6a0718SPierre Ossman host->cmd = NULL; 4291c6a0718SPierre Ossman 4301c6a0718SPierre Ossman mmc_request_done(host->mmc, mrq); 4311c6a0718SPierre Ossman } 4321c6a0718SPierre Ossman 4332686b4b4SLinus Walleij static void mmci_set_mask1(struct mmci_host *host, unsigned int mask) 4342686b4b4SLinus Walleij { 4352686b4b4SLinus Walleij void __iomem *base = host->base; 4366ea9cdf3SPatrice Chotard struct variant_data *variant = host->variant; 4372686b4b4SLinus Walleij 4382686b4b4SLinus Walleij if (host->singleirq) { 4392686b4b4SLinus Walleij unsigned int mask0 = readl(base + MMCIMASK0); 4402686b4b4SLinus Walleij 4412686b4b4SLinus Walleij mask0 &= ~MCI_IRQ1MASK; 4422686b4b4SLinus Walleij mask0 |= mask; 4432686b4b4SLinus Walleij 4442686b4b4SLinus Walleij writel(mask0, base + MMCIMASK0); 4452686b4b4SLinus Walleij } 4462686b4b4SLinus Walleij 4476ea9cdf3SPatrice Chotard if (variant->mmcimask1) 4482686b4b4SLinus Walleij writel(mask, base + MMCIMASK1); 4496ea9cdf3SPatrice Chotard 4506ea9cdf3SPatrice Chotard host->mask1_reg = mask; 4512686b4b4SLinus Walleij } 4522686b4b4SLinus Walleij 4531c6a0718SPierre Ossman static void mmci_stop_data(struct mmci_host *host) 4541c6a0718SPierre Ossman { 4559cc639a2SUlf Hansson mmci_write_datactrlreg(host, 0); 4562686b4b4SLinus Walleij mmci_set_mask1(host, 0); 4571c6a0718SPierre Ossman host->data = NULL; 4581c6a0718SPierre Ossman } 4591c6a0718SPierre Ossman 4604ce1d6cbSRabin Vincent static void mmci_init_sg(struct mmci_host *host, struct mmc_data *data) 4614ce1d6cbSRabin Vincent { 4624ce1d6cbSRabin Vincent unsigned int flags = SG_MITER_ATOMIC; 4634ce1d6cbSRabin Vincent 4644ce1d6cbSRabin Vincent if (data->flags & MMC_DATA_READ) 4654ce1d6cbSRabin Vincent flags |= SG_MITER_TO_SG; 4664ce1d6cbSRabin Vincent else 4674ce1d6cbSRabin Vincent flags |= SG_MITER_FROM_SG; 4684ce1d6cbSRabin Vincent 4694ce1d6cbSRabin Vincent sg_miter_start(&host->sg_miter, data->sg, data->sg_len, flags); 4704ce1d6cbSRabin Vincent } 4714ce1d6cbSRabin Vincent 472c8ebae37SRussell King /* 473c8ebae37SRussell King * All the DMA operation mode stuff goes inside this ifdef. 474c8ebae37SRussell King * This assumes that you have a generic DMA device interface, 475c8ebae37SRussell King * no custom DMA interfaces are supported. 476c8ebae37SRussell King */ 477c8ebae37SRussell King #ifdef CONFIG_DMA_ENGINE 478a813f2a2SLudovic Barre struct mmci_dmae_next { 479a813f2a2SLudovic Barre struct dma_async_tx_descriptor *desc; 480a813f2a2SLudovic Barre struct dma_chan *chan; 481a813f2a2SLudovic Barre }; 482a813f2a2SLudovic Barre 483a813f2a2SLudovic Barre struct mmci_dmae_priv { 484a813f2a2SLudovic Barre struct dma_chan *cur; 485a813f2a2SLudovic Barre struct dma_chan *rx_channel; 486a813f2a2SLudovic Barre struct dma_chan *tx_channel; 487a813f2a2SLudovic Barre struct dma_async_tx_descriptor *desc_current; 488a813f2a2SLudovic Barre struct mmci_dmae_next next_data; 489a813f2a2SLudovic Barre }; 490a813f2a2SLudovic Barre 491c3647fdcSLudovic Barre int mmci_dmae_setup(struct mmci_host *host) 492c8ebae37SRussell King { 493c8ebae37SRussell King const char *rxname, *txname; 494a813f2a2SLudovic Barre struct mmci_dmae_priv *dmae; 495c8ebae37SRussell King 496a813f2a2SLudovic Barre dmae = devm_kzalloc(mmc_dev(host->mmc), sizeof(*dmae), GFP_KERNEL); 497a813f2a2SLudovic Barre if (!dmae) 498a813f2a2SLudovic Barre return -ENOMEM; 499c8ebae37SRussell King 500a813f2a2SLudovic Barre host->dma_priv = dmae; 501a813f2a2SLudovic Barre 502a813f2a2SLudovic Barre dmae->rx_channel = dma_request_slave_channel(mmc_dev(host->mmc), 503a813f2a2SLudovic Barre "rx"); 504a813f2a2SLudovic Barre dmae->tx_channel = dma_request_slave_channel(mmc_dev(host->mmc), 505a813f2a2SLudovic Barre "tx"); 50658c7ccbfSPer Forlin 5071fd83f0eSLee Jones /* 5081fd83f0eSLee Jones * If only an RX channel is specified, the driver will 5091fd83f0eSLee Jones * attempt to use it bidirectionally, however if it is 5101fd83f0eSLee Jones * is specified but cannot be located, DMA will be disabled. 5111fd83f0eSLee Jones */ 512a813f2a2SLudovic Barre if (dmae->rx_channel && !dmae->tx_channel) 513a813f2a2SLudovic Barre dmae->tx_channel = dmae->rx_channel; 514c8ebae37SRussell King 515a813f2a2SLudovic Barre if (dmae->rx_channel) 516a813f2a2SLudovic Barre rxname = dma_chan_name(dmae->rx_channel); 517c8ebae37SRussell King else 518c8ebae37SRussell King rxname = "none"; 519c8ebae37SRussell King 520a813f2a2SLudovic Barre if (dmae->tx_channel) 521a813f2a2SLudovic Barre txname = dma_chan_name(dmae->tx_channel); 522c8ebae37SRussell King else 523c8ebae37SRussell King txname = "none"; 524c8ebae37SRussell King 525c8ebae37SRussell King dev_info(mmc_dev(host->mmc), "DMA channels RX %s, TX %s\n", 526c8ebae37SRussell King rxname, txname); 527c8ebae37SRussell King 528c8ebae37SRussell King /* 529c8ebae37SRussell King * Limit the maximum segment size in any SG entry according to 530c8ebae37SRussell King * the parameters of the DMA engine device. 531c8ebae37SRussell King */ 532a813f2a2SLudovic Barre if (dmae->tx_channel) { 533a813f2a2SLudovic Barre struct device *dev = dmae->tx_channel->device->dev; 534c8ebae37SRussell King unsigned int max_seg_size = dma_get_max_seg_size(dev); 535c8ebae37SRussell King 536c8ebae37SRussell King if (max_seg_size < host->mmc->max_seg_size) 537c8ebae37SRussell King host->mmc->max_seg_size = max_seg_size; 538c8ebae37SRussell King } 539a813f2a2SLudovic Barre if (dmae->rx_channel) { 540a813f2a2SLudovic Barre struct device *dev = dmae->rx_channel->device->dev; 541c8ebae37SRussell King unsigned int max_seg_size = dma_get_max_seg_size(dev); 542c8ebae37SRussell King 543c8ebae37SRussell King if (max_seg_size < host->mmc->max_seg_size) 544c8ebae37SRussell King host->mmc->max_seg_size = max_seg_size; 545c8ebae37SRussell King } 5469cb15142SSrinivas Kandagatla 547a813f2a2SLudovic Barre if (!dmae->tx_channel || !dmae->rx_channel) { 548c3647fdcSLudovic Barre mmci_dmae_release(host); 549c3647fdcSLudovic Barre return -EINVAL; 550c3647fdcSLudovic Barre } 551c3647fdcSLudovic Barre 552c3647fdcSLudovic Barre return 0; 553c8ebae37SRussell King } 554c8ebae37SRussell King 555c8ebae37SRussell King /* 5566e0ee714SBill Pemberton * This is used in or so inline it 557c8ebae37SRussell King * so it can be discarded. 558c8ebae37SRussell King */ 559c3647fdcSLudovic Barre void mmci_dmae_release(struct mmci_host *host) 560c8ebae37SRussell King { 561a813f2a2SLudovic Barre struct mmci_dmae_priv *dmae = host->dma_priv; 562a813f2a2SLudovic Barre 563a813f2a2SLudovic Barre if (dmae->rx_channel) 564a813f2a2SLudovic Barre dma_release_channel(dmae->rx_channel); 565a813f2a2SLudovic Barre if (dmae->tx_channel) 566a813f2a2SLudovic Barre dma_release_channel(dmae->tx_channel); 567a813f2a2SLudovic Barre dmae->rx_channel = dmae->tx_channel = NULL; 568c8ebae37SRussell King } 569c8ebae37SRussell King 570c8ebae37SRussell King static void mmci_dma_unmap(struct mmci_host *host, struct mmc_data *data) 571c8ebae37SRussell King { 572a813f2a2SLudovic Barre struct mmci_dmae_priv *dmae = host->dma_priv; 573653a761eSUlf Hansson struct dma_chan *chan; 574653a761eSUlf Hansson 575feeef096SHeiner Kallweit if (data->flags & MMC_DATA_READ) 576a813f2a2SLudovic Barre chan = dmae->rx_channel; 577feeef096SHeiner Kallweit else 578a813f2a2SLudovic Barre chan = dmae->tx_channel; 579653a761eSUlf Hansson 580feeef096SHeiner Kallweit dma_unmap_sg(chan->device->dev, data->sg, data->sg_len, 581feeef096SHeiner Kallweit mmc_get_dma_dir(data)); 582653a761eSUlf Hansson } 583653a761eSUlf Hansson 5847b2a6d51SLudovic Barre static void mmci_dma_data_error(struct mmci_host *host) 5857b2a6d51SLudovic Barre { 586a813f2a2SLudovic Barre struct mmci_dmae_priv *dmae = host->dma_priv; 587a813f2a2SLudovic Barre 588c3647fdcSLudovic Barre if (!host->use_dma || !dma_inprogress(host)) 589cdea1947SLudovic Barre return; 590cdea1947SLudovic Barre 5917b2a6d51SLudovic Barre dev_err(mmc_dev(host->mmc), "error during DMA transfer!\n"); 592a813f2a2SLudovic Barre dmaengine_terminate_all(dmae->cur); 5937b2a6d51SLudovic Barre host->dma_in_progress = false; 594a813f2a2SLudovic Barre dmae->cur = NULL; 595a813f2a2SLudovic Barre dmae->desc_current = NULL; 5967b2a6d51SLudovic Barre host->data->host_cookie = 0; 5977b2a6d51SLudovic Barre 5987b2a6d51SLudovic Barre mmci_dma_unmap(host, host->data); 5997b2a6d51SLudovic Barre } 6007b2a6d51SLudovic Barre 601653a761eSUlf Hansson static void mmci_dma_finalize(struct mmci_host *host, struct mmc_data *data) 602653a761eSUlf Hansson { 603a813f2a2SLudovic Barre struct mmci_dmae_priv *dmae = host->dma_priv; 604c8ebae37SRussell King u32 status; 605c8ebae37SRussell King int i; 606c8ebae37SRussell King 607c3647fdcSLudovic Barre if (!host->use_dma || !dma_inprogress(host)) 608cdea1947SLudovic Barre return; 609cdea1947SLudovic Barre 610c8ebae37SRussell King /* Wait up to 1ms for the DMA to complete */ 611c8ebae37SRussell King for (i = 0; ; i++) { 612c8ebae37SRussell King status = readl(host->base + MMCISTATUS); 613c8ebae37SRussell King if (!(status & MCI_RXDATAAVLBLMASK) || i >= 100) 614c8ebae37SRussell King break; 615c8ebae37SRussell King udelay(10); 616c8ebae37SRussell King } 617c8ebae37SRussell King 618c8ebae37SRussell King /* 619c8ebae37SRussell King * Check to see whether we still have some data left in the FIFO - 620c8ebae37SRussell King * this catches DMA controllers which are unable to monitor the 621c8ebae37SRussell King * DMALBREQ and DMALSREQ signals while allowing us to DMA to non- 622c8ebae37SRussell King * contiguous buffers. On TX, we'll get a FIFO underrun error. 623c8ebae37SRussell King */ 624c8ebae37SRussell King if (status & MCI_RXDATAAVLBLMASK) { 625653a761eSUlf Hansson mmci_dma_data_error(host); 626c8ebae37SRussell King if (!data->error) 627c8ebae37SRussell King data->error = -EIO; 6287b2a6d51SLudovic Barre } else if (!data->host_cookie) { 629653a761eSUlf Hansson mmci_dma_unmap(host, data); 6307b2a6d51SLudovic Barre } 631c8ebae37SRussell King 632c8ebae37SRussell King /* 633c8ebae37SRussell King * Use of DMA with scatter-gather is impossible. 634c8ebae37SRussell King * Give up with DMA and switch back to PIO mode. 635c8ebae37SRussell King */ 636c8ebae37SRussell King if (status & MCI_RXDATAAVLBLMASK) { 637c8ebae37SRussell King dev_err(mmc_dev(host->mmc), "buggy DMA detected. Taking evasive action.\n"); 638c8ebae37SRussell King mmci_dma_release(host); 639c8ebae37SRussell King } 640653a761eSUlf Hansson 641e13934bdSLinus Walleij host->dma_in_progress = false; 642a813f2a2SLudovic Barre dmae->cur = NULL; 643a813f2a2SLudovic Barre dmae->desc_current = NULL; 644c8ebae37SRussell King } 645c8ebae37SRussell King 646653a761eSUlf Hansson /* prepares DMA channel and DMA descriptor, returns non-zero on failure */ 64747983510SLudovic Barre static int _mmci_dmae_prep_data(struct mmci_host *host, struct mmc_data *data, 648653a761eSUlf Hansson struct dma_chan **dma_chan, 649653a761eSUlf Hansson struct dma_async_tx_descriptor **dma_desc) 650c8ebae37SRussell King { 651a813f2a2SLudovic Barre struct mmci_dmae_priv *dmae = host->dma_priv; 652c8ebae37SRussell King struct variant_data *variant = host->variant; 653c8ebae37SRussell King struct dma_slave_config conf = { 654c8ebae37SRussell King .src_addr = host->phybase + MMCIFIFO, 655c8ebae37SRussell King .dst_addr = host->phybase + MMCIFIFO, 656c8ebae37SRussell King .src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES, 657c8ebae37SRussell King .dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES, 658c8ebae37SRussell King .src_maxburst = variant->fifohalfsize >> 2, /* # of words */ 659c8ebae37SRussell King .dst_maxburst = variant->fifohalfsize >> 2, /* # of words */ 660258aea76SViresh Kumar .device_fc = false, 661c8ebae37SRussell King }; 662c8ebae37SRussell King struct dma_chan *chan; 663c8ebae37SRussell King struct dma_device *device; 664c8ebae37SRussell King struct dma_async_tx_descriptor *desc; 665c8ebae37SRussell King int nr_sg; 6669cb15142SSrinivas Kandagatla unsigned long flags = DMA_CTRL_ACK; 667c8ebae37SRussell King 668c8ebae37SRussell King if (data->flags & MMC_DATA_READ) { 66905f5799cSVinod Koul conf.direction = DMA_DEV_TO_MEM; 670a813f2a2SLudovic Barre chan = dmae->rx_channel; 671c8ebae37SRussell King } else { 67205f5799cSVinod Koul conf.direction = DMA_MEM_TO_DEV; 673a813f2a2SLudovic Barre chan = dmae->tx_channel; 674c8ebae37SRussell King } 675c8ebae37SRussell King 676c8ebae37SRussell King /* If there's no DMA channel, fall back to PIO */ 677c8ebae37SRussell King if (!chan) 678c8ebae37SRussell King return -EINVAL; 679c8ebae37SRussell King 680c8ebae37SRussell King /* If less than or equal to the fifo size, don't bother with DMA */ 68158c7ccbfSPer Forlin if (data->blksz * data->blocks <= variant->fifosize) 682c8ebae37SRussell King return -EINVAL; 683c8ebae37SRussell King 684c8ebae37SRussell King device = chan->device; 685feeef096SHeiner Kallweit nr_sg = dma_map_sg(device->dev, data->sg, data->sg_len, 686feeef096SHeiner Kallweit mmc_get_dma_dir(data)); 687c8ebae37SRussell King if (nr_sg == 0) 688c8ebae37SRussell King return -EINVAL; 689c8ebae37SRussell King 6909cb15142SSrinivas Kandagatla if (host->variant->qcom_dml) 6919cb15142SSrinivas Kandagatla flags |= DMA_PREP_INTERRUPT; 6929cb15142SSrinivas Kandagatla 693c8ebae37SRussell King dmaengine_slave_config(chan, &conf); 69416052827SAlexandre Bounine desc = dmaengine_prep_slave_sg(chan, data->sg, nr_sg, 6959cb15142SSrinivas Kandagatla conf.direction, flags); 696c8ebae37SRussell King if (!desc) 697c8ebae37SRussell King goto unmap_exit; 698c8ebae37SRussell King 699653a761eSUlf Hansson *dma_chan = chan; 700653a761eSUlf Hansson *dma_desc = desc; 701c8ebae37SRussell King 70258c7ccbfSPer Forlin return 0; 70358c7ccbfSPer Forlin 70458c7ccbfSPer Forlin unmap_exit: 705feeef096SHeiner Kallweit dma_unmap_sg(device->dev, data->sg, data->sg_len, 706feeef096SHeiner Kallweit mmc_get_dma_dir(data)); 70758c7ccbfSPer Forlin return -ENOMEM; 70858c7ccbfSPer Forlin } 70958c7ccbfSPer Forlin 71047983510SLudovic Barre int mmci_dmae_prep_data(struct mmci_host *host, 711ad7b8918SLudovic Barre struct mmc_data *data, 712ad7b8918SLudovic Barre bool next) 713653a761eSUlf Hansson { 714a813f2a2SLudovic Barre struct mmci_dmae_priv *dmae = host->dma_priv; 715ad7b8918SLudovic Barre struct mmci_dmae_next *nd = &dmae->next_data; 716a813f2a2SLudovic Barre 71747983510SLudovic Barre if (!host->use_dma) 71847983510SLudovic Barre return -EINVAL; 71947983510SLudovic Barre 720ad7b8918SLudovic Barre if (next) 72147983510SLudovic Barre return _mmci_dmae_prep_data(host, data, &nd->chan, &nd->desc); 722653a761eSUlf Hansson /* Check if next job is already prepared. */ 723a813f2a2SLudovic Barre if (dmae->cur && dmae->desc_current) 724653a761eSUlf Hansson return 0; 725653a761eSUlf Hansson 726653a761eSUlf Hansson /* No job were prepared thus do it now. */ 72747983510SLudovic Barre return _mmci_dmae_prep_data(host, data, &dmae->cur, 728a813f2a2SLudovic Barre &dmae->desc_current); 729653a761eSUlf Hansson } 730653a761eSUlf Hansson 73158c7ccbfSPer Forlin static int mmci_dma_start_data(struct mmci_host *host, unsigned int datactrl) 73258c7ccbfSPer Forlin { 73358c7ccbfSPer Forlin int ret; 734a813f2a2SLudovic Barre struct mmci_dmae_priv *dmae = host->dma_priv; 73558c7ccbfSPer Forlin struct mmc_data *data = host->data; 73658c7ccbfSPer Forlin 737c3647fdcSLudovic Barre if (!host->use_dma) 738c3647fdcSLudovic Barre return -EINVAL; 739c3647fdcSLudovic Barre 74047983510SLudovic Barre ret = mmci_dmae_prep_data(host, host->data, false); 74158c7ccbfSPer Forlin if (ret) 74258c7ccbfSPer Forlin return ret; 74358c7ccbfSPer Forlin 74458c7ccbfSPer Forlin /* Okay, go for it. */ 745c8ebae37SRussell King dev_vdbg(mmc_dev(host->mmc), 746c8ebae37SRussell King "Submit MMCI DMA job, sglen %d blksz %04x blks %04x flags %08x\n", 747c8ebae37SRussell King data->sg_len, data->blksz, data->blocks, data->flags); 748e13934bdSLinus Walleij host->dma_in_progress = true; 749a813f2a2SLudovic Barre dmaengine_submit(dmae->desc_current); 750a813f2a2SLudovic Barre dma_async_issue_pending(dmae->cur); 751c8ebae37SRussell King 7529cb15142SSrinivas Kandagatla if (host->variant->qcom_dml) 7539cb15142SSrinivas Kandagatla dml_start_xfer(host, data); 7549cb15142SSrinivas Kandagatla 755c8ebae37SRussell King datactrl |= MCI_DPSM_DMAENABLE; 756c8ebae37SRussell King 757c8ebae37SRussell King /* Trigger the DMA transfer */ 7589cc639a2SUlf Hansson mmci_write_datactrlreg(host, datactrl); 759c8ebae37SRussell King 760c8ebae37SRussell King /* 761c8ebae37SRussell King * Let the MMCI say when the data is ended and it's time 762c8ebae37SRussell King * to fire next DMA request. When that happens, MMCI will 763c8ebae37SRussell King * call mmci_data_end() 764c8ebae37SRussell King */ 765c8ebae37SRussell King writel(readl(host->base + MMCIMASK0) | MCI_DATAENDMASK, 766c8ebae37SRussell King host->base + MMCIMASK0); 767c8ebae37SRussell King return 0; 768c8ebae37SRussell King } 76958c7ccbfSPer Forlin 77058c7ccbfSPer Forlin static void mmci_get_next_data(struct mmci_host *host, struct mmc_data *data) 77158c7ccbfSPer Forlin { 772a813f2a2SLudovic Barre struct mmci_dmae_priv *dmae = host->dma_priv; 773a813f2a2SLudovic Barre struct mmci_dmae_next *next = &dmae->next_data; 77458c7ccbfSPer Forlin 775c3647fdcSLudovic Barre if (!host->use_dma) 776c3647fdcSLudovic Barre return; 777c3647fdcSLudovic Barre 778a813f2a2SLudovic Barre WARN_ON(data->host_cookie && data->host_cookie != host->next_cookie); 779a813f2a2SLudovic Barre WARN_ON(!data->host_cookie && (next->desc || next->chan)); 78058c7ccbfSPer Forlin 781a813f2a2SLudovic Barre dmae->desc_current = next->desc; 782a813f2a2SLudovic Barre dmae->cur = next->chan; 783a813f2a2SLudovic Barre next->desc = NULL; 784a813f2a2SLudovic Barre next->chan = NULL; 78558c7ccbfSPer Forlin } 78658c7ccbfSPer Forlin 78747983510SLudovic Barre void mmci_dmae_unprep_data(struct mmci_host *host, 78847983510SLudovic Barre struct mmc_data *data, int err) 78947983510SLudovic Barre 79058c7ccbfSPer Forlin { 791a813f2a2SLudovic Barre struct mmci_dmae_priv *dmae = host->dma_priv; 79258c7ccbfSPer Forlin 79347983510SLudovic Barre if (!host->use_dma) 79458c7ccbfSPer Forlin return; 79558c7ccbfSPer Forlin 796653a761eSUlf Hansson mmci_dma_unmap(host, data); 797653a761eSUlf Hansson 798653a761eSUlf Hansson if (err) { 799a813f2a2SLudovic Barre struct mmci_dmae_next *next = &dmae->next_data; 800653a761eSUlf Hansson struct dma_chan *chan; 801653a761eSUlf Hansson if (data->flags & MMC_DATA_READ) 802a813f2a2SLudovic Barre chan = dmae->rx_channel; 803653a761eSUlf Hansson else 804a813f2a2SLudovic Barre chan = dmae->tx_channel; 80558c7ccbfSPer Forlin dmaengine_terminate_all(chan); 806653a761eSUlf Hansson 807a813f2a2SLudovic Barre if (dmae->desc_current == next->desc) 808a813f2a2SLudovic Barre dmae->desc_current = NULL; 809b5c16a60SSrinivas Kandagatla 810a813f2a2SLudovic Barre if (dmae->cur == next->chan) { 811e13934bdSLinus Walleij host->dma_in_progress = false; 812a813f2a2SLudovic Barre dmae->cur = NULL; 813e13934bdSLinus Walleij } 814b5c16a60SSrinivas Kandagatla 815a813f2a2SLudovic Barre next->desc = NULL; 816a813f2a2SLudovic Barre next->chan = NULL; 81758c7ccbfSPer Forlin } 81858c7ccbfSPer Forlin } 81958c7ccbfSPer Forlin 820c3647fdcSLudovic Barre static struct mmci_host_ops mmci_variant_ops = { 82147983510SLudovic Barre .prep_data = mmci_dmae_prep_data, 82247983510SLudovic Barre .unprep_data = mmci_dmae_unprep_data, 823c3647fdcSLudovic Barre .dma_setup = mmci_dmae_setup, 824c3647fdcSLudovic Barre .dma_release = mmci_dmae_release, 825c3647fdcSLudovic Barre }; 826c3647fdcSLudovic Barre 827c3647fdcSLudovic Barre void mmci_variant_init(struct mmci_host *host) 828c3647fdcSLudovic Barre { 829c3647fdcSLudovic Barre host->ops = &mmci_variant_ops; 830c3647fdcSLudovic Barre } 831c8ebae37SRussell King #else 832c8ebae37SRussell King /* Blank functions if the DMA engine is not available */ 83358c7ccbfSPer Forlin static void mmci_get_next_data(struct mmci_host *host, struct mmc_data *data) 83458c7ccbfSPer Forlin { 83558c7ccbfSPer Forlin } 836c8ebae37SRussell King 837653a761eSUlf Hansson static inline void mmci_dma_finalize(struct mmci_host *host, 838653a761eSUlf Hansson struct mmc_data *data) 839653a761eSUlf Hansson { 840653a761eSUlf Hansson } 841653a761eSUlf Hansson 842c8ebae37SRussell King static inline void mmci_dma_data_error(struct mmci_host *host) 843c8ebae37SRussell King { 844c8ebae37SRussell King } 845c8ebae37SRussell King 846c8ebae37SRussell King static inline int mmci_dma_start_data(struct mmci_host *host, unsigned int datactrl) 847c8ebae37SRussell King { 848c8ebae37SRussell King return -ENOSYS; 849c8ebae37SRussell King } 85058c7ccbfSPer Forlin 851c8ebae37SRussell King #endif 852c8ebae37SRussell King 85347983510SLudovic Barre static void mmci_pre_request(struct mmc_host *mmc, struct mmc_request *mrq) 85447983510SLudovic Barre { 85547983510SLudovic Barre struct mmci_host *host = mmc_priv(mmc); 85647983510SLudovic Barre struct mmc_data *data = mrq->data; 85747983510SLudovic Barre 85847983510SLudovic Barre if (!data) 85947983510SLudovic Barre return; 86047983510SLudovic Barre 86147983510SLudovic Barre WARN_ON(data->host_cookie); 86247983510SLudovic Barre 86347983510SLudovic Barre if (mmci_validate_data(host, data)) 86447983510SLudovic Barre return; 86547983510SLudovic Barre 86647983510SLudovic Barre mmci_prep_data(host, data, true); 86747983510SLudovic Barre } 86847983510SLudovic Barre 86947983510SLudovic Barre static void mmci_post_request(struct mmc_host *mmc, struct mmc_request *mrq, 87047983510SLudovic Barre int err) 87147983510SLudovic Barre { 87247983510SLudovic Barre struct mmci_host *host = mmc_priv(mmc); 87347983510SLudovic Barre struct mmc_data *data = mrq->data; 87447983510SLudovic Barre 87547983510SLudovic Barre if (!data || !data->host_cookie) 87647983510SLudovic Barre return; 87747983510SLudovic Barre 87847983510SLudovic Barre mmci_unprep_data(host, data, err); 87947983510SLudovic Barre } 88047983510SLudovic Barre 8811c6a0718SPierre Ossman static void mmci_start_data(struct mmci_host *host, struct mmc_data *data) 8821c6a0718SPierre Ossman { 8838301bb68SRabin Vincent struct variant_data *variant = host->variant; 8841c6a0718SPierre Ossman unsigned int datactrl, timeout, irqmask; 8851c6a0718SPierre Ossman unsigned long long clks; 8861c6a0718SPierre Ossman void __iomem *base; 8871c6a0718SPierre Ossman int blksz_bits; 8881c6a0718SPierre Ossman 88964de0289SLinus Walleij dev_dbg(mmc_dev(host->mmc), "blksz %04x blks %04x flags %08x\n", 8901c6a0718SPierre Ossman data->blksz, data->blocks, data->flags); 8911c6a0718SPierre Ossman 8921c6a0718SPierre Ossman host->data = data; 893528320dbSRabin Vincent host->size = data->blksz * data->blocks; 89451d4375dSRussell King data->bytes_xfered = 0; 8951c6a0718SPierre Ossman 8961c6a0718SPierre Ossman clks = (unsigned long long)data->timeout_ns * host->cclk; 897c4a35769SSrinivas Kandagatla do_div(clks, NSEC_PER_SEC); 8981c6a0718SPierre Ossman 8991c6a0718SPierre Ossman timeout = data->timeout_clks + (unsigned int)clks; 9001c6a0718SPierre Ossman 9011c6a0718SPierre Ossman base = host->base; 9021c6a0718SPierre Ossman writel(timeout, base + MMCIDATATIMER); 9031c6a0718SPierre Ossman writel(host->size, base + MMCIDATALENGTH); 9041c6a0718SPierre Ossman 9051c6a0718SPierre Ossman blksz_bits = ffs(data->blksz) - 1; 9061c6a0718SPierre Ossman BUG_ON(1 << blksz_bits != data->blksz); 9071c6a0718SPierre Ossman 9081784b157SPhilippe Langlais if (variant->blksz_datactrl16) 9091784b157SPhilippe Langlais datactrl = MCI_DPSM_ENABLE | (data->blksz << 16); 910ff783233SSrinivas Kandagatla else if (variant->blksz_datactrl4) 911ff783233SSrinivas Kandagatla datactrl = MCI_DPSM_ENABLE | (data->blksz << 4); 9121784b157SPhilippe Langlais else 9131c6a0718SPierre Ossman datactrl = MCI_DPSM_ENABLE | blksz_bits << 4; 914c8ebae37SRussell King 915c8ebae37SRussell King if (data->flags & MMC_DATA_READ) 9161c6a0718SPierre Ossman datactrl |= MCI_DPSM_DIRECTION; 917c8ebae37SRussell King 918c7354133SSrinivas Kandagatla if (host->mmc->card && mmc_card_sdio(host->mmc->card)) { 91906c1a121SUlf Hansson u32 clk; 920c7354133SSrinivas Kandagatla 9215df014dfSSrinivas Kandagatla datactrl |= variant->datactrl_mask_sdio; 9227258db7eSUlf Hansson 923c8ebae37SRussell King /* 92470ac0935SUlf Hansson * The ST Micro variant for SDIO small write transfers 92570ac0935SUlf Hansson * needs to have clock H/W flow control disabled, 92670ac0935SUlf Hansson * otherwise the transfer will not start. The threshold 92770ac0935SUlf Hansson * depends on the rate of MCLK. 92806c1a121SUlf Hansson */ 929c7354133SSrinivas Kandagatla if (variant->st_sdio && data->flags & MMC_DATA_WRITE && 93070ac0935SUlf Hansson (host->size < 8 || 93170ac0935SUlf Hansson (host->size <= 8 && host->mclk > 50000000))) 93206c1a121SUlf Hansson clk = host->clk_reg & ~variant->clkreg_enable; 93306c1a121SUlf Hansson else 93406c1a121SUlf Hansson clk = host->clk_reg | variant->clkreg_enable; 93506c1a121SUlf Hansson 93606c1a121SUlf Hansson mmci_write_clkreg(host, clk); 93706c1a121SUlf Hansson } 93806c1a121SUlf Hansson 9396dad6c95SSeungwon Jeon if (host->mmc->ios.timing == MMC_TIMING_UHS_DDR50 || 9406dad6c95SSeungwon Jeon host->mmc->ios.timing == MMC_TIMING_MMC_DDR52) 941e17dca2bSSrinivas Kandagatla datactrl |= variant->datactrl_mask_ddrmode; 9426dbb6ee0SUlf Hansson 94306c1a121SUlf Hansson /* 944c8ebae37SRussell King * Attempt to use DMA operation mode, if this 945c8ebae37SRussell King * should fail, fall back to PIO mode 946c8ebae37SRussell King */ 947c8ebae37SRussell King if (!mmci_dma_start_data(host, datactrl)) 948c8ebae37SRussell King return; 949c8ebae37SRussell King 950c8ebae37SRussell King /* IRQ mode, map the SG list for CPU reading/writing */ 951c8ebae37SRussell King mmci_init_sg(host, data); 952c8ebae37SRussell King 953c8ebae37SRussell King if (data->flags & MMC_DATA_READ) { 9541c6a0718SPierre Ossman irqmask = MCI_RXFIFOHALFFULLMASK; 9551c6a0718SPierre Ossman 9561c6a0718SPierre Ossman /* 957c4d877c1SRussell King * If we have less than the fifo 'half-full' threshold to 958c4d877c1SRussell King * transfer, trigger a PIO interrupt as soon as any data 959c4d877c1SRussell King * is available. 9601c6a0718SPierre Ossman */ 961c4d877c1SRussell King if (host->size < variant->fifohalfsize) 9621c6a0718SPierre Ossman irqmask |= MCI_RXDATAAVLBLMASK; 9631c6a0718SPierre Ossman } else { 9641c6a0718SPierre Ossman /* 9651c6a0718SPierre Ossman * We don't actually need to include "FIFO empty" here 9661c6a0718SPierre Ossman * since its implicit in "FIFO half empty". 9671c6a0718SPierre Ossman */ 9681c6a0718SPierre Ossman irqmask = MCI_TXFIFOHALFEMPTYMASK; 9691c6a0718SPierre Ossman } 9701c6a0718SPierre Ossman 9719cc639a2SUlf Hansson mmci_write_datactrlreg(host, datactrl); 9721c6a0718SPierre Ossman writel(readl(base + MMCIMASK0) & ~MCI_DATAENDMASK, base + MMCIMASK0); 9732686b4b4SLinus Walleij mmci_set_mask1(host, irqmask); 9741c6a0718SPierre Ossman } 9751c6a0718SPierre Ossman 9761c6a0718SPierre Ossman static void 9771c6a0718SPierre Ossman mmci_start_command(struct mmci_host *host, struct mmc_command *cmd, u32 c) 9781c6a0718SPierre Ossman { 9791c6a0718SPierre Ossman void __iomem *base = host->base; 9801c6a0718SPierre Ossman 98164de0289SLinus Walleij dev_dbg(mmc_dev(host->mmc), "op %02x arg %08x flags %08x\n", 9821c6a0718SPierre Ossman cmd->opcode, cmd->arg, cmd->flags); 9831c6a0718SPierre Ossman 9841c6a0718SPierre Ossman if (readl(base + MMCICOMMAND) & MCI_CPSM_ENABLE) { 9851c6a0718SPierre Ossman writel(0, base + MMCICOMMAND); 9866adb2a80SSrinivas Kandagatla mmci_reg_delay(host); 9871c6a0718SPierre Ossman } 9881c6a0718SPierre Ossman 9891c6a0718SPierre Ossman c |= cmd->opcode | MCI_CPSM_ENABLE; 9901c6a0718SPierre Ossman if (cmd->flags & MMC_RSP_PRESENT) { 9911c6a0718SPierre Ossman if (cmd->flags & MMC_RSP_136) 9921c6a0718SPierre Ossman c |= MCI_CPSM_LONGRSP; 9931c6a0718SPierre Ossman c |= MCI_CPSM_RESPONSE; 9941c6a0718SPierre Ossman } 9951c6a0718SPierre Ossman if (/*interrupt*/0) 9961c6a0718SPierre Ossman c |= MCI_CPSM_INTERRUPT; 9971c6a0718SPierre Ossman 998ae7b0061SSrinivas Kandagatla if (mmc_cmd_type(cmd) == MMC_CMD_ADTC) 999ae7b0061SSrinivas Kandagatla c |= host->variant->data_cmd_enable; 1000ae7b0061SSrinivas Kandagatla 10011c6a0718SPierre Ossman host->cmd = cmd; 10021c6a0718SPierre Ossman 10031c6a0718SPierre Ossman writel(cmd->arg, base + MMCIARGUMENT); 10041c6a0718SPierre Ossman writel(c, base + MMCICOMMAND); 10051c6a0718SPierre Ossman } 10061c6a0718SPierre Ossman 10071c6a0718SPierre Ossman static void 10081c6a0718SPierre Ossman mmci_data_irq(struct mmci_host *host, struct mmc_data *data, 10091c6a0718SPierre Ossman unsigned int status) 10101c6a0718SPierre Ossman { 10111cb9da50SUlf Hansson /* Make sure we have data to handle */ 10121cb9da50SUlf Hansson if (!data) 10131cb9da50SUlf Hansson return; 10141cb9da50SUlf Hansson 1015f20f8f21SLinus Walleij /* First check for errors */ 10167f7b5503SPatrice Chotard if (status & (MCI_DATACRCFAIL | MCI_DATATIMEOUT | 10177f7b5503SPatrice Chotard host->variant->start_err | 1018b63038d6SUlf Hansson MCI_TXUNDERRUN | MCI_RXOVERRUN)) { 10198cb28155SLinus Walleij u32 remain, success; 1020f20f8f21SLinus Walleij 1021c8ebae37SRussell King /* Terminate the DMA transfer */ 1022c8ebae37SRussell King mmci_dma_data_error(host); 1023c8ebae37SRussell King 1024c8afc9d5SRussell King /* 1025c8afc9d5SRussell King * Calculate how far we are into the transfer. Note that 1026c8afc9d5SRussell King * the data counter gives the number of bytes transferred 1027c8afc9d5SRussell King * on the MMC bus, not on the host side. On reads, this 1028c8afc9d5SRussell King * can be as much as a FIFO-worth of data ahead. This 1029c8afc9d5SRussell King * matters for FIFO overruns only. 1030c8afc9d5SRussell King */ 1031f5a106d9SLinus Walleij remain = readl(host->base + MMCIDATACNT); 10328cb28155SLinus Walleij success = data->blksz * data->blocks - remain; 10338cb28155SLinus Walleij 1034c8afc9d5SRussell King dev_dbg(mmc_dev(host->mmc), "MCI ERROR IRQ, status 0x%08x at 0x%08x\n", 1035c8afc9d5SRussell King status, success); 10368cb28155SLinus Walleij if (status & MCI_DATACRCFAIL) { 10378cb28155SLinus Walleij /* Last block was not successful */ 1038c8afc9d5SRussell King success -= 1; 103917b0429dSPierre Ossman data->error = -EILSEQ; 10408cb28155SLinus Walleij } else if (status & MCI_DATATIMEOUT) { 104117b0429dSPierre Ossman data->error = -ETIMEDOUT; 1042757df746SLinus Walleij } else if (status & MCI_STARTBITERR) { 1043757df746SLinus Walleij data->error = -ECOMM; 1044c8afc9d5SRussell King } else if (status & MCI_TXUNDERRUN) { 104517b0429dSPierre Ossman data->error = -EIO; 1046c8afc9d5SRussell King } else if (status & MCI_RXOVERRUN) { 1047c8afc9d5SRussell King if (success > host->variant->fifosize) 1048c8afc9d5SRussell King success -= host->variant->fifosize; 1049c8afc9d5SRussell King else 1050c8afc9d5SRussell King success = 0; 10518cb28155SLinus Walleij data->error = -EIO; 10524ce1d6cbSRabin Vincent } 105351d4375dSRussell King data->bytes_xfered = round_down(success, data->blksz); 10541c6a0718SPierre Ossman } 1055f20f8f21SLinus Walleij 10568cb28155SLinus Walleij if (status & MCI_DATABLOCKEND) 10578cb28155SLinus Walleij dev_err(mmc_dev(host->mmc), "stray MCI_DATABLOCKEND interrupt\n"); 1058f20f8f21SLinus Walleij 1059ccff9b51SRussell King if (status & MCI_DATAEND || data->error) { 1060653a761eSUlf Hansson mmci_dma_finalize(host, data); 1061cdea1947SLudovic Barre 10621c6a0718SPierre Ossman mmci_stop_data(host); 10631c6a0718SPierre Ossman 10648cb28155SLinus Walleij if (!data->error) 10658cb28155SLinus Walleij /* The error clause is handled above, success! */ 106651d4375dSRussell King data->bytes_xfered = data->blksz * data->blocks; 1067f20f8f21SLinus Walleij 1068024629c6SUlf Hansson if (!data->stop || host->mrq->sbc) { 10691c6a0718SPierre Ossman mmci_request_end(host, data->mrq); 10701c6a0718SPierre Ossman } else { 10711c6a0718SPierre Ossman mmci_start_command(host, data->stop, 0); 10721c6a0718SPierre Ossman } 10731c6a0718SPierre Ossman } 10741c6a0718SPierre Ossman } 10751c6a0718SPierre Ossman 10761c6a0718SPierre Ossman static void 10771c6a0718SPierre Ossman mmci_cmd_irq(struct mmci_host *host, struct mmc_command *cmd, 10781c6a0718SPierre Ossman unsigned int status) 10791c6a0718SPierre Ossman { 10801c6a0718SPierre Ossman void __iomem *base = host->base; 108149adc0caSLinus Walleij bool sbc; 1082ad82bfeaSUlf Hansson 1083ad82bfeaSUlf Hansson if (!cmd) 1084ad82bfeaSUlf Hansson return; 1085ad82bfeaSUlf Hansson 1086ad82bfeaSUlf Hansson sbc = (cmd == host->mrq->sbc); 1087ad82bfeaSUlf Hansson 108849adc0caSLinus Walleij /* 108949adc0caSLinus Walleij * We need to be one of these interrupts to be considered worth 109049adc0caSLinus Walleij * handling. Note that we tag on any latent IRQs postponed 109149adc0caSLinus Walleij * due to waiting for busy status. 109249adc0caSLinus Walleij */ 109349adc0caSLinus Walleij if (!((status|host->busy_status) & 109449adc0caSLinus Walleij (MCI_CMDCRCFAIL|MCI_CMDTIMEOUT|MCI_CMDSENT|MCI_CMDRESPEND))) 1095ad82bfeaSUlf Hansson return; 10968d94b54dSUlf Hansson 109749adc0caSLinus Walleij /* 109849adc0caSLinus Walleij * ST Micro variant: handle busy detection. 109949adc0caSLinus Walleij */ 110049adc0caSLinus Walleij if (host->variant->busy_detect) { 110149adc0caSLinus Walleij bool busy_resp = !!(cmd->flags & MMC_RSP_BUSY); 110249adc0caSLinus Walleij 110349adc0caSLinus Walleij /* We are busy with a command, return */ 110449adc0caSLinus Walleij if (host->busy_status && 110549adc0caSLinus Walleij (status & host->variant->busy_detect_flag)) 11068d94b54dSUlf Hansson return; 11078d94b54dSUlf Hansson 110849adc0caSLinus Walleij /* 110949adc0caSLinus Walleij * We were not busy, but we now got a busy response on 111049adc0caSLinus Walleij * something that was not an error, and we double-check 111149adc0caSLinus Walleij * that the special busy status bit is still set before 111249adc0caSLinus Walleij * proceeding. 111349adc0caSLinus Walleij */ 11148d94b54dSUlf Hansson if (!host->busy_status && busy_resp && 11158d94b54dSUlf Hansson !(status & (MCI_CMDCRCFAIL|MCI_CMDTIMEOUT)) && 111649adc0caSLinus Walleij (readl(base + MMCISTATUS) & host->variant->busy_detect_flag)) { 11175cad24d8SJean-Nicolas Graux 11185cad24d8SJean-Nicolas Graux /* Clear the busy start IRQ */ 11195cad24d8SJean-Nicolas Graux writel(host->variant->busy_detect_mask, 11205cad24d8SJean-Nicolas Graux host->base + MMCICLEAR); 11215cad24d8SJean-Nicolas Graux 11225cad24d8SJean-Nicolas Graux /* Unmask the busy end IRQ */ 112349adc0caSLinus Walleij writel(readl(base + MMCIMASK0) | 112449adc0caSLinus Walleij host->variant->busy_detect_mask, 11258d94b54dSUlf Hansson base + MMCIMASK0); 112649adc0caSLinus Walleij /* 112749adc0caSLinus Walleij * Now cache the last response status code (until 112849adc0caSLinus Walleij * the busy bit goes low), and return. 112949adc0caSLinus Walleij */ 113049adc0caSLinus Walleij host->busy_status = 113149adc0caSLinus Walleij status & (MCI_CMDSENT|MCI_CMDRESPEND); 11328d94b54dSUlf Hansson return; 11338d94b54dSUlf Hansson } 11348d94b54dSUlf Hansson 113549adc0caSLinus Walleij /* 113649adc0caSLinus Walleij * At this point we are not busy with a command, we have 11375cad24d8SJean-Nicolas Graux * not received a new busy request, clear and mask the busy 11385cad24d8SJean-Nicolas Graux * end IRQ and fall through to process the IRQ. 113949adc0caSLinus Walleij */ 11408d94b54dSUlf Hansson if (host->busy_status) { 11415cad24d8SJean-Nicolas Graux 11425cad24d8SJean-Nicolas Graux writel(host->variant->busy_detect_mask, 11435cad24d8SJean-Nicolas Graux host->base + MMCICLEAR); 11445cad24d8SJean-Nicolas Graux 114549adc0caSLinus Walleij writel(readl(base + MMCIMASK0) & 114649adc0caSLinus Walleij ~host->variant->busy_detect_mask, 11478d94b54dSUlf Hansson base + MMCIMASK0); 11488d94b54dSUlf Hansson host->busy_status = 0; 11498d94b54dSUlf Hansson } 115049adc0caSLinus Walleij } 11511c6a0718SPierre Ossman 11521c6a0718SPierre Ossman host->cmd = NULL; 11531c6a0718SPierre Ossman 11541c6a0718SPierre Ossman if (status & MCI_CMDTIMEOUT) { 115517b0429dSPierre Ossman cmd->error = -ETIMEDOUT; 11561c6a0718SPierre Ossman } else if (status & MCI_CMDCRCFAIL && cmd->flags & MMC_RSP_CRC) { 115717b0429dSPierre Ossman cmd->error = -EILSEQ; 11589047b435SRussell King - ARM Linux } else { 11599047b435SRussell King - ARM Linux cmd->resp[0] = readl(base + MMCIRESPONSE0); 11609047b435SRussell King - ARM Linux cmd->resp[1] = readl(base + MMCIRESPONSE1); 11619047b435SRussell King - ARM Linux cmd->resp[2] = readl(base + MMCIRESPONSE2); 11629047b435SRussell King - ARM Linux cmd->resp[3] = readl(base + MMCIRESPONSE3); 11631c6a0718SPierre Ossman } 11641c6a0718SPierre Ossman 1165024629c6SUlf Hansson if ((!sbc && !cmd->data) || cmd->error) { 11663b6e3c73SUlf Hansson if (host->data) { 11673b6e3c73SUlf Hansson /* Terminate the DMA transfer */ 11683b6e3c73SUlf Hansson mmci_dma_data_error(host); 11697b2a6d51SLudovic Barre 11701c6a0718SPierre Ossman mmci_stop_data(host); 11713b6e3c73SUlf Hansson } 1172024629c6SUlf Hansson mmci_request_end(host, host->mrq); 1173024629c6SUlf Hansson } else if (sbc) { 1174024629c6SUlf Hansson mmci_start_command(host, host->mrq->cmd, 0); 11751c6a0718SPierre Ossman } else if (!(cmd->data->flags & MMC_DATA_READ)) { 11761c6a0718SPierre Ossman mmci_start_data(host, cmd->data); 11771c6a0718SPierre Ossman } 11781c6a0718SPierre Ossman } 11791c6a0718SPierre Ossman 11809c34b73dSSrinivas Kandagatla static int mmci_get_rx_fifocnt(struct mmci_host *host, u32 status, int remain) 11819c34b73dSSrinivas Kandagatla { 11829c34b73dSSrinivas Kandagatla return remain - (readl(host->base + MMCIFIFOCNT) << 2); 11839c34b73dSSrinivas Kandagatla } 11849c34b73dSSrinivas Kandagatla 11859c34b73dSSrinivas Kandagatla static int mmci_qcom_get_rx_fifocnt(struct mmci_host *host, u32 status, int r) 11869c34b73dSSrinivas Kandagatla { 11879c34b73dSSrinivas Kandagatla /* 11889c34b73dSSrinivas Kandagatla * on qcom SDCC4 only 8 words are used in each burst so only 8 addresses 11899c34b73dSSrinivas Kandagatla * from the fifo range should be used 11909c34b73dSSrinivas Kandagatla */ 11919c34b73dSSrinivas Kandagatla if (status & MCI_RXFIFOHALFFULL) 11929c34b73dSSrinivas Kandagatla return host->variant->fifohalfsize; 11939c34b73dSSrinivas Kandagatla else if (status & MCI_RXDATAAVLBL) 11949c34b73dSSrinivas Kandagatla return 4; 11959c34b73dSSrinivas Kandagatla 11969c34b73dSSrinivas Kandagatla return 0; 11979c34b73dSSrinivas Kandagatla } 11989c34b73dSSrinivas Kandagatla 11991c6a0718SPierre Ossman static int mmci_pio_read(struct mmci_host *host, char *buffer, unsigned int remain) 12001c6a0718SPierre Ossman { 12011c6a0718SPierre Ossman void __iomem *base = host->base; 12021c6a0718SPierre Ossman char *ptr = buffer; 12039c34b73dSSrinivas Kandagatla u32 status = readl(host->base + MMCISTATUS); 120426eed9a5SLinus Walleij int host_remain = host->size; 12051c6a0718SPierre Ossman 12061c6a0718SPierre Ossman do { 12079c34b73dSSrinivas Kandagatla int count = host->get_rx_fifocnt(host, status, host_remain); 12081c6a0718SPierre Ossman 12091c6a0718SPierre Ossman if (count > remain) 12101c6a0718SPierre Ossman count = remain; 12111c6a0718SPierre Ossman 12121c6a0718SPierre Ossman if (count <= 0) 12131c6a0718SPierre Ossman break; 12141c6a0718SPierre Ossman 1215393e5e24SUlf Hansson /* 1216393e5e24SUlf Hansson * SDIO especially may want to send something that is 1217393e5e24SUlf Hansson * not divisible by 4 (as opposed to card sectors 1218393e5e24SUlf Hansson * etc). Therefore make sure to always read the last bytes 1219393e5e24SUlf Hansson * while only doing full 32-bit reads towards the FIFO. 1220393e5e24SUlf Hansson */ 1221393e5e24SUlf Hansson if (unlikely(count & 0x3)) { 1222393e5e24SUlf Hansson if (count < 4) { 1223393e5e24SUlf Hansson unsigned char buf[4]; 12244b85da08SDavide Ciminaghi ioread32_rep(base + MMCIFIFO, buf, 1); 1225393e5e24SUlf Hansson memcpy(ptr, buf, count); 1226393e5e24SUlf Hansson } else { 12274b85da08SDavide Ciminaghi ioread32_rep(base + MMCIFIFO, ptr, count >> 2); 1228393e5e24SUlf Hansson count &= ~0x3; 1229393e5e24SUlf Hansson } 1230393e5e24SUlf Hansson } else { 12314b85da08SDavide Ciminaghi ioread32_rep(base + MMCIFIFO, ptr, count >> 2); 1232393e5e24SUlf Hansson } 12331c6a0718SPierre Ossman 12341c6a0718SPierre Ossman ptr += count; 12351c6a0718SPierre Ossman remain -= count; 123626eed9a5SLinus Walleij host_remain -= count; 12371c6a0718SPierre Ossman 12381c6a0718SPierre Ossman if (remain == 0) 12391c6a0718SPierre Ossman break; 12401c6a0718SPierre Ossman 12411c6a0718SPierre Ossman status = readl(base + MMCISTATUS); 12421c6a0718SPierre Ossman } while (status & MCI_RXDATAAVLBL); 12431c6a0718SPierre Ossman 12441c6a0718SPierre Ossman return ptr - buffer; 12451c6a0718SPierre Ossman } 12461c6a0718SPierre Ossman 12471c6a0718SPierre Ossman static int mmci_pio_write(struct mmci_host *host, char *buffer, unsigned int remain, u32 status) 12481c6a0718SPierre Ossman { 12498301bb68SRabin Vincent struct variant_data *variant = host->variant; 12501c6a0718SPierre Ossman void __iomem *base = host->base; 12511c6a0718SPierre Ossman char *ptr = buffer; 12521c6a0718SPierre Ossman 12531c6a0718SPierre Ossman do { 12541c6a0718SPierre Ossman unsigned int count, maxcnt; 12551c6a0718SPierre Ossman 12568301bb68SRabin Vincent maxcnt = status & MCI_TXFIFOEMPTY ? 12578301bb68SRabin Vincent variant->fifosize : variant->fifohalfsize; 12581c6a0718SPierre Ossman count = min(remain, maxcnt); 12591c6a0718SPierre Ossman 126034177802SLinus Walleij /* 126134177802SLinus Walleij * SDIO especially may want to send something that is 126234177802SLinus Walleij * not divisible by 4 (as opposed to card sectors 126334177802SLinus Walleij * etc), and the FIFO only accept full 32-bit writes. 126434177802SLinus Walleij * So compensate by adding +3 on the count, a single 126534177802SLinus Walleij * byte become a 32bit write, 7 bytes will be two 126634177802SLinus Walleij * 32bit writes etc. 126734177802SLinus Walleij */ 12684b85da08SDavide Ciminaghi iowrite32_rep(base + MMCIFIFO, ptr, (count + 3) >> 2); 12691c6a0718SPierre Ossman 12701c6a0718SPierre Ossman ptr += count; 12711c6a0718SPierre Ossman remain -= count; 12721c6a0718SPierre Ossman 12731c6a0718SPierre Ossman if (remain == 0) 12741c6a0718SPierre Ossman break; 12751c6a0718SPierre Ossman 12761c6a0718SPierre Ossman status = readl(base + MMCISTATUS); 12771c6a0718SPierre Ossman } while (status & MCI_TXFIFOHALFEMPTY); 12781c6a0718SPierre Ossman 12791c6a0718SPierre Ossman return ptr - buffer; 12801c6a0718SPierre Ossman } 12811c6a0718SPierre Ossman 12821c6a0718SPierre Ossman /* 12831c6a0718SPierre Ossman * PIO data transfer IRQ handler. 12841c6a0718SPierre Ossman */ 12851c6a0718SPierre Ossman static irqreturn_t mmci_pio_irq(int irq, void *dev_id) 12861c6a0718SPierre Ossman { 12871c6a0718SPierre Ossman struct mmci_host *host = dev_id; 12884ce1d6cbSRabin Vincent struct sg_mapping_iter *sg_miter = &host->sg_miter; 12898301bb68SRabin Vincent struct variant_data *variant = host->variant; 12901c6a0718SPierre Ossman void __iomem *base = host->base; 12911c6a0718SPierre Ossman u32 status; 12921c6a0718SPierre Ossman 12931c6a0718SPierre Ossman status = readl(base + MMCISTATUS); 12941c6a0718SPierre Ossman 129564de0289SLinus Walleij dev_dbg(mmc_dev(host->mmc), "irq1 (pio) %08x\n", status); 12961c6a0718SPierre Ossman 12971c6a0718SPierre Ossman do { 12981c6a0718SPierre Ossman unsigned int remain, len; 12991c6a0718SPierre Ossman char *buffer; 13001c6a0718SPierre Ossman 13011c6a0718SPierre Ossman /* 13021c6a0718SPierre Ossman * For write, we only need to test the half-empty flag 13031c6a0718SPierre Ossman * here - if the FIFO is completely empty, then by 13041c6a0718SPierre Ossman * definition it is more than half empty. 13051c6a0718SPierre Ossman * 13061c6a0718SPierre Ossman * For read, check for data available. 13071c6a0718SPierre Ossman */ 13081c6a0718SPierre Ossman if (!(status & (MCI_TXFIFOHALFEMPTY|MCI_RXDATAAVLBL))) 13091c6a0718SPierre Ossman break; 13101c6a0718SPierre Ossman 13114ce1d6cbSRabin Vincent if (!sg_miter_next(sg_miter)) 13124ce1d6cbSRabin Vincent break; 13134ce1d6cbSRabin Vincent 13144ce1d6cbSRabin Vincent buffer = sg_miter->addr; 13154ce1d6cbSRabin Vincent remain = sg_miter->length; 13161c6a0718SPierre Ossman 13171c6a0718SPierre Ossman len = 0; 13181c6a0718SPierre Ossman if (status & MCI_RXACTIVE) 13191c6a0718SPierre Ossman len = mmci_pio_read(host, buffer, remain); 13201c6a0718SPierre Ossman if (status & MCI_TXACTIVE) 13211c6a0718SPierre Ossman len = mmci_pio_write(host, buffer, remain, status); 13221c6a0718SPierre Ossman 13234ce1d6cbSRabin Vincent sg_miter->consumed = len; 13241c6a0718SPierre Ossman 13251c6a0718SPierre Ossman host->size -= len; 13261c6a0718SPierre Ossman remain -= len; 13271c6a0718SPierre Ossman 13281c6a0718SPierre Ossman if (remain) 13291c6a0718SPierre Ossman break; 13301c6a0718SPierre Ossman 13311c6a0718SPierre Ossman status = readl(base + MMCISTATUS); 13321c6a0718SPierre Ossman } while (1); 13331c6a0718SPierre Ossman 13344ce1d6cbSRabin Vincent sg_miter_stop(sg_miter); 13354ce1d6cbSRabin Vincent 13361c6a0718SPierre Ossman /* 1337c4d877c1SRussell King * If we have less than the fifo 'half-full' threshold to transfer, 1338c4d877c1SRussell King * trigger a PIO interrupt as soon as any data is available. 13391c6a0718SPierre Ossman */ 1340c4d877c1SRussell King if (status & MCI_RXACTIVE && host->size < variant->fifohalfsize) 13412686b4b4SLinus Walleij mmci_set_mask1(host, MCI_RXDATAAVLBLMASK); 13421c6a0718SPierre Ossman 13431c6a0718SPierre Ossman /* 13441c6a0718SPierre Ossman * If we run out of data, disable the data IRQs; this 13451c6a0718SPierre Ossman * prevents a race where the FIFO becomes empty before 13461c6a0718SPierre Ossman * the chip itself has disabled the data path, and 13471c6a0718SPierre Ossman * stops us racing with our data end IRQ. 13481c6a0718SPierre Ossman */ 13491c6a0718SPierre Ossman if (host->size == 0) { 13502686b4b4SLinus Walleij mmci_set_mask1(host, 0); 13511c6a0718SPierre Ossman writel(readl(base + MMCIMASK0) | MCI_DATAENDMASK, base + MMCIMASK0); 13521c6a0718SPierre Ossman } 13531c6a0718SPierre Ossman 13541c6a0718SPierre Ossman return IRQ_HANDLED; 13551c6a0718SPierre Ossman } 13561c6a0718SPierre Ossman 13571c6a0718SPierre Ossman /* 13581c6a0718SPierre Ossman * Handle completion of command and data transfers. 13591c6a0718SPierre Ossman */ 13601c6a0718SPierre Ossman static irqreturn_t mmci_irq(int irq, void *dev_id) 13611c6a0718SPierre Ossman { 13621c6a0718SPierre Ossman struct mmci_host *host = dev_id; 13631c6a0718SPierre Ossman u32 status; 13641c6a0718SPierre Ossman int ret = 0; 13651c6a0718SPierre Ossman 13661c6a0718SPierre Ossman spin_lock(&host->lock); 13671c6a0718SPierre Ossman 13681c6a0718SPierre Ossman do { 13691c6a0718SPierre Ossman status = readl(host->base + MMCISTATUS); 13702686b4b4SLinus Walleij 13712686b4b4SLinus Walleij if (host->singleirq) { 13726ea9cdf3SPatrice Chotard if (status & host->mask1_reg) 13732686b4b4SLinus Walleij mmci_pio_irq(irq, dev_id); 13742686b4b4SLinus Walleij 13752686b4b4SLinus Walleij status &= ~MCI_IRQ1MASK; 13762686b4b4SLinus Walleij } 13772686b4b4SLinus Walleij 13788d94b54dSUlf Hansson /* 13795cad24d8SJean-Nicolas Graux * We intentionally clear the MCI_ST_CARDBUSY IRQ (if it's 13805cad24d8SJean-Nicolas Graux * enabled) in mmci_cmd_irq() function where ST Micro busy 13815cad24d8SJean-Nicolas Graux * detection variant is handled. Considering the HW seems to be 13825cad24d8SJean-Nicolas Graux * triggering the IRQ on both edges while monitoring DAT0 for 13835cad24d8SJean-Nicolas Graux * busy completion and that same status bit is used to monitor 13845cad24d8SJean-Nicolas Graux * start and end of busy detection, special care must be taken 13855cad24d8SJean-Nicolas Graux * to make sure that both start and end interrupts are always 13865cad24d8SJean-Nicolas Graux * cleared one after the other. 13878d94b54dSUlf Hansson */ 13881c6a0718SPierre Ossman status &= readl(host->base + MMCIMASK0); 13895cad24d8SJean-Nicolas Graux if (host->variant->busy_detect) 13905cad24d8SJean-Nicolas Graux writel(status & ~host->variant->busy_detect_mask, 13915cad24d8SJean-Nicolas Graux host->base + MMCICLEAR); 13925cad24d8SJean-Nicolas Graux else 13931c6a0718SPierre Ossman writel(status, host->base + MMCICLEAR); 13941c6a0718SPierre Ossman 139564de0289SLinus Walleij dev_dbg(mmc_dev(host->mmc), "irq0 (data+cmd) %08x\n", status); 13961c6a0718SPierre Ossman 13977878289bSUlf Hansson if (host->variant->reversed_irq_handling) { 13987878289bSUlf Hansson mmci_data_irq(host, host->data, status); 13997878289bSUlf Hansson mmci_cmd_irq(host, host->cmd, status); 14007878289bSUlf Hansson } else { 1401ad82bfeaSUlf Hansson mmci_cmd_irq(host, host->cmd, status); 14021cb9da50SUlf Hansson mmci_data_irq(host, host->data, status); 14037878289bSUlf Hansson } 14041c6a0718SPierre Ossman 140549adc0caSLinus Walleij /* 140649adc0caSLinus Walleij * Don't poll for busy completion in irq context. 140749adc0caSLinus Walleij */ 140849adc0caSLinus Walleij if (host->variant->busy_detect && host->busy_status) 140949adc0caSLinus Walleij status &= ~host->variant->busy_detect_flag; 14108d94b54dSUlf Hansson 14111c6a0718SPierre Ossman ret = 1; 14121c6a0718SPierre Ossman } while (status); 14131c6a0718SPierre Ossman 14141c6a0718SPierre Ossman spin_unlock(&host->lock); 14151c6a0718SPierre Ossman 14161c6a0718SPierre Ossman return IRQ_RETVAL(ret); 14171c6a0718SPierre Ossman } 14181c6a0718SPierre Ossman 14191c6a0718SPierre Ossman static void mmci_request(struct mmc_host *mmc, struct mmc_request *mrq) 14201c6a0718SPierre Ossman { 14211c6a0718SPierre Ossman struct mmci_host *host = mmc_priv(mmc); 14229e943021SLinus Walleij unsigned long flags; 14231c6a0718SPierre Ossman 14241c6a0718SPierre Ossman WARN_ON(host->mrq != NULL); 14251c6a0718SPierre Ossman 1426653a761eSUlf Hansson mrq->cmd->error = mmci_validate_data(host, mrq->data); 1427653a761eSUlf Hansson if (mrq->cmd->error) { 1428255d01afSPierre Ossman mmc_request_done(mmc, mrq); 1429255d01afSPierre Ossman return; 1430255d01afSPierre Ossman } 1431255d01afSPierre Ossman 14329e943021SLinus Walleij spin_lock_irqsave(&host->lock, flags); 14331c6a0718SPierre Ossman 14341c6a0718SPierre Ossman host->mrq = mrq; 14351c6a0718SPierre Ossman 143658c7ccbfSPer Forlin if (mrq->data) 143758c7ccbfSPer Forlin mmci_get_next_data(host, mrq->data); 143858c7ccbfSPer Forlin 14391c6a0718SPierre Ossman if (mrq->data && mrq->data->flags & MMC_DATA_READ) 14401c6a0718SPierre Ossman mmci_start_data(host, mrq->data); 14411c6a0718SPierre Ossman 1442024629c6SUlf Hansson if (mrq->sbc) 1443024629c6SUlf Hansson mmci_start_command(host, mrq->sbc, 0); 1444024629c6SUlf Hansson else 14451c6a0718SPierre Ossman mmci_start_command(host, mrq->cmd, 0); 14461c6a0718SPierre Ossman 14479e943021SLinus Walleij spin_unlock_irqrestore(&host->lock, flags); 14481c6a0718SPierre Ossman } 14491c6a0718SPierre Ossman 14501c6a0718SPierre Ossman static void mmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) 14511c6a0718SPierre Ossman { 14521c6a0718SPierre Ossman struct mmci_host *host = mmc_priv(mmc); 14537d72a1d4SUlf Hansson struct variant_data *variant = host->variant; 1454a6a6464aSLinus Walleij u32 pwr = 0; 1455a6a6464aSLinus Walleij unsigned long flags; 1456db90f91fSLee Jones int ret; 14571c6a0718SPierre Ossman 1458bc521818SUlf Hansson if (host->plat->ios_handler && 1459bc521818SUlf Hansson host->plat->ios_handler(mmc_dev(mmc), ios)) 1460bc521818SUlf Hansson dev_err(mmc_dev(mmc), "platform ios_handler failed\n"); 1461bc521818SUlf Hansson 14621c6a0718SPierre Ossman switch (ios->power_mode) { 14631c6a0718SPierre Ossman case MMC_POWER_OFF: 1464599c1d5cSUlf Hansson if (!IS_ERR(mmc->supply.vmmc)) 1465599c1d5cSUlf Hansson mmc_regulator_set_ocr(mmc, mmc->supply.vmmc, 0); 1466237fb5e6SLee Jones 14677c0136efSUlf Hansson if (!IS_ERR(mmc->supply.vqmmc) && host->vqmmc_enabled) { 1468237fb5e6SLee Jones regulator_disable(mmc->supply.vqmmc); 14697c0136efSUlf Hansson host->vqmmc_enabled = false; 14707c0136efSUlf Hansson } 1471237fb5e6SLee Jones 14721c6a0718SPierre Ossman break; 14731c6a0718SPierre Ossman case MMC_POWER_UP: 1474599c1d5cSUlf Hansson if (!IS_ERR(mmc->supply.vmmc)) 1475599c1d5cSUlf Hansson mmc_regulator_set_ocr(mmc, mmc->supply.vmmc, ios->vdd); 1476599c1d5cSUlf Hansson 14777d72a1d4SUlf Hansson /* 14787d72a1d4SUlf Hansson * The ST Micro variant doesn't have the PL180s MCI_PWR_UP 14797d72a1d4SUlf Hansson * and instead uses MCI_PWR_ON so apply whatever value is 14807d72a1d4SUlf Hansson * configured in the variant data. 14817d72a1d4SUlf Hansson */ 14827d72a1d4SUlf Hansson pwr |= variant->pwrreg_powerup; 14837d72a1d4SUlf Hansson 14841c6a0718SPierre Ossman break; 14851c6a0718SPierre Ossman case MMC_POWER_ON: 14867c0136efSUlf Hansson if (!IS_ERR(mmc->supply.vqmmc) && !host->vqmmc_enabled) { 1487db90f91fSLee Jones ret = regulator_enable(mmc->supply.vqmmc); 1488db90f91fSLee Jones if (ret < 0) 1489db90f91fSLee Jones dev_err(mmc_dev(mmc), 1490db90f91fSLee Jones "failed to enable vqmmc regulator\n"); 14917c0136efSUlf Hansson else 14927c0136efSUlf Hansson host->vqmmc_enabled = true; 1493db90f91fSLee Jones } 1494237fb5e6SLee Jones 14951c6a0718SPierre Ossman pwr |= MCI_PWR_ON; 14961c6a0718SPierre Ossman break; 14971c6a0718SPierre Ossman } 14981c6a0718SPierre Ossman 14994d1a3a0dSUlf Hansson if (variant->signal_direction && ios->power_mode != MMC_POWER_OFF) { 15004d1a3a0dSUlf Hansson /* 15014d1a3a0dSUlf Hansson * The ST Micro variant has some additional bits 15024d1a3a0dSUlf Hansson * indicating signal direction for the signals in 15034d1a3a0dSUlf Hansson * the SD/MMC bus and feedback-clock usage. 15044d1a3a0dSUlf Hansson */ 15054593df29SUlf Hansson pwr |= host->pwr_reg_add; 15064d1a3a0dSUlf Hansson 15074d1a3a0dSUlf Hansson if (ios->bus_width == MMC_BUS_WIDTH_4) 15084d1a3a0dSUlf Hansson pwr &= ~MCI_ST_DATA74DIREN; 15094d1a3a0dSUlf Hansson else if (ios->bus_width == MMC_BUS_WIDTH_1) 15104d1a3a0dSUlf Hansson pwr &= (~MCI_ST_DATA74DIREN & 15114d1a3a0dSUlf Hansson ~MCI_ST_DATA31DIREN & 15124d1a3a0dSUlf Hansson ~MCI_ST_DATA2DIREN); 15134d1a3a0dSUlf Hansson } 15144d1a3a0dSUlf Hansson 1515f9bb304cSPatrice Chotard if (variant->opendrain) { 1516f9bb304cSPatrice Chotard if (ios->bus_mode == MMC_BUSMODE_OPENDRAIN) 151711dfb970SPatrice Chotard pwr |= variant->opendrain; 1518f9bb304cSPatrice Chotard } else { 1519f9bb304cSPatrice Chotard /* 1520f9bb304cSPatrice Chotard * If the variant cannot configure the pads by its own, then we 1521f9bb304cSPatrice Chotard * expect the pinctrl to be able to do that for us 1522f9bb304cSPatrice Chotard */ 1523f9bb304cSPatrice Chotard if (ios->bus_mode == MMC_BUSMODE_OPENDRAIN) 1524f9bb304cSPatrice Chotard pinctrl_select_state(host->pinctrl, host->pins_opendrain); 1525f9bb304cSPatrice Chotard else 1526f9bb304cSPatrice Chotard pinctrl_select_state(host->pinctrl, host->pins_default); 1527f9bb304cSPatrice Chotard } 15281c6a0718SPierre Ossman 1529f4670daeSUlf Hansson /* 1530f4670daeSUlf Hansson * If clock = 0 and the variant requires the MMCIPOWER to be used for 1531f4670daeSUlf Hansson * gating the clock, the MCI_PWR_ON bit is cleared. 1532f4670daeSUlf Hansson */ 1533f4670daeSUlf Hansson if (!ios->clock && variant->pwrreg_clkgate) 1534f4670daeSUlf Hansson pwr &= ~MCI_PWR_ON; 1535f4670daeSUlf Hansson 15363f4e6f7bSSrinivas Kandagatla if (host->variant->explicit_mclk_control && 15373f4e6f7bSSrinivas Kandagatla ios->clock != host->clock_cache) { 15383f4e6f7bSSrinivas Kandagatla ret = clk_set_rate(host->clk, ios->clock); 15393f4e6f7bSSrinivas Kandagatla if (ret < 0) 15403f4e6f7bSSrinivas Kandagatla dev_err(mmc_dev(host->mmc), 15413f4e6f7bSSrinivas Kandagatla "Error setting clock rate (%d)\n", ret); 15423f4e6f7bSSrinivas Kandagatla else 15433f4e6f7bSSrinivas Kandagatla host->mclk = clk_get_rate(host->clk); 15443f4e6f7bSSrinivas Kandagatla } 15453f4e6f7bSSrinivas Kandagatla host->clock_cache = ios->clock; 15463f4e6f7bSSrinivas Kandagatla 1547a6a6464aSLinus Walleij spin_lock_irqsave(&host->lock, flags); 1548a6a6464aSLinus Walleij 1549a6a6464aSLinus Walleij mmci_set_clkreg(host, ios->clock); 15507437cfa5SUlf Hansson mmci_write_pwrreg(host, pwr); 1551f829c042SUlf Hansson mmci_reg_delay(host); 1552a6a6464aSLinus Walleij 1553a6a6464aSLinus Walleij spin_unlock_irqrestore(&host->lock, flags); 15541c6a0718SPierre Ossman } 15551c6a0718SPierre Ossman 155689001446SRussell King static int mmci_get_cd(struct mmc_host *mmc) 155789001446SRussell King { 155889001446SRussell King struct mmci_host *host = mmc_priv(mmc); 155929719445SRabin Vincent struct mmci_platform_data *plat = host->plat; 1560d2762090SUlf Hansson unsigned int status = mmc_gpio_get_cd(mmc); 156189001446SRussell King 1562d2762090SUlf Hansson if (status == -ENOSYS) { 15634b8caec0SRabin Vincent if (!plat->status) 15644b8caec0SRabin Vincent return 1; /* Assume always present */ 15654b8caec0SRabin Vincent 156629719445SRabin Vincent status = plat->status(mmc_dev(host->mmc)); 1567d2762090SUlf Hansson } 156874bc8093SRussell King return status; 156989001446SRussell King } 157089001446SRussell King 15710f3ed7f7SUlf Hansson static int mmci_sig_volt_switch(struct mmc_host *mmc, struct mmc_ios *ios) 15720f3ed7f7SUlf Hansson { 15730f3ed7f7SUlf Hansson int ret = 0; 15740f3ed7f7SUlf Hansson 15750f3ed7f7SUlf Hansson if (!IS_ERR(mmc->supply.vqmmc)) { 15760f3ed7f7SUlf Hansson 15770f3ed7f7SUlf Hansson switch (ios->signal_voltage) { 15780f3ed7f7SUlf Hansson case MMC_SIGNAL_VOLTAGE_330: 15790f3ed7f7SUlf Hansson ret = regulator_set_voltage(mmc->supply.vqmmc, 15800f3ed7f7SUlf Hansson 2700000, 3600000); 15810f3ed7f7SUlf Hansson break; 15820f3ed7f7SUlf Hansson case MMC_SIGNAL_VOLTAGE_180: 15830f3ed7f7SUlf Hansson ret = regulator_set_voltage(mmc->supply.vqmmc, 15840f3ed7f7SUlf Hansson 1700000, 1950000); 15850f3ed7f7SUlf Hansson break; 15860f3ed7f7SUlf Hansson case MMC_SIGNAL_VOLTAGE_120: 15870f3ed7f7SUlf Hansson ret = regulator_set_voltage(mmc->supply.vqmmc, 15880f3ed7f7SUlf Hansson 1100000, 1300000); 15890f3ed7f7SUlf Hansson break; 15900f3ed7f7SUlf Hansson } 15910f3ed7f7SUlf Hansson 15920f3ed7f7SUlf Hansson if (ret) 15930f3ed7f7SUlf Hansson dev_warn(mmc_dev(mmc), "Voltage switch failed\n"); 15940f3ed7f7SUlf Hansson } 15950f3ed7f7SUlf Hansson 15960f3ed7f7SUlf Hansson return ret; 15970f3ed7f7SUlf Hansson } 15980f3ed7f7SUlf Hansson 159901259620SUlf Hansson static struct mmc_host_ops mmci_ops = { 16001c6a0718SPierre Ossman .request = mmci_request, 160158c7ccbfSPer Forlin .pre_req = mmci_pre_request, 160258c7ccbfSPer Forlin .post_req = mmci_post_request, 16031c6a0718SPierre Ossman .set_ios = mmci_set_ios, 1604d2762090SUlf Hansson .get_ro = mmc_gpio_get_ro, 160589001446SRussell King .get_cd = mmci_get_cd, 16060f3ed7f7SUlf Hansson .start_signal_voltage_switch = mmci_sig_volt_switch, 16071c6a0718SPierre Ossman }; 16081c6a0718SPierre Ossman 160978f87df2SUlf Hansson static int mmci_of_parse(struct device_node *np, struct mmc_host *mmc) 161078f87df2SUlf Hansson { 16114593df29SUlf Hansson struct mmci_host *host = mmc_priv(mmc); 161278f87df2SUlf Hansson int ret = mmc_of_parse(mmc); 1613000bc9d5SLee Jones 161478f87df2SUlf Hansson if (ret) 161578f87df2SUlf Hansson return ret; 1616000bc9d5SLee Jones 16174593df29SUlf Hansson if (of_get_property(np, "st,sig-dir-dat0", NULL)) 16184593df29SUlf Hansson host->pwr_reg_add |= MCI_ST_DATA0DIREN; 16194593df29SUlf Hansson if (of_get_property(np, "st,sig-dir-dat2", NULL)) 16204593df29SUlf Hansson host->pwr_reg_add |= MCI_ST_DATA2DIREN; 16214593df29SUlf Hansson if (of_get_property(np, "st,sig-dir-dat31", NULL)) 16224593df29SUlf Hansson host->pwr_reg_add |= MCI_ST_DATA31DIREN; 16234593df29SUlf Hansson if (of_get_property(np, "st,sig-dir-dat74", NULL)) 16244593df29SUlf Hansson host->pwr_reg_add |= MCI_ST_DATA74DIREN; 16254593df29SUlf Hansson if (of_get_property(np, "st,sig-dir-cmd", NULL)) 16264593df29SUlf Hansson host->pwr_reg_add |= MCI_ST_CMDDIREN; 16274593df29SUlf Hansson if (of_get_property(np, "st,sig-pin-fbclk", NULL)) 16284593df29SUlf Hansson host->pwr_reg_add |= MCI_ST_FBCLKEN; 16294593df29SUlf Hansson 1630000bc9d5SLee Jones if (of_get_property(np, "mmc-cap-mmc-highspeed", NULL)) 163178f87df2SUlf Hansson mmc->caps |= MMC_CAP_MMC_HIGHSPEED; 1632000bc9d5SLee Jones if (of_get_property(np, "mmc-cap-sd-highspeed", NULL)) 163378f87df2SUlf Hansson mmc->caps |= MMC_CAP_SD_HIGHSPEED; 1634000bc9d5SLee Jones 163578f87df2SUlf Hansson return 0; 1636000bc9d5SLee Jones } 1637000bc9d5SLee Jones 1638c3be1efdSBill Pemberton static int mmci_probe(struct amba_device *dev, 1639aa25afadSRussell King const struct amba_id *id) 16401c6a0718SPierre Ossman { 16416ef297f8SLinus Walleij struct mmci_platform_data *plat = dev->dev.platform_data; 1642000bc9d5SLee Jones struct device_node *np = dev->dev.of_node; 16434956e109SRabin Vincent struct variant_data *variant = id->data; 16441c6a0718SPierre Ossman struct mmci_host *host; 16451c6a0718SPierre Ossman struct mmc_host *mmc; 16461c6a0718SPierre Ossman int ret; 16471c6a0718SPierre Ossman 1648000bc9d5SLee Jones /* Must have platform data or Device Tree. */ 1649000bc9d5SLee Jones if (!plat && !np) { 1650000bc9d5SLee Jones dev_err(&dev->dev, "No plat data or DT found\n"); 1651000bc9d5SLee Jones return -EINVAL; 16521c6a0718SPierre Ossman } 16531c6a0718SPierre Ossman 1654b9b52918SLee Jones if (!plat) { 1655b9b52918SLee Jones plat = devm_kzalloc(&dev->dev, sizeof(*plat), GFP_KERNEL); 1656b9b52918SLee Jones if (!plat) 1657b9b52918SLee Jones return -ENOMEM; 1658b9b52918SLee Jones } 1659b9b52918SLee Jones 16601c6a0718SPierre Ossman mmc = mmc_alloc_host(sizeof(struct mmci_host), &dev->dev); 1661ef289982SUlf Hansson if (!mmc) 1662ef289982SUlf Hansson return -ENOMEM; 16631c6a0718SPierre Ossman 166478f87df2SUlf Hansson ret = mmci_of_parse(np, mmc); 166578f87df2SUlf Hansson if (ret) 166678f87df2SUlf Hansson goto host_free; 166778f87df2SUlf Hansson 16681c6a0718SPierre Ossman host = mmc_priv(mmc); 16694ea580f1SRabin Vincent host->mmc = mmc; 1670012b7d33SRussell King 1671f9bb304cSPatrice Chotard /* 1672f9bb304cSPatrice Chotard * Some variant (STM32) doesn't have opendrain bit, nevertheless 1673f9bb304cSPatrice Chotard * pins can be set accordingly using pinctrl 1674f9bb304cSPatrice Chotard */ 1675f9bb304cSPatrice Chotard if (!variant->opendrain) { 1676f9bb304cSPatrice Chotard host->pinctrl = devm_pinctrl_get(&dev->dev); 1677f9bb304cSPatrice Chotard if (IS_ERR(host->pinctrl)) { 1678f9bb304cSPatrice Chotard dev_err(&dev->dev, "failed to get pinctrl"); 1679310eb252SWei Yongjun ret = PTR_ERR(host->pinctrl); 1680f9bb304cSPatrice Chotard goto host_free; 1681f9bb304cSPatrice Chotard } 1682f9bb304cSPatrice Chotard 1683f9bb304cSPatrice Chotard host->pins_default = pinctrl_lookup_state(host->pinctrl, 1684f9bb304cSPatrice Chotard PINCTRL_STATE_DEFAULT); 1685f9bb304cSPatrice Chotard if (IS_ERR(host->pins_default)) { 1686f9bb304cSPatrice Chotard dev_err(mmc_dev(mmc), "Can't select default pins\n"); 1687310eb252SWei Yongjun ret = PTR_ERR(host->pins_default); 1688f9bb304cSPatrice Chotard goto host_free; 1689f9bb304cSPatrice Chotard } 1690f9bb304cSPatrice Chotard 1691f9bb304cSPatrice Chotard host->pins_opendrain = pinctrl_lookup_state(host->pinctrl, 1692f9bb304cSPatrice Chotard MMCI_PINCTRL_STATE_OPENDRAIN); 1693f9bb304cSPatrice Chotard if (IS_ERR(host->pins_opendrain)) { 1694f9bb304cSPatrice Chotard dev_err(mmc_dev(mmc), "Can't select opendrain pins\n"); 1695310eb252SWei Yongjun ret = PTR_ERR(host->pins_opendrain); 1696f9bb304cSPatrice Chotard goto host_free; 1697f9bb304cSPatrice Chotard } 1698f9bb304cSPatrice Chotard } 1699f9bb304cSPatrice Chotard 1700012b7d33SRussell King host->hw_designer = amba_manf(dev); 1701012b7d33SRussell King host->hw_revision = amba_rev(dev); 170264de0289SLinus Walleij dev_dbg(mmc_dev(mmc), "designer ID = 0x%02x\n", host->hw_designer); 170364de0289SLinus Walleij dev_dbg(mmc_dev(mmc), "revision = 0x%01x\n", host->hw_revision); 1704012b7d33SRussell King 1705665ba56fSUlf Hansson host->clk = devm_clk_get(&dev->dev, NULL); 17061c6a0718SPierre Ossman if (IS_ERR(host->clk)) { 17071c6a0718SPierre Ossman ret = PTR_ERR(host->clk); 17081c6a0718SPierre Ossman goto host_free; 17091c6a0718SPierre Ossman } 17101c6a0718SPierre Ossman 1711ac940938SJulia Lawall ret = clk_prepare_enable(host->clk); 17121c6a0718SPierre Ossman if (ret) 1713665ba56fSUlf Hansson goto host_free; 17141c6a0718SPierre Ossman 17159c34b73dSSrinivas Kandagatla if (variant->qcom_fifo) 17169c34b73dSSrinivas Kandagatla host->get_rx_fifocnt = mmci_qcom_get_rx_fifocnt; 17179c34b73dSSrinivas Kandagatla else 17189c34b73dSSrinivas Kandagatla host->get_rx_fifocnt = mmci_get_rx_fifocnt; 17199c34b73dSSrinivas Kandagatla 17201c6a0718SPierre Ossman host->plat = plat; 17214956e109SRabin Vincent host->variant = variant; 17221c6a0718SPierre Ossman host->mclk = clk_get_rate(host->clk); 1723c8df9a53SLinus Walleij /* 1724c8df9a53SLinus Walleij * According to the spec, mclk is max 100 MHz, 1725c8df9a53SLinus Walleij * so we try to adjust the clock down to this, 1726c8df9a53SLinus Walleij * (if possible). 1727c8df9a53SLinus Walleij */ 1728dc6500bfSSrinivas Kandagatla if (host->mclk > variant->f_max) { 1729dc6500bfSSrinivas Kandagatla ret = clk_set_rate(host->clk, variant->f_max); 1730c8df9a53SLinus Walleij if (ret < 0) 1731c8df9a53SLinus Walleij goto clk_disable; 1732c8df9a53SLinus Walleij host->mclk = clk_get_rate(host->clk); 173364de0289SLinus Walleij dev_dbg(mmc_dev(mmc), "eventual mclk rate: %u Hz\n", 173464de0289SLinus Walleij host->mclk); 1735c8df9a53SLinus Walleij } 1736ef289982SUlf Hansson 1737c8ebae37SRussell King host->phybase = dev->res.start; 1738ef289982SUlf Hansson host->base = devm_ioremap_resource(&dev->dev, &dev->res); 1739ef289982SUlf Hansson if (IS_ERR(host->base)) { 1740ef289982SUlf Hansson ret = PTR_ERR(host->base); 17411c6a0718SPierre Ossman goto clk_disable; 17421c6a0718SPierre Ossman } 17431c6a0718SPierre Ossman 1744ed9067fdSUlf Hansson if (variant->init) 1745ed9067fdSUlf Hansson variant->init(host); 1746ed9067fdSUlf Hansson 17477f294e49SLinus Walleij /* 17487f294e49SLinus Walleij * The ARM and ST versions of the block have slightly different 17497f294e49SLinus Walleij * clock divider equations which means that the minimum divider 17507f294e49SLinus Walleij * differs too. 17513f4e6f7bSSrinivas Kandagatla * on Qualcomm like controllers get the nearest minimum clock to 100Khz 17527f294e49SLinus Walleij */ 17537f294e49SLinus Walleij if (variant->st_clkdiv) 17547f294e49SLinus Walleij mmc->f_min = DIV_ROUND_UP(host->mclk, 257); 17553f4e6f7bSSrinivas Kandagatla else if (variant->explicit_mclk_control) 17563f4e6f7bSSrinivas Kandagatla mmc->f_min = clk_round_rate(host->clk, 100000); 17577f294e49SLinus Walleij else 17587f294e49SLinus Walleij mmc->f_min = DIV_ROUND_UP(host->mclk, 512); 1759808d97ccSLinus Walleij /* 176078f87df2SUlf Hansson * If no maximum operating frequency is supplied, fall back to use 176178f87df2SUlf Hansson * the module parameter, which has a (low) default value in case it 176278f87df2SUlf Hansson * is not specified. Either value must not exceed the clock rate into 17635080a08dSUlf Hansson * the block, of course. 1764808d97ccSLinus Walleij */ 176578f87df2SUlf Hansson if (mmc->f_max) 17663f4e6f7bSSrinivas Kandagatla mmc->f_max = variant->explicit_mclk_control ? 17673f4e6f7bSSrinivas Kandagatla min(variant->f_max, mmc->f_max) : 17683f4e6f7bSSrinivas Kandagatla min(host->mclk, mmc->f_max); 1769808d97ccSLinus Walleij else 17703f4e6f7bSSrinivas Kandagatla mmc->f_max = variant->explicit_mclk_control ? 17713f4e6f7bSSrinivas Kandagatla fmax : min(host->mclk, fmax); 17723f4e6f7bSSrinivas Kandagatla 17733f4e6f7bSSrinivas Kandagatla 177464de0289SLinus Walleij dev_dbg(mmc_dev(mmc), "clocking block at %u Hz\n", mmc->f_max); 177564de0289SLinus Walleij 1776599c1d5cSUlf Hansson /* Get regulators and the supported OCR mask */ 17779369c97cSBjorn Andersson ret = mmc_regulator_get_supply(mmc); 177851006952SWolfram Sang if (ret) 17799369c97cSBjorn Andersson goto clk_disable; 17809369c97cSBjorn Andersson 1781599c1d5cSUlf Hansson if (!mmc->ocr_avail) 17821c6a0718SPierre Ossman mmc->ocr_avail = plat->ocr_mask; 1783599c1d5cSUlf Hansson else if (plat->ocr_mask) 1784599c1d5cSUlf Hansson dev_warn(mmc_dev(mmc), "Platform OCR mask is ignored\n"); 1785599c1d5cSUlf Hansson 17869dd8a8b8SUlf Hansson /* We support these capabilities. */ 17879dd8a8b8SUlf Hansson mmc->caps |= MMC_CAP_CMD23; 17889dd8a8b8SUlf Hansson 178949adc0caSLinus Walleij /* 179049adc0caSLinus Walleij * Enable busy detection. 179149adc0caSLinus Walleij */ 17928d94b54dSUlf Hansson if (variant->busy_detect) { 17938d94b54dSUlf Hansson mmci_ops.card_busy = mmci_card_busy; 179449adc0caSLinus Walleij /* 179549adc0caSLinus Walleij * Not all variants have a flag to enable busy detection 179649adc0caSLinus Walleij * in the DPSM, but if they do, set it here. 179749adc0caSLinus Walleij */ 179849adc0caSLinus Walleij if (variant->busy_dpsm_flag) 179949adc0caSLinus Walleij mmci_write_datactrlreg(host, 180049adc0caSLinus Walleij host->variant->busy_dpsm_flag); 18018d94b54dSUlf Hansson mmc->caps |= MMC_CAP_WAIT_WHILE_BUSY; 18028d94b54dSUlf Hansson mmc->max_busy_timeout = 0; 18038d94b54dSUlf Hansson } 18048d94b54dSUlf Hansson 18058d94b54dSUlf Hansson mmc->ops = &mmci_ops; 18068d94b54dSUlf Hansson 180770be208fSUlf Hansson /* We support these PM capabilities. */ 180878f87df2SUlf Hansson mmc->pm_caps |= MMC_PM_KEEP_POWER; 180970be208fSUlf Hansson 18101c6a0718SPierre Ossman /* 18111c6a0718SPierre Ossman * We can do SGIO 18121c6a0718SPierre Ossman */ 1813a36274e0SMartin K. Petersen mmc->max_segs = NR_SG; 18141c6a0718SPierre Ossman 18151c6a0718SPierre Ossman /* 181608458ef6SRabin Vincent * Since only a certain number of bits are valid in the data length 181708458ef6SRabin Vincent * register, we must ensure that we don't exceed 2^num-1 bytes in a 181808458ef6SRabin Vincent * single request. 18191c6a0718SPierre Ossman */ 182008458ef6SRabin Vincent mmc->max_req_size = (1 << variant->datalength_bits) - 1; 18211c6a0718SPierre Ossman 18221c6a0718SPierre Ossman /* 18231c6a0718SPierre Ossman * Set the maximum segment size. Since we aren't doing DMA 18241c6a0718SPierre Ossman * (yet) we are only limited by the data length register. 18251c6a0718SPierre Ossman */ 18261c6a0718SPierre Ossman mmc->max_seg_size = mmc->max_req_size; 18271c6a0718SPierre Ossman 18281c6a0718SPierre Ossman /* 18291c6a0718SPierre Ossman * Block size can be up to 2048 bytes, but must be a power of two. 18301c6a0718SPierre Ossman */ 18318f7f6b7eSWill Deacon mmc->max_blk_size = 1 << 11; 18321c6a0718SPierre Ossman 18331c6a0718SPierre Ossman /* 18348f7f6b7eSWill Deacon * Limit the number of blocks transferred so that we don't overflow 18358f7f6b7eSWill Deacon * the maximum request size. 18361c6a0718SPierre Ossman */ 18378f7f6b7eSWill Deacon mmc->max_blk_count = mmc->max_req_size >> 11; 18381c6a0718SPierre Ossman 18391c6a0718SPierre Ossman spin_lock_init(&host->lock); 18401c6a0718SPierre Ossman 18411c6a0718SPierre Ossman writel(0, host->base + MMCIMASK0); 18426ea9cdf3SPatrice Chotard 18436ea9cdf3SPatrice Chotard if (variant->mmcimask1) 18441c6a0718SPierre Ossman writel(0, host->base + MMCIMASK1); 18456ea9cdf3SPatrice Chotard 18461c6a0718SPierre Ossman writel(0xfff, host->base + MMCICLEAR); 18471c6a0718SPierre Ossman 1848ce437aa4SLinus Walleij /* 1849ce437aa4SLinus Walleij * If: 1850ce437aa4SLinus Walleij * - not using DT but using a descriptor table, or 1851ce437aa4SLinus Walleij * - using a table of descriptors ALONGSIDE DT, or 1852ce437aa4SLinus Walleij * look up these descriptors named "cd" and "wp" right here, fail 18539ef986a6SLinus Walleij * silently of these do not exist 1854ce437aa4SLinus Walleij */ 1855ce437aa4SLinus Walleij if (!np) { 185689168b48SLinus Walleij ret = mmc_gpiod_request_cd(mmc, "cd", 0, false, 0, NULL); 1857ce437aa4SLinus Walleij if (ret == -EPROBE_DEFER) 1858ce437aa4SLinus Walleij goto clk_disable; 1859ce437aa4SLinus Walleij 186089168b48SLinus Walleij ret = mmc_gpiod_request_ro(mmc, "wp", 0, false, 0, NULL); 1861ce437aa4SLinus Walleij if (ret == -EPROBE_DEFER) 1862ce437aa4SLinus Walleij goto clk_disable; 1863ce437aa4SLinus Walleij } 186489001446SRussell King 1865ef289982SUlf Hansson ret = devm_request_irq(&dev->dev, dev->irq[0], mmci_irq, IRQF_SHARED, 1866ef289982SUlf Hansson DRIVER_NAME " (cmd)", host); 18671c6a0718SPierre Ossman if (ret) 1868ef289982SUlf Hansson goto clk_disable; 18691c6a0718SPierre Ossman 1870dfb85185SRussell King if (!dev->irq[1]) 18712686b4b4SLinus Walleij host->singleirq = true; 18722686b4b4SLinus Walleij else { 1873ef289982SUlf Hansson ret = devm_request_irq(&dev->dev, dev->irq[1], mmci_pio_irq, 1874ef289982SUlf Hansson IRQF_SHARED, DRIVER_NAME " (pio)", host); 18751c6a0718SPierre Ossman if (ret) 1876ef289982SUlf Hansson goto clk_disable; 18772686b4b4SLinus Walleij } 18781c6a0718SPierre Ossman 18798cb28155SLinus Walleij writel(MCI_IRQENABLE, host->base + MMCIMASK0); 18801c6a0718SPierre Ossman 18811c6a0718SPierre Ossman amba_set_drvdata(dev, mmc); 18821c6a0718SPierre Ossman 1883c8ebae37SRussell King dev_info(&dev->dev, "%s: PL%03x manf %x rev%u at 0x%08llx irq %d,%d (pio)\n", 1884c8ebae37SRussell King mmc_hostname(mmc), amba_part(dev), amba_manf(dev), 1885c8ebae37SRussell King amba_rev(dev), (unsigned long long)dev->res.start, 1886c8ebae37SRussell King dev->irq[0], dev->irq[1]); 1887c8ebae37SRussell King 1888c8ebae37SRussell King mmci_dma_setup(host); 18891c6a0718SPierre Ossman 18902cd976c4SUlf Hansson pm_runtime_set_autosuspend_delay(&dev->dev, 50); 18912cd976c4SUlf Hansson pm_runtime_use_autosuspend(&dev->dev); 18921c3be369SRussell King 18938c11a94dSRussell King mmc_add_host(mmc); 18948c11a94dSRussell King 18956f2d3c89SUlf Hansson pm_runtime_put(&dev->dev); 18961c6a0718SPierre Ossman return 0; 18971c6a0718SPierre Ossman 18981c6a0718SPierre Ossman clk_disable: 1899ac940938SJulia Lawall clk_disable_unprepare(host->clk); 19001c6a0718SPierre Ossman host_free: 19011c6a0718SPierre Ossman mmc_free_host(mmc); 19021c6a0718SPierre Ossman return ret; 19031c6a0718SPierre Ossman } 19041c6a0718SPierre Ossman 19056e0ee714SBill Pemberton static int mmci_remove(struct amba_device *dev) 19061c6a0718SPierre Ossman { 19071c6a0718SPierre Ossman struct mmc_host *mmc = amba_get_drvdata(dev); 19081c6a0718SPierre Ossman 19091c6a0718SPierre Ossman if (mmc) { 19101c6a0718SPierre Ossman struct mmci_host *host = mmc_priv(mmc); 19116ea9cdf3SPatrice Chotard struct variant_data *variant = host->variant; 19121c6a0718SPierre Ossman 19131c3be369SRussell King /* 19141c3be369SRussell King * Undo pm_runtime_put() in probe. We use the _sync 19151c3be369SRussell King * version here so that we can access the primecell. 19161c3be369SRussell King */ 19171c3be369SRussell King pm_runtime_get_sync(&dev->dev); 19181c3be369SRussell King 19191c6a0718SPierre Ossman mmc_remove_host(mmc); 19201c6a0718SPierre Ossman 19211c6a0718SPierre Ossman writel(0, host->base + MMCIMASK0); 19226ea9cdf3SPatrice Chotard 19236ea9cdf3SPatrice Chotard if (variant->mmcimask1) 19241c6a0718SPierre Ossman writel(0, host->base + MMCIMASK1); 19251c6a0718SPierre Ossman 19261c6a0718SPierre Ossman writel(0, host->base + MMCICOMMAND); 19271c6a0718SPierre Ossman writel(0, host->base + MMCIDATACTRL); 19281c6a0718SPierre Ossman 1929c8ebae37SRussell King mmci_dma_release(host); 1930ac940938SJulia Lawall clk_disable_unprepare(host->clk); 19311c6a0718SPierre Ossman mmc_free_host(mmc); 19321c6a0718SPierre Ossman } 19331c6a0718SPierre Ossman 19341c6a0718SPierre Ossman return 0; 19351c6a0718SPierre Ossman } 19361c6a0718SPierre Ossman 1937571dce4fSUlf Hansson #ifdef CONFIG_PM 19381ff44433SUlf Hansson static void mmci_save(struct mmci_host *host) 19391ff44433SUlf Hansson { 19401ff44433SUlf Hansson unsigned long flags; 19411ff44433SUlf Hansson 19421ff44433SUlf Hansson spin_lock_irqsave(&host->lock, flags); 19431ff44433SUlf Hansson 19441ff44433SUlf Hansson writel(0, host->base + MMCIMASK0); 194542dcc89aSUlf Hansson if (host->variant->pwrreg_nopower) { 19461ff44433SUlf Hansson writel(0, host->base + MMCIDATACTRL); 19471ff44433SUlf Hansson writel(0, host->base + MMCIPOWER); 19481ff44433SUlf Hansson writel(0, host->base + MMCICLOCK); 194942dcc89aSUlf Hansson } 19501ff44433SUlf Hansson mmci_reg_delay(host); 19511ff44433SUlf Hansson 19521ff44433SUlf Hansson spin_unlock_irqrestore(&host->lock, flags); 19531ff44433SUlf Hansson } 19541ff44433SUlf Hansson 19551ff44433SUlf Hansson static void mmci_restore(struct mmci_host *host) 19561ff44433SUlf Hansson { 19571ff44433SUlf Hansson unsigned long flags; 19581ff44433SUlf Hansson 19591ff44433SUlf Hansson spin_lock_irqsave(&host->lock, flags); 19601ff44433SUlf Hansson 196142dcc89aSUlf Hansson if (host->variant->pwrreg_nopower) { 19621ff44433SUlf Hansson writel(host->clk_reg, host->base + MMCICLOCK); 19631ff44433SUlf Hansson writel(host->datactrl_reg, host->base + MMCIDATACTRL); 19641ff44433SUlf Hansson writel(host->pwr_reg, host->base + MMCIPOWER); 196542dcc89aSUlf Hansson } 19661ff44433SUlf Hansson writel(MCI_IRQENABLE, host->base + MMCIMASK0); 19671ff44433SUlf Hansson mmci_reg_delay(host); 19681ff44433SUlf Hansson 19691ff44433SUlf Hansson spin_unlock_irqrestore(&host->lock, flags); 19701ff44433SUlf Hansson } 19711ff44433SUlf Hansson 19728259293aSUlf Hansson static int mmci_runtime_suspend(struct device *dev) 19738259293aSUlf Hansson { 19748259293aSUlf Hansson struct amba_device *adev = to_amba_device(dev); 19758259293aSUlf Hansson struct mmc_host *mmc = amba_get_drvdata(adev); 19768259293aSUlf Hansson 19778259293aSUlf Hansson if (mmc) { 19788259293aSUlf Hansson struct mmci_host *host = mmc_priv(mmc); 1979e36bd9c6SUlf Hansson pinctrl_pm_select_sleep_state(dev); 19801ff44433SUlf Hansson mmci_save(host); 19818259293aSUlf Hansson clk_disable_unprepare(host->clk); 19828259293aSUlf Hansson } 19838259293aSUlf Hansson 19848259293aSUlf Hansson return 0; 19858259293aSUlf Hansson } 19868259293aSUlf Hansson 19878259293aSUlf Hansson static int mmci_runtime_resume(struct device *dev) 19888259293aSUlf Hansson { 19898259293aSUlf Hansson struct amba_device *adev = to_amba_device(dev); 19908259293aSUlf Hansson struct mmc_host *mmc = amba_get_drvdata(adev); 19918259293aSUlf Hansson 19928259293aSUlf Hansson if (mmc) { 19938259293aSUlf Hansson struct mmci_host *host = mmc_priv(mmc); 19948259293aSUlf Hansson clk_prepare_enable(host->clk); 19951ff44433SUlf Hansson mmci_restore(host); 1996e36bd9c6SUlf Hansson pinctrl_pm_select_default_state(dev); 19978259293aSUlf Hansson } 19988259293aSUlf Hansson 19998259293aSUlf Hansson return 0; 20008259293aSUlf Hansson } 20018259293aSUlf Hansson #endif 20028259293aSUlf Hansson 200348fa7003SUlf Hansson static const struct dev_pm_ops mmci_dev_pm_ops = { 2004f3737fa3SUlf Hansson SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, 2005f3737fa3SUlf Hansson pm_runtime_force_resume) 20066ed23b80SRafael J. Wysocki SET_RUNTIME_PM_OPS(mmci_runtime_suspend, mmci_runtime_resume, NULL) 200748fa7003SUlf Hansson }; 200848fa7003SUlf Hansson 200988411deaSArvind Yadav static const struct amba_id mmci_ids[] = { 20101c6a0718SPierre Ossman { 20111c6a0718SPierre Ossman .id = 0x00041180, 2012768fbc18SPawel Moll .mask = 0xff0fffff, 20134956e109SRabin Vincent .data = &variant_arm, 20141c6a0718SPierre Ossman }, 20151c6a0718SPierre Ossman { 2016768fbc18SPawel Moll .id = 0x01041180, 2017768fbc18SPawel Moll .mask = 0xff0fffff, 2018768fbc18SPawel Moll .data = &variant_arm_extended_fifo, 2019768fbc18SPawel Moll }, 2020768fbc18SPawel Moll { 20213a37298aSPawel Moll .id = 0x02041180, 20223a37298aSPawel Moll .mask = 0xff0fffff, 20233a37298aSPawel Moll .data = &variant_arm_extended_fifo_hwfc, 20243a37298aSPawel Moll }, 20253a37298aSPawel Moll { 20261c6a0718SPierre Ossman .id = 0x00041181, 20271c6a0718SPierre Ossman .mask = 0x000fffff, 20284956e109SRabin Vincent .data = &variant_arm, 20291c6a0718SPierre Ossman }, 2030cc30d60eSLinus Walleij /* ST Micro variants */ 2031cc30d60eSLinus Walleij { 2032cc30d60eSLinus Walleij .id = 0x00180180, 2033cc30d60eSLinus Walleij .mask = 0x00ffffff, 20344956e109SRabin Vincent .data = &variant_u300, 2035cc30d60eSLinus Walleij }, 2036cc30d60eSLinus Walleij { 203734fd4213SLinus Walleij .id = 0x10180180, 203834fd4213SLinus Walleij .mask = 0xf0ffffff, 203934fd4213SLinus Walleij .data = &variant_nomadik, 204034fd4213SLinus Walleij }, 204134fd4213SLinus Walleij { 2042cc30d60eSLinus Walleij .id = 0x00280180, 2043cc30d60eSLinus Walleij .mask = 0x00ffffff, 20440bcb7efdSLinus Walleij .data = &variant_nomadik, 20454956e109SRabin Vincent }, 20464956e109SRabin Vincent { 20474956e109SRabin Vincent .id = 0x00480180, 20481784b157SPhilippe Langlais .mask = 0xf0ffffff, 20494956e109SRabin Vincent .data = &variant_ux500, 2050cc30d60eSLinus Walleij }, 20511784b157SPhilippe Langlais { 20521784b157SPhilippe Langlais .id = 0x10480180, 20531784b157SPhilippe Langlais .mask = 0xf0ffffff, 20541784b157SPhilippe Langlais .data = &variant_ux500v2, 20551784b157SPhilippe Langlais }, 20562a9d6c80SPatrice Chotard { 20572a9d6c80SPatrice Chotard .id = 0x00880180, 20582a9d6c80SPatrice Chotard .mask = 0x00ffffff, 20592a9d6c80SPatrice Chotard .data = &variant_stm32, 20602a9d6c80SPatrice Chotard }, 206155b604aeSSrinivas Kandagatla /* Qualcomm variants */ 206255b604aeSSrinivas Kandagatla { 206355b604aeSSrinivas Kandagatla .id = 0x00051180, 206455b604aeSSrinivas Kandagatla .mask = 0x000fffff, 206555b604aeSSrinivas Kandagatla .data = &variant_qcom, 206655b604aeSSrinivas Kandagatla }, 20671c6a0718SPierre Ossman { 0, 0 }, 20681c6a0718SPierre Ossman }; 20691c6a0718SPierre Ossman 20709f99835fSDave Martin MODULE_DEVICE_TABLE(amba, mmci_ids); 20719f99835fSDave Martin 20721c6a0718SPierre Ossman static struct amba_driver mmci_driver = { 20731c6a0718SPierre Ossman .drv = { 20741c6a0718SPierre Ossman .name = DRIVER_NAME, 207548fa7003SUlf Hansson .pm = &mmci_dev_pm_ops, 20761c6a0718SPierre Ossman }, 20771c6a0718SPierre Ossman .probe = mmci_probe, 20780433c143SBill Pemberton .remove = mmci_remove, 20791c6a0718SPierre Ossman .id_table = mmci_ids, 20801c6a0718SPierre Ossman }; 20811c6a0718SPierre Ossman 20829e5ed094Sviresh kumar module_amba_driver(mmci_driver); 20831c6a0718SPierre Ossman 20841c6a0718SPierre Ossman module_param(fmax, uint, 0444); 20851c6a0718SPierre Ossman 20861c6a0718SPierre Ossman MODULE_DESCRIPTION("ARM PrimeCell PL180/181 Multimedia Card Interface driver"); 20871c6a0718SPierre Ossman MODULE_LICENSE("GPL"); 2088