davinci-mmc: use rw_threshold where appropriate instead of assuming it is 32

Signed-off-by: Troy Kisky <[EMAIL PROTECTED]>

Note: this goes on top of previous patches (repeat, forgot PATCH in subject 
line)


diff --git a/drivers/mmc/host/davinci_mmc.c b/drivers/mmc/host/davinci_mmc.c
index 7459649..615b5eb 100644
--- a/drivers/mmc/host/davinci_mmc.c
+++ b/drivers/mmc/host/davinci_mmc.c
@@ -424,7 +424,7 @@ static int mmc_davinci_start_dma_transfer(struct 
mmc_davinci_host *host,
 {
     int use_dma = 1, i;
     struct mmc_data *data = host->data;
-    int block_size = data->blksz;
+    int mask = mmcsd_cfg.rw_threshold-1;

     host->sg_len = dma_map_sg(mmc_dev(host->mmc), data->sg, host->sg_len,
                 ((data->flags & MMC_DATA_WRITE)
@@ -433,7 +433,7 @@ static int mmc_davinci_start_dma_transfer(struct 
mmc_davinci_host *host,

     /* Decide if we can use DMA */
     for (i = 0; i < host->sg_len; i++) {
-        if ((data->sg[i].length % block_size) != 0) {
+        if (data->sg[i].length & mask) {
             use_dma = 0;
             break;
         }
@@ -555,14 +555,29 @@ static int mmc_davinci_send_dma_request(struct 
mmc_davinci_host *host,
         count = frame;
     }

-    if (count % 32 == 0) {
+    if ((count & (mmcsd_cfg.rw_threshold-1)) == 0) {
+        /* This should always be true due to an earlier check */
         acnt = 4;
-        bcnt = 8;
-        num_frames = count / 32;
-    } else {
-        acnt = count;
-        bcnt = 1;
+        bcnt = mmcsd_cfg.rw_threshold>>2;
+        num_frames = count >> ((mmcsd_cfg.rw_threshold==32)? 5 : 4);
+    } else if ( count < mmcsd_cfg.rw_threshold ) {
+        if ((count&3)==0) {
+            acnt = 4;
+            bcnt = count>>2;
+        } else if ((count&1)==0) {
+            acnt = 2;
+            bcnt = count>>1;
+        } else {
+            acnt = 1;
+            bcnt = count;
+        }
         num_frames = 1;
+    } else {
+        acnt = 4;
+        bcnt = mmcsd_cfg.rw_threshold>>2;
+        num_frames = count >> ((mmcsd_cfg.rw_threshold==32)? 5 : 4);
+        dev_warn(&mmc_dev,
+            "MMC: count of 0x%x unsupported, truncating transfer\n", count);
     }

     if (num_frames > MAX_C_CNT) {
@@ -583,7 +598,7 @@ static int mmc_davinci_send_dma_request(struct 
mmc_davinci_host *host,
         src_bidx = acnt;
         src_cidx = acnt * bcnt;
         dst_port = MMCSD_REGS_BASE_ADDR + 0x2C;
-        mode_dst = INCR;
+        mode_dst = INCR;    /* cannot be FIFO, address not aligned on 32 byte 
boundary */
         fifo_width_dst = W8BIT;    /* It's not cared as modeDsr is INCR */
         dst_bidx = 0;
         dst_cidx = 0;
@@ -594,7 +609,7 @@ static int mmc_davinci_send_dma_request(struct 
mmc_davinci_host *host,
         sync_dev = DAVINCI_DMA_MMCRXEVT;

         src_port = MMCSD_REGS_BASE_ADDR + 0x28;
-        mode_src = INCR;
+        mode_src = INCR;    /* cannot be FIFO, address not aligned on 32 byte 
boundary */
         fifo_width_src = W8BIT;
         src_bidx = 0;
         src_cidx = 0;
@@ -661,7 +676,7 @@ static int mmc_davinci_send_dma_request(struct 
mmc_davinci_host *host,
             if ((data->blocks == 1) && (count > data->blksz))
                 count = frame;

-            ccnt = count / 32;
+            ccnt = count >> ((mmcsd_cfg.rw_threshold==32)? 5 : 4);

             if (sync_dev == DAVINCI_DMA_MMCTXEVT)
                 temp.src = (unsigned int)sg_dma_address(sg);
@@ -690,6 +705,7 @@ static int mmc_davinci_send_dma_request(struct 
mmc_davinci_host *host,
 static void
 mmc_davinci_prepare_data(struct mmc_davinci_host *host, struct mmc_request 
*req)
 {
+    int fifoLev = (mmcsd_cfg.rw_threshold==32)? 4 : 0;
     int timeout, sg_len;
     host->data = req->data;
     if (req->data == NULL) {
@@ -726,16 +742,13 @@ mmc_davinci_prepare_data(struct mmc_davinci_host *host, 
struct mmc_request *req)
     /* Configure the FIFO */
     switch (host->data_dir) {
     case DAVINCI_MMC_DATADIR_WRITE:
-        mmcsd_regs->mmc_fifo_ctl = mmcsd_regs->mmc_fifo_ctl | 0x1;
-        mmcsd_regs->mmc_fifo_ctl = 0x0;
-        mmcsd_regs->mmc_fifo_ctl = mmcsd_regs->mmc_fifo_ctl | (1 << 1);
-        mmcsd_regs->mmc_fifo_ctl = mmcsd_regs->mmc_fifo_ctl | (1 << 2);
+        mmcsd_regs->mmc_fifo_ctl = fifoLev | 3;
+        mmcsd_regs->mmc_fifo_ctl = fifoLev | 2;
         break;

     case DAVINCI_MMC_DATADIR_READ:
-        mmcsd_regs->mmc_fifo_ctl = mmcsd_regs->mmc_fifo_ctl | 0x1;
-        mmcsd_regs->mmc_fifo_ctl = 0x0;
-        mmcsd_regs->mmc_fifo_ctl = mmcsd_regs->mmc_fifo_ctl | (1 << 2);
+        mmcsd_regs->mmc_fifo_ctl = fifoLev | 0x1;
+        mmcsd_regs->mmc_fifo_ctl = fifoLev;
         break;
     default:
         break;
@@ -746,7 +759,7 @@ mmc_davinci_prepare_data(struct mmc_davinci_host *host, 
struct mmc_request *req)

     host->bytes_left = req->data->blocks * req->data->blksz;

-    if ((host->use_dma == 1) && (host->bytes_left % 32 == 0)
+    if ((host->use_dma == 1) && ((host->bytes_left & 
(mmcsd_cfg.rw_threshold-1)) == 0)
         && (mmc_davinci_start_dma_transfer(host, req) == 0)) {
         host->buffer = NULL;
         host->bytes_left = 0;
_______________________________________________
Davinci-linux-open-source mailing list
[email protected]
http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source

Reply via email to