Message ID | 1405112025-6103-3-git-send-email-trini@ti.com |
---|---|
State | Changes Requested |
Delegated to: | Jagannadha Sutradharudu Teki |
Headers | show |
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!
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.
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!
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!
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 --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