davinci-mmc: speed up fifo access,
fix initial fifo write,
allow odd byte count

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

Note: this goes on top of previous patch

diff --git a/drivers/mmc/host/davinci_mmc.c b/drivers/mmc/host/davinci_mmc.c
index 7fb8023..7459649 100644
--- a/drivers/mmc/host/davinci_mmc.c
+++ b/drivers/mmc/host/davinci_mmc.c
@@ -70,7 +70,7 @@ extern void davinci_clean_channel(int ch_no);
 struct device mmc_dev;
 struct clk *mmc_clkp = NULL;
 mmcsd_config_def mmcsd_cfg = {
-/* read write thresholds (in bytes) can be any power of 2 from 2 to 64 */
+/* read write thresholds (in bytes) can be 16/32 */
        32,
 /* To use the DMA or not-- 1- Use DMA, 0-Interrupt mode */
        1,
@@ -281,7 +281,7 @@ static void mmc_davinci_start_command(struct 
mmc_davinci_host *host,
                        && (cmd_type == DAVINCI_MMC_CMDTYPE_ADTC)
                        && (host->do_dma != 1))
                /* Fill the FIFO for Tx */
-               davinci_fifo_data_trans(host);
+               davinci_fifo_data_trans(host,32);

        if (cmd->opcode == 7) {
                spin_lock_irqsave(&mmc_lock, flags);
@@ -314,9 +314,63 @@ static void mmc_davinci_dma_cb(int lch, u16 ch_status, 
void *data)
        }
 }

-static void davinci_fifo_data_trans(struct mmc_davinci_host *host)
+
+#define ReadFifo(pDst,pRegs,cnt) asm ( \
+       "  cmp     %3,#16\n" \
+       "1:        ldrhs   r0,[%1,%2]\n" \
+       "  ldrhs   r1,[%1,%2]\n" \
+       "  ldrhs   r2,[%1,%2]\n" \
+       "  ldrhs   r3,[%1,%2]\n" \
+       "  stmhsia %0!,{r0,r1,r2,r3}\n" \
+       "  beq     3f\n" \
+       "  subhs   %3,%3,#16\n" \
+       "  cmp     %3,#16\n" \
+       "  bhs     1b\n" \
+       "  tst     %3,#0x0c\n" \
+       "2:        ldrne   r0,[%1,%2]\n" \
+       "  strne   r0,[%0],#4\n" \
+       "  subne   %3,%3,#4\n" \
+       "  tst     %3,#0x0c\n" \
+       "  bne     2b\n" \
+       "  tst     %3,#2\n" \
+       "  ldrneh  r0,[%1,%2]\n" \
+       "  strneh  r0,[%0],#2\n" \
+       "  tst     %3,#1\n" \
+       "  ldrneb  r0,[%1,%2]\n" \
+       "  strneb  r0,[%0],#1\n" \
+       "3:\n" \
+        : "+r"(pDst) : "r"(pRegs),"i"(offsetof(mmcsd_regs_base,mmc_drr)),"r"(cnt) : 
"r0","r1","r2","r3" );
+
+#define WriteFifo(pDst,pRegs,cnt) asm ( \
+       "  cmp     %3,#16\n" \
+       "1:        ldmhsia %0!,{r0,r1,r2,r3}\n" \
+       "  strhs   r0,[%1,%2]\n" \
+       "  strhs   r1,[%1,%2]\n" \
+       "  strhs   r2,[%1,%2]\n" \
+       "  strhs   r3,[%1,%2]\n" \
+       "  beq     3f\n" \
+       "  subhs   %3,%3,#16\n" \
+       "  cmp     %3,#16\n" \
+       "  bhs     1b\n" \
+       "  tst     %3,#0x0c\n" \
+       "2:        ldrne   r0,[%0],#4\n" \
+       "  strne   r0,[%1,%2]\n" \
+       "  subne   %3,%3,#4\n" \
+       "  tst     %3,#0x0c\n" \
+       "  bne     2b\n" \
+       "  tst     %3,#2\n" \
+       "  ldrneh  r0,[%0],#2\n" \
+       "  strneh  r0,[%1,%2]\n" \
+       "  tst     %3,#1\n" \
+       "  ldrneb  r0,[%0],#1\n" \
+       "  strneb  r0,[%1,%2]\n" \
+       "3:\n" \
+        : "+r"(pDst) : "r"(pRegs),"i"(offsetof(mmcsd_regs_base,mmc_dxr)),"r"(cnt) : 
"r0","r1","r2","r3" );
+
+
+static void davinci_fifo_data_trans(struct mmc_davinci_host *host, int n)
 {
-       int n, i;
+       unsigned int * p;

        if (host->buffer_bytes_left == 0) {
                host->sg_idx++;
@@ -324,23 +378,18 @@ static void davinci_fifo_data_trans(struct 
mmc_davinci_host *host)
                mmc_davinci_sg_to_buf(host);
        }

-       n = mmcsd_cfg.rw_threshold;
+       p = host->buffer;
        if (n > host->buffer_bytes_left)
                n = host->buffer_bytes_left;
        host->buffer_bytes_left -= n;
        host->bytes_left -= n;

        if (host->data_dir == DAVINCI_MMC_DATADIR_WRITE) {
-               for (i = 0; i < (n / 4); i++) {
-                       mmcsd_regs->mmc_dxr = *host->buffer;
-                       host->buffer++;
-               }
+               WriteFifo(p,mmcsd_regs,n);
        } else {
-               for (i = 0; i < (n / 4); i++) {
-                       *host->buffer = mmcsd_regs->mmc_drr;
-                       host->buffer++;
-               }
+               ReadFifo(p,mmcsd_regs,n);
        }
+       host->buffer = p;
 }

 static void davinci_reinit_chan(void)
@@ -936,7 +985,7 @@ static irqreturn_t mmc_davinci_irq(int irq, void *dev_id)
                                if (status & MMCSD_EVENT_WRITE) {
                                        /* Buffer almost empty */
                                        if (host->bytes_left > 0)
-                                               davinci_fifo_data_trans(host);
+                                               
davinci_fifo_data_trans(host,mmcsd_cfg.rw_threshold);
                                }
                        }

@@ -944,7 +993,7 @@ static irqreturn_t mmc_davinci_irq(int irq, void *dev_id)
                                if (status & MMCSD_EVENT_READ) {
                                        /* Buffer almost empty */
                                        if (host->bytes_left > 0)
-                                               davinci_fifo_data_trans(host);
+                                               
davinci_fifo_data_trans(host,mmcsd_cfg.rw_threshold);
                                }
                        }

@@ -957,7 +1006,7 @@ static irqreturn_t mmc_davinci_irq(int irq, void *dev_id)
                                                /* if datasize<32 no RX ints 
are generated */
                                                if (host->bytes_left > 0) {
                                                        davinci_fifo_data_trans
-                                                           (host);
+                                                           
(host,mmcsd_cfg.rw_threshold);
                                                }
                                                end_transfer = 1;
                                        }
diff --git a/drivers/mmc/host/davinci_mmc.h b/drivers/mmc/host/davinci_mmc.h
index 5840ccf..446191e 100644
--- a/drivers/mmc/host/davinci_mmc.h
+++ b/drivers/mmc/host/davinci_mmc.h
@@ -177,7 +177,7 @@ typedef enum {

 static void init_mmcsd_host(void);

-static void davinci_fifo_data_trans(struct mmc_davinci_host *host);
+static void davinci_fifo_data_trans(struct mmc_davinci_host *host,int n);

 static void mmc_davinci_sg_to_buf(struct mmc_davinci_host *host);

_______________________________________________
Davinci-linux-open-source mailing list
Davinci-linux-open-source@linux.davincidsp.com
http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source

Reply via email to