Skip to contentSkip to conversation

sf: ops: Add spi_flash_copy_mmap function

PATCH New Tom Rini 3 participants 8 messages Jul 11, 2014 – Apr 22, 2015

Subsystems (4)
lore
Share & tools
lore

Tom Rini

author
#0 lore raw

PATCH 1/3 sf: ops: Add spi_flash_copy_mmap function

When doing a memory mapped copy we may have DMA available and thus need to have this copy abstracted so that the driver can do it, rather than a simple memcpy.

Cc Jagannadha Sutradharudu Teki <[email protected]>
---
 drivers/mtd/spi/sf_ops.c |    8 +++++++-
 include/spi.h            |    3 +++
 2 files changed, 10 insertions(+), 1 deletion(-)
drivers/mtd/spi/sf_ops.c +7 -1
index ef91b92..2c7b890 100644
@@ -14,6 +14,7 @@
 #include <spi.h>
 #include <spi_flash.h>
 #include <watchdog.h>
+#include <linux/compiler.h>
 
 #include "sf_internal.h"
 
@@ -359,6 +360,11 @@ int spi_flash_read_common(struct spi_flash *flash, const u8 *cmd,
 	return ret;
 }
 
+void __weak spi_flash_copy_mmap(void *data, void *offset, size_t len)
+{
+	memcpy(data, offset, len);
+}
+
 int spi_flash_cmd_read_ops(struct spi_flash *flash, u32 offset,
 		size_t len, void *data)
 {
@@ -375,7 +381,7 @@ int spi_flash_cmd_read_ops(struct spi_flash *flash, u32 offset,
 			return ret;
 		}
 		spi_xfer(flash->spi, 0, NULL, NULL, SPI_XFER_MMAP);
-		memcpy(data, flash->memory_map + offset, len);
+		spi_flash_copy_mmap(data, flash->memory_map + offset, len);
 		spi_xfer(flash->spi, 0, NULL, NULL, SPI_XFER_MMAP_END);
 		spi_release_bus(flash->spi);
 		return 0;
include/spi.h +3 -0
index ffd6647..eecb9ad 100644
@@ -220,6 +220,9 @@ int spi_set_wordlen(struct spi_slave *slave, unsigned int wordlen);
 int  spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *dout,
 		void *din, unsigned long flags);
 
+/* Copy memory mapped data */
+void spi_flash_copy_mmap(void *data, void *offset, size_t len);
+
 /**
  * Determine if a SPI chipselect is valid.
  * This function is provided by the board if the low-level SPI driver
Signature · 1 line
1.7.9.5
author
#1 lore raw

PATCH 2/3 dma: Add TI EDMA driver

From: Vinothkumar Rajendran <[email protected]>

Add a driver for the EDMA (EDMA3) IP block. Provide an API to initialize edma, program PaRAM, set register, enable and disable the interrupts, map channel to eventq and enble and disable event triggers.

---
 arch/arm/cpu/armv7/omap5/hw_data.c     |    2 +
 arch/arm/cpu/armv7/omap5/prcm-regs.c   |    4 +
 arch/arm/include/asm/arch-omap5/edma.h |   46 +++++++
 arch/arm/include/asm/omap_common.h     |    4 +
 drivers/dma/Makefile                   |    1 +
 drivers/dma/ti_edma.c                  |  225 ++++++++++++++++++++++++++++++++
 drivers/dma/ti_edma.h                  |  117 +++++++++++++++++
 include/configs/dra7xx_evm.h           |    4 +
 8 files changed, 403 insertions(+)
 create mode 100644 arch/arm/include/asm/arch-omap5/edma.h
 create mode 100644 drivers/dma/ti_edma.c
 create mode 100644 drivers/dma/ti_edma.h
arch/arm/cpu/armv7/omap5/hw_data.c +2 -0
index 4baca11..a349525 100644
@@ -499,6 +499,8 @@ 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
 	};
 
arch/arm/cpu/armv7/omap5/prcm-regs.c +4 -0
index ff08ef4..edda406 100644
@@ -975,4 +975,8 @@ struct prcm_regs const dra7xx_prcm = {
 
 	.prm_abbldo_mpu_setup			= 0x4AE07DDC,
 	.prm_abbldo_mpu_ctrl			= 0x4AE07DE0,
+
+	/*l3main1 edma*/
+	.cm_l3main1_tptc1_clkctrl		= 0x4a008778,
+	.cm_l3main1_tptc2_clkctrl		= 0x4a008780,
 };
arch/arm/include/asm/arch-omap5/edma.h new file +46 -0

46 lines not on this page · raw message

arch/arm/include/asm/omap_common.h +4 -0
index d1344ee..969a541 100644
@@ -344,6 +344,10 @@ struct prcm_regs {
 	/* GMAC Clk Ctrl */
 	u32 cm_gmac_gmac_clkctrl;
 	u32 cm_gmac_clkstctrl;
+
+	/*l3main1 edma*/
+	u32 cm_l3main1_tptc1_clkctrl;
+	u32 cm_l3main1_tptc2_clkctrl;
 };
 
 struct omap_sys_ctrl_regs {
drivers/dma/Makefile +1 -0
index 8b2821b..4ac6170 100644
@@ -9,3 +9,4 @@ obj-$(CONFIG_FSLDMAFEC) += MCD_tasksInit.o MCD_dmaApi.o MCD_tasks.o
 obj-$(CONFIG_APBH_DMA) += apbh_dma.o
 obj-$(CONFIG_FSL_DMA) += fsl_dma.o
 obj-$(CONFIG_OMAP3_DMA) += omap3_dma.o
+obj-$(CONFIG_TI_EDMA) += ti_edma.o
drivers/dma/ti_edma.c new file +225 -0

225 lines not on this page · raw message

drivers/dma/ti_edma.h new file +117 -0

117 lines not on this page · raw message

include/configs/dra7xx_evm.h +4 -0
index 8d0a0eb..f86ec38 100644
@@ -113,6 +113,10 @@
 
 /* SPI SPL */
 #define CONFIG_SPL_SPI_SUPPORT
+#define CONFIG_SPL_DMA_SUPPORT
+#ifdef CONFIG_SPL_BUILD
+#define CONFIG_TI_EDMA
+#endif
 #define CONFIG_SPL_SPI_LOAD
 #define CONFIG_SPL_SPI_FLASH_SUPPORT
 #define CONFIG_SPL_SPI_BUS             0
Signature · 1 line
1.7.9.5
author
#2 lore raw

PATCH 3/3 sf: ti_qspi: Enable EDMA for reads in SPL

In reply to Tom Rini

From: Vinothkumar Rajendran <[email protected]>

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.

---
 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(-)
arch/arm/cpu/armv7/omap-common/boot-common.c +5 -0
index 3033564..636f5d6 100644
@@ -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
arch/arm/cpu/armv7/omap5/hw_data.c +3 -2
index a349525..7ee101a 100644
@@ -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
 	};
 
drivers/spi/ti_qspi.c +71 -0

80 lines not on this page · raw message

Signature · 1 line
1.7.9.5
#3 lore raw

PATCH 3/3 sf: ti_qspi: Enable EDMA for reads in SPL

Quoted 72 lines · Tom Rini

From: Vinothkumar Rajendran <[email protected]>

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.

---
 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(-)
arch/arm/cpu/armv7/omap-common/boot-common.c +5 -0
index 3033564..636f5d6 100644
@@ -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
arch/arm/cpu/armv7/omap5/hw_data.c +3 -2
index a349525..7ee101a 100644
@@ -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
        };
 
drivers/spi/ti_qspi.c +0 -0
index fd7fea8..f2ba75b 100644

drivers/spi/ti_qspi.c line 17

Quoted 5 lines
drivers/spi/ti_qspi.c +2 -0
@@ -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.

Quoted 66 lines
drivers/spi/ti_qspi.c +59 -0
 /* 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 |

drivers/spi/ti_qspi.c int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *dout, · line 413

Quoted 10 lines
drivers/spi/ti_qspi.c +10 -0
+                        ((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!

Signature · 1 line
Jagan.
author
#4 lore raw

PATCH 3/3 sf: ti_qspi: Enable EDMA for reads in SPL

Quoted 6 lines · Jagan Teki
Quoted 5 lines · Tom Rini

From: Vinothkumar Rajendran <[email protected]>

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]

Quoted 4 lines

drivers/spi/ti_qspi.c line 17

Quoted 2 lines
drivers/spi/ti_qspi.c +2 -0
+#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.

Quoted 82 lines
Quoted 66 lines

/* ti qpsi register bit masks */
#define QSPI_TIMEOUT 2000000

drivers/spi/ti_qspi.c +59 -0
@@ -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 |

drivers/spi/ti_qspi.c int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *dout, · line 413

Quoted 10 lines
drivers/spi/ti_qspi.c +10 -0
+                        ((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.

Quoted 1 line

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.

Signature · 8 lines
Tom
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20140714/a800cdd6/attachment.pgp>
author
#5 lore raw

PATCH 3/3 sf: ti_qspi: Enable EDMA for reads in SPL

Quoted 97 lines · Tom Rini
Quoted 6 lines · Jagan Teki
Quoted 5 lines · Tom Rini

From: Vinothkumar Rajendran <[email protected]>

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]

Quoted 4 lines

drivers/spi/ti_qspi.c line 17

Quoted 2 lines
drivers/spi/ti_qspi.c +2 -0
+#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.

Quoted 82 lines
Quoted 66 lines

/* ti qpsi register bit masks */
#define QSPI_TIMEOUT 2000000

drivers/spi/ti_qspi.c +59 -0
@@ -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 |

drivers/spi/ti_qspi.c int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *dout, · line 413

Quoted 10 lines
drivers/spi/ti_qspi.c +10 -0
+                        ((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.

Quoted 4 lines
Quoted 1 line

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!

Signature · 8 lines
Tom
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20150116/2ef03682/attachment.pgp>
#6 lore raw

PATCH 3/3 sf: ti_qspi: Enable EDMA for reads in SPL

In reply to Tom Rini
Quoted 7 lines · Tom Rini
Quoted 6 lines · Jagan Teki
Quoted 5 lines · Tom Rini

From: Vinothkumar Rajendran <[email protected]>

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.

Quoted 7 lines

[snip]

Quoted 4 lines

drivers/spi/ti_qspi.c line 17

Quoted 2 lines
drivers/spi/ti_qspi.c +2 -0
+#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?

Quoted 83 lines
Quoted 83 lines
Quoted 67 lines

/* ti qpsi register bit masks */
#define QSPI_TIMEOUT 2000000

drivers/spi/ti_qspi.c +59 -0
@@ -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 |

drivers/spi/ti_qspi.c int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *dout, · line 413

Quoted 10 lines
drivers/spi/ti_qspi.c +10 -0
+                        ((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.

Quoted 4 lines
Quoted 1 line

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!

Signature · 1 line
Jagan.
#7 lore raw

PATCH 3/3 sf: ti_qspi: Enable EDMA for reads in SPL

Quoted 9 lines · Jagan Teki
Quoted 8 lines · Tom Rini
Quoted 6 lines · Jagan Teki
Quoted 5 lines · Tom Rini

From: Vinothkumar Rajendran <[email protected]>

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]

Quoted 8 lines
Quoted 6 lines
Quoted 4 lines

drivers/spi/ti_qspi.c line 17

Quoted 2 lines
drivers/spi/ti_qspi.c +2 -0
+#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 :)

Quoted 81 lines
Quoted 81 lines
Quoted 81 lines
Quoted 65 lines

/* ti qpsi register bit masks */
#define QSPI_TIMEOUT 2000000

drivers/spi/ti_qspi.c +59 -0
@@ -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 |

drivers/spi/ti_qspi.c int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *dout, · line 413

Quoted 10 lines
drivers/spi/ti_qspi.c +10 -0
+                        ((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.

Quoted 6 lines
Quoted 4 lines
Quoted 1 line

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.

Signature · 8 lines
Tom
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20150422/5f7c831a/attachment.sig>