Vipin Bhandari <vipin.bhand...@ti.com> writes: > The scatterlist traversal is made proper. The patch has some minor comments > modification and also sets the value written to the DAVINCI_MMCTOR register > properly. The timeout calculation is made proper by deriving it from the > clock values. > > This patch incorporates most of review comments given on LKLM by > Pierre Ossman. > > Signed-off-by: Vipin Bhandari <vipin.bhand...@ti.com>
Thanks, pushing today. Kevin > --- > drivers/mmc/host/davinci_mmc.c | 73 > ++++++++++++++++++++++------------------ > 1 files changed, 40 insertions(+), 33 deletions(-) > > diff --git a/drivers/mmc/host/davinci_mmc.c b/drivers/mmc/host/davinci_mmc.c > index 9b23802..d2193ca 100644 > --- a/drivers/mmc/host/davinci_mmc.c > +++ b/drivers/mmc/host/davinci_mmc.c > @@ -30,6 +30,7 @@ > #include <linux/irq.h> > #include <linux/delay.h> > #include <linux/dma-mapping.h> > +#include <linux/mmc/mmc.h> > > #include <mach/mmc.h> > #include <mach/cpu.h> > @@ -145,7 +146,9 @@ > > #define NR_SG 16 > > +#define DAVINCI_MMC_FIFO_SIZE_BYTE 32 > static unsigned rw_threshold = 32; > +static unsigned ns_in_one_cycle = 1; > module_param(rw_threshold, uint, S_IRUGO); > MODULE_PARM_DESC(rw_threshold, > "Read/Write threshold. Default = 32"); > @@ -194,7 +197,6 @@ struct mmc_davinci_host { > > /* For PIO we walk scatterlists one segment at a time. */ > unsigned int sg_len; > - int sg_idx; > > /* Version of the MMC/SD controller */ > u8 version; > @@ -205,8 +207,7 @@ struct mmc_davinci_host { > static void mmc_davinci_sg_to_buf(struct mmc_davinci_host *host) > { > struct scatterlist *sg; > - > - sg = host->data->sg + host->sg_idx; > + sg = host->data->sg; > host->buffer_bytes_left = sg_dma_len(sg); > host->buffer = sg_virt(sg); > if (host->buffer_bytes_left > host->bytes_left) > @@ -220,8 +221,7 @@ static void davinci_fifo_data_trans(struct > mmc_davinci_host *host, > unsigned int i; > > if (host->buffer_bytes_left == 0) { > - host->sg_idx++; > - BUG_ON(host->sg_idx == host->sg_len); > + host->data->sg = sg_next(host->data->sg); > mmc_davinci_sg_to_buf(host); > } > > @@ -312,10 +312,6 @@ static void mmc_davinci_start_command(struct > mmc_davinci_host *host, > /* Set command index */ > cmd_reg |= cmd->opcode; > > - /* Setting initialize clock */ > - if (cmd->opcode == 0) > - cmd_reg |= MMCCMD_INITCK; > - > /* Enable EDMA transfer triggers */ > if (host->do_dma) > cmd_reg |= MMCCMD_DMATRIG; > @@ -340,7 +336,7 @@ static void mmc_davinci_start_command(struct > mmc_davinci_host *host, > cmd_reg |= MMCCMD_PPLEN; > > /* set Command timeout */ > - writel(0xFFFF, host->base + DAVINCI_MMCTOR); > + writel(0x1FFF, host->base + DAVINCI_MMCTOR); > > /* Enable interrupt (calculate here, defer until FIFO is stuffed). */ > im_val = MMCST0_RSPDNE | MMCST0_CRCRS | MMCST0_TOUTRS; > @@ -358,10 +354,12 @@ static void mmc_davinci_start_command(struct > mmc_davinci_host *host, > > /* > * Before non-DMA WRITE commands the controller needs priming: > - * FIFO should be populated with 32 bytes > + * FIFO should be populated with 32 bytes i.e. whatever is the FIFO size > */ > - if (!host->do_dma && (host->data_dir == DAVINCI_MMC_DATADIR_WRITE)) > - davinci_fifo_data_trans(host, 32); > + if (!host->do_dma && (host->data_dir == DAVINCI_MMC_DATADIR_WRITE) && > + ((cmd->opcode == MMC_WRITE_BLOCK) || > + (cmd->opcode == MMC_WRITE_MULTIPLE_BLOCK))) > + davinci_fifo_data_trans(host, DAVINCI_MMC_FIFO_SIZE_BYTE); > > writel(cmd->arg, host->base + DAVINCI_MMCARGHL); > writel(cmd_reg, host->base + DAVINCI_MMCCMD); > @@ -489,13 +487,14 @@ static void mmc_davinci_send_dma_request(struct > mmc_davinci_host *host, > } > > /* We know sg_len and ccnt will never be out of range because > - * we told the block layer to ensure that it only hands us one > - * scatterlist segment per EDMA PARAM entry. Update the PARAM > + * we told the mmc layer which in turn tells the block layer > + * to ensure that it only hands us one scatterlist segment > + * per EDMA PARAM entry. Update the PARAM > * entries needed for each segment of this scatterlist. > */ > for (slot = channel, link = 0, sg = data->sg, sg_len = host->sg_len; > sg_len-- != 0 && bytes_left; > - sg++, slot = host->links[link++]) { > + sg = sg_next(sg), slot = host->links[link++]) { > u32 buf = sg_dma_address(sg); > unsigned count = sg_dma_len(sg); > > @@ -638,11 +637,7 @@ mmc_davinci_prepare_data(struct mmc_davinci_host *host, > struct mmc_request *req) > data->blocks, data->blksz); > dev_dbg(mmc_dev(host->mmc), " DTO %d cycles + %d ns\n", > data->timeout_clks, data->timeout_ns); > - > - /* Convert ns to clock cycles by assuming 20MHz frequency > - * 1 cycle at 20MHz = 500 ns > - */ > - timeout = data->timeout_clks + data->timeout_ns / 500; > + timeout = data->timeout_clks + data->timeout_ns / ns_in_one_cycle; > if (timeout > 0xffff) > timeout = 0xffff; > > @@ -686,7 +681,6 @@ mmc_davinci_prepare_data(struct mmc_davinci_host *host, > struct mmc_request *req) > host->bytes_left = 0; > } else { > /* Revert to CPU Copy */ > - host->sg_idx = 0; > host->sg_len = data->sg_len; > mmc_davinci_sg_to_buf(host); > } > @@ -736,6 +730,14 @@ static unsigned int calculate_freq_for_card(struct > mmc_davinci_host *host, > if (mmc_freq > mmc_req_freq) > mmc_push_pull = mmc_push_pull + 1; > > + /* Convert ns to clock cycles */ > + if (mmc_req_freq < 400000) > + ns_in_one_cycle = 1000000 / ((cpu_arm_clk > + / (2 * (mmc_push_pull + 1)))/1000); > + else > + ns_in_one_cycle = 1000000 / ((cpu_arm_clk > + / (2 * (mmc_push_pull + 1)))/1000000); > + > return mmc_push_pull; > } > > @@ -762,11 +764,22 @@ static void mmc_davinci_set_ios(struct mmc_host *mmc, > struct mmc_ios *ios) > > if (ios->bus_mode == MMC_BUSMODE_OPENDRAIN) { > u32 temp; > + > + /* Ignoring the init clock value passed for fixing the inter > + * operability with different cards. > + */ > open_drain_freq = ((unsigned int)cpu_arm_clk > / (2 * MMCSD_INIT_CLOCK)) - 1; > - temp = readl(host->base + DAVINCI_MMCCLK) & ~0xFF; > + > + if (open_drain_freq > 0xFF) > + open_drain_freq = 0xFF; > + > + temp = readl(host->base + DAVINCI_MMCCLK) & ~MMCCLK_CLKRT_MASK; > temp |= open_drain_freq; > writel(temp, host->base + DAVINCI_MMCCLK); > + > + /* Convert ns to clock cycles */ > + ns_in_one_cycle = (1000000) / (MMCSD_INIT_CLOCK/1000); > } else { > u32 temp; > mmc_push_pull_freq = calculate_freq_for_card(host, ios->clock); > @@ -863,10 +876,6 @@ davinci_abort_data(struct mmc_davinci_host *host, struct > mmc_data *data) > { > u32 temp; > > - /* record how much data we transferred */ > - temp = readl(host->base + DAVINCI_MMCNBLC); > - data->bytes_xfered += (data->blocks - temp) * data->blksz; > - > /* reset command and data state machines */ > temp = readl(host->base + DAVINCI_MMCCTL); > writel(temp | MMCCTL_CMDRST | MMCCTL_DATRST, > @@ -922,7 +931,7 @@ static irqreturn_t mmc_davinci_irq(int irq, void *dev_id) > davinci_fifo_data_trans(host, host->bytes_left); > } > end_transfer = 1; > - data->bytes_xfered += data->blocks * data->blksz; > + data->bytes_xfered = data->blocks * data->blksz; > } else { > dev_err(mmc_dev(host->mmc), > "DATDNE with no host->data\n"); > @@ -984,9 +993,7 @@ static irqreturn_t mmc_davinci_irq(int irq, void *dev_id) > /* Command CRC error */ > dev_dbg(mmc_dev(host->mmc), "Command CRC error\n"); > if (host->cmd) { > - /* Ignore CMD CRC errors during high speed operation */ > - if (host->mmc->ios.clock <= 25000000) > - host->cmd->error = -EILSEQ; > + host->cmd->error = -EILSEQ; > end_command = 1; > } > } > @@ -1047,7 +1054,7 @@ static void __init init_mmcsd_host(struct > mmc_davinci_host *host) > writel(0, host->base + DAVINCI_MMCCLK); > writel(MMCCLK_CLKEN, host->base + DAVINCI_MMCCLK); > > - writel(0xFFFF, host->base + DAVINCI_MMCTOR); > + writel(0x1FFF, host->base + DAVINCI_MMCTOR); > writel(0xFFFF, host->base + DAVINCI_MMCTOD); > > writel(readl(host->base + DAVINCI_MMCCTL) & ~MMCCTL_DATRST, > @@ -1149,7 +1156,7 @@ static int __init davinci_mmcsd_probe(struct > platform_device *pdev) > mmc->max_seg_size = MAX_CCNT * rw_threshold; > > /* MMC/SD controller limits for multiblock requests */ > - mmc->max_blk_size = 4095; /* BLEN is 11 bits */ > + mmc->max_blk_size = 4095; /* BLEN is 12 bits */ > mmc->max_blk_count = 65535; /* NBLK is 16 bits */ > mmc->max_req_size = mmc->max_blk_size * mmc->max_blk_count; > > -- > 1.5.6 > > _______________________________________________ > Davinci-linux-open-source mailing list > Davinci-linux-open-source@linux.davincidsp.com > http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source _______________________________________________ Davinci-linux-open-source mailing list Davinci-linux-open-source@linux.davincidsp.com http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source