Re: [U-Boot] [PATCH 08/11] spi: ti_qspi: Use DMA to read from qspi flash
On 7/15/2015 12:32 AM, Tom Rini wrote: On Thu, Jul 09, 2015 at 12:10:03PM +0530, Vignesh R wrote: On 07/03/2015 05:12 PM, Tom Rini wrote: On Fri, Jul 03, 2015 at 04:46:10PM +0530, Vignesh R wrote: ti_qspi uses memory map mode for faster read. Enabling DMA will increase read speed by 3x @48MHz on DRA74 EVM. Signed-off-by: Vignesh R vigne...@ti.com This ignores the feedback from http://lists.denx.de/pipermail/u-boot/2014-July/183715.html where we need to model the DMA changes on how it's done for mxs_spi.c Is the following patch an acceptable solution? Jagan, are you OK with the SPI side of this? Thanks! Gentle ping... Any comments? I will send a v2 for this series if the below patch is acceptable. 8--- Move DMA related initialization code to helper function in ti-edma3 driver. Use this function for scheduling DMA transfer from ti_qspi driver. diff --git a/arch/arm/include/asm/ti-common/ti-edma3.h b/arch/arm/include/asm/ti-common/ti-edma3.h index 5adc1dac0e65..6a7a321c1bdf 100644 --- a/arch/arm/include/asm/ti-common/ti-edma3.h +++ b/arch/arm/include/asm/ti-common/ti-edma3.h @@ -117,5 +117,7 @@ void edma3_set_src_addr(u32 base, int slot, u32 src); void edma3_set_transfer_params(u32 base, int slot, int acnt, int bcnt, int ccnt, u16 bcnt_rld, enum edma3_sync_dimension sync_mode); +void edma3_transfer(unsigned long edma3_base_addr, unsigned int +edma_slot_num, void *dst, void *src, size_t len); #endif diff --git a/drivers/dma/ti-edma3.c b/drivers/dma/ti-edma3.c index 8184ded9fa81..d6a427f2e21d 100644 --- a/drivers/dma/ti-edma3.c +++ b/drivers/dma/ti-edma3.c @@ -382,3 +382,81 @@ void qedma3_stop(u32 base, struct edma3_channel_config *cfg) /* Clear the channel map */ __raw_writel(0, base + EDMA3_QCHMAP(cfg-chnum)); } + +void edma3_transfer(unsigned long edma3_base_addr, unsigned int +edma_slot_num, void *dst, void *src, size_t len) +{ +struct edma3_slot_configslot; +struct edma3_channel_config edma_channel; +int b_cnt_value = 1; +int rem_bytes = 0; +int a_cnt_value = len; +unsigned intaddr = (unsigned int) (dst); +unsigned intmax_acnt = 0x7FFFU; + +if (len max_acnt) { +b_cnt_value = (len / max_acnt); +rem_bytes = (len % max_acnt); +a_cnt_value = max_acnt; +} + +slot.opt= 0; +slot.src= ((unsigned int) src); +slot.acnt = a_cnt_value; +slot.bcnt = b_cnt_value; +slot.ccnt = 1; +slot.src_bidx = a_cnt_value; +slot.dst_bidx = a_cnt_value; +slot.src_cidx = 0; +slot.dst_cidx = 0; +slot.link = EDMA3_PARSET_NULL_LINK; +slot.bcntrld= 0; +slot.opt= EDMA3_SLOPT_TRANS_COMP_INT_ENB | + EDMA3_SLOPT_COMP_CODE(0) | + EDMA3_SLOPT_STATIC | EDMA3_SLOPT_AB_SYNC; + +edma3_slot_configure(edma3_base_addr, edma_slot_num, slot); +edma_channel.slot = edma_slot_num; +edma_channel.chnum = 0; +edma_channel.complete_code = 0; + /* set event trigger to dst update */ +edma_channel.trigger_slot_word = EDMA3_TWORD(dst); + +qedma3_start(edma3_base_addr, edma_channel); +edma3_set_dest_addr(edma3_base_addr, edma_channel.slot, addr); + +while (edma3_check_for_transfer(edma3_base_addr, edma_channel)) +; +qedma3_stop(edma3_base_addr, edma_channel); + +if (rem_bytes != 0) { +slot.opt= 0; +slot.src= +(b_cnt_value * max_acnt) + ((unsigned int) src); +slot.acnt = rem_bytes; +slot.bcnt = 1; +slot.ccnt = 1; +slot.src_bidx = rem_bytes; +slot.dst_bidx = rem_bytes; +slot.src_cidx = 0; +slot.dst_cidx = 0; +slot.link = EDMA3_PARSET_NULL_LINK; +slot.bcntrld= 0; +slot.opt= EDMA3_SLOPT_TRANS_COMP_INT_ENB | + EDMA3_SLOPT_COMP_CODE(0) | + EDMA3_SLOPT_STATIC | EDMA3_SLOPT_AB_SYNC; +edma3_slot_configure(edma3_base_addr, edma_slot_num, slot); +edma_channel.slot = edma_slot_num; +edma_channel.chnum = 0; +edma_channel.complete_code = 0; +/* set event trigger to dst update */ +edma_channel.trigger_slot_word = EDMA3_TWORD(dst); + +qedma3_start(edma3_base_addr, edma_channel); +edma3_set_dest_addr(edma3_base_addr, edma_channel.slot, addr + +(max_acnt * b_cnt_value)); +
Re: [U-Boot] [PATCH 08/11] spi: ti_qspi: Use DMA to read from qspi flash
On Thu, Jul 09, 2015 at 12:10:03PM +0530, Vignesh R wrote: On 07/03/2015 05:12 PM, Tom Rini wrote: On Fri, Jul 03, 2015 at 04:46:10PM +0530, Vignesh R wrote: ti_qspi uses memory map mode for faster read. Enabling DMA will increase read speed by 3x @48MHz on DRA74 EVM. Signed-off-by: Vignesh R vigne...@ti.com This ignores the feedback from http://lists.denx.de/pipermail/u-boot/2014-July/183715.html where we need to model the DMA changes on how it's done for mxs_spi.c Is the following patch an acceptable solution? Jagan, are you OK with the SPI side of this? Thanks! 8--- Move DMA related initialization code to helper function in ti-edma3 driver. Use this function for scheduling DMA transfer from ti_qspi driver. diff --git a/arch/arm/include/asm/ti-common/ti-edma3.h b/arch/arm/include/asm/ti-common/ti-edma3.h index 5adc1dac0e65..6a7a321c1bdf 100644 --- a/arch/arm/include/asm/ti-common/ti-edma3.h +++ b/arch/arm/include/asm/ti-common/ti-edma3.h @@ -117,5 +117,7 @@ void edma3_set_src_addr(u32 base, int slot, u32 src); void edma3_set_transfer_params(u32 base, int slot, int acnt, int bcnt, int ccnt, u16 bcnt_rld, enum edma3_sync_dimension sync_mode); +void edma3_transfer(unsigned long edma3_base_addr, unsigned int + edma_slot_num, void *dst, void *src, size_t len); #endif diff --git a/drivers/dma/ti-edma3.c b/drivers/dma/ti-edma3.c index 8184ded9fa81..d6a427f2e21d 100644 --- a/drivers/dma/ti-edma3.c +++ b/drivers/dma/ti-edma3.c @@ -382,3 +382,81 @@ void qedma3_stop(u32 base, struct edma3_channel_config *cfg) /* Clear the channel map */ __raw_writel(0, base + EDMA3_QCHMAP(cfg-chnum)); } + +void edma3_transfer(unsigned long edma3_base_addr, unsigned int + edma_slot_num, void *dst, void *src, size_t len) +{ + struct edma3_slot_configslot; + struct edma3_channel_config edma_channel; + int b_cnt_value = 1; + int rem_bytes = 0; + int a_cnt_value = len; + unsigned intaddr = (unsigned int) (dst); + unsigned intmax_acnt = 0x7FFFU; + + if (len max_acnt) { + b_cnt_value = (len / max_acnt); + rem_bytes = (len % max_acnt); + a_cnt_value = max_acnt; + } + + slot.opt= 0; + slot.src= ((unsigned int) src); + slot.acnt = a_cnt_value; + slot.bcnt = b_cnt_value; + slot.ccnt = 1; + slot.src_bidx = a_cnt_value; + slot.dst_bidx = a_cnt_value; + slot.src_cidx = 0; + slot.dst_cidx = 0; + slot.link = EDMA3_PARSET_NULL_LINK; + slot.bcntrld= 0; + slot.opt= EDMA3_SLOPT_TRANS_COMP_INT_ENB | + EDMA3_SLOPT_COMP_CODE(0) | + EDMA3_SLOPT_STATIC | EDMA3_SLOPT_AB_SYNC; + + edma3_slot_configure(edma3_base_addr, edma_slot_num, slot); + edma_channel.slot = edma_slot_num; + edma_channel.chnum = 0; + edma_channel.complete_code = 0; + /* set event trigger to dst update */ + edma_channel.trigger_slot_word = EDMA3_TWORD(dst); + + qedma3_start(edma3_base_addr, edma_channel); + edma3_set_dest_addr(edma3_base_addr, edma_channel.slot, addr); + + while (edma3_check_for_transfer(edma3_base_addr, edma_channel)) + ; + qedma3_stop(edma3_base_addr, edma_channel); + + if (rem_bytes != 0) { + slot.opt= 0; + slot.src= + (b_cnt_value * max_acnt) + ((unsigned int) src); + slot.acnt = rem_bytes; + slot.bcnt = 1; + slot.ccnt = 1; + slot.src_bidx = rem_bytes; + slot.dst_bidx = rem_bytes; + slot.src_cidx = 0; + slot.dst_cidx = 0; + slot.link = EDMA3_PARSET_NULL_LINK; + slot.bcntrld= 0; + slot.opt= EDMA3_SLOPT_TRANS_COMP_INT_ENB | + EDMA3_SLOPT_COMP_CODE(0) | + EDMA3_SLOPT_STATIC | EDMA3_SLOPT_AB_SYNC; + edma3_slot_configure(edma3_base_addr, edma_slot_num, slot); + edma_channel.slot = edma_slot_num; + edma_channel.chnum = 0; + edma_channel.complete_code = 0; + /* set event trigger to dst update */ + edma_channel.trigger_slot_word = EDMA3_TWORD(dst); + + qedma3_start(edma3_base_addr, edma_channel); + edma3_set_dest_addr(edma3_base_addr, edma_channel.slot, addr + + (max_acnt * b_cnt_value)); + while (edma3_check_for_transfer(edma3_base_addr,
Re: [U-Boot] [PATCH 08/11] spi: ti_qspi: Use DMA to read from qspi flash
On 07/03/2015 05:12 PM, Tom Rini wrote: On Fri, Jul 03, 2015 at 04:46:10PM +0530, Vignesh R wrote: ti_qspi uses memory map mode for faster read. Enabling DMA will increase read speed by 3x @48MHz on DRA74 EVM. Signed-off-by: Vignesh R vigne...@ti.com This ignores the feedback from http://lists.denx.de/pipermail/u-boot/2014-July/183715.html where we need to model the DMA changes on how it's done for mxs_spi.c Is the following patch an acceptable solution? 8--- Move DMA related initialization code to helper function in ti-edma3 driver. Use this function for scheduling DMA transfer from ti_qspi driver. diff --git a/arch/arm/include/asm/ti-common/ti-edma3.h b/arch/arm/include/asm/ti-common/ti-edma3.h index 5adc1dac0e65..6a7a321c1bdf 100644 --- a/arch/arm/include/asm/ti-common/ti-edma3.h +++ b/arch/arm/include/asm/ti-common/ti-edma3.h @@ -117,5 +117,7 @@ void edma3_set_src_addr(u32 base, int slot, u32 src); void edma3_set_transfer_params(u32 base, int slot, int acnt, int bcnt, int ccnt, u16 bcnt_rld, enum edma3_sync_dimension sync_mode); +void edma3_transfer(unsigned long edma3_base_addr, unsigned int + edma_slot_num, void *dst, void *src, size_t len); #endif diff --git a/drivers/dma/ti-edma3.c b/drivers/dma/ti-edma3.c index 8184ded9fa81..d6a427f2e21d 100644 --- a/drivers/dma/ti-edma3.c +++ b/drivers/dma/ti-edma3.c @@ -382,3 +382,81 @@ void qedma3_stop(u32 base, struct edma3_channel_config *cfg) /* Clear the channel map */ __raw_writel(0, base + EDMA3_QCHMAP(cfg-chnum)); } + +void edma3_transfer(unsigned long edma3_base_addr, unsigned int + edma_slot_num, void *dst, void *src, size_t len) +{ + struct edma3_slot_configslot; + struct edma3_channel_config edma_channel; + int b_cnt_value = 1; + int rem_bytes = 0; + int a_cnt_value = len; + unsigned intaddr = (unsigned int) (dst); + unsigned intmax_acnt = 0x7FFFU; + + if (len max_acnt) { + b_cnt_value = (len / max_acnt); + rem_bytes = (len % max_acnt); + a_cnt_value = max_acnt; + } + + slot.opt= 0; + slot.src= ((unsigned int) src); + slot.acnt = a_cnt_value; + slot.bcnt = b_cnt_value; + slot.ccnt = 1; + slot.src_bidx = a_cnt_value; + slot.dst_bidx = a_cnt_value; + slot.src_cidx = 0; + slot.dst_cidx = 0; + slot.link = EDMA3_PARSET_NULL_LINK; + slot.bcntrld= 0; + slot.opt= EDMA3_SLOPT_TRANS_COMP_INT_ENB | + EDMA3_SLOPT_COMP_CODE(0) | + EDMA3_SLOPT_STATIC | EDMA3_SLOPT_AB_SYNC; + + edma3_slot_configure(edma3_base_addr, edma_slot_num, slot); + edma_channel.slot = edma_slot_num; + edma_channel.chnum = 0; + edma_channel.complete_code = 0; +/* set event trigger to dst update */ + edma_channel.trigger_slot_word = EDMA3_TWORD(dst); + + qedma3_start(edma3_base_addr, edma_channel); + edma3_set_dest_addr(edma3_base_addr, edma_channel.slot, addr); + + while (edma3_check_for_transfer(edma3_base_addr, edma_channel)) + ; + qedma3_stop(edma3_base_addr, edma_channel); + + if (rem_bytes != 0) { + slot.opt= 0; + slot.src= + (b_cnt_value * max_acnt) + ((unsigned int) src); + slot.acnt = rem_bytes; + slot.bcnt = 1; + slot.ccnt = 1; + slot.src_bidx = rem_bytes; + slot.dst_bidx = rem_bytes; + slot.src_cidx = 0; + slot.dst_cidx = 0; + slot.link = EDMA3_PARSET_NULL_LINK; + slot.bcntrld= 0; + slot.opt= EDMA3_SLOPT_TRANS_COMP_INT_ENB | + EDMA3_SLOPT_COMP_CODE(0) | + EDMA3_SLOPT_STATIC | EDMA3_SLOPT_AB_SYNC; + edma3_slot_configure(edma3_base_addr, edma_slot_num, slot); + edma_channel.slot = edma_slot_num; + edma_channel.chnum = 0; + edma_channel.complete_code = 0; + /* set event trigger to dst update */ + edma_channel.trigger_slot_word = EDMA3_TWORD(dst); + + qedma3_start(edma3_base_addr, edma_channel); + edma3_set_dest_addr(edma3_base_addr, edma_channel.slot, addr + + (max_acnt * b_cnt_value)); + while (edma3_check_for_transfer(edma3_base_addr, edma_channel)) + ; + qedma3_stop(edma3_base_addr, edma_channel); +
Re: [U-Boot] [PATCH 08/11] spi: ti_qspi: Use DMA to read from qspi flash
On Saturday 04 July 2015 06:23 PM, R, Vignesh wrote: On 7/3/2015 5:12 PM, Tom Rini wrote: On Fri, Jul 03, 2015 at 04:46:10PM +0530, Vignesh R wrote: ti_qspi uses memory map mode for faster read. Enabling DMA will increase read speed by 3x @48MHz on DRA74 EVM. Signed-off-by: Vignesh R vigne...@ti.com This ignores the feedback from http://lists.denx.de/pipermail/u-boot/2014-July/183715.html where we need to model the DMA changes on how it's done for mxs_spi.c Sorry.. I didn't look into that before. mxs_spi uses peripheral DMA to read/write flash. But ti_qspi can use DMA to read from flash in mmap mode only. In current u-boot, defining CONFIG_TI_SPI_MMAP will make memory map address available (spi_flash-memory_map) to sf layer and spi_flash_cmd_read_ops() (in sf_ops.c) directly calls memcpy() to read data from flash into buffer. There is no spi_xfer() call to the ti_qspi driver at all. In order to implement mxs_spi like approach for ti_qspi.c, I can delete mmap handling in sf_ops.c( I don't think any other spi driver uses this part of code), so that spi_xfer() is always called. And then, in spi_xfer() implementation of ti_qspi, I can do DMA transfer similar to mxs_spi.c. Is this approach ok? I think I misinterpreted the thread previously. The suggestion is to move DMA initialization related code from to ti-edma3.c and use spi_flash_copy_mmap() just to pass addresses to ti-edma3 apis. Am I correct? -- Regards Vignesh ___ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot
Re: [U-Boot] [PATCH 08/11] spi: ti_qspi: Use DMA to read from qspi flash
On 7/3/2015 5:12 PM, Tom Rini wrote: On Fri, Jul 03, 2015 at 04:46:10PM +0530, Vignesh R wrote: ti_qspi uses memory map mode for faster read. Enabling DMA will increase read speed by 3x @48MHz on DRA74 EVM. Signed-off-by: Vignesh R vigne...@ti.com This ignores the feedback from http://lists.denx.de/pipermail/u-boot/2014-July/183715.html where we need to model the DMA changes on how it's done for mxs_spi.c Sorry.. I didn't look into that before. mxs_spi uses peripheral DMA to read/write flash. But ti_qspi can use DMA to read from flash in mmap mode only. In current u-boot, defining CONFIG_TI_SPI_MMAP will make memory map address available (spi_flash-memory_map) to sf layer and spi_flash_cmd_read_ops() (in sf_ops.c) directly calls memcpy() to read data from flash into buffer. There is no spi_xfer() call to the ti_qspi driver at all. In order to implement mxs_spi like approach for ti_qspi.c, I can delete mmap handling in sf_ops.c( I don't think any other spi driver uses this part of code), so that spi_xfer() is always called. And then, in spi_xfer() implementation of ti_qspi, I can do DMA transfer similar to mxs_spi.c. Is this approach ok? And are you ok with patch 1 and 2 of this series? Regards Vignesh ___ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot
Re: [U-Boot] [PATCH 08/11] spi: ti_qspi: Use DMA to read from qspi flash
On Fri, Jul 03, 2015 at 04:46:10PM +0530, Vignesh R wrote: ti_qspi uses memory map mode for faster read. Enabling DMA will increase read speed by 3x @48MHz on DRA74 EVM. Signed-off-by: Vignesh R vigne...@ti.com This ignores the feedback from http://lists.denx.de/pipermail/u-boot/2014-July/183715.html where we need to model the DMA changes on how it's done for mxs_spi.c -- Tom signature.asc Description: Digital signature ___ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot