
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"
/* 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