Merge git://git.denx.de/u-boot-socfpga
- Misc MMC, FPGA bridge, general SoCFPGA fixes
This commit is contained in:
commit
4862830b69
@ -77,6 +77,7 @@
|
||||
};
|
||||
|
||||
&uart0 {
|
||||
clock-frequency = <100000000>;
|
||||
u-boot,dm-pre-reloc;
|
||||
};
|
||||
|
||||
|
@ -39,6 +39,6 @@ void socfpga_init_security_policies(void);
|
||||
void socfpga_sdram_remap_zero(void);
|
||||
#endif
|
||||
|
||||
void do_bridge_reset(int enable);
|
||||
void do_bridge_reset(int enable, unsigned int mask);
|
||||
|
||||
#endif /* _MISC_H_ */
|
||||
|
@ -9,6 +9,7 @@
|
||||
#include <dt-bindings/reset/altr,rst-mgr.h>
|
||||
|
||||
void reset_deassert_peripherals_handoff(void);
|
||||
void socfpga_bridges_set_handoff_regs(bool h2f, bool lwh2f, bool f2h);
|
||||
void socfpga_bridges_reset(int enable);
|
||||
|
||||
struct socfpga_reset_manager {
|
||||
|
@ -126,17 +126,22 @@ int arch_cpu_init(void)
|
||||
#ifndef CONFIG_SPL_BUILD
|
||||
static int do_bridge(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
|
||||
{
|
||||
if (argc != 2)
|
||||
unsigned int mask = ~0;
|
||||
|
||||
if (argc < 2 || argc > 3)
|
||||
return CMD_RET_USAGE;
|
||||
|
||||
argv++;
|
||||
|
||||
if (argc == 3)
|
||||
mask = simple_strtoul(argv[1], NULL, 16);
|
||||
|
||||
switch (*argv[0]) {
|
||||
case 'e': /* Enable */
|
||||
do_bridge_reset(1);
|
||||
do_bridge_reset(1, mask);
|
||||
break;
|
||||
case 'd': /* Disable */
|
||||
do_bridge_reset(0);
|
||||
do_bridge_reset(0, mask);
|
||||
break;
|
||||
default:
|
||||
return CMD_RET_USAGE;
|
||||
@ -145,10 +150,10 @@ static int do_bridge(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
|
||||
return 0;
|
||||
}
|
||||
|
||||
U_BOOT_CMD(bridge, 2, 1, do_bridge,
|
||||
U_BOOT_CMD(bridge, 3, 1, do_bridge,
|
||||
"SoCFPGA HPS FPGA bridge control",
|
||||
"enable - Enable HPS-to-FPGA, FPGA-to-HPS, LWHPS-to-FPGA bridges\n"
|
||||
"bridge disable - Enable HPS-to-FPGA, FPGA-to-HPS, LWHPS-to-FPGA bridges\n"
|
||||
"enable [mask] - Enable HPS-to-FPGA, FPGA-to-HPS, LWHPS-to-FPGA bridges\n"
|
||||
"bridge disable [mask] - Enable HPS-to-FPGA, FPGA-to-HPS, LWHPS-to-FPGA bridges\n"
|
||||
""
|
||||
);
|
||||
|
||||
|
@ -115,7 +115,7 @@ int print_cpuinfo(void)
|
||||
}
|
||||
#endif
|
||||
|
||||
void do_bridge_reset(int enable)
|
||||
void do_bridge_reset(int enable, unsigned int mask)
|
||||
{
|
||||
if (enable)
|
||||
socfpga_reset_deassert_bridges_handoff();
|
||||
|
@ -210,47 +210,26 @@ static struct socfpga_reset_manager *reset_manager_base =
|
||||
static struct socfpga_sdr_ctrl *sdr_ctrl =
|
||||
(struct socfpga_sdr_ctrl *)SDR_CTRLGRP_ADDRESS;
|
||||
|
||||
static void socfpga_sdram_apply_static_cfg(void)
|
||||
void do_bridge_reset(int enable, unsigned int mask)
|
||||
{
|
||||
const u32 applymask = 0x8;
|
||||
u32 val = readl(&sdr_ctrl->static_cfg) | applymask;
|
||||
int i;
|
||||
|
||||
/*
|
||||
* SDRAM staticcfg register specific:
|
||||
* When applying the register setting, the CPU must not access
|
||||
* SDRAM. Luckily for us, we can abuse i-cache here to help us
|
||||
* circumvent the SDRAM access issue. The idea is to make sure
|
||||
* that the code is in one full i-cache line by branching past
|
||||
* it and back. Once it is in the i-cache, we execute the core
|
||||
* of the code and apply the register settings.
|
||||
*
|
||||
* The code below uses 7 instructions, while the Cortex-A9 has
|
||||
* 32-byte cachelines, thus the limit is 8 instructions total.
|
||||
*/
|
||||
asm volatile(
|
||||
".align 5 \n"
|
||||
" b 2f \n"
|
||||
"1: str %0, [%1] \n"
|
||||
" dsb \n"
|
||||
" isb \n"
|
||||
" b 3f \n"
|
||||
"2: b 1b \n"
|
||||
"3: nop \n"
|
||||
: : "r"(val), "r"(&sdr_ctrl->static_cfg) : "memory", "cc");
|
||||
}
|
||||
|
||||
void do_bridge_reset(int enable)
|
||||
{
|
||||
if (enable) {
|
||||
socfpga_bridges_set_handoff_regs(!(mask & BIT(0)),
|
||||
!(mask & BIT(1)),
|
||||
!(mask & BIT(2)));
|
||||
for (i = 0; i < 2; i++) { /* Reload SW setting cache */
|
||||
iswgrp_handoff[i] =
|
||||
readl(&sysmgr_regs->iswgrp_handoff[i]);
|
||||
}
|
||||
|
||||
writel(iswgrp_handoff[2], &sysmgr_regs->fpgaintfgrp_module);
|
||||
socfpga_sdram_apply_static_cfg();
|
||||
writel(iswgrp_handoff[3], &sdr_ctrl->fpgaport_rst);
|
||||
writel(iswgrp_handoff[0], &reset_manager_base->brg_mod_reset);
|
||||
writel(iswgrp_handoff[1], &nic301_regs->remap);
|
||||
} else {
|
||||
writel(0, &sysmgr_regs->fpgaintfgrp_module);
|
||||
writel(0, &sdr_ctrl->fpgaport_rst);
|
||||
socfpga_sdram_apply_static_cfg();
|
||||
writel(0, &reset_manager_base->brg_mod_reset);
|
||||
writel(1, &nic301_regs->remap);
|
||||
}
|
||||
|
@ -150,7 +150,7 @@ int arch_early_init_r(void)
|
||||
return 0;
|
||||
}
|
||||
|
||||
void do_bridge_reset(int enable)
|
||||
void do_bridge_reset(int enable, unsigned int mask)
|
||||
{
|
||||
socfpga_bridges_reset(enable);
|
||||
}
|
||||
|
@ -73,6 +73,28 @@ void reset_deassert_peripherals_handoff(void)
|
||||
#define L3REGS_REMAP_HPS2FPGA_MASK 0x08
|
||||
#define L3REGS_REMAP_OCRAM_MASK 0x01
|
||||
|
||||
void socfpga_bridges_set_handoff_regs(bool h2f, bool lwh2f, bool f2h)
|
||||
{
|
||||
u32 brgmask = 0x0;
|
||||
u32 l3rmask = L3REGS_REMAP_OCRAM_MASK;
|
||||
|
||||
if (h2f)
|
||||
brgmask |= BIT(0);
|
||||
else
|
||||
l3rmask |= L3REGS_REMAP_HPS2FPGA_MASK;
|
||||
|
||||
if (lwh2f)
|
||||
brgmask |= BIT(1);
|
||||
else
|
||||
l3rmask |= L3REGS_REMAP_LWHPS2FPGA_MASK;
|
||||
|
||||
if (f2h)
|
||||
brgmask |= BIT(2);
|
||||
|
||||
writel(brgmask, &sysmgr_regs->iswgrp_handoff[0]);
|
||||
writel(l3rmask, &sysmgr_regs->iswgrp_handoff[1]);
|
||||
}
|
||||
|
||||
void socfpga_bridges_reset(int enable)
|
||||
{
|
||||
const u32 l3mask = L3REGS_REMAP_LWHPS2FPGA_MASK |
|
||||
@ -81,10 +103,10 @@ void socfpga_bridges_reset(int enable)
|
||||
|
||||
if (enable) {
|
||||
/* brdmodrst */
|
||||
writel(0xffffffff, &reset_manager_base->brg_mod_reset);
|
||||
writel(0x7, &reset_manager_base->brg_mod_reset);
|
||||
writel(L3REGS_REMAP_OCRAM_MASK, SOCFPGA_L3REGS_ADDRESS);
|
||||
} else {
|
||||
writel(0, &sysmgr_regs->iswgrp_handoff[0]);
|
||||
writel(l3mask, &sysmgr_regs->iswgrp_handoff[1]);
|
||||
socfpga_bridges_set_handoff_regs(false, false, false);
|
||||
|
||||
/* Check signal from FPGA. */
|
||||
if (!fpgamgr_test_fpga_ready()) {
|
||||
|
@ -175,8 +175,9 @@ void board_init_f(ulong dummy)
|
||||
sysmgr_pinmux_init();
|
||||
sysmgr_config_warmrstcfgio(0);
|
||||
|
||||
/* De-assert reset for bridges based on handoff */
|
||||
socfpga_bridges_reset(0);
|
||||
/* De-assert reset for peripherals and bridges based on handoff */
|
||||
reset_deassert_peripherals_handoff();
|
||||
socfpga_bridges_set_handoff_regs(true, true, true);
|
||||
|
||||
debug("Unfreezing/Thaw all I/O banks\n");
|
||||
/* unfreeze / thaw all IO banks */
|
||||
@ -205,7 +206,4 @@ void board_init_f(ulong dummy)
|
||||
debug("DRAM init failed: %d\n", ret);
|
||||
hang();
|
||||
}
|
||||
|
||||
if (!socfpga_is_booting_from_fpga())
|
||||
socfpga_bridges_reset(1);
|
||||
}
|
||||
|
@ -74,15 +74,15 @@ static void dwmci_prepare_data(struct dwmci_host *host,
|
||||
dwmci_set_idma_desc(cur_idmac, flags, cnt,
|
||||
(ulong)bounce_buffer + (i * PAGE_SIZE));
|
||||
|
||||
cur_idmac++;
|
||||
if (blk_cnt <= 8)
|
||||
break;
|
||||
blk_cnt -= 8;
|
||||
cur_idmac++;
|
||||
i++;
|
||||
} while(1);
|
||||
|
||||
data_end = (ulong)cur_idmac;
|
||||
flush_dcache_range(data_start, data_end + ARCH_DMA_MINALIGN);
|
||||
flush_dcache_range(data_start, roundup(data_end, ARCH_DMA_MINALIGN));
|
||||
|
||||
ctrl = dwmci_readl(host, DWMCI_CTRL);
|
||||
ctrl |= DWMCI_IDMAC_EN | DWMCI_DMA_EN;
|
||||
@ -114,22 +114,40 @@ static int dwmci_fifo_ready(struct dwmci_host *host, u32 bit, u32 *len)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static unsigned int dwmci_get_timeout(struct mmc *mmc, const unsigned int size)
|
||||
{
|
||||
unsigned int timeout;
|
||||
|
||||
timeout = size * 8 * 1000; /* counting in bits and msec */
|
||||
timeout *= 2; /* wait twice as long */
|
||||
timeout /= mmc->clock;
|
||||
timeout /= mmc->bus_width;
|
||||
timeout /= mmc->ddr_mode ? 2 : 1;
|
||||
timeout = (timeout < 1000) ? 1000 : timeout;
|
||||
|
||||
return timeout;
|
||||
}
|
||||
|
||||
static int dwmci_data_transfer(struct dwmci_host *host, struct mmc_data *data)
|
||||
{
|
||||
struct mmc *mmc = host->mmc;
|
||||
int ret = 0;
|
||||
u32 timeout = 240000;
|
||||
u32 mask, size, i, len = 0;
|
||||
u32 timeout, mask, size, i, len = 0;
|
||||
u32 *buf = NULL;
|
||||
ulong start = get_timer(0);
|
||||
u32 fifo_depth = (((host->fifoth_val & RX_WMARK_MASK) >>
|
||||
RX_WMARK_SHIFT) + 1) * 2;
|
||||
|
||||
size = data->blocksize * data->blocks / 4;
|
||||
size = data->blocksize * data->blocks;
|
||||
if (data->flags == MMC_DATA_READ)
|
||||
buf = (unsigned int *)data->dest;
|
||||
else
|
||||
buf = (unsigned int *)data->src;
|
||||
|
||||
timeout = dwmci_get_timeout(mmc, size);
|
||||
|
||||
size /= 4;
|
||||
|
||||
for (;;) {
|
||||
mask = dwmci_readl(host, DWMCI_RINTSTS);
|
||||
/* Error during data transfer. */
|
||||
@ -252,14 +270,20 @@ static int dwmci_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd,
|
||||
dwmci_wait_reset(host, DWMCI_CTRL_FIFO_RESET);
|
||||
} else {
|
||||
if (data->flags == MMC_DATA_READ) {
|
||||
bounce_buffer_start(&bbstate, (void*)data->dest,
|
||||
ret = bounce_buffer_start(&bbstate,
|
||||
(void*)data->dest,
|
||||
data->blocksize *
|
||||
data->blocks, GEN_BB_WRITE);
|
||||
} else {
|
||||
bounce_buffer_start(&bbstate, (void*)data->src,
|
||||
ret = bounce_buffer_start(&bbstate,
|
||||
(void*)data->src,
|
||||
data->blocksize *
|
||||
data->blocks, GEN_BB_READ);
|
||||
}
|
||||
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
dwmci_prepare_data(host, data, cur_idmac,
|
||||
bbstate.bounce_buffer);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user