aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRussell King <rmk+kernel@arm.linux.org.uk>2012-04-21 17:41:10 -0400
committerRussell King <rmk+kernel@arm.linux.org.uk>2012-07-31 07:06:23 -0400
commit4e078fbd581a92fa26ba2def4ac8f2a633cdcb5b (patch)
tree6dae1ad3a0ffa44b762d2723ce8ee00e035c01ca
parent3451c06754b5777d227aa99f85c35bdfabac3ca0 (diff)
mmc: omap: remove private DMA API implementation
Remove the private DMA API implementation from omap, making it use entirely the DMA engine API. Tested-by: Tony Lindgren <tony@atomide.com> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
-rw-r--r--drivers/mmc/host/omap.c235
1 files changed, 6 insertions, 229 deletions
diff --git a/drivers/mmc/host/omap.c b/drivers/mmc/host/omap.c
index 25e7efee5733..50e08f03aa65 100644
--- a/drivers/mmc/host/omap.c
+++ b/drivers/mmc/host/omap.c
@@ -101,8 +101,6 @@
101 101
102struct mmc_omap_host; 102struct mmc_omap_host;
103 103
104#define USE_DMA_PRIVATE
105
106struct mmc_omap_slot { 104struct mmc_omap_slot {
107 int id; 105 int id;
108 unsigned int vdd; 106 unsigned int vdd;
@@ -162,12 +160,6 @@ struct mmc_omap_host {
162 unsigned use_dma:1; 160 unsigned use_dma:1;
163 unsigned brs_received:1, dma_done:1; 161 unsigned brs_received:1, dma_done:1;
164 unsigned dma_in_use:1; 162 unsigned dma_in_use:1;
165#ifdef USE_DMA_PRIVATE
166 unsigned dma_is_read:1;
167 int dma_ch;
168 struct timer_list dma_timer;
169 unsigned dma_len;
170#endif
171 spinlock_t dma_lock; 163 spinlock_t dma_lock;
172 164
173 struct mmc_omap_slot *slots[OMAP_MMC_MAX_SLOTS]; 165 struct mmc_omap_slot *slots[OMAP_MMC_MAX_SLOTS];
@@ -419,13 +411,6 @@ mmc_omap_release_dma(struct mmc_omap_host *host, struct mmc_data *data,
419 struct device *dev = mmc_dev(host->mmc); 411 struct device *dev = mmc_dev(host->mmc);
420 struct dma_chan *c; 412 struct dma_chan *c;
421 413
422#ifdef USE_DMA_PRIVATE
423 BUG_ON(host->dma_ch < 0);
424 if (data->error)
425 omap_stop_dma(host->dma_ch);
426 /* Release DMA channel lazily */
427 mod_timer(&host->dma_timer, jiffies + HZ);
428#endif
429 if (data->flags & MMC_DATA_WRITE) { 414 if (data->flags & MMC_DATA_WRITE) {
430 dma_data_dir = DMA_TO_DEVICE; 415 dma_data_dir = DMA_TO_DEVICE;
431 c = host->dma_tx; 416 c = host->dma_tx;
@@ -548,18 +533,6 @@ mmc_omap_end_of_data(struct mmc_omap_host *host, struct mmc_data *data)
548 mmc_omap_xfer_done(host, data); 533 mmc_omap_xfer_done(host, data);
549} 534}
550 535
551#ifdef USE_DMA_PRIVATE
552static void
553mmc_omap_dma_timer(unsigned long data)
554{
555 struct mmc_omap_host *host = (struct mmc_omap_host *) data;
556
557 BUG_ON(host->dma_ch < 0);
558 omap_free_dma(host->dma_ch);
559 host->dma_ch = -1;
560}
561#endif
562
563static void 536static void
564mmc_omap_dma_done(struct mmc_omap_host *host, struct mmc_data *data) 537mmc_omap_dma_done(struct mmc_omap_host *host, struct mmc_data *data)
565{ 538{
@@ -928,163 +901,6 @@ static void mmc_omap_dma_callback(void *priv)
928 mmc_omap_dma_done(host, data); 901 mmc_omap_dma_done(host, data);
929} 902}
930 903
931#ifdef USE_DMA_PRIVATE
932/* Prepare to transfer the next segment of a scatterlist */
933static void
934mmc_omap_prepare_dma(struct mmc_omap_host *host, struct mmc_data *data)
935{
936 int dma_ch = host->dma_ch;
937 unsigned long data_addr;
938 u16 buf, frame;
939 u32 count;
940 struct scatterlist *sg = &data->sg[host->sg_idx];
941 int src_port = 0;
942 int dst_port = 0;
943 int sync_dev = 0;
944
945 data_addr = host->phys_base + OMAP_MMC_REG(host, DATA);
946 frame = data->blksz;
947 count = sg_dma_len(sg);
948
949 if ((data->blocks == 1) && (count > data->blksz))
950 count = frame;
951
952 host->dma_len = count;
953
954 /* FIFO is 16x2 bytes on 15xx, and 32x2 bytes on 16xx and 24xx.
955 * Use 16 or 32 word frames when the blocksize is at least that large.
956 * Blocksize is usually 512 bytes; but not for some SD reads.
957 */
958 if (cpu_is_omap15xx() && frame > 32)
959 frame = 32;
960 else if (frame > 64)
961 frame = 64;
962 count /= frame;
963 frame >>= 1;
964
965 if (!(data->flags & MMC_DATA_WRITE)) {
966 buf = 0x800f | ((frame - 1) << 8);
967
968 if (cpu_class_is_omap1()) {
969 src_port = OMAP_DMA_PORT_TIPB;
970 dst_port = OMAP_DMA_PORT_EMIFF;
971 }
972 if (cpu_is_omap24xx())
973 sync_dev = OMAP24XX_DMA_MMC1_RX;
974
975 omap_set_dma_src_params(dma_ch, src_port,
976 OMAP_DMA_AMODE_CONSTANT,
977 data_addr, 0, 0);
978 omap_set_dma_dest_params(dma_ch, dst_port,
979 OMAP_DMA_AMODE_POST_INC,
980 sg_dma_address(sg), 0, 0);
981 omap_set_dma_dest_data_pack(dma_ch, 1);
982 omap_set_dma_dest_burst_mode(dma_ch, OMAP_DMA_DATA_BURST_4);
983 } else {
984 buf = 0x0f80 | ((frame - 1) << 0);
985
986 if (cpu_class_is_omap1()) {
987 src_port = OMAP_DMA_PORT_EMIFF;
988 dst_port = OMAP_DMA_PORT_TIPB;
989 }
990 if (cpu_is_omap24xx())
991 sync_dev = OMAP24XX_DMA_MMC1_TX;
992
993 omap_set_dma_dest_params(dma_ch, dst_port,
994 OMAP_DMA_AMODE_CONSTANT,
995 data_addr, 0, 0);
996 omap_set_dma_src_params(dma_ch, src_port,
997 OMAP_DMA_AMODE_POST_INC,
998 sg_dma_address(sg), 0, 0);
999 omap_set_dma_src_data_pack(dma_ch, 1);
1000 omap_set_dma_src_burst_mode(dma_ch, OMAP_DMA_DATA_BURST_4);
1001 }
1002
1003 /* Max limit for DMA frame count is 0xffff */
1004 BUG_ON(count > 0xffff);
1005
1006 OMAP_MMC_WRITE(host, BUF, buf);
1007 omap_set_dma_transfer_params(dma_ch, OMAP_DMA_DATA_TYPE_S16,
1008 frame, count, OMAP_DMA_SYNC_FRAME,
1009 sync_dev, 0);
1010}
1011
1012/* A scatterlist segment completed */
1013static void mmc_omap_dma_cb(int lch, u16 ch_status, void *data)
1014{
1015 struct mmc_omap_host *host = (struct mmc_omap_host *) data;
1016 struct mmc_data *mmcdat = host->data;
1017
1018 if (unlikely(host->dma_ch < 0)) {
1019 dev_err(mmc_dev(host->mmc),
1020 "DMA callback while DMA not enabled\n");
1021 return;
1022 }
1023 /* FIXME: We really should do something to _handle_ the errors */
1024 if (ch_status & OMAP1_DMA_TOUT_IRQ) {
1025 dev_err(mmc_dev(host->mmc),"DMA timeout\n");
1026 return;
1027 }
1028 if (ch_status & OMAP_DMA_DROP_IRQ) {
1029 dev_err(mmc_dev(host->mmc), "DMA sync error\n");
1030 return;
1031 }
1032 if (!(ch_status & OMAP_DMA_BLOCK_IRQ)) {
1033 return;
1034 }
1035 mmcdat->bytes_xfered += host->dma_len;
1036 host->sg_idx++;
1037 if (host->sg_idx < host->sg_len) {
1038 mmc_omap_prepare_dma(host, host->data);
1039 omap_start_dma(host->dma_ch);
1040 } else
1041 mmc_omap_dma_done(host, host->data);
1042}
1043
1044static int mmc_omap_get_dma_channel(struct mmc_omap_host *host, struct mmc_data *data)
1045{
1046 const char *dma_dev_name;
1047 int sync_dev, dma_ch, is_read, r;
1048
1049 is_read = !(data->flags & MMC_DATA_WRITE);
1050 del_timer_sync(&host->dma_timer);
1051 if (host->dma_ch >= 0) {
1052 if (is_read == host->dma_is_read)
1053 return 0;
1054 omap_free_dma(host->dma_ch);
1055 host->dma_ch = -1;
1056 }
1057
1058 if (is_read) {
1059 if (host->id == 0) {
1060 sync_dev = OMAP_DMA_MMC_RX;
1061 dma_dev_name = "MMC1 read";
1062 } else {
1063 sync_dev = OMAP_DMA_MMC2_RX;
1064 dma_dev_name = "MMC2 read";
1065 }
1066 } else {
1067 if (host->id == 0) {
1068 sync_dev = OMAP_DMA_MMC_TX;
1069 dma_dev_name = "MMC1 write";
1070 } else {
1071 sync_dev = OMAP_DMA_MMC2_TX;
1072 dma_dev_name = "MMC2 write";
1073 }
1074 }
1075 r = omap_request_dma(sync_dev, dma_dev_name, mmc_omap_dma_cb,
1076 host, &dma_ch);
1077 if (r != 0) {
1078 dev_dbg(mmc_dev(host->mmc), "omap_request_dma() failed with %d\n", r);
1079 return r;
1080 }
1081 host->dma_ch = dma_ch;
1082 host->dma_is_read = is_read;
1083
1084 return 0;
1085}
1086#endif
1087
1088static inline void set_cmd_timeout(struct mmc_omap_host *host, struct mmc_request *req) 904static inline void set_cmd_timeout(struct mmc_omap_host *host, struct mmc_request *req)
1089{ 905{
1090 u16 reg; 906 u16 reg;
@@ -1229,38 +1045,13 @@ mmc_omap_prepare_data(struct mmc_omap_host *host, struct mmc_request *req)
1229 return; 1045 return;
1230 } 1046 }
1231 use_pio: 1047 use_pio:
1232#ifdef USE_DMA_PRIVATE
1233 if (use_dma) {
1234 if (mmc_omap_get_dma_channel(host, data) == 0) {
1235 enum dma_data_direction dma_data_dir;
1236
1237 if (data->flags & MMC_DATA_WRITE)
1238 dma_data_dir = DMA_TO_DEVICE;
1239 else
1240 dma_data_dir = DMA_FROM_DEVICE;
1241
1242 host->sg_len = dma_map_sg(mmc_dev(host->mmc), data->sg,
1243 sg_len, dma_data_dir);
1244 host->total_bytes_left = 0;
1245 mmc_omap_prepare_dma(host, req->data);
1246 host->brs_received = 0;
1247 host->dma_done = 0;
1248 host->dma_in_use = 1;
1249 } else
1250 use_dma = 0;
1251 }
1252#else
1253 use_dma = 0;
1254#endif
1255 1048
1256 /* Revert to PIO? */ 1049 /* Revert to PIO? */
1257 if (!use_dma) { 1050 OMAP_MMC_WRITE(host, BUF, 0x1f1f);
1258 OMAP_MMC_WRITE(host, BUF, 0x1f1f); 1051 host->total_bytes_left = data->blocks * block_size;
1259 host->total_bytes_left = data->blocks * block_size; 1052 host->sg_len = sg_len;
1260 host->sg_len = sg_len; 1053 mmc_omap_sg_to_buf(host);
1261 mmc_omap_sg_to_buf(host); 1054 host->dma_in_use = 0;
1262 host->dma_in_use = 0;
1263 }
1264} 1055}
1265 1056
1266static void mmc_omap_start_request(struct mmc_omap_host *host, 1057static void mmc_omap_start_request(struct mmc_omap_host *host,
@@ -1277,12 +1068,7 @@ static void mmc_omap_start_request(struct mmc_omap_host *host,
1277 struct dma_chan *c = host->data->flags & MMC_DATA_WRITE ? 1068 struct dma_chan *c = host->data->flags & MMC_DATA_WRITE ?
1278 host->dma_tx : host->dma_rx; 1069 host->dma_tx : host->dma_rx;
1279 1070
1280 if (c) 1071 dma_async_issue_pending(c);
1281 dma_async_issue_pending(c);
1282#ifdef USE_DMA_PRIVATE
1283 else
1284 omap_start_dma(host->dma_ch);
1285#endif
1286 } 1072 }
1287} 1073}
1288 1074
@@ -1566,9 +1352,6 @@ static int __devinit mmc_omap_probe(struct platform_device *pdev)
1566 setup_timer(&host->clk_timer, mmc_omap_clk_timer, (unsigned long) host); 1352 setup_timer(&host->clk_timer, mmc_omap_clk_timer, (unsigned long) host);
1567 1353
1568 spin_lock_init(&host->dma_lock); 1354 spin_lock_init(&host->dma_lock);
1569#ifdef USE_DMA_PRIVATE
1570 setup_timer(&host->dma_timer, mmc_omap_dma_timer, (unsigned long) host);
1571#endif
1572 spin_lock_init(&host->slot_lock); 1355 spin_lock_init(&host->slot_lock);
1573 init_waitqueue_head(&host->slot_wq); 1356 init_waitqueue_head(&host->slot_wq);
1574 1357
@@ -1579,13 +1362,7 @@ static int __devinit mmc_omap_probe(struct platform_device *pdev)
1579 host->id = pdev->id; 1362 host->id = pdev->id;
1580 host->mem_res = res; 1363 host->mem_res = res;
1581 host->irq = irq; 1364 host->irq = irq;
1582
1583 host->use_dma = 1; 1365 host->use_dma = 1;
1584#ifdef USE_DMA_PRIVATE
1585 host->dev->dma_mask = &pdata->dma_mask;
1586 host->dma_ch = -1;
1587#endif
1588
1589 host->irq = irq; 1366 host->irq = irq;
1590 host->phys_base = host->mem_res->start; 1367 host->phys_base = host->mem_res->start;
1591 host->virt_base = ioremap(res->start, resource_size(res)); 1368 host->virt_base = ioremap(res->start, resource_size(res));