From 0a02655481834a4ebdf457e43c24729ffd7daf37 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Mon, 3 Aug 2015 01:28:56 +0200 Subject: sf: Make 4K sector support configurable Make the support for 4K subpage I/O on a SPI NOR flash configurable. A board which requires the SPI NOR to be accessed in larger 32KiB or 64KiB pages can disable the 4K subpage support, but by default, the support for 4K subpage I/O is enabled. The functionality of this option is the same as CONFIG_MTD_SPI_NOR_USE_4K_SECTORS in Linux. This is extremely useful in case one uses UBI on a SPI NOR flash. UBI needs at least 15k EBs and can not work on a flash which uses 4k ones, so disabling the support for 4k subpages lets UBI work on such flash. Signed-off-by: Marek Vasut Reviewed-by: Jagan Teki --- drivers/mtd/spi/Kconfig | 15 +++++++++++++++ drivers/mtd/spi/sf_internal.h | 4 ++++ 2 files changed, 19 insertions(+) (limited to 'drivers') diff --git a/drivers/mtd/spi/Kconfig b/drivers/mtd/spi/Kconfig index 8b730ff3c5..3f7433cbc2 100644 --- a/drivers/mtd/spi/Kconfig +++ b/drivers/mtd/spi/Kconfig @@ -86,6 +86,21 @@ config SPI_FLASH_WINBOND endif +config SPI_FLASH_USE_4K_SECTORS + bool "Use small 4096 B erase sectors" + depends on SPI_FLASH + default y + help + Many flash memories support erasing small (4096 B) sectors. Depending + on the usage this feature may provide performance gain in comparison + to erasing whole blocks (32/64 KiB). + Changing a small part of the flash's contents is usually faster with + small sectors. On the other hand erasing should be faster when using + 64 KiB block instead of 16 × 4 KiB sectors. + + Please note that some tools/drivers/filesystems may not work with + 4096 B erase size (e.g. UBIFS requires 15 KiB as a minimum). + config SPI_FLASH_DATAFLASH bool "AT45xxx DataFlash support" depends on SPI_FLASH && DM_SPI_FLASH diff --git a/drivers/mtd/spi/sf_internal.h b/drivers/mtd/spi/sf_internal.h index 9fb555707c..9c95d5616e 100644 --- a/drivers/mtd/spi/sf_internal.h +++ b/drivers/mtd/spi/sf_internal.h @@ -37,7 +37,11 @@ enum spi_read_cmds { /* sf param flags */ enum { +#ifdef CONFIG_SPI_FLASH_USE_4K_SECTORS SECT_4K = 1 << 0, +#else + SECT_4K = 0 << 0, +#endif SECT_32K = 1 << 1, E_FSR = 1 << 2, SST_BP = 1 << 3, -- cgit v1.2.1 From a39cfe717c4152ececea5c4ce0aa2e97faa263ab Mon Sep 17 00:00:00 2001 From: "vishalm@ti.com" Date: Mon, 17 Aug 2015 10:47:51 -0500 Subject: ti: qspi: set flash quad bit based on quad support flag Update op_mode_rx flag based on CONFIG_QSPI_QUAD_SUPPORT flag, instead of platform. Signed-off-by: Vishal Mahaveer Reviewed-by: Jagan Teki --- drivers/spi/ti_qspi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/spi/ti_qspi.c b/drivers/spi/ti_qspi.c index 3356c0f072..af40ec864f 100644 --- a/drivers/spi/ti_qspi.c +++ b/drivers/spi/ti_qspi.c @@ -106,7 +106,6 @@ static void ti_spi_setup_spi_register(struct ti_qspi_slave *qslave) slave->memory_map = (void *)MMAP_START_ADDR_DRA; #else slave->memory_map = (void *)MMAP_START_ADDR_AM43x; - slave->op_mode_rx = 8; #endif #ifdef CONFIG_QSPI_QUAD_SUPPORT @@ -114,6 +113,7 @@ static void ti_spi_setup_spi_register(struct ti_qspi_slave *qslave) QSPI_SETUP0_NUM_D_BYTES_8_BITS | QSPI_SETUP0_READ_QUAD | QSPI_CMD_WRITE | QSPI_NUM_DUMMY_BITS); + slave->op_mode_rx = SPI_OPM_RX_QOF; #else memval |= QSPI_CMD_READ | QSPI_SETUP0_NUM_A_BYTES | QSPI_SETUP0_NUM_D_BYTES_NO_BITS | -- cgit v1.2.1 From 146bad96191753f1918bfa4dca75d20e03fc63b2 Mon Sep 17 00:00:00 2001 From: Tom Rini Date: Mon, 17 Aug 2015 13:29:54 +0530 Subject: 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. Signed-off-by: Tom Rini Signed-off-by: Vignesh R Reviewed-by: Jagan Teki --- drivers/mtd/spi/sf_ops.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/mtd/spi/sf_ops.c b/drivers/mtd/spi/sf_ops.c index 38592f518b..900ec1f2a9 100644 --- a/drivers/mtd/spi/sf_ops.c +++ b/drivers/mtd/spi/sf_ops.c @@ -14,6 +14,7 @@ #include #include #include +#include #include "sf_internal.h" @@ -378,6 +379,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) { @@ -394,7 +400,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; -- cgit v1.2.1 From 664ab2c992d1e06c4381f66c93d2e155fc7722e1 Mon Sep 17 00:00:00 2001 From: Vignesh R Date: Mon, 17 Aug 2015 13:29:55 +0530 Subject: dma: ti-edma3: Add helper function to support edma3 transfer Signed-off-by: Vignesh R Reviewed-by: Jagan Teki --- drivers/dma/ti-edma3.c | 78 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 78 insertions(+) (limited to 'drivers') diff --git a/drivers/dma/ti-edma3.c b/drivers/dma/ti-edma3.c index 8184ded9fa..d6a427f2e2 100644 --- a/drivers/dma/ti-edma3.c +++ b/drivers/dma/ti-edma3.c @@ -382,3 +382,81 @@ void qedma3_stop(u32 base, struct edma3_channel_config *cfg) /* Clear the channel map */ __raw_writel(0, base + EDMA3_QCHMAP(cfg->chnum)); } + +void edma3_transfer(unsigned long edma3_base_addr, unsigned int + edma_slot_num, void *dst, void *src, size_t len) +{ + struct edma3_slot_config slot; + struct edma3_channel_config edma_channel; + int b_cnt_value = 1; + int rem_bytes = 0; + int a_cnt_value = len; + unsigned int addr = (unsigned int) (dst); + unsigned int max_acnt = 0x7FFFU; + + if (len > max_acnt) { + b_cnt_value = (len / max_acnt); + rem_bytes = (len % max_acnt); + a_cnt_value = max_acnt; + } + + slot.opt = 0; + slot.src = ((unsigned int) src); + slot.acnt = a_cnt_value; + slot.bcnt = b_cnt_value; + slot.ccnt = 1; + slot.src_bidx = a_cnt_value; + slot.dst_bidx = a_cnt_value; + slot.src_cidx = 0; + slot.dst_cidx = 0; + slot.link = EDMA3_PARSET_NULL_LINK; + slot.bcntrld = 0; + slot.opt = EDMA3_SLOPT_TRANS_COMP_INT_ENB | + EDMA3_SLOPT_COMP_CODE(0) | + EDMA3_SLOPT_STATIC | EDMA3_SLOPT_AB_SYNC; + + edma3_slot_configure(edma3_base_addr, edma_slot_num, &slot); + edma_channel.slot = edma_slot_num; + edma_channel.chnum = 0; + edma_channel.complete_code = 0; + /* set event trigger to dst update */ + edma_channel.trigger_slot_word = EDMA3_TWORD(dst); + + qedma3_start(edma3_base_addr, &edma_channel); + edma3_set_dest_addr(edma3_base_addr, edma_channel.slot, addr); + + while (edma3_check_for_transfer(edma3_base_addr, &edma_channel)) + ; + qedma3_stop(edma3_base_addr, &edma_channel); + + if (rem_bytes != 0) { + slot.opt = 0; + slot.src = + (b_cnt_value * max_acnt) + ((unsigned int) src); + slot.acnt = rem_bytes; + slot.bcnt = 1; + slot.ccnt = 1; + slot.src_bidx = rem_bytes; + slot.dst_bidx = rem_bytes; + slot.src_cidx = 0; + slot.dst_cidx = 0; + slot.link = EDMA3_PARSET_NULL_LINK; + slot.bcntrld = 0; + slot.opt = EDMA3_SLOPT_TRANS_COMP_INT_ENB | + EDMA3_SLOPT_COMP_CODE(0) | + EDMA3_SLOPT_STATIC | EDMA3_SLOPT_AB_SYNC; + edma3_slot_configure(edma3_base_addr, edma_slot_num, &slot); + edma_channel.slot = edma_slot_num; + edma_channel.chnum = 0; + edma_channel.complete_code = 0; + /* set event trigger to dst update */ + edma_channel.trigger_slot_word = EDMA3_TWORD(dst); + + qedma3_start(edma3_base_addr, &edma_channel); + edma3_set_dest_addr(edma3_base_addr, edma_channel.slot, addr + + (max_acnt * b_cnt_value)); + while (edma3_check_for_transfer(edma3_base_addr, &edma_channel)) + ; + qedma3_stop(edma3_base_addr, &edma_channel); + } +} -- cgit v1.2.1 From 8ddd9c485f17de4bea55707f5b9cf07fd0a89ed0 Mon Sep 17 00:00:00 2001 From: Vignesh R Date: Mon, 17 Aug 2015 15:20:13 +0530 Subject: spi: ti_qspi: Use DMA to read from qspi flash ti_qspi uses memory map mode for faster read. Enabling DMA will increase read speed by 3x @48MHz on DRA74 EVM. Signed-off-by: Vignesh R Reviewed-by: Jagan Teki --- drivers/spi/ti_qspi.c | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) (limited to 'drivers') diff --git a/drivers/spi/ti_qspi.c b/drivers/spi/ti_qspi.c index af40ec864f..bd63db8a2a 100644 --- a/drivers/spi/ti_qspi.c +++ b/drivers/spi/ti_qspi.c @@ -13,6 +13,8 @@ #include #include #include +#include +#include /* ti qpsi register bit masks */ #define QSPI_TIMEOUT 2000000 @@ -347,3 +349,26 @@ int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *dout, return 0; } + +/* TODO: control from sf layer to here through dm-spi */ +#ifdef CONFIG_TI_EDMA3 +void spi_flash_copy_mmap(void *data, void *offset, size_t len) +{ + unsigned int addr = (unsigned int) (data); + unsigned int edma_slot_num = 1; + + /* Invalidate the area, so no writeback into the RAM races with DMA */ + invalidate_dcache_range(addr, addr + roundup(len, ARCH_DMA_MINALIGN)); + + /* enable edma3 clocks */ + enable_edma3_clocks(); + + /* Call edma3 api to do actual DMA transfer */ + edma3_transfer(EDMA3_BASE, edma_slot_num, data, offset, len); + + /* disable edma3 clocks */ + disable_edma3_clocks(); + + *((unsigned int *)offset) += len; +} +#endif -- cgit v1.2.1