]> git.karo-electronics.de Git - karo-tx-uboot.git/commitdiff
Merge branch 'master' of git://git.denx.de/u-boot-spi
authorTom Rini <trini@konsulko.com>
Tue, 18 Aug 2015 12:25:24 +0000 (08:25 -0400)
committerTom Rini <trini@konsulko.com>
Tue, 18 Aug 2015 12:25:24 +0000 (08:25 -0400)
18 files changed:
arch/arm/cpu/armv7/am33xx/clock.c
arch/arm/cpu/armv7/am33xx/clock_am43xx.c
arch/arm/cpu/armv7/omap-common/clocks-common.c
arch/arm/cpu/armv7/omap5/hw_data.c
arch/arm/cpu/armv7/omap5/prcm-regs.c
arch/arm/include/asm/arch-am33xx/clock.h
arch/arm/include/asm/arch-omap5/hardware.h
arch/arm/include/asm/omap_common.h
arch/arm/include/asm/ti-common/ti-edma3.h
common/cmd_sf.c
common/env_sf.c
drivers/dma/ti-edma3.c
drivers/mtd/spi/Kconfig
drivers/mtd/spi/sf_internal.h
drivers/mtd/spi/sf_ops.c
drivers/spi/ti_qspi.c
include/configs/dra7xx_evm.h
include/spi.h

index ec7d46838b74770b1a284cd4a2a72085506a5725..595c951ed245231f812ccd8c31f35f7237f9a1ab 100644 (file)
@@ -144,6 +144,33 @@ static inline void enable_clock_module(u32 *const clkctrl_addr, u32 enable_mode,
                wait_for_clk_enable(clkctrl_addr);
 }
 
+static inline void wait_for_clk_disable(u32 *clkctrl_addr)
+{
+       u32 clkctrl, idlest = MODULE_CLKCTRL_IDLEST_FULLY_FUNCTIONAL;
+       u32 bound = LDELAY;
+
+       while ((idlest != MODULE_CLKCTRL_IDLEST_DISABLED)) {
+               clkctrl = readl(clkctrl_addr);
+               idlest = (clkctrl & MODULE_CLKCTRL_IDLEST_MASK) >>
+                         MODULE_CLKCTRL_IDLEST_SHIFT;
+               if (--bound == 0) {
+                       printf("Clock disable failed for 0x%p idlest 0x%x\n",
+                              clkctrl_addr, clkctrl);
+                        return;
+               }
+       }
+}
+static inline void disable_clock_module(u32 *const clkctrl_addr,
+                                       u32 wait_for_disable)
+{
+       clrsetbits_le32(clkctrl_addr, MODULE_CLKCTRL_MODULEMODE_MASK,
+                       MODULE_CLKCTRL_MODULEMODE_SW_DISABLE <<
+                       MODULE_CLKCTRL_MODULEMODE_SHIFT);
+       debug("Disable clock module - %p\n", clkctrl_addr);
+       if (wait_for_disable)
+               wait_for_clk_disable(clkctrl_addr);
+}
+
 static inline void enable_clock_domain(u32 *const clkctrl_reg, u32 enable_mode)
 {
        clrsetbits_le32(clkctrl_reg, CD_CLKCTRL_CLKTRCTRL_MASK,
@@ -151,6 +178,14 @@ static inline void enable_clock_domain(u32 *const clkctrl_reg, u32 enable_mode)
        debug("Enable clock domain - %p\n", clkctrl_reg);
 }
 
+static inline void disable_clock_domain(u32 *const clkctrl_reg)
+{
+       clrsetbits_le32(clkctrl_reg, CD_CLKCTRL_CLKTRCTRL_MASK,
+                       CD_CLKCTRL_CLKTRCTRL_SW_SLEEP <<
+                       CD_CLKCTRL_CLKTRCTRL_SHIFT);
+       debug("Disable clock domain - %p\n", clkctrl_reg);
+}
+
 void do_enable_clocks(u32 *const *clk_domains,
                      u32 *const *clk_modules_explicit_en, u8 wait_for_enable)
 {
@@ -170,6 +205,23 @@ void do_enable_clocks(u32 *const *clk_domains,
        };
 }
 
+void do_disable_clocks(u32 *const *clk_domains,
+                       u32 *const *clk_modules_disable,
+                       u8 wait_for_disable)
+{
+       u32 i, max = 100;
+
+
+       /* Clock modules that need to be put in SW_DISABLE */
+       for (i = 0; (i < max) && clk_modules_disable[i]; i++)
+               disable_clock_module(clk_modules_disable[i],
+                                    wait_for_disable);
+
+       /* Put the clock domains in SW_SLEEP mode */
+       for (i = 0; (i < max) && clk_domains[i]; i++)
+               disable_clock_domain(clk_domains[i]);
+}
+
 /*
  * Before scaling up the clocks we need to have the PMIC scale up the
  * voltages first.  This will be dependent on which PMIC is in use
index b6396942bbff5135d3224271d40f2f36f4d54237..35c431eb292d63299948e30f08bc25adaedce7d3 100644 (file)
@@ -135,3 +135,39 @@ void enable_basic_clocks(void)
        /* For OPP100 the mac clock should be /5. */
        writel(0x4, &cmdpll->clkselmacclk);
 }
+
+#ifdef CONFIG_TI_EDMA3
+void enable_edma3_clocks(void)
+{
+       u32 *const clk_domains_edma3[] = {
+               0
+       };
+
+       u32 *const clk_modules_explicit_en_edma3[] = {
+               &cmper->tpccclkctrl,
+               &cmper->tptc0clkctrl,
+               0
+       };
+
+       do_enable_clocks(clk_domains_edma3,
+                        clk_modules_explicit_en_edma3,
+                        1);
+}
+
+void disable_edma3_clocks(void)
+{
+       u32 *const clk_domains_edma3[] = {
+               0
+       };
+
+       u32 *const clk_modules_disable_edma3[] = {
+               &cmper->tpccclkctrl,
+               &cmper->tptc0clkctrl,
+               0
+       };
+
+       do_disable_clocks(clk_domains_edma3,
+                         clk_modules_disable_edma3,
+                         1);
+}
+#endif
index c94a807819310fb2a3b00e7a79d45ce3074a3eb0..e28b79568d1d1f1137414f64af1fd6f9f46a1c1e 100644 (file)
@@ -648,6 +648,14 @@ static inline void enable_clock_domain(u32 const clkctrl_reg, u32 enable_mode)
        debug("Enable clock domain - %x\n", clkctrl_reg);
 }
 
+static inline void disable_clock_domain(u32 const clkctrl_reg)
+{
+       clrsetbits_le32(clkctrl_reg, CD_CLKCTRL_CLKTRCTRL_MASK,
+                       CD_CLKCTRL_CLKTRCTRL_SW_SLEEP <<
+                       CD_CLKCTRL_CLKTRCTRL_SHIFT);
+       debug("Disable clock domain - %x\n", clkctrl_reg);
+}
+
 static inline void wait_for_clk_enable(u32 clkctrl_addr)
 {
        u32 clkctrl, idlest = MODULE_CLKCTRL_IDLEST_DISABLED;
@@ -677,6 +685,34 @@ static inline void enable_clock_module(u32 const clkctrl_addr, u32 enable_mode,
                wait_for_clk_enable(clkctrl_addr);
 }
 
+static inline void wait_for_clk_disable(u32 clkctrl_addr)
+{
+       u32 clkctrl, idlest = MODULE_CLKCTRL_IDLEST_FULLY_FUNCTIONAL;
+       u32 bound = LDELAY;
+
+       while ((idlest != MODULE_CLKCTRL_IDLEST_DISABLED)) {
+               clkctrl = readl(clkctrl_addr);
+               idlest = (clkctrl & MODULE_CLKCTRL_IDLEST_MASK) >>
+                        MODULE_CLKCTRL_IDLEST_SHIFT;
+               if (--bound == 0) {
+                       printf("Clock disable failed for 0x%x idlest 0x%x\n",
+                              clkctrl_addr, clkctrl);
+                       return;
+               }
+       }
+}
+
+static inline void disable_clock_module(u32 const clkctrl_addr,
+                                       u32 wait_for_disable)
+{
+       clrsetbits_le32(clkctrl_addr, MODULE_CLKCTRL_MODULEMODE_MASK,
+                       MODULE_CLKCTRL_MODULEMODE_SW_DISABLE <<
+                       MODULE_CLKCTRL_MODULEMODE_SHIFT);
+       debug("Disable clock module - %x\n", clkctrl_addr);
+       if (wait_for_disable)
+               wait_for_clk_disable(clkctrl_addr);
+}
+
 void freq_update_core(void)
 {
        u32 freq_config1 = 0;
@@ -800,6 +836,23 @@ void do_enable_clocks(u32 const *clk_domains,
        }
 }
 
+void do_disable_clocks(u32 const *clk_domains,
+                           u32 const *clk_modules_disable,
+                           u8 wait_for_disable)
+{
+       u32 i, max = 100;
+
+
+       /* Clock modules that need to be put in SW_DISABLE */
+       for (i = 0; (i < max) && clk_modules_disable[i]; i++)
+               disable_clock_module(clk_modules_disable[i],
+                                    wait_for_disable);
+
+       /* Put the clock domains in SW_SLEEP mode */
+       for (i = 0; (i < max) && clk_domains[i]; i++)
+               disable_clock_domain(clk_domains[i]);
+}
+
 void prcm_init(void)
 {
        switch (omap_hw_init_context()) {
index 3a723cace71abf353ae20038b9672c3b6c64b27d..33f92b7e225d5051e6d9e9bd6727f11d462e537f 100644 (file)
@@ -565,6 +565,47 @@ void enable_basic_uboot_clocks(void)
                         1);
 }
 
+#ifdef CONFIG_TI_EDMA3
+void enable_edma3_clocks(void)
+{
+       u32 const clk_domains_edma3[] = {
+               0
+       };
+
+       u32 const clk_modules_hw_auto_edma3[] = {
+               (*prcm)->cm_l3main1_tptc1_clkctrl,
+               (*prcm)->cm_l3main1_tptc2_clkctrl,
+               0
+       };
+
+       u32 const clk_modules_explicit_en_edma3[] = {
+               0
+       };
+
+       do_enable_clocks(clk_domains_edma3,
+                        clk_modules_hw_auto_edma3,
+                        clk_modules_explicit_en_edma3,
+                        1);
+}
+
+void disable_edma3_clocks(void)
+{
+       u32 const clk_domains_edma3[] = {
+               0
+       };
+
+       u32 const clk_modules_disable_edma3[] = {
+               (*prcm)->cm_l3main1_tptc1_clkctrl,
+               (*prcm)->cm_l3main1_tptc2_clkctrl,
+               0
+       };
+
+       do_disable_clocks(clk_domains_edma3,
+                         clk_modules_disable_edma3,
+                         1);
+}
+#endif
+
 const struct ctrl_ioregs ioregs_omap5430 = {
        .ctrl_ddrch = DDR_IO_I_34OHM_SR_FASTEST_WD_DQ_NO_PULL_DQS_PULL_DOWN,
        .ctrl_lpddr2ch = DDR_IO_I_34OHM_SR_FASTEST_WD_CK_CKE_NCS_CA_PULL_DOWN,
index cd51fe7678be0182bbce06e046ce02f4e7023c99..d01ce88306eec2ec421de57d70951519b775ef1c 100644 (file)
@@ -989,4 +989,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,
 };
index 4af6b57e42f5528c7ed2e78796b654a94f179ec1..a6d2419fb843de713880e16b09fe7e57ad43a090 100644 (file)
@@ -112,5 +112,6 @@ void do_setup_dpll(const struct dpll_regs *, const struct dpll_params *);
 void prcm_init(void);
 void enable_basic_clocks(void);
 void do_enable_clocks(u32 *const *, u32 *const *, u8);
+void do_disable_clocks(u32 *const *, u32 *const *, u8);
 
 #endif
index f7011b4e904aaf2f17faf2d88bae173e626e49e3..a5bd600092891515e584ed2301595ff16b0a4037 100644 (file)
@@ -23,4 +23,9 @@
 /* GPMC Base address */
 #define GPMC_BASE                      0x50000000
 
+/* EDMA3 Base address for DRA7XX and AM57XX */
+#if defined(CONFIG_DRA7XX) || defined(CONFIG_AM57XX)
+#define EDMA3_BASE                     0x43300000
+#endif
+
 #endif
index 056affc3fabdccdf6be6a4ec2dd8ea32118fd1dc..b67d4b673d99f3bc8d2a1fc8973f8f300f18f9db 100644 (file)
@@ -349,6 +349,10 @@ struct prcm_regs {
        /* IPU */
        u32 cm_ipu_clkstctrl;
        u32 cm_ipu_i2c5_clkctrl;
+
+       /*l3main1 edma*/
+       u32 cm_l3main1_tptc1_clkctrl;
+       u32 cm_l3main1_tptc2_clkctrl;
 };
 
 struct omap_sys_ctrl_regs {
@@ -575,6 +579,10 @@ void do_enable_clocks(u32 const *clk_domains,
                      u32 const *clk_modules_explicit_en,
                      u8 wait_for_enable);
 
+void do_disable_clocks(u32 const *clk_domains,
+                      u32 const *clk_modules_disable,
+                      u8 wait_for_disable);
+
 void setup_post_dividers(u32 const base,
                        const struct dpll_params *params);
 u32 omap_ddr_clk(void);
@@ -594,6 +602,9 @@ void recalibrate_iodelay(void);
 
 void omap_smc1(u32 service, u32 val);
 
+void enable_edma3_clocks(void);
+void disable_edma3_clocks(void);
+
 /* ABB */
 #define OMAP_ABB_NOMINAL_OPP           0
 #define OMAP_ABB_FAST_OPP              1
index 5adc1dac0e65d17e553b46494f1b67c641c521af..6a7a321c1bdf1e7a90ba1bb9c4fa5ee60b2ce056 100644 (file)
@@ -117,5 +117,7 @@ void edma3_set_src_addr(u32 base, int slot, u32 src);
 void edma3_set_transfer_params(u32 base, int slot, int acnt,
                               int bcnt, int ccnt, u16 bcnt_rld,
                               enum edma3_sync_dimension sync_mode);
+void edma3_transfer(unsigned long edma3_base_addr, unsigned int
+               edma_slot_num, void *dst, void *src, size_t len);
 
 #endif
index 3746e0d9644f08aca368e60cf153387a79dab187..ac7f5dfb8181c28147ed9b1ea83e62e59c8ef20a 100644 (file)
@@ -223,7 +223,7 @@ static int spi_flash_update(struct spi_flash *flash, u32 offset,
 
        if (end - buf >= 200)
                scale = (end - buf) / 100;
-       cmp_buf = malloc(flash->sector_size);
+       cmp_buf = memalign(ARCH_DMA_MINALIGN, flash->sector_size);
        if (cmp_buf) {
                ulong last_update = get_timer(0);
 
@@ -484,12 +484,12 @@ static int do_spi_flash_test(int argc, char * const argv[])
        if (*argv[2] == 0 || *endp != 0)
                return -1;
 
-       vbuf = malloc(len);
+       vbuf = memalign(ARCH_DMA_MINALIGN, len);
        if (!vbuf) {
                printf("Cannot allocate memory (%lu bytes)\n", len);
                return 1;
        }
-       buf = malloc(len);
+       buf = memalign(ARCH_DMA_MINALIGN, len);
        if (!buf) {
                free(vbuf);
                printf("Cannot allocate memory (%lu bytes)\n", len);
index e928f5752cc7c5dddaf13b329a8f1eb67b8b669e..940983124fbbfd529e7dbd928da8b7f6d94dfab9 100644 (file)
@@ -79,7 +79,7 @@ int saveenv(void)
        if (CONFIG_ENV_SECT_SIZE > CONFIG_ENV_SIZE) {
                saved_size = CONFIG_ENV_SECT_SIZE - CONFIG_ENV_SIZE;
                saved_offset = env_new_offset + CONFIG_ENV_SIZE;
-               saved_buffer = malloc(saved_size);
+               saved_buffer = memalign(ARCH_DMA_MINALIGN, saved_size);
                if (!saved_buffer) {
                        ret = 1;
                        goto done;
@@ -142,9 +142,10 @@ void env_relocate_spec(void)
        env_t *tmp_env2 = NULL;
        env_t *ep = NULL;
 
-       tmp_env1 = (env_t *)malloc(CONFIG_ENV_SIZE);
-       tmp_env2 = (env_t *)malloc(CONFIG_ENV_SIZE);
-
+       tmp_env1 = (env_t *)memalign(ARCH_DMA_MINALIGN,
+                       CONFIG_ENV_SIZE);
+       tmp_env2 = (env_t *)memalign(ARCH_DMA_MINALIGN,
+                       CONFIG_ENV_SIZE);
        if (!tmp_env1 || !tmp_env2) {
                set_default_env("!malloc() failed");
                goto out;
@@ -295,7 +296,7 @@ void env_relocate_spec(void)
        int ret;
        char *buf = NULL;
 
-       buf = (char *)malloc(CONFIG_ENV_SIZE);
+       buf = (char *)memalign(ARCH_DMA_MINALIGN, CONFIG_ENV_SIZE);
        env_flash = spi_flash_probe(CONFIG_ENV_SPI_BUS, CONFIG_ENV_SPI_CS,
                        CONFIG_ENV_SPI_MAX_HZ, CONFIG_ENV_SPI_MODE);
        if (!env_flash) {
index 8184ded9fa81a22f040328e13d8b4a937b4935e8..d6a427f2e21d3f88679874d52c2b9fa53a815328 100644 (file)
@@ -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);
+       }
+}
index 8b730ff3c55458b5040e5891adcdeab6012948b7..3f7433cbc214b76a7120886f858047d64b51744c 100644 (file)
@@ -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
index 9fb555707cdeca8ca2c4e56e204053210a48d76a..9c95d5616eb6b3bb0c0f954001e6656b8941faf9 100644 (file)
@@ -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,
index 38592f518b72c7f4a7966fb2ad61d1c12242a84a..900ec1f2a9ce8cb95ae4f2d087db3bc440c72b69 100644 (file)
@@ -14,6 +14,7 @@
 #include <spi.h>
 #include <spi_flash.h>
 #include <watchdog.h>
+#include <linux/compiler.h>
 
 #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;
index 3356c0f072e55da3d80ab9bbd4a051e4deab5ab1..bd63db8a2acc52ffc26a3da283c6cf3bcb6e3e07 100644 (file)
@@ -13,6 +13,8 @@
 #include <spi.h>
 #include <asm/gpio.h>
 #include <asm/omap_gpio.h>
+#include <asm/omap_common.h>
+#include <asm/ti-common/ti-edma3.h>
 
 /* ti qpsi register bit masks */
 #define QSPI_TIMEOUT                    2000000
@@ -106,7 +108,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 +115,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 |
@@ -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
index 74994479e60b43cf09f4d6191ef720027f8ecff6..6e32de854619cf07172b5ae908e62942fd73a0b9 100644 (file)
 
 /* SPI SPL */
 #define CONFIG_SPL_SPI_SUPPORT
+#define CONFIG_SPL_DMA_SUPPORT
+#define CONFIG_TI_EDMA3
 #define CONFIG_SPL_SPI_LOAD
 #define CONFIG_SPL_SPI_FLASH_SUPPORT
 #define CONFIG_SYS_SPI_U_BOOT_OFFS     0x40000
index 18362364cf0ea639e55b275a2b229e66dc1fda9a..51fdfd6d7360d9c601ffce37fb3c83bc86c3a127 100644 (file)
@@ -272,6 +272,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