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

Jagan Teki jagannadh.teki at gmail.com
Sat Jul 12 15:12:31 CEST 2014


On Sat, Jul 12, 2014 at 2:23 AM, Tom Rini <trini at ti.com> wrote:
> From: Vinothkumar Rajendran <vinothr at 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 at ti.com>
> Signed-off-by: Tom Rini <trini at 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!
-- 
Jagan.


More information about the U-Boot mailing list