aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/mmc/host/omap.c199
-rw-r--r--drivers/mmc/host/omap_hsmmc.c3
2 files changed, 190 insertions, 12 deletions
diff --git a/drivers/mmc/host/omap.c b/drivers/mmc/host/omap.c
index 3e8dcf8d2e05..25e7efee5733 100644
--- a/drivers/mmc/host/omap.c
+++ b/drivers/mmc/host/omap.c
@@ -17,10 +17,12 @@
17#include <linux/ioport.h> 17#include <linux/ioport.h>
18#include <linux/platform_device.h> 18#include <linux/platform_device.h>
19#include <linux/interrupt.h> 19#include <linux/interrupt.h>
20#include <linux/dmaengine.h>
20#include <linux/dma-mapping.h> 21#include <linux/dma-mapping.h>
21#include <linux/delay.h> 22#include <linux/delay.h>
22#include <linux/spinlock.h> 23#include <linux/spinlock.h>
23#include <linux/timer.h> 24#include <linux/timer.h>
25#include <linux/omap-dma.h>
24#include <linux/mmc/host.h> 26#include <linux/mmc/host.h>
25#include <linux/mmc/card.h> 27#include <linux/mmc/card.h>
26#include <linux/clk.h> 28#include <linux/clk.h>
@@ -99,6 +101,8 @@
99 101
100struct mmc_omap_host; 102struct mmc_omap_host;
101 103
104#define USE_DMA_PRIVATE
105
102struct mmc_omap_slot { 106struct mmc_omap_slot {
103 int id; 107 int id;
104 unsigned int vdd; 108 unsigned int vdd;
@@ -128,6 +132,10 @@ struct mmc_omap_host {
128 unsigned char id; /* 16xx chips have 2 MMC blocks */ 132 unsigned char id; /* 16xx chips have 2 MMC blocks */
129 struct clk * iclk; 133 struct clk * iclk;
130 struct clk * fclk; 134 struct clk * fclk;
135 struct dma_chan *dma_rx;
136 u32 dma_rx_burst;
137 struct dma_chan *dma_tx;
138 u32 dma_tx_burst;
131 struct resource *mem_res; 139 struct resource *mem_res;
132 void __iomem *virt_base; 140 void __iomem *virt_base;
133 unsigned int phys_base; 141 unsigned int phys_base;
@@ -153,12 +161,14 @@ struct mmc_omap_host {
153 161
154 unsigned use_dma:1; 162 unsigned use_dma:1;
155 unsigned brs_received:1, dma_done:1; 163 unsigned brs_received:1, dma_done:1;
156 unsigned dma_is_read:1;
157 unsigned dma_in_use:1; 164 unsigned dma_in_use:1;
165#ifdef USE_DMA_PRIVATE
166 unsigned dma_is_read:1;
158 int dma_ch; 167 int dma_ch;
159 spinlock_t dma_lock;
160 struct timer_list dma_timer; 168 struct timer_list dma_timer;
161 unsigned dma_len; 169 unsigned dma_len;
170#endif
171 spinlock_t dma_lock;
162 172
163 struct mmc_omap_slot *slots[OMAP_MMC_MAX_SLOTS]; 173 struct mmc_omap_slot *slots[OMAP_MMC_MAX_SLOTS];
164 struct mmc_omap_slot *current_slot; 174 struct mmc_omap_slot *current_slot;
@@ -406,18 +416,32 @@ mmc_omap_release_dma(struct mmc_omap_host *host, struct mmc_data *data,
406 int abort) 416 int abort)
407{ 417{
408 enum dma_data_direction dma_data_dir; 418 enum dma_data_direction dma_data_dir;
419 struct device *dev = mmc_dev(host->mmc);
420 struct dma_chan *c;
409 421
422#ifdef USE_DMA_PRIVATE
410 BUG_ON(host->dma_ch < 0); 423 BUG_ON(host->dma_ch < 0);
411 if (data->error) 424 if (data->error)
412 omap_stop_dma(host->dma_ch); 425 omap_stop_dma(host->dma_ch);
413 /* Release DMA channel lazily */ 426 /* Release DMA channel lazily */
414 mod_timer(&host->dma_timer, jiffies + HZ); 427 mod_timer(&host->dma_timer, jiffies + HZ);
415 if (data->flags & MMC_DATA_WRITE) 428#endif
429 if (data->flags & MMC_DATA_WRITE) {
416 dma_data_dir = DMA_TO_DEVICE; 430 dma_data_dir = DMA_TO_DEVICE;
417 else 431 c = host->dma_tx;
432 } else {
418 dma_data_dir = DMA_FROM_DEVICE; 433 dma_data_dir = DMA_FROM_DEVICE;
419 dma_unmap_sg(mmc_dev(host->mmc), data->sg, host->sg_len, 434 c = host->dma_rx;
420 dma_data_dir); 435 }
436 if (c) {
437 if (data->error) {
438 dmaengine_terminate_all(c);
439 /* Claim nothing transferred on error... */
440 data->bytes_xfered = 0;
441 }
442 dev = c->device->dev;
443 }
444 dma_unmap_sg(dev, data->sg, host->sg_len, dma_data_dir);
421} 445}
422 446
423static void mmc_omap_send_stop_work(struct work_struct *work) 447static void mmc_omap_send_stop_work(struct work_struct *work)
@@ -524,6 +548,7 @@ mmc_omap_end_of_data(struct mmc_omap_host *host, struct mmc_data *data)
524 mmc_omap_xfer_done(host, data); 548 mmc_omap_xfer_done(host, data);
525} 549}
526 550
551#ifdef USE_DMA_PRIVATE
527static void 552static void
528mmc_omap_dma_timer(unsigned long data) 553mmc_omap_dma_timer(unsigned long data)
529{ 554{
@@ -533,6 +558,7 @@ mmc_omap_dma_timer(unsigned long data)
533 omap_free_dma(host->dma_ch); 558 omap_free_dma(host->dma_ch);
534 host->dma_ch = -1; 559 host->dma_ch = -1;
535} 560}
561#endif
536 562
537static void 563static void
538mmc_omap_dma_done(struct mmc_omap_host *host, struct mmc_data *data) 564mmc_omap_dma_done(struct mmc_omap_host *host, struct mmc_data *data)
@@ -891,6 +917,18 @@ static void mmc_omap_cover_handler(unsigned long param)
891 jiffies + msecs_to_jiffies(OMAP_MMC_COVER_POLL_DELAY)); 917 jiffies + msecs_to_jiffies(OMAP_MMC_COVER_POLL_DELAY));
892} 918}
893 919
920static void mmc_omap_dma_callback(void *priv)
921{
922 struct mmc_omap_host *host = priv;
923 struct mmc_data *data = host->data;
924
925 /* If we got to the end of DMA, assume everything went well */
926 data->bytes_xfered += data->blocks * data->blksz;
927
928 mmc_omap_dma_done(host, data);
929}
930
931#ifdef USE_DMA_PRIVATE
894/* Prepare to transfer the next segment of a scatterlist */ 932/* Prepare to transfer the next segment of a scatterlist */
895static void 933static void
896mmc_omap_prepare_dma(struct mmc_omap_host *host, struct mmc_data *data) 934mmc_omap_prepare_dma(struct mmc_omap_host *host, struct mmc_data *data)
@@ -1045,6 +1083,7 @@ static int mmc_omap_get_dma_channel(struct mmc_omap_host *host, struct mmc_data
1045 1083
1046 return 0; 1084 return 0;
1047} 1085}
1086#endif
1048 1087
1049static inline void set_cmd_timeout(struct mmc_omap_host *host, struct mmc_request *req) 1088static inline void set_cmd_timeout(struct mmc_omap_host *host, struct mmc_request *req)
1050{ 1089{
@@ -1118,6 +1157,80 @@ mmc_omap_prepare_data(struct mmc_omap_host *host, struct mmc_request *req)
1118 1157
1119 host->sg_idx = 0; 1158 host->sg_idx = 0;
1120 if (use_dma) { 1159 if (use_dma) {
1160 enum dma_data_direction dma_data_dir;
1161 struct dma_async_tx_descriptor *tx;
1162 struct dma_chan *c;
1163 u32 burst, *bp;
1164 u16 buf;
1165
1166 /*
1167 * FIFO is 16x2 bytes on 15xx, and 32x2 bytes on 16xx
1168 * and 24xx. Use 16 or 32 word frames when the
1169 * blocksize is at least that large. Blocksize is
1170 * usually 512 bytes; but not for some SD reads.
1171 */
1172 burst = cpu_is_omap15xx() ? 32 : 64;
1173 if (burst > data->blksz)
1174 burst = data->blksz;
1175
1176 burst >>= 1;
1177
1178 if (data->flags & MMC_DATA_WRITE) {
1179 c = host->dma_tx;
1180 bp = &host->dma_tx_burst;
1181 buf = 0x0f80 | (burst - 1) << 0;
1182 dma_data_dir = DMA_TO_DEVICE;
1183 } else {
1184 c = host->dma_rx;
1185 bp = &host->dma_rx_burst;
1186 buf = 0x800f | (burst - 1) << 8;
1187 dma_data_dir = DMA_FROM_DEVICE;
1188 }
1189
1190 if (!c)
1191 goto use_pio;
1192
1193 /* Only reconfigure if we have a different burst size */
1194 if (*bp != burst) {
1195 struct dma_slave_config cfg;
1196
1197 cfg.src_addr = host->phys_base + OMAP_MMC_REG(host, DATA);
1198 cfg.dst_addr = host->phys_base + OMAP_MMC_REG(host, DATA);
1199 cfg.src_addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES;
1200 cfg.dst_addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES;
1201 cfg.src_maxburst = burst;
1202 cfg.dst_maxburst = burst;
1203
1204 if (dmaengine_slave_config(c, &cfg))
1205 goto use_pio;
1206
1207 *bp = burst;
1208 }
1209
1210 host->sg_len = dma_map_sg(c->device->dev, data->sg, sg_len,
1211 dma_data_dir);
1212 if (host->sg_len == 0)
1213 goto use_pio;
1214
1215 tx = dmaengine_prep_slave_sg(c, data->sg, host->sg_len,
1216 data->flags & MMC_DATA_WRITE ? DMA_MEM_TO_DEV : DMA_DEV_TO_MEM,
1217 DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
1218 if (!tx)
1219 goto use_pio;
1220
1221 OMAP_MMC_WRITE(host, BUF, buf);
1222
1223 tx->callback = mmc_omap_dma_callback;
1224 tx->callback_param = host;
1225 dmaengine_submit(tx);
1226 host->brs_received = 0;
1227 host->dma_done = 0;
1228 host->dma_in_use = 1;
1229 return;
1230 }
1231 use_pio:
1232#ifdef USE_DMA_PRIVATE
1233 if (use_dma) {
1121 if (mmc_omap_get_dma_channel(host, data) == 0) { 1234 if (mmc_omap_get_dma_channel(host, data) == 0) {
1122 enum dma_data_direction dma_data_dir; 1235 enum dma_data_direction dma_data_dir;
1123 1236
@@ -1136,6 +1249,9 @@ mmc_omap_prepare_data(struct mmc_omap_host *host, struct mmc_request *req)
1136 } else 1249 } else
1137 use_dma = 0; 1250 use_dma = 0;
1138 } 1251 }
1252#else
1253 use_dma = 0;
1254#endif
1139 1255
1140 /* Revert to PIO? */ 1256 /* Revert to PIO? */
1141 if (!use_dma) { 1257 if (!use_dma) {
@@ -1157,8 +1273,17 @@ static void mmc_omap_start_request(struct mmc_omap_host *host,
1157 /* only touch fifo AFTER the controller readies it */ 1273 /* only touch fifo AFTER the controller readies it */
1158 mmc_omap_prepare_data(host, req); 1274 mmc_omap_prepare_data(host, req);
1159 mmc_omap_start_command(host, req->cmd); 1275 mmc_omap_start_command(host, req->cmd);
1160 if (host->dma_in_use) 1276 if (host->dma_in_use) {
1161 omap_start_dma(host->dma_ch); 1277 struct dma_chan *c = host->data->flags & MMC_DATA_WRITE ?
1278 host->dma_tx : host->dma_rx;
1279
1280 if (c)
1281 dma_async_issue_pending(c);
1282#ifdef USE_DMA_PRIVATE
1283 else
1284 omap_start_dma(host->dma_ch);
1285#endif
1286 }
1162} 1287}
1163 1288
1164static void mmc_omap_request(struct mmc_host *mmc, struct mmc_request *req) 1289static void mmc_omap_request(struct mmc_host *mmc, struct mmc_request *req)
@@ -1400,6 +1525,8 @@ static int __devinit mmc_omap_probe(struct platform_device *pdev)
1400 struct omap_mmc_platform_data *pdata = pdev->dev.platform_data; 1525 struct omap_mmc_platform_data *pdata = pdev->dev.platform_data;
1401 struct mmc_omap_host *host = NULL; 1526 struct mmc_omap_host *host = NULL;
1402 struct resource *res; 1527 struct resource *res;
1528 dma_cap_mask_t mask;
1529 unsigned sig;
1403 int i, ret = 0; 1530 int i, ret = 0;
1404 int irq; 1531 int irq;
1405 1532
@@ -1439,7 +1566,9 @@ static int __devinit mmc_omap_probe(struct platform_device *pdev)
1439 setup_timer(&host->clk_timer, mmc_omap_clk_timer, (unsigned long) host); 1566 setup_timer(&host->clk_timer, mmc_omap_clk_timer, (unsigned long) host);
1440 1567
1441 spin_lock_init(&host->dma_lock); 1568 spin_lock_init(&host->dma_lock);
1569#ifdef USE_DMA_PRIVATE
1442 setup_timer(&host->dma_timer, mmc_omap_dma_timer, (unsigned long) host); 1570 setup_timer(&host->dma_timer, mmc_omap_dma_timer, (unsigned long) host);
1571#endif
1443 spin_lock_init(&host->slot_lock); 1572 spin_lock_init(&host->slot_lock);
1444 init_waitqueue_head(&host->slot_wq); 1573 init_waitqueue_head(&host->slot_wq);
1445 1574
@@ -1452,8 +1581,10 @@ static int __devinit mmc_omap_probe(struct platform_device *pdev)
1452 host->irq = irq; 1581 host->irq = irq;
1453 1582
1454 host->use_dma = 1; 1583 host->use_dma = 1;
1584#ifdef USE_DMA_PRIVATE
1455 host->dev->dma_mask = &pdata->dma_mask; 1585 host->dev->dma_mask = &pdata->dma_mask;
1456 host->dma_ch = -1; 1586 host->dma_ch = -1;
1587#endif
1457 1588
1458 host->irq = irq; 1589 host->irq = irq;
1459 host->phys_base = host->mem_res->start; 1590 host->phys_base = host->mem_res->start;
@@ -1474,9 +1605,48 @@ static int __devinit mmc_omap_probe(struct platform_device *pdev)
1474 goto err_free_iclk; 1605 goto err_free_iclk;
1475 } 1606 }
1476 1607
1608 dma_cap_zero(mask);
1609 dma_cap_set(DMA_SLAVE, mask);
1610
1611 host->dma_tx_burst = -1;
1612 host->dma_rx_burst = -1;
1613
1614 if (cpu_is_omap24xx())
1615 sig = host->id == 0 ? OMAP24XX_DMA_MMC1_TX : OMAP24XX_DMA_MMC2_TX;
1616 else
1617 sig = host->id == 0 ? OMAP_DMA_MMC_TX : OMAP_DMA_MMC2_TX;
1618 host->dma_tx = dma_request_channel(mask, omap_dma_filter_fn, &sig);
1619#if 0
1620 if (!host->dma_tx) {
1621 dev_err(host->dev, "unable to obtain TX DMA engine channel %u\n",
1622 sig);
1623 goto err_dma;
1624 }
1625#else
1626 if (!host->dma_tx)
1627 dev_warn(host->dev, "unable to obtain TX DMA engine channel %u\n",
1628 sig);
1629#endif
1630 if (cpu_is_omap24xx())
1631 sig = host->id == 0 ? OMAP24XX_DMA_MMC1_RX : OMAP24XX_DMA_MMC2_RX;
1632 else
1633 sig = host->id == 0 ? OMAP_DMA_MMC_RX : OMAP_DMA_MMC2_RX;
1634 host->dma_rx = dma_request_channel(mask, omap_dma_filter_fn, &sig);
1635#if 0
1636 if (!host->dma_rx) {
1637 dev_err(host->dev, "unable to obtain RX DMA engine channel %u\n",
1638 sig);
1639 goto err_dma;
1640 }
1641#else
1642 if (!host->dma_rx)
1643 dev_warn(host->dev, "unable to obtain RX DMA engine channel %u\n",
1644 sig);
1645#endif
1646
1477 ret = request_irq(host->irq, mmc_omap_irq, 0, DRIVER_NAME, host); 1647 ret = request_irq(host->irq, mmc_omap_irq, 0, DRIVER_NAME, host);
1478 if (ret) 1648 if (ret)
1479 goto err_free_fclk; 1649 goto err_free_dma;
1480 1650
1481 if (pdata->init != NULL) { 1651 if (pdata->init != NULL) {
1482 ret = pdata->init(&pdev->dev); 1652 ret = pdata->init(&pdev->dev);
@@ -1510,7 +1680,11 @@ err_plat_cleanup:
1510 pdata->cleanup(&pdev->dev); 1680 pdata->cleanup(&pdev->dev);
1511err_free_irq: 1681err_free_irq:
1512 free_irq(host->irq, host); 1682 free_irq(host->irq, host);
1513err_free_fclk: 1683err_free_dma:
1684 if (host->dma_tx)
1685 dma_release_channel(host->dma_tx);
1686 if (host->dma_rx)
1687 dma_release_channel(host->dma_rx);
1514 clk_put(host->fclk); 1688 clk_put(host->fclk);
1515err_free_iclk: 1689err_free_iclk:
1516 clk_disable(host->iclk); 1690 clk_disable(host->iclk);
@@ -1545,6 +1719,11 @@ static int __devexit mmc_omap_remove(struct platform_device *pdev)
1545 clk_disable(host->iclk); 1719 clk_disable(host->iclk);
1546 clk_put(host->iclk); 1720 clk_put(host->iclk);
1547 1721
1722 if (host->dma_tx)
1723 dma_release_channel(host->dma_tx);
1724 if (host->dma_rx)
1725 dma_release_channel(host->dma_rx);
1726
1548 iounmap(host->virt_base); 1727 iounmap(host->virt_base);
1549 release_mem_region(pdev->resource[0].start, 1728 release_mem_region(pdev->resource[0].start,
1550 pdev->resource[0].end - pdev->resource[0].start + 1); 1729 pdev->resource[0].end - pdev->resource[0].start + 1);
diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
index 2b2c98773f15..2338703746a4 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -30,6 +30,7 @@
30#include <linux/of.h> 30#include <linux/of.h>
31#include <linux/of_gpio.h> 31#include <linux/of_gpio.h>
32#include <linux/of_device.h> 32#include <linux/of_device.h>
33#include <linux/omap-dma.h>
33#include <linux/mmc/host.h> 34#include <linux/mmc/host.h>
34#include <linux/mmc/core.h> 35#include <linux/mmc/core.h>
35#include <linux/mmc/mmc.h> 36#include <linux/mmc/mmc.h>
@@ -1766,8 +1767,6 @@ static inline struct omap_mmc_platform_data
1766} 1767}
1767#endif 1768#endif
1768 1769
1769extern bool omap_dma_filter_fn(struct dma_chan *chan, void *param);
1770
1771static int __devinit omap_hsmmc_probe(struct platform_device *pdev) 1770static int __devinit omap_hsmmc_probe(struct platform_device *pdev)
1772{ 1771{
1773 struct omap_mmc_platform_data *pdata = pdev->dev.platform_data; 1772 struct omap_mmc_platform_data *pdata = pdev->dev.platform_data;