From f6f5c4723639eb506b588ddc903f28f33643caf6 Mon Sep 17 00:00:00 2001 From: lhh Date: Fri, 26 Nov 2010 16:24:21 +0800 Subject: [PATCH] updata rk29 dma sdmmc --- arch/arm/common/pl330.c | 14 ++++++-------- arch/arm/mach-rk29/rk29-pl330.c | 12 ++++++++++++ drivers/mmc/host/rk29_sdmmc.c | 31 +++++++++++++++++-------------- 3 files changed, 35 insertions(+), 22 deletions(-) diff --git a/arch/arm/common/pl330.c b/arch/arm/common/pl330.c index 49a7b1df1301..27098b722da2 100644 --- a/arch/arm/common/pl330.c +++ b/arch/arm/common/pl330.c @@ -991,10 +991,10 @@ static inline int _ldst_devtomem(unsigned dry_run, u8 buf[], int off = 0; while (cyc--) { - off += _emit_WFP(dry_run, &buf[off], SINGLE, pxs->r->peri); - off += _emit_LDP(dry_run, &buf[off], SINGLE, pxs->r->peri); + off += _emit_WFP(dry_run, &buf[off], BURST, pxs->r->peri); + off += _emit_LDP(dry_run, &buf[off], BURST, pxs->r->peri); off += _emit_ST(dry_run, &buf[off], ALWAYS); - off += _emit_FLUSHP(dry_run, &buf[off], pxs->r->peri); + //off += _emit_FLUSHP(dry_run, &buf[off], pxs->r->peri); } return off; @@ -1006,10 +1006,10 @@ static inline int _ldst_memtodev(unsigned dry_run, u8 buf[], int off = 0; while (cyc--) { - off += _emit_WFP(dry_run, &buf[off], SINGLE, pxs->r->peri); + off += _emit_WFP(dry_run, &buf[off], BURST, pxs->r->peri); off += _emit_LD(dry_run, &buf[off], ALWAYS); - off += _emit_STP(dry_run, &buf[off], SINGLE, pxs->r->peri); - off += _emit_FLUSHP(dry_run, &buf[off], pxs->r->peri); + off += _emit_STP(dry_run, &buf[off], BURST, pxs->r->peri); + //off += _emit_FLUSHP(dry_run, &buf[off], pxs->r->peri); } return off; @@ -1435,7 +1435,6 @@ int pl330_update(const struct pl330_info *pi) i++; } } - /* Check which event happened i.e, thread notified */ val = readl(regs + ES); if (pi->pcfg.num_events < 32 @@ -1478,7 +1477,6 @@ int pl330_update(const struct pl330_info *pi) list_add_tail(&rqdone->rqd, &pl330->req_done); } } - /* Now that we are in no hurry, do the callbacks */ while (!list_empty(&pl330->req_done)) { rqdone = container_of(pl330->req_done.next, diff --git a/arch/arm/mach-rk29/rk29-pl330.c b/arch/arm/mach-rk29/rk29-pl330.c index 1970e2fbec32..5522782fb758 100644 --- a/arch/arm/mach-rk29/rk29-pl330.c +++ b/arch/arm/mach-rk29/rk29-pl330.c @@ -409,6 +409,7 @@ static inline void _finish_off(struct rk29_pl330_xfer *xfer, ch = xfer->chan; /* Do callback */ + if (ch->callback_fn) ch->callback_fn(xfer->token, xfer->px.bytes, res); @@ -428,6 +429,7 @@ static inline int rk29_pl330_submit(struct rk29_pl330_chan *ch, return 0; xfer = get_from_queue(ch, 0); + if (xfer) { r->x = &xfer->px; @@ -1069,6 +1071,16 @@ static int pl330_probe(struct platform_device *pdev) ret = request_irq(irq, pl330_irq_handler, 0, dev_name(&pdev->dev), pl330_info); + if(pdev->id == 1){ + request_irq(IRQ_DMAC2_1, pl330_irq_handler, 0, + dev_name(&pdev->dev), pl330_info); + request_irq(IRQ_DMAC2_2, pl330_irq_handler, 0, + dev_name(&pdev->dev), pl330_info); + request_irq(IRQ_DMAC2_3, pl330_irq_handler, 0, + dev_name(&pdev->dev), pl330_info); + request_irq(IRQ_DMAC2_4, pl330_irq_handler, 0, + dev_name(&pdev->dev), pl330_info); + } if (ret) goto probe_err4; diff --git a/drivers/mmc/host/rk29_sdmmc.c b/drivers/mmc/host/rk29_sdmmc.c index edaefe2f639f..7c24cb0d7531 100644 --- a/drivers/mmc/host/rk29_sdmmc.c +++ b/drivers/mmc/host/rk29_sdmmc.c @@ -90,7 +90,7 @@ struct rk29_sdmmc { struct mmc_command *cmd; struct mmc_data *data; int dma_chn; - //dma_addr_t sg_dma; + dma_addr_t dma_addr;; //dma_sg_ll_t *sg_cpu; unsigned int use_dma:1; char dma_name[8]; @@ -300,8 +300,8 @@ static void rk29_sdmmc_set_timeout(struct rk29_sdmmc *host,struct mmc_data *data unsigned timeout; timeout = ns_to_clocks(host->clock, data->timeout_ns) + data->timeout_clks; - - rk29_sdmmc_write(host->regs, SDMMC_TMOUT, (timeout << 8) | (70)); + rk29_sdmmc_write(host->regs, SDMMC_TMOUT, 0xffffffff); + ///rk29_sdmmc_write(host->regs, SDMMC_TMOUT, (timeout << 8) | (70)); } static u32 rk29_sdmmc_prepare_command(struct mmc_host *mmc, @@ -363,7 +363,6 @@ static void send_stop_cmd(struct rk29_sdmmc *host, struct mmc_data *data) static void rk29_sdmmc_dma_cleanup(struct rk29_sdmmc *host) { struct mmc_data *data = host->data; - if (data) dma_unmap_sg(&host->pdev->dev, data->sg, data->sg_len, ((data->flags & MMC_DATA_WRITE) @@ -389,7 +388,7 @@ static void rk29_sdmmc_dma_complete(void *arg, int size, enum rk29_dma_buffresul { struct rk29_sdmmc *host = arg; struct mmc_data *data = host->data; - printk("Enter:%s-----%d dma complete\n",__FUNCTION__,__LINE__); + if(host->use_dma == 0) return; dev_vdbg(&host->pdev->dev, "DMA complete\n"); @@ -397,7 +396,7 @@ static void rk29_sdmmc_dma_complete(void *arg, int size, enum rk29_dma_buffresul printk("%s: sdio dma complete err\n",__FUNCTION__); spin_lock(&host->lock); rk29_sdmmc_dma_cleanup(host); - + /* * If the card was removed, data will be NULL. No point trying * to send the stop command or waiting for NBUSY in this case. @@ -413,13 +412,13 @@ static int rk29_sdmmc_submit_data_dma(struct rk29_sdmmc *host, struct mmc_data * { struct scatterlist *sg; unsigned int i,direction; - + int dma_len=0; if(host->use_dma == 0) return -ENOSYS; /* If we don't have a channel, we can't do DMA */ if (host->dma_chn < 0) return -ENODEV; - + /* * We don't do DMA on "complex" transfers, i.e. with * non-word-aligned buffers or lengths. Also, we don't bother @@ -437,13 +436,16 @@ static int rk29_sdmmc_submit_data_dma(struct rk29_sdmmc *host, struct mmc_data * direction = RK29_DMASRC_HW; else direction = RK29_DMASRC_MEM; - dma_map_sg(&host->pdev->dev, data->sg, data->sg_len, - (data->flags & MMC_DATA_READ)? DMA_FROM_DEVICE : DMA_TO_DEVICE); - rk29_dma_devconfig(host->dma_chn, direction, (unsigned long )(host->regs+SDMMC_DATA)); - rk29_dma_enqueue(host->dma_chn, NULL, data->sg->dma_address, data->sg->length); + + rk29_dma_devconfig(host->dma_chn, direction, (unsigned long )(host->dma_addr)); + + dma_len = dma_map_sg(&host->pdev->dev, data->sg, data->sg_len, + (data->flags & MMC_DATA_READ)? DMA_FROM_DEVICE : DMA_TO_DEVICE); ; + for (i = 0; i < dma_len; i++) { + rk29_dma_enqueue(host->dma_chn, host, sg_dma_address(&data->sg[i]),sg_dma_len(&data->sg[i])); // data->sg->dma_address, data->sg->length); + } rk29_sdmmc_write(host->regs, SDMMC_CTRL, (rk29_sdmmc_read(host->regs, SDMMC_CTRL))|SDMMC_CTRL_DMA_ENABLE);// enable dma rk29_dma_ctrl(host->dma_chn, RK29_DMAOP_START); - printk("Enter:%s-----%d DMA DATA START\n",__FUNCTION__,__LINE__); return 0; } @@ -1219,8 +1221,9 @@ static int rk29_sdmmc_probe(struct platform_device *pdev) } rk29_dma_config(host->dma_chn, 16); rk29_dma_set_buffdone_fn(host->dma_chn, rk29_sdmmc_dma_complete); + host->dma_addr = regs->start + SDMMC_DATA; } - host->bus_hz = 25000000; ////cgu_get_clk_freq(CGU_SB_SD_MMC_CCLK_IN_ID); + host->bus_hz = 40000000; ////cgu_get_clk_freq(CGU_SB_SD_MMC_CCLK_IN_ID); /* reset all blocks */ rk29_sdmmc_write(host->regs, SDMMC_CTRL,(SDMMC_CTRL_RESET | SDMMC_CTRL_FIFO_RESET | SDMMC_CTRL_DMA_RESET)); -- 2.34.1