blob: eb11ce61941ddcdedb796c26dc0894898e9fa2b5 [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/*
Pierre Ossman70f10482007-07-11 20:04:50 +02002 * linux/drivers/mmc/host/mmci.c - ARM PrimeCell MMCI PL180/1 driver
Linus Torvalds1da177e2005-04-16 15:20:36 -07003 *
4 * Copyright (C) 2003 Deep Blue Solutions, Ltd, All Rights Reserved.
Russell Kingc8ebae32011-01-11 19:35:53 +00005 * Copyright (C) 2010 ST-Ericsson SA
Linus Torvalds1da177e2005-04-16 15:20:36 -07006 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
Linus Torvalds1da177e2005-04-16 15:20:36 -070011#include <linux/module.h>
12#include <linux/moduleparam.h>
13#include <linux/init.h>
14#include <linux/ioport.h>
15#include <linux/device.h>
16#include <linux/interrupt.h>
Russell King613b1522011-01-30 21:06:53 +000017#include <linux/kernel.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070018#include <linux/delay.h>
19#include <linux/err.h>
20#include <linux/highmem.h>
Nicolas Pitre019a5f52007-10-11 01:06:03 -040021#include <linux/log2.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070022#include <linux/mmc/host.h>
Linus Walleij34177802010-10-19 12:43:58 +010023#include <linux/mmc/card.h>
Russell Kinga62c80e2006-01-07 13:52:45 +000024#include <linux/amba/bus.h>
Russell Kingf8ce2542006-01-07 16:15:52 +000025#include <linux/clk.h>
Jens Axboebd6dee62007-10-24 09:01:09 +020026#include <linux/scatterlist.h>
Russell King89001442009-07-09 15:16:07 +010027#include <linux/gpio.h>
Linus Walleij34e84f32009-09-22 14:41:40 +010028#include <linux/regulator/consumer.h>
Russell Kingc8ebae32011-01-11 19:35:53 +000029#include <linux/dmaengine.h>
30#include <linux/dma-mapping.h>
31#include <linux/amba/mmci.h>
Russell King1c3be362011-08-14 09:17:05 +010032#include <linux/pm_runtime.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070033
Russell King7b09cda2005-07-01 12:02:59 +010034#include <asm/div64.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070035#include <asm/io.h>
Russell Kingc6b8fda2005-10-28 14:05:16 +010036#include <asm/sizes.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070037
38#include "mmci.h"
39
40#define DRIVER_NAME "mmci-pl18x"
41
Linus Torvalds1da177e2005-04-16 15:20:36 -070042static unsigned int fmax = 515633;
43
Rabin Vincent4956e102010-07-21 12:54:40 +010044/**
45 * struct variant_data - MMCI variant-specific quirks
46 * @clkreg: default value for MCICLOCK register
Rabin Vincent4380c142010-07-21 12:55:18 +010047 * @clkreg_enable: enable value for MMCICLOCK register
Rabin Vincent08458ef2010-07-21 12:55:59 +010048 * @datalength_bits: number of bits in the MMCIDATALENGTH register
Rabin Vincent8301bb62010-08-09 12:57:30 +010049 * @fifosize: number of bytes that can be written when MMCI_TXFIFOEMPTY
50 * is asserted (likewise for RX)
51 * @fifohalfsize: number of bytes that can be written when MCI_TXFIFOHALFEMPTY
52 * is asserted (likewise for RX)
Linus Walleij34177802010-10-19 12:43:58 +010053 * @sdio: variant supports SDIO
Linus Walleijb70a67f2010-12-06 09:24:14 +010054 * @st_clkdiv: true if using a ST-specific clock divider algorithm
Philippe Langlais1784b152011-03-25 08:51:52 +010055 * @blksz_datactrl16: true if Block size is at b16..b30 position in datactrl register
Ulf Hansson7d72a1d2011-12-13 16:54:55 +010056 * @pwrreg_powerup: power up value for MMCIPOWER register
Ulf Hansson4d1a3a02011-12-13 16:57:07 +010057 * @signal_direction: input/out direction of bus signals can be indicated
Rabin Vincent4956e102010-07-21 12:54:40 +010058 */
59struct variant_data {
60 unsigned int clkreg;
Rabin Vincent4380c142010-07-21 12:55:18 +010061 unsigned int clkreg_enable;
Rabin Vincent08458ef2010-07-21 12:55:59 +010062 unsigned int datalength_bits;
Rabin Vincent8301bb62010-08-09 12:57:30 +010063 unsigned int fifosize;
64 unsigned int fifohalfsize;
Linus Walleij34177802010-10-19 12:43:58 +010065 bool sdio;
Linus Walleijb70a67f2010-12-06 09:24:14 +010066 bool st_clkdiv;
Philippe Langlais1784b152011-03-25 08:51:52 +010067 bool blksz_datactrl16;
Ulf Hansson7d72a1d2011-12-13 16:54:55 +010068 u32 pwrreg_powerup;
Ulf Hansson4d1a3a02011-12-13 16:57:07 +010069 bool signal_direction;
Rabin Vincent4956e102010-07-21 12:54:40 +010070};
71
72static struct variant_data variant_arm = {
Rabin Vincent8301bb62010-08-09 12:57:30 +010073 .fifosize = 16 * 4,
74 .fifohalfsize = 8 * 4,
Rabin Vincent08458ef2010-07-21 12:55:59 +010075 .datalength_bits = 16,
Ulf Hansson7d72a1d2011-12-13 16:54:55 +010076 .pwrreg_powerup = MCI_PWR_UP,
Rabin Vincent4956e102010-07-21 12:54:40 +010077};
78
Pawel Moll768fbc12011-03-11 17:18:07 +000079static struct variant_data variant_arm_extended_fifo = {
80 .fifosize = 128 * 4,
81 .fifohalfsize = 64 * 4,
82 .datalength_bits = 16,
Ulf Hansson7d72a1d2011-12-13 16:54:55 +010083 .pwrreg_powerup = MCI_PWR_UP,
Pawel Moll768fbc12011-03-11 17:18:07 +000084};
85
Rabin Vincent4956e102010-07-21 12:54:40 +010086static struct variant_data variant_u300 = {
Rabin Vincent8301bb62010-08-09 12:57:30 +010087 .fifosize = 16 * 4,
88 .fifohalfsize = 8 * 4,
Linus Walleij49ac2152011-03-04 14:54:16 +010089 .clkreg_enable = MCI_ST_U300_HWFCEN,
Rabin Vincent08458ef2010-07-21 12:55:59 +010090 .datalength_bits = 16,
Linus Walleij34177802010-10-19 12:43:58 +010091 .sdio = true,
Ulf Hansson7d72a1d2011-12-13 16:54:55 +010092 .pwrreg_powerup = MCI_PWR_ON,
Ulf Hansson4d1a3a02011-12-13 16:57:07 +010093 .signal_direction = true,
Rabin Vincent4956e102010-07-21 12:54:40 +010094};
95
96static struct variant_data variant_ux500 = {
Rabin Vincent8301bb62010-08-09 12:57:30 +010097 .fifosize = 30 * 4,
98 .fifohalfsize = 8 * 4,
Rabin Vincent4956e102010-07-21 12:54:40 +010099 .clkreg = MCI_CLK_ENABLE,
Linus Walleij49ac2152011-03-04 14:54:16 +0100100 .clkreg_enable = MCI_ST_UX500_HWFCEN,
Rabin Vincent08458ef2010-07-21 12:55:59 +0100101 .datalength_bits = 24,
Linus Walleij34177802010-10-19 12:43:58 +0100102 .sdio = true,
Linus Walleijb70a67f2010-12-06 09:24:14 +0100103 .st_clkdiv = true,
Ulf Hansson7d72a1d2011-12-13 16:54:55 +0100104 .pwrreg_powerup = MCI_PWR_ON,
Ulf Hansson4d1a3a02011-12-13 16:57:07 +0100105 .signal_direction = true,
Rabin Vincent4956e102010-07-21 12:54:40 +0100106};
Linus Walleijb70a67f2010-12-06 09:24:14 +0100107
Philippe Langlais1784b152011-03-25 08:51:52 +0100108static struct variant_data variant_ux500v2 = {
109 .fifosize = 30 * 4,
110 .fifohalfsize = 8 * 4,
111 .clkreg = MCI_CLK_ENABLE,
112 .clkreg_enable = MCI_ST_UX500_HWFCEN,
113 .datalength_bits = 24,
114 .sdio = true,
115 .st_clkdiv = true,
116 .blksz_datactrl16 = true,
Ulf Hansson7d72a1d2011-12-13 16:54:55 +0100117 .pwrreg_powerup = MCI_PWR_ON,
Ulf Hansson4d1a3a02011-12-13 16:57:07 +0100118 .signal_direction = true,
Philippe Langlais1784b152011-03-25 08:51:52 +0100119};
120
Linus Walleija6a64642009-09-14 12:56:14 +0100121/*
122 * This must be called with host->lock held
123 */
124static void mmci_set_clkreg(struct mmci_host *host, unsigned int desired)
125{
Rabin Vincent4956e102010-07-21 12:54:40 +0100126 struct variant_data *variant = host->variant;
127 u32 clk = variant->clkreg;
Linus Walleija6a64642009-09-14 12:56:14 +0100128
129 if (desired) {
130 if (desired >= host->mclk) {
Linus Walleij991a86e2010-12-10 09:35:53 +0100131 clk = MCI_CLK_BYPASS;
Linus Walleij399bc482011-04-01 07:59:17 +0100132 if (variant->st_clkdiv)
133 clk |= MCI_ST_UX500_NEG_EDGE;
Linus Walleija6a64642009-09-14 12:56:14 +0100134 host->cclk = host->mclk;
Linus Walleijb70a67f2010-12-06 09:24:14 +0100135 } else if (variant->st_clkdiv) {
136 /*
137 * DB8500 TRM says f = mclk / (clkdiv + 2)
138 * => clkdiv = (mclk / f) - 2
139 * Round the divider up so we don't exceed the max
140 * frequency
141 */
142 clk = DIV_ROUND_UP(host->mclk, desired) - 2;
143 if (clk >= 256)
144 clk = 255;
145 host->cclk = host->mclk / (clk + 2);
Linus Walleija6a64642009-09-14 12:56:14 +0100146 } else {
Linus Walleijb70a67f2010-12-06 09:24:14 +0100147 /*
148 * PL180 TRM says f = mclk / (2 * (clkdiv + 1))
149 * => clkdiv = mclk / (2 * f) - 1
150 */
Linus Walleija6a64642009-09-14 12:56:14 +0100151 clk = host->mclk / (2 * desired) - 1;
152 if (clk >= 256)
153 clk = 255;
154 host->cclk = host->mclk / (2 * (clk + 1));
155 }
Rabin Vincent4380c142010-07-21 12:55:18 +0100156
157 clk |= variant->clkreg_enable;
Linus Walleija6a64642009-09-14 12:56:14 +0100158 clk |= MCI_CLK_ENABLE;
159 /* This hasn't proven to be worthwhile */
160 /* clk |= MCI_CLK_PWRSAVE; */
161 }
162
Linus Walleij9e6c82c2009-09-14 12:57:11 +0100163 if (host->mmc->ios.bus_width == MMC_BUS_WIDTH_4)
Linus Walleij771dc152010-04-08 07:38:52 +0100164 clk |= MCI_4BIT_BUS;
165 if (host->mmc->ios.bus_width == MMC_BUS_WIDTH_8)
166 clk |= MCI_ST_8BIT_BUS;
Linus Walleij9e6c82c2009-09-14 12:57:11 +0100167
Linus Walleija6a64642009-09-14 12:56:14 +0100168 writel(clk, host->base + MMCICLOCK);
169}
170
Linus Torvalds1da177e2005-04-16 15:20:36 -0700171static void
172mmci_request_end(struct mmci_host *host, struct mmc_request *mrq)
173{
174 writel(0, host->base + MMCICOMMAND);
175
Russell Kinge47c2222007-01-08 16:42:51 +0000176 BUG_ON(host->data);
177
Linus Torvalds1da177e2005-04-16 15:20:36 -0700178 host->mrq = NULL;
179 host->cmd = NULL;
180
Russell King1c3be362011-08-14 09:17:05 +0100181 pm_runtime_put(mmc_dev(host->mmc));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700182 mmc_request_done(host->mmc, mrq);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700183}
184
Linus Walleij2686b4b2010-10-19 12:39:48 +0100185static void mmci_set_mask1(struct mmci_host *host, unsigned int mask)
186{
187 void __iomem *base = host->base;
188
189 if (host->singleirq) {
190 unsigned int mask0 = readl(base + MMCIMASK0);
191
192 mask0 &= ~MCI_IRQ1MASK;
193 mask0 |= mask;
194
195 writel(mask0, base + MMCIMASK0);
196 }
197
198 writel(mask, base + MMCIMASK1);
199}
200
Linus Torvalds1da177e2005-04-16 15:20:36 -0700201static void mmci_stop_data(struct mmci_host *host)
202{
203 writel(0, host->base + MMCIDATACTRL);
Linus Walleij2686b4b2010-10-19 12:39:48 +0100204 mmci_set_mask1(host, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700205 host->data = NULL;
206}
207
Rabin Vincent4ce1d6c2010-07-21 12:44:58 +0100208static void mmci_init_sg(struct mmci_host *host, struct mmc_data *data)
209{
210 unsigned int flags = SG_MITER_ATOMIC;
211
212 if (data->flags & MMC_DATA_READ)
213 flags |= SG_MITER_TO_SG;
214 else
215 flags |= SG_MITER_FROM_SG;
216
217 sg_miter_start(&host->sg_miter, data->sg, data->sg_len, flags);
218}
219
Russell Kingc8ebae32011-01-11 19:35:53 +0000220/*
221 * All the DMA operation mode stuff goes inside this ifdef.
222 * This assumes that you have a generic DMA device interface,
223 * no custom DMA interfaces are supported.
224 */
225#ifdef CONFIG_DMA_ENGINE
226static void __devinit mmci_dma_setup(struct mmci_host *host)
227{
228 struct mmci_platform_data *plat = host->plat;
229 const char *rxname, *txname;
230 dma_cap_mask_t mask;
231
232 if (!plat || !plat->dma_filter) {
233 dev_info(mmc_dev(host->mmc), "no DMA platform data\n");
234 return;
235 }
236
Per Forlin58c7ccb2011-07-01 18:55:24 +0200237 /* initialize pre request cookie */
238 host->next_data.cookie = 1;
239
Russell Kingc8ebae32011-01-11 19:35:53 +0000240 /* Try to acquire a generic DMA engine slave channel */
241 dma_cap_zero(mask);
242 dma_cap_set(DMA_SLAVE, mask);
243
244 /*
245 * If only an RX channel is specified, the driver will
246 * attempt to use it bidirectionally, however if it is
247 * is specified but cannot be located, DMA will be disabled.
248 */
249 if (plat->dma_rx_param) {
250 host->dma_rx_channel = dma_request_channel(mask,
251 plat->dma_filter,
252 plat->dma_rx_param);
253 /* E.g if no DMA hardware is present */
254 if (!host->dma_rx_channel)
255 dev_err(mmc_dev(host->mmc), "no RX DMA channel\n");
256 }
257
258 if (plat->dma_tx_param) {
259 host->dma_tx_channel = dma_request_channel(mask,
260 plat->dma_filter,
261 plat->dma_tx_param);
262 if (!host->dma_tx_channel)
263 dev_warn(mmc_dev(host->mmc), "no TX DMA channel\n");
264 } else {
265 host->dma_tx_channel = host->dma_rx_channel;
266 }
267
268 if (host->dma_rx_channel)
269 rxname = dma_chan_name(host->dma_rx_channel);
270 else
271 rxname = "none";
272
273 if (host->dma_tx_channel)
274 txname = dma_chan_name(host->dma_tx_channel);
275 else
276 txname = "none";
277
278 dev_info(mmc_dev(host->mmc), "DMA channels RX %s, TX %s\n",
279 rxname, txname);
280
281 /*
282 * Limit the maximum segment size in any SG entry according to
283 * the parameters of the DMA engine device.
284 */
285 if (host->dma_tx_channel) {
286 struct device *dev = host->dma_tx_channel->device->dev;
287 unsigned int max_seg_size = dma_get_max_seg_size(dev);
288
289 if (max_seg_size < host->mmc->max_seg_size)
290 host->mmc->max_seg_size = max_seg_size;
291 }
292 if (host->dma_rx_channel) {
293 struct device *dev = host->dma_rx_channel->device->dev;
294 unsigned int max_seg_size = dma_get_max_seg_size(dev);
295
296 if (max_seg_size < host->mmc->max_seg_size)
297 host->mmc->max_seg_size = max_seg_size;
298 }
299}
300
301/*
302 * This is used in __devinit or __devexit so inline it
303 * so it can be discarded.
304 */
305static inline void mmci_dma_release(struct mmci_host *host)
306{
307 struct mmci_platform_data *plat = host->plat;
308
309 if (host->dma_rx_channel)
310 dma_release_channel(host->dma_rx_channel);
311 if (host->dma_tx_channel && plat->dma_tx_param)
312 dma_release_channel(host->dma_tx_channel);
313 host->dma_rx_channel = host->dma_tx_channel = NULL;
314}
315
316static void mmci_dma_unmap(struct mmci_host *host, struct mmc_data *data)
317{
318 struct dma_chan *chan = host->dma_current;
319 enum dma_data_direction dir;
320 u32 status;
321 int i;
322
323 /* Wait up to 1ms for the DMA to complete */
324 for (i = 0; ; i++) {
325 status = readl(host->base + MMCISTATUS);
326 if (!(status & MCI_RXDATAAVLBLMASK) || i >= 100)
327 break;
328 udelay(10);
329 }
330
331 /*
332 * Check to see whether we still have some data left in the FIFO -
333 * this catches DMA controllers which are unable to monitor the
334 * DMALBREQ and DMALSREQ signals while allowing us to DMA to non-
335 * contiguous buffers. On TX, we'll get a FIFO underrun error.
336 */
337 if (status & MCI_RXDATAAVLBLMASK) {
338 dmaengine_terminate_all(chan);
339 if (!data->error)
340 data->error = -EIO;
341 }
342
343 if (data->flags & MMC_DATA_WRITE) {
344 dir = DMA_TO_DEVICE;
345 } else {
346 dir = DMA_FROM_DEVICE;
347 }
348
Per Forlin58c7ccb2011-07-01 18:55:24 +0200349 if (!data->host_cookie)
350 dma_unmap_sg(chan->device->dev, data->sg, data->sg_len, dir);
Russell Kingc8ebae32011-01-11 19:35:53 +0000351
352 /*
353 * Use of DMA with scatter-gather is impossible.
354 * Give up with DMA and switch back to PIO mode.
355 */
356 if (status & MCI_RXDATAAVLBLMASK) {
357 dev_err(mmc_dev(host->mmc), "buggy DMA detected. Taking evasive action.\n");
358 mmci_dma_release(host);
359 }
360}
361
362static void mmci_dma_data_error(struct mmci_host *host)
363{
364 dev_err(mmc_dev(host->mmc), "error during DMA transfer!\n");
365 dmaengine_terminate_all(host->dma_current);
366}
367
Per Forlin58c7ccb2011-07-01 18:55:24 +0200368static int mmci_dma_prep_data(struct mmci_host *host, struct mmc_data *data,
369 struct mmci_host_next *next)
Russell Kingc8ebae32011-01-11 19:35:53 +0000370{
371 struct variant_data *variant = host->variant;
372 struct dma_slave_config conf = {
373 .src_addr = host->phybase + MMCIFIFO,
374 .dst_addr = host->phybase + MMCIFIFO,
375 .src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES,
376 .dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES,
377 .src_maxburst = variant->fifohalfsize >> 2, /* # of words */
378 .dst_maxburst = variant->fifohalfsize >> 2, /* # of words */
379 };
Russell Kingc8ebae32011-01-11 19:35:53 +0000380 struct dma_chan *chan;
381 struct dma_device *device;
382 struct dma_async_tx_descriptor *desc;
Vinod Koul05f57992011-10-14 10:45:11 +0530383 enum dma_data_direction buffer_dirn;
Russell Kingc8ebae32011-01-11 19:35:53 +0000384 int nr_sg;
385
Per Forlin58c7ccb2011-07-01 18:55:24 +0200386 /* Check if next job is already prepared */
387 if (data->host_cookie && !next &&
388 host->dma_current && host->dma_desc_current)
389 return 0;
390
391 if (!next) {
392 host->dma_current = NULL;
393 host->dma_desc_current = NULL;
394 }
Russell Kingc8ebae32011-01-11 19:35:53 +0000395
396 if (data->flags & MMC_DATA_READ) {
Vinod Koul05f57992011-10-14 10:45:11 +0530397 conf.direction = DMA_DEV_TO_MEM;
398 buffer_dirn = DMA_FROM_DEVICE;
Russell Kingc8ebae32011-01-11 19:35:53 +0000399 chan = host->dma_rx_channel;
400 } else {
Vinod Koul05f57992011-10-14 10:45:11 +0530401 conf.direction = DMA_MEM_TO_DEV;
402 buffer_dirn = DMA_TO_DEVICE;
Russell Kingc8ebae32011-01-11 19:35:53 +0000403 chan = host->dma_tx_channel;
404 }
405
406 /* If there's no DMA channel, fall back to PIO */
407 if (!chan)
408 return -EINVAL;
409
410 /* If less than or equal to the fifo size, don't bother with DMA */
Per Forlin58c7ccb2011-07-01 18:55:24 +0200411 if (data->blksz * data->blocks <= variant->fifosize)
Russell Kingc8ebae32011-01-11 19:35:53 +0000412 return -EINVAL;
413
414 device = chan->device;
Vinod Koul05f57992011-10-14 10:45:11 +0530415 nr_sg = dma_map_sg(device->dev, data->sg, data->sg_len, buffer_dirn);
Russell Kingc8ebae32011-01-11 19:35:53 +0000416 if (nr_sg == 0)
417 return -EINVAL;
418
419 dmaengine_slave_config(chan, &conf);
420 desc = device->device_prep_slave_sg(chan, data->sg, nr_sg,
421 conf.direction, DMA_CTRL_ACK);
422 if (!desc)
423 goto unmap_exit;
424
Per Forlin58c7ccb2011-07-01 18:55:24 +0200425 if (next) {
426 next->dma_chan = chan;
427 next->dma_desc = desc;
428 } else {
429 host->dma_current = chan;
430 host->dma_desc_current = desc;
431 }
Russell Kingc8ebae32011-01-11 19:35:53 +0000432
Per Forlin58c7ccb2011-07-01 18:55:24 +0200433 return 0;
434
435 unmap_exit:
436 if (!next)
437 dmaengine_terminate_all(chan);
Vinod Koul05f57992011-10-14 10:45:11 +0530438 dma_unmap_sg(device->dev, data->sg, data->sg_len, buffer_dirn);
Per Forlin58c7ccb2011-07-01 18:55:24 +0200439 return -ENOMEM;
440}
441
442static int mmci_dma_start_data(struct mmci_host *host, unsigned int datactrl)
443{
444 int ret;
445 struct mmc_data *data = host->data;
446
447 ret = mmci_dma_prep_data(host, host->data, NULL);
448 if (ret)
449 return ret;
450
451 /* Okay, go for it. */
Russell Kingc8ebae32011-01-11 19:35:53 +0000452 dev_vdbg(mmc_dev(host->mmc),
453 "Submit MMCI DMA job, sglen %d blksz %04x blks %04x flags %08x\n",
454 data->sg_len, data->blksz, data->blocks, data->flags);
Per Forlin58c7ccb2011-07-01 18:55:24 +0200455 dmaengine_submit(host->dma_desc_current);
456 dma_async_issue_pending(host->dma_current);
Russell Kingc8ebae32011-01-11 19:35:53 +0000457
458 datactrl |= MCI_DPSM_DMAENABLE;
459
460 /* Trigger the DMA transfer */
461 writel(datactrl, host->base + MMCIDATACTRL);
462
463 /*
464 * Let the MMCI say when the data is ended and it's time
465 * to fire next DMA request. When that happens, MMCI will
466 * call mmci_data_end()
467 */
468 writel(readl(host->base + MMCIMASK0) | MCI_DATAENDMASK,
469 host->base + MMCIMASK0);
470 return 0;
Russell Kingc8ebae32011-01-11 19:35:53 +0000471}
Per Forlin58c7ccb2011-07-01 18:55:24 +0200472
473static void mmci_get_next_data(struct mmci_host *host, struct mmc_data *data)
474{
475 struct mmci_host_next *next = &host->next_data;
476
477 if (data->host_cookie && data->host_cookie != next->cookie) {
Girish K Sa3c76eb2011-10-11 11:44:09 +0530478 pr_warning("[%s] invalid cookie: data->host_cookie %d"
Per Forlin58c7ccb2011-07-01 18:55:24 +0200479 " host->next_data.cookie %d\n",
480 __func__, data->host_cookie, host->next_data.cookie);
481 data->host_cookie = 0;
482 }
483
484 if (!data->host_cookie)
485 return;
486
487 host->dma_desc_current = next->dma_desc;
488 host->dma_current = next->dma_chan;
489
490 next->dma_desc = NULL;
491 next->dma_chan = NULL;
492}
493
494static void mmci_pre_request(struct mmc_host *mmc, struct mmc_request *mrq,
495 bool is_first_req)
496{
497 struct mmci_host *host = mmc_priv(mmc);
498 struct mmc_data *data = mrq->data;
499 struct mmci_host_next *nd = &host->next_data;
500
501 if (!data)
502 return;
503
504 if (data->host_cookie) {
505 data->host_cookie = 0;
506 return;
507 }
508
509 /* if config for dma */
510 if (((data->flags & MMC_DATA_WRITE) && host->dma_tx_channel) ||
511 ((data->flags & MMC_DATA_READ) && host->dma_rx_channel)) {
512 if (mmci_dma_prep_data(host, data, nd))
513 data->host_cookie = 0;
514 else
515 data->host_cookie = ++nd->cookie < 0 ? 1 : nd->cookie;
516 }
517}
518
519static void mmci_post_request(struct mmc_host *mmc, struct mmc_request *mrq,
520 int err)
521{
522 struct mmci_host *host = mmc_priv(mmc);
523 struct mmc_data *data = mrq->data;
524 struct dma_chan *chan;
525 enum dma_data_direction dir;
526
527 if (!data)
528 return;
529
530 if (data->flags & MMC_DATA_READ) {
531 dir = DMA_FROM_DEVICE;
532 chan = host->dma_rx_channel;
533 } else {
534 dir = DMA_TO_DEVICE;
535 chan = host->dma_tx_channel;
536 }
537
538
539 /* if config for dma */
540 if (chan) {
541 if (err)
542 dmaengine_terminate_all(chan);
Per Forlin8e3336b2011-08-29 15:35:59 +0200543 if (data->host_cookie)
Per Forlin58c7ccb2011-07-01 18:55:24 +0200544 dma_unmap_sg(mmc_dev(host->mmc), data->sg,
545 data->sg_len, dir);
546 mrq->data->host_cookie = 0;
547 }
548}
549
Russell Kingc8ebae32011-01-11 19:35:53 +0000550#else
551/* Blank functions if the DMA engine is not available */
Per Forlin58c7ccb2011-07-01 18:55:24 +0200552static void mmci_get_next_data(struct mmci_host *host, struct mmc_data *data)
553{
554}
Russell Kingc8ebae32011-01-11 19:35:53 +0000555static inline void mmci_dma_setup(struct mmci_host *host)
556{
557}
558
559static inline void mmci_dma_release(struct mmci_host *host)
560{
561}
562
563static inline void mmci_dma_unmap(struct mmci_host *host, struct mmc_data *data)
564{
565}
566
567static inline void mmci_dma_data_error(struct mmci_host *host)
568{
569}
570
571static inline int mmci_dma_start_data(struct mmci_host *host, unsigned int datactrl)
572{
573 return -ENOSYS;
574}
Per Forlin58c7ccb2011-07-01 18:55:24 +0200575
576#define mmci_pre_request NULL
577#define mmci_post_request NULL
578
Russell Kingc8ebae32011-01-11 19:35:53 +0000579#endif
580
Linus Torvalds1da177e2005-04-16 15:20:36 -0700581static void mmci_start_data(struct mmci_host *host, struct mmc_data *data)
582{
Rabin Vincent8301bb62010-08-09 12:57:30 +0100583 struct variant_data *variant = host->variant;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700584 unsigned int datactrl, timeout, irqmask;
Russell King7b09cda2005-07-01 12:02:59 +0100585 unsigned long long clks;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700586 void __iomem *base;
Russell King3bc87f22006-08-27 13:51:28 +0100587 int blksz_bits;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700588
Linus Walleij64de0282010-02-19 01:09:10 +0100589 dev_dbg(mmc_dev(host->mmc), "blksz %04x blks %04x flags %08x\n",
590 data->blksz, data->blocks, data->flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700591
592 host->data = data;
Rabin Vincent528320d2010-07-21 12:49:49 +0100593 host->size = data->blksz * data->blocks;
Russell King51d43752011-01-27 10:56:52 +0000594 data->bytes_xfered = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700595
Russell King7b09cda2005-07-01 12:02:59 +0100596 clks = (unsigned long long)data->timeout_ns * host->cclk;
597 do_div(clks, 1000000000UL);
598
599 timeout = data->timeout_clks + (unsigned int)clks;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700600
601 base = host->base;
602 writel(timeout, base + MMCIDATATIMER);
603 writel(host->size, base + MMCIDATALENGTH);
604
Russell King3bc87f22006-08-27 13:51:28 +0100605 blksz_bits = ffs(data->blksz) - 1;
606 BUG_ON(1 << blksz_bits != data->blksz);
607
Philippe Langlais1784b152011-03-25 08:51:52 +0100608 if (variant->blksz_datactrl16)
609 datactrl = MCI_DPSM_ENABLE | (data->blksz << 16);
610 else
611 datactrl = MCI_DPSM_ENABLE | blksz_bits << 4;
Russell Kingc8ebae32011-01-11 19:35:53 +0000612
613 if (data->flags & MMC_DATA_READ)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700614 datactrl |= MCI_DPSM_DIRECTION;
Russell Kingc8ebae32011-01-11 19:35:53 +0000615
616 /*
617 * Attempt to use DMA operation mode, if this
618 * should fail, fall back to PIO mode
619 */
620 if (!mmci_dma_start_data(host, datactrl))
621 return;
622
623 /* IRQ mode, map the SG list for CPU reading/writing */
624 mmci_init_sg(host, data);
625
626 if (data->flags & MMC_DATA_READ) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700627 irqmask = MCI_RXFIFOHALFFULLMASK;
Russell King0425a142006-02-16 16:48:31 +0000628
629 /*
Russell Kingc4d877c2011-01-27 09:50:13 +0000630 * If we have less than the fifo 'half-full' threshold to
631 * transfer, trigger a PIO interrupt as soon as any data
632 * is available.
Russell King0425a142006-02-16 16:48:31 +0000633 */
Russell Kingc4d877c2011-01-27 09:50:13 +0000634 if (host->size < variant->fifohalfsize)
Russell King0425a142006-02-16 16:48:31 +0000635 irqmask |= MCI_RXDATAAVLBLMASK;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700636 } else {
637 /*
638 * We don't actually need to include "FIFO empty" here
639 * since its implicit in "FIFO half empty".
640 */
641 irqmask = MCI_TXFIFOHALFEMPTYMASK;
642 }
643
Linus Walleij34177802010-10-19 12:43:58 +0100644 /* The ST Micro variants has a special bit to enable SDIO */
645 if (variant->sdio && host->mmc->card)
646 if (mmc_card_sdio(host->mmc->card))
647 datactrl |= MCI_ST_DPSM_SDIOEN;
648
Linus Torvalds1da177e2005-04-16 15:20:36 -0700649 writel(datactrl, base + MMCIDATACTRL);
650 writel(readl(base + MMCIMASK0) & ~MCI_DATAENDMASK, base + MMCIMASK0);
Linus Walleij2686b4b2010-10-19 12:39:48 +0100651 mmci_set_mask1(host, irqmask);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700652}
653
654static void
655mmci_start_command(struct mmci_host *host, struct mmc_command *cmd, u32 c)
656{
657 void __iomem *base = host->base;
658
Linus Walleij64de0282010-02-19 01:09:10 +0100659 dev_dbg(mmc_dev(host->mmc), "op %02x arg %08x flags %08x\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -0700660 cmd->opcode, cmd->arg, cmd->flags);
661
662 if (readl(base + MMCICOMMAND) & MCI_CPSM_ENABLE) {
663 writel(0, base + MMCICOMMAND);
664 udelay(1);
665 }
666
667 c |= cmd->opcode | MCI_CPSM_ENABLE;
Russell Kinge9225172006-02-02 12:23:12 +0000668 if (cmd->flags & MMC_RSP_PRESENT) {
669 if (cmd->flags & MMC_RSP_136)
670 c |= MCI_CPSM_LONGRSP;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700671 c |= MCI_CPSM_RESPONSE;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700672 }
673 if (/*interrupt*/0)
674 c |= MCI_CPSM_INTERRUPT;
675
676 host->cmd = cmd;
677
678 writel(cmd->arg, base + MMCIARGUMENT);
679 writel(c, base + MMCICOMMAND);
680}
681
682static void
683mmci_data_irq(struct mmci_host *host, struct mmc_data *data,
684 unsigned int status)
685{
Linus Walleijf20f8f22010-10-19 13:41:24 +0100686 /* First check for errors */
Ulf Hanssonb63038d2011-12-13 16:51:04 +0100687 if (status & (MCI_DATACRCFAIL|MCI_DATATIMEOUT|MCI_STARTBITERR|
688 MCI_TXUNDERRUN|MCI_RXOVERRUN)) {
Linus Walleij8cb28152011-01-24 15:22:13 +0100689 u32 remain, success;
Linus Walleijf20f8f22010-10-19 13:41:24 +0100690
Russell Kingc8ebae32011-01-11 19:35:53 +0000691 /* Terminate the DMA transfer */
692 if (dma_inprogress(host))
693 mmci_dma_data_error(host);
694
Russell Kingc8afc9d2011-02-04 09:19:46 +0000695 /*
696 * Calculate how far we are into the transfer. Note that
697 * the data counter gives the number of bytes transferred
698 * on the MMC bus, not on the host side. On reads, this
699 * can be as much as a FIFO-worth of data ahead. This
700 * matters for FIFO overruns only.
701 */
Linus Walleijf5a106d2011-01-27 17:44:34 +0100702 remain = readl(host->base + MMCIDATACNT);
Linus Walleij8cb28152011-01-24 15:22:13 +0100703 success = data->blksz * data->blocks - remain;
704
Russell Kingc8afc9d2011-02-04 09:19:46 +0000705 dev_dbg(mmc_dev(host->mmc), "MCI ERROR IRQ, status 0x%08x at 0x%08x\n",
706 status, success);
Linus Walleij8cb28152011-01-24 15:22:13 +0100707 if (status & MCI_DATACRCFAIL) {
708 /* Last block was not successful */
Russell Kingc8afc9d2011-02-04 09:19:46 +0000709 success -= 1;
Pierre Ossman17b04292007-07-22 22:18:46 +0200710 data->error = -EILSEQ;
Linus Walleij8cb28152011-01-24 15:22:13 +0100711 } else if (status & MCI_DATATIMEOUT) {
Pierre Ossman17b04292007-07-22 22:18:46 +0200712 data->error = -ETIMEDOUT;
Linus Walleij757df742011-06-30 15:10:21 +0100713 } else if (status & MCI_STARTBITERR) {
714 data->error = -ECOMM;
Russell Kingc8afc9d2011-02-04 09:19:46 +0000715 } else if (status & MCI_TXUNDERRUN) {
Pierre Ossman17b04292007-07-22 22:18:46 +0200716 data->error = -EIO;
Russell Kingc8afc9d2011-02-04 09:19:46 +0000717 } else if (status & MCI_RXOVERRUN) {
718 if (success > host->variant->fifosize)
719 success -= host->variant->fifosize;
720 else
721 success = 0;
Linus Walleij8cb28152011-01-24 15:22:13 +0100722 data->error = -EIO;
Rabin Vincent4ce1d6c2010-07-21 12:44:58 +0100723 }
Russell King51d43752011-01-27 10:56:52 +0000724 data->bytes_xfered = round_down(success, data->blksz);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700725 }
Linus Walleijf20f8f22010-10-19 13:41:24 +0100726
Linus Walleij8cb28152011-01-24 15:22:13 +0100727 if (status & MCI_DATABLOCKEND)
728 dev_err(mmc_dev(host->mmc), "stray MCI_DATABLOCKEND interrupt\n");
Linus Walleijf20f8f22010-10-19 13:41:24 +0100729
Russell Kingccff9b52011-01-30 21:03:50 +0000730 if (status & MCI_DATAEND || data->error) {
Russell Kingc8ebae32011-01-11 19:35:53 +0000731 if (dma_inprogress(host))
732 mmci_dma_unmap(host, data);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700733 mmci_stop_data(host);
734
Linus Walleij8cb28152011-01-24 15:22:13 +0100735 if (!data->error)
736 /* The error clause is handled above, success! */
Russell King51d43752011-01-27 10:56:52 +0000737 data->bytes_xfered = data->blksz * data->blocks;
Linus Walleijf20f8f22010-10-19 13:41:24 +0100738
Linus Torvalds1da177e2005-04-16 15:20:36 -0700739 if (!data->stop) {
740 mmci_request_end(host, data->mrq);
741 } else {
742 mmci_start_command(host, data->stop, 0);
743 }
744 }
745}
746
747static void
748mmci_cmd_irq(struct mmci_host *host, struct mmc_command *cmd,
749 unsigned int status)
750{
751 void __iomem *base = host->base;
752
753 host->cmd = NULL;
754
Linus Torvalds1da177e2005-04-16 15:20:36 -0700755 if (status & MCI_CMDTIMEOUT) {
Pierre Ossman17b04292007-07-22 22:18:46 +0200756 cmd->error = -ETIMEDOUT;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700757 } else if (status & MCI_CMDCRCFAIL && cmd->flags & MMC_RSP_CRC) {
Pierre Ossman17b04292007-07-22 22:18:46 +0200758 cmd->error = -EILSEQ;
Russell King - ARM Linux9047b432011-01-11 16:35:56 +0000759 } else {
760 cmd->resp[0] = readl(base + MMCIRESPONSE0);
761 cmd->resp[1] = readl(base + MMCIRESPONSE1);
762 cmd->resp[2] = readl(base + MMCIRESPONSE2);
763 cmd->resp[3] = readl(base + MMCIRESPONSE3);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700764 }
765
Pierre Ossman17b04292007-07-22 22:18:46 +0200766 if (!cmd->data || cmd->error) {
Ulf Hansson3b6e3c72011-12-13 16:58:43 +0100767 if (host->data) {
768 /* Terminate the DMA transfer */
769 if (dma_inprogress(host))
770 mmci_dma_data_error(host);
Russell Kinge47c2222007-01-08 16:42:51 +0000771 mmci_stop_data(host);
Ulf Hansson3b6e3c72011-12-13 16:58:43 +0100772 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700773 mmci_request_end(host, cmd->mrq);
774 } else if (!(cmd->data->flags & MMC_DATA_READ)) {
775 mmci_start_data(host, cmd->data);
776 }
777}
778
779static int mmci_pio_read(struct mmci_host *host, char *buffer, unsigned int remain)
780{
781 void __iomem *base = host->base;
782 char *ptr = buffer;
783 u32 status;
Linus Walleij26eed9a2008-04-26 23:39:44 +0100784 int host_remain = host->size;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700785
786 do {
Linus Walleij26eed9a2008-04-26 23:39:44 +0100787 int count = host_remain - (readl(base + MMCIFIFOCNT) << 2);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700788
789 if (count > remain)
790 count = remain;
791
792 if (count <= 0)
793 break;
794
795 readsl(base + MMCIFIFO, ptr, count >> 2);
796
797 ptr += count;
798 remain -= count;
Linus Walleij26eed9a2008-04-26 23:39:44 +0100799 host_remain -= count;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700800
801 if (remain == 0)
802 break;
803
804 status = readl(base + MMCISTATUS);
805 } while (status & MCI_RXDATAAVLBL);
806
807 return ptr - buffer;
808}
809
810static int mmci_pio_write(struct mmci_host *host, char *buffer, unsigned int remain, u32 status)
811{
Rabin Vincent8301bb62010-08-09 12:57:30 +0100812 struct variant_data *variant = host->variant;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700813 void __iomem *base = host->base;
814 char *ptr = buffer;
815
816 do {
817 unsigned int count, maxcnt;
818
Rabin Vincent8301bb62010-08-09 12:57:30 +0100819 maxcnt = status & MCI_TXFIFOEMPTY ?
820 variant->fifosize : variant->fifohalfsize;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700821 count = min(remain, maxcnt);
822
Linus Walleij34177802010-10-19 12:43:58 +0100823 /*
824 * The ST Micro variant for SDIO transfer sizes
825 * less then 8 bytes should have clock H/W flow
826 * control disabled.
827 */
828 if (variant->sdio &&
829 mmc_card_sdio(host->mmc->card)) {
830 if (count < 8)
831 writel(readl(host->base + MMCICLOCK) &
832 ~variant->clkreg_enable,
833 host->base + MMCICLOCK);
834 else
835 writel(readl(host->base + MMCICLOCK) |
836 variant->clkreg_enable,
837 host->base + MMCICLOCK);
838 }
839
840 /*
841 * SDIO especially may want to send something that is
842 * not divisible by 4 (as opposed to card sectors
843 * etc), and the FIFO only accept full 32-bit writes.
844 * So compensate by adding +3 on the count, a single
845 * byte become a 32bit write, 7 bytes will be two
846 * 32bit writes etc.
847 */
848 writesl(base + MMCIFIFO, ptr, (count + 3) >> 2);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700849
850 ptr += count;
851 remain -= count;
852
853 if (remain == 0)
854 break;
855
856 status = readl(base + MMCISTATUS);
857 } while (status & MCI_TXFIFOHALFEMPTY);
858
859 return ptr - buffer;
860}
861
862/*
863 * PIO data transfer IRQ handler.
864 */
David Howells7d12e782006-10-05 14:55:46 +0100865static irqreturn_t mmci_pio_irq(int irq, void *dev_id)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700866{
867 struct mmci_host *host = dev_id;
Rabin Vincent4ce1d6c2010-07-21 12:44:58 +0100868 struct sg_mapping_iter *sg_miter = &host->sg_miter;
Rabin Vincent8301bb62010-08-09 12:57:30 +0100869 struct variant_data *variant = host->variant;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700870 void __iomem *base = host->base;
Rabin Vincent4ce1d6c2010-07-21 12:44:58 +0100871 unsigned long flags;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700872 u32 status;
873
874 status = readl(base + MMCISTATUS);
875
Linus Walleij64de0282010-02-19 01:09:10 +0100876 dev_dbg(mmc_dev(host->mmc), "irq1 (pio) %08x\n", status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700877
Rabin Vincent4ce1d6c2010-07-21 12:44:58 +0100878 local_irq_save(flags);
879
Linus Torvalds1da177e2005-04-16 15:20:36 -0700880 do {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700881 unsigned int remain, len;
882 char *buffer;
883
884 /*
885 * For write, we only need to test the half-empty flag
886 * here - if the FIFO is completely empty, then by
887 * definition it is more than half empty.
888 *
889 * For read, check for data available.
890 */
891 if (!(status & (MCI_TXFIFOHALFEMPTY|MCI_RXDATAAVLBL)))
892 break;
893
Rabin Vincent4ce1d6c2010-07-21 12:44:58 +0100894 if (!sg_miter_next(sg_miter))
895 break;
896
897 buffer = sg_miter->addr;
898 remain = sg_miter->length;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700899
900 len = 0;
901 if (status & MCI_RXACTIVE)
902 len = mmci_pio_read(host, buffer, remain);
903 if (status & MCI_TXACTIVE)
904 len = mmci_pio_write(host, buffer, remain, status);
905
Rabin Vincent4ce1d6c2010-07-21 12:44:58 +0100906 sg_miter->consumed = len;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700907
Linus Torvalds1da177e2005-04-16 15:20:36 -0700908 host->size -= len;
909 remain -= len;
910
911 if (remain)
912 break;
913
Linus Torvalds1da177e2005-04-16 15:20:36 -0700914 status = readl(base + MMCISTATUS);
915 } while (1);
916
Rabin Vincent4ce1d6c2010-07-21 12:44:58 +0100917 sg_miter_stop(sg_miter);
918
919 local_irq_restore(flags);
920
Linus Torvalds1da177e2005-04-16 15:20:36 -0700921 /*
Russell Kingc4d877c2011-01-27 09:50:13 +0000922 * If we have less than the fifo 'half-full' threshold to transfer,
923 * trigger a PIO interrupt as soon as any data is available.
Linus Torvalds1da177e2005-04-16 15:20:36 -0700924 */
Russell Kingc4d877c2011-01-27 09:50:13 +0000925 if (status & MCI_RXACTIVE && host->size < variant->fifohalfsize)
Linus Walleij2686b4b2010-10-19 12:39:48 +0100926 mmci_set_mask1(host, MCI_RXDATAAVLBLMASK);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700927
928 /*
929 * If we run out of data, disable the data IRQs; this
930 * prevents a race where the FIFO becomes empty before
931 * the chip itself has disabled the data path, and
932 * stops us racing with our data end IRQ.
933 */
934 if (host->size == 0) {
Linus Walleij2686b4b2010-10-19 12:39:48 +0100935 mmci_set_mask1(host, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700936 writel(readl(base + MMCIMASK0) | MCI_DATAENDMASK, base + MMCIMASK0);
937 }
938
939 return IRQ_HANDLED;
940}
941
942/*
943 * Handle completion of command and data transfers.
944 */
David Howells7d12e782006-10-05 14:55:46 +0100945static irqreturn_t mmci_irq(int irq, void *dev_id)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700946{
947 struct mmci_host *host = dev_id;
948 u32 status;
949 int ret = 0;
950
951 spin_lock(&host->lock);
952
953 do {
954 struct mmc_command *cmd;
955 struct mmc_data *data;
956
957 status = readl(host->base + MMCISTATUS);
Linus Walleij2686b4b2010-10-19 12:39:48 +0100958
959 if (host->singleirq) {
960 if (status & readl(host->base + MMCIMASK1))
961 mmci_pio_irq(irq, dev_id);
962
963 status &= ~MCI_IRQ1MASK;
964 }
965
Linus Torvalds1da177e2005-04-16 15:20:36 -0700966 status &= readl(host->base + MMCIMASK0);
967 writel(status, host->base + MMCICLEAR);
968
Linus Walleij64de0282010-02-19 01:09:10 +0100969 dev_dbg(mmc_dev(host->mmc), "irq0 (data+cmd) %08x\n", status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700970
971 data = host->data;
Ulf Hanssonb63038d2011-12-13 16:51:04 +0100972 if (status & (MCI_DATACRCFAIL|MCI_DATATIMEOUT|MCI_STARTBITERR|
973 MCI_TXUNDERRUN|MCI_RXOVERRUN|MCI_DATAEND|
974 MCI_DATABLOCKEND) && data)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700975 mmci_data_irq(host, data, status);
976
977 cmd = host->cmd;
978 if (status & (MCI_CMDCRCFAIL|MCI_CMDTIMEOUT|MCI_CMDSENT|MCI_CMDRESPEND) && cmd)
979 mmci_cmd_irq(host, cmd, status);
980
981 ret = 1;
982 } while (status);
983
984 spin_unlock(&host->lock);
985
986 return IRQ_RETVAL(ret);
987}
988
989static void mmci_request(struct mmc_host *mmc, struct mmc_request *mrq)
990{
991 struct mmci_host *host = mmc_priv(mmc);
Linus Walleij9e943022008-10-24 21:17:50 +0100992 unsigned long flags;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700993
994 WARN_ON(host->mrq != NULL);
995
Nicolas Pitre019a5f52007-10-11 01:06:03 -0400996 if (mrq->data && !is_power_of_2(mrq->data->blksz)) {
Linus Walleij64de0282010-02-19 01:09:10 +0100997 dev_err(mmc_dev(mmc), "unsupported block size (%d bytes)\n",
998 mrq->data->blksz);
Pierre Ossman255d01a2007-07-24 20:38:53 +0200999 mrq->cmd->error = -EINVAL;
1000 mmc_request_done(mmc, mrq);
1001 return;
1002 }
1003
Russell King1c3be362011-08-14 09:17:05 +01001004 pm_runtime_get_sync(mmc_dev(mmc));
1005
Linus Walleij9e943022008-10-24 21:17:50 +01001006 spin_lock_irqsave(&host->lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001007
1008 host->mrq = mrq;
1009
Per Forlin58c7ccb2011-07-01 18:55:24 +02001010 if (mrq->data)
1011 mmci_get_next_data(host, mrq->data);
1012
Linus Torvalds1da177e2005-04-16 15:20:36 -07001013 if (mrq->data && mrq->data->flags & MMC_DATA_READ)
1014 mmci_start_data(host, mrq->data);
1015
1016 mmci_start_command(host, mrq->cmd, 0);
1017
Linus Walleij9e943022008-10-24 21:17:50 +01001018 spin_unlock_irqrestore(&host->lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001019}
1020
1021static void mmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
1022{
1023 struct mmci_host *host = mmc_priv(mmc);
Ulf Hansson7d72a1d2011-12-13 16:54:55 +01001024 struct variant_data *variant = host->variant;
Linus Walleija6a64642009-09-14 12:56:14 +01001025 u32 pwr = 0;
1026 unsigned long flags;
Linus Walleij99fc5132010-09-29 01:08:27 -04001027 int ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001028
Linus Torvalds1da177e2005-04-16 15:20:36 -07001029 switch (ios->power_mode) {
1030 case MMC_POWER_OFF:
Linus Walleij99fc5132010-09-29 01:08:27 -04001031 if (host->vcc)
1032 ret = mmc_regulator_set_ocr(mmc, host->vcc, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001033 break;
1034 case MMC_POWER_UP:
Linus Walleij99fc5132010-09-29 01:08:27 -04001035 if (host->vcc) {
1036 ret = mmc_regulator_set_ocr(mmc, host->vcc, ios->vdd);
1037 if (ret) {
1038 dev_err(mmc_dev(mmc), "unable to set OCR\n");
1039 /*
1040 * The .set_ios() function in the mmc_host_ops
1041 * struct return void, and failing to set the
1042 * power should be rare so we print an error
1043 * and return here.
1044 */
1045 return;
1046 }
1047 }
Rabin Vincentbb8f5632010-07-21 12:53:57 +01001048 if (host->plat->vdd_handler)
1049 pwr |= host->plat->vdd_handler(mmc_dev(mmc), ios->vdd,
1050 ios->power_mode);
Ulf Hansson7d72a1d2011-12-13 16:54:55 +01001051
1052 /*
1053 * The ST Micro variant doesn't have the PL180s MCI_PWR_UP
1054 * and instead uses MCI_PWR_ON so apply whatever value is
1055 * configured in the variant data.
1056 */
1057 pwr |= variant->pwrreg_powerup;
1058
1059 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001060 case MMC_POWER_ON:
1061 pwr |= MCI_PWR_ON;
1062 break;
1063 }
1064
Ulf Hansson4d1a3a02011-12-13 16:57:07 +01001065 if (variant->signal_direction && ios->power_mode != MMC_POWER_OFF) {
1066 /*
1067 * The ST Micro variant has some additional bits
1068 * indicating signal direction for the signals in
1069 * the SD/MMC bus and feedback-clock usage.
1070 */
1071 pwr |= host->plat->sigdir;
1072
1073 if (ios->bus_width == MMC_BUS_WIDTH_4)
1074 pwr &= ~MCI_ST_DATA74DIREN;
1075 else if (ios->bus_width == MMC_BUS_WIDTH_1)
1076 pwr &= (~MCI_ST_DATA74DIREN &
1077 ~MCI_ST_DATA31DIREN &
1078 ~MCI_ST_DATA2DIREN);
1079 }
1080
Linus Walleijcc30d602009-01-04 15:18:54 +01001081 if (ios->bus_mode == MMC_BUSMODE_OPENDRAIN) {
Linus Walleijf17a1f02009-08-04 01:01:02 +01001082 if (host->hw_designer != AMBA_VENDOR_ST)
Linus Walleijcc30d602009-01-04 15:18:54 +01001083 pwr |= MCI_ROD;
1084 else {
1085 /*
1086 * The ST Micro variant use the ROD bit for something
1087 * else and only has OD (Open Drain).
1088 */
1089 pwr |= MCI_OD;
1090 }
1091 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001092
Linus Walleija6a64642009-09-14 12:56:14 +01001093 spin_lock_irqsave(&host->lock, flags);
1094
1095 mmci_set_clkreg(host, ios->clock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001096
1097 if (host->pwr != pwr) {
1098 host->pwr = pwr;
1099 writel(pwr, host->base + MMCIPOWER);
1100 }
Linus Walleija6a64642009-09-14 12:56:14 +01001101
1102 spin_unlock_irqrestore(&host->lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001103}
1104
Russell King89001442009-07-09 15:16:07 +01001105static int mmci_get_ro(struct mmc_host *mmc)
1106{
1107 struct mmci_host *host = mmc_priv(mmc);
1108
1109 if (host->gpio_wp == -ENOSYS)
1110 return -ENOSYS;
1111
Linus Walleij18a063012010-09-12 12:56:44 +01001112 return gpio_get_value_cansleep(host->gpio_wp);
Russell King89001442009-07-09 15:16:07 +01001113}
1114
1115static int mmci_get_cd(struct mmc_host *mmc)
1116{
1117 struct mmci_host *host = mmc_priv(mmc);
Rabin Vincent29719442010-08-09 12:54:43 +01001118 struct mmci_platform_data *plat = host->plat;
Russell King89001442009-07-09 15:16:07 +01001119 unsigned int status;
1120
Rabin Vincent4b8caec2010-08-09 12:56:40 +01001121 if (host->gpio_cd == -ENOSYS) {
1122 if (!plat->status)
1123 return 1; /* Assume always present */
1124
Rabin Vincent29719442010-08-09 12:54:43 +01001125 status = plat->status(mmc_dev(host->mmc));
Rabin Vincent4b8caec2010-08-09 12:56:40 +01001126 } else
Linus Walleij18a063012010-09-12 12:56:44 +01001127 status = !!gpio_get_value_cansleep(host->gpio_cd)
1128 ^ plat->cd_invert;
Russell King89001442009-07-09 15:16:07 +01001129
Russell King74bc8092010-07-29 15:58:59 +01001130 /*
1131 * Use positive logic throughout - status is zero for no card,
1132 * non-zero for card inserted.
1133 */
1134 return status;
Russell King89001442009-07-09 15:16:07 +01001135}
1136
Rabin Vincent148b8b32010-08-09 12:55:48 +01001137static irqreturn_t mmci_cd_irq(int irq, void *dev_id)
1138{
1139 struct mmci_host *host = dev_id;
1140
1141 mmc_detect_change(host->mmc, msecs_to_jiffies(500));
1142
1143 return IRQ_HANDLED;
1144}
1145
David Brownellab7aefd2006-11-12 17:55:30 -08001146static const struct mmc_host_ops mmci_ops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001147 .request = mmci_request,
Per Forlin58c7ccb2011-07-01 18:55:24 +02001148 .pre_req = mmci_pre_request,
1149 .post_req = mmci_post_request,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001150 .set_ios = mmci_set_ios,
Russell King89001442009-07-09 15:16:07 +01001151 .get_ro = mmci_get_ro,
1152 .get_cd = mmci_get_cd,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001153};
1154
Russell Kingaa25afa2011-02-19 15:55:00 +00001155static int __devinit mmci_probe(struct amba_device *dev,
1156 const struct amba_id *id)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001157{
Linus Walleij6ef297f2009-09-22 14:29:36 +01001158 struct mmci_platform_data *plat = dev->dev.platform_data;
Rabin Vincent4956e102010-07-21 12:54:40 +01001159 struct variant_data *variant = id->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001160 struct mmci_host *host;
1161 struct mmc_host *mmc;
1162 int ret;
1163
1164 /* must have platform data */
1165 if (!plat) {
1166 ret = -EINVAL;
1167 goto out;
1168 }
1169
1170 ret = amba_request_regions(dev, DRIVER_NAME);
1171 if (ret)
1172 goto out;
1173
1174 mmc = mmc_alloc_host(sizeof(struct mmci_host), &dev->dev);
1175 if (!mmc) {
1176 ret = -ENOMEM;
1177 goto rel_regions;
1178 }
1179
1180 host = mmc_priv(mmc);
Rabin Vincent4ea580f2009-04-17 08:44:19 +05301181 host->mmc = mmc;
Russell King012b7d32009-07-09 15:13:56 +01001182
Russell King89001442009-07-09 15:16:07 +01001183 host->gpio_wp = -ENOSYS;
1184 host->gpio_cd = -ENOSYS;
Rabin Vincent148b8b32010-08-09 12:55:48 +01001185 host->gpio_cd_irq = -1;
Russell King89001442009-07-09 15:16:07 +01001186
Russell King012b7d32009-07-09 15:13:56 +01001187 host->hw_designer = amba_manf(dev);
1188 host->hw_revision = amba_rev(dev);
Linus Walleij64de0282010-02-19 01:09:10 +01001189 dev_dbg(mmc_dev(mmc), "designer ID = 0x%02x\n", host->hw_designer);
1190 dev_dbg(mmc_dev(mmc), "revision = 0x%01x\n", host->hw_revision);
Russell King012b7d32009-07-09 15:13:56 +01001191
Russell Kingee569c42008-11-30 17:38:14 +00001192 host->clk = clk_get(&dev->dev, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001193 if (IS_ERR(host->clk)) {
1194 ret = PTR_ERR(host->clk);
1195 host->clk = NULL;
1196 goto host_free;
1197 }
1198
Russell King52ca0f32011-09-22 11:36:41 +01001199 ret = clk_prepare(host->clk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001200 if (ret)
Russell Kinga8d35842006-01-03 18:41:37 +00001201 goto clk_free;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001202
Russell King52ca0f32011-09-22 11:36:41 +01001203 ret = clk_enable(host->clk);
1204 if (ret)
1205 goto clk_unprep;
1206
Linus Torvalds1da177e2005-04-16 15:20:36 -07001207 host->plat = plat;
Rabin Vincent4956e102010-07-21 12:54:40 +01001208 host->variant = variant;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001209 host->mclk = clk_get_rate(host->clk);
Linus Walleijc8df9a52008-04-29 09:34:07 +01001210 /*
1211 * According to the spec, mclk is max 100 MHz,
1212 * so we try to adjust the clock down to this,
1213 * (if possible).
1214 */
1215 if (host->mclk > 100000000) {
1216 ret = clk_set_rate(host->clk, 100000000);
1217 if (ret < 0)
1218 goto clk_disable;
1219 host->mclk = clk_get_rate(host->clk);
Linus Walleij64de0282010-02-19 01:09:10 +01001220 dev_dbg(mmc_dev(mmc), "eventual mclk rate: %u Hz\n",
1221 host->mclk);
Linus Walleijc8df9a52008-04-29 09:34:07 +01001222 }
Russell Kingc8ebae32011-01-11 19:35:53 +00001223 host->phybase = dev->res.start;
Linus Walleijdc890c22009-06-07 23:27:31 +01001224 host->base = ioremap(dev->res.start, resource_size(&dev->res));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001225 if (!host->base) {
1226 ret = -ENOMEM;
1227 goto clk_disable;
1228 }
1229
1230 mmc->ops = &mmci_ops;
Linus Walleij7f294e42011-07-08 09:57:15 +01001231 /*
1232 * The ARM and ST versions of the block have slightly different
1233 * clock divider equations which means that the minimum divider
1234 * differs too.
1235 */
1236 if (variant->st_clkdiv)
1237 mmc->f_min = DIV_ROUND_UP(host->mclk, 257);
1238 else
1239 mmc->f_min = DIV_ROUND_UP(host->mclk, 512);
Linus Walleij808d97c2010-04-08 07:39:38 +01001240 /*
1241 * If the platform data supplies a maximum operating
1242 * frequency, this takes precedence. Else, we fall back
1243 * to using the module parameter, which has a (low)
1244 * default value in case it is not specified. Either
1245 * value must not exceed the clock rate into the block,
1246 * of course.
1247 */
1248 if (plat->f_max)
1249 mmc->f_max = min(host->mclk, plat->f_max);
1250 else
1251 mmc->f_max = min(host->mclk, fmax);
Linus Walleij64de0282010-02-19 01:09:10 +01001252 dev_dbg(mmc_dev(mmc), "clocking block at %u Hz\n", mmc->f_max);
1253
Linus Walleij34e84f32009-09-22 14:41:40 +01001254#ifdef CONFIG_REGULATOR
1255 /* If we're using the regulator framework, try to fetch a regulator */
1256 host->vcc = regulator_get(&dev->dev, "vmmc");
1257 if (IS_ERR(host->vcc))
1258 host->vcc = NULL;
1259 else {
1260 int mask = mmc_regulator_get_ocrmask(host->vcc);
1261
1262 if (mask < 0)
1263 dev_err(&dev->dev, "error getting OCR mask (%d)\n",
1264 mask);
1265 else {
1266 host->mmc->ocr_avail = (u32) mask;
1267 if (plat->ocr_mask)
1268 dev_warn(&dev->dev,
1269 "Provided ocr_mask/setpower will not be used "
1270 "(using regulator instead)\n");
1271 }
1272 }
1273#endif
1274 /* Fall back to platform data if no regulator is found */
1275 if (host->vcc == NULL)
1276 mmc->ocr_avail = plat->ocr_mask;
Linus Walleij9e6c82c2009-09-14 12:57:11 +01001277 mmc->caps = plat->capabilities;
Per Forlin5a092622011-11-14 12:02:28 +01001278 mmc->caps2 = plat->capabilities2;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001279
1280 /*
1281 * We can do SGIO
1282 */
Martin K. Petersena36274e2010-09-10 01:33:59 -04001283 mmc->max_segs = NR_SG;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001284
1285 /*
Rabin Vincent08458ef2010-07-21 12:55:59 +01001286 * Since only a certain number of bits are valid in the data length
1287 * register, we must ensure that we don't exceed 2^num-1 bytes in a
1288 * single request.
Linus Torvalds1da177e2005-04-16 15:20:36 -07001289 */
Rabin Vincent08458ef2010-07-21 12:55:59 +01001290 mmc->max_req_size = (1 << variant->datalength_bits) - 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001291
1292 /*
1293 * Set the maximum segment size. Since we aren't doing DMA
1294 * (yet) we are only limited by the data length register.
1295 */
Pierre Ossman55db8902006-11-21 17:55:45 +01001296 mmc->max_seg_size = mmc->max_req_size;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001297
Pierre Ossmanfe4a3c72006-11-21 17:54:23 +01001298 /*
1299 * Block size can be up to 2048 bytes, but must be a power of two.
1300 */
1301 mmc->max_blk_size = 2048;
1302
Pierre Ossman55db8902006-11-21 17:55:45 +01001303 /*
1304 * No limit on the number of blocks transferred.
1305 */
1306 mmc->max_blk_count = mmc->max_req_size;
1307
Linus Torvalds1da177e2005-04-16 15:20:36 -07001308 spin_lock_init(&host->lock);
1309
1310 writel(0, host->base + MMCIMASK0);
1311 writel(0, host->base + MMCIMASK1);
1312 writel(0xfff, host->base + MMCICLEAR);
1313
Russell King89001442009-07-09 15:16:07 +01001314 if (gpio_is_valid(plat->gpio_cd)) {
1315 ret = gpio_request(plat->gpio_cd, DRIVER_NAME " (cd)");
1316 if (ret == 0)
1317 ret = gpio_direction_input(plat->gpio_cd);
1318 if (ret == 0)
1319 host->gpio_cd = plat->gpio_cd;
1320 else if (ret != -ENOSYS)
1321 goto err_gpio_cd;
Rabin Vincent148b8b32010-08-09 12:55:48 +01001322
Linus Walleij17ee0832011-05-05 17:23:10 +01001323 /*
1324 * A gpio pin that will detect cards when inserted and removed
1325 * will most likely want to trigger on the edges if it is
1326 * 0 when ejected and 1 when inserted (or mutatis mutandis
1327 * for the inverted case) so we request triggers on both
1328 * edges.
1329 */
Rabin Vincent148b8b32010-08-09 12:55:48 +01001330 ret = request_any_context_irq(gpio_to_irq(plat->gpio_cd),
Linus Walleij17ee0832011-05-05 17:23:10 +01001331 mmci_cd_irq,
1332 IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
1333 DRIVER_NAME " (cd)", host);
Rabin Vincent148b8b32010-08-09 12:55:48 +01001334 if (ret >= 0)
1335 host->gpio_cd_irq = gpio_to_irq(plat->gpio_cd);
Russell King89001442009-07-09 15:16:07 +01001336 }
1337 if (gpio_is_valid(plat->gpio_wp)) {
1338 ret = gpio_request(plat->gpio_wp, DRIVER_NAME " (wp)");
1339 if (ret == 0)
1340 ret = gpio_direction_input(plat->gpio_wp);
1341 if (ret == 0)
1342 host->gpio_wp = plat->gpio_wp;
1343 else if (ret != -ENOSYS)
1344 goto err_gpio_wp;
1345 }
1346
Rabin Vincent4b8caec2010-08-09 12:56:40 +01001347 if ((host->plat->status || host->gpio_cd != -ENOSYS)
1348 && host->gpio_cd_irq < 0)
Rabin Vincent148b8b32010-08-09 12:55:48 +01001349 mmc->caps |= MMC_CAP_NEEDS_POLL;
1350
Thomas Gleixnerdace1452006-07-01 19:29:38 -07001351 ret = request_irq(dev->irq[0], mmci_irq, IRQF_SHARED, DRIVER_NAME " (cmd)", host);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001352 if (ret)
1353 goto unmap;
1354
Linus Walleij2686b4b2010-10-19 12:39:48 +01001355 if (dev->irq[1] == NO_IRQ)
1356 host->singleirq = true;
1357 else {
1358 ret = request_irq(dev->irq[1], mmci_pio_irq, IRQF_SHARED,
1359 DRIVER_NAME " (pio)", host);
1360 if (ret)
1361 goto irq0_free;
1362 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001363
Linus Walleij8cb28152011-01-24 15:22:13 +01001364 writel(MCI_IRQENABLE, host->base + MMCIMASK0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001365
1366 amba_set_drvdata(dev, mmc);
1367
Russell Kingc8ebae32011-01-11 19:35:53 +00001368 dev_info(&dev->dev, "%s: PL%03x manf %x rev%u at 0x%08llx irq %d,%d (pio)\n",
1369 mmc_hostname(mmc), amba_part(dev), amba_manf(dev),
1370 amba_rev(dev), (unsigned long long)dev->res.start,
1371 dev->irq[0], dev->irq[1]);
1372
1373 mmci_dma_setup(host);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001374
Russell King1c3be362011-08-14 09:17:05 +01001375 pm_runtime_put(&dev->dev);
1376
Russell King8c11a942010-12-28 19:40:40 +00001377 mmc_add_host(mmc);
1378
Linus Torvalds1da177e2005-04-16 15:20:36 -07001379 return 0;
1380
1381 irq0_free:
1382 free_irq(dev->irq[0], host);
1383 unmap:
Russell King89001442009-07-09 15:16:07 +01001384 if (host->gpio_wp != -ENOSYS)
1385 gpio_free(host->gpio_wp);
1386 err_gpio_wp:
Rabin Vincent148b8b32010-08-09 12:55:48 +01001387 if (host->gpio_cd_irq >= 0)
1388 free_irq(host->gpio_cd_irq, host);
Russell King89001442009-07-09 15:16:07 +01001389 if (host->gpio_cd != -ENOSYS)
1390 gpio_free(host->gpio_cd);
1391 err_gpio_cd:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001392 iounmap(host->base);
1393 clk_disable:
1394 clk_disable(host->clk);
Russell King52ca0f32011-09-22 11:36:41 +01001395 clk_unprep:
1396 clk_unprepare(host->clk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001397 clk_free:
1398 clk_put(host->clk);
1399 host_free:
1400 mmc_free_host(mmc);
1401 rel_regions:
1402 amba_release_regions(dev);
1403 out:
1404 return ret;
1405}
1406
Linus Walleij6dc4a472009-03-07 00:23:52 +01001407static int __devexit mmci_remove(struct amba_device *dev)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001408{
1409 struct mmc_host *mmc = amba_get_drvdata(dev);
1410
1411 amba_set_drvdata(dev, NULL);
1412
1413 if (mmc) {
1414 struct mmci_host *host = mmc_priv(mmc);
1415
Russell King1c3be362011-08-14 09:17:05 +01001416 /*
1417 * Undo pm_runtime_put() in probe. We use the _sync
1418 * version here so that we can access the primecell.
1419 */
1420 pm_runtime_get_sync(&dev->dev);
1421
Linus Torvalds1da177e2005-04-16 15:20:36 -07001422 mmc_remove_host(mmc);
1423
1424 writel(0, host->base + MMCIMASK0);
1425 writel(0, host->base + MMCIMASK1);
1426
1427 writel(0, host->base + MMCICOMMAND);
1428 writel(0, host->base + MMCIDATACTRL);
1429
Russell Kingc8ebae32011-01-11 19:35:53 +00001430 mmci_dma_release(host);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001431 free_irq(dev->irq[0], host);
Linus Walleij2686b4b2010-10-19 12:39:48 +01001432 if (!host->singleirq)
1433 free_irq(dev->irq[1], host);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001434
Russell King89001442009-07-09 15:16:07 +01001435 if (host->gpio_wp != -ENOSYS)
1436 gpio_free(host->gpio_wp);
Rabin Vincent148b8b32010-08-09 12:55:48 +01001437 if (host->gpio_cd_irq >= 0)
1438 free_irq(host->gpio_cd_irq, host);
Russell King89001442009-07-09 15:16:07 +01001439 if (host->gpio_cd != -ENOSYS)
1440 gpio_free(host->gpio_cd);
1441
Linus Torvalds1da177e2005-04-16 15:20:36 -07001442 iounmap(host->base);
1443 clk_disable(host->clk);
Russell King52ca0f32011-09-22 11:36:41 +01001444 clk_unprepare(host->clk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001445 clk_put(host->clk);
1446
Linus Walleij99fc5132010-09-29 01:08:27 -04001447 if (host->vcc)
1448 mmc_regulator_set_ocr(mmc, host->vcc, 0);
Linus Walleij34e84f32009-09-22 14:41:40 +01001449 regulator_put(host->vcc);
1450
Linus Torvalds1da177e2005-04-16 15:20:36 -07001451 mmc_free_host(mmc);
1452
1453 amba_release_regions(dev);
1454 }
1455
1456 return 0;
1457}
1458
1459#ifdef CONFIG_PM
Pavel Macheke5378ca2005-04-16 15:25:29 -07001460static int mmci_suspend(struct amba_device *dev, pm_message_t state)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001461{
1462 struct mmc_host *mmc = amba_get_drvdata(dev);
1463 int ret = 0;
1464
1465 if (mmc) {
1466 struct mmci_host *host = mmc_priv(mmc);
1467
Matt Fleming1a13f8f2010-05-26 14:42:08 -07001468 ret = mmc_suspend_host(mmc);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001469 if (ret == 0)
1470 writel(0, host->base + MMCIMASK0);
1471 }
1472
1473 return ret;
1474}
1475
1476static int mmci_resume(struct amba_device *dev)
1477{
1478 struct mmc_host *mmc = amba_get_drvdata(dev);
1479 int ret = 0;
1480
1481 if (mmc) {
1482 struct mmci_host *host = mmc_priv(mmc);
1483
1484 writel(MCI_IRQENABLE, host->base + MMCIMASK0);
1485
1486 ret = mmc_resume_host(mmc);
1487 }
1488
1489 return ret;
1490}
1491#else
1492#define mmci_suspend NULL
1493#define mmci_resume NULL
1494#endif
1495
1496static struct amba_id mmci_ids[] = {
1497 {
1498 .id = 0x00041180,
Pawel Moll768fbc12011-03-11 17:18:07 +00001499 .mask = 0xff0fffff,
Rabin Vincent4956e102010-07-21 12:54:40 +01001500 .data = &variant_arm,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001501 },
1502 {
Pawel Moll768fbc12011-03-11 17:18:07 +00001503 .id = 0x01041180,
1504 .mask = 0xff0fffff,
1505 .data = &variant_arm_extended_fifo,
1506 },
1507 {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001508 .id = 0x00041181,
1509 .mask = 0x000fffff,
Rabin Vincent4956e102010-07-21 12:54:40 +01001510 .data = &variant_arm,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001511 },
Linus Walleijcc30d602009-01-04 15:18:54 +01001512 /* ST Micro variants */
1513 {
1514 .id = 0x00180180,
1515 .mask = 0x00ffffff,
Rabin Vincent4956e102010-07-21 12:54:40 +01001516 .data = &variant_u300,
Linus Walleijcc30d602009-01-04 15:18:54 +01001517 },
1518 {
1519 .id = 0x00280180,
1520 .mask = 0x00ffffff,
Rabin Vincent4956e102010-07-21 12:54:40 +01001521 .data = &variant_u300,
1522 },
1523 {
1524 .id = 0x00480180,
Philippe Langlais1784b152011-03-25 08:51:52 +01001525 .mask = 0xf0ffffff,
Rabin Vincent4956e102010-07-21 12:54:40 +01001526 .data = &variant_ux500,
Linus Walleijcc30d602009-01-04 15:18:54 +01001527 },
Philippe Langlais1784b152011-03-25 08:51:52 +01001528 {
1529 .id = 0x10480180,
1530 .mask = 0xf0ffffff,
1531 .data = &variant_ux500v2,
1532 },
Linus Torvalds1da177e2005-04-16 15:20:36 -07001533 { 0, 0 },
1534};
1535
Dave Martin9f998352011-10-05 15:15:21 +01001536MODULE_DEVICE_TABLE(amba, mmci_ids);
1537
Linus Torvalds1da177e2005-04-16 15:20:36 -07001538static struct amba_driver mmci_driver = {
1539 .drv = {
1540 .name = DRIVER_NAME,
1541 },
1542 .probe = mmci_probe,
Linus Walleij6dc4a472009-03-07 00:23:52 +01001543 .remove = __devexit_p(mmci_remove),
Linus Torvalds1da177e2005-04-16 15:20:36 -07001544 .suspend = mmci_suspend,
1545 .resume = mmci_resume,
1546 .id_table = mmci_ids,
1547};
1548
1549static int __init mmci_init(void)
1550{
1551 return amba_driver_register(&mmci_driver);
1552}
1553
1554static void __exit mmci_exit(void)
1555{
1556 amba_driver_unregister(&mmci_driver);
1557}
1558
1559module_init(mmci_init);
1560module_exit(mmci_exit);
1561module_param(fmax, uint, 0444);
1562
1563MODULE_DESCRIPTION("ARM PrimeCell PL180/181 Multimedia Card Interface driver");
1564MODULE_LICENSE("GPL");