diff mbox

[U-Boot,3/3] sf: ti_qspi: Enable EDMA for reads in SPL

Message ID 1405112025-6103-3-git-send-email-trini@ti.com
State Changes Requested
Delegated to: Jagannadha Sutradharudu Teki
Headers show

Commit Message

Tom Rini July 11, 2014, 8:53 p.m. UTC
From: Vinothkumar Rajendran <vinothr@ti.com>

By default QSPI data through-put in memory mapped mode is ~2.4MB/sec @
48MHz. Added edma memory copy functionality in spi flash driver to
improve the data through put to 5.1MB/Sec.

Signed-off-by: Vinothkumar Rajendran <vinothr@ti.com>
Signed-off-by: Tom Rini <trini@ti.com>
---
 arch/arm/cpu/armv7/omap-common/boot-common.c |    5 ++
 arch/arm/cpu/armv7/omap5/hw_data.c           |    5 +-
 drivers/spi/ti_qspi.c                        |   71 ++++++++++++++++++++++++++
 3 files changed, 79 insertions(+), 2 deletions(-)

Comments

Jagan Teki July 12, 2014, 1:12 p.m. UTC | #1
On Sat, Jul 12, 2014 at 2:23 AM, Tom Rini <trini@ti.com> wrote:
> From: Vinothkumar Rajendran <vinothr@ti.com>
>
> By default QSPI data through-put in memory mapped mode is ~2.4MB/sec @
> 48MHz. Added edma memory copy functionality in spi flash driver to
> improve the data through put to 5.1MB/Sec.
>
> Signed-off-by: Vinothkumar Rajendran <vinothr@ti.com>
> Signed-off-by: Tom Rini <trini@ti.com>
> ---
>  arch/arm/cpu/armv7/omap-common/boot-common.c |    5 ++
>  arch/arm/cpu/armv7/omap5/hw_data.c           |    5 +-
>  drivers/spi/ti_qspi.c                        |   71 ++++++++++++++++++++++++++
>  3 files changed, 79 insertions(+), 2 deletions(-)
>
> diff --git a/arch/arm/cpu/armv7/omap-common/boot-common.c b/arch/arm/cpu/armv7/omap-common/boot-common.c
> index 3033564..636f5d6 100644
> --- a/arch/arm/cpu/armv7/omap-common/boot-common.c
> +++ b/arch/arm/cpu/armv7/omap-common/boot-common.c
> @@ -14,6 +14,7 @@
>  #include <asm/arch/omap.h>
>  #include <asm/arch/mmc_host_def.h>
>  #include <asm/arch/sys_proto.h>
> +#include "../../../../../drivers/dma/ti_edma.h"
>  #include <watchdog.h>
>
>  DECLARE_GLOBAL_DATA_PTR;
> @@ -93,6 +94,10 @@ u32 spl_boot_mode(void)
>
>  void spl_board_init(void)
>  {
> +#if defined(CONFIG_SPL_DMA_SUPPORT) && defined(CONFIG_TI_EDMA)
> +       edma_init(0);
> +       edma_request_channel(1,1,0);
> +#endif
>  #ifdef CONFIG_SPL_NAND_SUPPORT
>         gpmc_init();
>  #endif
> diff --git a/arch/arm/cpu/armv7/omap5/hw_data.c b/arch/arm/cpu/armv7/omap5/hw_data.c
> index a349525..7ee101a 100644
> --- a/arch/arm/cpu/armv7/omap5/hw_data.c
> +++ b/arch/arm/cpu/armv7/omap5/hw_data.c
> @@ -418,6 +418,7 @@ void enable_basic_clocks(void)
>  #ifdef CONFIG_DRIVER_TI_CPSW
>                 (*prcm)->cm_gmac_clkstctrl,
>  #endif
> +               (*prcm)->cm_l3_1_clkstctrl,
>                 0
>         };
>
> @@ -434,6 +435,8 @@ void enable_basic_clocks(void)
>                 (*prcm)->cm_l4per_gpio6_clkctrl,
>                 (*prcm)->cm_l4per_gpio7_clkctrl,
>                 (*prcm)->cm_l4per_gpio8_clkctrl,
> +               (*prcm)->cm_l3main1_tptc1_clkctrl,
> +               (*prcm)->cm_l3main1_tptc2_clkctrl,
>                 0
>         };
>
> @@ -499,8 +502,6 @@ void enable_basic_uboot_clocks(void)
>
>         u32 const clk_modules_hw_auto_essential[] = {
>                 (*prcm)->cm_l3init_hsusbtll_clkctrl,
> -               (*prcm)->cm_l3main1_tptc1_clkctrl,
> -               (*prcm)->cm_l3main1_tptc2_clkctrl,
>                 0
>         };
>
> diff --git a/drivers/spi/ti_qspi.c b/drivers/spi/ti_qspi.c
> index fd7fea8..f2ba75b 100644
> --- a/drivers/spi/ti_qspi.c
> +++ b/drivers/spi/ti_qspi.c
> @@ -13,6 +13,8 @@
>  #include <spi.h>
>  #include <asm/gpio.h>
>  #include <asm/omap_gpio.h>
> +#include <asm/arch/edma.h>
> +#include "../dma/ti_edma.h"

This looks odd to me - header inclusion, as .h in drivers even.

>
>  /* ti qpsi register bit masks */
>  #define QSPI_TIMEOUT                    2000000
> @@ -340,3 +342,72 @@ int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *dout,
>
>         return 0;
>  }
> +
> +#if defined(CONFIG_SPL_DMA_SUPPORT) && defined(CONFIG_TI_EDMA)
> +void spi_flash_copy_mmap(void *data, void *offset, size_t len)
> +{
> +       struct edma_param_entry edma_param;
> +       int           b_cnt_value = 1;
> +       int           rem_bytes  = 0;
> +       int           a_cnt_value = len;
> +       unsigned int          addr      = (unsigned int) (data);
> +       unsigned int          max_acnt  = 0x7FFFU;
> +       unsigned int edma_ch_num = 1;
> +
> +       if (len > max_acnt)
> +       {
> +               b_cnt_value = (len / max_acnt);
> +               rem_bytes  = (len % max_acnt);
> +               a_cnt_value = max_acnt;
> +       }
> +
> +       /* Compute QSPI address and size */
> +       edma_param.opt      = 0;
> +       edma_param.src_addr  = ((unsigned int) offset);
> +       edma_param.dest_addr = addr;
> +       edma_param.a_cnt     = a_cnt_value;
> +       edma_param.b_cnt     = b_cnt_value;
> +       edma_param.c_cnt     = 1;
> +       edma_param.src_bidx  = a_cnt_value;
> +       edma_param.dest_bidx = a_cnt_value;
> +       edma_param.src_cidx  = 0;
> +       edma_param.dest_cidx = 0;
> +       edma_param.link_addr = 0xFFFF;
> +       edma_param.opt     |=
> +               (EDMA_TPCC_OPT_TCINTEN_MASK |
> +                ((edma_ch_num <<
> +                  EDMA_TPCC_OPT_TCC_SHIFT) &
> +                 EDMA_TPCC_OPT_TCC_MASK) | EDMA_TPCC_OPT_SYNCDIM_MASK);
> +
> +       edma_set_param(edma_ch_num, &edma_param);
> +       edma_enable_transfer(edma_ch_num);
> +
> +       while (!(edma_get_intr_status() & (1 << edma_ch_num))) ;
> +       edma_clr_intr(edma_ch_num);
> +       if (rem_bytes != 0)
> +       {
> +               /* Compute QSPI address and size */
> +               edma_param.opt     = 0;
> +               edma_param.src_addr =
> +                       (b_cnt_value * max_acnt) + ((unsigned int) offset);
> +               edma_param.dest_addr = (addr + (max_acnt * b_cnt_value));
> +               edma_param.a_cnt     = rem_bytes;
> +               edma_param.b_cnt     = 1;
> +               edma_param.c_cnt     = 1;
> +               edma_param.src_bidx  = rem_bytes;
> +               edma_param.dest_bidx = rem_bytes;
> +               edma_param.src_cidx  = 0;
> +               edma_param.dest_cidx = 0;
> +               edma_param.link_addr = 0xFFFF;
> +               edma_param.opt     |=
> +                       (EDMA_TPCC_OPT_TCINTEN_MASK |
> +                        ((edma_ch_num << EDMA_TPCC_OPT_TCC_SHIFT) & EDMA_TPCC_OPT_TCC_MASK));
> +               edma_set_param(edma_ch_num, &edma_param);
> +               edma_enable_transfer(edma_ch_num);
> +
> +               while (!(edma_get_intr_status() & (1 << edma_ch_num))) ;
> +               edma_clr_intr(edma_ch_num);
> +       }
> +       *((unsigned int *) offset) += len;
> +}
> +#endif

I'm some how !OK with this memory or flash change in spi driver.
Any better approach to move this - may be in DMA driver itself and
picking up the
memory attributes from sf layer.

I'm not much clear about this now, but will come back again.

thanks!
Tom Rini July 14, 2014, 8:37 p.m. UTC | #2
On Sat, Jul 12, 2014 at 06:42:31PM +0530, Jagan Teki wrote:
> On Sat, Jul 12, 2014 at 2:23 AM, Tom Rini <trini@ti.com> wrote:
> > From: Vinothkumar Rajendran <vinothr@ti.com>
> >
> > By default QSPI data through-put in memory mapped mode is ~2.4MB/sec @
> > 48MHz. Added edma memory copy functionality in spi flash driver to
> > improve the data through put to 5.1MB/Sec.
[snip]
> > +#include <asm/arch/edma.h>
> > +#include "../dma/ti_edma.h"
> 
> This looks odd to me - header inclusion, as .h in drivers even.

I could shove this under arch/arm/include/asm/ti-common I suppose.

> >
> >  /* ti qpsi register bit masks */
> >  #define QSPI_TIMEOUT                    2000000
> > @@ -340,3 +342,72 @@ int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *dout,
> >
> >         return 0;
> >  }
> > +
> > +#if defined(CONFIG_SPL_DMA_SUPPORT) && defined(CONFIG_TI_EDMA)
> > +void spi_flash_copy_mmap(void *data, void *offset, size_t len)
> > +{
> > +       struct edma_param_entry edma_param;
> > +       int           b_cnt_value = 1;
> > +       int           rem_bytes  = 0;
> > +       int           a_cnt_value = len;
> > +       unsigned int          addr      = (unsigned int) (data);
> > +       unsigned int          max_acnt  = 0x7FFFU;
> > +       unsigned int edma_ch_num = 1;
> > +
> > +       if (len > max_acnt)
> > +       {
> > +               b_cnt_value = (len / max_acnt);
> > +               rem_bytes  = (len % max_acnt);
> > +               a_cnt_value = max_acnt;
> > +       }
> > +
> > +       /* Compute QSPI address and size */
> > +       edma_param.opt      = 0;
> > +       edma_param.src_addr  = ((unsigned int) offset);
> > +       edma_param.dest_addr = addr;
> > +       edma_param.a_cnt     = a_cnt_value;
> > +       edma_param.b_cnt     = b_cnt_value;
> > +       edma_param.c_cnt     = 1;
> > +       edma_param.src_bidx  = a_cnt_value;
> > +       edma_param.dest_bidx = a_cnt_value;
> > +       edma_param.src_cidx  = 0;
> > +       edma_param.dest_cidx = 0;
> > +       edma_param.link_addr = 0xFFFF;
> > +       edma_param.opt     |=
> > +               (EDMA_TPCC_OPT_TCINTEN_MASK |
> > +                ((edma_ch_num <<
> > +                  EDMA_TPCC_OPT_TCC_SHIFT) &
> > +                 EDMA_TPCC_OPT_TCC_MASK) | EDMA_TPCC_OPT_SYNCDIM_MASK);
> > +
> > +       edma_set_param(edma_ch_num, &edma_param);
> > +       edma_enable_transfer(edma_ch_num);
> > +
> > +       while (!(edma_get_intr_status() & (1 << edma_ch_num))) ;
> > +       edma_clr_intr(edma_ch_num);
> > +       if (rem_bytes != 0)
> > +       {
> > +               /* Compute QSPI address and size */
> > +               edma_param.opt     = 0;
> > +               edma_param.src_addr =
> > +                       (b_cnt_value * max_acnt) + ((unsigned int) offset);
> > +               edma_param.dest_addr = (addr + (max_acnt * b_cnt_value));
> > +               edma_param.a_cnt     = rem_bytes;
> > +               edma_param.b_cnt     = 1;
> > +               edma_param.c_cnt     = 1;
> > +               edma_param.src_bidx  = rem_bytes;
> > +               edma_param.dest_bidx = rem_bytes;
> > +               edma_param.src_cidx  = 0;
> > +               edma_param.dest_cidx = 0;
> > +               edma_param.link_addr = 0xFFFF;
> > +               edma_param.opt     |=
> > +                       (EDMA_TPCC_OPT_TCINTEN_MASK |
> > +                        ((edma_ch_num << EDMA_TPCC_OPT_TCC_SHIFT) & EDMA_TPCC_OPT_TCC_MASK));
> > +               edma_set_param(edma_ch_num, &edma_param);
> > +               edma_enable_transfer(edma_ch_num);
> > +
> > +               while (!(edma_get_intr_status() & (1 << edma_ch_num))) ;
> > +               edma_clr_intr(edma_ch_num);
> > +       }
> > +       *((unsigned int *) offset) += len;
> > +}
> > +#endif
> 
> I'm some how !OK with this memory or flash change in spi driver.
> Any better approach to move this - may be in DMA driver itself and
> picking up the
> memory attributes from sf layer.
> 
> I'm not much clear about this now, but will come back again.

Well, are you happy with how drivers/spi/mxs_spi.c works (search around
on mxs_dma)?  I can re-jigger things along those lines I suppose.
Tom Rini Jan. 16, 2015, 4 p.m. UTC | #3
On Mon, Jul 14, 2014 at 04:37:36PM -0400, Tom Rini wrote:
> On Sat, Jul 12, 2014 at 06:42:31PM +0530, Jagan Teki wrote:
> > On Sat, Jul 12, 2014 at 2:23 AM, Tom Rini <trini@ti.com> wrote:
> > > From: Vinothkumar Rajendran <vinothr@ti.com>
> > >
> > > By default QSPI data through-put in memory mapped mode is ~2.4MB/sec @
> > > 48MHz. Added edma memory copy functionality in spi flash driver to
> > > improve the data through put to 5.1MB/Sec.
> [snip]
> > > +#include <asm/arch/edma.h>
> > > +#include "../dma/ti_edma.h"
> > 
> > This looks odd to me - header inclusion, as .h in drivers even.
> 
> I could shove this under arch/arm/include/asm/ti-common I suppose.
> 
> > >
> > >  /* ti qpsi register bit masks */
> > >  #define QSPI_TIMEOUT                    2000000
> > > @@ -340,3 +342,72 @@ int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *dout,
> > >
> > >         return 0;
> > >  }
> > > +
> > > +#if defined(CONFIG_SPL_DMA_SUPPORT) && defined(CONFIG_TI_EDMA)
> > > +void spi_flash_copy_mmap(void *data, void *offset, size_t len)
> > > +{
> > > +       struct edma_param_entry edma_param;
> > > +       int           b_cnt_value = 1;
> > > +       int           rem_bytes  = 0;
> > > +       int           a_cnt_value = len;
> > > +       unsigned int          addr      = (unsigned int) (data);
> > > +       unsigned int          max_acnt  = 0x7FFFU;
> > > +       unsigned int edma_ch_num = 1;
> > > +
> > > +       if (len > max_acnt)
> > > +       {
> > > +               b_cnt_value = (len / max_acnt);
> > > +               rem_bytes  = (len % max_acnt);
> > > +               a_cnt_value = max_acnt;
> > > +       }
> > > +
> > > +       /* Compute QSPI address and size */
> > > +       edma_param.opt      = 0;
> > > +       edma_param.src_addr  = ((unsigned int) offset);
> > > +       edma_param.dest_addr = addr;
> > > +       edma_param.a_cnt     = a_cnt_value;
> > > +       edma_param.b_cnt     = b_cnt_value;
> > > +       edma_param.c_cnt     = 1;
> > > +       edma_param.src_bidx  = a_cnt_value;
> > > +       edma_param.dest_bidx = a_cnt_value;
> > > +       edma_param.src_cidx  = 0;
> > > +       edma_param.dest_cidx = 0;
> > > +       edma_param.link_addr = 0xFFFF;
> > > +       edma_param.opt     |=
> > > +               (EDMA_TPCC_OPT_TCINTEN_MASK |
> > > +                ((edma_ch_num <<
> > > +                  EDMA_TPCC_OPT_TCC_SHIFT) &
> > > +                 EDMA_TPCC_OPT_TCC_MASK) | EDMA_TPCC_OPT_SYNCDIM_MASK);
> > > +
> > > +       edma_set_param(edma_ch_num, &edma_param);
> > > +       edma_enable_transfer(edma_ch_num);
> > > +
> > > +       while (!(edma_get_intr_status() & (1 << edma_ch_num))) ;
> > > +       edma_clr_intr(edma_ch_num);
> > > +       if (rem_bytes != 0)
> > > +       {
> > > +               /* Compute QSPI address and size */
> > > +               edma_param.opt     = 0;
> > > +               edma_param.src_addr =
> > > +                       (b_cnt_value * max_acnt) + ((unsigned int) offset);
> > > +               edma_param.dest_addr = (addr + (max_acnt * b_cnt_value));
> > > +               edma_param.a_cnt     = rem_bytes;
> > > +               edma_param.b_cnt     = 1;
> > > +               edma_param.c_cnt     = 1;
> > > +               edma_param.src_bidx  = rem_bytes;
> > > +               edma_param.dest_bidx = rem_bytes;
> > > +               edma_param.src_cidx  = 0;
> > > +               edma_param.dest_cidx = 0;
> > > +               edma_param.link_addr = 0xFFFF;
> > > +               edma_param.opt     |=
> > > +                       (EDMA_TPCC_OPT_TCINTEN_MASK |
> > > +                        ((edma_ch_num << EDMA_TPCC_OPT_TCC_SHIFT) & EDMA_TPCC_OPT_TCC_MASK));
> > > +               edma_set_param(edma_ch_num, &edma_param);
> > > +               edma_enable_transfer(edma_ch_num);
> > > +
> > > +               while (!(edma_get_intr_status() & (1 << edma_ch_num))) ;
> > > +               edma_clr_intr(edma_ch_num);
> > > +       }
> > > +       *((unsigned int *) offset) += len;
> > > +}
> > > +#endif
> > 
> > I'm some how !OK with this memory or flash change in spi driver.
> > Any better approach to move this - may be in DMA driver itself and
> > picking up the
> > memory attributes from sf layer.
> > 
> > I'm not much clear about this now, but will come back again.
> 
> Well, are you happy with how drivers/spi/mxs_spi.c works (search around
> on mxs_dma)?  I can re-jigger things along those lines I suppose.

Ping?  Thanks!
Jagan Teki April 22, 2015, 11:15 a.m. UTC | #4
On 15 July 2014 at 02:07, Tom Rini <trini@ti.com> wrote:
> On Sat, Jul 12, 2014 at 06:42:31PM +0530, Jagan Teki wrote:
>> On Sat, Jul 12, 2014 at 2:23 AM, Tom Rini <trini@ti.com> wrote:
>> > From: Vinothkumar Rajendran <vinothr@ti.com>
>> >
>> > By default QSPI data through-put in memory mapped mode is ~2.4MB/sec @
>> > 48MHz. Added edma memory copy functionality in spi flash driver to
>> > improve the data through put to 5.1MB/Sec.
> [snip]
>> > +#include <asm/arch/edma.h>
>> > +#include "../dma/ti_edma.h"
>>
>> This looks odd to me - header inclusion, as .h in drivers even.
>
> I could shove this under arch/arm/include/asm/ti-common I suppose.

Any changes in code logic or updates?

>
>> >
>> >  /* ti qpsi register bit masks */
>> >  #define QSPI_TIMEOUT                    2000000
>> > @@ -340,3 +342,72 @@ int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *dout,
>> >
>> >         return 0;
>> >  }
>> > +
>> > +#if defined(CONFIG_SPL_DMA_SUPPORT) && defined(CONFIG_TI_EDMA)
>> > +void spi_flash_copy_mmap(void *data, void *offset, size_t len)
>> > +{
>> > +       struct edma_param_entry edma_param;
>> > +       int           b_cnt_value = 1;
>> > +       int           rem_bytes  = 0;
>> > +       int           a_cnt_value = len;
>> > +       unsigned int          addr      = (unsigned int) (data);
>> > +       unsigned int          max_acnt  = 0x7FFFU;
>> > +       unsigned int edma_ch_num = 1;
>> > +
>> > +       if (len > max_acnt)
>> > +       {
>> > +               b_cnt_value = (len / max_acnt);
>> > +               rem_bytes  = (len % max_acnt);
>> > +               a_cnt_value = max_acnt;
>> > +       }
>> > +
>> > +       /* Compute QSPI address and size */
>> > +       edma_param.opt      = 0;
>> > +       edma_param.src_addr  = ((unsigned int) offset);
>> > +       edma_param.dest_addr = addr;
>> > +       edma_param.a_cnt     = a_cnt_value;
>> > +       edma_param.b_cnt     = b_cnt_value;
>> > +       edma_param.c_cnt     = 1;
>> > +       edma_param.src_bidx  = a_cnt_value;
>> > +       edma_param.dest_bidx = a_cnt_value;
>> > +       edma_param.src_cidx  = 0;
>> > +       edma_param.dest_cidx = 0;
>> > +       edma_param.link_addr = 0xFFFF;
>> > +       edma_param.opt     |=
>> > +               (EDMA_TPCC_OPT_TCINTEN_MASK |
>> > +                ((edma_ch_num <<
>> > +                  EDMA_TPCC_OPT_TCC_SHIFT) &
>> > +                 EDMA_TPCC_OPT_TCC_MASK) | EDMA_TPCC_OPT_SYNCDIM_MASK);
>> > +
>> > +       edma_set_param(edma_ch_num, &edma_param);
>> > +       edma_enable_transfer(edma_ch_num);
>> > +
>> > +       while (!(edma_get_intr_status() & (1 << edma_ch_num))) ;
>> > +       edma_clr_intr(edma_ch_num);
>> > +       if (rem_bytes != 0)
>> > +       {
>> > +               /* Compute QSPI address and size */
>> > +               edma_param.opt     = 0;
>> > +               edma_param.src_addr =
>> > +                       (b_cnt_value * max_acnt) + ((unsigned int) offset);
>> > +               edma_param.dest_addr = (addr + (max_acnt * b_cnt_value));
>> > +               edma_param.a_cnt     = rem_bytes;
>> > +               edma_param.b_cnt     = 1;
>> > +               edma_param.c_cnt     = 1;
>> > +               edma_param.src_bidx  = rem_bytes;
>> > +               edma_param.dest_bidx = rem_bytes;
>> > +               edma_param.src_cidx  = 0;
>> > +               edma_param.dest_cidx = 0;
>> > +               edma_param.link_addr = 0xFFFF;
>> > +               edma_param.opt     |=
>> > +                       (EDMA_TPCC_OPT_TCINTEN_MASK |
>> > +                        ((edma_ch_num << EDMA_TPCC_OPT_TCC_SHIFT) & EDMA_TPCC_OPT_TCC_MASK));
>> > +               edma_set_param(edma_ch_num, &edma_param);
>> > +               edma_enable_transfer(edma_ch_num);
>> > +
>> > +               while (!(edma_get_intr_status() & (1 << edma_ch_num))) ;
>> > +               edma_clr_intr(edma_ch_num);
>> > +       }
>> > +       *((unsigned int *) offset) += len;
>> > +}
>> > +#endif
>>
>> I'm some how !OK with this memory or flash change in spi driver.
>> Any better approach to move this - may be in DMA driver itself and
>> picking up the
>> memory attributes from sf layer.
>>
>> I'm not much clear about this now, but will come back again.
>
> Well, are you happy with how drivers/spi/mxs_spi.c works (search around
> on mxs_dma)?  I can re-jigger things along those lines I suppose.

thanks!
Tom Rini April 22, 2015, 2:25 p.m. UTC | #5
On Wed, Apr 22, 2015 at 04:45:05PM +0530, Jagan Teki wrote:
> On 15 July 2014 at 02:07, Tom Rini <trini@ti.com> wrote:
> > On Sat, Jul 12, 2014 at 06:42:31PM +0530, Jagan Teki wrote:
> >> On Sat, Jul 12, 2014 at 2:23 AM, Tom Rini <trini@ti.com> wrote:
> >> > From: Vinothkumar Rajendran <vinothr@ti.com>
> >> >
> >> > By default QSPI data through-put in memory mapped mode is ~2.4MB/sec @
> >> > 48MHz. Added edma memory copy functionality in spi flash driver to
> >> > improve the data through put to 5.1MB/Sec.
> > [snip]
> >> > +#include <asm/arch/edma.h>
> >> > +#include "../dma/ti_edma.h"
> >>
> >> This looks odd to me - header inclusion, as .h in drivers even.
> >
> > I could shove this under arch/arm/include/asm/ti-common I suppose.
> 
> Any changes in code logic or updates?

Since I posted? No, I was waiting for your reply :)

> >> >  /* ti qpsi register bit masks */
> >> >  #define QSPI_TIMEOUT                    2000000
> >> > @@ -340,3 +342,72 @@ int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *dout,
> >> >
> >> >         return 0;
> >> >  }
> >> > +
> >> > +#if defined(CONFIG_SPL_DMA_SUPPORT) && defined(CONFIG_TI_EDMA)
> >> > +void spi_flash_copy_mmap(void *data, void *offset, size_t len)
> >> > +{
> >> > +       struct edma_param_entry edma_param;
> >> > +       int           b_cnt_value = 1;
> >> > +       int           rem_bytes  = 0;
> >> > +       int           a_cnt_value = len;
> >> > +       unsigned int          addr      = (unsigned int) (data);
> >> > +       unsigned int          max_acnt  = 0x7FFFU;
> >> > +       unsigned int edma_ch_num = 1;
> >> > +
> >> > +       if (len > max_acnt)
> >> > +       {
> >> > +               b_cnt_value = (len / max_acnt);
> >> > +               rem_bytes  = (len % max_acnt);
> >> > +               a_cnt_value = max_acnt;
> >> > +       }
> >> > +
> >> > +       /* Compute QSPI address and size */
> >> > +       edma_param.opt      = 0;
> >> > +       edma_param.src_addr  = ((unsigned int) offset);
> >> > +       edma_param.dest_addr = addr;
> >> > +       edma_param.a_cnt     = a_cnt_value;
> >> > +       edma_param.b_cnt     = b_cnt_value;
> >> > +       edma_param.c_cnt     = 1;
> >> > +       edma_param.src_bidx  = a_cnt_value;
> >> > +       edma_param.dest_bidx = a_cnt_value;
> >> > +       edma_param.src_cidx  = 0;
> >> > +       edma_param.dest_cidx = 0;
> >> > +       edma_param.link_addr = 0xFFFF;
> >> > +       edma_param.opt     |=
> >> > +               (EDMA_TPCC_OPT_TCINTEN_MASK |
> >> > +                ((edma_ch_num <<
> >> > +                  EDMA_TPCC_OPT_TCC_SHIFT) &
> >> > +                 EDMA_TPCC_OPT_TCC_MASK) | EDMA_TPCC_OPT_SYNCDIM_MASK);
> >> > +
> >> > +       edma_set_param(edma_ch_num, &edma_param);
> >> > +       edma_enable_transfer(edma_ch_num);
> >> > +
> >> > +       while (!(edma_get_intr_status() & (1 << edma_ch_num))) ;
> >> > +       edma_clr_intr(edma_ch_num);
> >> > +       if (rem_bytes != 0)
> >> > +       {
> >> > +               /* Compute QSPI address and size */
> >> > +               edma_param.opt     = 0;
> >> > +               edma_param.src_addr =
> >> > +                       (b_cnt_value * max_acnt) + ((unsigned int) offset);
> >> > +               edma_param.dest_addr = (addr + (max_acnt * b_cnt_value));
> >> > +               edma_param.a_cnt     = rem_bytes;
> >> > +               edma_param.b_cnt     = 1;
> >> > +               edma_param.c_cnt     = 1;
> >> > +               edma_param.src_bidx  = rem_bytes;
> >> > +               edma_param.dest_bidx = rem_bytes;
> >> > +               edma_param.src_cidx  = 0;
> >> > +               edma_param.dest_cidx = 0;
> >> > +               edma_param.link_addr = 0xFFFF;
> >> > +               edma_param.opt     |=
> >> > +                       (EDMA_TPCC_OPT_TCINTEN_MASK |
> >> > +                        ((edma_ch_num << EDMA_TPCC_OPT_TCC_SHIFT) & EDMA_TPCC_OPT_TCC_MASK));
> >> > +               edma_set_param(edma_ch_num, &edma_param);
> >> > +               edma_enable_transfer(edma_ch_num);
> >> > +
> >> > +               while (!(edma_get_intr_status() & (1 << edma_ch_num))) ;
> >> > +               edma_clr_intr(edma_ch_num);
> >> > +       }
> >> > +       *((unsigned int *) offset) += len;
> >> > +}
> >> > +#endif
> >>
> >> I'm some how !OK with this memory or flash change in spi driver.
> >> Any better approach to move this - may be in DMA driver itself and
> >> picking up the
> >> memory attributes from sf layer.
> >>
> >> I'm not much clear about this now, but will come back again.
> >
> > Well, are you happy with how drivers/spi/mxs_spi.c works (search around
> > on mxs_dma)?  I can re-jigger things along those lines I suppose.
> 
> thanks!

So you're happy with how mxs_spi.c does DMA then?  I'll pencil in some
time to rework this code using that driver as a model then, thanks.
diff mbox

Patch

diff --git a/arch/arm/cpu/armv7/omap-common/boot-common.c b/arch/arm/cpu/armv7/omap-common/boot-common.c
index 3033564..636f5d6 100644
--- a/arch/arm/cpu/armv7/omap-common/boot-common.c
+++ b/arch/arm/cpu/armv7/omap-common/boot-common.c
@@ -14,6 +14,7 @@ 
 #include <asm/arch/omap.h>
 #include <asm/arch/mmc_host_def.h>
 #include <asm/arch/sys_proto.h>
+#include "../../../../../drivers/dma/ti_edma.h"
 #include <watchdog.h>
 
 DECLARE_GLOBAL_DATA_PTR;
@@ -93,6 +94,10 @@  u32 spl_boot_mode(void)
 
 void spl_board_init(void)
 {
+#if defined(CONFIG_SPL_DMA_SUPPORT) && defined(CONFIG_TI_EDMA)
+	edma_init(0);
+	edma_request_channel(1,1,0);
+#endif
 #ifdef CONFIG_SPL_NAND_SUPPORT
 	gpmc_init();
 #endif
diff --git a/arch/arm/cpu/armv7/omap5/hw_data.c b/arch/arm/cpu/armv7/omap5/hw_data.c
index a349525..7ee101a 100644
--- a/arch/arm/cpu/armv7/omap5/hw_data.c
+++ b/arch/arm/cpu/armv7/omap5/hw_data.c
@@ -418,6 +418,7 @@  void enable_basic_clocks(void)
 #ifdef CONFIG_DRIVER_TI_CPSW
 		(*prcm)->cm_gmac_clkstctrl,
 #endif
+		(*prcm)->cm_l3_1_clkstctrl,
 		0
 	};
 
@@ -434,6 +435,8 @@  void enable_basic_clocks(void)
 		(*prcm)->cm_l4per_gpio6_clkctrl,
 		(*prcm)->cm_l4per_gpio7_clkctrl,
 		(*prcm)->cm_l4per_gpio8_clkctrl,
+		(*prcm)->cm_l3main1_tptc1_clkctrl,
+		(*prcm)->cm_l3main1_tptc2_clkctrl,
 		0
 	};
 
@@ -499,8 +502,6 @@  void enable_basic_uboot_clocks(void)
 
 	u32 const clk_modules_hw_auto_essential[] = {
 		(*prcm)->cm_l3init_hsusbtll_clkctrl,
-		(*prcm)->cm_l3main1_tptc1_clkctrl,
-		(*prcm)->cm_l3main1_tptc2_clkctrl,
 		0
 	};
 
diff --git a/drivers/spi/ti_qspi.c b/drivers/spi/ti_qspi.c
index fd7fea8..f2ba75b 100644
--- a/drivers/spi/ti_qspi.c
+++ b/drivers/spi/ti_qspi.c
@@ -13,6 +13,8 @@ 
 #include <spi.h>
 #include <asm/gpio.h>
 #include <asm/omap_gpio.h>
+#include <asm/arch/edma.h>
+#include "../dma/ti_edma.h"
 
 /* ti qpsi register bit masks */
 #define QSPI_TIMEOUT                    2000000
@@ -340,3 +342,72 @@  int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *dout,
 
 	return 0;
 }
+
+#if defined(CONFIG_SPL_DMA_SUPPORT) && defined(CONFIG_TI_EDMA)
+void spi_flash_copy_mmap(void *data, void *offset, size_t len)
+{
+	struct edma_param_entry edma_param;
+	int           b_cnt_value = 1;
+	int           rem_bytes  = 0;
+	int           a_cnt_value = len;
+	unsigned int          addr      = (unsigned int) (data);
+	unsigned int          max_acnt  = 0x7FFFU;
+	unsigned int edma_ch_num = 1;
+
+	if (len > max_acnt)
+	{
+		b_cnt_value = (len / max_acnt);
+		rem_bytes  = (len % max_acnt);
+		a_cnt_value = max_acnt;
+	}
+
+	/* Compute QSPI address and size */
+	edma_param.opt      = 0;
+	edma_param.src_addr  = ((unsigned int) offset);
+	edma_param.dest_addr = addr;
+	edma_param.a_cnt     = a_cnt_value;
+	edma_param.b_cnt     = b_cnt_value;
+	edma_param.c_cnt     = 1;
+	edma_param.src_bidx  = a_cnt_value;
+	edma_param.dest_bidx = a_cnt_value;
+	edma_param.src_cidx  = 0;
+	edma_param.dest_cidx = 0;
+	edma_param.link_addr = 0xFFFF;
+	edma_param.opt     |=
+		(EDMA_TPCC_OPT_TCINTEN_MASK |
+		 ((edma_ch_num <<
+		   EDMA_TPCC_OPT_TCC_SHIFT) &
+		  EDMA_TPCC_OPT_TCC_MASK) | EDMA_TPCC_OPT_SYNCDIM_MASK);
+
+	edma_set_param(edma_ch_num, &edma_param);
+	edma_enable_transfer(edma_ch_num);
+
+	while (!(edma_get_intr_status() & (1 << edma_ch_num))) ;
+	edma_clr_intr(edma_ch_num);
+	if (rem_bytes != 0)
+	{
+		/* Compute QSPI address and size */
+		edma_param.opt     = 0;
+		edma_param.src_addr =
+			(b_cnt_value * max_acnt) + ((unsigned int) offset);
+		edma_param.dest_addr = (addr + (max_acnt * b_cnt_value));
+		edma_param.a_cnt     = rem_bytes;
+		edma_param.b_cnt     = 1;
+		edma_param.c_cnt     = 1;
+		edma_param.src_bidx  = rem_bytes;
+		edma_param.dest_bidx = rem_bytes;
+		edma_param.src_cidx  = 0;
+		edma_param.dest_cidx = 0;
+		edma_param.link_addr = 0xFFFF;
+		edma_param.opt     |=
+			(EDMA_TPCC_OPT_TCINTEN_MASK |
+			 ((edma_ch_num << EDMA_TPCC_OPT_TCC_SHIFT) & EDMA_TPCC_OPT_TCC_MASK));
+		edma_set_param(edma_ch_num, &edma_param);
+		edma_enable_transfer(edma_ch_num);
+
+		while (!(edma_get_intr_status() & (1 << edma_ch_num))) ;
+		edma_clr_intr(edma_ch_num);
+	}
+	*((unsigned int *) offset) += len;
+}
+#endif