mirror of
https://github.com/Fishwaldo/u-boot.git
synced 2025-03-18 13:11:31 +00:00
Merge branch 'master' of git://git.denx.de/u-boot-spi
This commit is contained in:
commit
952bd79b53
18 changed files with 349 additions and 10 deletions
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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()) {
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
};
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -166,6 +166,8 @@
|
|||
|
||||
/* 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
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Add table
Reference in a new issue