/*
* Copyright Altera Corporation (C) 2012-2013. All rights reserved
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see .
*/
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#ifndef CONFIG_SPL_BUILD
#include
#include
#endif
#include
DECLARE_GLOBAL_DATA_PTR;
static const struct socfpga_reset_manager *reset_manager_base =
(void *)SOCFPGA_RSTMGR_ADDRESS;
/*
* FPGA programming support for SoC FPGA Cyclone V
*/
/* currently only single FPGA device avaiable on dev kit */
Altera_desc altera_fpga[CONFIG_FPGA_COUNT] = {
{Altera_SoCFPGA, /* family */
fast_passive_parallel, /* interface type */
-1, /* no limitation as
additional data will be ignored */
NULL, /* no device function table */
NULL, /* base interface address specified in driver */
0} /* no cookie implementation */
};
/* add device descriptor to FPGA device table */
void socfpga_fpga_add(void)
{
int i;
fpga_init();
for (i = 0; i < CONFIG_FPGA_COUNT; i++)
fpga_add(fpga_altera, &altera_fpga[i]);
}
/*
* Print CPU information
*/
int print_cpuinfo(void)
{
puts("CPU : Altera SOCFPGA Platform\n");
return 0;
}
int misc_init_r(void)
{
char buf[32];
/* add device descriptor to FPGA device table */
socfpga_fpga_add();
/* create environment for bridges and handoff */
/* hps peripheral controller to fgpa */
setenv_addr("fpgaintf", (void *)SYSMGR_FPGAINTF_MODULE);
sprintf(buf, "0x%08x", readl(ISWGRP_HANDOFF_FPGAINTF));
setenv("fpgaintf_handoff", buf);
/* fpga2sdram port */
setenv_addr("fpga2sdram", (void *)(SOCFPGA_SDR_ADDRESS +
SDR_CTRLGRP_FPGAPORTRST_ADDRESS));
sprintf(buf, "0x%08x", readl(ISWGRP_HANDOFF_FPGA2SDR));
setenv("fpga2sdram_handoff", buf);
setenv_addr("fpga2sdram_apply", (void *)sdram_applycfg_uboot);
/* axi bridges (hps2fpga, lwhps2fpga and fpga2hps) */
setenv_addr("axibridge", (void *)&reset_manager_base->brg_mod_reset);
sprintf(buf, "0x%08x", readl(ISWGRP_HANDOFF_AXIBRIDGE));
setenv("axibridge_handoff", buf);
/* l3 remap register */
setenv_addr("l3remap", (void *)SOCFPGA_L3REGS_ADDRESS);
sprintf(buf, "0x%08x", readl(ISWGRP_HANDOFF_L3REMAP));
setenv("l3remap_handoff", buf);
/* add signle command to enable all bridges based on handoff */
setenv("bridge_enable_handoff",
"mw $fpgaintf ${fpgaintf_handoff}; "
"go $fpga2sdram_apply; "
"mw $fpga2sdram ${fpga2sdram_handoff}; "
"mw $axibridge ${axibridge_handoff}; "
"mw $l3remap ${l3remap_handoff} ");
/* add signle command to disable all bridges */
setenv("bridge_disable",
"mw $fpgaintf 0; "
"mw $fpga2sdram 0; "
"go $fpga2sdram_apply; "
"mw $axibridge 0; "
"mw $l3remap 0x1 ");
return 0;
}
#if defined(CONFIG_SYS_CONSOLE_IS_IN_ENV) && \
defined(CONFIG_SYS_CONSOLE_OVERWRITE_ROUTINE)
int overwrite_console(void)
{
return 0;
}
#endif
/*
* Initializes MMC controllers.
* to override, implement board_mmc_init()
*/
int cpu_mmc_init(bd_t *bis)
{
#ifdef CONFIG_DWMMC
return altera_dwmmc_init(CONFIG_SDMMC_BASE,
CONFIG_DWMMC_BUS_WIDTH, 0);
#else
return 0;
#endif
}
#ifndef CONFIG_SYS_DCACHE_OFF
void enable_caches(void)
{
/* Enable D-cache. I-cache is already enabled in start.S */
dcache_enable();
}
#endif
#ifdef CONFIG_SPL_BUILD
/*
* Setup RAM boot to ensure the clock are reset under CSEL = 0
*/
void ram_boot_setup(void)
{
unsigned csel, ramboot_addr;
csel = (readl(SYSMGR_BOOTINFO) & SYSMGR_BOOTINFO_CSEL_MASK) >>
SYSMGR_BOOTINFO_CSEL_LSB;
if (!csel) {
/*
* Copy the ramboot program at end of Preloader or offset 60kB
* which is bigger. With that, customer can modify any content
* within first 60kB of OCRAM at any boot stage
*/
ramboot_addr = CONFIG_SYS_INIT_RAM_ADDR + 0xf000;
if ((unsigned)&__ecc_padding_end > ramboot_addr)
ramboot_addr = (unsigned)&__ecc_padding_end;
memcpy((void *)ramboot_addr, reset_clock_manager,
reset_clock_manager_size);
/* tell BootROM where the RAM boot code start */
writel(ramboot_addr &
CONFIG_SYSMGR_WARMRAMGRP_EXECUTION_OFFSET_MASK,
CONFIG_SYSMGR_WARMRAMGRP_EXECUTION);
/* Enable the RAM boot */
writel(CONFIG_SYSMGR_WARMRAMGRP_ENABLE_MAGIC,
CONFIG_SYSMGR_WARMRAMGRP_ENABLE);
}
}
#endif