diff options
-rw-r--r-- | arch/arm/dts/socfpga_arria10.dtsi | 11 | ||||
-rw-r--r-- | arch/arm/dts/socfpga_arria10_socdk.dtsi | 13 | ||||
-rw-r--r-- | arch/arm/mach-socfpga/Makefile | 1 | ||||
-rw-r--r-- | arch/arm/mach-socfpga/board.c | 8 | ||||
-rw-r--r-- | arch/arm/mach-socfpga/clock_manager_arria10.c | 11 | ||||
-rw-r--r-- | arch/arm/mach-socfpga/include/mach/clock_manager_arria10.h | 3 | ||||
-rw-r--r-- | arch/arm/mach-socfpga/include/mach/misc.h | 5 | ||||
-rw-r--r-- | arch/arm/mach-socfpga/mailbox_s10.c | 15 | ||||
-rw-r--r-- | arch/arm/mach-socfpga/misc_arria10.c | 25 | ||||
-rw-r--r-- | arch/arm/mach-socfpga/spl_a10.c | 28 | ||||
-rw-r--r-- | arch/arm/mach-socfpga/spl_s10.c | 2 | ||||
-rw-r--r-- | configs/socfpga_arria10_defconfig | 3 | ||||
-rw-r--r-- | drivers/timer/Kconfig | 7 | ||||
-rw-r--r-- | drivers/timer/Makefile | 1 | ||||
-rw-r--r-- | drivers/timer/dw-apb-timer.c | 90 | ||||
-rw-r--r-- | include/configs/socfpga_common.h | 2 |
16 files changed, 158 insertions, 67 deletions
diff --git a/arch/arm/dts/socfpga_arria10.dtsi b/arch/arm/dts/socfpga_arria10.dtsi index ce000512ef..46f2fd4b69 100644 --- a/arch/arm/dts/socfpga_arria10.dtsi +++ b/arch/arm/dts/socfpga_arria10.dtsi @@ -21,6 +21,11 @@ #address-cells = <1>; #size-cells = <1>; + chosen { + tick-timer = &timer2; + u-boot,dm-pre-reloc; + }; + cpus { #address-cells = <1>; #size-cells = <0>; @@ -147,6 +152,7 @@ compatible = "altr,socfpga-a10-perip-clk"; clocks = <&main_pll>; div-reg = <0x144 0 11>; + u-boot,dm-pre-reloc; }; main_emaca_clk: main_emaca_clk@68 { @@ -236,6 +242,7 @@ compatible = "altr,socfpga-a10-perip-clk"; clocks = <&periph_pll>; div-reg = <0x144 16 11>; + u-boot,dm-pre-reloc; }; peri_emaca_clk: peri_emaca_clk@e8 { @@ -311,6 +318,7 @@ <&osc1>, <&cb_intosc_hs_div2_clk>, <&f2s_free_clk>; reg = <0x64>; + u-boot,dm-pre-reloc; }; s2f_user1_free_clk: s2f_user1_free_clk@104 { @@ -337,6 +345,7 @@ compatible = "altr,socfpga-a10-perip-clk"; clocks = <&noc_free_clk>; fixed-divider = <4>; + u-boot,dm-pre-reloc; }; l4_main_clk: l4_main_clk { @@ -664,6 +673,7 @@ interrupts = <0 99 4>; dma-mask = <0xffffffff>; clocks = <&nand_clk>; + resets = <&rst NAND_RESET>; status = "disabled"; }; @@ -800,6 +810,7 @@ reg = <0xffd00000 0x100>; clocks = <&l4_sys_free_clk>; clock-names = "timer"; + u-boot,dm-pre-reloc; }; timer3: timer3@ffd00100 { diff --git a/arch/arm/dts/socfpga_arria10_socdk.dtsi b/arch/arm/dts/socfpga_arria10_socdk.dtsi index 9160c20bd0..42e888548e 100644 --- a/arch/arm/dts/socfpga_arria10_socdk.dtsi +++ b/arch/arm/dts/socfpga_arria10_socdk.dtsi @@ -154,7 +154,6 @@ }; &uart1 { - clock-frequency = <50000000>; u-boot,dm-pre-reloc; status = "okay"; }; @@ -169,22 +168,10 @@ }; /* Clock available early */ -&main_noc_base_clk { - u-boot,dm-pre-reloc; -}; - &main_periph_ref_clk { u-boot,dm-pre-reloc; }; -&peri_noc_base_clk { - u-boot,dm-pre-reloc; -}; - -&noc_free_clk { - u-boot,dm-pre-reloc; -}; - &l4_mp_clk { u-boot,dm-pre-reloc; }; diff --git a/arch/arm/mach-socfpga/Makefile b/arch/arm/mach-socfpga/Makefile index 654999cdf6..e66720447f 100644 --- a/arch/arm/mach-socfpga/Makefile +++ b/arch/arm/mach-socfpga/Makefile @@ -26,7 +26,6 @@ obj-y += clock_manager_arria10.o obj-y += misc_arria10.o obj-y += pinmux_arria10.o obj-y += reset_manager_arria10.o -obj-y += timer.o endif ifdef CONFIG_TARGET_SOCFPGA_STRATIX10 diff --git a/arch/arm/mach-socfpga/board.c b/arch/arm/mach-socfpga/board.c index e8c7503fba..7c8c05cc31 100644 --- a/arch/arm/mach-socfpga/board.c +++ b/arch/arm/mach-socfpga/board.c @@ -43,14 +43,6 @@ int board_init(void) /* Address of boot parameters for ATAG (if ATAG is used) */ gd->bd->bi_boot_params = CONFIG_SYS_SDRAM_BASE + 0x100; -#if defined(CONFIG_TARGET_SOCFPGA_ARRIA10) - /* configuring the clock based on handoff */ - cm_basic_init(gd->fdt_blob); - - /* Add device descriptor to FPGA device table */ - socfpga_fpga_add(); -#endif - return 0; } diff --git a/arch/arm/mach-socfpga/clock_manager_arria10.c b/arch/arm/mach-socfpga/clock_manager_arria10.c index 1b4052cd37..334a79fd9c 100644 --- a/arch/arm/mach-socfpga/clock_manager_arria10.c +++ b/arch/arm/mach-socfpga/clock_manager_arria10.c @@ -11,8 +11,7 @@ #include <dm/device-internal.h> #include <asm/arch/clock_manager.h> -static const struct socfpga_clock_manager *clock_manager_base = - (struct socfpga_clock_manager *)SOCFPGA_CLKMGR_ADDRESS; +#ifdef CONFIG_SPL_BUILD static u32 eosc1_hz; static u32 cb_intosc_hz; @@ -232,6 +231,9 @@ static int of_get_clk_cfg(const void *blob, struct mainpll_cfg *main_cfg, return 0; } +static const struct socfpga_clock_manager *clock_manager_base = + (struct socfpga_clock_manager *)SOCFPGA_CLKMGR_ADDRESS; + /* calculate the intended main VCO frequency based on handoff */ static unsigned int cm_calc_handoff_main_vco_clk_hz (struct mainpll_cfg *main_cfg) @@ -897,7 +899,7 @@ static int cm_full_cfg(struct mainpll_cfg *main_cfg, struct perpll_cfg *per_cfg) return 0; } -void cm_use_intosc(void) +static void cm_use_intosc(void) { setbits_le32(&clock_manager_base->ctrl, CLKMGR_CLKMGR_CTL_BOOTCLK_INTOSC_SET_MSK); @@ -917,8 +919,11 @@ int cm_basic_init(const void *blob) if (rval) return rval; + cm_use_intosc(); + return cm_full_cfg(&main_cfg, &per_cfg); } +#endif static u32 cm_get_rate_dm(char *name) { diff --git a/arch/arm/mach-socfpga/include/mach/clock_manager_arria10.h b/arch/arm/mach-socfpga/include/mach/clock_manager_arria10.h index b3c8853aa3..de8c22540f 100644 --- a/arch/arm/mach-socfpga/include/mach/clock_manager_arria10.h +++ b/arch/arm/mach-socfpga/include/mach/clock_manager_arria10.h @@ -89,8 +89,9 @@ struct socfpga_clock_manager { struct socfpga_clock_manager_altera altera; }; -void cm_use_intosc(void); +#ifdef CONFIG_SPL_BUILD int cm_basic_init(const void *blob); +#endif unsigned int cm_get_l4_sp_clk_hz(void); unsigned long cm_get_mpu_clk_hz(void); diff --git a/arch/arm/mach-socfpga/include/mach/misc.h b/arch/arm/mach-socfpga/include/mach/misc.h index e7e08b72d2..4fc9570a04 100644 --- a/arch/arm/mach-socfpga/include/mach/misc.h +++ b/arch/arm/mach-socfpga/include/mach/misc.h @@ -25,6 +25,11 @@ static inline void socfpga_fpga_add(void) {} void socfpga_sdram_remap_zero(void); #endif +#ifdef CONFIG_TARGET_SOCFPGA_ARRIA10 +void socfpga_init_security_policies(void); +void socfpga_sdram_remap_zero(void); +#endif + void do_bridge_reset(int enable); #endif /* _MISC_H_ */ diff --git a/arch/arm/mach-socfpga/mailbox_s10.c b/arch/arm/mach-socfpga/mailbox_s10.c index cccd1a4404..0d906c3480 100644 --- a/arch/arm/mach-socfpga/mailbox_s10.c +++ b/arch/arm/mach-socfpga/mailbox_s10.c @@ -160,15 +160,15 @@ static __always_inline int mbox_send_cmd_common(u8 id, u32 cmd, u8 is_indirect, u32 buf_len; int ret; - ret = mbox_prepare_cmd_only(id, cmd, is_indirect, len, arg); - if (ret) - return ret; - if (urgent) { /* Read status because it is toggled */ status = MBOX_READL(MBOX_STATUS) & MBOX_STATUS_UA_MSK; - /* Send command as urgent command */ - MBOX_WRITEL(1, MBOX_URG); + /* Write urgent command to urgent register */ + MBOX_WRITEL(cmd, MBOX_URG); + } else { + ret = mbox_prepare_cmd_only(id, cmd, is_indirect, len, arg); + if (ret) + return ret; } /* write doorbell */ @@ -188,8 +188,7 @@ static __always_inline int mbox_send_cmd_common(u8 id, u32 cmd, u8 is_indirect, if (urgent) { u32 new_status = MBOX_READL(MBOX_STATUS); - /* urgent command doesn't have response */ - MBOX_WRITEL(0, MBOX_URG); + /* Urgent ACK is toggled */ if ((new_status & MBOX_STATUS_UA_MSK) ^ status) return 0; diff --git a/arch/arm/mach-socfpga/misc_arria10.c b/arch/arm/mach-socfpga/misc_arria10.c index 284e076ad6..f347ae857e 100644 --- a/arch/arm/mach-socfpga/misc_arria10.c +++ b/arch/arm/mach-socfpga/misc_arria10.c @@ -28,17 +28,14 @@ #define PINMUX_UART1_TX_SHARED_IO_OFFSET_Q3_7 0x78 #define PINMUX_UART1_TX_SHARED_IO_OFFSET_Q4_3 0x98 +static struct socfpga_system_manager *sysmgr_regs = + (struct socfpga_system_manager *)SOCFPGA_SYSMGR_ADDRESS; #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; -#if defined(CONFIG_SPL_BUILD) /* + * This function initializes security policies to be consistent across + * all logic units in the Arria 10. @@ -46,7 +43,7 @@ static struct socfpga_system_manager *sysmgr_regs = + * The idea is to set all security policies to be normal, nonsecure + * for all units. + */ -static void initialize_security_policies(void) +void socfpga_init_security_policies(void) { /* Put OCRAM in non-secure */ writel(0x003f0000, &noc_fw_ocram_base->region0); @@ -66,24 +63,20 @@ static void initialize_security_policies(void) writel(0x0007FFFF, &sysmgr_regs->ecc_intmask_set); } -int arch_early_init_r(void) +void socfpga_sdram_remap_zero(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(); - - return 0; } -#else +#endif + int arch_early_init_r(void) { + /* Add device descriptor to FPGA device table */ + socfpga_fpga_add(); + return 0; } -#endif /* * Print CPU information diff --git a/arch/arm/mach-socfpga/spl_a10.c b/arch/arm/mach-socfpga/spl_a10.c index 7d35e9daa8..3ea64f7e94 100644 --- a/arch/arm/mach-socfpga/spl_a10.c +++ b/arch/arm/mach-socfpga/spl_a10.c @@ -68,33 +68,26 @@ u32 spl_boot_mode(const u32 boot_device) 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(); - /* enable console uart printing */ preloader_console_init(); - WATCHDOG_RESET(); - /* Add device descriptor to FPGA device table */ - socfpga_fpga_add(); + arch_early_init_r(); } 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_init_security_policies(); + socfpga_sdram_remap_zero(); + /* Assert reset to all except L4WD0 and L4TIMER0 */ + socfpga_per_reset_all(); socfpga_watchdog_disable(); - arch_early_init_r(); + spl_early_init(); + + /* Configure the clock based on handoff */ + cm_basic_init(gd->fdt_blob); #ifdef CONFIG_HW_WATCHDOG /* release osc1 watchdog timer 0 from reset */ @@ -104,4 +97,7 @@ void board_init_f(ulong dummy) hw_watchdog_init(); WATCHDOG_RESET(); #endif /* CONFIG_HW_WATCHDOG */ + + config_dedicated_pins(gd->fdt_blob); + WATCHDOG_RESET(); } diff --git a/arch/arm/mach-socfpga/spl_s10.c b/arch/arm/mach-socfpga/spl_s10.c index 69d6e919aa..cc5dc4f3d7 100644 --- a/arch/arm/mach-socfpga/spl_s10.c +++ b/arch/arm/mach-socfpga/spl_s10.c @@ -136,7 +136,7 @@ void board_init_f(ulong dummy) socfpga_per_reset(SOCFPGA_RESET(OSC1TIMER0), 0); timer_init(); - populate_sysmgr_pinmux(); + sysmgr_pinmux_init(); /* configuring the HPS clocks */ cm_basic_init(cm_default_cfg); diff --git a/configs/socfpga_arria10_defconfig b/configs/socfpga_arria10_defconfig index 4b0d47489a..a504035547 100644 --- a/configs/socfpga_arria10_defconfig +++ b/configs/socfpga_arria10_defconfig @@ -39,4 +39,7 @@ CONFIG_DM_ETH=y CONFIG_ETH_DESIGNWARE=y CONFIG_MII=y CONFIG_SPI=y +CONFIG_TIMER=y +CONFIG_SPL_TIMER=y +CONFIG_DESIGNWARE_APB_TIMER=y CONFIG_USE_TINY_PRINTF=y diff --git a/drivers/timer/Kconfig b/drivers/timer/Kconfig index 8a31397553..5ab6749193 100644 --- a/drivers/timer/Kconfig +++ b/drivers/timer/Kconfig @@ -59,6 +59,13 @@ config CADENCE_TTC_TIMER Enables support for the cadence ttc driver. This driver is present on Xilinx Zynq and ZynqMP SoCs. +config DESIGNWARE_APB_TIMER + bool "Designware APB Timer" + depends on TIMER + help + Enables support for the Designware APB Timer driver. This timer is + present on Altera SoCFPGA SoCs. + config SANDBOX_TIMER bool "Sandbox timer support" depends on SANDBOX && TIMER diff --git a/drivers/timer/Makefile b/drivers/timer/Makefile index ee2fcb1fa7..0c8a62767a 100644 --- a/drivers/timer/Makefile +++ b/drivers/timer/Makefile @@ -5,6 +5,7 @@ obj-y += timer-uclass.o obj-$(CONFIG_ALTERA_TIMER) += altera_timer.o obj-$(CONFIG_CADENCE_TTC_TIMER) += cadence-ttc.o +obj-$(CONFIG_DESIGNWARE_APB_TIMER) += dw-apb-timer.o obj-$(CONFIG_SANDBOX_TIMER) += sandbox_timer.o obj-$(CONFIG_X86_TSC_TIMER) += tsc_timer.o obj-$(CONFIG_OMAP_TIMER) += omap-timer.o diff --git a/drivers/timer/dw-apb-timer.c b/drivers/timer/dw-apb-timer.c new file mode 100644 index 0000000000..031f429acb --- /dev/null +++ b/drivers/timer/dw-apb-timer.c @@ -0,0 +1,90 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Designware APB Timer driver + * + * Copyright (C) 2018 Marek Vasut <marex@denx.de> + */ + +#include <common.h> +#include <dm.h> +#include <clk.h> +#include <timer.h> + +#include <asm/io.h> +#include <asm/arch/timer.h> + +#define DW_APB_LOAD_VAL 0x0 +#define DW_APB_CURR_VAL 0x4 +#define DW_APB_CTRL 0x8 + +DECLARE_GLOBAL_DATA_PTR; + +struct dw_apb_timer_priv { + fdt_addr_t regs; +}; + +static int dw_apb_timer_get_count(struct udevice *dev, u64 *count) +{ + struct dw_apb_timer_priv *priv = dev_get_priv(dev); + + /* + * The DW APB counter counts down, but this function + * requires the count to be incrementing. Invert the + * result. + */ + *count = ~readl(priv->regs + DW_APB_CURR_VAL); + + return 0; +} + +static int dw_apb_timer_probe(struct udevice *dev) +{ + struct timer_dev_priv *uc_priv = dev_get_uclass_priv(dev); + struct dw_apb_timer_priv *priv = dev_get_priv(dev); + struct clk clk; + int ret; + + ret = clk_get_by_index(dev, 0, &clk); + if (ret) + return ret; + + uc_priv->clock_rate = clk_get_rate(&clk); + + clk_free(&clk); + + /* init timer */ + writel(0xffffffff, priv->regs + DW_APB_LOAD_VAL); + writel(0xffffffff, priv->regs + DW_APB_CURR_VAL); + setbits_le32(priv->regs + DW_APB_CTRL, 0x3); + + return 0; +} + +static int dw_apb_timer_ofdata_to_platdata(struct udevice *dev) +{ + struct dw_apb_timer_priv *priv = dev_get_priv(dev); + + priv->regs = dev_read_addr(dev); + + return 0; +} + +static const struct timer_ops dw_apb_timer_ops = { + .get_count = dw_apb_timer_get_count, +}; + +static const struct udevice_id dw_apb_timer_ids[] = { + { .compatible = "snps,dw-apb-timer" }, + {} +}; + +U_BOOT_DRIVER(dw_apb_timer) = { + .name = "dw_apb_timer", + .id = UCLASS_TIMER, + .ops = &dw_apb_timer_ops, + .probe = dw_apb_timer_probe, + .flags = DM_FLAG_PRE_RELOC, + .of_match = dw_apb_timer_ids, + .ofdata_to_platdata = dw_apb_timer_ofdata_to_platdata, + .priv_auto_alloc_size = sizeof(struct dw_apb_timer_priv), +}; diff --git a/include/configs/socfpga_common.h b/include/configs/socfpga_common.h index 440a918fc7..2330143cf1 100644 --- a/include/configs/socfpga_common.h +++ b/include/configs/socfpga_common.h @@ -86,11 +86,13 @@ /* * L4 OSC1 Timer 0 */ +#ifndef CONFIG_TIMER /* This timer uses eosc1, whose clock frequency is fixed at any condition. */ #define CONFIG_SYS_TIMERBASE SOCFPGA_OSC1TIMER0_ADDRESS #define CONFIG_SYS_TIMER_COUNTS_DOWN #define CONFIG_SYS_TIMER_COUNTER (CONFIG_SYS_TIMERBASE + 0x4) #define CONFIG_SYS_TIMER_RATE 25000000 +#endif /* * L4 Watchdog |