Re: [U-Boot] [PATCH 08/11] spi: ti_qspi: Use DMA to read from qspi flash

2015-07-21 Thread R, Vignesh


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

2015-07-14 Thread Tom Rini
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

2015-07-09 Thread Vignesh R


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

2015-07-05 Thread Vignesh R


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

2015-07-04 Thread R, Vignesh


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

2015-07-03 Thread Tom Rini
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