Initial fifo write should always be 32
allow odd byte count transfers
speed up fof access
Signed-off-by: Troy Kisky <[EMAIL PROTECTED]>
---
drivers/mmc/host/davinci_mmc.c | 86 ++++++++++++++++++++++++++++++++-------
drivers/mmc/host/davinci_mmc.h | 2 +-
2 files changed, 71 insertions(+), 17 deletions(-)
mode change 100644 => 100755 drivers/mmc/host/davinci_mmc.c
mode change 100644 => 100755 drivers/mmc/host/davinci_mmc.h
diff --git a/drivers/mmc/host/davinci_mmc.c b/drivers/mmc/host/davinci_mmc.c
old mode 100644
new mode 100755
index 7fb8023..e36493b
--- 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,64 @@ 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 +379,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 +986,8 @@ 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 +995,8 @@ 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 +1009,9 @@ 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
old mode 100644
new mode 100755
index 5840ccf..ca0f872
--- 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);
--
1.5.4
_______________________________________________
Davinci-linux-open-source mailing list
[email protected]
http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source