From 05a217212b41c6342fc1c6be0fe49ce28c9afe40 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Tue, 21 Apr 2015 20:38:21 +0900 Subject: ARM: socfpga: move SoC sources to mach-socfpga Our recent trend is to collect SoC files into arch/arm/mach-(SOC). Signed-off-by: Masahiro Yamada --- arch/arm/Makefile | 1 + arch/arm/cpu/armv7/Makefile | 1 - arch/arm/cpu/armv7/socfpga/Makefile | 12 - arch/arm/cpu/armv7/socfpga/clock_manager.c | 560 ------------------------- arch/arm/cpu/armv7/socfpga/fpga_manager.c | 78 ---- arch/arm/cpu/armv7/socfpga/freeze_controller.c | 213 ---------- arch/arm/cpu/armv7/socfpga/misc.c | 289 ------------- arch/arm/cpu/armv7/socfpga/reset_manager.c | 139 ------ arch/arm/cpu/armv7/socfpga/scan_manager.c | 209 --------- arch/arm/cpu/armv7/socfpga/spl.c | 229 ---------- arch/arm/cpu/armv7/socfpga/system_manager.c | 77 ---- arch/arm/cpu/armv7/socfpga/timer.c | 24 -- arch/arm/cpu/armv7/socfpga/u-boot-spl.lds | 45 -- arch/arm/mach-socfpga/Makefile | 12 + arch/arm/mach-socfpga/clock_manager.c | 560 +++++++++++++++++++++++++ arch/arm/mach-socfpga/fpga_manager.c | 78 ++++ arch/arm/mach-socfpga/freeze_controller.c | 213 ++++++++++ arch/arm/mach-socfpga/misc.c | 289 +++++++++++++ arch/arm/mach-socfpga/reset_manager.c | 139 ++++++ arch/arm/mach-socfpga/scan_manager.c | 209 +++++++++ arch/arm/mach-socfpga/spl.c | 229 ++++++++++ arch/arm/mach-socfpga/system_manager.c | 77 ++++ arch/arm/mach-socfpga/timer.c | 24 ++ arch/arm/mach-socfpga/u-boot-spl.lds | 45 ++ include/configs/socfpga_common.h | 2 +- 25 files changed, 1877 insertions(+), 1877 deletions(-) delete mode 100644 arch/arm/cpu/armv7/socfpga/Makefile delete mode 100644 arch/arm/cpu/armv7/socfpga/clock_manager.c delete mode 100644 arch/arm/cpu/armv7/socfpga/fpga_manager.c delete mode 100644 arch/arm/cpu/armv7/socfpga/freeze_controller.c delete mode 100644 arch/arm/cpu/armv7/socfpga/misc.c delete mode 100644 arch/arm/cpu/armv7/socfpga/reset_manager.c delete mode 100644 arch/arm/cpu/armv7/socfpga/scan_manager.c delete mode 100644 arch/arm/cpu/armv7/socfpga/spl.c delete mode 100644 arch/arm/cpu/armv7/socfpga/system_manager.c delete mode 100644 arch/arm/cpu/armv7/socfpga/timer.c delete mode 100644 arch/arm/cpu/armv7/socfpga/u-boot-spl.lds create mode 100644 arch/arm/mach-socfpga/Makefile create mode 100644 arch/arm/mach-socfpga/clock_manager.c create mode 100644 arch/arm/mach-socfpga/fpga_manager.c create mode 100644 arch/arm/mach-socfpga/freeze_controller.c create mode 100644 arch/arm/mach-socfpga/misc.c create mode 100644 arch/arm/mach-socfpga/reset_manager.c create mode 100644 arch/arm/mach-socfpga/scan_manager.c create mode 100644 arch/arm/mach-socfpga/spl.c create mode 100644 arch/arm/mach-socfpga/system_manager.c create mode 100644 arch/arm/mach-socfpga/timer.c create mode 100644 arch/arm/mach-socfpga/u-boot-spl.lds diff --git a/arch/arm/Makefile b/arch/arm/Makefile index 8ff94a3c0b..6f30098f0a 100644 --- a/arch/arm/Makefile +++ b/arch/arm/Makefile @@ -53,6 +53,7 @@ machine-$(CONFIG_ARMADA_XP) += mvebu machine-$(CONFIG_ARCH_NOMADIK) += nomadik # TODO: rename CONFIG_ORION5X -> CONFIG_ARCH_ORION5X machine-$(CONFIG_ORION5X) += orion5x +machine-$(CONFIG_ARCH_SOCFPGA) += socfpga machine-$(CONFIG_TEGRA) += tegra machine-$(CONFIG_ARCH_UNIPHIER) += uniphier machine-$(CONFIG_ARCH_VERSATILE) += versatile diff --git a/arch/arm/cpu/armv7/Makefile b/arch/arm/cpu/armv7/Makefile index d335845d93..64a283f866 100644 --- a/arch/arm/cpu/armv7/Makefile +++ b/arch/arm/cpu/armv7/Makefile @@ -50,7 +50,6 @@ obj-$(CONFIG_OMAP44XX) += omap4/ obj-$(CONFIG_OMAP54XX) += omap5/ obj-$(CONFIG_RMOBILE) += rmobile/ obj-$(CONFIG_ARCH_S5PC1XX) += s5pc1xx/ -obj-$(CONFIG_SOCFPGA) += socfpga/ obj-$(if $(filter stv0991,$(SOC)),y) += stv0991/ obj-$(CONFIG_ARCH_SUNXI) += sunxi/ obj-$(CONFIG_U8500) += u8500/ diff --git a/arch/arm/cpu/armv7/socfpga/Makefile b/arch/arm/cpu/armv7/socfpga/Makefile deleted file mode 100644 index 7524ef90e4..0000000000 --- a/arch/arm/cpu/armv7/socfpga/Makefile +++ /dev/null @@ -1,12 +0,0 @@ -# -# (C) Copyright 2000-2003 -# Wolfgang Denk, DENX Software Engineering, wd@denx.de. -# -# Copyright (C) 2012 Altera Corporation -# -# SPDX-License-Identifier: GPL-2.0+ -# - -obj-y += misc.o timer.o reset_manager.o system_manager.o clock_manager.o \ - fpga_manager.o -obj-$(CONFIG_SPL_BUILD) += spl.o freeze_controller.o scan_manager.o diff --git a/arch/arm/cpu/armv7/socfpga/clock_manager.c b/arch/arm/cpu/armv7/socfpga/clock_manager.c deleted file mode 100644 index fa3b93a257..0000000000 --- a/arch/arm/cpu/armv7/socfpga/clock_manager.c +++ /dev/null @@ -1,560 +0,0 @@ -/* - * Copyright (C) 2013 Altera Corporation - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include -#include -#include - -DECLARE_GLOBAL_DATA_PTR; - -static const struct socfpga_clock_manager *clock_manager_base = - (struct socfpga_clock_manager *)SOCFPGA_CLKMGR_ADDRESS; - -static void cm_wait_for_lock(uint32_t mask) -{ - register uint32_t inter_val; - uint32_t retry = 0; - do { - inter_val = readl(&clock_manager_base->inter) & mask; - if (inter_val == mask) - retry++; - else - retry = 0; - if (retry >= 10) - break; - } while (1); -} - -/* function to poll in the fsm busy bit */ -static void cm_wait_for_fsm(void) -{ - while (readl(&clock_manager_base->stat) & CLKMGR_STAT_BUSY) - ; -} - -/* - * function to write the bypass register which requires a poll of the - * busy bit - */ -static void cm_write_bypass(uint32_t val) -{ - writel(val, &clock_manager_base->bypass); - cm_wait_for_fsm(); -} - -/* function to write the ctrl register which requires a poll of the busy bit */ -static void cm_write_ctrl(uint32_t val) -{ - writel(val, &clock_manager_base->ctrl); - cm_wait_for_fsm(); -} - -/* function to write a clock register that has phase information */ -static void cm_write_with_phase(uint32_t value, - uint32_t reg_address, uint32_t mask) -{ - /* poll until phase is zero */ - while (readl(reg_address) & mask) - ; - - writel(value, reg_address); - - while (readl(reg_address) & mask) - ; -} - -/* - * Setup clocks while making no assumptions about previous state of the clocks. - * - * Start by being paranoid and gate all sw managed clocks - * Put all plls in bypass - * Put all plls VCO registers back to reset value (bandgap power down). - * Put peripheral and main pll src to reset value to avoid glitch. - * Delay 5 us. - * Deassert bandgap power down and set numerator and denominator - * Start 7 us timer. - * set internal dividers - * Wait for 7 us timer. - * Enable plls - * Set external dividers while plls are locking - * Wait for pll lock - * Assert/deassert outreset all. - * Take all pll's out of bypass - * Clear safe mode - * set source main and peripheral clocks - * Ungate clocks - */ - -void cm_basic_init(const cm_config_t *cfg) -{ - uint32_t start, timeout; - - /* Start by being paranoid and gate all sw managed clocks */ - - /* - * We need to disable nandclk - * and then do another apb access before disabling - * gatting off the rest of the periperal clocks. - */ - writel(~CLKMGR_PERPLLGRP_EN_NANDCLK_MASK & - readl(&clock_manager_base->per_pll.en), - &clock_manager_base->per_pll.en); - - /* DO NOT GATE OFF DEBUG CLOCKS & BRIDGE CLOCKS */ - writel(CLKMGR_MAINPLLGRP_EN_DBGTIMERCLK_MASK | - CLKMGR_MAINPLLGRP_EN_DBGTRACECLK_MASK | - CLKMGR_MAINPLLGRP_EN_DBGCLK_MASK | - CLKMGR_MAINPLLGRP_EN_DBGATCLK_MASK | - CLKMGR_MAINPLLGRP_EN_S2FUSER0CLK_MASK | - CLKMGR_MAINPLLGRP_EN_L4MPCLK_MASK, - &clock_manager_base->main_pll.en); - - writel(0, &clock_manager_base->sdr_pll.en); - - /* now we can gate off the rest of the peripheral clocks */ - writel(0, &clock_manager_base->per_pll.en); - - /* Put all plls in bypass */ - cm_write_bypass(CLKMGR_BYPASS_PERPLL | CLKMGR_BYPASS_SDRPLL | - CLKMGR_BYPASS_MAINPLL); - - /* Put all plls VCO registers back to reset value. */ - writel(CLKMGR_MAINPLLGRP_VCO_RESET_VALUE & - ~CLKMGR_MAINPLLGRP_VCO_REGEXTSEL_MASK, - &clock_manager_base->main_pll.vco); - writel(CLKMGR_PERPLLGRP_VCO_RESET_VALUE & - ~CLKMGR_PERPLLGRP_VCO_REGEXTSEL_MASK, - &clock_manager_base->per_pll.vco); - writel(CLKMGR_SDRPLLGRP_VCO_RESET_VALUE & - ~CLKMGR_SDRPLLGRP_VCO_REGEXTSEL_MASK, - &clock_manager_base->sdr_pll.vco); - - /* - * The clocks to the flash devices and the L4_MAIN clocks can - * glitch when coming out of safe mode if their source values - * are different from their reset value. So the trick it to - * put them back to their reset state, and change input - * after exiting safe mode but before ungating the clocks. - */ - writel(CLKMGR_PERPLLGRP_SRC_RESET_VALUE, - &clock_manager_base->per_pll.src); - writel(CLKMGR_MAINPLLGRP_L4SRC_RESET_VALUE, - &clock_manager_base->main_pll.l4src); - - /* read back for the required 5 us delay. */ - readl(&clock_manager_base->main_pll.vco); - readl(&clock_manager_base->per_pll.vco); - readl(&clock_manager_base->sdr_pll.vco); - - - /* - * We made sure bgpwr down was assert for 5 us. Now deassert BG PWR DN - * with numerator and denominator. - */ - writel(cfg->main_vco_base, &clock_manager_base->main_pll.vco); - writel(cfg->peri_vco_base, &clock_manager_base->per_pll.vco); - writel(cfg->sdram_vco_base, &clock_manager_base->sdr_pll.vco); - - /* - * Time starts here - * must wait 7 us from BGPWRDN_SET(0) to VCO_ENABLE_SET(1) - */ - start = get_timer(0); - /* timeout in unit of us as CONFIG_SYS_HZ = 1000*1000 */ - timeout = 7; - - /* main mpu */ - writel(cfg->mpuclk, &clock_manager_base->main_pll.mpuclk); - - /* main main clock */ - writel(cfg->mainclk, &clock_manager_base->main_pll.mainclk); - - /* main for dbg */ - writel(cfg->dbgatclk, &clock_manager_base->main_pll.dbgatclk); - - /* main for cfgs2fuser0clk */ - writel(cfg->cfg2fuser0clk, - &clock_manager_base->main_pll.cfgs2fuser0clk); - - /* Peri emac0 50 MHz default to RMII */ - writel(cfg->emac0clk, &clock_manager_base->per_pll.emac0clk); - - /* Peri emac1 50 MHz default to RMII */ - writel(cfg->emac1clk, &clock_manager_base->per_pll.emac1clk); - - /* Peri QSPI */ - writel(cfg->mainqspiclk, &clock_manager_base->main_pll.mainqspiclk); - - writel(cfg->perqspiclk, &clock_manager_base->per_pll.perqspiclk); - - /* Peri pernandsdmmcclk */ - writel(cfg->mainnandsdmmcclk, - &clock_manager_base->main_pll.mainnandsdmmcclk); - - writel(cfg->pernandsdmmcclk, - &clock_manager_base->per_pll.pernandsdmmcclk); - - /* Peri perbaseclk */ - writel(cfg->perbaseclk, &clock_manager_base->per_pll.perbaseclk); - - /* Peri s2fuser1clk */ - writel(cfg->s2fuser1clk, &clock_manager_base->per_pll.s2fuser1clk); - - /* 7 us must have elapsed before we can enable the VCO */ - while (get_timer(start) < timeout) - ; - - /* Enable vco */ - /* main pll vco */ - writel(cfg->main_vco_base | CLKMGR_MAINPLLGRP_VCO_EN, - &clock_manager_base->main_pll.vco); - - /* periferal pll */ - writel(cfg->peri_vco_base | CLKMGR_MAINPLLGRP_VCO_EN, - &clock_manager_base->per_pll.vco); - - /* sdram pll vco */ - writel(cfg->sdram_vco_base | CLKMGR_MAINPLLGRP_VCO_EN, - &clock_manager_base->sdr_pll.vco); - - /* L3 MP and L3 SP */ - writel(cfg->maindiv, &clock_manager_base->main_pll.maindiv); - - writel(cfg->dbgdiv, &clock_manager_base->main_pll.dbgdiv); - - writel(cfg->tracediv, &clock_manager_base->main_pll.tracediv); - - /* L4 MP, L4 SP, can0, and can1 */ - writel(cfg->perdiv, &clock_manager_base->per_pll.div); - - writel(cfg->gpiodiv, &clock_manager_base->per_pll.gpiodiv); - -#define LOCKED_MASK \ - (CLKMGR_INTER_SDRPLLLOCKED_MASK | \ - CLKMGR_INTER_PERPLLLOCKED_MASK | \ - CLKMGR_INTER_MAINPLLLOCKED_MASK) - - cm_wait_for_lock(LOCKED_MASK); - - /* write the sdram clock counters before toggling outreset all */ - writel(cfg->ddrdqsclk & CLKMGR_SDRPLLGRP_DDRDQSCLK_CNT_MASK, - &clock_manager_base->sdr_pll.ddrdqsclk); - - writel(cfg->ddr2xdqsclk & CLKMGR_SDRPLLGRP_DDR2XDQSCLK_CNT_MASK, - &clock_manager_base->sdr_pll.ddr2xdqsclk); - - writel(cfg->ddrdqclk & CLKMGR_SDRPLLGRP_DDRDQCLK_CNT_MASK, - &clock_manager_base->sdr_pll.ddrdqclk); - - writel(cfg->s2fuser2clk & CLKMGR_SDRPLLGRP_S2FUSER2CLK_CNT_MASK, - &clock_manager_base->sdr_pll.s2fuser2clk); - - /* - * after locking, but before taking out of bypass - * assert/deassert outresetall - */ - uint32_t mainvco = readl(&clock_manager_base->main_pll.vco); - - /* assert main outresetall */ - writel(mainvco | CLKMGR_MAINPLLGRP_VCO_OUTRESETALL_MASK, - &clock_manager_base->main_pll.vco); - - uint32_t periphvco = readl(&clock_manager_base->per_pll.vco); - - /* assert pheriph outresetall */ - writel(periphvco | CLKMGR_PERPLLGRP_VCO_OUTRESETALL_MASK, - &clock_manager_base->per_pll.vco); - - /* assert sdram outresetall */ - writel(cfg->sdram_vco_base | CLKMGR_MAINPLLGRP_VCO_EN| - CLKMGR_SDRPLLGRP_VCO_OUTRESETALL, - &clock_manager_base->sdr_pll.vco); - - /* deassert main outresetall */ - writel(mainvco & ~CLKMGR_MAINPLLGRP_VCO_OUTRESETALL_MASK, - &clock_manager_base->main_pll.vco); - - /* deassert pheriph outresetall */ - writel(periphvco & ~CLKMGR_PERPLLGRP_VCO_OUTRESETALL_MASK, - &clock_manager_base->per_pll.vco); - - /* deassert sdram outresetall */ - writel(cfg->sdram_vco_base | CLKMGR_MAINPLLGRP_VCO_EN, - &clock_manager_base->sdr_pll.vco); - - /* - * now that we've toggled outreset all, all the clocks - * are aligned nicely; so we can change any phase. - */ - cm_write_with_phase(cfg->ddrdqsclk, - (uint32_t)&clock_manager_base->sdr_pll.ddrdqsclk, - CLKMGR_SDRPLLGRP_DDRDQSCLK_PHASE_MASK); - - /* SDRAM DDR2XDQSCLK */ - cm_write_with_phase(cfg->ddr2xdqsclk, - (uint32_t)&clock_manager_base->sdr_pll.ddr2xdqsclk, - CLKMGR_SDRPLLGRP_DDR2XDQSCLK_PHASE_MASK); - - cm_write_with_phase(cfg->ddrdqclk, - (uint32_t)&clock_manager_base->sdr_pll.ddrdqclk, - CLKMGR_SDRPLLGRP_DDRDQCLK_PHASE_MASK); - - cm_write_with_phase(cfg->s2fuser2clk, - (uint32_t)&clock_manager_base->sdr_pll.s2fuser2clk, - CLKMGR_SDRPLLGRP_S2FUSER2CLK_PHASE_MASK); - - /* Take all three PLLs out of bypass when safe mode is cleared. */ - cm_write_bypass(0); - - /* clear safe mode */ - cm_write_ctrl(readl(&clock_manager_base->ctrl) | CLKMGR_CTRL_SAFEMODE); - - /* - * now that safe mode is clear with clocks gated - * it safe to change the source mux for the flashes the the L4_MAIN - */ - writel(cfg->persrc, &clock_manager_base->per_pll.src); - writel(cfg->l4src, &clock_manager_base->main_pll.l4src); - - /* Now ungate non-hw-managed clocks */ - writel(~0, &clock_manager_base->main_pll.en); - writel(~0, &clock_manager_base->per_pll.en); - writel(~0, &clock_manager_base->sdr_pll.en); - - /* Clear the loss of lock bits (write 1 to clear) */ - writel(CLKMGR_INTER_SDRPLLLOST_MASK | CLKMGR_INTER_PERPLLLOST_MASK | - CLKMGR_INTER_MAINPLLLOST_MASK, - &clock_manager_base->inter); -} - -static unsigned int cm_get_main_vco_clk_hz(void) -{ - uint32_t reg, clock; - - /* get the main VCO clock */ - reg = readl(&clock_manager_base->main_pll.vco); - clock = CONFIG_HPS_CLK_OSC1_HZ; - clock /= ((reg & CLKMGR_MAINPLLGRP_VCO_DENOM_MASK) >> - CLKMGR_MAINPLLGRP_VCO_DENOM_OFFSET) + 1; - clock *= ((reg & CLKMGR_MAINPLLGRP_VCO_NUMER_MASK) >> - CLKMGR_MAINPLLGRP_VCO_NUMER_OFFSET) + 1; - - return clock; -} - -static unsigned int cm_get_per_vco_clk_hz(void) -{ - uint32_t reg, clock = 0; - - /* identify PER PLL clock source */ - reg = readl(&clock_manager_base->per_pll.vco); - reg = (reg & CLKMGR_PERPLLGRP_VCO_SSRC_MASK) >> - CLKMGR_PERPLLGRP_VCO_SSRC_OFFSET; - if (reg == CLKMGR_VCO_SSRC_EOSC1) - clock = CONFIG_HPS_CLK_OSC1_HZ; - else if (reg == CLKMGR_VCO_SSRC_EOSC2) - clock = CONFIG_HPS_CLK_OSC2_HZ; - else if (reg == CLKMGR_VCO_SSRC_F2S) - clock = CONFIG_HPS_CLK_F2S_PER_REF_HZ; - - /* get the PER VCO clock */ - reg = readl(&clock_manager_base->per_pll.vco); - clock /= ((reg & CLKMGR_PERPLLGRP_VCO_DENOM_MASK) >> - CLKMGR_PERPLLGRP_VCO_DENOM_OFFSET) + 1; - clock *= ((reg & CLKMGR_PERPLLGRP_VCO_NUMER_MASK) >> - CLKMGR_PERPLLGRP_VCO_NUMER_OFFSET) + 1; - - return clock; -} - -unsigned long cm_get_mpu_clk_hz(void) -{ - uint32_t reg, clock; - - clock = cm_get_main_vco_clk_hz(); - - /* get the MPU clock */ - reg = readl(&clock_manager_base->altera.mpuclk); - clock /= (reg + 1); - reg = readl(&clock_manager_base->main_pll.mpuclk); - clock /= (reg + 1); - return clock; -} - -unsigned long cm_get_sdram_clk_hz(void) -{ - uint32_t reg, clock = 0; - - /* identify SDRAM PLL clock source */ - reg = readl(&clock_manager_base->sdr_pll.vco); - reg = (reg & CLKMGR_SDRPLLGRP_VCO_SSRC_MASK) >> - CLKMGR_SDRPLLGRP_VCO_SSRC_OFFSET; - if (reg == CLKMGR_VCO_SSRC_EOSC1) - clock = CONFIG_HPS_CLK_OSC1_HZ; - else if (reg == CLKMGR_VCO_SSRC_EOSC2) - clock = CONFIG_HPS_CLK_OSC2_HZ; - else if (reg == CLKMGR_VCO_SSRC_F2S) - clock = CONFIG_HPS_CLK_F2S_SDR_REF_HZ; - - /* get the SDRAM VCO clock */ - reg = readl(&clock_manager_base->sdr_pll.vco); - clock /= ((reg & CLKMGR_SDRPLLGRP_VCO_DENOM_MASK) >> - CLKMGR_SDRPLLGRP_VCO_DENOM_OFFSET) + 1; - clock *= ((reg & CLKMGR_SDRPLLGRP_VCO_NUMER_MASK) >> - CLKMGR_SDRPLLGRP_VCO_NUMER_OFFSET) + 1; - - /* get the SDRAM (DDR_DQS) clock */ - reg = readl(&clock_manager_base->sdr_pll.ddrdqsclk); - reg = (reg & CLKMGR_SDRPLLGRP_DDRDQSCLK_CNT_MASK) >> - CLKMGR_SDRPLLGRP_DDRDQSCLK_CNT_OFFSET; - clock /= (reg + 1); - - return clock; -} - -unsigned int cm_get_l4_sp_clk_hz(void) -{ - uint32_t reg, clock = 0; - - /* identify the source of L4 SP clock */ - reg = readl(&clock_manager_base->main_pll.l4src); - reg = (reg & CLKMGR_MAINPLLGRP_L4SRC_L4SP) >> - CLKMGR_MAINPLLGRP_L4SRC_L4SP_OFFSET; - - if (reg == CLKMGR_L4_SP_CLK_SRC_MAINPLL) { - clock = cm_get_main_vco_clk_hz(); - - /* get the clock prior L4 SP divider (main clk) */ - reg = readl(&clock_manager_base->altera.mainclk); - clock /= (reg + 1); - reg = readl(&clock_manager_base->main_pll.mainclk); - clock /= (reg + 1); - } else if (reg == CLKMGR_L4_SP_CLK_SRC_PERPLL) { - clock = cm_get_per_vco_clk_hz(); - - /* get the clock prior L4 SP divider (periph_base_clk) */ - reg = readl(&clock_manager_base->per_pll.perbaseclk); - clock /= (reg + 1); - } - - /* get the L4 SP clock which supplied to UART */ - reg = readl(&clock_manager_base->main_pll.maindiv); - reg = (reg & CLKMGR_MAINPLLGRP_MAINDIV_L4SPCLK_MASK) >> - CLKMGR_MAINPLLGRP_MAINDIV_L4SPCLK_OFFSET; - clock = clock / (1 << reg); - - return clock; -} - -unsigned int cm_get_mmc_controller_clk_hz(void) -{ - uint32_t reg, clock = 0; - - /* identify the source of MMC clock */ - reg = readl(&clock_manager_base->per_pll.src); - reg = (reg & CLKMGR_PERPLLGRP_SRC_SDMMC_MASK) >> - CLKMGR_PERPLLGRP_SRC_SDMMC_OFFSET; - - if (reg == CLKMGR_SDMMC_CLK_SRC_F2S) { - clock = CONFIG_HPS_CLK_F2S_PER_REF_HZ; - } else if (reg == CLKMGR_SDMMC_CLK_SRC_MAIN) { - clock = cm_get_main_vco_clk_hz(); - - /* get the SDMMC clock */ - reg = readl(&clock_manager_base->main_pll.mainnandsdmmcclk); - clock /= (reg + 1); - } else if (reg == CLKMGR_SDMMC_CLK_SRC_PER) { - clock = cm_get_per_vco_clk_hz(); - - /* get the SDMMC clock */ - reg = readl(&clock_manager_base->per_pll.pernandsdmmcclk); - clock /= (reg + 1); - } - - /* further divide by 4 as we have fixed divider at wrapper */ - clock /= 4; - return clock; -} - -unsigned int cm_get_qspi_controller_clk_hz(void) -{ - uint32_t reg, clock = 0; - - /* identify the source of QSPI clock */ - reg = readl(&clock_manager_base->per_pll.src); - reg = (reg & CLKMGR_PERPLLGRP_SRC_QSPI_MASK) >> - CLKMGR_PERPLLGRP_SRC_QSPI_OFFSET; - - if (reg == CLKMGR_QSPI_CLK_SRC_F2S) { - clock = CONFIG_HPS_CLK_F2S_PER_REF_HZ; - } else if (reg == CLKMGR_QSPI_CLK_SRC_MAIN) { - clock = cm_get_main_vco_clk_hz(); - - /* get the qspi clock */ - reg = readl(&clock_manager_base->main_pll.mainqspiclk); - clock /= (reg + 1); - } else if (reg == CLKMGR_QSPI_CLK_SRC_PER) { - clock = cm_get_per_vco_clk_hz(); - - /* get the qspi clock */ - reg = readl(&clock_manager_base->per_pll.perqspiclk); - clock /= (reg + 1); - } - - return clock; -} - -unsigned int cm_get_spi_controller_clk_hz(void) -{ - uint32_t reg, clock = 0; - - clock = cm_get_per_vco_clk_hz(); - - /* get the clock prior L4 SP divider (periph_base_clk) */ - reg = readl(&clock_manager_base->per_pll.perbaseclk); - clock /= (reg + 1); - - return clock; -} - -static void cm_print_clock_quick_summary(void) -{ - printf("MPU %10ld kHz\n", cm_get_mpu_clk_hz() / 1000); - printf("DDR %10ld kHz\n", cm_get_sdram_clk_hz() / 1000); - printf("EOSC1 %8d kHz\n", CONFIG_HPS_CLK_OSC1_HZ / 1000); - printf("EOSC2 %8d kHz\n", CONFIG_HPS_CLK_OSC2_HZ / 1000); - printf("F2S_SDR_REF %8d kHz\n", CONFIG_HPS_CLK_F2S_SDR_REF_HZ / 1000); - printf("F2S_PER_REF %8d kHz\n", CONFIG_HPS_CLK_F2S_PER_REF_HZ / 1000); - printf("MMC %8d kHz\n", cm_get_mmc_controller_clk_hz() / 1000); - printf("QSPI %8d kHz\n", cm_get_qspi_controller_clk_hz() / 1000); - printf("UART %8d kHz\n", cm_get_l4_sp_clk_hz() / 1000); - printf("SPI %8d kHz\n", cm_get_spi_controller_clk_hz() / 1000); -} - -int set_cpu_clk_info(void) -{ - /* Calculate the clock frequencies required for drivers */ - cm_get_l4_sp_clk_hz(); - cm_get_mmc_controller_clk_hz(); - - gd->bd->bi_arm_freq = cm_get_mpu_clk_hz() / 1000000; - gd->bd->bi_dsp_freq = 0; - gd->bd->bi_ddr_freq = cm_get_sdram_clk_hz() / 1000000; - - return 0; -} - -int do_showclocks(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) -{ - cm_print_clock_quick_summary(); - return 0; -} - -U_BOOT_CMD( - clocks, CONFIG_SYS_MAXARGS, 1, do_showclocks, - "display clocks", - "" -); diff --git a/arch/arm/cpu/armv7/socfpga/fpga_manager.c b/arch/arm/cpu/armv7/socfpga/fpga_manager.c deleted file mode 100644 index 43fd2fedee..0000000000 --- a/arch/arm/cpu/armv7/socfpga/fpga_manager.c +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright (C) 2012 Altera Corporation - * All rights reserved. - * - * This file contains only support functions used also by the SoCFPGA - * platform code, the real meat is located in drivers/fpga/socfpga.c . - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include -#include -#include -#include -#include -#include - -DECLARE_GLOBAL_DATA_PTR; - -/* Timeout count */ -#define FPGA_TIMEOUT_CNT 0x1000000 - -static struct socfpga_fpga_manager *fpgamgr_regs = - (struct socfpga_fpga_manager *)SOCFPGA_FPGAMGRREGS_ADDRESS; - -/* Check whether FPGA Init_Done signal is high */ -static int is_fpgamgr_initdone_high(void) -{ - unsigned long val; - - val = readl(&fpgamgr_regs->gpio_ext_porta); - return val & FPGAMGRREGS_MON_GPIO_EXT_PORTA_ID_MASK; -} - -/* Get the FPGA mode */ -int fpgamgr_get_mode(void) -{ - unsigned long val; - - val = readl(&fpgamgr_regs->stat); - return val & FPGAMGRREGS_STAT_MODE_MASK; -} - -/* Check whether FPGA is ready to be accessed */ -int fpgamgr_test_fpga_ready(void) -{ - /* Check for init done signal */ - if (!is_fpgamgr_initdone_high()) - return 0; - - /* Check again to avoid false glitches */ - if (!is_fpgamgr_initdone_high()) - return 0; - - if (fpgamgr_get_mode() != FPGAMGRREGS_MODE_USERMODE) - return 0; - - return 1; -} - -/* Poll until FPGA is ready to be accessed or timeout occurred */ -int fpgamgr_poll_fpga_ready(void) -{ - unsigned long i; - - /* If FPGA is blank, wait till WD invoke warm reset */ - for (i = 0; i < FPGA_TIMEOUT_CNT; i++) { - /* check for init done signal */ - if (!is_fpgamgr_initdone_high()) - continue; - /* check again to avoid false glitches */ - if (!is_fpgamgr_initdone_high()) - continue; - return 1; - } - - return 0; -} diff --git a/arch/arm/cpu/armv7/socfpga/freeze_controller.c b/arch/arm/cpu/armv7/socfpga/freeze_controller.c deleted file mode 100644 index 0be643c817..0000000000 --- a/arch/arm/cpu/armv7/socfpga/freeze_controller.c +++ /dev/null @@ -1,213 +0,0 @@ -/* - * Copyright (C) 2013 Altera Corporation - * - * SPDX-License-Identifier: GPL-2.0+ - */ - - -#include -#include -#include -#include -#include - -DECLARE_GLOBAL_DATA_PTR; - -static const struct socfpga_freeze_controller *freeze_controller_base = - (void *)(SOCFPGA_SYSMGR_ADDRESS + SYSMGR_FRZCTRL_ADDRESS); - -/* - * Default state from cold reset is FREEZE_ALL; the global - * flag is set to TRUE to indicate the IO banks are frozen - */ -static uint32_t frzctrl_channel_freeze[FREEZE_CHANNEL_NUM] - = { FREEZE_CTRL_FROZEN, FREEZE_CTRL_FROZEN, - FREEZE_CTRL_FROZEN, FREEZE_CTRL_FROZEN}; - -/* Freeze HPS IOs */ -void sys_mgr_frzctrl_freeze_req(void) -{ - u32 ioctrl_reg_offset; - u32 reg_value; - u32 reg_cfg_mask; - u32 channel_id; - - /* select software FSM */ - writel(SYSMGR_FRZCTRL_SRC_VIO1_ENUM_SW, &freeze_controller_base->src); - - /* Freeze channel 0 to 2 */ - for (channel_id = 0; channel_id <= 2; channel_id++) { - ioctrl_reg_offset = (u32)( - &freeze_controller_base->vioctrl + channel_id); - - /* - * Assert active low enrnsl, plniotri - * and niotri signals - */ - reg_cfg_mask = - SYSMGR_FRZCTRL_VIOCTRL_SLEW_MASK - | SYSMGR_FRZCTRL_VIOCTRL_WKPULLUP_MASK - | SYSMGR_FRZCTRL_VIOCTRL_TRISTATE_MASK; - clrbits_le32(ioctrl_reg_offset, reg_cfg_mask); - - /* - * Note: Delay for 20ns at min - * Assert active low bhniotri signal and de-assert - * active high csrdone - */ - reg_cfg_mask - = SYSMGR_FRZCTRL_VIOCTRL_BUSHOLD_MASK - | SYSMGR_FRZCTRL_VIOCTRL_CFG_MASK; - clrbits_le32(ioctrl_reg_offset, reg_cfg_mask); - - /* Set global flag to indicate channel is frozen */ - frzctrl_channel_freeze[channel_id] = FREEZE_CTRL_FROZEN; - } - - /* Freeze channel 3 */ - /* - * Assert active low enrnsl, plniotri and - * niotri signals - */ - reg_cfg_mask - = SYSMGR_FRZCTRL_HIOCTRL_SLEW_MASK - | SYSMGR_FRZCTRL_HIOCTRL_WKPULLUP_MASK - | SYSMGR_FRZCTRL_HIOCTRL_TRISTATE_MASK; - clrbits_le32(&freeze_controller_base->hioctrl, reg_cfg_mask); - - /* - * assert active low bhniotri & nfrzdrv signals, - * de-assert active high csrdone and assert - * active high frzreg and nfrzdrv signals - */ - reg_value = readl(&freeze_controller_base->hioctrl); - reg_cfg_mask - = SYSMGR_FRZCTRL_HIOCTRL_BUSHOLD_MASK - | SYSMGR_FRZCTRL_HIOCTRL_CFG_MASK; - reg_value - = (reg_value & ~reg_cfg_mask) - | SYSMGR_FRZCTRL_HIOCTRL_REGRST_MASK - | SYSMGR_FRZCTRL_HIOCTRL_OCTRST_MASK; - writel(reg_value, &freeze_controller_base->hioctrl); - - /* - * assert active high reinit signal and de-assert - * active high pllbiasen signals - */ - reg_value = readl(&freeze_controller_base->hioctrl); - reg_value - = (reg_value & - ~SYSMGR_FRZCTRL_HIOCTRL_OCT_CFGEN_CALSTART_MASK) - | SYSMGR_FRZCTRL_HIOCTRL_DLLRST_MASK; - writel(reg_value, &freeze_controller_base->hioctrl); - - /* Set global flag to indicate channel is frozen */ - frzctrl_channel_freeze[channel_id] = FREEZE_CTRL_FROZEN; -} - -/* Unfreeze/Thaw HPS IOs */ -void sys_mgr_frzctrl_thaw_req(void) -{ - u32 ioctrl_reg_offset; - u32 reg_cfg_mask; - u32 reg_value; - u32 channel_id; - - /* select software FSM */ - writel(SYSMGR_FRZCTRL_SRC_VIO1_ENUM_SW, &freeze_controller_base->src); - - /* Thaw channel 0 to 2 */ - for (channel_id = 0; channel_id <= 2; channel_id++) { - ioctrl_reg_offset - = (u32)(&freeze_controller_base->vioctrl + channel_id); - - /* - * Assert active low bhniotri signal and - * de-assert active high csrdone - */ - reg_cfg_mask - = SYSMGR_FRZCTRL_VIOCTRL_BUSHOLD_MASK - | SYSMGR_FRZCTRL_VIOCTRL_CFG_MASK; - setbits_le32(ioctrl_reg_offset, reg_cfg_mask); - - /* - * Note: Delay for 20ns at min - * de-assert active low plniotri and niotri signals - */ - reg_cfg_mask - = SYSMGR_FRZCTRL_VIOCTRL_WKPULLUP_MASK - | SYSMGR_FRZCTRL_VIOCTRL_TRISTATE_MASK; - setbits_le32(ioctrl_reg_offset, reg_cfg_mask); - - /* - * Note: Delay for 20ns at min - * de-assert active low enrnsl signal - */ - setbits_le32(ioctrl_reg_offset, - SYSMGR_FRZCTRL_VIOCTRL_SLEW_MASK); - - /* Set global flag to indicate channel is thawed */ - frzctrl_channel_freeze[channel_id] = FREEZE_CTRL_THAWED; - } - - /* Thaw channel 3 */ - /* de-assert active high reinit signal */ - clrbits_le32(&freeze_controller_base->hioctrl, - SYSMGR_FRZCTRL_HIOCTRL_DLLRST_MASK); - - /* - * Note: Delay for 40ns at min - * assert active high pllbiasen signals - */ - setbits_le32(&freeze_controller_base->hioctrl, - SYSMGR_FRZCTRL_HIOCTRL_OCT_CFGEN_CALSTART_MASK); - - /* - * Delay 1000 intosc. intosc is based on eosc1 - * Use worst case which is fatest eosc1=50MHz, delay required - * is 1/50MHz * 1000 = 20us - */ - udelay(20); - - /* - * de-assert active low bhniotri signals, - * assert active high csrdone and nfrzdrv signal - */ - reg_value = readl(&freeze_controller_base->hioctrl); - reg_value = (reg_value - | SYSMGR_FRZCTRL_HIOCTRL_BUSHOLD_MASK - | SYSMGR_FRZCTRL_HIOCTRL_CFG_MASK) - & ~SYSMGR_FRZCTRL_HIOCTRL_OCTRST_MASK; - writel(reg_value, &freeze_controller_base->hioctrl); - - /* - * Delay 33 intosc - * Use worst case which is fatest eosc1=50MHz, delay required - * is 1/50MHz * 33 = 660ns ~= 1us - */ - udelay(1); - - /* de-assert active low plniotri and niotri signals */ - reg_cfg_mask - = SYSMGR_FRZCTRL_HIOCTRL_WKPULLUP_MASK - | SYSMGR_FRZCTRL_HIOCTRL_TRISTATE_MASK; - - setbits_le32(&freeze_controller_base->hioctrl, reg_cfg_mask); - - /* - * Note: Delay for 40ns at min - * de-assert active high frzreg signal - */ - clrbits_le32(&freeze_controller_base->hioctrl, - SYSMGR_FRZCTRL_HIOCTRL_REGRST_MASK); - - /* - * Note: Delay for 40ns at min - * de-assert active low enrnsl signal - */ - setbits_le32(&freeze_controller_base->hioctrl, - SYSMGR_FRZCTRL_HIOCTRL_SLEW_MASK); - - /* Set global flag to indicate channel is thawed */ - frzctrl_channel_freeze[channel_id] = FREEZE_CTRL_THAWED; -} diff --git a/arch/arm/cpu/armv7/socfpga/misc.c b/arch/arm/cpu/armv7/socfpga/misc.c deleted file mode 100644 index 0f8b4d095d..0000000000 --- a/arch/arm/cpu/armv7/socfpga/misc.c +++ /dev/null @@ -1,289 +0,0 @@ -/* - * Copyright (C) 2012 Altera Corporation - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -DECLARE_GLOBAL_DATA_PTR; - -static struct pl310_regs *const pl310 = - (struct pl310_regs *)CONFIG_SYS_PL310_BASE; -static struct socfpga_system_manager *sysmgr_regs = - (struct socfpga_system_manager *)SOCFPGA_SYSMGR_ADDRESS; -static struct socfpga_reset_manager *reset_manager_base = - (struct socfpga_reset_manager *)SOCFPGA_RSTMGR_ADDRESS; -static struct nic301_registers *nic301_regs = - (struct nic301_registers *)SOCFPGA_L3REGS_ADDRESS; -static struct scu_registers *scu_regs = - (struct scu_registers *)SOCFPGA_MPUSCU_ADDRESS; - -int dram_init(void) -{ - gd->ram_size = get_ram_size((long *)PHYS_SDRAM_1, PHYS_SDRAM_1_SIZE); - return 0; -} - -void enable_caches(void) -{ -#ifndef CONFIG_SYS_ICACHE_OFF - icache_enable(); -#endif -#ifndef CONFIG_SYS_DCACHE_OFF - dcache_enable(); -#endif -} - -/* - * DesignWare Ethernet initialization - */ -#ifdef CONFIG_ETH_DESIGNWARE -int cpu_eth_init(bd_t *bis) -{ -#if CONFIG_EMAC_BASE == SOCFPGA_EMAC0_ADDRESS - const int physhift = SYSMGR_EMACGRP_CTRL_PHYSEL0_LSB; -#elif CONFIG_EMAC_BASE == SOCFPGA_EMAC1_ADDRESS - const int physhift = SYSMGR_EMACGRP_CTRL_PHYSEL1_LSB; -#else -#error "Incorrect CONFIG_EMAC_BASE value!" -#endif - - /* Initialize EMAC. This needs to be done at least once per boot. */ - - /* - * Putting the EMAC controller to reset when configuring the PHY - * interface select at System Manager - */ - socfpga_emac_reset(1); - - /* Clearing emac0 PHY interface select to 0 */ - clrbits_le32(&sysmgr_regs->emacgrp_ctrl, - SYSMGR_EMACGRP_CTRL_PHYSEL_MASK << physhift); - - /* configure to PHY interface select choosed */ - setbits_le32(&sysmgr_regs->emacgrp_ctrl, - SYSMGR_EMACGRP_CTRL_PHYSEL_ENUM_RGMII << physhift); - - /* Release the EMAC controller from reset */ - socfpga_emac_reset(0); - - /* initialize and register the emac */ - return designware_initialize(CONFIG_EMAC_BASE, - CONFIG_PHY_INTERFACE_MODE); -} -#endif - -#ifdef CONFIG_DWMMC -/* - * Initializes MMC controllers. - * to override, implement board_mmc_init() - */ -int cpu_mmc_init(bd_t *bis) -{ - return socfpga_dwmmc_init(SOCFPGA_SDMMC_ADDRESS, - CONFIG_HPS_SDMMC_BUSWIDTH, 0); -} -#endif - -#if defined(CONFIG_DISPLAY_CPUINFO) -/* - * Print CPU information - */ -int print_cpuinfo(void) -{ - puts("CPU: Altera SoCFPGA Platform\n"); - return 0; -} -#endif - -#if defined(CONFIG_SYS_CONSOLE_IS_IN_ENV) && \ -defined(CONFIG_SYS_CONSOLE_OVERWRITE_ROUTINE) -int overwrite_console(void) -{ - return 0; -} -#endif - -#ifdef CONFIG_FPGA -/* - * FPGA programming support for SoC FPGA Cyclone V - */ -static Altera_desc altera_fpga[] = { - { - /* Family */ - Altera_SoCFPGA, - /* Interface type */ - fast_passive_parallel, - /* No limitation as additional data will be ignored */ - -1, - /* No device function table */ - NULL, - /* Base interface address specified in driver */ - NULL, - /* No cookie implementation */ - 0 - }, -}; - -/* add device descriptor to FPGA device table */ -static void socfpga_fpga_add(void) -{ - int i; - fpga_init(); - for (i = 0; i < ARRAY_SIZE(altera_fpga); i++) - fpga_add(fpga_altera, &altera_fpga[i]); -} -#else -static inline void socfpga_fpga_add(void) {} -#endif - -int arch_cpu_init(void) -{ -#ifdef CONFIG_HW_WATCHDOG - /* - * In case the watchdog is enabled, make sure to (re-)configure it - * so that the defined timeout is valid. Otherwise the SPL (Perloader) - * timeout value is still active which might too short for Linux - * booting. - */ - hw_watchdog_init(); -#else - /* - * If the HW watchdog is NOT enabled, make sure it is not running, - * for example because it was enabled in the preloader. This might - * trigger a watchdog-triggered reboot of Linux kernel later. - */ - socfpga_watchdog_reset(); -#endif - - return 0; -} - -/* - * Convert all NIC-301 AMBA slaves from secure to non-secure - */ -static void socfpga_nic301_slave_ns(void) -{ - writel(0x1, &nic301_regs->lwhps2fpgaregs); - writel(0x1, &nic301_regs->hps2fpgaregs); - writel(0x1, &nic301_regs->acp); - writel(0x1, &nic301_regs->rom); - writel(0x1, &nic301_regs->ocram); - writel(0x1, &nic301_regs->sdrdata); -} - -static uint32_t iswgrp_handoff[8]; - -int arch_early_init_r(void) -{ - int i; - for (i = 0; i < 8; i++) /* Cache initial SW setting regs */ - iswgrp_handoff[i] = readl(&sysmgr_regs->iswgrp_handoff[i]); - - socfpga_bridges_reset(1); - socfpga_nic301_slave_ns(); - - /* - * Private components security: - * U-Boot : configure private timer, global timer and cpu component - * access as non secure for kernel stage (as required by Linux) - */ - setbits_le32(&scu_regs->sacr, 0xfff); - - /* Configure the L2 controller to make SDRAM start at 0 */ -#ifdef CONFIG_SOCFPGA_VIRTUAL_TARGET - writel(0x2, &nic301_regs->remap); -#else - writel(0x1, &nic301_regs->remap); /* remap.mpuzero */ - writel(0x1, &pl310->pl310_addr_filter_start); -#endif - - /* Add device descriptor to FPGA device table */ - socfpga_fpga_add(); - -#ifdef CONFIG_DESIGNWARE_SPI - /* Get Designware SPI controller out of reset */ - socfpga_spim_enable(); -#endif - - return 0; -} - -static void socfpga_sdram_apply_static_cfg(void) -{ - const uint32_t staticcfg = SOCFPGA_SDR_ADDRESS + 0x505c; - const uint32_t applymask = 0x8; - uint32_t val = readl(staticcfg) | applymask; - - /* - * 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"(staticcfg) : "memory", "cc"); -} - -int do_bridge(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) -{ - if (argc != 2) - return CMD_RET_USAGE; - - argv++; - - switch (*argv[0]) { - case 'e': /* Enable */ - writel(iswgrp_handoff[2], &sysmgr_regs->fpgaintfgrp_module); - socfpga_sdram_apply_static_cfg(); - writel(iswgrp_handoff[3], SOCFPGA_SDR_ADDRESS + 0x5080); - writel(iswgrp_handoff[0], &reset_manager_base->brg_mod_reset); - writel(iswgrp_handoff[1], &nic301_regs->remap); - break; - case 'd': /* Disable */ - writel(0, &sysmgr_regs->fpgaintfgrp_module); - writel(0, SOCFPGA_SDR_ADDRESS + 0x5080); - socfpga_sdram_apply_static_cfg(); - writel(0, &reset_manager_base->brg_mod_reset); - writel(1, &nic301_regs->remap); - break; - default: - return CMD_RET_USAGE; - } - - return 0; -} - -U_BOOT_CMD( - bridge, 2, 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" - "" -); diff --git a/arch/arm/cpu/armv7/socfpga/reset_manager.c b/arch/arm/cpu/armv7/socfpga/reset_manager.c deleted file mode 100644 index 45b352bdfc..0000000000 --- a/arch/arm/cpu/armv7/socfpga/reset_manager.c +++ /dev/null @@ -1,139 +0,0 @@ -/* - * Copyright (C) 2013 Altera Corporation - * - * SPDX-License-Identifier: GPL-2.0+ - */ - - -#include -#include -#include -#include - -DECLARE_GLOBAL_DATA_PTR; - -static const struct socfpga_reset_manager *reset_manager_base = - (void *)SOCFPGA_RSTMGR_ADDRESS; - -/* Toggle reset signal to watchdog (WDT is disabled after this operation!) */ -void socfpga_watchdog_reset(void) -{ - /* assert reset for watchdog */ - setbits_le32(&reset_manager_base->per_mod_reset, - 1 << RSTMGR_PERMODRST_L4WD0_LSB); - - /* deassert watchdog from reset (watchdog in not running state) */ - clrbits_le32(&reset_manager_base->per_mod_reset, - 1 << RSTMGR_PERMODRST_L4WD0_LSB); -} - -/* - * Write the reset manager register to cause reset - */ -void reset_cpu(ulong addr) -{ - /* request a warm reset */ - writel((1 << RSTMGR_CTRL_SWWARMRSTREQ_LSB), - &reset_manager_base->ctrl); - /* - * infinite loop here as watchdog will trigger and reset - * the processor - */ - while (1) - ; -} - -/* - * Release peripherals from reset based on handoff - */ -void reset_deassert_peripherals_handoff(void) -{ - writel(0, &reset_manager_base->per_mod_reset); -} - -#if defined(CONFIG_SOCFPGA_VIRTUAL_TARGET) -void socfpga_bridges_reset(int enable) -{ - /* For SoCFPGA-VT, this is NOP. */ -} -#else - -#define L3REGS_REMAP_LWHPS2FPGA_MASK 0x10 -#define L3REGS_REMAP_HPS2FPGA_MASK 0x08 -#define L3REGS_REMAP_OCRAM_MASK 0x01 - -void socfpga_bridges_reset(int enable) -{ - const uint32_t l3mask = L3REGS_REMAP_LWHPS2FPGA_MASK | - L3REGS_REMAP_HPS2FPGA_MASK | - L3REGS_REMAP_OCRAM_MASK; - - if (enable) { - /* brdmodrst */ - writel(0xffffffff, &reset_manager_base->brg_mod_reset); - } else { - /* Check signal from FPGA. */ - if (fpgamgr_poll_fpga_ready()) { - /* FPGA not ready. Wait for watchdog timeout. */ - printf("%s: fpga not ready, hanging.\n", __func__); - hang(); - } - - /* brdmodrst */ - writel(0, &reset_manager_base->brg_mod_reset); - - /* Remap the bridges into memory map */ - writel(l3mask, SOCFPGA_L3REGS_ADDRESS); - } -} -#endif - -/* Change the reset state for EMAC 0 and EMAC 1 */ -void socfpga_emac_reset(int enable) -{ - const void *reset = &reset_manager_base->per_mod_reset; - - if (enable) { - setbits_le32(reset, 1 << RSTMGR_PERMODRST_EMAC0_LSB); - setbits_le32(reset, 1 << RSTMGR_PERMODRST_EMAC1_LSB); - } else { -#if (CONFIG_EMAC_BASE == SOCFPGA_EMAC0_ADDRESS) - clrbits_le32(reset, 1 << RSTMGR_PERMODRST_EMAC0_LSB); -#elif (CONFIG_EMAC_BASE == SOCFPGA_EMAC1_ADDRESS) - clrbits_le32(reset, 1 << RSTMGR_PERMODRST_EMAC1_LSB); -#endif - } -} - -/* SPI Master enable (its held in reset by the preloader) */ -void socfpga_spim_enable(void) -{ - const void *reset = &reset_manager_base->per_mod_reset; - - clrbits_le32(reset, (1 << RSTMGR_PERMODRST_SPIM0_LSB) | - (1 << RSTMGR_PERMODRST_SPIM1_LSB)); -} - -/* Bring UART0 out of reset. */ -void socfpga_uart0_enable(void) -{ - const void *reset = &reset_manager_base->per_mod_reset; - - clrbits_le32(reset, 1 << RSTMGR_PERMODRST_UART0_LSB); -} - -/* Bring SDRAM controller out of reset. */ -void socfpga_sdram_enable(void) -{ - const void *reset = &reset_manager_base->per_mod_reset; - - clrbits_le32(reset, 1 << RSTMGR_PERMODRST_SDR_LSB); -} - -/* Bring OSC1 timer out of reset. */ -void socfpga_osc1timer_enable(void) -{ - const void *reset = &reset_manager_base->per_mod_reset; - - clrbits_le32(reset, 1 << RSTMGR_PERMODRST_OSC1TIMER0_LSB); -} diff --git a/arch/arm/cpu/armv7/socfpga/scan_manager.c b/arch/arm/cpu/armv7/socfpga/scan_manager.c deleted file mode 100644 index a820b1b1bf..0000000000 --- a/arch/arm/cpu/armv7/socfpga/scan_manager.c +++ /dev/null @@ -1,209 +0,0 @@ -/* - * Copyright (C) 2013 Altera Corporation - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include -#include -#include -#include - -DECLARE_GLOBAL_DATA_PTR; - -static const struct socfpga_scan_manager *scan_manager_base = - (void *)(SOCFPGA_SCANMGR_ADDRESS); -static const struct socfpga_freeze_controller *freeze_controller_base = - (void *)(SOCFPGA_SYSMGR_ADDRESS + SYSMGR_FRZCTRL_ADDRESS); - -/* - * Function to check IO scan chain engine status and wait if the engine is - * is active. Poll the IO scan chain engine till maximum iteration reached. - */ -static inline uint32_t scan_chain_engine_is_idle(uint32_t max_iter) -{ - uint32_t scanmgr_status; - - scanmgr_status = readl(&scan_manager_base->stat); - - /* Poll the engine until the scan engine is inactive */ - while (SCANMGR_STAT_ACTIVE_GET(scanmgr_status) || - (SCANMGR_STAT_WFIFOCNT_GET(scanmgr_status) > 0)) { - max_iter--; - if (max_iter > 0) - scanmgr_status = readl(&scan_manager_base->stat); - else - return 0; - } - return 1; -} - -/* Program HPS IO Scan Chain */ -uint32_t scan_mgr_io_scan_chain_prg( - uint32_t io_scan_chain_id, - uint32_t io_scan_chain_len_in_bits, - const uint32_t *iocsr_scan_chain) -{ - uint16_t tdi_tdo_header; - uint32_t io_program_iter; - uint32_t io_scan_chain_data_residual; - uint32_t residual; - uint32_t i; - uint32_t index = 0; - - /* - * De-assert reinit if the IO scan chain is intended for HIO. In - * this, its the chain 3. - */ - if (io_scan_chain_id == 3) - clrbits_le32(&freeze_controller_base->hioctrl, - SYSMGR_FRZCTRL_HIOCTRL_DLLRST_MASK); - - /* - * Check if the scan chain engine is inactive and the - * WFIFO is empty before enabling the IO scan chain - */ - if (!scan_chain_engine_is_idle(SCAN_MAX_DELAY)) - return 1; - - /* - * Enable IO Scan chain based on scan chain id - * Note: only one chain can be enabled at a time - */ - setbits_le32(&scan_manager_base->en, 1 << io_scan_chain_id); - - /* - * Calculate number of iteration needed for full 128-bit (4 x32-bits) - * bits shifting. Each TDI_TDO packet can shift in maximum 128-bits - */ - io_program_iter = io_scan_chain_len_in_bits >> - IO_SCAN_CHAIN_128BIT_SHIFT; - io_scan_chain_data_residual = io_scan_chain_len_in_bits & - IO_SCAN_CHAIN_128BIT_MASK; - - /* Construct TDI_TDO packet for 128-bit IO scan chain (2 bytes) */ - tdi_tdo_header = TDI_TDO_HEADER_FIRST_BYTE | - (TDI_TDO_MAX_PAYLOAD << TDI_TDO_HEADER_SECOND_BYTE_SHIFT); - - /* Program IO scan chain in 128-bit iteration */ - for (i = 0; i < io_program_iter; i++) { - /* write TDI_TDO packet header to scan manager */ - writel(tdi_tdo_header, &scan_manager_base->fifo_double_byte); - - /* calculate array index. Multiply by 4 as write 4 x 32bits */ - index = i * 4; - - /* write 4 successive 32-bit IO scan chain data into WFIFO */ - writel(iocsr_scan_chain[index], - &scan_manager_base->fifo_quad_byte); - writel(iocsr_scan_chain[index + 1], - &scan_manager_base->fifo_quad_byte); - writel(iocsr_scan_chain[index + 2], - &scan_manager_base->fifo_quad_byte); - writel(iocsr_scan_chain[index + 3], - &scan_manager_base->fifo_quad_byte); - - /* - * Check if the scan chain engine has completed the - * IO scan chain data shifting - */ - if (!scan_chain_engine_is_idle(SCAN_MAX_DELAY)) - goto error; - } - - /* Calculate array index for final TDI_TDO packet */ - index = io_program_iter * 4; - - /* Final TDI_TDO packet if any */ - if (io_scan_chain_data_residual) { - /* - * Calculate number of quad bytes FIFO write - * needed for the final TDI_TDO packet - */ - io_program_iter = io_scan_chain_data_residual >> - IO_SCAN_CHAIN_32BIT_SHIFT; - - /* - * Construct TDI_TDO packet for remaining IO - * scan chain (2 bytes) - */ - tdi_tdo_header = TDI_TDO_HEADER_FIRST_BYTE | - ((io_scan_chain_data_residual - 1) << - TDI_TDO_HEADER_SECOND_BYTE_SHIFT); - - /* - * Program the last part of IO scan chain write TDI_TDO packet - * header (2 bytes) to scan manager - */ - writel(tdi_tdo_header, &scan_manager_base->fifo_double_byte); - - for (i = 0; i < io_program_iter; i++) { - /* - * write remaining scan chain data into scan - * manager WFIFO with 4 bytes write - */ - writel(iocsr_scan_chain[index + i], - &scan_manager_base->fifo_quad_byte); - } - - index += io_program_iter; - residual = io_scan_chain_data_residual & - IO_SCAN_CHAIN_32BIT_MASK; - - if (IO_SCAN_CHAIN_PAYLOAD_24BIT < residual) { - /* - * write the last 4B scan chain data - * into scan manager WFIFO - */ - writel(iocsr_scan_chain[index], - &scan_manager_base->fifo_quad_byte); - } else { - /* - * write the remaining 1 - 3 bytes scan chain - * data into scan manager WFIFO byte by byte - * to prevent JTAG engine shifting unused data - * from the FIFO and mistaken the data as a - * valid command (even though unused bits are - * set to 0, but just to prevent hardware - * glitch) - */ - for (i = 0; i < residual; i += 8) { - writel(((iocsr_scan_chain[index] >> i) - & IO_SCAN_CHAIN_BYTE_MASK), - &scan_manager_base->fifo_single_byte); - } - } - - /* - * Check if the scan chain engine has completed the - * IO scan chain data shifting - */ - if (!scan_chain_engine_is_idle(SCAN_MAX_DELAY)) - goto error; - } - - /* Disable IO Scan chain when configuration done*/ - clrbits_le32(&scan_manager_base->en, 1 << io_scan_chain_id); - return 0; - -error: - /* Disable IO Scan chain when error detected */ - clrbits_le32(&scan_manager_base->en, 1 << io_scan_chain_id); - return 1; -} - -int scan_mgr_configure_iocsr(void) -{ - int status = 0; - - /* configure the IOCSR through scan chain */ - status |= scan_mgr_io_scan_chain_prg(0, - CONFIG_HPS_IOCSR_SCANCHAIN0_LENGTH, iocsr_scan_chain0_table); - status |= scan_mgr_io_scan_chain_prg(1, - CONFIG_HPS_IOCSR_SCANCHAIN1_LENGTH, iocsr_scan_chain1_table); - status |= scan_mgr_io_scan_chain_prg(2, - CONFIG_HPS_IOCSR_SCANCHAIN2_LENGTH, iocsr_scan_chain2_table); - status |= scan_mgr_io_scan_chain_prg(3, - CONFIG_HPS_IOCSR_SCANCHAIN3_LENGTH, iocsr_scan_chain3_table); - return status; -} diff --git a/arch/arm/cpu/armv7/socfpga/spl.c b/arch/arm/cpu/armv7/socfpga/spl.c deleted file mode 100644 index f994658452..0000000000 --- a/arch/arm/cpu/armv7/socfpga/spl.c +++ /dev/null @@ -1,229 +0,0 @@ -/* - * Copyright (C) 2012 Altera Corporation - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -DECLARE_GLOBAL_DATA_PTR; - -static struct pl310_regs *const pl310 = - (struct pl310_regs *)CONFIG_SYS_PL310_BASE; - -#define MAIN_VCO_BASE ( \ - (CONFIG_HPS_MAINPLLGRP_VCO_DENOM << \ - CLKMGR_MAINPLLGRP_VCO_DENOM_OFFSET) | \ - (CONFIG_HPS_MAINPLLGRP_VCO_NUMER << \ - CLKMGR_MAINPLLGRP_VCO_NUMER_OFFSET) \ - ) - -#define PERI_VCO_BASE ( \ - (CONFIG_HPS_PERPLLGRP_VCO_PSRC << \ - CLKMGR_PERPLLGRP_VCO_PSRC_OFFSET) | \ - (CONFIG_HPS_PERPLLGRP_VCO_DENOM << \ - CLKMGR_PERPLLGRP_VCO_DENOM_OFFSET) | \ - (CONFIG_HPS_PERPLLGRP_VCO_NUMER << \ - CLKMGR_PERPLLGRP_VCO_NUMER_OFFSET) \ - ) - -#define SDR_VCO_BASE ( \ - (CONFIG_HPS_SDRPLLGRP_VCO_SSRC << \ - CLKMGR_SDRPLLGRP_VCO_SSRC_OFFSET) | \ - (CONFIG_HPS_SDRPLLGRP_VCO_DENOM << \ - CLKMGR_SDRPLLGRP_VCO_DENOM_OFFSET) | \ - (CONFIG_HPS_SDRPLLGRP_VCO_NUMER << \ - CLKMGR_SDRPLLGRP_VCO_NUMER_OFFSET) \ - ) - -void board_init_f(ulong dummy) -{ - struct socfpga_system_manager *sysmgr_regs = - (struct socfpga_system_manager *)SOCFPGA_SYSMGR_ADDRESS; - unsigned long reg; - /* - * First C code to run. Clear fake OCRAM ECC first as SBE - * and DBE might triggered during power on - */ - reg = readl(&sysmgr_regs->eccgrp_ocram); - if (reg & SYSMGR_ECC_OCRAM_SERR) - writel(SYSMGR_ECC_OCRAM_SERR | SYSMGR_ECC_OCRAM_EN, - &sysmgr_regs->eccgrp_ocram); - if (reg & SYSMGR_ECC_OCRAM_DERR) - writel(SYSMGR_ECC_OCRAM_DERR | SYSMGR_ECC_OCRAM_EN, - &sysmgr_regs->eccgrp_ocram); - - memset(__bss_start, 0, __bss_end - __bss_start); - - /* Remap SDRAM to 0x0 */ - writel(0x1, &pl310->pl310_addr_filter_start); - - board_init_r(NULL, 0); -} - -u32 spl_boot_device(void) -{ - return BOOT_DEVICE_RAM; -} - -/* - * Board initialization after bss clearance - */ -void spl_board_init(void) -{ - unsigned long sdram_size; -#ifndef CONFIG_SOCFPGA_VIRTUAL_TARGET - cm_config_t cm_default_cfg = { - /* main group */ - MAIN_VCO_BASE, - (CONFIG_HPS_MAINPLLGRP_MPUCLK_CNT << - CLKMGR_MAINPLLGRP_MPUCLK_CNT_OFFSET), - (CONFIG_HPS_MAINPLLGRP_MAINCLK_CNT << - CLKMGR_MAINPLLGRP_MAINCLK_CNT_OFFSET), - (CONFIG_HPS_MAINPLLGRP_DBGATCLK_CNT << - CLKMGR_MAINPLLGRP_DBGATCLK_CNT_OFFSET), - (CONFIG_HPS_MAINPLLGRP_MAINQSPICLK_CNT << - CLKMGR_MAINPLLGRP_MAINQSPICLK_CNT_OFFSET), - (CONFIG_HPS_MAINPLLGRP_MAINNANDSDMMCCLK_CNT << - CLKMGR_PERPLLGRP_PERNANDSDMMCCLK_CNT_OFFSET), - (CONFIG_HPS_MAINPLLGRP_CFGS2FUSER0CLK_CNT << - CLKMGR_MAINPLLGRP_CFGS2FUSER0CLK_CNT_OFFSET), - (CONFIG_HPS_MAINPLLGRP_MAINDIV_L3MPCLK << - CLKMGR_MAINPLLGRP_MAINDIV_L3MPCLK_OFFSET) | - (CONFIG_HPS_MAINPLLGRP_MAINDIV_L3SPCLK << - CLKMGR_MAINPLLGRP_MAINDIV_L3SPCLK_OFFSET) | - (CONFIG_HPS_MAINPLLGRP_MAINDIV_L4MPCLK << - CLKMGR_MAINPLLGRP_MAINDIV_L4MPCLK_OFFSET) | - (CONFIG_HPS_MAINPLLGRP_MAINDIV_L4SPCLK << - CLKMGR_MAINPLLGRP_MAINDIV_L4SPCLK_OFFSET), - (CONFIG_HPS_MAINPLLGRP_DBGDIV_DBGATCLK << - CLKMGR_MAINPLLGRP_DBGDIV_DBGATCLK_OFFSET) | - (CONFIG_HPS_MAINPLLGRP_DBGDIV_DBGCLK << - CLKMGR_MAINPLLGRP_DBGDIV_DBGCLK_OFFSET), - (CONFIG_HPS_MAINPLLGRP_TRACEDIV_TRACECLK << - CLKMGR_MAINPLLGRP_TRACEDIV_TRACECLK_OFFSET), - (CONFIG_HPS_MAINPLLGRP_L4SRC_L4MP << - CLKMGR_MAINPLLGRP_L4SRC_L4MP_OFFSET) | - (CONFIG_HPS_MAINPLLGRP_L4SRC_L4SP << - CLKMGR_MAINPLLGRP_L4SRC_L4SP_OFFSET), - - /* peripheral group */ - PERI_VCO_BASE, - (CONFIG_HPS_PERPLLGRP_EMAC0CLK_CNT << - CLKMGR_PERPLLGRP_EMAC0CLK_CNT_OFFSET), - (CONFIG_HPS_PERPLLGRP_EMAC1CLK_CNT << - CLKMGR_PERPLLGRP_EMAC1CLK_CNT_OFFSET), - (CONFIG_HPS_PERPLLGRP_PERQSPICLK_CNT << - CLKMGR_PERPLLGRP_PERQSPICLK_CNT_OFFSET), - (CONFIG_HPS_PERPLLGRP_PERNANDSDMMCCLK_CNT << - CLKMGR_PERPLLGRP_PERNANDSDMMCCLK_CNT_OFFSET), - (CONFIG_HPS_PERPLLGRP_PERBASECLK_CNT << - CLKMGR_PERPLLGRP_PERBASECLK_CNT_OFFSET), - (CONFIG_HPS_PERPLLGRP_S2FUSER1CLK_CNT << - CLKMGR_PERPLLGRP_S2FUSER1CLK_CNT_OFFSET), - (CONFIG_HPS_PERPLLGRP_DIV_USBCLK << - CLKMGR_PERPLLGRP_DIV_USBCLK_OFFSET) | - (CONFIG_HPS_PERPLLGRP_DIV_SPIMCLK << - CLKMGR_PERPLLGRP_DIV_SPIMCLK_OFFSET) | - (CONFIG_HPS_PERPLLGRP_DIV_CAN0CLK << - CLKMGR_PERPLLGRP_DIV_CAN0CLK_OFFSET) | - (CONFIG_HPS_PERPLLGRP_DIV_CAN1CLK << - CLKMGR_PERPLLGRP_DIV_CAN1CLK_OFFSET), - (CONFIG_HPS_PERPLLGRP_GPIODIV_GPIODBCLK << - CLKMGR_PERPLLGRP_GPIODIV_GPIODBCLK_OFFSET), - (CONFIG_HPS_PERPLLGRP_SRC_QSPI << - CLKMGR_PERPLLGRP_SRC_QSPI_OFFSET) | - (CONFIG_HPS_PERPLLGRP_SRC_NAND << - CLKMGR_PERPLLGRP_SRC_NAND_OFFSET) | - (CONFIG_HPS_PERPLLGRP_SRC_SDMMC << - CLKMGR_PERPLLGRP_SRC_SDMMC_OFFSET), - - /* sdram pll group */ - SDR_VCO_BASE, - (CONFIG_HPS_SDRPLLGRP_DDRDQSCLK_PHASE << - CLKMGR_SDRPLLGRP_DDRDQSCLK_PHASE_OFFSET) | - (CONFIG_HPS_SDRPLLGRP_DDRDQSCLK_CNT << - CLKMGR_SDRPLLGRP_DDRDQSCLK_CNT_OFFSET), - (CONFIG_HPS_SDRPLLGRP_DDR2XDQSCLK_PHASE << - CLKMGR_SDRPLLGRP_DDR2XDQSCLK_PHASE_OFFSET) | - (CONFIG_HPS_SDRPLLGRP_DDR2XDQSCLK_CNT << - CLKMGR_SDRPLLGRP_DDR2XDQSCLK_CNT_OFFSET), - (CONFIG_HPS_SDRPLLGRP_DDRDQCLK_PHASE << - CLKMGR_SDRPLLGRP_DDRDQCLK_PHASE_OFFSET) | - (CONFIG_HPS_SDRPLLGRP_DDRDQCLK_CNT << - CLKMGR_SDRPLLGRP_DDRDQCLK_CNT_OFFSET), - (CONFIG_HPS_SDRPLLGRP_S2FUSER2CLK_PHASE << - CLKMGR_SDRPLLGRP_S2FUSER2CLK_PHASE_OFFSET) | - (CONFIG_HPS_SDRPLLGRP_S2FUSER2CLK_CNT << - CLKMGR_SDRPLLGRP_S2FUSER2CLK_CNT_OFFSET), - - }; - - debug("Freezing all I/O banks\n"); - /* freeze all IO banks */ - sys_mgr_frzctrl_freeze_req(); - - socfpga_sdram_enable(); - socfpga_uart0_enable(); - socfpga_osc1timer_enable(); - - timer_init(); - - debug("Reconfigure Clock Manager\n"); - /* reconfigure the PLLs */ - cm_basic_init(&cm_default_cfg); - - /* Enable bootrom to configure IOs. */ - sysmgr_enable_warmrstcfgio(); - - /* configure the IOCSR / IO buffer settings */ - if (scan_mgr_configure_iocsr()) - hang(); - - /* configure the pin muxing through system manager */ - sysmgr_pinmux_init(); -#endif /* CONFIG_SOCFPGA_VIRTUAL_TARGET */ - - /* de-assert reset for peripherals and bridges based on handoff */ - reset_deassert_peripherals_handoff(); - - debug("Unfreezing/Thaw all I/O banks\n"); - /* unfreeze / thaw all IO banks */ - sys_mgr_frzctrl_thaw_req(); - - /* enable console uart printing */ - preloader_console_init(); - - if (sdram_mmr_init_full(0xffffffff) != 0) { - puts("SDRAM init failed.\n"); - hang(); - } - - debug("SDRAM: Calibrating PHY\n"); - /* SDRAM calibration */ - if (sdram_calibration_full() == 0) { - puts("SDRAM calibration failed.\n"); - hang(); - } - - sdram_size = sdram_calculate_size(); - debug("SDRAM: %ld MiB\n", sdram_size >> 20); - - /* Sanity check ensure correct SDRAM size specified */ - if (get_ram_size(0, sdram_size) != sdram_size) { - puts("SDRAM size check failed!\n"); - hang(); - } -} diff --git a/arch/arm/cpu/armv7/socfpga/system_manager.c b/arch/arm/cpu/armv7/socfpga/system_manager.c deleted file mode 100644 index 8126e0d43c..0000000000 --- a/arch/arm/cpu/armv7/socfpga/system_manager.c +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright (C) 2013 Altera Corporation - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include -#include -#include -#include - -DECLARE_GLOBAL_DATA_PTR; - -static struct socfpga_system_manager *sysmgr_regs = - (struct socfpga_system_manager *)SOCFPGA_SYSMGR_ADDRESS; - -/* - * Populate the value for SYSMGR.FPGAINTF.MODULE based on pinmux setting. - * The value is not wrote to SYSMGR.FPGAINTF.MODULE but - * CONFIG_SYSMGR_ISWGRP_HANDOFF. - */ -static void populate_sysmgr_fpgaintf_module(void) -{ - uint32_t handoff_val = 0; - - /* ISWGRP_HANDOFF_FPGAINTF */ - writel(0, &sysmgr_regs->iswgrp_handoff[2]); - - /* Enable the signal for those HPS peripherals that use FPGA. */ - if (readl(&sysmgr_regs->nandusefpga) == SYSMGR_FPGAINTF_USEFPGA) - handoff_val |= SYSMGR_FPGAINTF_NAND; - if (readl(&sysmgr_regs->rgmii1usefpga) == SYSMGR_FPGAINTF_USEFPGA) - handoff_val |= SYSMGR_FPGAINTF_EMAC1; - if (readl(&sysmgr_regs->sdmmcusefpga) == SYSMGR_FPGAINTF_USEFPGA) - handoff_val |= SYSMGR_FPGAINTF_SDMMC; - if (readl(&sysmgr_regs->rgmii0usefpga) == SYSMGR_FPGAINTF_USEFPGA) - handoff_val |= SYSMGR_FPGAINTF_EMAC0; - if (readl(&sysmgr_regs->spim0usefpga) == SYSMGR_FPGAINTF_USEFPGA) - handoff_val |= SYSMGR_FPGAINTF_SPIM0; - if (readl(&sysmgr_regs->spim1usefpga) == SYSMGR_FPGAINTF_USEFPGA) - handoff_val |= SYSMGR_FPGAINTF_SPIM1; - - /* populate (not writing) the value for SYSMGR.FPGAINTF.MODULE - based on pinmux setting */ - setbits_le32(&sysmgr_regs->iswgrp_handoff[2], handoff_val); - - handoff_val = readl(&sysmgr_regs->iswgrp_handoff[2]); - if (fpgamgr_test_fpga_ready()) { - /* Enable the required signals only */ - writel(handoff_val, &sysmgr_regs->fpgaintfgrp_module); - } -} - -/* - * Configure all the pin muxes - */ -void sysmgr_pinmux_init(void) -{ - uint32_t regs = (uint32_t)&sysmgr_regs->emacio[0]; - int i; - - for (i = 0; i < ARRAY_SIZE(sys_mgr_init_table); i++) { - writel(sys_mgr_init_table[i], regs); - regs += sizeof(regs); - } - - populate_sysmgr_fpgaintf_module(); -} - -/* - * This bit allows the bootrom to configure the IOs after a warm reset. - */ -void sysmgr_enable_warmrstcfgio(void) -{ - setbits_le32(&sysmgr_regs->romcodegrp_ctrl, - SYSMGR_ROMCODEGRP_CTRL_WARMRSTCFGIO); -} diff --git a/arch/arm/cpu/armv7/socfpga/timer.c b/arch/arm/cpu/armv7/socfpga/timer.c deleted file mode 100644 index 253cde39d1..0000000000 --- a/arch/arm/cpu/armv7/socfpga/timer.c +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright (C) 2012 Altera Corporation - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include -#include -#include - -#define TIMER_LOAD_VAL 0xFFFFFFFF - -static const struct socfpga_timer *timer_base = (void *)CONFIG_SYS_TIMERBASE; - -/* - * Timer initialization - */ -int timer_init(void) -{ - writel(TIMER_LOAD_VAL, &timer_base->load_val); - writel(TIMER_LOAD_VAL, &timer_base->curr_val); - writel(readl(&timer_base->ctrl) | 0x3, &timer_base->ctrl); - return 0; -} diff --git a/arch/arm/cpu/armv7/socfpga/u-boot-spl.lds b/arch/arm/cpu/armv7/socfpga/u-boot-spl.lds deleted file mode 100644 index 569fa418f4..0000000000 --- a/arch/arm/cpu/armv7/socfpga/u-boot-spl.lds +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (C) 2012 Altera Corporation - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -MEMORY { .sdram : ORIGIN = (0), LENGTH = (0xffffffff) } - -OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") -OUTPUT_ARCH(arm) -ENTRY(_start) -SECTIONS -{ - . = 0x00000000; - - . = ALIGN(4); - .text : - { - *(.vectors) - arch/arm/cpu/armv7/start.o (.text*) - *(.text*) - } >.sdram - - . = ALIGN(4); - .rodata : { *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) } >.sdram - - . = ALIGN(4); - .data : { *(SORT_BY_ALIGNMENT(.data*)) } >.sdram - - . = ALIGN(4); - __image_copy_end = .; - - .end : - { - *(.__end) - } - - .bss : { - . = ALIGN(4); - __bss_start = .; - *(.bss*) - . = ALIGN(4); - __bss_end = .; - } >.sdram -} diff --git a/arch/arm/mach-socfpga/Makefile b/arch/arm/mach-socfpga/Makefile new file mode 100644 index 0000000000..7524ef90e4 --- /dev/null +++ b/arch/arm/mach-socfpga/Makefile @@ -0,0 +1,12 @@ +# +# (C) Copyright 2000-2003 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# Copyright (C) 2012 Altera Corporation +# +# SPDX-License-Identifier: GPL-2.0+ +# + +obj-y += misc.o timer.o reset_manager.o system_manager.o clock_manager.o \ + fpga_manager.o +obj-$(CONFIG_SPL_BUILD) += spl.o freeze_controller.o scan_manager.o diff --git a/arch/arm/mach-socfpga/clock_manager.c b/arch/arm/mach-socfpga/clock_manager.c new file mode 100644 index 0000000000..fa3b93a257 --- /dev/null +++ b/arch/arm/mach-socfpga/clock_manager.c @@ -0,0 +1,560 @@ +/* + * Copyright (C) 2013 Altera Corporation + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include + +DECLARE_GLOBAL_DATA_PTR; + +static const struct socfpga_clock_manager *clock_manager_base = + (struct socfpga_clock_manager *)SOCFPGA_CLKMGR_ADDRESS; + +static void cm_wait_for_lock(uint32_t mask) +{ + register uint32_t inter_val; + uint32_t retry = 0; + do { + inter_val = readl(&clock_manager_base->inter) & mask; + if (inter_val == mask) + retry++; + else + retry = 0; + if (retry >= 10) + break; + } while (1); +} + +/* function to poll in the fsm busy bit */ +static void cm_wait_for_fsm(void) +{ + while (readl(&clock_manager_base->stat) & CLKMGR_STAT_BUSY) + ; +} + +/* + * function to write the bypass register which requires a poll of the + * busy bit + */ +static void cm_write_bypass(uint32_t val) +{ + writel(val, &clock_manager_base->bypass); + cm_wait_for_fsm(); +} + +/* function to write the ctrl register which requires a poll of the busy bit */ +static void cm_write_ctrl(uint32_t val) +{ + writel(val, &clock_manager_base->ctrl); + cm_wait_for_fsm(); +} + +/* function to write a clock register that has phase information */ +static void cm_write_with_phase(uint32_t value, + uint32_t reg_address, uint32_t mask) +{ + /* poll until phase is zero */ + while (readl(reg_address) & mask) + ; + + writel(value, reg_address); + + while (readl(reg_address) & mask) + ; +} + +/* + * Setup clocks while making no assumptions about previous state of the clocks. + * + * Start by being paranoid and gate all sw managed clocks + * Put all plls in bypass + * Put all plls VCO registers back to reset value (bandgap power down). + * Put peripheral and main pll src to reset value to avoid glitch. + * Delay 5 us. + * Deassert bandgap power down and set numerator and denominator + * Start 7 us timer. + * set internal dividers + * Wait for 7 us timer. + * Enable plls + * Set external dividers while plls are locking + * Wait for pll lock + * Assert/deassert outreset all. + * Take all pll's out of bypass + * Clear safe mode + * set source main and peripheral clocks + * Ungate clocks + */ + +void cm_basic_init(const cm_config_t *cfg) +{ + uint32_t start, timeout; + + /* Start by being paranoid and gate all sw managed clocks */ + + /* + * We need to disable nandclk + * and then do another apb access before disabling + * gatting off the rest of the periperal clocks. + */ + writel(~CLKMGR_PERPLLGRP_EN_NANDCLK_MASK & + readl(&clock_manager_base->per_pll.en), + &clock_manager_base->per_pll.en); + + /* DO NOT GATE OFF DEBUG CLOCKS & BRIDGE CLOCKS */ + writel(CLKMGR_MAINPLLGRP_EN_DBGTIMERCLK_MASK | + CLKMGR_MAINPLLGRP_EN_DBGTRACECLK_MASK | + CLKMGR_MAINPLLGRP_EN_DBGCLK_MASK | + CLKMGR_MAINPLLGRP_EN_DBGATCLK_MASK | + CLKMGR_MAINPLLGRP_EN_S2FUSER0CLK_MASK | + CLKMGR_MAINPLLGRP_EN_L4MPCLK_MASK, + &clock_manager_base->main_pll.en); + + writel(0, &clock_manager_base->sdr_pll.en); + + /* now we can gate off the rest of the peripheral clocks */ + writel(0, &clock_manager_base->per_pll.en); + + /* Put all plls in bypass */ + cm_write_bypass(CLKMGR_BYPASS_PERPLL | CLKMGR_BYPASS_SDRPLL | + CLKMGR_BYPASS_MAINPLL); + + /* Put all plls VCO registers back to reset value. */ + writel(CLKMGR_MAINPLLGRP_VCO_RESET_VALUE & + ~CLKMGR_MAINPLLGRP_VCO_REGEXTSEL_MASK, + &clock_manager_base->main_pll.vco); + writel(CLKMGR_PERPLLGRP_VCO_RESET_VALUE & + ~CLKMGR_PERPLLGRP_VCO_REGEXTSEL_MASK, + &clock_manager_base->per_pll.vco); + writel(CLKMGR_SDRPLLGRP_VCO_RESET_VALUE & + ~CLKMGR_SDRPLLGRP_VCO_REGEXTSEL_MASK, + &clock_manager_base->sdr_pll.vco); + + /* + * The clocks to the flash devices and the L4_MAIN clocks can + * glitch when coming out of safe mode if their source values + * are different from their reset value. So the trick it to + * put them back to their reset state, and change input + * after exiting safe mode but before ungating the clocks. + */ + writel(CLKMGR_PERPLLGRP_SRC_RESET_VALUE, + &clock_manager_base->per_pll.src); + writel(CLKMGR_MAINPLLGRP_L4SRC_RESET_VALUE, + &clock_manager_base->main_pll.l4src); + + /* read back for the required 5 us delay. */ + readl(&clock_manager_base->main_pll.vco); + readl(&clock_manager_base->per_pll.vco); + readl(&clock_manager_base->sdr_pll.vco); + + + /* + * We made sure bgpwr down was assert for 5 us. Now deassert BG PWR DN + * with numerator and denominator. + */ + writel(cfg->main_vco_base, &clock_manager_base->main_pll.vco); + writel(cfg->peri_vco_base, &clock_manager_base->per_pll.vco); + writel(cfg->sdram_vco_base, &clock_manager_base->sdr_pll.vco); + + /* + * Time starts here + * must wait 7 us from BGPWRDN_SET(0) to VCO_ENABLE_SET(1) + */ + start = get_timer(0); + /* timeout in unit of us as CONFIG_SYS_HZ = 1000*1000 */ + timeout = 7; + + /* main mpu */ + writel(cfg->mpuclk, &clock_manager_base->main_pll.mpuclk); + + /* main main clock */ + writel(cfg->mainclk, &clock_manager_base->main_pll.mainclk); + + /* main for dbg */ + writel(cfg->dbgatclk, &clock_manager_base->main_pll.dbgatclk); + + /* main for cfgs2fuser0clk */ + writel(cfg->cfg2fuser0clk, + &clock_manager_base->main_pll.cfgs2fuser0clk); + + /* Peri emac0 50 MHz default to RMII */ + writel(cfg->emac0clk, &clock_manager_base->per_pll.emac0clk); + + /* Peri emac1 50 MHz default to RMII */ + writel(cfg->emac1clk, &clock_manager_base->per_pll.emac1clk); + + /* Peri QSPI */ + writel(cfg->mainqspiclk, &clock_manager_base->main_pll.mainqspiclk); + + writel(cfg->perqspiclk, &clock_manager_base->per_pll.perqspiclk); + + /* Peri pernandsdmmcclk */ + writel(cfg->mainnandsdmmcclk, + &clock_manager_base->main_pll.mainnandsdmmcclk); + + writel(cfg->pernandsdmmcclk, + &clock_manager_base->per_pll.pernandsdmmcclk); + + /* Peri perbaseclk */ + writel(cfg->perbaseclk, &clock_manager_base->per_pll.perbaseclk); + + /* Peri s2fuser1clk */ + writel(cfg->s2fuser1clk, &clock_manager_base->per_pll.s2fuser1clk); + + /* 7 us must have elapsed before we can enable the VCO */ + while (get_timer(start) < timeout) + ; + + /* Enable vco */ + /* main pll vco */ + writel(cfg->main_vco_base | CLKMGR_MAINPLLGRP_VCO_EN, + &clock_manager_base->main_pll.vco); + + /* periferal pll */ + writel(cfg->peri_vco_base | CLKMGR_MAINPLLGRP_VCO_EN, + &clock_manager_base->per_pll.vco); + + /* sdram pll vco */ + writel(cfg->sdram_vco_base | CLKMGR_MAINPLLGRP_VCO_EN, + &clock_manager_base->sdr_pll.vco); + + /* L3 MP and L3 SP */ + writel(cfg->maindiv, &clock_manager_base->main_pll.maindiv); + + writel(cfg->dbgdiv, &clock_manager_base->main_pll.dbgdiv); + + writel(cfg->tracediv, &clock_manager_base->main_pll.tracediv); + + /* L4 MP, L4 SP, can0, and can1 */ + writel(cfg->perdiv, &clock_manager_base->per_pll.div); + + writel(cfg->gpiodiv, &clock_manager_base->per_pll.gpiodiv); + +#define LOCKED_MASK \ + (CLKMGR_INTER_SDRPLLLOCKED_MASK | \ + CLKMGR_INTER_PERPLLLOCKED_MASK | \ + CLKMGR_INTER_MAINPLLLOCKED_MASK) + + cm_wait_for_lock(LOCKED_MASK); + + /* write the sdram clock counters before toggling outreset all */ + writel(cfg->ddrdqsclk & CLKMGR_SDRPLLGRP_DDRDQSCLK_CNT_MASK, + &clock_manager_base->sdr_pll.ddrdqsclk); + + writel(cfg->ddr2xdqsclk & CLKMGR_SDRPLLGRP_DDR2XDQSCLK_CNT_MASK, + &clock_manager_base->sdr_pll.ddr2xdqsclk); + + writel(cfg->ddrdqclk & CLKMGR_SDRPLLGRP_DDRDQCLK_CNT_MASK, + &clock_manager_base->sdr_pll.ddrdqclk); + + writel(cfg->s2fuser2clk & CLKMGR_SDRPLLGRP_S2FUSER2CLK_CNT_MASK, + &clock_manager_base->sdr_pll.s2fuser2clk); + + /* + * after locking, but before taking out of bypass + * assert/deassert outresetall + */ + uint32_t mainvco = readl(&clock_manager_base->main_pll.vco); + + /* assert main outresetall */ + writel(mainvco | CLKMGR_MAINPLLGRP_VCO_OUTRESETALL_MASK, + &clock_manager_base->main_pll.vco); + + uint32_t periphvco = readl(&clock_manager_base->per_pll.vco); + + /* assert pheriph outresetall */ + writel(periphvco | CLKMGR_PERPLLGRP_VCO_OUTRESETALL_MASK, + &clock_manager_base->per_pll.vco); + + /* assert sdram outresetall */ + writel(cfg->sdram_vco_base | CLKMGR_MAINPLLGRP_VCO_EN| + CLKMGR_SDRPLLGRP_VCO_OUTRESETALL, + &clock_manager_base->sdr_pll.vco); + + /* deassert main outresetall */ + writel(mainvco & ~CLKMGR_MAINPLLGRP_VCO_OUTRESETALL_MASK, + &clock_manager_base->main_pll.vco); + + /* deassert pheriph outresetall */ + writel(periphvco & ~CLKMGR_PERPLLGRP_VCO_OUTRESETALL_MASK, + &clock_manager_base->per_pll.vco); + + /* deassert sdram outresetall */ + writel(cfg->sdram_vco_base | CLKMGR_MAINPLLGRP_VCO_EN, + &clock_manager_base->sdr_pll.vco); + + /* + * now that we've toggled outreset all, all the clocks + * are aligned nicely; so we can change any phase. + */ + cm_write_with_phase(cfg->ddrdqsclk, + (uint32_t)&clock_manager_base->sdr_pll.ddrdqsclk, + CLKMGR_SDRPLLGRP_DDRDQSCLK_PHASE_MASK); + + /* SDRAM DDR2XDQSCLK */ + cm_write_with_phase(cfg->ddr2xdqsclk, + (uint32_t)&clock_manager_base->sdr_pll.ddr2xdqsclk, + CLKMGR_SDRPLLGRP_DDR2XDQSCLK_PHASE_MASK); + + cm_write_with_phase(cfg->ddrdqclk, + (uint32_t)&clock_manager_base->sdr_pll.ddrdqclk, + CLKMGR_SDRPLLGRP_DDRDQCLK_PHASE_MASK); + + cm_write_with_phase(cfg->s2fuser2clk, + (uint32_t)&clock_manager_base->sdr_pll.s2fuser2clk, + CLKMGR_SDRPLLGRP_S2FUSER2CLK_PHASE_MASK); + + /* Take all three PLLs out of bypass when safe mode is cleared. */ + cm_write_bypass(0); + + /* clear safe mode */ + cm_write_ctrl(readl(&clock_manager_base->ctrl) | CLKMGR_CTRL_SAFEMODE); + + /* + * now that safe mode is clear with clocks gated + * it safe to change the source mux for the flashes the the L4_MAIN + */ + writel(cfg->persrc, &clock_manager_base->per_pll.src); + writel(cfg->l4src, &clock_manager_base->main_pll.l4src); + + /* Now ungate non-hw-managed clocks */ + writel(~0, &clock_manager_base->main_pll.en); + writel(~0, &clock_manager_base->per_pll.en); + writel(~0, &clock_manager_base->sdr_pll.en); + + /* Clear the loss of lock bits (write 1 to clear) */ + writel(CLKMGR_INTER_SDRPLLLOST_MASK | CLKMGR_INTER_PERPLLLOST_MASK | + CLKMGR_INTER_MAINPLLLOST_MASK, + &clock_manager_base->inter); +} + +static unsigned int cm_get_main_vco_clk_hz(void) +{ + uint32_t reg, clock; + + /* get the main VCO clock */ + reg = readl(&clock_manager_base->main_pll.vco); + clock = CONFIG_HPS_CLK_OSC1_HZ; + clock /= ((reg & CLKMGR_MAINPLLGRP_VCO_DENOM_MASK) >> + CLKMGR_MAINPLLGRP_VCO_DENOM_OFFSET) + 1; + clock *= ((reg & CLKMGR_MAINPLLGRP_VCO_NUMER_MASK) >> + CLKMGR_MAINPLLGRP_VCO_NUMER_OFFSET) + 1; + + return clock; +} + +static unsigned int cm_get_per_vco_clk_hz(void) +{ + uint32_t reg, clock = 0; + + /* identify PER PLL clock source */ + reg = readl(&clock_manager_base->per_pll.vco); + reg = (reg & CLKMGR_PERPLLGRP_VCO_SSRC_MASK) >> + CLKMGR_PERPLLGRP_VCO_SSRC_OFFSET; + if (reg == CLKMGR_VCO_SSRC_EOSC1) + clock = CONFIG_HPS_CLK_OSC1_HZ; + else if (reg == CLKMGR_VCO_SSRC_EOSC2) + clock = CONFIG_HPS_CLK_OSC2_HZ; + else if (reg == CLKMGR_VCO_SSRC_F2S) + clock = CONFIG_HPS_CLK_F2S_PER_REF_HZ; + + /* get the PER VCO clock */ + reg = readl(&clock_manager_base->per_pll.vco); + clock /= ((reg & CLKMGR_PERPLLGRP_VCO_DENOM_MASK) >> + CLKMGR_PERPLLGRP_VCO_DENOM_OFFSET) + 1; + clock *= ((reg & CLKMGR_PERPLLGRP_VCO_NUMER_MASK) >> + CLKMGR_PERPLLGRP_VCO_NUMER_OFFSET) + 1; + + return clock; +} + +unsigned long cm_get_mpu_clk_hz(void) +{ + uint32_t reg, clock; + + clock = cm_get_main_vco_clk_hz(); + + /* get the MPU clock */ + reg = readl(&clock_manager_base->altera.mpuclk); + clock /= (reg + 1); + reg = readl(&clock_manager_base->main_pll.mpuclk); + clock /= (reg + 1); + return clock; +} + +unsigned long cm_get_sdram_clk_hz(void) +{ + uint32_t reg, clock = 0; + + /* identify SDRAM PLL clock source */ + reg = readl(&clock_manager_base->sdr_pll.vco); + reg = (reg & CLKMGR_SDRPLLGRP_VCO_SSRC_MASK) >> + CLKMGR_SDRPLLGRP_VCO_SSRC_OFFSET; + if (reg == CLKMGR_VCO_SSRC_EOSC1) + clock = CONFIG_HPS_CLK_OSC1_HZ; + else if (reg == CLKMGR_VCO_SSRC_EOSC2) + clock = CONFIG_HPS_CLK_OSC2_HZ; + else if (reg == CLKMGR_VCO_SSRC_F2S) + clock = CONFIG_HPS_CLK_F2S_SDR_REF_HZ; + + /* get the SDRAM VCO clock */ + reg = readl(&clock_manager_base->sdr_pll.vco); + clock /= ((reg & CLKMGR_SDRPLLGRP_VCO_DENOM_MASK) >> + CLKMGR_SDRPLLGRP_VCO_DENOM_OFFSET) + 1; + clock *= ((reg & CLKMGR_SDRPLLGRP_VCO_NUMER_MASK) >> + CLKMGR_SDRPLLGRP_VCO_NUMER_OFFSET) + 1; + + /* get the SDRAM (DDR_DQS) clock */ + reg = readl(&clock_manager_base->sdr_pll.ddrdqsclk); + reg = (reg & CLKMGR_SDRPLLGRP_DDRDQSCLK_CNT_MASK) >> + CLKMGR_SDRPLLGRP_DDRDQSCLK_CNT_OFFSET; + clock /= (reg + 1); + + return clock; +} + +unsigned int cm_get_l4_sp_clk_hz(void) +{ + uint32_t reg, clock = 0; + + /* identify the source of L4 SP clock */ + reg = readl(&clock_manager_base->main_pll.l4src); + reg = (reg & CLKMGR_MAINPLLGRP_L4SRC_L4SP) >> + CLKMGR_MAINPLLGRP_L4SRC_L4SP_OFFSET; + + if (reg == CLKMGR_L4_SP_CLK_SRC_MAINPLL) { + clock = cm_get_main_vco_clk_hz(); + + /* get the clock prior L4 SP divider (main clk) */ + reg = readl(&clock_manager_base->altera.mainclk); + clock /= (reg + 1); + reg = readl(&clock_manager_base->main_pll.mainclk); + clock /= (reg + 1); + } else if (reg == CLKMGR_L4_SP_CLK_SRC_PERPLL) { + clock = cm_get_per_vco_clk_hz(); + + /* get the clock prior L4 SP divider (periph_base_clk) */ + reg = readl(&clock_manager_base->per_pll.perbaseclk); + clock /= (reg + 1); + } + + /* get the L4 SP clock which supplied to UART */ + reg = readl(&clock_manager_base->main_pll.maindiv); + reg = (reg & CLKMGR_MAINPLLGRP_MAINDIV_L4SPCLK_MASK) >> + CLKMGR_MAINPLLGRP_MAINDIV_L4SPCLK_OFFSET; + clock = clock / (1 << reg); + + return clock; +} + +unsigned int cm_get_mmc_controller_clk_hz(void) +{ + uint32_t reg, clock = 0; + + /* identify the source of MMC clock */ + reg = readl(&clock_manager_base->per_pll.src); + reg = (reg & CLKMGR_PERPLLGRP_SRC_SDMMC_MASK) >> + CLKMGR_PERPLLGRP_SRC_SDMMC_OFFSET; + + if (reg == CLKMGR_SDMMC_CLK_SRC_F2S) { + clock = CONFIG_HPS_CLK_F2S_PER_REF_HZ; + } else if (reg == CLKMGR_SDMMC_CLK_SRC_MAIN) { + clock = cm_get_main_vco_clk_hz(); + + /* get the SDMMC clock */ + reg = readl(&clock_manager_base->main_pll.mainnandsdmmcclk); + clock /= (reg + 1); + } else if (reg == CLKMGR_SDMMC_CLK_SRC_PER) { + clock = cm_get_per_vco_clk_hz(); + + /* get the SDMMC clock */ + reg = readl(&clock_manager_base->per_pll.pernandsdmmcclk); + clock /= (reg + 1); + } + + /* further divide by 4 as we have fixed divider at wrapper */ + clock /= 4; + return clock; +} + +unsigned int cm_get_qspi_controller_clk_hz(void) +{ + uint32_t reg, clock = 0; + + /* identify the source of QSPI clock */ + reg = readl(&clock_manager_base->per_pll.src); + reg = (reg & CLKMGR_PERPLLGRP_SRC_QSPI_MASK) >> + CLKMGR_PERPLLGRP_SRC_QSPI_OFFSET; + + if (reg == CLKMGR_QSPI_CLK_SRC_F2S) { + clock = CONFIG_HPS_CLK_F2S_PER_REF_HZ; + } else if (reg == CLKMGR_QSPI_CLK_SRC_MAIN) { + clock = cm_get_main_vco_clk_hz(); + + /* get the qspi clock */ + reg = readl(&clock_manager_base->main_pll.mainqspiclk); + clock /= (reg + 1); + } else if (reg == CLKMGR_QSPI_CLK_SRC_PER) { + clock = cm_get_per_vco_clk_hz(); + + /* get the qspi clock */ + reg = readl(&clock_manager_base->per_pll.perqspiclk); + clock /= (reg + 1); + } + + return clock; +} + +unsigned int cm_get_spi_controller_clk_hz(void) +{ + uint32_t reg, clock = 0; + + clock = cm_get_per_vco_clk_hz(); + + /* get the clock prior L4 SP divider (periph_base_clk) */ + reg = readl(&clock_manager_base->per_pll.perbaseclk); + clock /= (reg + 1); + + return clock; +} + +static void cm_print_clock_quick_summary(void) +{ + printf("MPU %10ld kHz\n", cm_get_mpu_clk_hz() / 1000); + printf("DDR %10ld kHz\n", cm_get_sdram_clk_hz() / 1000); + printf("EOSC1 %8d kHz\n", CONFIG_HPS_CLK_OSC1_HZ / 1000); + printf("EOSC2 %8d kHz\n", CONFIG_HPS_CLK_OSC2_HZ / 1000); + printf("F2S_SDR_REF %8d kHz\n", CONFIG_HPS_CLK_F2S_SDR_REF_HZ / 1000); + printf("F2S_PER_REF %8d kHz\n", CONFIG_HPS_CLK_F2S_PER_REF_HZ / 1000); + printf("MMC %8d kHz\n", cm_get_mmc_controller_clk_hz() / 1000); + printf("QSPI %8d kHz\n", cm_get_qspi_controller_clk_hz() / 1000); + printf("UART %8d kHz\n", cm_get_l4_sp_clk_hz() / 1000); + printf("SPI %8d kHz\n", cm_get_spi_controller_clk_hz() / 1000); +} + +int set_cpu_clk_info(void) +{ + /* Calculate the clock frequencies required for drivers */ + cm_get_l4_sp_clk_hz(); + cm_get_mmc_controller_clk_hz(); + + gd->bd->bi_arm_freq = cm_get_mpu_clk_hz() / 1000000; + gd->bd->bi_dsp_freq = 0; + gd->bd->bi_ddr_freq = cm_get_sdram_clk_hz() / 1000000; + + return 0; +} + +int do_showclocks(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +{ + cm_print_clock_quick_summary(); + return 0; +} + +U_BOOT_CMD( + clocks, CONFIG_SYS_MAXARGS, 1, do_showclocks, + "display clocks", + "" +); diff --git a/arch/arm/mach-socfpga/fpga_manager.c b/arch/arm/mach-socfpga/fpga_manager.c new file mode 100644 index 0000000000..43fd2fedee --- /dev/null +++ b/arch/arm/mach-socfpga/fpga_manager.c @@ -0,0 +1,78 @@ +/* + * Copyright (C) 2012 Altera Corporation + * All rights reserved. + * + * This file contains only support functions used also by the SoCFPGA + * platform code, the real meat is located in drivers/fpga/socfpga.c . + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include +#include +#include +#include + +DECLARE_GLOBAL_DATA_PTR; + +/* Timeout count */ +#define FPGA_TIMEOUT_CNT 0x1000000 + +static struct socfpga_fpga_manager *fpgamgr_regs = + (struct socfpga_fpga_manager *)SOCFPGA_FPGAMGRREGS_ADDRESS; + +/* Check whether FPGA Init_Done signal is high */ +static int is_fpgamgr_initdone_high(void) +{ + unsigned long val; + + val = readl(&fpgamgr_regs->gpio_ext_porta); + return val & FPGAMGRREGS_MON_GPIO_EXT_PORTA_ID_MASK; +} + +/* Get the FPGA mode */ +int fpgamgr_get_mode(void) +{ + unsigned long val; + + val = readl(&fpgamgr_regs->stat); + return val & FPGAMGRREGS_STAT_MODE_MASK; +} + +/* Check whether FPGA is ready to be accessed */ +int fpgamgr_test_fpga_ready(void) +{ + /* Check for init done signal */ + if (!is_fpgamgr_initdone_high()) + return 0; + + /* Check again to avoid false glitches */ + if (!is_fpgamgr_initdone_high()) + return 0; + + if (fpgamgr_get_mode() != FPGAMGRREGS_MODE_USERMODE) + return 0; + + return 1; +} + +/* Poll until FPGA is ready to be accessed or timeout occurred */ +int fpgamgr_poll_fpga_ready(void) +{ + unsigned long i; + + /* If FPGA is blank, wait till WD invoke warm reset */ + for (i = 0; i < FPGA_TIMEOUT_CNT; i++) { + /* check for init done signal */ + if (!is_fpgamgr_initdone_high()) + continue; + /* check again to avoid false glitches */ + if (!is_fpgamgr_initdone_high()) + continue; + return 1; + } + + return 0; +} diff --git a/arch/arm/mach-socfpga/freeze_controller.c b/arch/arm/mach-socfpga/freeze_controller.c new file mode 100644 index 0000000000..0be643c817 --- /dev/null +++ b/arch/arm/mach-socfpga/freeze_controller.c @@ -0,0 +1,213 @@ +/* + * Copyright (C) 2013 Altera Corporation + * + * SPDX-License-Identifier: GPL-2.0+ + */ + + +#include +#include +#include +#include +#include + +DECLARE_GLOBAL_DATA_PTR; + +static const struct socfpga_freeze_controller *freeze_controller_base = + (void *)(SOCFPGA_SYSMGR_ADDRESS + SYSMGR_FRZCTRL_ADDRESS); + +/* + * Default state from cold reset is FREEZE_ALL; the global + * flag is set to TRUE to indicate the IO banks are frozen + */ +static uint32_t frzctrl_channel_freeze[FREEZE_CHANNEL_NUM] + = { FREEZE_CTRL_FROZEN, FREEZE_CTRL_FROZEN, + FREEZE_CTRL_FROZEN, FREEZE_CTRL_FROZEN}; + +/* Freeze HPS IOs */ +void sys_mgr_frzctrl_freeze_req(void) +{ + u32 ioctrl_reg_offset; + u32 reg_value; + u32 reg_cfg_mask; + u32 channel_id; + + /* select software FSM */ + writel(SYSMGR_FRZCTRL_SRC_VIO1_ENUM_SW, &freeze_controller_base->src); + + /* Freeze channel 0 to 2 */ + for (channel_id = 0; channel_id <= 2; channel_id++) { + ioctrl_reg_offset = (u32)( + &freeze_controller_base->vioctrl + channel_id); + + /* + * Assert active low enrnsl, plniotri + * and niotri signals + */ + reg_cfg_mask = + SYSMGR_FRZCTRL_VIOCTRL_SLEW_MASK + | SYSMGR_FRZCTRL_VIOCTRL_WKPULLUP_MASK + | SYSMGR_FRZCTRL_VIOCTRL_TRISTATE_MASK; + clrbits_le32(ioctrl_reg_offset, reg_cfg_mask); + + /* + * Note: Delay for 20ns at min + * Assert active low bhniotri signal and de-assert + * active high csrdone + */ + reg_cfg_mask + = SYSMGR_FRZCTRL_VIOCTRL_BUSHOLD_MASK + | SYSMGR_FRZCTRL_VIOCTRL_CFG_MASK; + clrbits_le32(ioctrl_reg_offset, reg_cfg_mask); + + /* Set global flag to indicate channel is frozen */ + frzctrl_channel_freeze[channel_id] = FREEZE_CTRL_FROZEN; + } + + /* Freeze channel 3 */ + /* + * Assert active low enrnsl, plniotri and + * niotri signals + */ + reg_cfg_mask + = SYSMGR_FRZCTRL_HIOCTRL_SLEW_MASK + | SYSMGR_FRZCTRL_HIOCTRL_WKPULLUP_MASK + | SYSMGR_FRZCTRL_HIOCTRL_TRISTATE_MASK; + clrbits_le32(&freeze_controller_base->hioctrl, reg_cfg_mask); + + /* + * assert active low bhniotri & nfrzdrv signals, + * de-assert active high csrdone and assert + * active high frzreg and nfrzdrv signals + */ + reg_value = readl(&freeze_controller_base->hioctrl); + reg_cfg_mask + = SYSMGR_FRZCTRL_HIOCTRL_BUSHOLD_MASK + | SYSMGR_FRZCTRL_HIOCTRL_CFG_MASK; + reg_value + = (reg_value & ~reg_cfg_mask) + | SYSMGR_FRZCTRL_HIOCTRL_REGRST_MASK + | SYSMGR_FRZCTRL_HIOCTRL_OCTRST_MASK; + writel(reg_value, &freeze_controller_base->hioctrl); + + /* + * assert active high reinit signal and de-assert + * active high pllbiasen signals + */ + reg_value = readl(&freeze_controller_base->hioctrl); + reg_value + = (reg_value & + ~SYSMGR_FRZCTRL_HIOCTRL_OCT_CFGEN_CALSTART_MASK) + | SYSMGR_FRZCTRL_HIOCTRL_DLLRST_MASK; + writel(reg_value, &freeze_controller_base->hioctrl); + + /* Set global flag to indicate channel is frozen */ + frzctrl_channel_freeze[channel_id] = FREEZE_CTRL_FROZEN; +} + +/* Unfreeze/Thaw HPS IOs */ +void sys_mgr_frzctrl_thaw_req(void) +{ + u32 ioctrl_reg_offset; + u32 reg_cfg_mask; + u32 reg_value; + u32 channel_id; + + /* select software FSM */ + writel(SYSMGR_FRZCTRL_SRC_VIO1_ENUM_SW, &freeze_controller_base->src); + + /* Thaw channel 0 to 2 */ + for (channel_id = 0; channel_id <= 2; channel_id++) { + ioctrl_reg_offset + = (u32)(&freeze_controller_base->vioctrl + channel_id); + + /* + * Assert active low bhniotri signal and + * de-assert active high csrdone + */ + reg_cfg_mask + = SYSMGR_FRZCTRL_VIOCTRL_BUSHOLD_MASK + | SYSMGR_FRZCTRL_VIOCTRL_CFG_MASK; + setbits_le32(ioctrl_reg_offset, reg_cfg_mask); + + /* + * Note: Delay for 20ns at min + * de-assert active low plniotri and niotri signals + */ + reg_cfg_mask + = SYSMGR_FRZCTRL_VIOCTRL_WKPULLUP_MASK + | SYSMGR_FRZCTRL_VIOCTRL_TRISTATE_MASK; + setbits_le32(ioctrl_reg_offset, reg_cfg_mask); + + /* + * Note: Delay for 20ns at min + * de-assert active low enrnsl signal + */ + setbits_le32(ioctrl_reg_offset, + SYSMGR_FRZCTRL_VIOCTRL_SLEW_MASK); + + /* Set global flag to indicate channel is thawed */ + frzctrl_channel_freeze[channel_id] = FREEZE_CTRL_THAWED; + } + + /* Thaw channel 3 */ + /* de-assert active high reinit signal */ + clrbits_le32(&freeze_controller_base->hioctrl, + SYSMGR_FRZCTRL_HIOCTRL_DLLRST_MASK); + + /* + * Note: Delay for 40ns at min + * assert active high pllbiasen signals + */ + setbits_le32(&freeze_controller_base->hioctrl, + SYSMGR_FRZCTRL_HIOCTRL_OCT_CFGEN_CALSTART_MASK); + + /* + * Delay 1000 intosc. intosc is based on eosc1 + * Use worst case which is fatest eosc1=50MHz, delay required + * is 1/50MHz * 1000 = 20us + */ + udelay(20); + + /* + * de-assert active low bhniotri signals, + * assert active high csrdone and nfrzdrv signal + */ + reg_value = readl(&freeze_controller_base->hioctrl); + reg_value = (reg_value + | SYSMGR_FRZCTRL_HIOCTRL_BUSHOLD_MASK + | SYSMGR_FRZCTRL_HIOCTRL_CFG_MASK) + & ~SYSMGR_FRZCTRL_HIOCTRL_OCTRST_MASK; + writel(reg_value, &freeze_controller_base->hioctrl); + + /* + * Delay 33 intosc + * Use worst case which is fatest eosc1=50MHz, delay required + * is 1/50MHz * 33 = 660ns ~= 1us + */ + udelay(1); + + /* de-assert active low plniotri and niotri signals */ + reg_cfg_mask + = SYSMGR_FRZCTRL_HIOCTRL_WKPULLUP_MASK + | SYSMGR_FRZCTRL_HIOCTRL_TRISTATE_MASK; + + setbits_le32(&freeze_controller_base->hioctrl, reg_cfg_mask); + + /* + * Note: Delay for 40ns at min + * de-assert active high frzreg signal + */ + clrbits_le32(&freeze_controller_base->hioctrl, + SYSMGR_FRZCTRL_HIOCTRL_REGRST_MASK); + + /* + * Note: Delay for 40ns at min + * de-assert active low enrnsl signal + */ + setbits_le32(&freeze_controller_base->hioctrl, + SYSMGR_FRZCTRL_HIOCTRL_SLEW_MASK); + + /* Set global flag to indicate channel is thawed */ + frzctrl_channel_freeze[channel_id] = FREEZE_CTRL_THAWED; +} diff --git a/arch/arm/mach-socfpga/misc.c b/arch/arm/mach-socfpga/misc.c new file mode 100644 index 0000000000..0f8b4d095d --- /dev/null +++ b/arch/arm/mach-socfpga/misc.c @@ -0,0 +1,289 @@ +/* + * Copyright (C) 2012 Altera Corporation + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +DECLARE_GLOBAL_DATA_PTR; + +static struct pl310_regs *const pl310 = + (struct pl310_regs *)CONFIG_SYS_PL310_BASE; +static struct socfpga_system_manager *sysmgr_regs = + (struct socfpga_system_manager *)SOCFPGA_SYSMGR_ADDRESS; +static struct socfpga_reset_manager *reset_manager_base = + (struct socfpga_reset_manager *)SOCFPGA_RSTMGR_ADDRESS; +static struct nic301_registers *nic301_regs = + (struct nic301_registers *)SOCFPGA_L3REGS_ADDRESS; +static struct scu_registers *scu_regs = + (struct scu_registers *)SOCFPGA_MPUSCU_ADDRESS; + +int dram_init(void) +{ + gd->ram_size = get_ram_size((long *)PHYS_SDRAM_1, PHYS_SDRAM_1_SIZE); + return 0; +} + +void enable_caches(void) +{ +#ifndef CONFIG_SYS_ICACHE_OFF + icache_enable(); +#endif +#ifndef CONFIG_SYS_DCACHE_OFF + dcache_enable(); +#endif +} + +/* + * DesignWare Ethernet initialization + */ +#ifdef CONFIG_ETH_DESIGNWARE +int cpu_eth_init(bd_t *bis) +{ +#if CONFIG_EMAC_BASE == SOCFPGA_EMAC0_ADDRESS + const int physhift = SYSMGR_EMACGRP_CTRL_PHYSEL0_LSB; +#elif CONFIG_EMAC_BASE == SOCFPGA_EMAC1_ADDRESS + const int physhift = SYSMGR_EMACGRP_CTRL_PHYSEL1_LSB; +#else +#error "Incorrect CONFIG_EMAC_BASE value!" +#endif + + /* Initialize EMAC. This needs to be done at least once per boot. */ + + /* + * Putting the EMAC controller to reset when configuring the PHY + * interface select at System Manager + */ + socfpga_emac_reset(1); + + /* Clearing emac0 PHY interface select to 0 */ + clrbits_le32(&sysmgr_regs->emacgrp_ctrl, + SYSMGR_EMACGRP_CTRL_PHYSEL_MASK << physhift); + + /* configure to PHY interface select choosed */ + setbits_le32(&sysmgr_regs->emacgrp_ctrl, + SYSMGR_EMACGRP_CTRL_PHYSEL_ENUM_RGMII << physhift); + + /* Release the EMAC controller from reset */ + socfpga_emac_reset(0); + + /* initialize and register the emac */ + return designware_initialize(CONFIG_EMAC_BASE, + CONFIG_PHY_INTERFACE_MODE); +} +#endif + +#ifdef CONFIG_DWMMC +/* + * Initializes MMC controllers. + * to override, implement board_mmc_init() + */ +int cpu_mmc_init(bd_t *bis) +{ + return socfpga_dwmmc_init(SOCFPGA_SDMMC_ADDRESS, + CONFIG_HPS_SDMMC_BUSWIDTH, 0); +} +#endif + +#if defined(CONFIG_DISPLAY_CPUINFO) +/* + * Print CPU information + */ +int print_cpuinfo(void) +{ + puts("CPU: Altera SoCFPGA Platform\n"); + return 0; +} +#endif + +#if defined(CONFIG_SYS_CONSOLE_IS_IN_ENV) && \ +defined(CONFIG_SYS_CONSOLE_OVERWRITE_ROUTINE) +int overwrite_console(void) +{ + return 0; +} +#endif + +#ifdef CONFIG_FPGA +/* + * FPGA programming support for SoC FPGA Cyclone V + */ +static Altera_desc altera_fpga[] = { + { + /* Family */ + Altera_SoCFPGA, + /* Interface type */ + fast_passive_parallel, + /* No limitation as additional data will be ignored */ + -1, + /* No device function table */ + NULL, + /* Base interface address specified in driver */ + NULL, + /* No cookie implementation */ + 0 + }, +}; + +/* add device descriptor to FPGA device table */ +static void socfpga_fpga_add(void) +{ + int i; + fpga_init(); + for (i = 0; i < ARRAY_SIZE(altera_fpga); i++) + fpga_add(fpga_altera, &altera_fpga[i]); +} +#else +static inline void socfpga_fpga_add(void) {} +#endif + +int arch_cpu_init(void) +{ +#ifdef CONFIG_HW_WATCHDOG + /* + * In case the watchdog is enabled, make sure to (re-)configure it + * so that the defined timeout is valid. Otherwise the SPL (Perloader) + * timeout value is still active which might too short for Linux + * booting. + */ + hw_watchdog_init(); +#else + /* + * If the HW watchdog is NOT enabled, make sure it is not running, + * for example because it was enabled in the preloader. This might + * trigger a watchdog-triggered reboot of Linux kernel later. + */ + socfpga_watchdog_reset(); +#endif + + return 0; +} + +/* + * Convert all NIC-301 AMBA slaves from secure to non-secure + */ +static void socfpga_nic301_slave_ns(void) +{ + writel(0x1, &nic301_regs->lwhps2fpgaregs); + writel(0x1, &nic301_regs->hps2fpgaregs); + writel(0x1, &nic301_regs->acp); + writel(0x1, &nic301_regs->rom); + writel(0x1, &nic301_regs->ocram); + writel(0x1, &nic301_regs->sdrdata); +} + +static uint32_t iswgrp_handoff[8]; + +int arch_early_init_r(void) +{ + int i; + for (i = 0; i < 8; i++) /* Cache initial SW setting regs */ + iswgrp_handoff[i] = readl(&sysmgr_regs->iswgrp_handoff[i]); + + socfpga_bridges_reset(1); + socfpga_nic301_slave_ns(); + + /* + * Private components security: + * U-Boot : configure private timer, global timer and cpu component + * access as non secure for kernel stage (as required by Linux) + */ + setbits_le32(&scu_regs->sacr, 0xfff); + + /* Configure the L2 controller to make SDRAM start at 0 */ +#ifdef CONFIG_SOCFPGA_VIRTUAL_TARGET + writel(0x2, &nic301_regs->remap); +#else + writel(0x1, &nic301_regs->remap); /* remap.mpuzero */ + writel(0x1, &pl310->pl310_addr_filter_start); +#endif + + /* Add device descriptor to FPGA device table */ + socfpga_fpga_add(); + +#ifdef CONFIG_DESIGNWARE_SPI + /* Get Designware SPI controller out of reset */ + socfpga_spim_enable(); +#endif + + return 0; +} + +static void socfpga_sdram_apply_static_cfg(void) +{ + const uint32_t staticcfg = SOCFPGA_SDR_ADDRESS + 0x505c; + const uint32_t applymask = 0x8; + uint32_t val = readl(staticcfg) | applymask; + + /* + * 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"(staticcfg) : "memory", "cc"); +} + +int do_bridge(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +{ + if (argc != 2) + return CMD_RET_USAGE; + + argv++; + + switch (*argv[0]) { + case 'e': /* Enable */ + writel(iswgrp_handoff[2], &sysmgr_regs->fpgaintfgrp_module); + socfpga_sdram_apply_static_cfg(); + writel(iswgrp_handoff[3], SOCFPGA_SDR_ADDRESS + 0x5080); + writel(iswgrp_handoff[0], &reset_manager_base->brg_mod_reset); + writel(iswgrp_handoff[1], &nic301_regs->remap); + break; + case 'd': /* Disable */ + writel(0, &sysmgr_regs->fpgaintfgrp_module); + writel(0, SOCFPGA_SDR_ADDRESS + 0x5080); + socfpga_sdram_apply_static_cfg(); + writel(0, &reset_manager_base->brg_mod_reset); + writel(1, &nic301_regs->remap); + break; + default: + return CMD_RET_USAGE; + } + + return 0; +} + +U_BOOT_CMD( + bridge, 2, 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" + "" +); diff --git a/arch/arm/mach-socfpga/reset_manager.c b/arch/arm/mach-socfpga/reset_manager.c new file mode 100644 index 0000000000..45b352bdfc --- /dev/null +++ b/arch/arm/mach-socfpga/reset_manager.c @@ -0,0 +1,139 @@ +/* + * Copyright (C) 2013 Altera Corporation + * + * SPDX-License-Identifier: GPL-2.0+ + */ + + +#include +#include +#include +#include + +DECLARE_GLOBAL_DATA_PTR; + +static const struct socfpga_reset_manager *reset_manager_base = + (void *)SOCFPGA_RSTMGR_ADDRESS; + +/* Toggle reset signal to watchdog (WDT is disabled after this operation!) */ +void socfpga_watchdog_reset(void) +{ + /* assert reset for watchdog */ + setbits_le32(&reset_manager_base->per_mod_reset, + 1 << RSTMGR_PERMODRST_L4WD0_LSB); + + /* deassert watchdog from reset (watchdog in not running state) */ + clrbits_le32(&reset_manager_base->per_mod_reset, + 1 << RSTMGR_PERMODRST_L4WD0_LSB); +} + +/* + * Write the reset manager register to cause reset + */ +void reset_cpu(ulong addr) +{ + /* request a warm reset */ + writel((1 << RSTMGR_CTRL_SWWARMRSTREQ_LSB), + &reset_manager_base->ctrl); + /* + * infinite loop here as watchdog will trigger and reset + * the processor + */ + while (1) + ; +} + +/* + * Release peripherals from reset based on handoff + */ +void reset_deassert_peripherals_handoff(void) +{ + writel(0, &reset_manager_base->per_mod_reset); +} + +#if defined(CONFIG_SOCFPGA_VIRTUAL_TARGET) +void socfpga_bridges_reset(int enable) +{ + /* For SoCFPGA-VT, this is NOP. */ +} +#else + +#define L3REGS_REMAP_LWHPS2FPGA_MASK 0x10 +#define L3REGS_REMAP_HPS2FPGA_MASK 0x08 +#define L3REGS_REMAP_OCRAM_MASK 0x01 + +void socfpga_bridges_reset(int enable) +{ + const uint32_t l3mask = L3REGS_REMAP_LWHPS2FPGA_MASK | + L3REGS_REMAP_HPS2FPGA_MASK | + L3REGS_REMAP_OCRAM_MASK; + + if (enable) { + /* brdmodrst */ + writel(0xffffffff, &reset_manager_base->brg_mod_reset); + } else { + /* Check signal from FPGA. */ + if (fpgamgr_poll_fpga_ready()) { + /* FPGA not ready. Wait for watchdog timeout. */ + printf("%s: fpga not ready, hanging.\n", __func__); + hang(); + } + + /* brdmodrst */ + writel(0, &reset_manager_base->brg_mod_reset); + + /* Remap the bridges into memory map */ + writel(l3mask, SOCFPGA_L3REGS_ADDRESS); + } +} +#endif + +/* Change the reset state for EMAC 0 and EMAC 1 */ +void socfpga_emac_reset(int enable) +{ + const void *reset = &reset_manager_base->per_mod_reset; + + if (enable) { + setbits_le32(reset, 1 << RSTMGR_PERMODRST_EMAC0_LSB); + setbits_le32(reset, 1 << RSTMGR_PERMODRST_EMAC1_LSB); + } else { +#if (CONFIG_EMAC_BASE == SOCFPGA_EMAC0_ADDRESS) + clrbits_le32(reset, 1 << RSTMGR_PERMODRST_EMAC0_LSB); +#elif (CONFIG_EMAC_BASE == SOCFPGA_EMAC1_ADDRESS) + clrbits_le32(reset, 1 << RSTMGR_PERMODRST_EMAC1_LSB); +#endif + } +} + +/* SPI Master enable (its held in reset by the preloader) */ +void socfpga_spim_enable(void) +{ + const void *reset = &reset_manager_base->per_mod_reset; + + clrbits_le32(reset, (1 << RSTMGR_PERMODRST_SPIM0_LSB) | + (1 << RSTMGR_PERMODRST_SPIM1_LSB)); +} + +/* Bring UART0 out of reset. */ +void socfpga_uart0_enable(void) +{ + const void *reset = &reset_manager_base->per_mod_reset; + + clrbits_le32(reset, 1 << RSTMGR_PERMODRST_UART0_LSB); +} + +/* Bring SDRAM controller out of reset. */ +void socfpga_sdram_enable(void) +{ + const void *reset = &reset_manager_base->per_mod_reset; + + clrbits_le32(reset, 1 << RSTMGR_PERMODRST_SDR_LSB); +} + +/* Bring OSC1 timer out of reset. */ +void socfpga_osc1timer_enable(void) +{ + const void *reset = &reset_manager_base->per_mod_reset; + + clrbits_le32(reset, 1 << RSTMGR_PERMODRST_OSC1TIMER0_LSB); +} diff --git a/arch/arm/mach-socfpga/scan_manager.c b/arch/arm/mach-socfpga/scan_manager.c new file mode 100644 index 0000000000..a820b1b1bf --- /dev/null +++ b/arch/arm/mach-socfpga/scan_manager.c @@ -0,0 +1,209 @@ +/* + * Copyright (C) 2013 Altera Corporation + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include + +DECLARE_GLOBAL_DATA_PTR; + +static const struct socfpga_scan_manager *scan_manager_base = + (void *)(SOCFPGA_SCANMGR_ADDRESS); +static const struct socfpga_freeze_controller *freeze_controller_base = + (void *)(SOCFPGA_SYSMGR_ADDRESS + SYSMGR_FRZCTRL_ADDRESS); + +/* + * Function to check IO scan chain engine status and wait if the engine is + * is active. Poll the IO scan chain engine till maximum iteration reached. + */ +static inline uint32_t scan_chain_engine_is_idle(uint32_t max_iter) +{ + uint32_t scanmgr_status; + + scanmgr_status = readl(&scan_manager_base->stat); + + /* Poll the engine until the scan engine is inactive */ + while (SCANMGR_STAT_ACTIVE_GET(scanmgr_status) || + (SCANMGR_STAT_WFIFOCNT_GET(scanmgr_status) > 0)) { + max_iter--; + if (max_iter > 0) + scanmgr_status = readl(&scan_manager_base->stat); + else + return 0; + } + return 1; +} + +/* Program HPS IO Scan Chain */ +uint32_t scan_mgr_io_scan_chain_prg( + uint32_t io_scan_chain_id, + uint32_t io_scan_chain_len_in_bits, + const uint32_t *iocsr_scan_chain) +{ + uint16_t tdi_tdo_header; + uint32_t io_program_iter; + uint32_t io_scan_chain_data_residual; + uint32_t residual; + uint32_t i; + uint32_t index = 0; + + /* + * De-assert reinit if the IO scan chain is intended for HIO. In + * this, its the chain 3. + */ + if (io_scan_chain_id == 3) + clrbits_le32(&freeze_controller_base->hioctrl, + SYSMGR_FRZCTRL_HIOCTRL_DLLRST_MASK); + + /* + * Check if the scan chain engine is inactive and the + * WFIFO is empty before enabling the IO scan chain + */ + if (!scan_chain_engine_is_idle(SCAN_MAX_DELAY)) + return 1; + + /* + * Enable IO Scan chain based on scan chain id + * Note: only one chain can be enabled at a time + */ + setbits_le32(&scan_manager_base->en, 1 << io_scan_chain_id); + + /* + * Calculate number of iteration needed for full 128-bit (4 x32-bits) + * bits shifting. Each TDI_TDO packet can shift in maximum 128-bits + */ + io_program_iter = io_scan_chain_len_in_bits >> + IO_SCAN_CHAIN_128BIT_SHIFT; + io_scan_chain_data_residual = io_scan_chain_len_in_bits & + IO_SCAN_CHAIN_128BIT_MASK; + + /* Construct TDI_TDO packet for 128-bit IO scan chain (2 bytes) */ + tdi_tdo_header = TDI_TDO_HEADER_FIRST_BYTE | + (TDI_TDO_MAX_PAYLOAD << TDI_TDO_HEADER_SECOND_BYTE_SHIFT); + + /* Program IO scan chain in 128-bit iteration */ + for (i = 0; i < io_program_iter; i++) { + /* write TDI_TDO packet header to scan manager */ + writel(tdi_tdo_header, &scan_manager_base->fifo_double_byte); + + /* calculate array index. Multiply by 4 as write 4 x 32bits */ + index = i * 4; + + /* write 4 successive 32-bit IO scan chain data into WFIFO */ + writel(iocsr_scan_chain[index], + &scan_manager_base->fifo_quad_byte); + writel(iocsr_scan_chain[index + 1], + &scan_manager_base->fifo_quad_byte); + writel(iocsr_scan_chain[index + 2], + &scan_manager_base->fifo_quad_byte); + writel(iocsr_scan_chain[index + 3], + &scan_manager_base->fifo_quad_byte); + + /* + * Check if the scan chain engine has completed the + * IO scan chain data shifting + */ + if (!scan_chain_engine_is_idle(SCAN_MAX_DELAY)) + goto error; + } + + /* Calculate array index for final TDI_TDO packet */ + index = io_program_iter * 4; + + /* Final TDI_TDO packet if any */ + if (io_scan_chain_data_residual) { + /* + * Calculate number of quad bytes FIFO write + * needed for the final TDI_TDO packet + */ + io_program_iter = io_scan_chain_data_residual >> + IO_SCAN_CHAIN_32BIT_SHIFT; + + /* + * Construct TDI_TDO packet for remaining IO + * scan chain (2 bytes) + */ + tdi_tdo_header = TDI_TDO_HEADER_FIRST_BYTE | + ((io_scan_chain_data_residual - 1) << + TDI_TDO_HEADER_SECOND_BYTE_SHIFT); + + /* + * Program the last part of IO scan chain write TDI_TDO packet + * header (2 bytes) to scan manager + */ + writel(tdi_tdo_header, &scan_manager_base->fifo_double_byte); + + for (i = 0; i < io_program_iter; i++) { + /* + * write remaining scan chain data into scan + * manager WFIFO with 4 bytes write + */ + writel(iocsr_scan_chain[index + i], + &scan_manager_base->fifo_quad_byte); + } + + index += io_program_iter; + residual = io_scan_chain_data_residual & + IO_SCAN_CHAIN_32BIT_MASK; + + if (IO_SCAN_CHAIN_PAYLOAD_24BIT < residual) { + /* + * write the last 4B scan chain data + * into scan manager WFIFO + */ + writel(iocsr_scan_chain[index], + &scan_manager_base->fifo_quad_byte); + } else { + /* + * write the remaining 1 - 3 bytes scan chain + * data into scan manager WFIFO byte by byte + * to prevent JTAG engine shifting unused data + * from the FIFO and mistaken the data as a + * valid command (even though unused bits are + * set to 0, but just to prevent hardware + * glitch) + */ + for (i = 0; i < residual; i += 8) { + writel(((iocsr_scan_chain[index] >> i) + & IO_SCAN_CHAIN_BYTE_MASK), + &scan_manager_base->fifo_single_byte); + } + } + + /* + * Check if the scan chain engine has completed the + * IO scan chain data shifting + */ + if (!scan_chain_engine_is_idle(SCAN_MAX_DELAY)) + goto error; + } + + /* Disable IO Scan chain when configuration done*/ + clrbits_le32(&scan_manager_base->en, 1 << io_scan_chain_id); + return 0; + +error: + /* Disable IO Scan chain when error detected */ + clrbits_le32(&scan_manager_base->en, 1 << io_scan_chain_id); + return 1; +} + +int scan_mgr_configure_iocsr(void) +{ + int status = 0; + + /* configure the IOCSR through scan chain */ + status |= scan_mgr_io_scan_chain_prg(0, + CONFIG_HPS_IOCSR_SCANCHAIN0_LENGTH, iocsr_scan_chain0_table); + status |= scan_mgr_io_scan_chain_prg(1, + CONFIG_HPS_IOCSR_SCANCHAIN1_LENGTH, iocsr_scan_chain1_table); + status |= scan_mgr_io_scan_chain_prg(2, + CONFIG_HPS_IOCSR_SCANCHAIN2_LENGTH, iocsr_scan_chain2_table); + status |= scan_mgr_io_scan_chain_prg(3, + CONFIG_HPS_IOCSR_SCANCHAIN3_LENGTH, iocsr_scan_chain3_table); + return status; +} diff --git a/arch/arm/mach-socfpga/spl.c b/arch/arm/mach-socfpga/spl.c new file mode 100644 index 0000000000..f994658452 --- /dev/null +++ b/arch/arm/mach-socfpga/spl.c @@ -0,0 +1,229 @@ +/* + * Copyright (C) 2012 Altera Corporation + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +DECLARE_GLOBAL_DATA_PTR; + +static struct pl310_regs *const pl310 = + (struct pl310_regs *)CONFIG_SYS_PL310_BASE; + +#define MAIN_VCO_BASE ( \ + (CONFIG_HPS_MAINPLLGRP_VCO_DENOM << \ + CLKMGR_MAINPLLGRP_VCO_DENOM_OFFSET) | \ + (CONFIG_HPS_MAINPLLGRP_VCO_NUMER << \ + CLKMGR_MAINPLLGRP_VCO_NUMER_OFFSET) \ + ) + +#define PERI_VCO_BASE ( \ + (CONFIG_HPS_PERPLLGRP_VCO_PSRC << \ + CLKMGR_PERPLLGRP_VCO_PSRC_OFFSET) | \ + (CONFIG_HPS_PERPLLGRP_VCO_DENOM << \ + CLKMGR_PERPLLGRP_VCO_DENOM_OFFSET) | \ + (CONFIG_HPS_PERPLLGRP_VCO_NUMER << \ + CLKMGR_PERPLLGRP_VCO_NUMER_OFFSET) \ + ) + +#define SDR_VCO_BASE ( \ + (CONFIG_HPS_SDRPLLGRP_VCO_SSRC << \ + CLKMGR_SDRPLLGRP_VCO_SSRC_OFFSET) | \ + (CONFIG_HPS_SDRPLLGRP_VCO_DENOM << \ + CLKMGR_SDRPLLGRP_VCO_DENOM_OFFSET) | \ + (CONFIG_HPS_SDRPLLGRP_VCO_NUMER << \ + CLKMGR_SDRPLLGRP_VCO_NUMER_OFFSET) \ + ) + +void board_init_f(ulong dummy) +{ + struct socfpga_system_manager *sysmgr_regs = + (struct socfpga_system_manager *)SOCFPGA_SYSMGR_ADDRESS; + unsigned long reg; + /* + * First C code to run. Clear fake OCRAM ECC first as SBE + * and DBE might triggered during power on + */ + reg = readl(&sysmgr_regs->eccgrp_ocram); + if (reg & SYSMGR_ECC_OCRAM_SERR) + writel(SYSMGR_ECC_OCRAM_SERR | SYSMGR_ECC_OCRAM_EN, + &sysmgr_regs->eccgrp_ocram); + if (reg & SYSMGR_ECC_OCRAM_DERR) + writel(SYSMGR_ECC_OCRAM_DERR | SYSMGR_ECC_OCRAM_EN, + &sysmgr_regs->eccgrp_ocram); + + memset(__bss_start, 0, __bss_end - __bss_start); + + /* Remap SDRAM to 0x0 */ + writel(0x1, &pl310->pl310_addr_filter_start); + + board_init_r(NULL, 0); +} + +u32 spl_boot_device(void) +{ + return BOOT_DEVICE_RAM; +} + +/* + * Board initialization after bss clearance + */ +void spl_board_init(void) +{ + unsigned long sdram_size; +#ifndef CONFIG_SOCFPGA_VIRTUAL_TARGET + cm_config_t cm_default_cfg = { + /* main group */ + MAIN_VCO_BASE, + (CONFIG_HPS_MAINPLLGRP_MPUCLK_CNT << + CLKMGR_MAINPLLGRP_MPUCLK_CNT_OFFSET), + (CONFIG_HPS_MAINPLLGRP_MAINCLK_CNT << + CLKMGR_MAINPLLGRP_MAINCLK_CNT_OFFSET), + (CONFIG_HPS_MAINPLLGRP_DBGATCLK_CNT << + CLKMGR_MAINPLLGRP_DBGATCLK_CNT_OFFSET), + (CONFIG_HPS_MAINPLLGRP_MAINQSPICLK_CNT << + CLKMGR_MAINPLLGRP_MAINQSPICLK_CNT_OFFSET), + (CONFIG_HPS_MAINPLLGRP_MAINNANDSDMMCCLK_CNT << + CLKMGR_PERPLLGRP_PERNANDSDMMCCLK_CNT_OFFSET), + (CONFIG_HPS_MAINPLLGRP_CFGS2FUSER0CLK_CNT << + CLKMGR_MAINPLLGRP_CFGS2FUSER0CLK_CNT_OFFSET), + (CONFIG_HPS_MAINPLLGRP_MAINDIV_L3MPCLK << + CLKMGR_MAINPLLGRP_MAINDIV_L3MPCLK_OFFSET) | + (CONFIG_HPS_MAINPLLGRP_MAINDIV_L3SPCLK << + CLKMGR_MAINPLLGRP_MAINDIV_L3SPCLK_OFFSET) | + (CONFIG_HPS_MAINPLLGRP_MAINDIV_L4MPCLK << + CLKMGR_MAINPLLGRP_MAINDIV_L4MPCLK_OFFSET) | + (CONFIG_HPS_MAINPLLGRP_MAINDIV_L4SPCLK << + CLKMGR_MAINPLLGRP_MAINDIV_L4SPCLK_OFFSET), + (CONFIG_HPS_MAINPLLGRP_DBGDIV_DBGATCLK << + CLKMGR_MAINPLLGRP_DBGDIV_DBGATCLK_OFFSET) | + (CONFIG_HPS_MAINPLLGRP_DBGDIV_DBGCLK << + CLKMGR_MAINPLLGRP_DBGDIV_DBGCLK_OFFSET), + (CONFIG_HPS_MAINPLLGRP_TRACEDIV_TRACECLK << + CLKMGR_MAINPLLGRP_TRACEDIV_TRACECLK_OFFSET), + (CONFIG_HPS_MAINPLLGRP_L4SRC_L4MP << + CLKMGR_MAINPLLGRP_L4SRC_L4MP_OFFSET) | + (CONFIG_HPS_MAINPLLGRP_L4SRC_L4SP << + CLKMGR_MAINPLLGRP_L4SRC_L4SP_OFFSET), + + /* peripheral group */ + PERI_VCO_BASE, + (CONFIG_HPS_PERPLLGRP_EMAC0CLK_CNT << + CLKMGR_PERPLLGRP_EMAC0CLK_CNT_OFFSET), + (CONFIG_HPS_PERPLLGRP_EMAC1CLK_CNT << + CLKMGR_PERPLLGRP_EMAC1CLK_CNT_OFFSET), + (CONFIG_HPS_PERPLLGRP_PERQSPICLK_CNT << + CLKMGR_PERPLLGRP_PERQSPICLK_CNT_OFFSET), + (CONFIG_HPS_PERPLLGRP_PERNANDSDMMCCLK_CNT << + CLKMGR_PERPLLGRP_PERNANDSDMMCCLK_CNT_OFFSET), + (CONFIG_HPS_PERPLLGRP_PERBASECLK_CNT << + CLKMGR_PERPLLGRP_PERBASECLK_CNT_OFFSET), + (CONFIG_HPS_PERPLLGRP_S2FUSER1CLK_CNT << + CLKMGR_PERPLLGRP_S2FUSER1CLK_CNT_OFFSET), + (CONFIG_HPS_PERPLLGRP_DIV_USBCLK << + CLKMGR_PERPLLGRP_DIV_USBCLK_OFFSET) | + (CONFIG_HPS_PERPLLGRP_DIV_SPIMCLK << + CLKMGR_PERPLLGRP_DIV_SPIMCLK_OFFSET) | + (CONFIG_HPS_PERPLLGRP_DIV_CAN0CLK << + CLKMGR_PERPLLGRP_DIV_CAN0CLK_OFFSET) | + (CONFIG_HPS_PERPLLGRP_DIV_CAN1CLK << + CLKMGR_PERPLLGRP_DIV_CAN1CLK_OFFSET), + (CONFIG_HPS_PERPLLGRP_GPIODIV_GPIODBCLK << + CLKMGR_PERPLLGRP_GPIODIV_GPIODBCLK_OFFSET), + (CONFIG_HPS_PERPLLGRP_SRC_QSPI << + CLKMGR_PERPLLGRP_SRC_QSPI_OFFSET) | + (CONFIG_HPS_PERPLLGRP_SRC_NAND << + CLKMGR_PERPLLGRP_SRC_NAND_OFFSET) | + (CONFIG_HPS_PERPLLGRP_SRC_SDMMC << + CLKMGR_PERPLLGRP_SRC_SDMMC_OFFSET), + + /* sdram pll group */ + SDR_VCO_BASE, + (CONFIG_HPS_SDRPLLGRP_DDRDQSCLK_PHASE << + CLKMGR_SDRPLLGRP_DDRDQSCLK_PHASE_OFFSET) | + (CONFIG_HPS_SDRPLLGRP_DDRDQSCLK_CNT << + CLKMGR_SDRPLLGRP_DDRDQSCLK_CNT_OFFSET), + (CONFIG_HPS_SDRPLLGRP_DDR2XDQSCLK_PHASE << + CLKMGR_SDRPLLGRP_DDR2XDQSCLK_PHASE_OFFSET) | + (CONFIG_HPS_SDRPLLGRP_DDR2XDQSCLK_CNT << + CLKMGR_SDRPLLGRP_DDR2XDQSCLK_CNT_OFFSET), + (CONFIG_HPS_SDRPLLGRP_DDRDQCLK_PHASE << + CLKMGR_SDRPLLGRP_DDRDQCLK_PHASE_OFFSET) | + (CONFIG_HPS_SDRPLLGRP_DDRDQCLK_CNT << + CLKMGR_SDRPLLGRP_DDRDQCLK_CNT_OFFSET), + (CONFIG_HPS_SDRPLLGRP_S2FUSER2CLK_PHASE << + CLKMGR_SDRPLLGRP_S2FUSER2CLK_PHASE_OFFSET) | + (CONFIG_HPS_SDRPLLGRP_S2FUSER2CLK_CNT << + CLKMGR_SDRPLLGRP_S2FUSER2CLK_CNT_OFFSET), + + }; + + debug("Freezing all I/O banks\n"); + /* freeze all IO banks */ + sys_mgr_frzctrl_freeze_req(); + + socfpga_sdram_enable(); + socfpga_uart0_enable(); + socfpga_osc1timer_enable(); + + timer_init(); + + debug("Reconfigure Clock Manager\n"); + /* reconfigure the PLLs */ + cm_basic_init(&cm_default_cfg); + + /* Enable bootrom to configure IOs. */ + sysmgr_enable_warmrstcfgio(); + + /* configure the IOCSR / IO buffer settings */ + if (scan_mgr_configure_iocsr()) + hang(); + + /* configure the pin muxing through system manager */ + sysmgr_pinmux_init(); +#endif /* CONFIG_SOCFPGA_VIRTUAL_TARGET */ + + /* de-assert reset for peripherals and bridges based on handoff */ + reset_deassert_peripherals_handoff(); + + debug("Unfreezing/Thaw all I/O banks\n"); + /* unfreeze / thaw all IO banks */ + sys_mgr_frzctrl_thaw_req(); + + /* enable console uart printing */ + preloader_console_init(); + + if (sdram_mmr_init_full(0xffffffff) != 0) { + puts("SDRAM init failed.\n"); + hang(); + } + + debug("SDRAM: Calibrating PHY\n"); + /* SDRAM calibration */ + if (sdram_calibration_full() == 0) { + puts("SDRAM calibration failed.\n"); + hang(); + } + + sdram_size = sdram_calculate_size(); + debug("SDRAM: %ld MiB\n", sdram_size >> 20); + + /* Sanity check ensure correct SDRAM size specified */ + if (get_ram_size(0, sdram_size) != sdram_size) { + puts("SDRAM size check failed!\n"); + hang(); + } +} diff --git a/arch/arm/mach-socfpga/system_manager.c b/arch/arm/mach-socfpga/system_manager.c new file mode 100644 index 0000000000..8126e0d43c --- /dev/null +++ b/arch/arm/mach-socfpga/system_manager.c @@ -0,0 +1,77 @@ +/* + * Copyright (C) 2013 Altera Corporation + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include + +DECLARE_GLOBAL_DATA_PTR; + +static struct socfpga_system_manager *sysmgr_regs = + (struct socfpga_system_manager *)SOCFPGA_SYSMGR_ADDRESS; + +/* + * Populate the value for SYSMGR.FPGAINTF.MODULE based on pinmux setting. + * The value is not wrote to SYSMGR.FPGAINTF.MODULE but + * CONFIG_SYSMGR_ISWGRP_HANDOFF. + */ +static void populate_sysmgr_fpgaintf_module(void) +{ + uint32_t handoff_val = 0; + + /* ISWGRP_HANDOFF_FPGAINTF */ + writel(0, &sysmgr_regs->iswgrp_handoff[2]); + + /* Enable the signal for those HPS peripherals that use FPGA. */ + if (readl(&sysmgr_regs->nandusefpga) == SYSMGR_FPGAINTF_USEFPGA) + handoff_val |= SYSMGR_FPGAINTF_NAND; + if (readl(&sysmgr_regs->rgmii1usefpga) == SYSMGR_FPGAINTF_USEFPGA) + handoff_val |= SYSMGR_FPGAINTF_EMAC1; + if (readl(&sysmgr_regs->sdmmcusefpga) == SYSMGR_FPGAINTF_USEFPGA) + handoff_val |= SYSMGR_FPGAINTF_SDMMC; + if (readl(&sysmgr_regs->rgmii0usefpga) == SYSMGR_FPGAINTF_USEFPGA) + handoff_val |= SYSMGR_FPGAINTF_EMAC0; + if (readl(&sysmgr_regs->spim0usefpga) == SYSMGR_FPGAINTF_USEFPGA) + handoff_val |= SYSMGR_FPGAINTF_SPIM0; + if (readl(&sysmgr_regs->spim1usefpga) == SYSMGR_FPGAINTF_USEFPGA) + handoff_val |= SYSMGR_FPGAINTF_SPIM1; + + /* populate (not writing) the value for SYSMGR.FPGAINTF.MODULE + based on pinmux setting */ + setbits_le32(&sysmgr_regs->iswgrp_handoff[2], handoff_val); + + handoff_val = readl(&sysmgr_regs->iswgrp_handoff[2]); + if (fpgamgr_test_fpga_ready()) { + /* Enable the required signals only */ + writel(handoff_val, &sysmgr_regs->fpgaintfgrp_module); + } +} + +/* + * Configure all the pin muxes + */ +void sysmgr_pinmux_init(void) +{ + uint32_t regs = (uint32_t)&sysmgr_regs->emacio[0]; + int i; + + for (i = 0; i < ARRAY_SIZE(sys_mgr_init_table); i++) { + writel(sys_mgr_init_table[i], regs); + regs += sizeof(regs); + } + + populate_sysmgr_fpgaintf_module(); +} + +/* + * This bit allows the bootrom to configure the IOs after a warm reset. + */ +void sysmgr_enable_warmrstcfgio(void) +{ + setbits_le32(&sysmgr_regs->romcodegrp_ctrl, + SYSMGR_ROMCODEGRP_CTRL_WARMRSTCFGIO); +} diff --git a/arch/arm/mach-socfpga/timer.c b/arch/arm/mach-socfpga/timer.c new file mode 100644 index 0000000000..253cde39d1 --- /dev/null +++ b/arch/arm/mach-socfpga/timer.c @@ -0,0 +1,24 @@ +/* + * Copyright (C) 2012 Altera Corporation + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include + +#define TIMER_LOAD_VAL 0xFFFFFFFF + +static const struct socfpga_timer *timer_base = (void *)CONFIG_SYS_TIMERBASE; + +/* + * Timer initialization + */ +int timer_init(void) +{ + writel(TIMER_LOAD_VAL, &timer_base->load_val); + writel(TIMER_LOAD_VAL, &timer_base->curr_val); + writel(readl(&timer_base->ctrl) | 0x3, &timer_base->ctrl); + return 0; +} diff --git a/arch/arm/mach-socfpga/u-boot-spl.lds b/arch/arm/mach-socfpga/u-boot-spl.lds new file mode 100644 index 0000000000..569fa418f4 --- /dev/null +++ b/arch/arm/mach-socfpga/u-boot-spl.lds @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2012 Altera Corporation + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +MEMORY { .sdram : ORIGIN = (0), LENGTH = (0xffffffff) } + +OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") +OUTPUT_ARCH(arm) +ENTRY(_start) +SECTIONS +{ + . = 0x00000000; + + . = ALIGN(4); + .text : + { + *(.vectors) + arch/arm/cpu/armv7/start.o (.text*) + *(.text*) + } >.sdram + + . = ALIGN(4); + .rodata : { *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) } >.sdram + + . = ALIGN(4); + .data : { *(SORT_BY_ALIGNMENT(.data*)) } >.sdram + + . = ALIGN(4); + __image_copy_end = .; + + .end : + { + *(.__end) + } + + .bss : { + . = ALIGN(4); + __bss_start = .; + *(.bss*) + . = ALIGN(4); + __bss_end = .; + } >.sdram +} diff --git a/include/configs/socfpga_common.h b/include/configs/socfpga_common.h index 41bb52bc8c..61ce376968 100644 --- a/include/configs/socfpga_common.h +++ b/include/configs/socfpga_common.h @@ -298,7 +298,7 @@ unsigned int cm_get_qspi_controller_clk_hz(void); #define CONFIG_CRC32_VERIFY /* Linker script for SPL */ -#define CONFIG_SPL_LDSCRIPT "arch/arm/cpu/armv7/socfpga/u-boot-spl.lds" +#define CONFIG_SPL_LDSCRIPT "arch/arm/mach-socfpga/u-boot-spl.lds" #define CONFIG_SPL_LIBCOMMON_SUPPORT #define CONFIG_SPL_LIBGENERIC_SUPPORT -- cgit v1.2.1