diff options
Diffstat (limited to 'arch/arm/mach-socfpga')
27 files changed, 4442 insertions, 1436 deletions
diff --git a/arch/arm/mach-socfpga/Kconfig b/arch/arm/mach-socfpga/Kconfig index f6e5773272..2563e7926d 100644 --- a/arch/arm/mach-socfpga/Kconfig +++ b/arch/arm/mach-socfpga/Kconfig @@ -37,6 +37,9 @@ config TARGET_SOCFPGA_ARRIA5 bool select TARGET_SOCFPGA_GEN5 +config TARGET_SOCFPGA_ARRIA10 + bool + config TARGET_SOCFPGA_CYCLONE5 bool select TARGET_SOCFPGA_GEN5 @@ -49,6 +52,10 @@ choice prompt "Altera SOCFPGA board select" optional +config TARGET_SOCFPGA_ARRIA10_SOCDK + bool "Altera SOCFPGA SoCDK (Arria 10)" + select TARGET_SOCFPGA_ARRIA10 + config TARGET_SOCFPGA_ARRIA5_SOCDK bool "Altera SOCFPGA SoCDK (Arria V)" select TARGET_SOCFPGA_ARRIA5 @@ -98,6 +105,7 @@ endchoice config SYS_BOARD default "arria5-socdk" if TARGET_SOCFPGA_ARRIA5_SOCDK + default "arria10-socdk" if TARGET_SOCFPGA_ARRIA10_SOCDK default "cyclone5-socdk" if TARGET_SOCFPGA_CYCLONE5_SOCDK default "de0-nano-soc" if TARGET_SOCFPGA_TERASIC_DE0_NANO default "de1-soc" if TARGET_SOCFPGA_TERASIC_DE1_SOC @@ -111,6 +119,7 @@ config SYS_BOARD config SYS_VENDOR default "altera" if TARGET_SOCFPGA_ARRIA5_SOCDK + default "altera" if TARGET_SOCFPGA_ARRIA10_SOCDK default "altera" if TARGET_SOCFPGA_CYCLONE5_SOCDK default "aries" if TARGET_SOCFPGA_ARIES_MCVEVK default "ebv" if TARGET_SOCFPGA_EBV_SOCRATES @@ -125,6 +134,7 @@ config SYS_SOC config SYS_CONFIG_NAME default "socfpga_arria5_socdk" if TARGET_SOCFPGA_ARRIA5_SOCDK + default "socfpga_arria10_socdk" if TARGET_SOCFPGA_ARRIA10_SOCDK default "socfpga_cyclone5_socdk" if TARGET_SOCFPGA_CYCLONE5_SOCDK default "socfpga_de0_nano_soc" if TARGET_SOCFPGA_TERASIC_DE0_NANO default "socfpga_de1_soc" if TARGET_SOCFPGA_TERASIC_DE1_SOC diff --git a/arch/arm/mach-socfpga/Makefile b/arch/arm/mach-socfpga/Makefile index 809cd47947..41b779c5ca 100644 --- a/arch/arm/mach-socfpga/Makefile +++ b/arch/arm/mach-socfpga/Makefile @@ -2,21 +2,48 @@ # (C) Copyright 2000-2003 # Wolfgang Denk, DENX Software Engineering, wd@denx.de. # -# Copyright (C) 2012 Altera Corporation <www.altera.com> +# Copyright (C) 2012-2017 Altera Corporation <www.altera.com> # # SPDX-License-Identifier: GPL-2.0+ # -obj-y += misc.o timer.o reset_manager.o system_manager.o clock_manager.o \ - fpga_manager.o board.o +obj-y += board.o +obj-y += clock_manager.o +obj-y += fpga_manager.o +obj-y += misc.o +obj-y += reset_manager.o +obj-y += timer.o -obj-$(CONFIG_SPL_BUILD) += spl.o freeze_controller.o +ifdef CONFIG_TARGET_SOCFPGA_GEN5 +obj-y += clock_manager_gen5.o +obj-y += misc_gen5.o +obj-y += reset_manager_gen5.o +obj-y += scan_manager.o +obj-y += system_manager_gen5.o +obj-y += wrap_pll_config.o +endif +ifdef CONFIG_TARGET_SOCFPGA_ARRIA10 +obj-y += clock_manager_arria10.o +obj-y += misc_arria10.o +obj-y += pinmux_arria10.o +obj-y += reset_manager_arria10.o +endif + +ifdef CONFIG_SPL_BUILD +obj-y += spl.o +ifdef CONFIG_TARGET_SOCFPGA_GEN5 +obj-y += freeze_controller.o +obj-y += wrap_iocsr_config.o +obj-y += wrap_pinmux_config.o +obj-y += wrap_sdram_config.o +endif +endif + +ifdef CONFIG_TARGET_SOCFPGA_GEN5 # QTS-generated config file wrappers -obj-$(CONFIG_TARGET_SOCFPGA_GEN5) += scan_manager.o wrap_pll_config.o -obj-$(CONFIG_SPL_BUILD) += wrap_iocsr_config.o wrap_pinmux_config.o \ - wrap_sdram_config.o CFLAGS_wrap_iocsr_config.o += -I$(srctree)/board/$(BOARDDIR) CFLAGS_wrap_pinmux_config.o += -I$(srctree)/board/$(BOARDDIR) CFLAGS_wrap_pll_config.o += -I$(srctree)/board/$(BOARDDIR) CFLAGS_wrap_sdram_config.o += -I$(srctree)/board/$(BOARDDIR) +endif diff --git a/arch/arm/mach-socfpga/clock_manager.c b/arch/arm/mach-socfpga/clock_manager.c index 29e18f8996..cb6ae03696 100644 --- a/arch/arm/mach-socfpga/clock_manager.c +++ b/arch/arm/mach-socfpga/clock_manager.c @@ -1,10 +1,11 @@ /* - * Copyright (C) 2013 Altera Corporation <www.altera.com> + * Copyright (C) 2013-2017 Altera Corporation <www.altera.com> * * SPDX-License-Identifier: GPL-2.0+ */ #include <common.h> +#include <wait_bit.h> #include <asm/io.h> #include <asm/arch/clock_manager.h> @@ -13,12 +14,17 @@ 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) +void cm_wait_for_lock(u32 mask) { - register uint32_t inter_val; - uint32_t retry = 0; + u32 inter_val; + u32 retry = 0; do { +#if defined(CONFIG_TARGET_SOCFPGA_GEN5) inter_val = readl(&clock_manager_base->inter) & mask; +#elif defined(CONFIG_TARGET_SOCFPGA_ARRIA10) + inter_val = readl(&clock_manager_base->stat) & mask; +#endif + /* Wait for stable lock */ if (inter_val == mask) retry++; else @@ -29,510 +35,10 @@ static void cm_wait_for_lock(uint32_t mask) } /* function to poll in the fsm busy bit */ -static void cm_wait_for_fsm(void) +int 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 struct cm_config * const cfg) -{ - unsigned long end; - - /* 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). - */ - end = timer_get_us() + 7; - - /* main mpu */ - writel(cfg->mpuclk, &clock_manager_base->main_pll.mpuclk); - - /* altera group mpuclk */ - writel(cfg->altera_grp_mpuclk, &clock_manager_base->altera.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 (timer_get_us() < end) - ; - - /* 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 = cm_get_osc_clk_hz(1); - 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 = cm_get_osc_clk_hz(1); - else if (reg == CLKMGR_VCO_SSRC_EOSC2) - clock = cm_get_osc_clk_hz(2); - else if (reg == CLKMGR_VCO_SSRC_F2S) - clock = cm_get_f2s_per_ref_clk_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 = cm_get_osc_clk_hz(1); - else if (reg == CLKMGR_VCO_SSRC_EOSC2) - clock = cm_get_osc_clk_hz(2); - else if (reg == CLKMGR_VCO_SSRC_F2S) - clock = cm_get_f2s_sdr_ref_clk_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 = cm_get_f2s_per_ref_clk_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 = cm_get_f2s_per_ref_clk_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", cm_get_osc_clk_hz(1) / 1000); - printf("EOSC2 %8d kHz\n", cm_get_osc_clk_hz(2) / 1000); - printf("F2S_SDR_REF %8d kHz\n", cm_get_f2s_sdr_ref_clk_hz() / 1000); - printf("F2S_PER_REF %8d kHz\n", cm_get_f2s_per_ref_clk_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); + return wait_for_bit(__func__, (const u32 *)&clock_manager_base->stat, + CLKMGR_STAT_BUSY, false, 20000, false); } int set_cpu_clk_info(void) @@ -543,7 +49,12 @@ int set_cpu_clk_info(void) gd->bd->bi_arm_freq = cm_get_mpu_clk_hz() / 1000000; gd->bd->bi_dsp_freq = 0; + +#if defined(CONFIG_TARGET_SOCFPGA_GEN5) gd->bd->bi_ddr_freq = cm_get_sdram_clk_hz() / 1000000; +#elif defined(CONFIG_TARGET_SOCFPGA_ARRIA10) + gd->bd->bi_ddr_freq = 0; +#endif return 0; } diff --git a/arch/arm/mach-socfpga/clock_manager_arria10.c b/arch/arm/mach-socfpga/clock_manager_arria10.c new file mode 100644 index 0000000000..482b8543f4 --- /dev/null +++ b/arch/arm/mach-socfpga/clock_manager_arria10.c @@ -0,0 +1,1096 @@ +/* + * Copyright (C) 2016-2017 Intel Corporation + * + * SPDX-License-Identifier: GPL-2.0 + */ + +#include <common.h> +#include <fdtdec.h> +#include <asm/io.h> +#include <asm/arch/clock_manager.h> + +DECLARE_GLOBAL_DATA_PTR; + +static u32 eosc1_hz; +static u32 cb_intosc_hz; +static u32 f2s_free_hz; +static u32 cm_l4_main_clk_hz; +static u32 cm_l4_sp_clk_hz; +static u32 cm_l4_mp_clk_hz; +static u32 cm_l4_sys_free_clk_hz; + +struct mainpll_cfg { + u32 vco0_psrc; + u32 vco1_denom; + u32 vco1_numer; + u32 mpuclk; + u32 mpuclk_cnt; + u32 mpuclk_src; + u32 nocclk; + u32 nocclk_cnt; + u32 nocclk_src; + u32 cntr2clk_cnt; + u32 cntr3clk_cnt; + u32 cntr4clk_cnt; + u32 cntr5clk_cnt; + u32 cntr6clk_cnt; + u32 cntr7clk_cnt; + u32 cntr7clk_src; + u32 cntr8clk_cnt; + u32 cntr9clk_cnt; + u32 cntr9clk_src; + u32 cntr15clk_cnt; + u32 nocdiv_l4mainclk; + u32 nocdiv_l4mpclk; + u32 nocdiv_l4spclk; + u32 nocdiv_csatclk; + u32 nocdiv_cstraceclk; + u32 nocdiv_cspdbclk; +}; + +struct perpll_cfg { + u32 vco0_psrc; + u32 vco1_denom; + u32 vco1_numer; + u32 cntr2clk_cnt; + u32 cntr2clk_src; + u32 cntr3clk_cnt; + u32 cntr3clk_src; + u32 cntr4clk_cnt; + u32 cntr4clk_src; + u32 cntr5clk_cnt; + u32 cntr5clk_src; + u32 cntr6clk_cnt; + u32 cntr6clk_src; + u32 cntr7clk_cnt; + u32 cntr8clk_cnt; + u32 cntr8clk_src; + u32 cntr9clk_cnt; + u32 emacctl_emac0sel; + u32 emacctl_emac1sel; + u32 emacctl_emac2sel; + u32 gpiodiv_gpiodbclk; +}; + +struct alteragrp_cfg { + u32 nocclk; + u32 mpuclk; +}; + +static const struct socfpga_clock_manager *clock_manager_base = + (struct socfpga_clock_manager *)SOCFPGA_CLKMGR_ADDRESS; + +static int of_to_struct(const void *blob, int node, int cfg_len, void *cfg) +{ + if (fdtdec_get_int_array(blob, node, "altr,of_reg_value", + (u32 *)cfg, cfg_len)) { + /* could not find required property */ + return -EINVAL; + } + + return 0; +} + +static int of_get_input_clks(const void *blob, int node, u32 *val) +{ + *val = fdtdec_get_uint(blob, node, "clock-frequency", 0); + if (!*val) + return -EINVAL; + + return 0; +} + +static int of_get_clk_cfg(const void *blob, struct mainpll_cfg *main_cfg, + struct perpll_cfg *per_cfg, + struct alteragrp_cfg *altrgrp_cfg) +{ + int node, child, len; + const char *node_name; + + node = fdtdec_next_compatible(blob, 0, COMPAT_ALTERA_SOCFPGA_CLK); + if (node < 0) + return -EINVAL; + + child = fdt_first_subnode(blob, node); + if (child < 0) + return -EINVAL; + + child = fdt_first_subnode(blob, child); + if (child < 0) + return -EINVAL; + + node_name = fdt_get_name(blob, child, &len); + + while (node_name) { + if (!strcmp(node_name, "osc1")) { + if (of_get_input_clks(blob, child, &eosc1_hz)) + return -EINVAL; + } else if (!strcmp(node_name, "cb_intosc_ls_clk")) { + if (of_get_input_clks(blob, child, &cb_intosc_hz)) + return -EINVAL; + } else if (!strcmp(node_name, "f2s_free_clk")) { + if (of_get_input_clks(blob, child, &f2s_free_hz)) + return -EINVAL; + } else if (!strcmp(node_name, "main_pll")) { + if (of_to_struct(blob, child, + sizeof(*main_cfg)/sizeof(u32), + main_cfg)) + return -EINVAL; + } else if (!strcmp(node_name, "periph_pll")) { + if (of_to_struct(blob, child, + sizeof(*per_cfg)/sizeof(u32), + per_cfg)) + return -EINVAL; + } else if (!strcmp(node_name, "altera")) { + if (of_to_struct(blob, child, + sizeof(*altrgrp_cfg)/sizeof(u32), + altrgrp_cfg)) + return -EINVAL; + + main_cfg->mpuclk = altrgrp_cfg->mpuclk; + main_cfg->nocclk = altrgrp_cfg->nocclk; + } + child = fdt_next_subnode(blob, child); + + if (child < 0) + break; + + node_name = fdt_get_name(blob, child, &len); + } + + return 0; +} + +/* calculate the intended main VCO frequency based on handoff */ +static unsigned int cm_calc_handoff_main_vco_clk_hz + (struct mainpll_cfg *main_cfg) +{ + unsigned int clk_hz; + + /* Check main VCO clock source: eosc, intosc or f2s? */ + switch (main_cfg->vco0_psrc) { + case CLKMGR_MAINPLL_VCO0_PSRC_EOSC: + clk_hz = eosc1_hz; + break; + case CLKMGR_MAINPLL_VCO0_PSRC_E_INTOSC: + clk_hz = cb_intosc_hz; + break; + case CLKMGR_MAINPLL_VCO0_PSRC_F2S: + clk_hz = f2s_free_hz; + break; + default: + return 0; + } + + /* calculate the VCO frequency */ + clk_hz /= 1 + main_cfg->vco1_denom; + clk_hz *= 1 + main_cfg->vco1_numer; + + return clk_hz; +} + +/* calculate the intended periph VCO frequency based on handoff */ +static unsigned int cm_calc_handoff_periph_vco_clk_hz( + struct mainpll_cfg *main_cfg, struct perpll_cfg *per_cfg) +{ + unsigned int clk_hz; + + /* Check periph VCO clock source: eosc, intosc, f2s or mainpll? */ + switch (per_cfg->vco0_psrc) { + case CLKMGR_PERPLL_VCO0_PSRC_EOSC: + clk_hz = eosc1_hz; + break; + case CLKMGR_PERPLL_VCO0_PSRC_E_INTOSC: + clk_hz = cb_intosc_hz; + break; + case CLKMGR_PERPLL_VCO0_PSRC_F2S: + clk_hz = f2s_free_hz; + break; + case CLKMGR_PERPLL_VCO0_PSRC_MAIN: + clk_hz = cm_calc_handoff_main_vco_clk_hz(main_cfg); + clk_hz /= main_cfg->cntr15clk_cnt; + break; + default: + return 0; + } + + /* calculate the VCO frequency */ + clk_hz /= 1 + per_cfg->vco1_denom; + clk_hz *= 1 + per_cfg->vco1_numer; + + return clk_hz; +} + +/* calculate the intended MPU clock frequency based on handoff */ +static unsigned int cm_calc_handoff_mpu_clk_hz(struct mainpll_cfg *main_cfg, + struct perpll_cfg *per_cfg) +{ + unsigned int clk_hz; + + /* Check MPU clock source: main, periph, osc1, intosc or f2s? */ + switch (main_cfg->mpuclk_src) { + case CLKMGR_MAINPLL_MPUCLK_SRC_MAIN: + clk_hz = cm_calc_handoff_main_vco_clk_hz(main_cfg); + clk_hz /= (main_cfg->mpuclk & CLKMGR_MAINPLL_MPUCLK_CNT_MSK) + + 1; + break; + case CLKMGR_MAINPLL_MPUCLK_SRC_PERI: + clk_hz = cm_calc_handoff_periph_vco_clk_hz(main_cfg, per_cfg); + clk_hz /= ((main_cfg->mpuclk >> + CLKMGR_MAINPLL_MPUCLK_PERICNT_LSB) & + CLKMGR_MAINPLL_MPUCLK_CNT_MSK) + 1; + break; + case CLKMGR_MAINPLL_MPUCLK_SRC_OSC1: + clk_hz = eosc1_hz; + break; + case CLKMGR_MAINPLL_MPUCLK_SRC_INTOSC: + clk_hz = cb_intosc_hz; + break; + case CLKMGR_MAINPLL_MPUCLK_SRC_FPGA: + clk_hz = f2s_free_hz; + break; + default: + return 0; + } + + clk_hz /= main_cfg->mpuclk_cnt + 1; + return clk_hz; +} + +/* calculate the intended NOC clock frequency based on handoff */ +static unsigned int cm_calc_handoff_noc_clk_hz(struct mainpll_cfg *main_cfg, + struct perpll_cfg *per_cfg) +{ + unsigned int clk_hz; + + /* Check MPU clock source: main, periph, osc1, intosc or f2s? */ + switch (main_cfg->nocclk_src) { + case CLKMGR_MAINPLL_NOCCLK_SRC_MAIN: + clk_hz = cm_calc_handoff_main_vco_clk_hz(main_cfg); + clk_hz /= (main_cfg->nocclk & CLKMGR_MAINPLL_NOCCLK_CNT_MSK) + + 1; + break; + case CLKMGR_MAINPLL_NOCCLK_SRC_PERI: + clk_hz = cm_calc_handoff_periph_vco_clk_hz(main_cfg, per_cfg); + clk_hz /= ((main_cfg->nocclk >> + CLKMGR_MAINPLL_NOCCLK_PERICNT_LSB) & + CLKMGR_MAINPLL_NOCCLK_CNT_MSK) + 1; + break; + case CLKMGR_MAINPLL_NOCCLK_SRC_OSC1: + clk_hz = eosc1_hz; + break; + case CLKMGR_MAINPLL_NOCCLK_SRC_INTOSC: + clk_hz = cb_intosc_hz; + break; + case CLKMGR_MAINPLL_NOCCLK_SRC_FPGA: + clk_hz = f2s_free_hz; + break; + default: + return 0; + } + + clk_hz /= main_cfg->nocclk_cnt + 1; + return clk_hz; +} + +/* return 1 if PLL ramp is required */ +static int cm_is_pll_ramp_required(int main0periph1, + struct mainpll_cfg *main_cfg, + struct perpll_cfg *per_cfg) +{ + /* Check for main PLL */ + if (main0periph1 == 0) { + /* + * PLL ramp is not required if both MPU clock and NOC clock are + * not sourced from main PLL + */ + if (main_cfg->mpuclk_src != CLKMGR_MAINPLL_MPUCLK_SRC_MAIN && + main_cfg->nocclk_src != CLKMGR_MAINPLL_NOCCLK_SRC_MAIN) + return 0; + + /* + * PLL ramp is required if MPU clock is sourced from main PLL + * and MPU clock is over 900MHz (as advised by HW team) + */ + if (main_cfg->mpuclk_src == CLKMGR_MAINPLL_MPUCLK_SRC_MAIN && + (cm_calc_handoff_mpu_clk_hz(main_cfg, per_cfg) > + CLKMGR_PLL_RAMP_MPUCLK_THRESHOLD_HZ)) + return 1; + + /* + * PLL ramp is required if NOC clock is sourced from main PLL + * and NOC clock is over 300MHz (as advised by HW team) + */ + if (main_cfg->nocclk_src == CLKMGR_MAINPLL_NOCCLK_SRC_MAIN && + (cm_calc_handoff_noc_clk_hz(main_cfg, per_cfg) > + CLKMGR_PLL_RAMP_NOCCLK_THRESHOLD_HZ)) + return 2; + + } else if (main0periph1 == 1) { + /* + * PLL ramp is not required if both MPU clock and NOC clock are + * not sourced from periph PLL + */ + if (main_cfg->mpuclk_src != CLKMGR_MAINPLL_MPUCLK_SRC_PERI && + main_cfg->nocclk_src != CLKMGR_MAINPLL_NOCCLK_SRC_PERI) + return 0; + + /* + * PLL ramp is required if MPU clock are source from periph PLL + * and MPU clock is over 900MHz (as advised by HW team) + */ + if (main_cfg->mpuclk_src == CLKMGR_MAINPLL_MPUCLK_SRC_PERI && + (cm_calc_handoff_mpu_clk_hz(main_cfg, per_cfg) > + CLKMGR_PLL_RAMP_MPUCLK_THRESHOLD_HZ)) + return 1; + + /* + * PLL ramp is required if NOC clock are source from periph PLL + * and NOC clock is over 300MHz (as advised by HW team) + */ + if (main_cfg->nocclk_src == CLKMGR_MAINPLL_NOCCLK_SRC_PERI && + (cm_calc_handoff_noc_clk_hz(main_cfg, per_cfg) > + CLKMGR_PLL_RAMP_NOCCLK_THRESHOLD_HZ)) + return 2; + } + + return 0; +} + +static u32 cm_calculate_numer(struct mainpll_cfg *main_cfg, + struct perpll_cfg *per_cfg, + u32 safe_hz, u32 clk_hz) +{ + u32 cnt; + u32 clk; + u32 shift; + u32 mask; + u32 denom; + + if (main_cfg->mpuclk_src == CLKMGR_MAINPLL_MPUCLK_SRC_MAIN) { + cnt = main_cfg->mpuclk_cnt; + clk = main_cfg->mpuclk; + shift = 0; + mask = CLKMGR_MAINPLL_MPUCLK_CNT_MSK; + denom = main_cfg->vco1_denom; + } else if (main_cfg->nocclk_src == CLKMGR_MAINPLL_NOCCLK_SRC_MAIN) { + cnt = main_cfg->nocclk_cnt; + clk = main_cfg->nocclk; + shift = 0; + mask = CLKMGR_MAINPLL_NOCCLK_CNT_MSK; + denom = main_cfg->vco1_denom; + } else if (main_cfg->mpuclk_src == CLKMGR_MAINPLL_MPUCLK_SRC_PERI) { + cnt = main_cfg->mpuclk_cnt; + clk = main_cfg->mpuclk; + shift = CLKMGR_MAINPLL_MPUCLK_PERICNT_LSB; + mask = CLKMGR_MAINPLL_MPUCLK_CNT_MSK; + denom = per_cfg->vco1_denom; + } else if (main_cfg->nocclk_src == CLKMGR_MAINPLL_NOCCLK_SRC_PERI) { + cnt = main_cfg->nocclk_cnt; + clk = main_cfg->nocclk; + shift = CLKMGR_MAINPLL_NOCCLK_PERICNT_LSB; + mask = CLKMGR_MAINPLL_NOCCLK_CNT_MSK; + denom = per_cfg->vco1_denom; + } else { + return 0; + } + + return (safe_hz / clk_hz) * (cnt + 1) * (((clk >> shift) & mask) + 1) * + (1 + denom) - 1; +} + +/* + * Calculate the new PLL numerator which is based on existing DTS hand off and + * intended safe frequency (safe_hz). Note that PLL ramp is only modifying the + * numerator while maintaining denominator as denominator will influence the + * jitter condition. Please refer A10 HPS TRM for the jitter guide. Note final + * value for numerator is minus with 1 to cater our register value + * representation. + */ +static unsigned int cm_calc_safe_pll_numer(int main0periph1, + struct mainpll_cfg *main_cfg, + struct perpll_cfg *per_cfg, + unsigned int safe_hz) +{ + unsigned int clk_hz = 0; + + /* Check for main PLL */ + if (main0periph1 == 0) { + /* Check main VCO clock source: eosc, intosc or f2s? */ + switch (main_cfg->vco0_psrc) { + case CLKMGR_MAINPLL_VCO0_PSRC_EOSC: + clk_hz = eosc1_hz; + break; + case CLKMGR_MAINPLL_VCO0_PSRC_E_INTOSC: + clk_hz = cb_intosc_hz; + break; + case CLKMGR_MAINPLL_VCO0_PSRC_F2S: + clk_hz = f2s_free_hz; + break; + default: + return 0; + } + } else if (main0periph1 == 1) { + /* Check periph VCO clock source: eosc, intosc, f2s, mainpll */ + switch (per_cfg->vco0_psrc) { + case CLKMGR_PERPLL_VCO0_PSRC_EOSC: + clk_hz = eosc1_hz; + break; + case CLKMGR_PERPLL_VCO0_PSRC_E_INTOSC: + clk_hz = cb_intosc_hz; + break; + case CLKMGR_PERPLL_VCO0_PSRC_F2S: + clk_hz = f2s_free_hz; + break; + case CLKMGR_PERPLL_VCO0_PSRC_MAIN: + clk_hz = cm_calc_handoff_main_vco_clk_hz(main_cfg); + clk_hz /= main_cfg->cntr15clk_cnt; + break; + default: + return 0; + } + } else { + return 0; + } + + return cm_calculate_numer(main_cfg, per_cfg, safe_hz, clk_hz); +} + +/* ramping the main PLL to final value */ +static void cm_pll_ramp_main(struct mainpll_cfg *main_cfg, + struct perpll_cfg *per_cfg, + unsigned int pll_ramp_main_hz) +{ + unsigned int clk_hz = 0, clk_incr_hz = 0, clk_final_hz = 0; + + /* find out the increment value */ + if (main_cfg->mpuclk_src == CLKMGR_MAINPLL_MPUCLK_SRC_MAIN) { + clk_incr_hz = CLKMGR_PLL_RAMP_MPUCLK_INCREMENT_HZ; + clk_final_hz = cm_calc_handoff_mpu_clk_hz(main_cfg, per_cfg); + } else if (main_cfg->nocclk_src == CLKMGR_MAINPLL_NOCCLK_SRC_MAIN) { + clk_incr_hz = CLKMGR_PLL_RAMP_NOCCLK_INCREMENT_HZ; + clk_final_hz = cm_calc_handoff_noc_clk_hz(main_cfg, per_cfg); + } + + /* execute the ramping here */ + for (clk_hz = pll_ramp_main_hz + clk_incr_hz; + clk_hz < clk_final_hz; clk_hz += clk_incr_hz) { + writel((main_cfg->vco1_denom << + CLKMGR_MAINPLL_VCO1_DENOM_LSB) | + cm_calc_safe_pll_numer(0, main_cfg, per_cfg, clk_hz), + &clock_manager_base->main_pll.vco1); + mdelay(1); + cm_wait_for_lock(LOCKED_MASK); + } + writel((main_cfg->vco1_denom << CLKMGR_MAINPLL_VCO1_DENOM_LSB) | + main_cfg->vco1_numer, &clock_manager_base->main_pll.vco1); + mdelay(1); + cm_wait_for_lock(LOCKED_MASK); +} + +/* ramping the periph PLL to final value */ +static void cm_pll_ramp_periph(struct mainpll_cfg *main_cfg, + struct perpll_cfg *per_cfg, + unsigned int pll_ramp_periph_hz) +{ + unsigned int clk_hz = 0, clk_incr_hz = 0, clk_final_hz = 0; + + /* find out the increment value */ + if (main_cfg->mpuclk_src == CLKMGR_MAINPLL_MPUCLK_SRC_PERI) { + clk_incr_hz = CLKMGR_PLL_RAMP_MPUCLK_INCREMENT_HZ; + clk_final_hz = cm_calc_handoff_mpu_clk_hz(main_cfg, per_cfg); + } else if (main_cfg->nocclk_src == CLKMGR_MAINPLL_NOCCLK_SRC_PERI) { + clk_incr_hz = CLKMGR_PLL_RAMP_NOCCLK_INCREMENT_HZ; + clk_final_hz = cm_calc_handoff_noc_clk_hz(main_cfg, per_cfg); + } + /* execute the ramping here */ + for (clk_hz = pll_ramp_periph_hz + clk_incr_hz; + clk_hz < clk_final_hz; clk_hz += clk_incr_hz) { + writel((per_cfg->vco1_denom << CLKMGR_PERPLL_VCO1_DENOM_LSB) | + cm_calc_safe_pll_numer(1, main_cfg, per_cfg, clk_hz), + &clock_manager_base->per_pll.vco1); + mdelay(1); + cm_wait_for_lock(LOCKED_MASK); + } + writel((per_cfg->vco1_denom << CLKMGR_PERPLL_VCO1_DENOM_LSB) | + per_cfg->vco1_numer, &clock_manager_base->per_pll.vco1); + mdelay(1); + cm_wait_for_lock(LOCKED_MASK); +} + +/* + * Setup clocks while making no assumptions of the + * 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 (bgpwr dwn). + * + * Put peripheral and main pll src to reset value to avoid glitch. + * + * Delay 5 us. + * + * Deassert bg pwr dn 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 + */ + +static int cm_full_cfg(struct mainpll_cfg *main_cfg, struct perpll_cfg *per_cfg) +{ + unsigned int pll_ramp_main_hz = 0, pll_ramp_periph_hz = 0, + ramp_required; + + /* gate off all mainpll clock excpet HW managed clock */ + writel(CLKMGR_MAINPLL_EN_S2FUSER0CLKEN_SET_MSK | + CLKMGR_MAINPLL_EN_HMCPLLREFCLKEN_SET_MSK, + &clock_manager_base->main_pll.enr); + + /* now we can gate off the rest of the peripheral clocks */ + writel(0, &clock_manager_base->per_pll.en); + + /* Put all plls in external bypass */ + writel(CLKMGR_MAINPLL_BYPASS_RESET, + &clock_manager_base->main_pll.bypasss); + writel(CLKMGR_PERPLL_BYPASS_RESET, + &clock_manager_base->per_pll.bypasss); + + /* + * Put all plls VCO registers back to reset value. + * Some code might have messed with them. At same time set the + * desired clock source + */ + writel(CLKMGR_MAINPLL_VCO0_RESET | + CLKMGR_MAINPLL_VCO0_REGEXTSEL_SET_MSK | + (main_cfg->vco0_psrc << CLKMGR_MAINPLL_VCO0_PSRC_LSB), + &clock_manager_base->main_pll.vco0); + + writel(CLKMGR_PERPLL_VCO0_RESET | + CLKMGR_PERPLL_VCO0_REGEXTSEL_SET_MSK | + (per_cfg->vco0_psrc << CLKMGR_PERPLL_VCO0_PSRC_LSB), + &clock_manager_base->per_pll.vco0); + + writel(CLKMGR_MAINPLL_VCO1_RESET, &clock_manager_base->main_pll.vco1); + writel(CLKMGR_PERPLL_VCO1_RESET, &clock_manager_base->per_pll.vco1); + + /* clear the interrupt register status register */ + writel(CLKMGR_CLKMGR_INTR_MAINPLLLOST_SET_MSK | + CLKMGR_CLKMGR_INTR_PERPLLLOST_SET_MSK | + CLKMGR_CLKMGR_INTR_MAINPLLRFSLIP_SET_MSK | + CLKMGR_CLKMGR_INTR_PERPLLRFSLIP_SET_MSK | + CLKMGR_CLKMGR_INTR_MAINPLLFBSLIP_SET_MSK | + CLKMGR_CLKMGR_INTR_PERPLLFBSLIP_SET_MSK | + CLKMGR_CLKMGR_INTR_MAINPLLACHIEVED_SET_MSK | + CLKMGR_CLKMGR_INTR_PERPLLACHIEVED_SET_MSK, + &clock_manager_base->intr); + + /* Program VCO Numerator and Denominator for main PLL */ + ramp_required = cm_is_pll_ramp_required(0, main_cfg, per_cfg); + if (ramp_required) { + /* set main PLL to safe starting threshold frequency */ + if (ramp_required == 1) + pll_ramp_main_hz = CLKMGR_PLL_RAMP_MPUCLK_THRESHOLD_HZ; + else if (ramp_required == 2) + pll_ramp_main_hz = CLKMGR_PLL_RAMP_NOCCLK_THRESHOLD_HZ; + + writel((main_cfg->vco1_denom << CLKMGR_MAINPLL_VCO1_DENOM_LSB) | + cm_calc_safe_pll_numer(0, main_cfg, per_cfg, + pll_ramp_main_hz), + &clock_manager_base->main_pll.vco1); + } else + writel((main_cfg->vco1_denom << CLKMGR_MAINPLL_VCO1_DENOM_LSB) | + main_cfg->vco1_numer, + &clock_manager_base->main_pll.vco1); + + /* Program VCO Numerator and Denominator for periph PLL */ + ramp_required = cm_is_pll_ramp_required(1, main_cfg, per_cfg); + if (ramp_required) { + /* set periph PLL to safe starting threshold frequency */ + if (ramp_required == 1) + pll_ramp_periph_hz = + CLKMGR_PLL_RAMP_MPUCLK_THRESHOLD_HZ; + else if (ramp_required == 2) + pll_ramp_periph_hz = + CLKMGR_PLL_RAMP_NOCCLK_THRESHOLD_HZ; + + writel((per_cfg->vco1_denom << CLKMGR_PERPLL_VCO1_DENOM_LSB) | + cm_calc_safe_pll_numer(1, main_cfg, per_cfg, + pll_ramp_periph_hz), + &clock_manager_base->per_pll.vco1); + } else + writel((per_cfg->vco1_denom << CLKMGR_PERPLL_VCO1_DENOM_LSB) | + per_cfg->vco1_numer, + &clock_manager_base->per_pll.vco1); + + /* Wait for at least 5 us */ + udelay(5); + + /* Now deassert BGPWRDN and PWRDN */ + clrbits_le32(&clock_manager_base->main_pll.vco0, + CLKMGR_MAINPLL_VCO0_BGPWRDN_SET_MSK | + CLKMGR_MAINPLL_VCO0_PWRDN_SET_MSK); + clrbits_le32(&clock_manager_base->per_pll.vco0, + CLKMGR_PERPLL_VCO0_BGPWRDN_SET_MSK | + CLKMGR_PERPLL_VCO0_PWRDN_SET_MSK); + + /* Wait for at least 7 us */ + udelay(7); + + /* enable the VCO and disable the external regulator to PLL */ + writel((readl(&clock_manager_base->main_pll.vco0) & + ~CLKMGR_MAINPLL_VCO0_REGEXTSEL_SET_MSK) | + CLKMGR_MAINPLL_VCO0_EN_SET_MSK, + &clock_manager_base->main_pll.vco0); + writel((readl(&clock_manager_base->per_pll.vco0) & + ~CLKMGR_PERPLL_VCO0_REGEXTSEL_SET_MSK) | + CLKMGR_PERPLL_VCO0_EN_SET_MSK, + &clock_manager_base->per_pll.vco0); + + /* setup all the main PLL counter and clock source */ + writel(main_cfg->nocclk, + SOCFPGA_CLKMGR_ADDRESS + CLKMGR_MAINPLL_NOC_CLK_OFFSET); + writel(main_cfg->mpuclk, + SOCFPGA_CLKMGR_ADDRESS + CLKMGR_ALTERAGRP_MPU_CLK_OFFSET); + + /* main_emaca_clk divider */ + writel(main_cfg->cntr2clk_cnt, &clock_manager_base->main_pll.cntr2clk); + /* main_emacb_clk divider */ + writel(main_cfg->cntr3clk_cnt, &clock_manager_base->main_pll.cntr3clk); + /* main_emac_ptp_clk divider */ + writel(main_cfg->cntr4clk_cnt, &clock_manager_base->main_pll.cntr4clk); + /* main_gpio_db_clk divider */ + writel(main_cfg->cntr5clk_cnt, &clock_manager_base->main_pll.cntr5clk); + /* main_sdmmc_clk divider */ + writel(main_cfg->cntr6clk_cnt, &clock_manager_base->main_pll.cntr6clk); + /* main_s2f_user0_clk divider */ + writel(main_cfg->cntr7clk_cnt | + (main_cfg->cntr7clk_src << CLKMGR_MAINPLL_CNTR7CLK_SRC_LSB), + &clock_manager_base->main_pll.cntr7clk); + /* main_s2f_user1_clk divider */ + writel(main_cfg->cntr8clk_cnt, &clock_manager_base->main_pll.cntr8clk); + /* main_hmc_pll_clk divider */ + writel(main_cfg->cntr9clk_cnt | + (main_cfg->cntr9clk_src << CLKMGR_MAINPLL_CNTR9CLK_SRC_LSB), + &clock_manager_base->main_pll.cntr9clk); + /* main_periph_ref_clk divider */ + writel(main_cfg->cntr15clk_cnt, + &clock_manager_base->main_pll.cntr15clk); + + /* setup all the peripheral PLL counter and clock source */ + /* peri_emaca_clk divider */ + writel(per_cfg->cntr2clk_cnt | + (per_cfg->cntr2clk_src << CLKMGR_PERPLL_CNTR2CLK_SRC_LSB), + &clock_manager_base->per_pll.cntr2clk); + /* peri_emacb_clk divider */ + writel(per_cfg->cntr3clk_cnt | + (per_cfg->cntr3clk_src << CLKMGR_PERPLL_CNTR3CLK_SRC_LSB), + &clock_manager_base->per_pll.cntr3clk); + /* peri_emac_ptp_clk divider */ + writel(per_cfg->cntr4clk_cnt | + (per_cfg->cntr4clk_src << CLKMGR_PERPLL_CNTR4CLK_SRC_LSB), + &clock_manager_base->per_pll.cntr4clk); + /* peri_gpio_db_clk divider */ + writel(per_cfg->cntr5clk_cnt | + (per_cfg->cntr5clk_src << CLKMGR_PERPLL_CNTR5CLK_SRC_LSB), + &clock_manager_base->per_pll.cntr5clk); + /* peri_sdmmc_clk divider */ + writel(per_cfg->cntr6clk_cnt | + (per_cfg->cntr6clk_src << CLKMGR_PERPLL_CNTR6CLK_SRC_LSB), + &clock_manager_base->per_pll.cntr6clk); + /* peri_s2f_user0_clk divider */ + writel(per_cfg->cntr7clk_cnt, &clock_manager_base->per_pll.cntr7clk); + /* peri_s2f_user1_clk divider */ + writel(per_cfg->cntr8clk_cnt | + (per_cfg->cntr8clk_src << CLKMGR_PERPLL_CNTR8CLK_SRC_LSB), + &clock_manager_base->per_pll.cntr8clk); + /* peri_hmc_pll_clk divider */ + writel(per_cfg->cntr9clk_cnt, &clock_manager_base->per_pll.cntr9clk); + + /* setup all the external PLL counter */ + /* mpu wrapper / external divider */ + writel(main_cfg->mpuclk_cnt | + (main_cfg->mpuclk_src << CLKMGR_MAINPLL_MPUCLK_SRC_LSB), + &clock_manager_base->main_pll.mpuclk); + /* NOC wrapper / external divider */ + writel(main_cfg->nocclk_cnt | + (main_cfg->nocclk_src << CLKMGR_MAINPLL_NOCCLK_SRC_LSB), + &clock_manager_base->main_pll.nocclk); + /* NOC subclock divider such as l4 */ + writel(main_cfg->nocdiv_l4mainclk | + (main_cfg->nocdiv_l4mpclk << + CLKMGR_MAINPLL_NOCDIV_L4MPCLK_LSB) | + (main_cfg->nocdiv_l4spclk << + CLKMGR_MAINPLL_NOCDIV_L4SPCLK_LSB) | + (main_cfg->nocdiv_csatclk << + CLKMGR_MAINPLL_NOCDIV_CSATCLK_LSB) | + (main_cfg->nocdiv_cstraceclk << + CLKMGR_MAINPLL_NOCDIV_CSTRACECLK_LSB) | + (main_cfg->nocdiv_cspdbclk << + CLKMGR_MAINPLL_NOCDIV_CSPDBGCLK_LSB), + &clock_manager_base->main_pll.nocdiv); + /* gpio_db external divider */ + writel(per_cfg->gpiodiv_gpiodbclk, + &clock_manager_base->per_pll.gpiodiv); + + /* setup the EMAC clock mux select */ + writel((per_cfg->emacctl_emac0sel << + CLKMGR_PERPLL_EMACCTL_EMAC0SEL_LSB) | + (per_cfg->emacctl_emac1sel << + CLKMGR_PERPLL_EMACCTL_EMAC1SEL_LSB) | + (per_cfg->emacctl_emac2sel << + CLKMGR_PERPLL_EMACCTL_EMAC2SEL_LSB), + &clock_manager_base->per_pll.emacctl); + + /* at this stage, check for PLL lock status */ + cm_wait_for_lock(LOCKED_MASK); + + /* + * after locking, but before taking out of bypass, + * assert/deassert outresetall + */ + /* assert mainpll outresetall */ + setbits_le32(&clock_manager_base->main_pll.vco0, + CLKMGR_MAINPLL_VCO0_OUTRSTALL_SET_MSK); + /* assert perpll outresetall */ + setbits_le32(&clock_manager_base->per_pll.vco0, + CLKMGR_PERPLL_VCO0_OUTRSTALL_SET_MSK); + /* de-assert mainpll outresetall */ + clrbits_le32(&clock_manager_base->main_pll.vco0, + CLKMGR_MAINPLL_VCO0_OUTRSTALL_SET_MSK); + /* de-assert perpll outresetall */ + clrbits_le32(&clock_manager_base->per_pll.vco0, + CLKMGR_PERPLL_VCO0_OUTRSTALL_SET_MSK); + + /* Take all PLLs out of bypass when boot mode is cleared. */ + /* release mainpll from bypass */ + writel(CLKMGR_MAINPLL_BYPASS_RESET, + &clock_manager_base->main_pll.bypassr); + /* wait till Clock Manager is not busy */ + cm_wait_for_fsm(); + + /* release perpll from bypass */ + writel(CLKMGR_PERPLL_BYPASS_RESET, + &clock_manager_base->per_pll.bypassr); + /* wait till Clock Manager is not busy */ + cm_wait_for_fsm(); + + /* clear boot mode */ + clrbits_le32(&clock_manager_base->ctrl, + CLKMGR_CLKMGR_CTL_BOOTMOD_SET_MSK); + /* wait till Clock Manager is not busy */ + cm_wait_for_fsm(); + + /* At here, we need to ramp to final value if needed */ + if (pll_ramp_main_hz != 0) + cm_pll_ramp_main(main_cfg, per_cfg, pll_ramp_main_hz); + if (pll_ramp_periph_hz != 0) + cm_pll_ramp_periph(main_cfg, per_cfg, pll_ramp_periph_hz); + + /* Now ungate non-hw-managed clocks */ + writel(CLKMGR_MAINPLL_EN_S2FUSER0CLKEN_SET_MSK | + CLKMGR_MAINPLL_EN_HMCPLLREFCLKEN_SET_MSK, + &clock_manager_base->main_pll.ens); + writel(CLKMGR_PERPLL_EN_RESET, &clock_manager_base->per_pll.ens); + + /* Clear the loss lock and slip bits as they might set during + clock reconfiguration */ + writel(CLKMGR_CLKMGR_INTR_MAINPLLLOST_SET_MSK | + CLKMGR_CLKMGR_INTR_PERPLLLOST_SET_MSK | + CLKMGR_CLKMGR_INTR_MAINPLLRFSLIP_SET_MSK | + CLKMGR_CLKMGR_INTR_PERPLLRFSLIP_SET_MSK | + CLKMGR_CLKMGR_INTR_MAINPLLFBSLIP_SET_MSK | + CLKMGR_CLKMGR_INTR_PERPLLFBSLIP_SET_MSK, + &clock_manager_base->intr); + + return 0; +} + +void cm_use_intosc(void) +{ + setbits_le32(&clock_manager_base->ctrl, + CLKMGR_CLKMGR_CTL_BOOTCLK_INTOSC_SET_MSK); +} + +unsigned int cm_get_noc_clk_hz(void) +{ + unsigned int clk_src, divisor, nocclk, src_hz; + + nocclk = readl(&clock_manager_base->main_pll.nocclk); + clk_src = (nocclk >> CLKMGR_MAINPLL_NOCCLK_SRC_LSB) & + CLKMGR_MAINPLL_NOCCLK_SRC_MSK; + + divisor = 1 + (nocclk & CLKMGR_MAINPLL_NOCDIV_MSK); + + if (clk_src == CLKMGR_PERPLLGRP_SRC_MAIN) { + src_hz = cm_get_main_vco_clk_hz(); + src_hz /= 1 + + (readl(SOCFPGA_CLKMGR_ADDRESS + CLKMGR_MAINPLL_NOC_CLK_OFFSET) & + CLKMGR_MAINPLL_NOCCLK_CNT_MSK); + } else if (clk_src == CLKMGR_PERPLLGRP_SRC_PERI) { + src_hz = cm_get_per_vco_clk_hz(); + src_hz /= 1 + + ((readl(SOCFPGA_CLKMGR_ADDRESS + + CLKMGR_MAINPLL_NOC_CLK_OFFSET) >> + CLKMGR_MAINPLL_NOCCLK_PERICNT_LSB) & + CLKMGR_MAINPLL_NOCCLK_CNT_MSK); + } else if (clk_src == CLKMGR_PERPLLGRP_SRC_OSC1) { + src_hz = eosc1_hz; + } else if (clk_src == CLKMGR_PERPLLGRP_SRC_INTOSC) { + src_hz = cb_intosc_hz; + } else if (clk_src == CLKMGR_PERPLLGRP_SRC_FPGA) { + src_hz = f2s_free_hz; + } else { + src_hz = 0; + } + + return src_hz / divisor; +} + +unsigned int cm_get_l4_noc_hz(unsigned int nocdivshift) +{ + unsigned int divisor2 = 1 << + ((readl(&clock_manager_base->main_pll.nocdiv) >> + nocdivshift) & CLKMGR_MAINPLL_NOCDIV_MSK); + + return cm_get_noc_clk_hz() / divisor2; +} + +int cm_basic_init(const void *blob) +{ + struct mainpll_cfg main_cfg; + struct perpll_cfg per_cfg; + struct alteragrp_cfg altrgrp_cfg; + int rval; + + /* initialize to zero for use case of optional node */ + memset(&main_cfg, 0, sizeof(main_cfg)); + memset(&per_cfg, 0, sizeof(per_cfg)); + memset(&altrgrp_cfg, 0, sizeof(altrgrp_cfg)); + + rval = of_get_clk_cfg(blob, &main_cfg, &per_cfg, &altrgrp_cfg); + if (rval) + return rval; + + rval = cm_full_cfg(&main_cfg, &per_cfg); + + cm_l4_main_clk_hz = + cm_get_l4_noc_hz(CLKMGR_MAINPLL_NOCDIV_L4MAINCLK_LSB); + + cm_l4_mp_clk_hz = cm_get_l4_noc_hz(CLKMGR_MAINPLL_NOCDIV_L4MPCLK_LSB); + + cm_l4_sp_clk_hz = cm_get_l4_sp_clk_hz(); + + cm_l4_sys_free_clk_hz = cm_get_noc_clk_hz() / 4; + + return rval; +} + +unsigned long cm_get_mpu_clk_hz(void) +{ + u32 reg, clk_hz; + u32 clk_src, mainmpuclk_reg; + + mainmpuclk_reg = readl(&clock_manager_base->main_pll.mpuclk); + + clk_src = (mainmpuclk_reg >> CLKMGR_MAINPLL_MPUCLK_SRC_LSB) & + CLKMGR_MAINPLL_MPUCLK_SRC_MSK; + + reg = readl(&clock_manager_base->altera.mpuclk); + /* Check MPU clock source: main, periph, osc1, intosc or f2s? */ + switch (clk_src) { + case CLKMGR_MAINPLL_MPUCLK_SRC_MAIN: + clk_hz = cm_get_main_vco_clk_hz(); + clk_hz /= (reg & CLKMGR_MAINPLL_MPUCLK_CNT_MSK) + 1; + break; + case CLKMGR_MAINPLL_MPUCLK_SRC_PERI: + clk_hz = cm_get_per_vco_clk_hz(); + clk_hz /= (((reg >> CLKMGR_MAINPLL_MPUCLK_PERICNT_LSB) & + CLKMGR_MAINPLL_MPUCLK_CNT_MSK) + 1); + break; + case CLKMGR_MAINPLL_MPUCLK_SRC_OSC1: + clk_hz = eosc1_hz; + break; + case CLKMGR_MAINPLL_MPUCLK_SRC_INTOSC: + clk_hz = cb_intosc_hz; + break; + case CLKMGR_MAINPLL_MPUCLK_SRC_FPGA: + clk_hz = f2s_free_hz; + break; + default: + printf("cm_get_mpu_clk_hz invalid clk_src %d\n", clk_src); + return 0; + } + + clk_hz /= (mainmpuclk_reg & CLKMGR_MAINPLL_MPUCLK_CNT_MSK) + 1; + + return clk_hz; +} + +unsigned int cm_get_per_vco_clk_hz(void) +{ + u32 src_hz = 0; + u32 clk_src = 0; + u32 numer = 0; + u32 denom = 0; + u32 vco = 0; + + clk_src = readl(&clock_manager_base->per_pll.vco0); + + clk_src = (clk_src >> CLKMGR_PERPLL_VCO0_PSRC_LSB) & + CLKMGR_PERPLL_VCO0_PSRC_MSK; + + if (clk_src == CLKMGR_PERPLL_VCO0_PSRC_EOSC) { + src_hz = eosc1_hz; + } else if (clk_src == CLKMGR_PERPLL_VCO0_PSRC_E_INTOSC) { + src_hz = cb_intosc_hz; + } else if (clk_src == CLKMGR_PERPLL_VCO0_PSRC_F2S) { + src_hz = f2s_free_hz; + } else if (clk_src == CLKMGR_PERPLL_VCO0_PSRC_MAIN) { + src_hz = cm_get_main_vco_clk_hz(); + src_hz /= (readl(&clock_manager_base->main_pll.cntr15clk) & + CLKMGR_MAINPLL_CNTRCLK_MSK) + 1; + } else { + printf("cm_get_per_vco_clk_hz invalid clk_src %d\n", clk_src); + return 0; + } + + vco = readl(&clock_manager_base->per_pll.vco1); + + numer = vco & CLKMGR_PERPLL_VCO1_NUMER_MSK; + + denom = (vco >> CLKMGR_PERPLL_VCO1_DENOM_LSB) & + CLKMGR_PERPLL_VCO1_DENOM_MSK; + + vco = src_hz; + vco /= 1 + denom; + vco *= 1 + numer; + + return vco; +} + +unsigned int cm_get_main_vco_clk_hz(void) +{ + u32 src_hz, numer, denom, vco; + + u32 clk_src = readl(&clock_manager_base->main_pll.vco0); + + clk_src = (clk_src >> CLKMGR_MAINPLL_VCO0_PSRC_LSB) & + CLKMGR_MAINPLL_VCO0_PSRC_MSK; + + if (clk_src == CLKMGR_MAINPLL_VCO0_PSRC_EOSC) { + src_hz = eosc1_hz; + } else if (clk_src == CLKMGR_MAINPLL_VCO0_PSRC_E_INTOSC) { + src_hz = cb_intosc_hz; + } else if (clk_src == CLKMGR_MAINPLL_VCO0_PSRC_F2S) { + src_hz = f2s_free_hz; + } else { + printf("cm_get_main_vco_clk_hz invalid clk_src %d\n", clk_src); + return 0; + } + + vco = readl(&clock_manager_base->main_pll.vco1); + + numer = vco & CLKMGR_MAINPLL_VCO1_NUMER_MSK; + + denom = (vco >> CLKMGR_MAINPLL_VCO1_DENOM_LSB) & + CLKMGR_MAINPLL_VCO1_DENOM_MSK; + + vco = src_hz; + vco /= 1 + denom; + vco *= 1 + numer; + + return vco; +} + +unsigned int cm_get_l4_sp_clk_hz(void) +{ + return cm_get_l4_noc_hz(CLKMGR_MAINPLL_NOCDIV_L4SPCLK_LSB); +} + +unsigned int cm_get_mmc_controller_clk_hz(void) +{ + u32 clk_hz = 0; + u32 clk_input = 0; + + clk_input = readl(&clock_manager_base->per_pll.cntr6clk); + clk_input = (clk_input >> CLKMGR_PERPLL_CNTR6CLK_SRC_LSB) & + CLKMGR_PERPLLGRP_SRC_MSK; + + switch (clk_input) { + case CLKMGR_PERPLLGRP_SRC_MAIN: + clk_hz = cm_get_main_vco_clk_hz(); + clk_hz /= 1 + (readl(&clock_manager_base->main_pll.cntr6clk) & + CLKMGR_MAINPLL_CNTRCLK_MSK); + break; + + case CLKMGR_PERPLLGRP_SRC_PERI: + clk_hz = cm_get_per_vco_clk_hz(); + clk_hz /= 1 + (readl(&clock_manager_base->per_pll.cntr6clk) & + CLKMGR_PERPLL_CNTRCLK_MSK); + break; + + case CLKMGR_PERPLLGRP_SRC_OSC1: + clk_hz = eosc1_hz; + break; + + case CLKMGR_PERPLLGRP_SRC_INTOSC: + clk_hz = cb_intosc_hz; + break; + + case CLKMGR_PERPLLGRP_SRC_FPGA: + clk_hz = f2s_free_hz; + break; + } + + return clk_hz / 4; +} + +unsigned int cm_get_spi_controller_clk_hz(void) +{ + return cm_get_l4_noc_hz(CLKMGR_MAINPLL_NOCDIV_L4MPCLK_LSB); +} + +unsigned int cm_get_qspi_controller_clk_hz(void) +{ + return cm_get_l4_noc_hz(CLKMGR_MAINPLL_NOCDIV_L4MAINCLK_LSB); +} + +void cm_print_clock_quick_summary(void) +{ + printf("MPU %10ld kHz\n", cm_get_mpu_clk_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("SPI %8d kHz\n", cm_get_spi_controller_clk_hz() / 1000); + printf("EOSC1 %8d kHz\n", eosc1_hz / 1000); + printf("cb_intosc %8d kHz\n", cb_intosc_hz / 1000); + printf("f2s_free %8d kHz\n", f2s_free_hz / 1000); + printf("Main VCO %8d kHz\n", cm_get_main_vco_clk_hz() / 1000); + printf("NOC %8d kHz\n", cm_get_noc_clk_hz() / 1000); + printf("L4 Main %8d kHz\n", + cm_get_l4_noc_hz(CLKMGR_MAINPLL_NOCDIV_L4MAINCLK_LSB) / 1000); + printf("L4 MP %8d kHz\n", + cm_get_l4_noc_hz(CLKMGR_MAINPLL_NOCDIV_L4MPCLK_LSB) / 1000); + printf("L4 SP %8d kHz\n", cm_get_l4_sp_clk_hz() / 1000); + printf("L4 sys free %8d kHz\n", cm_l4_sys_free_clk_hz / 1000); +} diff --git a/arch/arm/mach-socfpga/clock_manager_gen5.c b/arch/arm/mach-socfpga/clock_manager_gen5.c new file mode 100644 index 0000000000..31fd51097a --- /dev/null +++ b/arch/arm/mach-socfpga/clock_manager_gen5.c @@ -0,0 +1,524 @@ +/* + * Copyright (C) 2013-2017 Altera Corporation <www.altera.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <asm/io.h> +#include <asm/arch/clock_manager.h> +#include <wait_bit.h> + +DECLARE_GLOBAL_DATA_PTR; + +static const struct socfpga_clock_manager *clock_manager_base = + (struct socfpga_clock_manager *)SOCFPGA_CLKMGR_ADDRESS; + +/* + * function to write the bypass register which requires a poll of the + * busy bit + */ +static void cm_write_bypass(u32 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(u32 val) +{ + writel(val, &clock_manager_base->ctrl); + cm_wait_for_fsm(); +} + +/* function to write a clock register that has phase information */ +static int cm_write_with_phase(u32 value, u32 reg_address, u32 mask) +{ + int ret; + + /* poll until phase is zero */ + ret = wait_for_bit(__func__, (const u32 *)reg_address, mask, + false, 20000, false); + if (ret) + return ret; + + writel(value, reg_address); + + return wait_for_bit(__func__, (const u32 *)reg_address, mask, + false, 20000, false); +} + +/* + * 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 + */ + +int cm_basic_init(const struct cm_config * const cfg) +{ + unsigned long end; + int ret; + + /* 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). + */ + end = timer_get_us() + 7; + + /* main mpu */ + writel(cfg->mpuclk, &clock_manager_base->main_pll.mpuclk); + + /* altera group mpuclk */ + writel(cfg->altera_grp_mpuclk, &clock_manager_base->altera.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 (timer_get_us() < end) + ; + + /* 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); + + 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 + */ + u32 mainvco = readl(&clock_manager_base->main_pll.vco); + + /* assert main outresetall */ + writel(mainvco | CLKMGR_MAINPLLGRP_VCO_OUTRESETALL_MASK, + &clock_manager_base->main_pll.vco); + + u32 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. + */ + ret = cm_write_with_phase(cfg->ddrdqsclk, + (u32)&clock_manager_base->sdr_pll.ddrdqsclk, + CLKMGR_SDRPLLGRP_DDRDQSCLK_PHASE_MASK); + if (ret) + return ret; + + /* SDRAM DDR2XDQSCLK */ + ret = cm_write_with_phase(cfg->ddr2xdqsclk, + (u32)&clock_manager_base->sdr_pll.ddr2xdqsclk, + CLKMGR_SDRPLLGRP_DDR2XDQSCLK_PHASE_MASK); + if (ret) + return ret; + + ret = cm_write_with_phase(cfg->ddrdqclk, + (u32)&clock_manager_base->sdr_pll.ddrdqclk, + CLKMGR_SDRPLLGRP_DDRDQCLK_PHASE_MASK); + if (ret) + return ret; + + ret = cm_write_with_phase(cfg->s2fuser2clk, + (u32)&clock_manager_base->sdr_pll.s2fuser2clk, + CLKMGR_SDRPLLGRP_S2FUSER2CLK_PHASE_MASK); + if (ret) + return ret; + + /* 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); + + return 0; +} + +static unsigned int cm_get_main_vco_clk_hz(void) +{ + u32 reg, clock; + + /* get the main VCO clock */ + reg = readl(&clock_manager_base->main_pll.vco); + clock = cm_get_osc_clk_hz(1); + 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) +{ + u32 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 = cm_get_osc_clk_hz(1); + else if (reg == CLKMGR_VCO_SSRC_EOSC2) + clock = cm_get_osc_clk_hz(2); + else if (reg == CLKMGR_VCO_SSRC_F2S) + clock = cm_get_f2s_per_ref_clk_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) +{ + u32 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) +{ + u32 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 = cm_get_osc_clk_hz(1); + else if (reg == CLKMGR_VCO_SSRC_EOSC2) + clock = cm_get_osc_clk_hz(2); + else if (reg == CLKMGR_VCO_SSRC_F2S) + clock = cm_get_f2s_sdr_ref_clk_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) +{ + u32 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) +{ + u32 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 = cm_get_f2s_per_ref_clk_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) +{ + u32 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 = cm_get_f2s_per_ref_clk_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) +{ + u32 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; +} + +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", cm_get_osc_clk_hz(1) / 1000); + printf("EOSC2 %8d kHz\n", cm_get_osc_clk_hz(2) / 1000); + printf("F2S_SDR_REF %8d kHz\n", cm_get_f2s_sdr_ref_clk_hz() / 1000); + printf("F2S_PER_REF %8d kHz\n", cm_get_f2s_per_ref_clk_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); +} diff --git a/arch/arm/mach-socfpga/include/mach/base_addr_a10.h b/arch/arm/mach-socfpga/include/mach/base_addr_a10.h index a7056d4da7..7818aa5c2d 100644 --- a/arch/arm/mach-socfpga/include/mach/base_addr_a10.h +++ b/arch/arm/mach-socfpga/include/mach/base_addr_a10.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2014 Altera Corporation <www.altera.com> + * Copyright (C) 2014-2017 Altera Corporation <www.altera.com> * * SPDX-License-Identifier: GPL-2.0+ */ @@ -29,17 +29,23 @@ #define SOCFPGA_MPUL2_ADDRESS 0xfffff000 #define SOCFPGA_I2C0_ADDRESS 0xffc02200 #define SOCFPGA_I2C1_ADDRESS 0xffc02300 +#define SOCFPGA_I2C2_ADDRESS 0xffc02400 +#define SOCFPGA_I2C3_ADDRESS 0xffc02500 +#define SOCFPGA_I2C4_ADDRESS 0xffc02600 #define SOCFPGA_ECC_OCRAM_ADDRESS 0xff8c3000 #define SOCFPGA_UART0_ADDRESS 0xffc02000 #define SOCFPGA_OSC1TIMER0_ADDRESS 0xffd00000 +#define SOCFPGA_OSC1TIMER1_ADDRESS 0xffd00100 #define SOCFPGA_CLKMGR_ADDRESS 0xffd04000 #define SOCFPGA_RSTMGR_ADDRESS 0xffd05000 #define SOCFPGA_SDR_ADDRESS 0xffcfb000 +#define SOCFPGA_NOC_L4_PRIV_FLT_OFST 0xffd11000 #define SOCFPGA_SDR_SCHEDULER_ADDRESS 0xffd12400 #define SOCFPGA_SDR_FIREWALL_OCRAM_ADDRESS 0xffd13200 #define SOCFPGA_SDR_FIREWALL_MPU_FPGA_ADDRESS 0xffd13300 #define SOCFPGA_SDR_FIREWALL_L3_ADDRESS 0xffd13400 +#define SOCFPGA_NOC_FW_H2F_SCR_OFST 0xffd13500 #endif /* _SOCFPGA_A10_BASE_HARDWARE_H_ */ diff --git a/arch/arm/mach-socfpga/include/mach/clock_manager.h b/arch/arm/mach-socfpga/include/mach/clock_manager.h index 803c926220..4c6b1f832b 100644 --- a/arch/arm/mach-socfpga/include/mach/clock_manager.h +++ b/arch/arm/mach-socfpga/include/mach/clock_manager.h @@ -1,317 +1,22 @@ /* - * Copyright (C) 2013 Altera Corporation <www.altera.com> + * Copyright (C) 2013-2017 Altera Corporation <www.altera.com> * * SPDX-License-Identifier: GPL-2.0+ */ -#ifndef _CLOCK_MANAGER_H_ -#define _CLOCK_MANAGER_H_ +#ifndef _CLOCK_MANAGER_H_ +#define _CLOCK_MANAGER_H_ #ifndef __ASSEMBLER__ -/* Clock speed accessors */ -unsigned long cm_get_mpu_clk_hz(void); -unsigned long cm_get_sdram_clk_hz(void); -unsigned int cm_get_l4_sp_clk_hz(void); -unsigned int cm_get_mmc_controller_clk_hz(void); -unsigned int cm_get_qspi_controller_clk_hz(void); -unsigned int cm_get_spi_controller_clk_hz(void); -const unsigned int cm_get_osc_clk_hz(const int osc); -const unsigned int cm_get_f2s_per_ref_clk_hz(void); -const unsigned int cm_get_f2s_sdr_ref_clk_hz(void); - -/* Clock configuration accessors */ -const struct cm_config * const cm_get_default_config(void); +void cm_wait_for_lock(u32 mask); +int cm_wait_for_fsm(void); +void cm_print_clock_quick_summary(void); #endif -struct cm_config { - /* main group */ - uint32_t main_vco_base; - uint32_t mpuclk; - uint32_t mainclk; - uint32_t dbgatclk; - uint32_t mainqspiclk; - uint32_t mainnandsdmmcclk; - uint32_t cfg2fuser0clk; - uint32_t maindiv; - uint32_t dbgdiv; - uint32_t tracediv; - uint32_t l4src; - - /* peripheral group */ - uint32_t peri_vco_base; - uint32_t emac0clk; - uint32_t emac1clk; - uint32_t perqspiclk; - uint32_t pernandsdmmcclk; - uint32_t perbaseclk; - uint32_t s2fuser1clk; - uint32_t perdiv; - uint32_t gpiodiv; - uint32_t persrc; - - /* sdram pll group */ - uint32_t sdram_vco_base; - uint32_t ddrdqsclk; - uint32_t ddr2xdqsclk; - uint32_t ddrdqclk; - uint32_t s2fuser2clk; - - /* altera group */ - uint32_t altera_grp_mpuclk; -}; - -void cm_basic_init(const struct cm_config * const cfg); - -struct socfpga_clock_manager_main_pll { - u32 vco; - u32 misc; - u32 mpuclk; - u32 mainclk; - u32 dbgatclk; - u32 mainqspiclk; - u32 mainnandsdmmcclk; - u32 cfgs2fuser0clk; - u32 en; - u32 maindiv; - u32 dbgdiv; - u32 tracediv; - u32 l4src; - u32 stat; - u32 _pad_0x38_0x40[2]; -}; - -struct socfpga_clock_manager_per_pll { - u32 vco; - u32 misc; - u32 emac0clk; - u32 emac1clk; - u32 perqspiclk; - u32 pernandsdmmcclk; - u32 perbaseclk; - u32 s2fuser1clk; - u32 en; - u32 div; - u32 gpiodiv; - u32 src; - u32 stat; - u32 _pad_0x34_0x40[3]; -}; - -struct socfpga_clock_manager_sdr_pll { - u32 vco; - u32 ctrl; - u32 ddrdqsclk; - u32 ddr2xdqsclk; - u32 ddrdqclk; - u32 s2fuser2clk; - u32 en; - u32 stat; -}; - -struct socfpga_clock_manager_altera { - u32 mpuclk; - u32 mainclk; -}; - -struct socfpga_clock_manager { - u32 ctrl; - u32 bypass; - u32 inter; - u32 intren; - u32 dbctrl; - u32 stat; - u32 _pad_0x18_0x3f[10]; - struct socfpga_clock_manager_main_pll main_pll; - struct socfpga_clock_manager_per_pll per_pll; - struct socfpga_clock_manager_sdr_pll sdr_pll; - struct socfpga_clock_manager_altera altera; - u32 _pad_0xe8_0x200[70]; -}; - -#define CLKMGR_CTRL_SAFEMODE (1 << 0) -#define CLKMGR_CTRL_SAFEMODE_OFFSET 0 - -#define CLKMGR_BYPASS_PERPLLSRC (1 << 4) -#define CLKMGR_BYPASS_PERPLLSRC_OFFSET 4 -#define CLKMGR_BYPASS_PERPLL (1 << 3) -#define CLKMGR_BYPASS_PERPLL_OFFSET 3 -#define CLKMGR_BYPASS_SDRPLLSRC (1 << 2) -#define CLKMGR_BYPASS_SDRPLLSRC_OFFSET 2 -#define CLKMGR_BYPASS_SDRPLL (1 << 1) -#define CLKMGR_BYPASS_SDRPLL_OFFSET 1 -#define CLKMGR_BYPASS_MAINPLL (1 << 0) -#define CLKMGR_BYPASS_MAINPLL_OFFSET 0 - -#define CLKMGR_INTER_SDRPLLLOCKED_MASK 0x00000100 -#define CLKMGR_INTER_PERPLLLOCKED_MASK 0x00000080 -#define CLKMGR_INTER_MAINPLLLOCKED_MASK 0x00000040 -#define CLKMGR_INTER_PERPLLLOST_MASK 0x00000010 -#define CLKMGR_INTER_SDRPLLLOST_MASK 0x00000020 -#define CLKMGR_INTER_MAINPLLLOST_MASK 0x00000008 - -#define CLKMGR_STAT_BUSY (1 << 0) - -/* Main PLL */ -#define CLKMGR_MAINPLLGRP_VCO_BGPWRDN (1 << 0) -#define CLKMGR_MAINPLLGRP_VCO_BGPWRDN_OFFSET 0 -#define CLKMGR_MAINPLLGRP_VCO_DENOM_OFFSET 16 -#define CLKMGR_MAINPLLGRP_VCO_DENOM_MASK 0x003f0000 -#define CLKMGR_MAINPLLGRP_VCO_EN (1 << 1) -#define CLKMGR_MAINPLLGRP_VCO_EN_OFFSET 1 -#define CLKMGR_MAINPLLGRP_VCO_NUMER_OFFSET 3 -#define CLKMGR_MAINPLLGRP_VCO_NUMER_MASK 0x0000fff8 -#define CLKMGR_MAINPLLGRP_VCO_OUTRESETALL_MASK 0x01000000 -#define CLKMGR_MAINPLLGRP_VCO_PWRDN (1 << 2) -#define CLKMGR_MAINPLLGRP_VCO_PWRDN_OFFSET 2 -#define CLKMGR_MAINPLLGRP_VCO_REGEXTSEL_MASK 0x80000000 -#define CLKMGR_MAINPLLGRP_VCO_RESET_VALUE 0x8001000d - -#define CLKMGR_MAINPLLGRP_MPUCLK_CNT_OFFSET 0 -#define CLKMGR_MAINPLLGRP_MPUCLK_CNT_MASK 0x000001ff - -#define CLKMGR_MAINPLLGRP_MAINCLK_CNT_OFFSET 0 -#define CLKMGR_MAINPLLGRP_MAINCLK_CNT_MASK 0x000001ff - -#define CLKMGR_MAINPLLGRP_DBGATCLK_CNT_OFFSET 0 -#define CLKMGR_MAINPLLGRP_DBGATCLK_CNT_MASK 0x000001ff - -#define CLKMGR_MAINPLLGRP_MAINQSPICLK_CNT_OFFSET 0 -#define CLKMGR_MAINPLLGRP_MAINQSPICLK_CNT_MASK 0x000001ff - -#define CLKMGR_MAINPLLGRP_MAINNANDSDMMCCLK_CNT_OFFSET 0 -#define CLKMGR_MAINPLLGRP_MAINNANDSDMMCCLK_CNT_MASK 0x000001ff - -#define CLKMGR_MAINPLLGRP_CFGS2FUSER0CLK_CNT_OFFSET 0 -#define CLKMGR_MAINPLLGRP_CFGS2FUSER0CLK_CNT_MASK 0x000001ff - -#define CLKMGR_MAINPLLGRP_EN_DBGATCLK_MASK 0x00000010 -#define CLKMGR_MAINPLLGRP_EN_DBGCLK_MASK 0x00000020 -#define CLKMGR_MAINPLLGRP_EN_DBGTIMERCLK_MASK 0x00000080 -#define CLKMGR_MAINPLLGRP_EN_DBGTRACECLK_MASK 0x00000040 -#define CLKMGR_MAINPLLGRP_EN_L4MPCLK_MASK 0x00000004 -#define CLKMGR_MAINPLLGRP_EN_S2FUSER0CLK_MASK 0x00000200 - -#define CLKMGR_MAINPLLGRP_MAINDIV_L3MPCLK_OFFSET 0 -#define CLKMGR_MAINPLLGRP_MAINDIV_L3MPCLK_MASK 0x00000003 -#define CLKMGR_MAINPLLGRP_MAINDIV_L3SPCLK_OFFSET 2 -#define CLKMGR_MAINPLLGRP_MAINDIV_L3SPCLK_MASK 0x0000000c -#define CLKMGR_MAINPLLGRP_MAINDIV_L4MPCLK_OFFSET 4 -#define CLKMGR_MAINPLLGRP_MAINDIV_L4MPCLK_MASK 0x00000070 -#define CLKMGR_MAINPLLGRP_MAINDIV_L4SPCLK_OFFSET 7 -#define CLKMGR_MAINPLLGRP_MAINDIV_L4SPCLK_MASK 0x00000380 - -#define CLKMGR_MAINPLLGRP_DBGDIV_DBGATCLK_OFFSET 0 -#define CLKMGR_MAINPLLGRP_DBGDIV_DBGATCLK_MASK 0x00000003 -#define CLKMGR_MAINPLLGRP_DBGDIV_DBGCLK_OFFSET 2 -#define CLKMGR_MAINPLLGRP_DBGDIV_DBGCLK_MASK 0x0000000c - -#define CLKMGR_MAINPLLGRP_TRACEDIV_TRACECLK_OFFSET 0 -#define CLKMGR_MAINPLLGRP_TRACEDIV_TRACECLK_MASK 0x00000007 - -#define CLKMGR_MAINPLLGRP_L4SRC_L4MP (1 << 0) -#define CLKMGR_MAINPLLGRP_L4SRC_L4MP_OFFSET 0 -#define CLKMGR_MAINPLLGRP_L4SRC_L4SP (1 << 1) -#define CLKMGR_MAINPLLGRP_L4SRC_L4SP_OFFSET 1 -#define CLKMGR_MAINPLLGRP_L4SRC_RESET_VALUE 0x00000000 -#define CLKMGR_L4_SP_CLK_SRC_MAINPLL 0x0 -#define CLKMGR_L4_SP_CLK_SRC_PERPLL 0x1 - -/* Per PLL */ -#define CLKMGR_PERPLLGRP_VCO_DENOM_OFFSET 16 -#define CLKMGR_PERPLLGRP_VCO_DENOM_MASK 0x003f0000 -#define CLKMGR_PERPLLGRP_VCO_NUMER_OFFSET 3 -#define CLKMGR_PERPLLGRP_VCO_NUMER_MASK 0x0000fff8 -#define CLKMGR_PERPLLGRP_VCO_OUTRESETALL_MASK 0x01000000 -#define CLKMGR_PERPLLGRP_VCO_PSRC_OFFSET 22 -#define CLKMGR_PERPLLGRP_VCO_PSRC_MASK 0x00c00000 -#define CLKMGR_PERPLLGRP_VCO_REGEXTSEL_MASK 0x80000000 -#define CLKMGR_PERPLLGRP_VCO_RESET_VALUE 0x8001000d -#define CLKMGR_PERPLLGRP_VCO_SSRC_OFFSET 22 -#define CLKMGR_PERPLLGRP_VCO_SSRC_MASK 0x00c00000 - -#define CLKMGR_VCO_SSRC_EOSC1 0x0 -#define CLKMGR_VCO_SSRC_EOSC2 0x1 -#define CLKMGR_VCO_SSRC_F2S 0x2 - -#define CLKMGR_PERPLLGRP_EMAC0CLK_CNT_OFFSET 0 -#define CLKMGR_PERPLLGRP_EMAC0CLK_CNT_MASK 0x000001ff - -#define CLKMGR_PERPLLGRP_EMAC1CLK_CNT_OFFSET 0 -#define CLKMGR_PERPLLGRP_EMAC1CLK_CNT_MASK 0x000001ff - -#define CLKMGR_PERPLLGRP_PERQSPICLK_CNT_OFFSET 0 -#define CLKMGR_PERPLLGRP_PERQSPICLK_CNT_MASK 0x000001ff - -#define CLKMGR_PERPLLGRP_PERNANDSDMMCCLK_CNT_OFFSET 0 -#define CLKMGR_PERPLLGRP_PERNANDSDMMCCLK_CNT_MASK 0x000001ff - -#define CLKMGR_PERPLLGRP_PERBASECLK_CNT_OFFSET 0 -#define CLKMGR_PERPLLGRP_PERBASECLK_CNT_MASK 0x000001ff - -#define CLKMGR_PERPLLGRP_S2FUSER1CLK_CNT_OFFSET 0 -#define CLKMGR_PERPLLGRP_S2FUSER1CLK_CNT_MASK 0x000001ff - -#define CLKMGR_PERPLLGRP_EN_NANDCLK_MASK 0x00000400 -#define CLKMGR_PERPLLGRP_EN_SDMMCCLK_MASK 0x00000100 - -#define CLKMGR_PERPLLGRP_DIV_CAN0CLK_OFFSET 6 -#define CLKMGR_PERPLLGRP_DIV_CAN0CLK_MASK 0x000001c0 -#define CLKMGR_PERPLLGRP_DIV_CAN1CLK_OFFSET 9 -#define CLKMGR_PERPLLGRP_DIV_CAN1CLK_MASK 0x00000e00 -#define CLKMGR_PERPLLGRP_DIV_SPIMCLK_OFFSET 3 -#define CLKMGR_PERPLLGRP_DIV_SPIMCLK_OFFSET 3 -#define CLKMGR_PERPLLGRP_DIV_USBCLK_OFFSET 0 -#define CLKMGR_PERPLLGRP_DIV_USBCLK_MASK 0x00000007 - -#define CLKMGR_PERPLLGRP_GPIODIV_GPIODBCLK_OFFSET 0 -#define CLKMGR_PERPLLGRP_GPIODIV_GPIODBCLK_MASK 0x00ffffff - -#define CLKMGR_PERPLLGRP_SRC_NAND_OFFSET 2 -#define CLKMGR_PERPLLGRP_SRC_NAND_MASK 0x0000000c -#define CLKMGR_PERPLLGRP_SRC_QSPI_OFFSET 4 -#define CLKMGR_PERPLLGRP_SRC_QSPI_MASK 0x00000030 -#define CLKMGR_PERPLLGRP_SRC_RESET_VALUE 0x00000015 -#define CLKMGR_PERPLLGRP_SRC_SDMMC_OFFSET 0 -#define CLKMGR_PERPLLGRP_SRC_SDMMC_MASK 0x00000003 -#define CLKMGR_SDMMC_CLK_SRC_F2S 0x0 -#define CLKMGR_SDMMC_CLK_SRC_MAIN 0x1 -#define CLKMGR_SDMMC_CLK_SRC_PER 0x2 -#define CLKMGR_QSPI_CLK_SRC_F2S 0x0 -#define CLKMGR_QSPI_CLK_SRC_MAIN 0x1 -#define CLKMGR_QSPI_CLK_SRC_PER 0x2 - -/* SDR PLL */ -#define CLKMGR_SDRPLLGRP_VCO_DENOM_OFFSET 16 -#define CLKMGR_SDRPLLGRP_VCO_DENOM_MASK 0x003f0000 -#define CLKMGR_SDRPLLGRP_VCO_NUMER_OFFSET 3 -#define CLKMGR_SDRPLLGRP_VCO_NUMER_MASK 0x0000fff8 -#define CLKMGR_SDRPLLGRP_VCO_OUTRESETALL (1 << 24) -#define CLKMGR_SDRPLLGRP_VCO_OUTRESETALL_OFFSET 24 -#define CLKMGR_SDRPLLGRP_VCO_OUTRESET_OFFSET 25 -#define CLKMGR_SDRPLLGRP_VCO_OUTRESET_MASK 0x7e000000 -#define CLKMGR_SDRPLLGRP_VCO_REGEXTSEL_MASK 0x80000000 -#define CLKMGR_SDRPLLGRP_VCO_RESET_VALUE 0x8001000d -#define CLKMGR_SDRPLLGRP_VCO_SSRC_OFFSET 22 -#define CLKMGR_SDRPLLGRP_VCO_SSRC_MASK 0x00c00000 - -#define CLKMGR_SDRPLLGRP_DDRDQSCLK_CNT_OFFSET 0 -#define CLKMGR_SDRPLLGRP_DDRDQSCLK_CNT_MASK 0x000001ff -#define CLKMGR_SDRPLLGRP_DDRDQSCLK_PHASE_OFFSET 9 -#define CLKMGR_SDRPLLGRP_DDRDQSCLK_PHASE_MASK 0x00000e00 - -#define CLKMGR_SDRPLLGRP_DDR2XDQSCLK_CNT_OFFSET 0 -#define CLKMGR_SDRPLLGRP_DDR2XDQSCLK_CNT_MASK 0x000001ff -#define CLKMGR_SDRPLLGRP_DDR2XDQSCLK_PHASE_OFFSET 9 -#define CLKMGR_SDRPLLGRP_DDR2XDQSCLK_PHASE_MASK 0x00000e00 - -#define CLKMGR_SDRPLLGRP_DDRDQCLK_CNT_OFFSET 0 -#define CLKMGR_SDRPLLGRP_DDRDQCLK_CNT_MASK 0x000001ff -#define CLKMGR_SDRPLLGRP_DDRDQCLK_PHASE_OFFSET 9 -#define CLKMGR_SDRPLLGRP_DDRDQCLK_PHASE_MASK 0x00000e00 - -#define CLKMGR_SDRPLLGRP_S2FUSER2CLK_CNT_OFFSET 0 -#define CLKMGR_SDRPLLGRP_S2FUSER2CLK_CNT_MASK 0x000001ff -#define CLKMGR_SDRPLLGRP_S2FUSER2CLK_PHASE_OFFSET 9 -#define CLKMGR_SDRPLLGRP_S2FUSER2CLK_PHASE_MASK 0x00000e00 +#if defined(CONFIG_TARGET_SOCFPGA_GEN5) +#include <asm/arch/clock_manager_gen5.h> +#elif defined(CONFIG_TARGET_SOCFPGA_ARRIA10) +#include <asm/arch/clock_manager_arria10.h> +#endif #endif /* _CLOCK_MANAGER_H_ */ diff --git a/arch/arm/mach-socfpga/include/mach/clock_manager_arria10.h b/arch/arm/mach-socfpga/include/mach/clock_manager_arria10.h new file mode 100644 index 0000000000..1b55bb8ecf --- /dev/null +++ b/arch/arm/mach-socfpga/include/mach/clock_manager_arria10.h @@ -0,0 +1,224 @@ +/* + * Copyright (C) 2016-2017 Intel Corporation + * + * SPDX-License-Identifier: GPL-2.0 + */ + +#ifndef CLOCK_MANAGER_ARRIA10 +#define CLOCK_MANAGER_ARRIA10 + +#ifndef __ASSEMBLER__ + +struct socfpga_clock_manager_main_pll { + u32 vco0; + u32 vco1; + u32 en; + u32 ens; + u32 enr; + u32 bypass; + u32 bypasss; + u32 bypassr; + u32 mpuclk; + u32 nocclk; + u32 cntr2clk; + u32 cntr3clk; + u32 cntr4clk; + u32 cntr5clk; + u32 cntr6clk; + u32 cntr7clk; + u32 cntr8clk; + u32 cntr9clk; + u32 pad_0x48_0x5b[5]; + u32 cntr15clk; + u32 outrst; + u32 outrststat; + u32 nocdiv; + u32 pad_0x6c_0x80[5]; +}; + +struct socfpga_clock_manager_per_pll { + u32 vco0; + u32 vco1; + u32 en; + u32 ens; + u32 enr; + u32 bypass; + u32 bypasss; + u32 bypassr; + u32 pad_0x20_0x27[2]; + u32 cntr2clk; + u32 cntr3clk; + u32 cntr4clk; + u32 cntr5clk; + u32 cntr6clk; + u32 cntr7clk; + u32 cntr8clk; + u32 cntr9clk; + u32 pad_0x48_0x5f[6]; + u32 outrst; + u32 outrststat; + u32 emacctl; + u32 gpiodiv; + u32 pad_0x70_0x80[4]; +}; + +struct socfpga_clock_manager_altera { + u32 mpuclk; + u32 nocclk; + u32 mainmisc0; + u32 mainmisc1; + u32 perimisc0; + u32 perimisc1; +}; + +struct socfpga_clock_manager { + /* clkmgr */ + u32 ctrl; + u32 intr; + u32 intrs; + u32 intrr; + u32 intren; + u32 intrens; + u32 intrenr; + u32 stat; + u32 testioctrl; + u32 _pad_0x24_0x40[7]; + /* mainpllgrp */ + struct socfpga_clock_manager_main_pll main_pll; + /* perpllgrp */ + struct socfpga_clock_manager_per_pll per_pll; + struct socfpga_clock_manager_altera altera; +}; + +void cm_use_intosc(void); +unsigned int cm_get_noc_clk_hz(void); +unsigned int cm_get_l4_noc_hz(unsigned int nocdivshift); +int cm_basic_init(const void *blob); + +unsigned int cm_get_l4_sp_clk_hz(void); +unsigned int cm_get_main_vco_clk_hz(void); +unsigned int cm_get_per_vco_clk_hz(void); +unsigned long cm_get_mpu_clk_hz(void); + +unsigned int cm_get_qspi_controller_clk_hz(void); +unsigned int cm_get_mmc_controller_clk_hz(void); +unsigned int cm_get_spi_controller_clk_hz(void); + +#endif /* __ASSEMBLER__ */ + +#define CLKMGR_ALTERAGRP_MPU_CLK_OFFSET 0x140 +#define CLKMGR_MAINPLL_NOC_CLK_OFFSET 0x144 +#define LOCKED_MASK (CLKMGR_CLKMGR_STAT_MAINPLLLOCKED_SET_MSK | \ + CLKMGR_CLKMGR_STAT_PERPLLLOCKED_SET_MSK) + +/* value */ +#define CLKMGR_MAINPLL_BYPASS_RESET 0x0000003f +#define CLKMGR_PERPLL_BYPASS_RESET 0x000000ff +#define CLKMGR_MAINPLL_VCO0_RESET 0x00010053 +#define CLKMGR_MAINPLL_VCO1_RESET 0x00010001 +#define CLKMGR_PERPLL_VCO0_RESET 0x00010053 +#define CLKMGR_PERPLL_VCO1_RESET 0x00010001 +#define CLKMGR_MAINPLL_VCO0_PSRC_EOSC 0x0 +#define CLKMGR_MAINPLL_VCO0_PSRC_E_INTOSC 0x1 +#define CLKMGR_MAINPLL_VCO0_PSRC_F2S 0x2 +#define CLKMGR_PERPLL_VCO0_PSRC_EOSC 0x0 +#define CLKMGR_PERPLL_VCO0_PSRC_E_INTOSC 0x1 +#define CLKMGR_PERPLL_VCO0_PSRC_F2S 0x2 +#define CLKMGR_PERPLL_VCO0_PSRC_MAIN 0x3 + +/* mask */ +#define CLKMGR_MAINPLL_EN_S2FUSER0CLKEN_SET_MSK BIT(6) +#define CLKMGR_MAINPLL_EN_HMCPLLREFCLKEN_SET_MSK BIT(7) +#define CLKMGR_CLKMGR_STAT_MAINPLLLOCKED_SET_MSK BIT(8) +#define CLKMGR_CLKMGR_STAT_PERPLLLOCKED_SET_MSK BIT(9) +#define CLKMGR_CLKMGR_STAT_BOOTCLKSRC_SET_MSK BIT(17) +#define CLKMGR_MAINPLL_VCO0_BGPWRDN_SET_MSK BIT(0) +#define CLKMGR_MAINPLL_VCO0_PWRDN_SET_MSK BIT(1) +#define CLKMGR_MAINPLL_VCO0_EN_SET_MSK BIT(2) +#define CLKMGR_MAINPLL_VCO0_OUTRSTALL_SET_MSK BIT(3) +#define CLKMGR_MAINPLL_VCO0_REGEXTSEL_SET_MSK BIT(4) +#define CLKMGR_PERPLL_VCO0_BGPWRDN_SET_MSK BIT(0) +#define CLKMGR_PERPLL_VCO0_PWRDN_SET_MSK BIT(1) +#define CLKMGR_PERPLL_VCO0_EN_SET_MSK BIT(2) +#define CLKMGR_PERPLL_VCO0_OUTRSTALL_SET_MSK BIT(3) +#define CLKMGR_PERPLL_VCO0_REGEXTSEL_SET_MSK BIT(4) +#define CLKMGR_CLKMGR_INTR_MAINPLLACHIEVED_SET_MSK BIT(0) +#define CLKMGR_CLKMGR_INTR_PERPLLACHIEVED_SET_MSK BIT(1) +#define CLKMGR_CLKMGR_INTR_MAINPLLLOST_SET_MSK BIT(2) +#define CLKMGR_CLKMGR_INTR_PERPLLLOST_SET_MSK BIT(3) +#define CLKMGR_CLKMGR_INTR_MAINPLLRFSLIP_SET_MSK BIT(8) +#define CLKMGR_CLKMGR_INTR_PERPLLRFSLIP_SET_MSK BIT(9) +#define CLKMGR_CLKMGR_INTR_MAINPLLFBSLIP_SET_MSK BIT(10) +#define CLKMGR_CLKMGR_INTR_PERPLLFBSLIP_SET_MSK BIT(11) +#define CLKMGR_CLKMGR_CTL_BOOTMOD_SET_MSK BIT(0) +#define CLKMGR_CLKMGR_CTL_BOOTCLK_INTOSC_SET_MSK 0x00000300 +#define CLKMGR_PERPLL_EN_RESET 0x00000f7f +#define CLKMGR_PERPLLGRP_EN_SDMMCCLK_MASK BIT(5) +#define CLKMGR_MAINPLL_VCO0_PSRC_MSK 0x00000003 +#define CLKMGR_MAINPLL_VCO1_NUMER_MSK 0x00001fff +#define CLKMGR_MAINPLL_VCO1_DENOM_MSK 0x0000003f +#define CLKMGR_MAINPLL_CNTRCLK_MSK 0x000003ff +#define CLKMGR_PERPLL_VCO0_PSRC_MSK 0x00000003 +#define CLKMGR_PERPLL_VCO1_NUMER_MSK 0x00001fff +#define CLKMGR_PERPLL_VCO1_DENOM_MSK 0x0000003f +#define CLKMGR_PERPLL_CNTRCLK_MSK 0x000003ff +#define CLKMGR_MAINPLL_MPUCLK_SRC_MSK 0x00000007 +#define CLKMGR_MAINPLL_MPUCLK_CNT_MSK 0x000003ff +#define CLKMGR_MAINPLL_MPUCLK_SRC_MAIN 0 +#define CLKMGR_MAINPLL_MPUCLK_SRC_PERI 1 +#define CLKMGR_MAINPLL_MPUCLK_SRC_OSC1 2 +#define CLKMGR_MAINPLL_MPUCLK_SRC_INTOSC 3 +#define CLKMGR_MAINPLL_MPUCLK_SRC_FPGA 4 +#define CLKMGR_MAINPLL_NOCDIV_MSK 0x00000003 +#define CLKMGR_MAINPLL_NOCCLK_CNT_MSK 0x000003ff +#define CLKMGR_MAINPLL_NOCCLK_SRC_MSK 0x00000007 +#define CLKMGR_MAINPLL_NOCCLK_SRC_MAIN 0 +#define CLKMGR_MAINPLL_NOCCLK_SRC_PERI 1 +#define CLKMGR_MAINPLL_NOCCLK_SRC_OSC1 2 +#define CLKMGR_MAINPLL_NOCCLK_SRC_INTOSC 3 +#define CLKMGR_MAINPLL_NOCCLK_SRC_FPGA 4 + +#define CLKMGR_PERPLLGRP_SRC_MSK 0x00000007 +#define CLKMGR_PERPLLGRP_SRC_MAIN 0 +#define CLKMGR_PERPLLGRP_SRC_PERI 1 +#define CLKMGR_PERPLLGRP_SRC_OSC1 2 +#define CLKMGR_PERPLLGRP_SRC_INTOSC 3 +#define CLKMGR_PERPLLGRP_SRC_FPGA 4 + +/* bit shifting macro */ +#define CLKMGR_MAINPLL_VCO0_PSRC_LSB 8 +#define CLKMGR_PERPLL_VCO0_PSRC_LSB 8 +#define CLKMGR_MAINPLL_VCO1_DENOM_LSB 16 +#define CLKMGR_PERPLL_VCO1_DENOM_LSB 16 +#define CLKMGR_MAINPLL_NOCCLK_PERICNT_LSB 16 +#define CLKMGR_MAINPLL_NOCCLK_SRC_LSB 16 +#define CLKMGR_MAINPLL_NOCDIV_L4MAINCLK_LSB 0 +#define CLKMGR_MAINPLL_NOCDIV_L4MPCLK_LSB 8 +#define CLKMGR_MAINPLL_NOCDIV_L4SPCLK_LSB 16 +#define CLKMGR_MAINPLL_NOCDIV_CSATCLK_LSB 24 +#define CLKMGR_MAINPLL_NOCDIV_CSTRACECLK_LSB 26 +#define CLKMGR_MAINPLL_NOCDIV_CSPDBGCLK_LSB 28 +#define CLKMGR_MAINPLL_MPUCLK_SRC_LSB 16 +#define CLKMGR_MAINPLL_MPUCLK_PERICNT_LSB 16 +#define CLKMGR_MAINPLL_NOCCLK_SRC_LSB 16 +#define CLKMGR_MAINPLL_CNTR7CLK_SRC_LSB 16 +#define CLKMGR_MAINPLL_CNTR9CLK_SRC_LSB 16 +#define CLKMGR_PERPLL_CNTR2CLK_SRC_LSB 16 +#define CLKMGR_PERPLL_CNTR3CLK_SRC_LSB 16 +#define CLKMGR_PERPLL_CNTR4CLK_SRC_LSB 16 +#define CLKMGR_PERPLL_CNTR5CLK_SRC_LSB 16 +#define CLKMGR_PERPLL_CNTR6CLK_SRC_LSB 16 +#define CLKMGR_PERPLL_CNTR8CLK_SRC_LSB 16 +#define CLKMGR_PERPLL_EMACCTL_EMAC0SEL_LSB 26 +#define CLKMGR_PERPLL_EMACCTL_EMAC1SEL_LSB 27 +#define CLKMGR_PERPLL_EMACCTL_EMAC2SEL_LSB 28 + +/* PLL ramping work around */ +#define CLKMGR_PLL_RAMP_MPUCLK_THRESHOLD_HZ 900000000 +#define CLKMGR_PLL_RAMP_NOCCLK_THRESHOLD_HZ 300000000 +#define CLKMGR_PLL_RAMP_MPUCLK_INCREMENT_HZ 100000000 +#define CLKMGR_PLL_RAMP_NOCCLK_INCREMENT_HZ 33000000 + +#define CLKMGR_STAT_BUSY BIT(0) + +#endif /* CLOCK_MANAGER_ARRIA10 */ diff --git a/arch/arm/mach-socfpga/include/mach/clock_manager_gen5.h b/arch/arm/mach-socfpga/include/mach/clock_manager_gen5.h new file mode 100644 index 0000000000..9227dfb09a --- /dev/null +++ b/arch/arm/mach-socfpga/include/mach/clock_manager_gen5.h @@ -0,0 +1,322 @@ +/* + * Copyright (C) 2013-2017 Altera Corporation <www.altera.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef _CLOCK_MANAGER_GEN5_H_ +#define _CLOCK_MANAGER_GEN5_H_ + +#ifndef __ASSEMBLER__ + +struct cm_config { + /* main group */ + u32 main_vco_base; + u32 mpuclk; + u32 mainclk; + u32 dbgatclk; + u32 mainqspiclk; + u32 mainnandsdmmcclk; + u32 cfg2fuser0clk; + u32 maindiv; + u32 dbgdiv; + u32 tracediv; + u32 l4src; + + /* peripheral group */ + u32 peri_vco_base; + u32 emac0clk; + u32 emac1clk; + u32 perqspiclk; + u32 pernandsdmmcclk; + u32 perbaseclk; + u32 s2fuser1clk; + u32 perdiv; + u32 gpiodiv; + u32 persrc; + + /* sdram pll group */ + u32 sdram_vco_base; + u32 ddrdqsclk; + u32 ddr2xdqsclk; + u32 ddrdqclk; + u32 s2fuser2clk; + + /* altera group */ + u32 altera_grp_mpuclk; +}; + +struct socfpga_clock_manager_main_pll { + u32 vco; + u32 misc; + u32 mpuclk; + u32 mainclk; + u32 dbgatclk; + u32 mainqspiclk; + u32 mainnandsdmmcclk; + u32 cfgs2fuser0clk; + u32 en; + u32 maindiv; + u32 dbgdiv; + u32 tracediv; + u32 l4src; + u32 stat; + u32 _pad_0x38_0x40[2]; +}; + +struct socfpga_clock_manager_per_pll { + u32 vco; + u32 misc; + u32 emac0clk; + u32 emac1clk; + u32 perqspiclk; + u32 pernandsdmmcclk; + u32 perbaseclk; + u32 s2fuser1clk; + u32 en; + u32 div; + u32 gpiodiv; + u32 src; + u32 stat; + u32 _pad_0x34_0x40[3]; +}; + +struct socfpga_clock_manager_sdr_pll { + u32 vco; + u32 ctrl; + u32 ddrdqsclk; + u32 ddr2xdqsclk; + u32 ddrdqclk; + u32 s2fuser2clk; + u32 en; + u32 stat; +}; + +struct socfpga_clock_manager_altera { + u32 mpuclk; + u32 mainclk; +}; + +struct socfpga_clock_manager { + u32 ctrl; + u32 bypass; + u32 inter; + u32 intren; + u32 dbctrl; + u32 stat; + u32 _pad_0x18_0x3f[10]; + struct socfpga_clock_manager_main_pll main_pll; + struct socfpga_clock_manager_per_pll per_pll; + struct socfpga_clock_manager_sdr_pll sdr_pll; + struct socfpga_clock_manager_altera altera; + u32 _pad_0xe8_0x200[70]; +}; + +/* Clock speed accessors */ +unsigned long cm_get_mpu_clk_hz(void); +unsigned long cm_get_sdram_clk_hz(void); +unsigned int cm_get_l4_sp_clk_hz(void); +unsigned int cm_get_mmc_controller_clk_hz(void); +unsigned int cm_get_qspi_controller_clk_hz(void); +unsigned int cm_get_spi_controller_clk_hz(void); +const unsigned int cm_get_osc_clk_hz(const int osc); +const unsigned int cm_get_f2s_per_ref_clk_hz(void); +const unsigned int cm_get_f2s_sdr_ref_clk_hz(void); + +/* Clock configuration accessors */ +int cm_basic_init(const struct cm_config * const cfg); +const struct cm_config * const cm_get_default_config(void); +#endif /* __ASSEMBLER__ */ + +#define LOCKED_MASK \ + (CLKMGR_INTER_SDRPLLLOCKED_MASK | \ + CLKMGR_INTER_PERPLLLOCKED_MASK | \ + CLKMGR_INTER_MAINPLLLOCKED_MASK) + +#define CLKMGR_CTRL_SAFEMODE BIT(0) +#define CLKMGR_CTRL_SAFEMODE_OFFSET 0 + +#define CLKMGR_BYPASS_PERPLLSRC BIT(4) +#define CLKMGR_BYPASS_PERPLLSRC_OFFSET 4 +#define CLKMGR_BYPASS_PERPLL BIT(3) +#define CLKMGR_BYPASS_PERPLL_OFFSET 3 +#define CLKMGR_BYPASS_SDRPLLSRC BIT(2) +#define CLKMGR_BYPASS_SDRPLLSRC_OFFSET 2 +#define CLKMGR_BYPASS_SDRPLL BIT(1) +#define CLKMGR_BYPASS_SDRPLL_OFFSET 1 +#define CLKMGR_BYPASS_MAINPLL BIT(0) +#define CLKMGR_BYPASS_MAINPLL_OFFSET 0 + +#define CLKMGR_INTER_MAINPLLLOST_MASK BIT(3) +#define CLKMGR_INTER_PERPLLLOST_MASK BIT(4) +#define CLKMGR_INTER_SDRPLLLOST_MASK BIT(5) +#define CLKMGR_INTER_MAINPLLLOCKED_MASK BIT(6) +#define CLKMGR_INTER_PERPLLLOCKED_MASK BIT(7) +#define CLKMGR_INTER_SDRPLLLOCKED_MASK BIT(8) + +#define CLKMGR_STAT_BUSY BIT(0) + +/* Main PLL */ +#define CLKMGR_MAINPLLGRP_VCO_BGPWRDN BIT(0) +#define CLKMGR_MAINPLLGRP_VCO_BGPWRDN_OFFSET 0 +#define CLKMGR_MAINPLLGRP_VCO_DENOM_OFFSET 16 +#define CLKMGR_MAINPLLGRP_VCO_DENOM_MASK 0x003f0000 +#define CLKMGR_MAINPLLGRP_VCO_EN BIT(1) +#define CLKMGR_MAINPLLGRP_VCO_EN_OFFSET 1 +#define CLKMGR_MAINPLLGRP_VCO_NUMER_OFFSET 3 +#define CLKMGR_MAINPLLGRP_VCO_NUMER_MASK 0x0000fff8 +#define CLKMGR_MAINPLLGRP_VCO_OUTRESETALL_MASK 0x01000000 +#define CLKMGR_MAINPLLGRP_VCO_PWRDN BIT(2) +#define CLKMGR_MAINPLLGRP_VCO_PWRDN_OFFSET 2 +#define CLKMGR_MAINPLLGRP_VCO_REGEXTSEL_MASK 0x80000000 +#define CLKMGR_MAINPLLGRP_VCO_RESET_VALUE 0x8001000d + +#define CLKMGR_MAINPLLGRP_MPUCLK_CNT_OFFSET 0 +#define CLKMGR_MAINPLLGRP_MPUCLK_CNT_MASK 0x000001ff + +#define CLKMGR_MAINPLLGRP_MAINCLK_CNT_OFFSET 0 +#define CLKMGR_MAINPLLGRP_MAINCLK_CNT_MASK 0x000001ff + +#define CLKMGR_MAINPLLGRP_DBGATCLK_CNT_OFFSET 0 +#define CLKMGR_MAINPLLGRP_DBGATCLK_CNT_MASK 0x000001ff + +#define CLKMGR_MAINPLLGRP_MAINQSPICLK_CNT_OFFSET 0 +#define CLKMGR_MAINPLLGRP_MAINQSPICLK_CNT_MASK 0x000001ff + +#define CLKMGR_MAINPLLGRP_MAINNANDSDMMCCLK_CNT_OFFSET 0 +#define CLKMGR_MAINPLLGRP_MAINNANDSDMMCCLK_CNT_MASK 0x000001ff + +#define CLKMGR_MAINPLLGRP_CFGS2FUSER0CLK_CNT_OFFSET 0 +#define CLKMGR_MAINPLLGRP_CFGS2FUSER0CLK_CNT_MASK 0x000001ff + +#define CLKMGR_MAINPLLGRP_EN_L4MPCLK_MASK BIT(2) +#define CLKMGR_MAINPLLGRP_EN_DBGATCLK_MASK BIT(4) +#define CLKMGR_MAINPLLGRP_EN_DBGCLK_MASK BIT(5) +#define CLKMGR_MAINPLLGRP_EN_DBGTRACECLK_MASK BIT(6) +#define CLKMGR_MAINPLLGRP_EN_DBGTIMERCLK_MASK BIT(7) +#define CLKMGR_MAINPLLGRP_EN_S2FUSER0CLK_MASK BIT(9) + +#define CLKMGR_MAINPLLGRP_MAINDIV_L3MPCLK_OFFSET 0 +#define CLKMGR_MAINPLLGRP_MAINDIV_L3MPCLK_MASK 0x00000003 +#define CLKMGR_MAINPLLGRP_MAINDIV_L3SPCLK_OFFSET 2 +#define CLKMGR_MAINPLLGRP_MAINDIV_L3SPCLK_MASK 0x0000000c +#define CLKMGR_MAINPLLGRP_MAINDIV_L4MPCLK_OFFSET 4 +#define CLKMGR_MAINPLLGRP_MAINDIV_L4MPCLK_MASK 0x00000070 +#define CLKMGR_MAINPLLGRP_MAINDIV_L4SPCLK_OFFSET 7 +#define CLKMGR_MAINPLLGRP_MAINDIV_L4SPCLK_MASK 0x00000380 + +#define CLKMGR_MAINPLLGRP_DBGDIV_DBGATCLK_OFFSET 0 +#define CLKMGR_MAINPLLGRP_DBGDIV_DBGATCLK_MASK 0x00000003 +#define CLKMGR_MAINPLLGRP_DBGDIV_DBGCLK_OFFSET 2 +#define CLKMGR_MAINPLLGRP_DBGDIV_DBGCLK_MASK 0x0000000c + +#define CLKMGR_MAINPLLGRP_TRACEDIV_TRACECLK_OFFSET 0 +#define CLKMGR_MAINPLLGRP_TRACEDIV_TRACECLK_MASK 0x00000007 + +#define CLKMGR_MAINPLLGRP_L4SRC_L4MP BIT(0) +#define CLKMGR_MAINPLLGRP_L4SRC_L4MP_OFFSET 0 +#define CLKMGR_MAINPLLGRP_L4SRC_L4SP BIT(1) +#define CLKMGR_MAINPLLGRP_L4SRC_L4SP_OFFSET 1 +#define CLKMGR_MAINPLLGRP_L4SRC_RESET_VALUE 0x00000000 +#define CLKMGR_L4_SP_CLK_SRC_MAINPLL 0x0 +#define CLKMGR_L4_SP_CLK_SRC_PERPLL 0x1 + +/* Per PLL */ +#define CLKMGR_PERPLLGRP_VCO_DENOM_OFFSET 16 +#define CLKMGR_PERPLLGRP_VCO_DENOM_MASK 0x003f0000 +#define CLKMGR_PERPLLGRP_VCO_NUMER_OFFSET 3 +#define CLKMGR_PERPLLGRP_VCO_NUMER_MASK 0x0000fff8 +#define CLKMGR_PERPLLGRP_VCO_OUTRESETALL_MASK 0x01000000 +#define CLKMGR_PERPLLGRP_VCO_PSRC_OFFSET 22 +#define CLKMGR_PERPLLGRP_VCO_PSRC_MASK 0x00c00000 +#define CLKMGR_PERPLLGRP_VCO_REGEXTSEL_MASK 0x80000000 +#define CLKMGR_PERPLLGRP_VCO_RESET_VALUE 0x8001000d +#define CLKMGR_PERPLLGRP_VCO_SSRC_OFFSET 22 +#define CLKMGR_PERPLLGRP_VCO_SSRC_MASK 0x00c00000 + +#define CLKMGR_VCO_SSRC_EOSC1 0x0 +#define CLKMGR_VCO_SSRC_EOSC2 0x1 +#define CLKMGR_VCO_SSRC_F2S 0x2 + +#define CLKMGR_PERPLLGRP_EMAC0CLK_CNT_OFFSET 0 +#define CLKMGR_PERPLLGRP_EMAC0CLK_CNT_MASK 0x000001ff + +#define CLKMGR_PERPLLGRP_EMAC1CLK_CNT_OFFSET 0 +#define CLKMGR_PERPLLGRP_EMAC1CLK_CNT_MASK 0x000001ff + +#define CLKMGR_PERPLLGRP_PERQSPICLK_CNT_OFFSET 0 +#define CLKMGR_PERPLLGRP_PERQSPICLK_CNT_MASK 0x000001ff + +#define CLKMGR_PERPLLGRP_PERNANDSDMMCCLK_CNT_OFFSET 0 +#define CLKMGR_PERPLLGRP_PERNANDSDMMCCLK_CNT_MASK 0x000001ff + +#define CLKMGR_PERPLLGRP_PERBASECLK_CNT_OFFSET 0 +#define CLKMGR_PERPLLGRP_PERBASECLK_CNT_MASK 0x000001ff + +#define CLKMGR_PERPLLGRP_S2FUSER1CLK_CNT_OFFSET 0 +#define CLKMGR_PERPLLGRP_S2FUSER1CLK_CNT_MASK 0x000001ff + +#define CLKMGR_PERPLLGRP_EN_NANDCLK_MASK 0x00000400 +#define CLKMGR_PERPLLGRP_EN_SDMMCCLK_MASK 0x00000100 + +#define CLKMGR_PERPLLGRP_DIV_CAN0CLK_OFFSET 6 +#define CLKMGR_PERPLLGRP_DIV_CAN0CLK_MASK 0x000001c0 +#define CLKMGR_PERPLLGRP_DIV_CAN1CLK_OFFSET 9 +#define CLKMGR_PERPLLGRP_DIV_CAN1CLK_MASK 0x00000e00 +#define CLKMGR_PERPLLGRP_DIV_SPIMCLK_OFFSET 3 +#define CLKMGR_PERPLLGRP_DIV_SPIMCLK_OFFSET 3 +#define CLKMGR_PERPLLGRP_DIV_USBCLK_OFFSET 0 +#define CLKMGR_PERPLLGRP_DIV_USBCLK_MASK 0x00000007 + +#define CLKMGR_PERPLLGRP_GPIODIV_GPIODBCLK_OFFSET 0 +#define CLKMGR_PERPLLGRP_GPIODIV_GPIODBCLK_MASK 0x00ffffff + +#define CLKMGR_PERPLLGRP_SRC_NAND_OFFSET 2 +#define CLKMGR_PERPLLGRP_SRC_NAND_MASK 0x0000000c +#define CLKMGR_PERPLLGRP_SRC_QSPI_OFFSET 4 +#define CLKMGR_PERPLLGRP_SRC_QSPI_MASK 0x00000030 +#define CLKMGR_PERPLLGRP_SRC_RESET_VALUE 0x00000015 +#define CLKMGR_PERPLLGRP_SRC_SDMMC_OFFSET 0 +#define CLKMGR_PERPLLGRP_SRC_SDMMC_MASK 0x00000003 +#define CLKMGR_SDMMC_CLK_SRC_F2S 0x0 +#define CLKMGR_SDMMC_CLK_SRC_MAIN 0x1 +#define CLKMGR_SDMMC_CLK_SRC_PER 0x2 +#define CLKMGR_QSPI_CLK_SRC_F2S 0x0 +#define CLKMGR_QSPI_CLK_SRC_MAIN 0x1 +#define CLKMGR_QSPI_CLK_SRC_PER 0x2 + +/* SDR PLL */ +#define CLKMGR_SDRPLLGRP_VCO_DENOM_OFFSET 16 +#define CLKMGR_SDRPLLGRP_VCO_DENOM_MASK 0x003f0000 +#define CLKMGR_SDRPLLGRP_VCO_NUMER_OFFSET 3 +#define CLKMGR_SDRPLLGRP_VCO_NUMER_MASK 0x0000fff8 +#define CLKMGR_SDRPLLGRP_VCO_OUTRESETALL BIT(24) +#define CLKMGR_SDRPLLGRP_VCO_OUTRESETALL_OFFSET 24 +#define CLKMGR_SDRPLLGRP_VCO_OUTRESET_OFFSET 25 +#define CLKMGR_SDRPLLGRP_VCO_OUTRESET_MASK 0x7e000000 +#define CLKMGR_SDRPLLGRP_VCO_REGEXTSEL_MASK BIT(31) +#define CLKMGR_SDRPLLGRP_VCO_RESET_VALUE 0x8001000d +#define CLKMGR_SDRPLLGRP_VCO_SSRC_OFFSET 22 +#define CLKMGR_SDRPLLGRP_VCO_SSRC_MASK 0x00c00000 + +#define CLKMGR_SDRPLLGRP_DDRDQSCLK_CNT_OFFSET 0 +#define CLKMGR_SDRPLLGRP_DDRDQSCLK_CNT_MASK 0x000001ff +#define CLKMGR_SDRPLLGRP_DDRDQSCLK_PHASE_OFFSET 9 +#define CLKMGR_SDRPLLGRP_DDRDQSCLK_PHASE_MASK 0x00000e00 + +#define CLKMGR_SDRPLLGRP_DDR2XDQSCLK_CNT_OFFSET 0 +#define CLKMGR_SDRPLLGRP_DDR2XDQSCLK_CNT_MASK 0x000001ff +#define CLKMGR_SDRPLLGRP_DDR2XDQSCLK_PHASE_OFFSET 9 +#define CLKMGR_SDRPLLGRP_DDR2XDQSCLK_PHASE_MASK 0x00000e00 + +#define CLKMGR_SDRPLLGRP_DDRDQCLK_CNT_OFFSET 0 +#define CLKMGR_SDRPLLGRP_DDRDQCLK_CNT_MASK 0x000001ff +#define CLKMGR_SDRPLLGRP_DDRDQCLK_PHASE_OFFSET 9 +#define CLKMGR_SDRPLLGRP_DDRDQCLK_PHASE_MASK 0x00000e00 + +#define CLKMGR_SDRPLLGRP_S2FUSER2CLK_CNT_OFFSET 0 +#define CLKMGR_SDRPLLGRP_S2FUSER2CLK_CNT_MASK 0x000001ff +#define CLKMGR_SDRPLLGRP_S2FUSER2CLK_PHASE_OFFSET 9 +#define CLKMGR_SDRPLLGRP_S2FUSER2CLK_PHASE_MASK 0x00000e00 + +#endif /* _CLOCK_MANAGER_GEN5_H_ */ diff --git a/arch/arm/mach-socfpga/include/mach/misc.h b/arch/arm/mach-socfpga/include/mach/misc.h new file mode 100644 index 0000000000..0b65783b05 --- /dev/null +++ b/arch/arm/mach-socfpga/include/mach/misc.h @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2016-2017 Intel Corporation + * + * SPDX-License-Identifier: GPL-2.0 + */ + +#ifndef _MISC_H_ +#define _MISC_H_ + +void dwmac_deassert_reset(const unsigned int of_reset_id, const u32 phymode); + +struct bsel { + const char *mode; + const char *name; +}; + +extern struct bsel bsel_str[]; + +#ifdef CONFIG_FPGA +void socfpga_fpga_add(void); +#else +static inline void socfpga_fpga_add(void) {} +#endif + +#if defined(CONFIG_TARGET_SOCFPGA_ARRIA10) +unsigned int dedicated_uart_com_port(const void *blob); +unsigned int shared_uart_com_port(const void *blob); +unsigned int uart_com_port(const void *blob); +#endif + +#endif /* _MISC_H_ */ diff --git a/arch/arm/mach-socfpga/include/mach/pinmux.h b/arch/arm/mach-socfpga/include/mach/pinmux.h new file mode 100644 index 0000000000..563a3db110 --- /dev/null +++ b/arch/arm/mach-socfpga/include/mach/pinmux.h @@ -0,0 +1,17 @@ +/* + * Copyright (C) 2016-2017 Intel Corporation <www.intel.com> + * + * SPDX-License-Identifier: GPL-2.0 + */ + +#ifndef _PINMUX_H_ +#define _PINMUX_H_ + +#define PINMUX_UART 0xD + +#ifndef __ASSEMBLY__ +int config_dedicated_pins(const void *blob); +int config_pins(const void *blob, const char *pin_grp); +#endif + +#endif /* _PINMUX_H_ */ diff --git a/arch/arm/mach-socfpga/include/mach/reset_manager.h b/arch/arm/mach-socfpga/include/mach/reset_manager.h index 2f070f291c..65917454f8 100644 --- a/arch/arm/mach-socfpga/include/mach/reset_manager.h +++ b/arch/arm/mach-socfpga/include/mach/reset_manager.h @@ -1,34 +1,17 @@ /* - * Copyright (C) 2012 Altera Corporation <www.altera.com> + * Copyright (C) 2012-2017 Altera Corporation <www.altera.com> * * SPDX-License-Identifier: GPL-2.0+ */ -#ifndef _RESET_MANAGER_H_ -#define _RESET_MANAGER_H_ +#ifndef _RESET_MANAGER_H_ +#define _RESET_MANAGER_H_ void reset_cpu(ulong addr); -void reset_deassert_peripherals_handoff(void); - -void socfpga_bridges_reset(int enable); void socfpga_per_reset(u32 reset, int set); void socfpga_per_reset_all(void); -struct socfpga_reset_manager { - u32 status; - u32 ctrl; - u32 counts; - u32 padding1; - u32 mpu_mod_reset; - u32 per_mod_reset; - u32 per2_mod_reset; - u32 brg_mod_reset; - u32 misc_mod_reset; - u32 padding2[12]; - u32 tstscratch; -}; - #if defined(CONFIG_SOCFPGA_VIRTUAL_TARGET) #define RSTMGR_CTRL_SWWARMRSTREQ_LSB 2 #else @@ -55,28 +38,13 @@ struct socfpga_reset_manager { #define RSTMGR_BANK(_reset) \ (((_reset) >> RSTMGR_BANK_OFFSET) & RSTMGR_BANK_MASK) -/* - * SocFPGA Cyclone V/Arria V reset IDs, bank mapping is as follows: - * 0 ... mpumodrst - * 1 ... permodrst - * 2 ... per2modrst - * 3 ... brgmodrst - * 4 ... miscmodrst - */ -#define RSTMGR_EMAC0 RSTMGR_DEFINE(1, 0) -#define RSTMGR_EMAC1 RSTMGR_DEFINE(1, 1) -#define RSTMGR_NAND RSTMGR_DEFINE(1, 4) -#define RSTMGR_QSPI RSTMGR_DEFINE(1, 5) -#define RSTMGR_L4WD0 RSTMGR_DEFINE(1, 6) -#define RSTMGR_OSC1TIMER0 RSTMGR_DEFINE(1, 8) -#define RSTMGR_UART0 RSTMGR_DEFINE(1, 16) -#define RSTMGR_SPIM0 RSTMGR_DEFINE(1, 18) -#define RSTMGR_SPIM1 RSTMGR_DEFINE(1, 19) -#define RSTMGR_SDMMC RSTMGR_DEFINE(1, 22) -#define RSTMGR_DMA RSTMGR_DEFINE(1, 28) -#define RSTMGR_SDR RSTMGR_DEFINE(1, 29) - /* Create a human-readable reference to SoCFPGA reset. */ #define SOCFPGA_RESET(_name) RSTMGR_##_name +#if defined(CONFIG_TARGET_SOCFPGA_GEN5) +#include <asm/arch/reset_manager_gen5.h> +#elif defined(CONFIG_TARGET_SOCFPGA_ARRIA10) +#include <asm/arch/reset_manager_arria10.h> +#endif + #endif /* _RESET_MANAGER_H_ */ diff --git a/arch/arm/mach-socfpga/include/mach/reset_manager_arria10.h b/arch/arm/mach-socfpga/include/mach/reset_manager_arria10.h new file mode 100644 index 0000000000..7922db815c --- /dev/null +++ b/arch/arm/mach-socfpga/include/mach/reset_manager_arria10.h @@ -0,0 +1,147 @@ +/* + * Copyright (C) 2016-2017 Intel Corporation + * + * SPDX-License-Identifier: GPL-2.0 + */ + +#ifndef _RESET_MANAGER_ARRIA10_H_ +#define _RESET_MANAGER_ARRIA10_H_ + +#include <dt-bindings/reset/altr,rst-mgr-a10.h> + +void socfpga_watchdog_disable(void); +void socfpga_reset_deassert_noc_ddr_scheduler(void); +int socfpga_is_wdt_in_reset(void); +void socfpga_emac_manage_reset(ulong emacbase, u32 state); +int socfpga_reset_deassert_bridges_handoff(void); +void socfpga_reset_assert_fpga_connected_peripherals(void); +void socfpga_reset_deassert_osc1wd0(void); +void socfpga_reset_uart(int assert); +int socfpga_bridges_reset(int enable); + +struct socfpga_reset_manager { + u32 stat; + u32 ramstat; + u32 miscstat; + u32 ctrl; + u32 hdsken; + u32 hdskreq; + u32 hdskack; + u32 counts; + u32 mpumodrst; + u32 per0modrst; + u32 per1modrst; + u32 brgmodrst; + u32 sysmodrst; + u32 coldmodrst; + u32 nrstmodrst; + u32 dbgmodrst; + u32 mpuwarmmask; + u32 per0warmmask; + u32 per1warmmask; + u32 brgwarmmask; + u32 syswarmmask; + u32 nrstwarmmask; + u32 l3warmmask; + u32 tststa; + u32 tstscratch; + u32 hdsktimeout; + u32 hmcintr; + u32 hmcintren; + u32 hmcintrens; + u32 hmcintrenr; + u32 hmcgpout; + u32 hmcgpin; +}; + +/* + * SocFPGA Arria10 reset IDs, bank mapping is as follows: + * 0 ... mpumodrst + * 1 ... per0modrst + * 2 ... per1modrst + * 3 ... brgmodrst + * 4 ... sysmodrst + */ +#define RSTMGR_EMAC0 RSTMGR_DEFINE(1, 0) +#define RSTMGR_EMAC1 RSTMGR_DEFINE(1, 1) +#define RSTMGR_EMAC2 RSTMGR_DEFINE(1, 2) +#define RSTMGR_NAND RSTMGR_DEFINE(1, 5) +#define RSTMGR_QSPI RSTMGR_DEFINE(1, 6) +#define RSTMGR_SDMMC RSTMGR_DEFINE(1, 7) +#define RSTMGR_DMA RSTMGR_DEFINE(1, 16) +#define RSTMGR_SPIM0 RSTMGR_DEFINE(1, 17) +#define RSTMGR_SPIM1 RSTMGR_DEFINE(1, 18) +#define RSTMGR_L4WD0 RSTMGR_DEFINE(2, 0) +#define RSTMGR_L4WD1 RSTMGR_DEFINE(2, 1) +#define RSTMGR_L4SYSTIMER0 RSTMGR_DEFINE(2, 2) +#define RSTMGR_L4SYSTIMER1 RSTMGR_DEFINE(2, 3) +#define RSTMGR_SPTIMER0 RSTMGR_DEFINE(2, 4) +#define RSTMGR_SPTIMER1 RSTMGR_DEFINE(2, 5) +#define RSTMGR_UART0 RSTMGR_DEFINE(2, 16) +#define RSTMGR_UART1 RSTMGR_DEFINE(2, 17) +#define RSTMGR_DDRSCH RSTMGR_DEFINE(3, 6) + +#define ALT_RSTMGR_CTL_SWWARMRSTREQ_SET_MSK BIT(1) +#define ALT_RSTMGR_PER0MODRST_EMAC0_SET_MSK BIT(0) +#define ALT_RSTMGR_PER0MODRST_EMAC1_SET_MSK BIT(1) +#define ALT_RSTMGR_PER0MODRST_EMAC2_SET_MSK BIT(2) +#define ALT_RSTMGR_PER0MODRST_USB0_SET_MSK BIT(3) +#define ALT_RSTMGR_PER0MODRST_USB1_SET_MSK BIT(4) +#define ALT_RSTMGR_PER0MODRST_NAND_SET_MSK BIT(5) +#define ALT_RSTMGR_PER0MODRST_QSPI_SET_MSK BIT(6) +#define ALT_RSTMGR_PER0MODRST_SDMMC_SET_MSK BIT(7) +#define ALT_RSTMGR_PER0MODRST_EMACECC0_SET_MSK BIT(8) +#define ALT_RSTMGR_PER0MODRST_EMACECC1_SET_MSK BIT(9) +#define ALT_RSTMGR_PER0MODRST_EMACECC2_SET_MSK BIT(10) +#define ALT_RSTMGR_PER0MODRST_USBECC0_SET_MSK BIT(11) +#define ALT_RSTMGR_PER0MODRST_USBECC1_SET_MSK BIT(12) +#define ALT_RSTMGR_PER0MODRST_NANDECC_SET_MSK BIT(13) +#define ALT_RSTMGR_PER0MODRST_QSPIECC_SET_MSK BIT(14) +#define ALT_RSTMGR_PER0MODRST_SDMMCECC_SET_MSK BIT(15) +#define ALT_RSTMGR_PER0MODRST_DMA_SET_MSK BIT(16) +#define ALT_RSTMGR_PER0MODRST_SPIM0_SET_MSK BIT(17) +#define ALT_RSTMGR_PER0MODRST_SPIM1_SET_MSK BIT(18) +#define ALT_RSTMGR_PER0MODRST_SPIS0_SET_MSK BIT(19) +#define ALT_RSTMGR_PER0MODRST_SPIS1_SET_MSK BIT(20) +#define ALT_RSTMGR_PER0MODRST_DMAECC_SET_MSK BIT(21) +#define ALT_RSTMGR_PER0MODRST_EMACPTP_SET_MSK BIT(22) +#define ALT_RSTMGR_PER0MODRST_DMAIF0_SET_MSK BIT(24) +#define ALT_RSTMGR_PER0MODRST_DMAIF1_SET_MSK BIT(25) +#define ALT_RSTMGR_PER0MODRST_DMAIF2_SET_MSK BIT(26) +#define ALT_RSTMGR_PER0MODRST_DMAIF3_SET_MSK BIT(27) +#define ALT_RSTMGR_PER0MODRST_DMAIF4_SET_MSK BIT(28) +#define ALT_RSTMGR_PER0MODRST_DMAIF5_SET_MSK BIT(29) +#define ALT_RSTMGR_PER0MODRST_DMAIF6_SET_MSK BIT(30) +#define ALT_RSTMGR_PER0MODRST_DMAIF7_SET_MSK BIT(31) + +#define ALT_RSTMGR_PER1MODRST_WD0_SET_MSK BIT(0) +#define ALT_RSTMGR_PER1MODRST_WD1_SET_MSK BIT(1) +#define ALT_RSTMGR_PER1MODRST_L4SYSTMR0_SET_MSK BIT(2) +#define ALT_RSTMGR_PER1MODRST_L4SYSTMR1_SET_MSK BIT(3) +#define ALT_RSTMGR_PER1MODRST_SPTMR0_SET_MSK BIT(4) +#define ALT_RSTMGR_PER1MODRST_SPTMR1_SET_MSK BIT(5) +#define ALT_RSTMGR_PER1MODRST_I2C0_SET_MSK BIT(8) +#define ALT_RSTMGR_PER1MODRST_I2C1_SET_MSK BIT(9) +#define ALT_RSTMGR_PER1MODRST_I2C2_SET_MSK BIT(10) +#define ALT_RSTMGR_PER1MODRST_I2C3_SET_MSK BIT(11) +#define ALT_RSTMGR_PER1MODRST_I2C4_SET_MSK BIT(12) +#define ALT_RSTMGR_PER1MODRST_UART0_SET_MSK BIT(16) +#define ALT_RSTMGR_PER1MODRST_UART1_SET_MSK BIT(17) +#define ALT_RSTMGR_PER1MODRST_GPIO0_SET_MSK BIT(24) +#define ALT_RSTMGR_PER1MODRST_GPIO1_SET_MSK BIT(25) +#define ALT_RSTMGR_PER1MODRST_GPIO2_SET_MSK BIT(26) + +#define ALT_RSTMGR_BRGMODRST_H2F_SET_MSK BIT(0) +#define ALT_RSTMGR_BRGMODRST_LWH2F_SET_MSK BIT(1) +#define ALT_RSTMGR_BRGMODRST_F2H_SET_MSK BIT(2) +#define ALT_RSTMGR_BRGMODRST_F2SSDRAM0_SET_MSK BIT(3) +#define ALT_RSTMGR_BRGMODRST_F2SSDRAM1_SET_MSK BIT(4) +#define ALT_RSTMGR_BRGMODRST_F2SSDRAM2_SET_MSK BIT(5) +#define ALT_RSTMGR_BRGMODRST_DDRSCH_SET_MSK BIT(6) + +#define ALT_RSTMGR_HDSKEN_SDRSELFREFEN_SET_MSK BIT(0) +#define ALT_RSTMGR_HDSKEN_FPGAMGRHSEN_SET_MSK BIT(1) +#define ALT_RSTMGR_HDSKEN_FPGAHSEN_SET_MSK BIT(2) +#define ALT_RSTMGR_HDSKEN_ETRSTALLEN_SET_MSK BIT(3) + +#endif /* _RESET_MANAGER_ARRIA10_H_ */ diff --git a/arch/arm/mach-socfpga/include/mach/reset_manager_gen5.h b/arch/arm/mach-socfpga/include/mach/reset_manager_gen5.h new file mode 100644 index 0000000000..6d9cffea7b --- /dev/null +++ b/arch/arm/mach-socfpga/include/mach/reset_manager_gen5.h @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2012-2017 Altera Corporation <www.altera.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef _RESET_MANAGER_GEN5_H_ +#define _RESET_MANAGER_GEN5_H_ + +#include <dt-bindings/reset/altr,rst-mgr.h> + +void reset_deassert_peripherals_handoff(void); +void socfpga_bridges_reset(int enable); + +struct socfpga_reset_manager { + u32 status; + u32 ctrl; + u32 counts; + u32 padding1; + u32 mpu_mod_reset; + u32 per_mod_reset; + u32 per2_mod_reset; + u32 brg_mod_reset; + u32 misc_mod_reset; + u32 padding2[12]; + u32 tstscratch; +}; + +/* + * SocFPGA Cyclone V/Arria V reset IDs, bank mapping is as follows: + * 0 ... mpumodrst + * 1 ... permodrst + * 2 ... per2modrst + * 3 ... brgmodrst + * 4 ... miscmodrst + */ +#define RSTMGR_EMAC0 RSTMGR_DEFINE(1, 0) +#define RSTMGR_EMAC1 RSTMGR_DEFINE(1, 1) +#define RSTMGR_NAND RSTMGR_DEFINE(1, 4) +#define RSTMGR_QSPI RSTMGR_DEFINE(1, 5) +#define RSTMGR_L4WD0 RSTMGR_DEFINE(1, 6) +#define RSTMGR_OSC1TIMER0 RSTMGR_DEFINE(1, 8) +#define RSTMGR_UART0 RSTMGR_DEFINE(1, 16) +#define RSTMGR_SPIM0 RSTMGR_DEFINE(1, 18) +#define RSTMGR_SPIM1 RSTMGR_DEFINE(1, 19) +#define RSTMGR_SDMMC RSTMGR_DEFINE(1, 22) +#define RSTMGR_DMA RSTMGR_DEFINE(1, 28) +#define RSTMGR_SDR RSTMGR_DEFINE(1, 29) + +#endif /* _RESET_MANAGER_GEN5_H_ */ diff --git a/arch/arm/mach-socfpga/include/mach/sdram_arria10.h b/arch/arm/mach-socfpga/include/mach/sdram_arria10.h new file mode 100644 index 0000000000..1d7b7c119a --- /dev/null +++ b/arch/arm/mach-socfpga/include/mach/sdram_arria10.h @@ -0,0 +1,380 @@ +/* + * Copyright (C) 2015-2017 Intel Corporation <www.intel.com> + * + * SPDX-License-Identifier: GPL-2.0 + */ + +#ifndef _SOCFPGA_SDRAM_ARRIA10_H_ +#define _SOCFPGA_SDRAM_ARRIA10_H_ + +#ifndef __ASSEMBLY__ + +struct socfpga_ecc_hmc { + u32 ip_rev_id; + u32 _pad_0x4_0x7; + u32 ddrioctrl; + u32 ddrcalstat; + u32 mpr_0beat1; + u32 mpr_1beat1; + u32 mpr_2beat1; + u32 mpr_3beat1; + u32 mpr_4beat1; + u32 mpr_5beat1; + u32 mpr_6beat1; + u32 mpr_7beat1; + u32 mpr_8beat1; + u32 mpr_0beat2; + u32 mpr_1beat2; + u32 mpr_2beat2; + u32 mpr_3beat2; + u32 mpr_4beat2; + u32 mpr_5beat2; + u32 mpr_6beat2; + u32 mpr_7beat2; + u32 mpr_8beat2; + u32 _pad_0x58_0x5f[2]; + u32 auto_precharge; + u32 _pad_0x64_0xff[39]; + u32 eccctrl; + u32 eccctrl2; + u32 _pad_0x108_0x10f[2]; + u32 errinten; + u32 errintens; + u32 errintenr; + u32 intmode; + u32 intstat; + u32 diaginttest; + u32 modstat; + u32 derraddra; + u32 serraddra; + u32 _pad_0x134_0x137; + u32 autowb_corraddr; + u32 serrcntreg; + u32 autowb_drop_cntreg; + u32 _pad_0x144_0x147; + u32 ecc_reg2wreccdatabus; + u32 ecc_rdeccdata2regbus; + u32 ecc_reg2rdeccdatabus; + u32 _pad_0x154_0x15f[3]; + u32 ecc_diagon; + u32 ecc_decstat; + u32 _pad_0x168_0x16f[2]; + u32 ecc_errgenaddr_0; + u32 ecc_errgenaddr_1; + u32 ecc_errgenaddr_2; + u32 ecc_errgenaddr_3; +}; + +struct socfpga_noc_ddr_scheduler { + u32 ddr_t_main_scheduler_id_coreid; + u32 ddr_t_main_scheduler_id_revisionid; + u32 ddr_t_main_scheduler_ddrconf; + u32 ddr_t_main_scheduler_ddrtiming; + u32 ddr_t_main_scheduler_ddrmode; + u32 ddr_t_main_scheduler_readlatency; + u32 _pad_0x20_0x34[8]; + u32 ddr_t_main_scheduler_activate; + u32 ddr_t_main_scheduler_devtodev; +}; + +/* + * OCRAM firewall + */ +struct socfpga_noc_fw_ocram { + u32 enable; + u32 enable_set; + u32 enable_clear; + u32 region0; + u32 region1; + u32 region2; + u32 region3; + u32 region4; + u32 region5; +}; + +/* for master such as MPU and FPGA */ +struct socfpga_noc_fw_ddr_mpu_fpga2sdram { + u32 enable; + u32 enable_set; + u32 enable_clear; + u32 _pad_0xc_0xf; + u32 mpuregion0addr; + u32 mpuregion1addr; + u32 mpuregion2addr; + u32 mpuregion3addr; + u32 fpga2sdram0region0addr; + u32 fpga2sdram0region1addr; + u32 fpga2sdram0region2addr; + u32 fpga2sdram0region3addr; + u32 fpga2sdram1region0addr; + u32 fpga2sdram1region1addr; + u32 fpga2sdram1region2addr; + u32 fpga2sdram1region3addr; + u32 fpga2sdram2region0addr; + u32 fpga2sdram2region1addr; + u32 fpga2sdram2region2addr; + u32 fpga2sdram2region3addr; +}; + +/* for L3 master */ +struct socfpga_noc_fw_ddr_l3 { + u32 enable; + u32 enable_set; + u32 enable_clear; + u32 hpsregion0addr; + u32 hpsregion1addr; + u32 hpsregion2addr; + u32 hpsregion3addr; + u32 hpsregion4addr; + u32 hpsregion5addr; + u32 hpsregion6addr; + u32 hpsregion7addr; +}; + +struct socfpga_io48_mmr { + u32 dbgcfg0; + u32 dbgcfg1; + u32 dbgcfg2; + u32 dbgcfg3; + u32 dbgcfg4; + u32 dbgcfg5; + u32 dbgcfg6; + u32 reserve0; + u32 reserve1; + u32 reserve2; + u32 ctrlcfg0; + u32 ctrlcfg1; + u32 ctrlcfg2; + u32 ctrlcfg3; + u32 ctrlcfg4; + u32 ctrlcfg5; + u32 ctrlcfg6; + u32 ctrlcfg7; + u32 ctrlcfg8; + u32 ctrlcfg9; + u32 dramtiming0; + u32 dramodt0; + u32 dramodt1; + u32 sbcfg0; + u32 sbcfg1; + u32 sbcfg2; + u32 sbcfg3; + u32 sbcfg4; + u32 sbcfg5; + u32 sbcfg6; + u32 sbcfg7; + u32 caltiming0; + u32 caltiming1; + u32 caltiming2; + u32 caltiming3; + u32 caltiming4; + u32 caltiming5; + u32 caltiming6; + u32 caltiming7; + u32 caltiming8; + u32 caltiming9; + u32 caltiming10; + u32 dramaddrw; + u32 sideband0; + u32 sideband1; + u32 sideband2; + u32 sideband3; + u32 sideband4; + u32 sideband5; + u32 sideband6; + u32 sideband7; + u32 sideband8; + u32 sideband9; + u32 sideband10; + u32 sideband11; + u32 sideband12; + u32 sideband13; + u32 sideband14; + u32 sideband15; + u32 dramsts; + u32 dbgdone; + u32 dbgsignals; + u32 dbgreset; + u32 dbgmatch; + u32 counter0mask; + u32 counter1mask; + u32 counter0match; + u32 counter1match; + u32 niosreserve0; + u32 niosreserve1; + u32 niosreserve2; +}; +#endif /*__ASSEMBLY__*/ + +#define IO48_MMR_CTRLCFG0_DB2_BURST_LENGTH_MASK 0x1F000000 +#define IO48_MMR_CTRLCFG0_DB2_BURST_LENGTH_SHIFT 24 +#define IO48_MMR_CTRLCFG0_DB1_BURST_LENGTH_MASK 0x00F80000 +#define IO48_MMR_CTRLCFG0_DB1_BURST_LENGTH_SHIFT 19 +#define IO48_MMR_CTRLCFG0_DB0_BURST_LENGTH_MASK 0x0007C000 +#define IO48_MMR_CTRLCFG0_DB0_BURST_LENGTH_SHIFT 14 +#define IO48_MMR_CTRLCFG0_CTRL_BURST_LENGTH_MASK 0x00003E00 +#define IO48_MMR_CTRLCFG0_CTRL_BURST_LENGTH_SHIFT 9 +#define IO48_MMR_CTRLCFG0_AC_POS_MASK 0x00000180 +#define IO48_MMR_CTRLCFG0_AC_POS_SHIFT 7 +#define IO48_MMR_CTRLCFG0_DIMM_TYPE_MASK 0x00000070 +#define IO48_MMR_CTRLCFG0_DIM_TYPE_SHIFT 4 +#define IO48_MMR_CTRLCFG0_MEM_TYPE_MASK 0x0000000F +#define IO48_MMR_CTRLCFG0_MEM_TYPE_SHIFT 0 + +#define IO48_MMR_CTRLCFG1_DBC3_ENABLE_DM BIT(30) +#define IO48_MMR_CTRLCFG1_DBC2_ENABLE_DM BIT(29) +#define IO48_MMR_CTRLCFG1_DBC1_ENABLE_DM BIT(28) +#define IO48_MMR_CTRLCFG1_DBC0_ENABLE_DM BIT(27) +#define IO48_MMR_CTRLCFG1_CTRL_ENABLE_DM BIT(26) +#define IO48_MMR_CTRLCFG1_DQSTRK_EN BIT(25) +#define IO48_MMR_CTRLCFG1_STARVE_LIMIT_MASK 0x01F80000 +#define IO48_MMR_CTRLCFG1_STARVE_LIMIT_SHIFT 19 +#define IO48_MMR_CTRLCFG1_REORDER_READ BIT(18) +#define IO48_MMR_CTRLCFG1_DBC3_REORDER_RDATA BIT(17) +#define IO48_MMR_CTRLCFG1_DBC2_REORDER_RDATA BIT(16) +#define IO48_MMR_CTRLCFG1_DBC1_REORDER_RDATA BIT(15) +#define IO48_MMR_CTRLCFG1_DBC0_REORDER_RDATA BIT(14) +#define IO48_MMR_CTRLCFG1_CTRL_REORDER_RDATA BIT(13) +#define IO48_MMR_CTRLCFG1_REORDER_DATA BIT(12) +#define IO48_MMR_CTRLCFG1_DBC3_ENABLE_ECC BIT(11) +#define IO48_MMR_CTRLCFG1_DBC2_ENABLE_ECC BIT(10) +#define IO48_MMR_CTRLCFG1_DBC1_ENABLE_ECC BIT(9) +#define IO48_MMR_CTRLCFG1_DBC0_ENABLE_ECC BIT(8) +#define IO48_MMR_CTRLCFG1_CTRL_ENABLE_ECC BIT(7) +#define IO48_MMR_CTRLCFG1_ADDR_ORDER_MASK 0x00000060 +#define IO48_MMR_CTRLCFG1_ADDR_ORDER_SHIFT 5 +#define IO48_MMR_CTRLCFG1_DBC3_BURST_LENGTH_MASK 0x0000001F +#define IO48_MMR_CTRLCFG1_DBC3_BURST_LENGTH_SHIFT 0 + +#define IO48_MMR_CALTIMING0_CFG_ACT_TO_ACT_DIFF_BG_MASK 0x3F000000 +#define IO48_MMR_CALTIMING0_CFG_ACT_TO_ACT_DIFF_BG_SHIFT 24 +#define IO48_MMR_CALTIMING0_CFG_ACT_TO_ACT_DIFF_BANK_MASK 0x00FC0000 +#define IO48_MMR_CALTIMING0_CFG_ACT_TO_ACT_DIFF_BANK_SHIFT 18 +#define IO48_MMR_CALTIMING0_CFG_ACT_TO_ACT_MASK 0x0003F000 +#define IO48_MMR_CALTIMING0_CFG_ACT_TO_ACT_SHIFT 12 +#define IO48_MMR_CALTIMING0_CFG_ACT_TO_PCH_MASK 0x00000FC0 +#define IO48_MMR_CALTIMING0_CFG_ACT_TO_PCH_SHIFT 6 +#define IO48_MMR_CALTIMING0_CFG_ACT_TO_RDWR_MASK 0x0000003F +#define IO48_MMR_CALTIMING0_CFG_ACT_TO_RDWR_SHIFT 0 + +#define IO48_MMR_CALTIMING1_CFG_RD_TO_WR_DIFF_CHIP_MASK 0x3F000000 +#define IO48_MMR_CALTIMING1_CFG_RD_TO_WR_DIFF_CHIP_SHIFT 24 +#define IO48_MMR_CALTIMING1_CFG_RD_TO_WR_MASK 0x00FC0000 +#define IO48_MMR_CALTIMING1_CFG_RD_TO_WR_SHIFT 18 +#define IO48_MMR_CALTIMING1_CFG_RD_TO_RD_DB_MASK 0x0003F000 +#define IO48_MMR_CALTIMING1_CFG_RD_TO_RD_DB_SHIFT 12 +#define IO48_MMR_CALTIMING1_CFG_RD_TO_RD_DC_MASK 0x00000FC0 +#define IO48_MMR_CALTIMING1_CFG_RD_TO_RD_DC_SHIFT 6 +#define IO48_MMR_CALTIMING1_CFG_RD_TO_RD_MASK 0x0000003F +#define IO48_MMR_CALTIMING1_CFG_RD_TO_RD_SHIFT 0 + +#define IO48_MMR_CALTIMING2_CFG_WR_TO_WR_DIFF_CHIP_MASK 0x3F000000 +#define IO48_MMR_CALTIMING2_CFG_WR_TO_WR_DIFF_CHIP_SHIFT 24 +#define IO48_MMR_CALTIMING2_CFG_WR_TO_WR_MASK 0x00FC0000 +#define IO48_MMR_CALTIMING2_CFG_WR_TO_WR_SHIFT 18 +#define IO48_MMR_CALTIMING2_CFG_RD_TO_AP_VALID_MASK 0x0003F000 +#define IO48_MMR_CALTIMING2_CFG_RD_TO_AP_VALID_SHIFT 12 +#define IO48_MMR_CALTIMING2_CFG_RD_TO_PCH_MASK 0x00000FC0 +#define IO48_MMR_CALTIMING2_CFG_RD_TO_PCH_SHIFT 6 +#define IO48_MMR_CALTIMING2_CFG_RD_TO_WR_DIFF_BG_MASK 0x0000003F +#define IO48_MMR_CALTIMING2_CFG_RD_TO_WR_DIFF_BG_SHIFT 0 + +#define IO48_MMR_CALTIMING3_CFG_WR_TO_PCH_MASK 0x3F000000 +#define IO48_MMR_CALTIMING3_CFG_WR_TO_PCH_SHIFT 24 +#define IO48_MMR_CALTIMING3_CFG_WR_TO_RD_DIFF_BG_MASK 0x00FC0000 +#define IO48_MMR_CALTIMING3_CFG_WR_TO_RD_DIFF_BG_SHIFT 18 +#define IO48_MMR_CALTIMING3_CFG_WR_TO_RD_DIFF_CHIP_MASK 0x0003F000 +#define IO48_MMR_CALTIMING3_CFG_WR_TO_RD_DIFF_CHIP_SHIFT 12 +#define IO48_MMR_CALTIMING3_CFG_WR_TO_RD_MASK 0x00000FC0 +#define IO48_MMR_CALTIMING3_CFG_WR_TO_RD_SHIFT 6 +#define IO48_MMR_CALTIMING3_CFG_WR_TO_WR_DIFF_BG_MASK 0x0000003F +#define IO48_MMR_CALTIMING3_CFG_WR_TO_WR_DIFF_BG_SHIFT 0 + +#define IO48_MMR_CALTIMING4_CFG_PDN_TO_VALID_MASK 0xFC000000 +#define IO48_MMR_CALTIMING4_CFG_PDN_TO_VALID_SHIFT 26 +#define IO48_MMR_CALTIMING4_CFG_ARF_TO_VALID_MASK 0x03FC0000 +#define IO48_MMR_CALTIMING4_CFG_ARF_TO_VALID_SHIFT 18 +#define IO48_MMR_CALTIMING4_CFG_PCH_ALL_TO_VALID_MASK 0x0003F000 +#define IO48_MMR_CALTIMING4_CFG_PCH_ALL_TO_VALID_SHIFT 12 +#define IO48_MMR_CALTIMING4_CFG_PCH_TO_VALID_MASK 0x00000FC0 +#define IO48_MMR_CALTIMING4_CFG_PCH_TO_VALID_SHIFT 6 +#define IO48_MMR_CALTIMING4_CFG_WR_AP_TO_VALID_MASK 0x0000003F +#define IO48_MMR_CALTIMING4_CFG_WR_AP_TO_VALID_SHIFT 0 + +#define IO48_MMR_CALTIMING9_CFG_WR_4_ACT_TO_ACT_MASK 0x000000FF +#define IO48_MMR_CALTIMING9_CFG_WR_4_ACT_TO_ACT_SHIFT 0 + +#define IO48_MMR_DRAMADDRW_CFG_CS_ADDR_WIDTH_MASK 0x00070000 +#define IO48_MMR_DRAMADDRW_CFG_CS_ADDR_WIDTH_SHIFT 16 +#define IO48_MMR_DRAMADDRW_CFG_BANK_GROUP_ADDR_WIDTH_MASK 0x0000C000 +#define IO48_MMR_DRAMADDRW_CFG_BANK_GROUP_ADDR_WIDTH_SHIFT 14 +#define IO48_MMR_DRAMADDRW_CFG_BANK_ADDR_WIDTH_MASK 0x00003C00 +#define IO48_MMR_DRAMADDRW_CFG_BANK_ADDR_WIDTH_SHIFT 10 +#define IO48_MMR_DRAMADDRW_CFG_ROW_ADDR_WIDTH_MASK 0x000003E0 +#define IO48_MMR_DRAMADDRW_CFG_ROW_ADDR_WIDTH_SHIFT 5 +#define IO48_MMR_DRAMADDRW_CFG_COL_ADDR_WIDTH_MASK 0x0000001F +#define IO48_MMR_DRAMADDRW_CFG_COL_ADDR_WIDTH_SHIFT 0 + +#define ALT_ECC_HMC_OCP_DDRIOCTRL_IO_SIZE_MSK 0x00000003 + +#define ALT_ECC_HMC_OCP_INTSTAT_SERRPENA_SET_MSK BIT(0) +#define ALT_ECC_HMC_OCP_INTSTAT_DERRPENA_SET_MSK BIT(1) +#define ALT_ECC_HMC_OCP_ERRINTEN_SERRINTEN_SET_MSK BIT(0) +#define ALT_ECC_HMC_OCP_ERRINTEN_DERRINTEN_SET_MSK BIT(1) +#define ALT_ECC_HMC_OCP_INTMOD_INTONCMP_SET_MSK BIT(16) +#define ALT_ECC_HMC_OCP_ECCCTL_AWB_CNT_RST_SET_MSK BIT(16) +#define ALT_ECC_HMC_OCP_ECCCTL_CNT_RST_SET_MSK BIT(8) +#define ALT_ECC_HMC_OCP_ECCCTL_ECC_EN_SET_MSK BIT(0) +#define ALT_ECC_HMC_OCP_ECCCTL2_RMW_EN_SET_MSK BIT(8) +#define ALT_ECC_HMC_OCP_ECCCTL2_AWB_EN_SET_MSK BIT(0) + +#define ALT_ECC_HMC_OCP_SERRCNTREG_VALUE 8 + +#define ALT_NOC_MPU_DDR_T_SCHED_DDRTIMING_ACTTOACT_LSB 0 +#define ALT_NOC_MPU_DDR_T_SCHED_DDRTIMING_RDTOMISS_LSB 6 +#define ALT_NOC_MPU_DDR_T_SCHED_DDRTIMING_WRTOMISS_LSB 12 +#define ALT_NOC_MPU_DDR_T_SCHED_DDRTIMING_BURSTLEN_LSB 18 +#define ALT_NOC_MPU_DDR_T_SCHED_DDRTIMING_RDTOWR_LSB 21 +#define ALT_NOC_MPU_DDR_T_SCHED_DDRTIMING_WRTORD_LSB 26 +#define ALT_NOC_MPU_DDR_T_SCHED_DDRTIMING_BWRATIO_LSB 31 + +#define ALT_NOC_MPU_DDR_T_SCHED_DDRMOD_AUTOPRECHARGE_LSB 0 +#define ALT_NOC_MPU_DDR_T_SCHED_DDRMOD_BWRATIOEXTENDED_LSB 1 + +#define ALT_NOC_MPU_DDR_T_SCHED_ACTIVATE_RRD_LSB 0 +#define ALT_NOC_MPU_DDR_T_SCHED_ACTIVATE_FAW_LSB 4 +#define ALT_NOC_MPU_DDR_T_SCHED_ACTIVATE_FAWBANK_LSB 10 + +#define ALT_NOC_MPU_DDR_T_SCHED_DEVTODEV_BUSRDTORD_LSB 0 +#define ALT_NOC_MPU_DDR_T_SCHED_DEVTODEV_BUSRDTOWR_LSB 2 +#define ALT_NOC_MPU_DDR_T_SCHED_DEVTODEV_BUSWRTORD_LSB 4 + +#define ALT_NOC_FW_DDR_END_ADDR_LSB 16 +#define ALT_NOC_FW_DDR_ADDR_MASK 0xFFFF +#define ALT_NOC_FW_DDR_SCR_EN_HPSREG0EN_SET_MSK BIT(0) +#define ALT_NOC_FW_DDR_SCR_EN_HPSREG1EN_SET_MSK BIT(1) +#define ALT_NOC_FW_DDR_SCR_EN_HPSREG2EN_SET_MSK BIT(2) +#define ALT_NOC_FW_DDR_SCR_EN_HPSREG3EN_SET_MSK BIT(3) +#define ALT_NOC_FW_DDR_SCR_EN_HPSREG4EN_SET_MSK BIT(4) +#define ALT_NOC_FW_DDR_SCR_EN_HPSREG5EN_SET_MSK BIT(5) +#define ALT_NOC_FW_DDR_SCR_EN_HPSREG6EN_SET_MSK BIT(6) +#define ALT_NOC_FW_DDR_SCR_EN_HPSREG7EN_SET_MSK BIT(7) +#define ALT_NOC_FW_DDR_SCR_EN_MPUREG0EN_SET_MSK BIT(0) +#define ALT_NOC_FW_DDR_SCR_EN_MPUREG1EN_SET_MSK BIT(1) +#define ALT_NOC_FW_DDR_SCR_EN_MPUREG2EN_SET_MSK BIT(2) +#define ALT_NOC_FW_DDR_SCR_EN_MPUREG3EN_SET_MSK BIT(3) +#define ALT_NOC_FW_DDR_SCR_EN_F2SDR0REG0EN_SET_MSK BIT(4) +#define ALT_NOC_FW_DDR_SCR_EN_F2SDR0REG1EN_SET_MSK BIT(5) +#define ALT_NOC_FW_DDR_SCR_EN_F2SDR0REG2EN_SET_MSK BIT(6) +#define ALT_NOC_FW_DDR_SCR_EN_F2SDR0REG3EN_SET_MSK BIT(7) +#define ALT_NOC_FW_DDR_SCR_EN_F2SDR1REG0EN_SET_MSK BIT(8) +#define ALT_NOC_FW_DDR_SCR_EN_F2SDR1REG1EN_SET_MSK BIT(9) +#define ALT_NOC_FW_DDR_SCR_EN_F2SDR1REG2EN_SET_MSK BIT(10) +#define ALT_NOC_FW_DDR_SCR_EN_F2SDR1REG3EN_SET_MSK BIT(11) +#define ALT_NOC_FW_DDR_SCR_EN_F2SDR2REG0EN_SET_MSK BIT(12) +#define ALT_NOC_FW_DDR_SCR_EN_F2SDR2REG1EN_SET_MSK BIT(13) +#define ALT_NOC_FW_DDR_SCR_EN_F2SDR2REG2EN_SET_MSK BIT(14) +#define ALT_NOC_FW_DDR_SCR_EN_F2SDR2REG3EN_SET_MSK BIT(15) + +#define ALT_IO48_DRAMTIME_MEM_READ_LATENCY_MASK 0x0000003F +#endif /* _SOCFPGA_SDRAM_ARRIA10_H_ */ diff --git a/arch/arm/mach-socfpga/include/mach/system_manager.h b/arch/arm/mach-socfpga/include/mach/system_manager.h index c45edea32d..e6d4280c5b 100644 --- a/arch/arm/mach-socfpga/include/mach/system_manager.h +++ b/arch/arm/mach-socfpga/include/mach/system_manager.h @@ -1,139 +1,24 @@ /* - * Copyright (C) 2013 Altera Corporation <www.altera.com> + * Copyright (C) 2013-2017 Altera Corporation <www.altera.com> * * SPDX-License-Identifier: GPL-2.0+ */ -#ifndef _SYSTEM_MANAGER_H_ -#define _SYSTEM_MANAGER_H_ +#ifndef _SYSTEM_MANAGER_H_ +#define _SYSTEM_MANAGER_H_ -#ifndef __ASSEMBLY__ - -void sysmgr_pinmux_init(void); -void sysmgr_config_warmrstcfgio(int enable); - -void sysmgr_get_pinmux_table(const u8 **table, unsigned int *table_len); -#endif - -struct socfpga_system_manager { - /* System Manager Module */ - u32 siliconid1; /* 0x00 */ - u32 siliconid2; - u32 _pad_0x8_0xf[2]; - u32 wddbg; /* 0x10 */ - u32 bootinfo; - u32 hpsinfo; - u32 parityinj; - /* FPGA Interface Group */ - u32 fpgaintfgrp_gbl; /* 0x20 */ - u32 fpgaintfgrp_indiv; - u32 fpgaintfgrp_module; - u32 _pad_0x2c_0x2f; - /* Scan Manager Group */ - u32 scanmgrgrp_ctrl; /* 0x30 */ - u32 _pad_0x34_0x3f[3]; - /* Freeze Control Group */ - u32 frzctrl_vioctrl; /* 0x40 */ - u32 _pad_0x44_0x4f[3]; - u32 frzctrl_hioctrl; /* 0x50 */ - u32 frzctrl_src; - u32 frzctrl_hwctrl; - u32 _pad_0x5c_0x5f; - /* EMAC Group */ - u32 emacgrp_ctrl; /* 0x60 */ - u32 emacgrp_l3master; - u32 _pad_0x68_0x6f[2]; - /* DMA Controller Group */ - u32 dmagrp_ctrl; /* 0x70 */ - u32 dmagrp_persecurity; - u32 _pad_0x78_0x7f[2]; - /* Preloader (initial software) Group */ - u32 iswgrp_handoff[8]; /* 0x80 */ - u32 _pad_0xa0_0xbf[8]; /* 0xa0 */ - /* Boot ROM Code Register Group */ - u32 romcodegrp_ctrl; /* 0xc0 */ - u32 romcodegrp_cpu1startaddr; - u32 romcodegrp_initswstate; - u32 romcodegrp_initswlastld; - u32 romcodegrp_bootromswstate; /* 0xd0 */ - u32 __pad_0xd4_0xdf[3]; - /* Warm Boot from On-Chip RAM Group */ - u32 romcodegrp_warmramgrp_enable; /* 0xe0 */ - u32 romcodegrp_warmramgrp_datastart; - u32 romcodegrp_warmramgrp_length; - u32 romcodegrp_warmramgrp_execution; - u32 romcodegrp_warmramgrp_crc; /* 0xf0 */ - u32 __pad_0xf4_0xff[3]; - /* Boot ROM Hardware Register Group */ - u32 romhwgrp_ctrl; /* 0x100 */ - u32 _pad_0x104_0x107; - /* SDMMC Controller Group */ - u32 sdmmcgrp_ctrl; - u32 sdmmcgrp_l3master; - /* NAND Flash Controller Register Group */ - u32 nandgrp_bootstrap; /* 0x110 */ - u32 nandgrp_l3master; - /* USB Controller Group */ - u32 usbgrp_l3master; - u32 _pad_0x11c_0x13f[9]; - /* ECC Management Register Group */ - u32 eccgrp_l2; /* 0x140 */ - u32 eccgrp_ocram; - u32 eccgrp_usb0; - u32 eccgrp_usb1; - u32 eccgrp_emac0; /* 0x150 */ - u32 eccgrp_emac1; - u32 eccgrp_dma; - u32 eccgrp_can0; - u32 eccgrp_can1; /* 0x160 */ - u32 eccgrp_nand; - u32 eccgrp_qspi; - u32 eccgrp_sdmmc; - u32 _pad_0x170_0x3ff[164]; - /* Pin Mux Control Group */ - u32 emacio[20]; /* 0x400 */ - u32 flashio[12]; /* 0x450 */ - u32 generalio[28]; /* 0x480 */ - u32 _pad_0x4f0_0x4ff[4]; - u32 mixed1io[22]; /* 0x500 */ - u32 mixed2io[8]; /* 0x558 */ - u32 gplinmux[23]; /* 0x578 */ - u32 gplmux[71]; /* 0x5d4 */ - u32 nandusefpga; /* 0x6f0 */ - u32 _pad_0x6f4; - u32 rgmii1usefpga; /* 0x6f8 */ - u32 _pad_0x6fc_0x700[2]; - u32 i2c0usefpga; /* 0x704 */ - u32 sdmmcusefpga; /* 0x708 */ - u32 _pad_0x70c_0x710[2]; - u32 rgmii0usefpga; /* 0x714 */ - u32 _pad_0x718_0x720[3]; - u32 i2c3usefpga; /* 0x724 */ - u32 i2c2usefpga; /* 0x728 */ - u32 i2c1usefpga; /* 0x72c */ - u32 spim1usefpga; /* 0x730 */ - u32 _pad_0x734; - u32 spim0usefpga; /* 0x738 */ -}; - -#define SYSMGR_ROMCODEGRP_CTRL_WARMRSTCFGPINMUX (1 << 0) -#define SYSMGR_ROMCODEGRP_CTRL_WARMRSTCFGIO (1 << 1) -#define SYSMGR_ECC_OCRAM_EN (1 << 0) -#define SYSMGR_ECC_OCRAM_SERR (1 << 3) -#define SYSMGR_ECC_OCRAM_DERR (1 << 4) +#define SYSMGR_ROMCODEGRP_CTRL_WARMRSTCFGPINMUX BIT(0) +#define SYSMGR_ROMCODEGRP_CTRL_WARMRSTCFGIO BIT(1) +#define SYSMGR_ECC_OCRAM_EN BIT(0) +#define SYSMGR_ECC_OCRAM_SERR BIT(3) +#define SYSMGR_ECC_OCRAM_DERR BIT(4) #define SYSMGR_FPGAINTF_USEFPGA 0x1 -#define SYSMGR_FPGAINTF_SPIM0 (1 << 0) -#define SYSMGR_FPGAINTF_SPIM1 (1 << 1) -#define SYSMGR_FPGAINTF_EMAC0 (1 << 2) -#define SYSMGR_FPGAINTF_EMAC1 (1 << 3) -#define SYSMGR_FPGAINTF_NAND (1 << 4) -#define SYSMGR_FPGAINTF_SDMMC (1 << 5) - -#if defined(CONFIG_TARGET_SOCFPGA_GEN5) -#define SYSMGR_SDMMC_SMPLSEL_SHIFT 3 -#else -#define SYSMGR_SDMMC_SMPLSEL_SHIFT 4 -#endif +#define SYSMGR_FPGAINTF_SPIM0 BIT(0) +#define SYSMGR_FPGAINTF_SPIM1 BIT(1) +#define SYSMGR_FPGAINTF_EMAC0 BIT(2) +#define SYSMGR_FPGAINTF_EMAC1 BIT(3) +#define SYSMGR_FPGAINTF_NAND BIT(4) +#define SYSMGR_FPGAINTF_SDMMC BIT(5) #define SYSMGR_SDMMC_DRVSEL_SHIFT 0 @@ -146,4 +31,63 @@ struct socfpga_system_manager { #define SYSMGR_EMACGRP_CTRL_PHYSEL1_LSB 2 #define SYSMGR_EMACGRP_CTRL_PHYSEL_MASK 0x3 +/* For dedicated IO configuration */ +/* Voltage select enums */ +#define VOLTAGE_SEL_3V 0x0 +#define VOLTAGE_SEL_1P8V 0x1 +#define VOLTAGE_SEL_2P5V 0x2 + +/* Input buffer enable */ +#define INPUT_BUF_DISABLE 0 +#define INPUT_BUF_1P8V 1 +#define INPUT_BUF_2P5V3V 2 + +/* Weak pull up enable */ +#define WK_PU_DISABLE 0 +#define WK_PU_ENABLE 1 + +/* Pull up slew rate control */ +#define PU_SLW_RT_SLOW 0 +#define PU_SLW_RT_FAST 1 +#define PU_SLW_RT_DEFAULT PU_SLW_RT_SLOW + +/* Pull down slew rate control */ +#define PD_SLW_RT_SLOW 0 +#define PD_SLW_RT_FAST 1 +#define PD_SLW_RT_DEFAULT PD_SLW_RT_SLOW + +/* Drive strength control */ +#define PU_DRV_STRG_DEFAULT 0x10 +#define PD_DRV_STRG_DEFAULT 0x10 + +/* bit position */ +#define PD_DRV_STRG_LSB 0 +#define PD_SLW_RT_LSB 5 +#define PU_DRV_STRG_LSB 8 +#define PU_SLW_RT_LSB 13 +#define WK_PU_LSB 16 +#define INPUT_BUF_LSB 17 +#define BIAS_TRIM_LSB 19 +#define VOLTAGE_SEL_LSB 0 + +#define ALT_SYSMGR_NOC_H2F_SET_MSK BIT(0) +#define ALT_SYSMGR_NOC_LWH2F_SET_MSK BIT(4) +#define ALT_SYSMGR_NOC_F2H_SET_MSK BIT(8) +#define ALT_SYSMGR_NOC_F2SDR0_SET_MSK BIT(16) +#define ALT_SYSMGR_NOC_F2SDR1_SET_MSK BIT(20) +#define ALT_SYSMGR_NOC_F2SDR2_SET_MSK BIT(24) +#define ALT_SYSMGR_NOC_TMO_EN_SET_MSK BIT(0) + +#define ALT_SYSMGR_ECC_INTSTAT_SERR_OCRAM_SET_MSK BIT(1) +#define ALT_SYSMGR_ECC_INTSTAT_DERR_OCRAM_SET_MSK BIT(1) + +#if defined(CONFIG_TARGET_SOCFPGA_GEN5) +#include <asm/arch/system_manager_gen5.h> +#elif defined(CONFIG_TARGET_SOCFPGA_ARRIA10) +#include <asm/arch/system_manager_arria10.h> +#endif + +#define SYSMGR_GET_BOOTINFO_BSEL(bsel) \ + (((bsel) >> SYSMGR_BOOTINFO_BSEL_SHIFT) & 7) + #endif /* _SYSTEM_MANAGER_H_ */ diff --git a/arch/arm/mach-socfpga/include/mach/system_manager_arria10.h b/arch/arm/mach-socfpga/include/mach/system_manager_arria10.h new file mode 100644 index 0000000000..f235abab0b --- /dev/null +++ b/arch/arm/mach-socfpga/include/mach/system_manager_arria10.h @@ -0,0 +1,81 @@ +/* + * Copyright (C) 2016-2017 Intel Corporation <www.intel.com> + * + * SPDX-License-Identifier: GPL-2.0 + */ + +#ifndef _SYSTEM_MANAGER_ARRIA10_H_ +#define _SYSTEM_MANAGER_ARRIA10_H_ + +struct socfpga_system_manager { + u32 siliconid1; + u32 siliconid2; + u32 wddbg; + u32 bootinfo; + u32 mpu_ctrl_l2_ecc; + u32 _pad_0x14_0x1f[3]; + u32 dma; + u32 dma_periph; + u32 sdmmcgrp_ctrl; + u32 sdmmc_l3master; + u32 nand_bootstrap; + u32 nand_l3master; + u32 usb0_l3master; + u32 usb1_l3master; + u32 emac_global; + u32 emac[3]; + u32 _pad_0x50_0x5f[4]; + u32 fpgaintf_en_global; + u32 fpgaintf_en_0; + u32 fpgaintf_en_1; + u32 fpgaintf_en_2; + u32 fpgaintf_en_3; + u32 _pad_0x74_0x7f[3]; + u32 noc_addr_remap_value; + u32 noc_addr_remap_set; + u32 noc_addr_remap_clear; + u32 _pad_0x8c_0x8f; + u32 ecc_intmask_value; + u32 ecc_intmask_set; + u32 ecc_intmask_clr; + u32 ecc_intstatus_serr; + u32 ecc_intstatus_derr; + u32 mpu_status_l2_ecc; + u32 mpu_clear_l2_ecc; + u32 mpu_status_l1_parity; + u32 mpu_clear_l1_parity; + u32 mpu_set_l1_parity; + u32 _pad_0xb8_0xbf[2]; + u32 noc_timeout; + u32 noc_idlereq_set; + u32 noc_idlereq_clr; + u32 noc_idlereq_value; + u32 noc_idleack; + u32 noc_idlestatus; + u32 fpga2soc_ctrl; + u32 _pad_0xdc_0xff[9]; + u32 tsmc_tsel_0; + u32 tsmc_tsel_1; + u32 tsmc_tsel_2; + u32 tsmc_tsel_3; + u32 _pad_0x110_0x200[60]; + u32 romhw_ctrl; + u32 romcode_ctrl; + u32 romcode_cpu1startaddr; + u32 romcode_initswstate; + u32 romcode_initswlastld; + u32 _pad_0x214_0x217; + u32 warmram_enable; + u32 warmram_datastart; + u32 warmram_length; + u32 warmram_execution; + u32 warmram_crc; + u32 _pad_0x22c_0x22f; + u32 isw_handoff[8]; + u32 romcode_bootromswstate[8]; +}; + +#define SYSMGR_SDMMC_SMPLSEL_SHIFT 4 +#define SYSMGR_BOOTINFO_BSEL_SHIFT 12 + +#endif /* _SYSTEM_MANAGER_ARRIA10_H_ */ diff --git a/arch/arm/mach-socfpga/include/mach/system_manager_gen5.h b/arch/arm/mach-socfpga/include/mach/system_manager_gen5.h new file mode 100644 index 0000000000..285c1a29ad --- /dev/null +++ b/arch/arm/mach-socfpga/include/mach/system_manager_gen5.h @@ -0,0 +1,122 @@ +/* + * Copyright (C) 2013-2017 Altera Corporation <www.altera.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef _SYSTEM_MANAGER_GEN5_H_ +#define _SYSTEM_MANAGER_GEN5_H_ + +#ifndef __ASSEMBLY__ + +void sysmgr_pinmux_init(void); +void sysmgr_config_warmrstcfgio(int enable); + +void sysmgr_get_pinmux_table(const u8 **table, unsigned int *table_len); + +struct socfpga_system_manager { + /* System Manager Module */ + u32 siliconid1; /* 0x00 */ + u32 siliconid2; + u32 _pad_0x8_0xf[2]; + u32 wddbg; /* 0x10 */ + u32 bootinfo; + u32 hpsinfo; + u32 parityinj; + /* FPGA Interface Group */ + u32 fpgaintfgrp_gbl; /* 0x20 */ + u32 fpgaintfgrp_indiv; + u32 fpgaintfgrp_module; + u32 _pad_0x2c_0x2f; + /* Scan Manager Group */ + u32 scanmgrgrp_ctrl; /* 0x30 */ + u32 _pad_0x34_0x3f[3]; + /* Freeze Control Group */ + u32 frzctrl_vioctrl; /* 0x40 */ + u32 _pad_0x44_0x4f[3]; + u32 frzctrl_hioctrl; /* 0x50 */ + u32 frzctrl_src; + u32 frzctrl_hwctrl; + u32 _pad_0x5c_0x5f; + /* EMAC Group */ + u32 emacgrp_ctrl; /* 0x60 */ + u32 emacgrp_l3master; + u32 _pad_0x68_0x6f[2]; + /* DMA Controller Group */ + u32 dmagrp_ctrl; /* 0x70 */ + u32 dmagrp_persecurity; + u32 _pad_0x78_0x7f[2]; + /* Preloader (initial software) Group */ + u32 iswgrp_handoff[8]; /* 0x80 */ + u32 _pad_0xa0_0xbf[8]; /* 0xa0 */ + /* Boot ROM Code Register Group */ + u32 romcodegrp_ctrl; /* 0xc0 */ + u32 romcodegrp_cpu1startaddr; + u32 romcodegrp_initswstate; + u32 romcodegrp_initswlastld; + u32 romcodegrp_bootromswstate; /* 0xd0 */ + u32 __pad_0xd4_0xdf[3]; + /* Warm Boot from On-Chip RAM Group */ + u32 romcodegrp_warmramgrp_enable; /* 0xe0 */ + u32 romcodegrp_warmramgrp_datastart; + u32 romcodegrp_warmramgrp_length; + u32 romcodegrp_warmramgrp_execution; + u32 romcodegrp_warmramgrp_crc; /* 0xf0 */ + u32 __pad_0xf4_0xff[3]; + /* Boot ROM Hardware Register Group */ + u32 romhwgrp_ctrl; /* 0x100 */ + u32 _pad_0x104_0x107; + /* SDMMC Controller Group */ + u32 sdmmcgrp_ctrl; + u32 sdmmcgrp_l3master; + /* NAND Flash Controller Register Group */ + u32 nandgrp_bootstrap; /* 0x110 */ + u32 nandgrp_l3master; + /* USB Controller Group */ + u32 usbgrp_l3master; + u32 _pad_0x11c_0x13f[9]; + /* ECC Management Register Group */ + u32 eccgrp_l2; /* 0x140 */ + u32 eccgrp_ocram; + u32 eccgrp_usb0; + u32 eccgrp_usb1; + u32 eccgrp_emac0; /* 0x150 */ + u32 eccgrp_emac1; + u32 eccgrp_dma; + u32 eccgrp_can0; + u32 eccgrp_can1; /* 0x160 */ + u32 eccgrp_nand; + u32 eccgrp_qspi; + u32 eccgrp_sdmmc; + u32 _pad_0x170_0x3ff[164]; + /* Pin Mux Control Group */ + u32 emacio[20]; /* 0x400 */ + u32 flashio[12]; /* 0x450 */ + u32 generalio[28]; /* 0x480 */ + u32 _pad_0x4f0_0x4ff[4]; + u32 mixed1io[22]; /* 0x500 */ + u32 mixed2io[8]; /* 0x558 */ + u32 gplinmux[23]; /* 0x578 */ + u32 gplmux[71]; /* 0x5d4 */ + u32 nandusefpga; /* 0x6f0 */ + u32 _pad_0x6f4; + u32 rgmii1usefpga; /* 0x6f8 */ + u32 _pad_0x6fc_0x700[2]; + u32 i2c0usefpga; /* 0x704 */ + u32 sdmmcusefpga; /* 0x708 */ + u32 _pad_0x70c_0x710[2]; + u32 rgmii0usefpga; /* 0x714 */ + u32 _pad_0x718_0x720[3]; + u32 i2c3usefpga; /* 0x724 */ + u32 i2c2usefpga; /* 0x728 */ + u32 i2c1usefpga; /* 0x72c */ + u32 spim1usefpga; /* 0x730 */ + u32 _pad_0x734; + u32 spim0usefpga; /* 0x738 */ +}; +#endif + +#define SYSMGR_SDMMC_SMPLSEL_SHIFT 3 +#define SYSMGR_BOOTINFO_BSEL_SHIFT 0 + +#endif /* _SYSTEM_MANAGER_GEN5_H_ */ diff --git a/arch/arm/mach-socfpga/misc.c b/arch/arm/mach-socfpga/misc.c index dd6b53b24d..00eff90275 100644 --- a/arch/arm/mach-socfpga/misc.c +++ b/arch/arm/mach-socfpga/misc.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2012 Altera Corporation <www.altera.com> + * Copyright (C) 2012-2017 Altera Corporation <www.altera.com> * * SPDX-License-Identifier: GPL-2.0+ */ @@ -13,6 +13,7 @@ #include <miiphy.h> #include <netdev.h> #include <watchdog.h> +#include <asm/arch/misc.h> #include <asm/arch/reset_manager.h> #include <asm/arch/scan_manager.h> #include <asm/arch/system_manager.h> @@ -20,20 +21,21 @@ #include <asm/arch/scu.h> #include <asm/pl310.h> -#include <dt-bindings/reset/altr,rst-mgr.h> - DECLARE_GLOBAL_DATA_PTR; -static struct pl310_regs *const pl310 = +static const 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; + +struct bsel bsel_str[] = { + { "rsvd", "Reserved", }, + { "fpga", "FPGA (HPS2FPGA Bridge)", }, + { "nand", "NAND Flash (1.8V)", }, + { "nand", "NAND Flash (3.0V)", }, + { "sd", "SD/MMC External Transceiver (1.8V)", }, + { "sd", "SD/MMC Internal Transceiver (3.0V)", }, + { "qspi", "QSPI Flash (1.8V)", }, + { "qspi", "QSPI Flash (3.0V)", }, +}; int dram_init(void) { @@ -72,207 +74,6 @@ void v7_outer_cache_disable(void) clrbits_le32(&pl310->pl310_ctrl, L2X0_CTRL_EN); } -/* - * DesignWare Ethernet initialization - */ -#ifdef CONFIG_ETH_DESIGNWARE -static void dwmac_deassert_reset(const unsigned int of_reset_id, - const u32 phymode) -{ - u32 physhift, reset; - - if (of_reset_id == EMAC0_RESET) { - physhift = SYSMGR_EMACGRP_CTRL_PHYSEL0_LSB; - reset = SOCFPGA_RESET(EMAC0); - } else if (of_reset_id == EMAC1_RESET) { - physhift = SYSMGR_EMACGRP_CTRL_PHYSEL1_LSB; - reset = SOCFPGA_RESET(EMAC1); - } else { - printf("GMAC: Invalid reset ID (%i)!\n", of_reset_id); - return; - } - - /* 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, - phymode << physhift); - - /* Release the EMAC controller from reset */ - socfpga_per_reset(reset, 0); -} - -static u32 dwmac_phymode_to_modereg(const char *phymode, u32 *modereg) -{ - if (!phymode) - return -EINVAL; - - if (!strcmp(phymode, "mii") || !strcmp(phymode, "gmii")) { - *modereg = SYSMGR_EMACGRP_CTRL_PHYSEL_ENUM_GMII_MII; - return 0; - } - - if (!strcmp(phymode, "rgmii")) { - *modereg = SYSMGR_EMACGRP_CTRL_PHYSEL_ENUM_RGMII; - return 0; - } - - if (!strcmp(phymode, "rmii")) { - *modereg = SYSMGR_EMACGRP_CTRL_PHYSEL_ENUM_RMII; - return 0; - } - - return -EINVAL; -} - -static int socfpga_eth_reset(void) -{ - const void *fdt = gd->fdt_blob; - struct fdtdec_phandle_args args; - const char *phy_mode; - u32 phy_modereg; - int nodes[2]; /* Max. two GMACs */ - int ret, count; - int i, node; - - /* Put both GMACs into RESET state. */ - socfpga_per_reset(SOCFPGA_RESET(EMAC0), 1); - socfpga_per_reset(SOCFPGA_RESET(EMAC1), 1); - - count = fdtdec_find_aliases_for_id(fdt, "ethernet", - COMPAT_ALTERA_SOCFPGA_DWMAC, - nodes, ARRAY_SIZE(nodes)); - for (i = 0; i < count; i++) { - node = nodes[i]; - if (node <= 0) - continue; - - ret = fdtdec_parse_phandle_with_args(fdt, node, "resets", - "#reset-cells", 1, 0, - &args); - if (ret || (args.args_count != 1)) { - debug("GMAC%i: Failed to parse DT 'resets'!\n", i); - continue; - } - - phy_mode = fdt_getprop(fdt, node, "phy-mode", NULL); - ret = dwmac_phymode_to_modereg(phy_mode, &phy_modereg); - if (ret) { - debug("GMAC%i: Failed to parse DT 'phy-mode'!\n", i); - continue; - } - - dwmac_deassert_reset(args.args[0], phy_modereg); - } - - return 0; -} -#else -static int socfpga_eth_reset(void) -{ - return 0; -}; -#endif - -struct { - const char *mode; - const char *name; -} bsel_str[] = { - { "rsvd", "Reserved", }, - { "fpga", "FPGA (HPS2FPGA Bridge)", }, - { "nand", "NAND Flash (1.8V)", }, - { "nand", "NAND Flash (3.0V)", }, - { "sd", "SD/MMC External Transceiver (1.8V)", }, - { "sd", "SD/MMC Internal Transceiver (3.0V)", }, - { "qspi", "QSPI Flash (1.8V)", }, - { "qspi", "QSPI Flash (3.0V)", }, -}; - -static const struct { - const u16 pn; - const char *name; - const char *var; -} const socfpga_fpga_model[] = { - /* Cyclone V E */ - { 0x2b15, "Cyclone V, E/A2", "cv_e_a2" }, - { 0x2b05, "Cyclone V, E/A4", "cv_e_a4" }, - { 0x2b22, "Cyclone V, E/A5", "cv_e_a5" }, - { 0x2b13, "Cyclone V, E/A7", "cv_e_a7" }, - { 0x2b14, "Cyclone V, E/A9", "cv_e_a9" }, - /* Cyclone V GX/GT */ - { 0x2b01, "Cyclone V, GX/C3", "cv_gx_c3" }, - { 0x2b12, "Cyclone V, GX/C4", "cv_gx_c4" }, - { 0x2b02, "Cyclone V, GX/C5 or GT/D5", "cv_gx_c5" }, - { 0x2b03, "Cyclone V, GX/C7 or GT/D7", "cv_gx_c7" }, - { 0x2b04, "Cyclone V, GX/C9 or GT/D9", "cv_gx_c9" }, - /* Cyclone V SE/SX/ST */ - { 0x2d11, "Cyclone V, SE/A2 or SX/C2", "cv_se_a2" }, - { 0x2d01, "Cyclone V, SE/A4 or SX/C4", "cv_se_a4" }, - { 0x2d12, "Cyclone V, SE/A5 or SX/C5 or ST/D5", "cv_se_a5" }, - { 0x2d02, "Cyclone V, SE/A6 or SX/C6 or ST/D6", "cv_se_a6" }, - /* Arria V */ - { 0x2d03, "Arria V, D5", "av_d5" }, -}; - -static int socfpga_fpga_id(const bool print_id) -{ - const u32 altera_mi = 0x6e; - const u32 id = scan_mgr_get_fpga_id(); - - const u32 lsb = id & 0x00000001; - const u32 mi = (id >> 1) & 0x000007ff; - const u32 pn = (id >> 12) & 0x0000ffff; - const u32 version = (id >> 28) & 0x0000000f; - int i; - - if ((mi != altera_mi) || (lsb != 1)) { - printf("FPGA: Not Altera chip ID\n"); - return -EINVAL; - } - - for (i = 0; i < ARRAY_SIZE(socfpga_fpga_model); i++) - if (pn == socfpga_fpga_model[i].pn) - break; - - if (i == ARRAY_SIZE(socfpga_fpga_model)) { - printf("FPGA: Unknown Altera chip, ID 0x%08x\n", id); - return -EINVAL; - } - - if (print_id) - printf("FPGA: Altera %s, version 0x%01x\n", - socfpga_fpga_model[i].name, version); - return i; -} - -/* - * Print CPU information - */ -#if defined(CONFIG_DISPLAY_CPUINFO) -int print_cpuinfo(void) -{ - const u32 bsel = readl(&sysmgr_regs->bootinfo) & 0x7; - puts("CPU: Altera SoCFPGA Platform\n"); - socfpga_fpga_id(1); - printf("BOOT: %s\n", bsel_str[bsel].name); - return 0; -} -#endif - -#ifdef CONFIG_ARCH_MISC_INIT -int arch_misc_init(void) -{ - const u32 bsel = readl(&sysmgr_regs->bootinfo) & 0x7; - const int fpga_id = socfpga_fpga_id(0); - setenv("bootmode", bsel_str[bsel].mode); - if (fpga_id >= 0) - setenv("fpgatype", socfpga_fpga_model[fpga_id].var); - return socfpga_eth_reset(); -} -#endif - #if defined(CONFIG_SYS_CONSOLE_IS_IN_ENV) && \ defined(CONFIG_SYS_CONSOLE_OVERWRITE_ROUTINE) int overwrite_console(void) @@ -303,15 +104,13 @@ static Altera_desc altera_fpga[] = { }; /* add device descriptor to FPGA device table */ -static void socfpga_fpga_add(void) +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) @@ -337,135 +136,3 @@ int arch_cpu_init(void) 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; - - /* - * Write magic value into magic register to unlock support for - * issuing warm reset. The ancient kernel code expects this - * value to be written into the register by the bootloader, so - * to support that old code, we write it here instead of in the - * reset_cpu() function just before resetting the CPU. - */ - writel(0xae9efebc, &sysmgr_regs->romcodegrp_warmramgrp_enable); - - 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_per_reset(SOCFPGA_RESET(SPIM0), 0); - socfpga_per_reset(SOCFPGA_RESET(SPIM1), 0); -#endif - -#ifdef CONFIG_NAND_DENALI - socfpga_per_reset(SOCFPGA_RESET(NAND), 0); -#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/misc_arria10.c b/arch/arm/mach-socfpga/misc_arria10.c new file mode 100644 index 0000000000..9d751f6b2f --- /dev/null +++ b/arch/arm/mach-socfpga/misc_arria10.c @@ -0,0 +1,259 @@ +/* + * Copyright (C) 2016-2017 Intel Corporation + * + * SPDX-License-Identifier: GPL-2.0 + */ + +#include <altera.h> +#include <common.h> +#include <errno.h> +#include <fdtdec.h> +#include <miiphy.h> +#include <netdev.h> +#include <ns16550.h> +#include <watchdog.h> +#include <asm/arch/misc.h> +#include <asm/arch/pinmux.h> +#include <asm/arch/reset_manager.h> +#include <asm/arch/sdram_arria10.h> +#include <asm/arch/system_manager.h> +#include <asm/arch/nic301.h> +#include <asm/io.h> +#include <asm/pl310.h> + +#define PINMUX_UART0_TX_SHARED_IO_OFFSET_Q1_3 0x08 +#define PINMUX_UART0_TX_SHARED_IO_OFFSET_Q2_11 0x58 +#define PINMUX_UART0_TX_SHARED_IO_OFFSET_Q3_3 0x68 +#define PINMUX_UART1_TX_SHARED_IO_OFFSET_Q1_7 0x18 +#define PINMUX_UART1_TX_SHARED_IO_OFFSET_Q3_7 0x78 +#define PINMUX_UART1_TX_SHARED_IO_OFFSET_Q4_3 0x98 + +DECLARE_GLOBAL_DATA_PTR; + +#if defined(CONFIG_SPL_BUILD) +static struct pl310_regs *const pl310 = + (struct pl310_regs *)CONFIG_SYS_PL310_BASE; +static const struct socfpga_noc_fw_ocram *noc_fw_ocram_base = + (void *)SOCFPGA_SDR_FIREWALL_OCRAM_ADDRESS; +#endif + +static struct socfpga_system_manager *sysmgr_regs = + (struct socfpga_system_manager *)SOCFPGA_SYSMGR_ADDRESS; + +/* + * DesignWare Ethernet initialization + */ +#ifdef CONFIG_ETH_DESIGNWARE +void dwmac_deassert_reset(const unsigned int of_reset_id, + const u32 phymode) +{ + u32 reset; + + if (of_reset_id == EMAC0_RESET) { + reset = SOCFPGA_RESET(EMAC0); + } else if (of_reset_id == EMAC1_RESET) { + reset = SOCFPGA_RESET(EMAC1); + } else if (of_reset_id == EMAC2_RESET) { + reset = SOCFPGA_RESET(EMAC2); + } else { + printf("GMAC: Invalid reset ID (%i)!\n", of_reset_id); + return; + } + + clrsetbits_le32(&sysmgr_regs->emac[of_reset_id - EMAC0_RESET], + SYSMGR_EMACGRP_CTRL_PHYSEL_MASK, + phymode); + + /* Release the EMAC controller from reset */ + socfpga_per_reset(reset, 0); +} +#endif + +#if defined(CONFIG_SPL_BUILD) +/* ++ * This function initializes security policies to be consistent across ++ * all logic units in the Arria 10. ++ * ++ * The idea is to set all security policies to be normal, nonsecure ++ * for all units. ++ */ +static void initialize_security_policies(void) +{ + /* Put OCRAM in non-secure */ + writel(0x003f0000, &noc_fw_ocram_base->region0); + writel(0x1, &noc_fw_ocram_base->enable); +} + +int arch_early_init_r(void) +{ + initialize_security_policies(); + + /* Configure the L2 controller to make SDRAM start at 0 */ + writel(0x1, &pl310->pl310_addr_filter_start); + + /* assert reset to all except L4WD0 and L4TIMER0 */ + socfpga_per_reset_all(); + + /* configuring the clock based on handoff */ + /* TODO: Add call to cm_basic_init() */ + + /* Add device descriptor to FPGA device table */ + socfpga_fpga_add(); + return 0; +} +#else +int arch_early_init_r(void) +{ + return 0; +} +#endif + +/* + * This function looking the 1st encounter UART peripheral, + * and then return its offset of the dedicated/shared IO pin + * mux. offset value (zero and above). + */ +static int find_peripheral_uart(const void *blob, + int child, const char *node_name) +{ + int len; + fdt_addr_t base_addr = 0; + fdt_size_t size; + const u32 *cell; + u32 value, offset = 0; + + base_addr = fdtdec_get_addr_size(blob, child, "reg", &size); + if (base_addr != FDT_ADDR_T_NONE) { + cell = fdt_getprop(blob, child, "pinctrl-single,pins", + &len); + if (cell != NULL) { + for (; len > 0; len -= (2 * sizeof(u32))) { + offset = fdt32_to_cpu(*cell++); + value = fdt32_to_cpu(*cell++); + /* Found UART peripheral. */ + if (value == PINMUX_UART) + return offset; + } + } + } + return -EINVAL; +} + +/* + * This function looks up the 1st encounter UART peripheral, + * and then return its offset of the dedicated/shared IO pin + * mux. UART peripheral is found if the offset is not in negative + * value. + */ +static int is_peripheral_uart_true(const void *blob, + int node, const char *child_name) +{ + int child, len; + const char *node_name; + + child = fdt_first_subnode(blob, node); + + if (child < 0) + return -EINVAL; + + node_name = fdt_get_name(blob, child, &len); + + while (node_name) { + if (!strcmp(child_name, node_name)) + return find_peripheral_uart(blob, child, node_name); + + child = fdt_next_subnode(blob, child); + if (child < 0) + break; + + node_name = fdt_get_name(blob, child, &len); + } + + return -1; +} + +/* + * This function looking the 1st encounter UART dedicated IO peripheral, + * and then return based address of the 1st encounter UART dedicated + * IO peripheral. + */ +unsigned int dedicated_uart_com_port(const void *blob) +{ + int node; + + node = fdtdec_next_compatible(blob, 0, + COMPAT_ALTERA_SOCFPGA_PINCTRL_SINGLE); + if (node < 0) + return 0; + + if (is_peripheral_uart_true(blob, node, "dedicated") >= 0) + return SOCFPGA_UART1_ADDRESS; + + return 0; +} + +/* + * This function looking the 1st encounter UART shared IO peripheral, and then + * return based address of the 1st encounter UART shared IO peripheral. + */ +unsigned int shared_uart_com_port(const void *blob) +{ + int node, ret; + + node = fdtdec_next_compatible(blob, 0, + COMPAT_ALTERA_SOCFPGA_PINCTRL_SINGLE); + if (node < 0) + return 0; + + ret = is_peripheral_uart_true(blob, node, "shared"); + + if (ret == PINMUX_UART0_TX_SHARED_IO_OFFSET_Q1_3 || + ret == PINMUX_UART0_TX_SHARED_IO_OFFSET_Q2_11 || + ret == PINMUX_UART0_TX_SHARED_IO_OFFSET_Q3_3) + return SOCFPGA_UART0_ADDRESS; + else if (ret == PINMUX_UART1_TX_SHARED_IO_OFFSET_Q1_7 || + ret == PINMUX_UART1_TX_SHARED_IO_OFFSET_Q3_7 || + ret == PINMUX_UART1_TX_SHARED_IO_OFFSET_Q4_3) + return SOCFPGA_UART1_ADDRESS; + + return 0; +} + +/* + * This function looking the 1st encounter UART peripheral, and then return + * base address of the 1st encounter UART peripheral. + */ +unsigned int uart_com_port(const void *blob) +{ + unsigned int ret; + + ret = dedicated_uart_com_port(blob); + + if (ret) + return ret; + + return shared_uart_com_port(blob); +} + +/* + * Print CPU information + */ +#if defined(CONFIG_DISPLAY_CPUINFO) +int print_cpuinfo(void) +{ + const u32 bsel = + SYSMGR_GET_BOOTINFO_BSEL(readl(&sysmgr_regs->bootinfo)); + + puts("CPU: Altera SoCFPGA Arria 10\n"); + + printf("BOOT: %s\n", bsel_str[bsel].name); + return 0; +} +#endif + +#ifdef CONFIG_ARCH_MISC_INIT +int arch_misc_init(void) +{ + return 0; +} +#endif diff --git a/arch/arm/mach-socfpga/misc_gen5.c b/arch/arm/mach-socfpga/misc_gen5.c new file mode 100644 index 0000000000..49b26b3570 --- /dev/null +++ b/arch/arm/mach-socfpga/misc_gen5.c @@ -0,0 +1,359 @@ +/* + * Copyright (C) 2012-2017 Altera Corporation <www.altera.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <asm/io.h> +#include <errno.h> +#include <fdtdec.h> +#include <libfdt.h> +#include <altera.h> +#include <miiphy.h> +#include <netdev.h> +#include <watchdog.h> +#include <asm/arch/misc.h> +#include <asm/arch/reset_manager.h> +#include <asm/arch/scan_manager.h> +#include <asm/arch/sdram.h> +#include <asm/arch/system_manager.h> +#include <asm/arch/nic301.h> +#include <asm/arch/scu.h> +#include <asm/pl310.h> + +#include <dt-bindings/reset/altr,rst-mgr.h> + +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; +static struct socfpga_sdr_ctrl *sdr_ctrl = + (struct socfpga_sdr_ctrl *)SDR_CTRLGRP_ADDRESS; + +/* + * DesignWare Ethernet initialization + */ +#ifdef CONFIG_ETH_DESIGNWARE +void dwmac_deassert_reset(const unsigned int of_reset_id, + const u32 phymode) +{ + u32 physhift, reset; + + if (of_reset_id == EMAC0_RESET) { + physhift = SYSMGR_EMACGRP_CTRL_PHYSEL0_LSB; + reset = SOCFPGA_RESET(EMAC0); + } else if (of_reset_id == EMAC1_RESET) { + physhift = SYSMGR_EMACGRP_CTRL_PHYSEL1_LSB; + reset = SOCFPGA_RESET(EMAC1); + } else { + printf("GMAC: Invalid reset ID (%i)!\n", of_reset_id); + return; + } + + /* configure to PHY interface select choosed */ + clrsetbits_le32(&sysmgr_regs->emacgrp_ctrl, + SYSMGR_EMACGRP_CTRL_PHYSEL_MASK << physhift, + phymode << physhift); + + /* Release the EMAC controller from reset */ + socfpga_per_reset(reset, 0); +} + +static u32 dwmac_phymode_to_modereg(const char *phymode, u32 *modereg) +{ + if (!phymode) + return -EINVAL; + + if (!strcmp(phymode, "mii") || !strcmp(phymode, "gmii")) { + *modereg = SYSMGR_EMACGRP_CTRL_PHYSEL_ENUM_GMII_MII; + return 0; + } + + if (!strcmp(phymode, "rgmii")) { + *modereg = SYSMGR_EMACGRP_CTRL_PHYSEL_ENUM_RGMII; + return 0; + } + + if (!strcmp(phymode, "rmii")) { + *modereg = SYSMGR_EMACGRP_CTRL_PHYSEL_ENUM_RMII; + return 0; + } + + return -EINVAL; +} + +static int socfpga_eth_reset(void) +{ + const void *fdt = gd->fdt_blob; + struct fdtdec_phandle_args args; + const char *phy_mode; + u32 phy_modereg; + int nodes[2]; /* Max. two GMACs */ + int ret, count; + int i, node; + + /* Put both GMACs into RESET state. */ + socfpga_per_reset(SOCFPGA_RESET(EMAC0), 1); + socfpga_per_reset(SOCFPGA_RESET(EMAC1), 1); + + count = fdtdec_find_aliases_for_id(fdt, "ethernet", + COMPAT_ALTERA_SOCFPGA_DWMAC, + nodes, ARRAY_SIZE(nodes)); + for (i = 0; i < count; i++) { + node = nodes[i]; + if (node <= 0) + continue; + + ret = fdtdec_parse_phandle_with_args(fdt, node, "resets", + "#reset-cells", 1, 0, + &args); + if (ret || (args.args_count != 1)) { + debug("GMAC%i: Failed to parse DT 'resets'!\n", i); + continue; + } + + phy_mode = fdt_getprop(fdt, node, "phy-mode", NULL); + ret = dwmac_phymode_to_modereg(phy_mode, &phy_modereg); + if (ret) { + debug("GMAC%i: Failed to parse DT 'phy-mode'!\n", i); + continue; + } + + dwmac_deassert_reset(args.args[0], phy_modereg); + } + + return 0; +} +#else +static int socfpga_eth_reset(void) +{ + return 0; +}; +#endif + +static const struct { + const u16 pn; + const char *name; + const char *var; +} const socfpga_fpga_model[] = { + /* Cyclone V E */ + { 0x2b15, "Cyclone V, E/A2", "cv_e_a2" }, + { 0x2b05, "Cyclone V, E/A4", "cv_e_a4" }, + { 0x2b22, "Cyclone V, E/A5", "cv_e_a5" }, + { 0x2b13, "Cyclone V, E/A7", "cv_e_a7" }, + { 0x2b14, "Cyclone V, E/A9", "cv_e_a9" }, + /* Cyclone V GX/GT */ + { 0x2b01, "Cyclone V, GX/C3", "cv_gx_c3" }, + { 0x2b12, "Cyclone V, GX/C4", "cv_gx_c4" }, + { 0x2b02, "Cyclone V, GX/C5 or GT/D5", "cv_gx_c5" }, + { 0x2b03, "Cyclone V, GX/C7 or GT/D7", "cv_gx_c7" }, + { 0x2b04, "Cyclone V, GX/C9 or GT/D9", "cv_gx_c9" }, + /* Cyclone V SE/SX/ST */ + { 0x2d11, "Cyclone V, SE/A2 or SX/C2", "cv_se_a2" }, + { 0x2d01, "Cyclone V, SE/A4 or SX/C4", "cv_se_a4" }, + { 0x2d12, "Cyclone V, SE/A5 or SX/C5 or ST/D5", "cv_se_a5" }, + { 0x2d02, "Cyclone V, SE/A6 or SX/C6 or ST/D6", "cv_se_a6" }, + /* Arria V */ + { 0x2d03, "Arria V, D5", "av_d5" }, +}; + +static int socfpga_fpga_id(const bool print_id) +{ + const u32 altera_mi = 0x6e; + const u32 id = scan_mgr_get_fpga_id(); + + const u32 lsb = id & 0x00000001; + const u32 mi = (id >> 1) & 0x000007ff; + const u32 pn = (id >> 12) & 0x0000ffff; + const u32 version = (id >> 28) & 0x0000000f; + int i; + + if ((mi != altera_mi) || (lsb != 1)) { + printf("FPGA: Not Altera chip ID\n"); + return -EINVAL; + } + + for (i = 0; i < ARRAY_SIZE(socfpga_fpga_model); i++) + if (pn == socfpga_fpga_model[i].pn) + break; + + if (i == ARRAY_SIZE(socfpga_fpga_model)) { + printf("FPGA: Unknown Altera chip, ID 0x%08x\n", id); + return -EINVAL; + } + + if (print_id) + printf("FPGA: Altera %s, version 0x%01x\n", + socfpga_fpga_model[i].name, version); + return i; +} + +/* + * Print CPU information + */ +#if defined(CONFIG_DISPLAY_CPUINFO) +int print_cpuinfo(void) +{ + const u32 bsel = + SYSMGR_GET_BOOTINFO_BSEL(readl(&sysmgr_regs->bootinfo)); + + puts("CPU: Altera SoCFPGA Platform\n"); + socfpga_fpga_id(1); + + printf("BOOT: %s\n", bsel_str[bsel].name); + return 0; +} +#endif + +#ifdef CONFIG_ARCH_MISC_INIT +int arch_misc_init(void) +{ + const u32 bsel = readl(&sysmgr_regs->bootinfo) & 0x7; + const int fpga_id = socfpga_fpga_id(0); + setenv("bootmode", bsel_str[bsel].mode); + if (fpga_id >= 0) + setenv("fpgatype", socfpga_fpga_model[fpga_id].var); + return socfpga_eth_reset(); +} +#endif + +/* + * 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 u32 iswgrp_handoff[8]; + +int arch_early_init_r(void) +{ + int i; + + /* + * Write magic value into magic register to unlock support for + * issuing warm reset. The ancient kernel code expects this + * value to be written into the register by the bootloader, so + * to support that old code, we write it here instead of in the + * reset_cpu() function just before resetting the CPU. + */ + writel(0xae9efebc, &sysmgr_regs->romcodegrp_warmramgrp_enable); + + 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_per_reset(SOCFPGA_RESET(SPIM0), 0); + socfpga_per_reset(SOCFPGA_RESET(SPIM1), 0); +#endif + +#ifdef CONFIG_NAND_DENALI + socfpga_per_reset(SOCFPGA_RESET(NAND), 0); +#endif + + return 0; +} + +static void socfpga_sdram_apply_static_cfg(void) +{ + const u32 applymask = 0x8; + u32 val = readl(&sdr_ctrl->static_cfg) | 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"(&sdr_ctrl->static_cfg) : "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], &sdr_ctrl->fpgaport_rst); + 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, &sdr_ctrl->fpgaport_rst); + 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/pinmux_arria10.c b/arch/arm/mach-socfpga/pinmux_arria10.c new file mode 100644 index 0000000000..69d6a928a0 --- /dev/null +++ b/arch/arm/mach-socfpga/pinmux_arria10.c @@ -0,0 +1,96 @@ +/* + * Copyright (C) 2016-2017 Intel Corporation <www.intel.com> + * + * SPDX-License-Identifier: GPL-2.0 + */ + +#include <asm/arch/pinmux.h> +#include <asm/io.h> +#include <common.h> +#include <fdtdec.h> + +static int do_pinctr_pin(const void *blob, int child, const char *node_name) +{ + int len; + fdt_addr_t base_addr; + fdt_size_t size; + const u32 *cell; + u32 offset, value; + + base_addr = fdtdec_get_addr_size(blob, child, "reg", &size); + if (base_addr != FDT_ADDR_T_NONE) { + cell = fdt_getprop(blob, child, "pinctrl-single,pins", &len); + if (!cell || len <= 0) + return -EFAULT; + + debug("%p %d\n", cell, len); + for (; len > 0; len -= (2 * sizeof(u32))) { + offset = fdt32_to_cpu(*cell++); + value = fdt32_to_cpu(*cell++); + debug("<0x%x 0x%x>\n", offset, value); + writel(value, base_addr + offset); + } + return 0; + } + return -EFAULT; +} + +static int do_pinctrl_pins(const void *blob, int node, const char *child_name) +{ + int child, len; + const char *node_name; + + child = fdt_first_subnode(blob, node); + + if (child < 0) + return -EINVAL; + + node_name = fdt_get_name(blob, child, &len); + + while (node_name) { + if (!strcmp(child_name, node_name)) + return do_pinctr_pin(blob, child, node_name); + + child = fdt_next_subnode(blob, child); + + if (child < 0) + break; + + node_name = fdt_get_name(blob, child, &len); + } + + return -EFAULT; +} + +int config_dedicated_pins(const void *blob) +{ + int node; + + node = fdtdec_next_compatible(blob, 0, + COMPAT_ALTERA_SOCFPGA_PINCTRL_SINGLE); + if (node < 0) + return -EINVAL; + + if (do_pinctrl_pins(blob, node, "dedicated_cfg")) + return -EFAULT; + + if (do_pinctrl_pins(blob, node, "dedicated")) + return -EFAULT; + + return 0; +} + +int config_pins(const void *blob, const char *pin_grp) +{ + int node; + + node = fdtdec_next_compatible(blob, 0, + COMPAT_ALTERA_SOCFPGA_PINCTRL_SINGLE); + if (node < 0) + return -EINVAL; + + if (do_pinctrl_pins(blob, node, pin_grp)) + return -EFAULT; + + return 0; +} diff --git a/arch/arm/mach-socfpga/reset_manager.c b/arch/arm/mach-socfpga/reset_manager.c index b6beaa2f22..29438ed533 100644 --- a/arch/arm/mach-socfpga/reset_manager.c +++ b/arch/arm/mach-socfpga/reset_manager.c @@ -7,53 +7,12 @@ #include <common.h> #include <asm/io.h> -#include <asm/arch/fpga_manager.h> #include <asm/arch/reset_manager.h> -#include <asm/arch/system_manager.h> DECLARE_GLOBAL_DATA_PTR; static const struct socfpga_reset_manager *reset_manager_base = (void *)SOCFPGA_RSTMGR_ADDRESS; -static struct socfpga_system_manager *sysmgr_regs = - (struct socfpga_system_manager *)SOCFPGA_SYSMGR_ADDRESS; - -/* Assert or de-assert SoCFPGA reset manager reset. */ -void socfpga_per_reset(u32 reset, int set) -{ - const void *reg; - - if (RSTMGR_BANK(reset) == 0) - reg = &reset_manager_base->mpu_mod_reset; - else if (RSTMGR_BANK(reset) == 1) - reg = &reset_manager_base->per_mod_reset; - else if (RSTMGR_BANK(reset) == 2) - reg = &reset_manager_base->per2_mod_reset; - else if (RSTMGR_BANK(reset) == 3) - reg = &reset_manager_base->brg_mod_reset; - else if (RSTMGR_BANK(reset) == 4) - reg = &reset_manager_base->misc_mod_reset; - else /* Invalid reset register, do nothing */ - return; - - if (set) - setbits_le32(reg, 1 << RSTMGR_RESET(reset)); - else - clrbits_le32(reg, 1 << RSTMGR_RESET(reset)); -} - -/* - * Assert reset on every peripheral but L4WD0. - * Watchdog must be kept intact to prevent glitches - * and/or hangs. - */ -void socfpga_per_reset_all(void) -{ - const u32 l4wd0 = 1 << RSTMGR_RESET(SOCFPGA_RESET(L4WD0)); - - writel(~l4wd0, &reset_manager_base->per_mod_reset); - writel(0xffffffff, &reset_manager_base->per2_mod_reset); -} /* * Write the reset manager register to cause reset @@ -61,8 +20,8 @@ void socfpga_per_reset_all(void) void reset_cpu(ulong addr) { /* request a warm reset */ - writel((1 << RSTMGR_CTRL_SWWARMRSTREQ_LSB), - &reset_manager_base->ctrl); + writel(1 << RSTMGR_CTRL_SWWARMRSTREQ_LSB, + &reset_manager_base->ctrl); /* * infinite loop here as watchdog will trigger and reset * the processor @@ -70,51 +29,3 @@ void reset_cpu(ulong addr) 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 { - writel(0, &sysmgr_regs->iswgrp_handoff[0]); - writel(l3mask, &sysmgr_regs->iswgrp_handoff[1]); - - /* Check signal from FPGA. */ - if (!fpgamgr_test_fpga_ready()) { - /* FPGA not ready, do nothing. */ - printf("%s: FPGA not ready, aborting.\n", __func__); - return; - } - - /* brdmodrst */ - writel(0, &reset_manager_base->brg_mod_reset); - - /* Remap the bridges into memory map */ - writel(l3mask, SOCFPGA_L3REGS_ADDRESS); - } -} -#endif diff --git a/arch/arm/mach-socfpga/reset_manager_arria10.c b/arch/arm/mach-socfpga/reset_manager_arria10.c new file mode 100644 index 0000000000..d8c858c833 --- /dev/null +++ b/arch/arm/mach-socfpga/reset_manager_arria10.c @@ -0,0 +1,383 @@ +/* + * Copyright (C) 2016-2017 Intel Corporation + * + * SPDX-License-Identifier: GPL-2.0 + */ + +#include <asm/io.h> +#include <asm/arch/fpga_manager.h> +#include <asm/arch/misc.h> +#include <asm/arch/reset_manager.h> +#include <asm/arch/system_manager.h> +#include <common.h> +#include <errno.h> +#include <fdtdec.h> +#include <wait_bit.h> + +DECLARE_GLOBAL_DATA_PTR; + +static const struct socfpga_reset_manager *reset_manager_base = + (void *)SOCFPGA_RSTMGR_ADDRESS; +static const struct socfpga_system_manager *sysmgr_regs = + (struct socfpga_system_manager *)SOCFPGA_SYSMGR_ADDRESS; + +#define ECC_MASK (ALT_RSTMGR_PER0MODRST_EMACECC0_SET_MSK | \ + ALT_RSTMGR_PER0MODRST_EMACECC1_SET_MSK | \ + ALT_RSTMGR_PER0MODRST_EMACECC2_SET_MSK | \ + ALT_RSTMGR_PER0MODRST_NANDECC_SET_MSK | \ + ALT_RSTMGR_PER0MODRST_QSPIECC_SET_MSK | \ + ALT_RSTMGR_PER0MODRST_SDMMCECC_SET_MSK) + +void socfpga_reset_uart(int assert) +{ + unsigned int com_port; + + com_port = uart_com_port(gd->fdt_blob); + + if (com_port == SOCFPGA_UART1_ADDRESS) + socfpga_per_reset(SOCFPGA_RESET(UART1), assert); + else if (com_port == SOCFPGA_UART0_ADDRESS) + socfpga_per_reset(SOCFPGA_RESET(UART0), assert); +} + +static const u32 per0fpgamasks[] = { + ALT_RSTMGR_PER0MODRST_EMACECC0_SET_MSK | + ALT_RSTMGR_PER0MODRST_EMAC0_SET_MSK, + ALT_RSTMGR_PER0MODRST_EMACECC1_SET_MSK | + ALT_RSTMGR_PER0MODRST_EMAC1_SET_MSK, + ALT_RSTMGR_PER0MODRST_EMACECC2_SET_MSK | + ALT_RSTMGR_PER0MODRST_EMAC2_SET_MSK, + 0, /* i2c0 per1mod */ + 0, /* i2c1 per1mod */ + 0, /* i2c0_emac */ + 0, /* i2c1_emac */ + 0, /* i2c2_emac */ + ALT_RSTMGR_PER0MODRST_NANDECC_SET_MSK | + ALT_RSTMGR_PER0MODRST_NAND_SET_MSK, + ALT_RSTMGR_PER0MODRST_QSPIECC_SET_MSK | + ALT_RSTMGR_PER0MODRST_QSPI_SET_MSK, + ALT_RSTMGR_PER0MODRST_SDMMCECC_SET_MSK | + ALT_RSTMGR_PER0MODRST_SDMMC_SET_MSK, + ALT_RSTMGR_PER0MODRST_SPIM0_SET_MSK, + ALT_RSTMGR_PER0MODRST_SPIM1_SET_MSK, + ALT_RSTMGR_PER0MODRST_SPIS0_SET_MSK, + ALT_RSTMGR_PER0MODRST_SPIS1_SET_MSK, + 0, /* uart0 per1mod */ + 0, /* uart1 per1mod */ +}; + +static const u32 per1fpgamasks[] = { + 0, /* emac0 per0mod */ + 0, /* emac1 per0mod */ + 0, /* emac2 per0mod */ + ALT_RSTMGR_PER1MODRST_I2C0_SET_MSK, + ALT_RSTMGR_PER1MODRST_I2C1_SET_MSK, + ALT_RSTMGR_PER1MODRST_I2C2_SET_MSK, /* i2c0_emac */ + ALT_RSTMGR_PER1MODRST_I2C3_SET_MSK, /* i2c1_emac */ + ALT_RSTMGR_PER1MODRST_I2C4_SET_MSK, /* i2c2_emac */ + 0, /* nand per0mod */ + 0, /* qspi per0mod */ + 0, /* sdmmc per0mod */ + 0, /* spim0 per0mod */ + 0, /* spim1 per0mod */ + 0, /* spis0 per0mod */ + 0, /* spis1 per0mod */ + ALT_RSTMGR_PER1MODRST_UART0_SET_MSK, + ALT_RSTMGR_PER1MODRST_UART1_SET_MSK, +}; + +struct bridge_cfg { + int compat_id; + u32 mask_noc; + u32 mask_rstmgr; +}; + +static const struct bridge_cfg bridge_cfg_tbl[] = { + { + COMPAT_ALTERA_SOCFPGA_H2F_BRG, + ALT_SYSMGR_NOC_H2F_SET_MSK, + ALT_RSTMGR_BRGMODRST_H2F_SET_MSK, + }, + { + COMPAT_ALTERA_SOCFPGA_LWH2F_BRG, + ALT_SYSMGR_NOC_LWH2F_SET_MSK, + ALT_RSTMGR_BRGMODRST_LWH2F_SET_MSK, + }, + { + COMPAT_ALTERA_SOCFPGA_F2H_BRG, + ALT_SYSMGR_NOC_F2H_SET_MSK, + ALT_RSTMGR_BRGMODRST_F2H_SET_MSK, + }, + { + COMPAT_ALTERA_SOCFPGA_F2SDR0, + ALT_SYSMGR_NOC_F2SDR0_SET_MSK, + ALT_RSTMGR_BRGMODRST_F2SSDRAM0_SET_MSK, + }, + { + COMPAT_ALTERA_SOCFPGA_F2SDR1, + ALT_SYSMGR_NOC_F2SDR1_SET_MSK, + ALT_RSTMGR_BRGMODRST_F2SSDRAM1_SET_MSK, + }, + { + COMPAT_ALTERA_SOCFPGA_F2SDR2, + ALT_SYSMGR_NOC_F2SDR2_SET_MSK, + ALT_RSTMGR_BRGMODRST_F2SSDRAM2_SET_MSK, + }, +}; + +/* Disable the watchdog (toggle reset to watchdog) */ +void socfpga_watchdog_disable(void) +{ + /* assert reset for watchdog */ + setbits_le32(&reset_manager_base->per1modrst, + ALT_RSTMGR_PER1MODRST_WD0_SET_MSK); +} + +/* Release NOC ddr scheduler from reset */ +void socfpga_reset_deassert_noc_ddr_scheduler(void) +{ + clrbits_le32(&reset_manager_base->brgmodrst, + ALT_RSTMGR_BRGMODRST_DDRSCH_SET_MSK); +} + +/* Check whether Watchdog in reset state? */ +int socfpga_is_wdt_in_reset(void) +{ + u32 val; + + val = readl(&reset_manager_base->per1modrst); + val &= ALT_RSTMGR_PER1MODRST_WD0_SET_MSK; + + /* return 0x1 if watchdog in reset */ + return val; +} + +/* emacbase: base address of emac to enable/disable reset + * state: 0 - disable reset, !0 - enable reset + */ +void socfpga_emac_manage_reset(ulong emacbase, u32 state) +{ + ulong eccmask; + ulong emacmask; + + switch (emacbase) { + case SOCFPGA_EMAC0_ADDRESS: + eccmask = ALT_RSTMGR_PER0MODRST_EMACECC0_SET_MSK; + emacmask = ALT_RSTMGR_PER0MODRST_EMAC0_SET_MSK; + break; + case SOCFPGA_EMAC1_ADDRESS: + eccmask = ALT_RSTMGR_PER0MODRST_EMACECC1_SET_MSK; + emacmask = ALT_RSTMGR_PER0MODRST_EMAC1_SET_MSK; + break; + case SOCFPGA_EMAC2_ADDRESS: + eccmask = ALT_RSTMGR_PER0MODRST_EMACECC2_SET_MSK; + emacmask = ALT_RSTMGR_PER0MODRST_EMAC2_SET_MSK; + break; + default: + error("emac base address unexpected! %lx", emacbase); + hang(); + break; + } + + if (state) { + /* Enable ECC OCP first */ + setbits_le32(&reset_manager_base->per0modrst, eccmask); + setbits_le32(&reset_manager_base->per0modrst, emacmask); + } else { + /* Disable ECC OCP first */ + clrbits_le32(&reset_manager_base->per0modrst, emacmask); + clrbits_le32(&reset_manager_base->per0modrst, eccmask); + } +} + +static int get_bridge_init_val(const void *blob, int compat_id) +{ + int node; + + node = fdtdec_next_compatible(blob, 0, compat_id); + if (node < 0) + return 0; + + return fdtdec_get_uint(blob, node, "init-val", 0); +} + +/* Enable bridges (hps2fpga, lwhps2fpga, fpga2hps, fpga2sdram) per handoff */ +int socfpga_reset_deassert_bridges_handoff(void) +{ + u32 mask_noc = 0, mask_rstmgr = 0; + int i; + + for (i = 0; i < ARRAY_SIZE(bridge_cfg_tbl); i++) { + if (get_bridge_init_val(gd->fdt_blob, + bridge_cfg_tbl[i].compat_id)) { + mask_noc |= bridge_cfg_tbl[i].mask_noc; + mask_rstmgr |= bridge_cfg_tbl[i].mask_rstmgr; + } + } + + /* clear idle request to all bridges */ + setbits_le32(&sysmgr_regs->noc_idlereq_clr, mask_noc); + + /* Release bridges from reset state per handoff value */ + clrbits_le32(&reset_manager_base->brgmodrst, mask_rstmgr); + + /* Poll until all idleack to 0, timeout at 1000ms */ + return wait_for_bit(__func__, &sysmgr_regs->noc_idleack, mask_noc, + false, 1000, false); +} + +void socfpga_reset_assert_fpga_connected_peripherals(void) +{ + u32 mask0 = 0; + u32 mask1 = 0; + u32 fpga_pinux_addr = SOCFPGA_PINMUX_FPGA_INTERFACE_ADDRESS; + int i; + + for (i = 0; i < ARRAY_SIZE(per1fpgamasks); i++) { + if (readl(fpga_pinux_addr)) { + mask0 |= per0fpgamasks[i]; + mask1 |= per1fpgamasks[i]; + } + fpga_pinux_addr += sizeof(u32); + } + + setbits_le32(&reset_manager_base->per0modrst, mask0 & ECC_MASK); + setbits_le32(&reset_manager_base->per1modrst, mask1); + setbits_le32(&reset_manager_base->per0modrst, mask0); +} + +/* Release L4 OSC1 Watchdog Timer 0 from reset through reset manager */ +void socfpga_reset_deassert_osc1wd0(void) +{ + clrbits_le32(&reset_manager_base->per1modrst, + ALT_RSTMGR_PER1MODRST_WD0_SET_MSK); +} + +/* + * Assert or de-assert SoCFPGA reset manager reset. + */ +void socfpga_per_reset(u32 reset, int set) +{ + const u32 *reg; + u32 rstmgr_bank = RSTMGR_BANK(reset); + + switch (rstmgr_bank) { + case 0: + reg = &reset_manager_base->mpumodrst; + break; + case 1: + reg = &reset_manager_base->per0modrst; + break; + case 2: + reg = &reset_manager_base->per1modrst; + break; + case 3: + reg = &reset_manager_base->brgmodrst; + break; + case 4: + reg = &reset_manager_base->sysmodrst; + break; + + default: + return; + } + + if (set) + setbits_le32(reg, 1 << RSTMGR_RESET(reset)); + else + clrbits_le32(reg, 1 << RSTMGR_RESET(reset)); +} + +/* + * Assert reset on every peripheral but L4WD0. + * Watchdog must be kept intact to prevent glitches + * and/or hangs. + * For the Arria10, we disable all the peripherals except L4 watchdog0, + * L4 Timer 0, and ECC. + */ +void socfpga_per_reset_all(void) +{ + const u32 l4wd0 = (1 << RSTMGR_RESET(SOCFPGA_RESET(L4WD0)) | + (1 << RSTMGR_RESET(SOCFPGA_RESET(L4SYSTIMER0)))); + unsigned mask_ecc_ocp = + ALT_RSTMGR_PER0MODRST_EMACECC0_SET_MSK | + ALT_RSTMGR_PER0MODRST_EMACECC1_SET_MSK | + ALT_RSTMGR_PER0MODRST_EMACECC2_SET_MSK | + ALT_RSTMGR_PER0MODRST_USBECC0_SET_MSK | + ALT_RSTMGR_PER0MODRST_USBECC1_SET_MSK | + ALT_RSTMGR_PER0MODRST_NANDECC_SET_MSK | + ALT_RSTMGR_PER0MODRST_QSPIECC_SET_MSK | + ALT_RSTMGR_PER0MODRST_SDMMCECC_SET_MSK; + + /* disable all components except ECC_OCP, L4 Timer0 and L4 WD0 */ + writel(~l4wd0, &reset_manager_base->per1modrst); + setbits_le32(&reset_manager_base->per0modrst, ~mask_ecc_ocp); + + /* Finally disable the ECC_OCP */ + setbits_le32(&reset_manager_base->per0modrst, mask_ecc_ocp); +} + +#if defined(CONFIG_SOCFPGA_VIRTUAL_TARGET) +int socfpga_bridges_reset(int enable) +{ + /* For SoCFPGA-VT, this is NOP. */ + return 0; +} +#else +int socfpga_bridges_reset(int enable) +{ + int ret; + + /* Disable all the bridges (hps2fpga, lwhps2fpga, fpga2hps, + fpga2sdram) */ + /* set idle request to all bridges */ + writel(ALT_SYSMGR_NOC_H2F_SET_MSK | + ALT_SYSMGR_NOC_LWH2F_SET_MSK | + ALT_SYSMGR_NOC_F2H_SET_MSK | + ALT_SYSMGR_NOC_F2SDR0_SET_MSK | + ALT_SYSMGR_NOC_F2SDR1_SET_MSK | + ALT_SYSMGR_NOC_F2SDR2_SET_MSK, + &sysmgr_regs->noc_idlereq_set); + + /* Enable the NOC timeout */ + writel(ALT_SYSMGR_NOC_TMO_EN_SET_MSK, &sysmgr_regs->noc_timeout); + + /* Poll until all idleack to 1 */ + ret = wait_for_bit(__func__, &sysmgr_regs->noc_idleack, + ALT_SYSMGR_NOC_H2F_SET_MSK | + ALT_SYSMGR_NOC_LWH2F_SET_MSK | + ALT_SYSMGR_NOC_F2H_SET_MSK | + ALT_SYSMGR_NOC_F2SDR0_SET_MSK | + ALT_SYSMGR_NOC_F2SDR1_SET_MSK | + ALT_SYSMGR_NOC_F2SDR2_SET_MSK, + true, 10000, false); + if (ret) + return ret; + + /* Poll until all idlestatus to 1 */ + ret = wait_for_bit(__func__, &sysmgr_regs->noc_idlestatus, + ALT_SYSMGR_NOC_H2F_SET_MSK | + ALT_SYSMGR_NOC_LWH2F_SET_MSK | + ALT_SYSMGR_NOC_F2H_SET_MSK | + ALT_SYSMGR_NOC_F2SDR0_SET_MSK | + ALT_SYSMGR_NOC_F2SDR1_SET_MSK | + ALT_SYSMGR_NOC_F2SDR2_SET_MSK, + true, 10000, false); + if (ret) + return ret; + + /* Put all bridges (except NOR DDR scheduler) into reset state */ + setbits_le32(&reset_manager_base->brgmodrst, + (ALT_RSTMGR_BRGMODRST_H2F_SET_MSK | + ALT_RSTMGR_BRGMODRST_LWH2F_SET_MSK | + ALT_RSTMGR_BRGMODRST_F2H_SET_MSK | + ALT_RSTMGR_BRGMODRST_F2SSDRAM0_SET_MSK | + ALT_RSTMGR_BRGMODRST_F2SSDRAM1_SET_MSK | + ALT_RSTMGR_BRGMODRST_F2SSDRAM2_SET_MSK)); + + /* Disable NOC timeout */ + writel(0, &sysmgr_regs->noc_timeout); + + return 0; +} +#endif diff --git a/arch/arm/mach-socfpga/reset_manager_gen5.c b/arch/arm/mach-socfpga/reset_manager_gen5.c new file mode 100644 index 0000000000..aa88adb414 --- /dev/null +++ b/arch/arm/mach-socfpga/reset_manager_gen5.c @@ -0,0 +1,116 @@ +/* + * Copyright (C) 2013 Altera Corporation <www.altera.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + + +#include <common.h> +#include <asm/io.h> +#include <asm/arch/fpga_manager.h> +#include <asm/arch/reset_manager.h> +#include <asm/arch/system_manager.h> + +DECLARE_GLOBAL_DATA_PTR; + +static const struct socfpga_reset_manager *reset_manager_base = + (void *)SOCFPGA_RSTMGR_ADDRESS; +static const struct socfpga_system_manager *sysmgr_regs = + (struct socfpga_system_manager *)SOCFPGA_SYSMGR_ADDRESS; + +/* Assert or de-assert SoCFPGA reset manager reset. */ +void socfpga_per_reset(u32 reset, int set) +{ + const u32 *reg; + u32 rstmgr_bank = RSTMGR_BANK(reset); + + switch (rstmgr_bank) { + case 0: + reg = &reset_manager_base->mpu_mod_reset; + break; + case 1: + reg = &reset_manager_base->per_mod_reset; + break; + case 2: + reg = &reset_manager_base->per2_mod_reset; + break; + case 3: + reg = &reset_manager_base->brg_mod_reset; + break; + case 4: + reg = &reset_manager_base->misc_mod_reset; + break; + + default: + return; + } + + if (set) + setbits_le32(reg, 1 << RSTMGR_RESET(reset)); + else + clrbits_le32(reg, 1 << RSTMGR_RESET(reset)); +} + +/* + * Assert reset on every peripheral but L4WD0. + * Watchdog must be kept intact to prevent glitches + * and/or hangs. + */ +void socfpga_per_reset_all(void) +{ + const u32 l4wd0 = 1 << RSTMGR_RESET(SOCFPGA_RESET(L4WD0)); + + writel(~l4wd0, &reset_manager_base->per_mod_reset); + writel(0xffffffff, &reset_manager_base->per2_mod_reset); +} + +/* + * 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. */ + return; +} +#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 u32 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 { + writel(0, &sysmgr_regs->iswgrp_handoff[0]); + writel(l3mask, &sysmgr_regs->iswgrp_handoff[1]); + + /* Check signal from FPGA. */ + if (!fpgamgr_test_fpga_ready()) { + /* FPGA not ready, do nothing. We allow system to boot + * without FPGA ready. So, return 0 instead of error. */ + printf("%s: FPGA not ready, aborting.\n", __func__); + return; + } + + /* brdmodrst */ + writel(0, &reset_manager_base->brg_mod_reset); + + /* Remap the bridges into memory map */ + writel(l3mask, SOCFPGA_L3REGS_ADDRESS); + } + return; +} +#endif diff --git a/arch/arm/mach-socfpga/spl.c b/arch/arm/mach-socfpga/spl.c index fec4c7a991..71bae827a1 100644 --- a/arch/arm/mach-socfpga/spl.c +++ b/arch/arm/mach-socfpga/spl.c @@ -19,23 +19,32 @@ #include <asm/arch/sdram.h> #include <asm/arch/scu.h> #include <asm/arch/nic301.h> +#include <asm/sections.h> +#include <fdtdec.h> +#include <watchdog.h> +#if defined(CONFIG_TARGET_SOCFPGA_ARRIA10) +#include <asm/arch/pinmux.h> +#endif DECLARE_GLOBAL_DATA_PTR; +#if defined(CONFIG_TARGET_SOCFPGA_GEN5) static struct pl310_regs *const pl310 = (struct pl310_regs *)CONFIG_SYS_PL310_BASE; static struct scu_registers *scu_regs = (struct scu_registers *)SOCFPGA_MPUSCU_ADDRESS; static struct nic301_registers *nic301_regs = (struct nic301_registers *)SOCFPGA_L3REGS_ADDRESS; -static struct socfpga_system_manager *sysmgr_regs = +#endif + +static const struct socfpga_system_manager *sysmgr_regs = (struct socfpga_system_manager *)SOCFPGA_SYSMGR_ADDRESS; u32 spl_boot_device(void) { const u32 bsel = readl(&sysmgr_regs->bootinfo); - switch (bsel & 0x7) { + switch (SYSMGR_GET_BOOTINFO_BSEL(bsel)) { case 0x1: /* FPGA (HPS2FPGA Bridge) */ return BOOT_DEVICE_RAM; case 0x2: /* NAND Flash (1.8V) */ @@ -68,6 +77,7 @@ u32 spl_boot_mode(const u32 boot_device) } #endif +#if defined(CONFIG_TARGET_SOCFPGA_GEN5) static void socfpga_nic301_slave_ns(void) { writel(0x1, &nic301_regs->lwhps2fpgaregs); @@ -127,7 +137,8 @@ void board_init_f(ulong dummy) debug("Reconfigure Clock Manager\n"); /* reconfigure the PLLs */ - cm_basic_init(cm_default_cfg); + if (cm_basic_init(cm_default_cfg)) + hang(); /* Enable bootrom to configure IOs. */ sysmgr_config_warmrstcfgio(1); @@ -182,3 +193,42 @@ void board_init_f(ulong dummy) /* Configure simple malloc base pointer into RAM. */ gd->malloc_base = CONFIG_SYS_TEXT_BASE + (1024 * 1024); } +#elif defined(CONFIG_TARGET_SOCFPGA_ARRIA10) +void spl_board_init(void) +{ + /* configuring the clock based on handoff */ + cm_basic_init(gd->fdt_blob); + WATCHDOG_RESET(); + + config_dedicated_pins(gd->fdt_blob); + WATCHDOG_RESET(); + + /* Release UART from reset */ + socfpga_reset_uart(0); + + /* enable console uart printing */ + preloader_console_init(); +} + +void board_init_f(ulong dummy) +{ + /* + * Configure Clock Manager to use intosc clock instead external osc to + * ensure success watchdog operation. We do it as early as possible. + */ + cm_use_intosc(); + + socfpga_watchdog_disable(); + + arch_early_init_r(); + +#ifdef CONFIG_HW_WATCHDOG + /* release osc1 watchdog timer 0 from reset */ + socfpga_reset_deassert_osc1wd0(); + + /* reconfigure and enable the watchdog */ + hw_watchdog_init(); + WATCHDOG_RESET(); +#endif /* CONFIG_HW_WATCHDOG */ +} +#endif diff --git a/arch/arm/mach-socfpga/system_manager.c b/arch/arm/mach-socfpga/system_manager_gen5.c index 75a65f3e62..3588a570a7 100644 --- a/arch/arm/mach-socfpga/system_manager.c +++ b/arch/arm/mach-socfpga/system_manager_gen5.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2013 Altera Corporation <www.altera.com> + * Copyright (C) 2013-2017 Altera Corporation <www.altera.com> * * SPDX-License-Identifier: GPL-2.0+ */ @@ -21,7 +21,7 @@ static struct socfpga_system_manager *sysmgr_regs = */ static void populate_sysmgr_fpgaintf_module(void) { - uint32_t handoff_val = 0; + u32 handoff_val = 0; /* ISWGRP_HANDOFF_FPGAINTF */ writel(0, &sysmgr_regs->iswgrp_handoff[2]); @@ -56,7 +56,7 @@ static void populate_sysmgr_fpgaintf_module(void) */ void sysmgr_pinmux_init(void) { - uint32_t regs = (uint32_t)&sysmgr_regs->emacio[0]; + u32 regs = (u32)&sysmgr_regs->emacio[0]; const u8 *sys_mgr_init_table; unsigned int len; int i; |