From mboxrd@z Thu Jan 1 00:00:00 1970 From: Marek Vasut Date: Sat, 25 Feb 2017 22:28:30 +0100 Subject: [U-Boot] [PATCH 06/20] arm: socfpga: add reset driver support for Arria 10 In-Reply-To: <1487756858-16730-7-git-send-email-ley.foon.tan@intel.com> References: <1487756858-16730-1-git-send-email-ley.foon.tan@intel.com> <1487756858-16730-7-git-send-email-ley.foon.tan@intel.com> Message-ID: List-Id: MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit To: u-boot@lists.denx.de On 02/22/2017 10:47 AM, Ley Foon Tan wrote: > Add reset driver support for Arria 10. > > Signed-off-by: Tien Fong Chee > Signed-off-by: Ley Foon Tan > --- > arch/arm/mach-socfpga/Makefile | 2 + > arch/arm/mach-socfpga/include/mach/reset_manager.h | 4 +- > .../include/mach/reset_manager_arria10.h | 144 ++++++++ > arch/arm/mach-socfpga/reset_manager_arria10.c | 406 +++++++++++++++++++++ > include/dt-bindings/reset/altr,rst-mgr-a10.h | 103 ++++++ > 5 files changed, 658 insertions(+), 1 deletion(-) > create mode 100755 arch/arm/mach-socfpga/include/mach/reset_manager_arria10.h > create mode 100644 arch/arm/mach-socfpga/reset_manager_arria10.c > create mode 100644 include/dt-bindings/reset/altr,rst-mgr-a10.h > > diff --git a/arch/arm/mach-socfpga/Makefile b/arch/arm/mach-socfpga/Makefile > index e83da2e..d81f003 100644 > --- a/arch/arm/mach-socfpga/Makefile > +++ b/arch/arm/mach-socfpga/Makefile > @@ -10,6 +10,8 @@ > obj-y += misc.o timer.o reset_manager.o clock_manager.o \ > fpga_manager.o board.o > > +obj-$(CONFIG_TARGET_SOCFPGA_ARRIA10) += reset_manager_arria10.o > + > obj-$(CONFIG_SPL_BUILD) += spl.o freeze_controller.o > > # QTS-generated config file wrappers > diff --git a/arch/arm/mach-socfpga/include/mach/reset_manager.h b/arch/arm/mach-socfpga/include/mach/reset_manager.h > index 9e253bf..64526b6 100644 > --- a/arch/arm/mach-socfpga/include/mach/reset_manager.h > +++ b/arch/arm/mach-socfpga/include/mach/reset_manager.h > @@ -43,7 +43,9 @@ void socfpga_per_reset_all(void); > /* Create a human-readable reference to SoCFPGA reset. */ > #define SOCFPGA_RESET(_name) RSTMGR_##_name > > -#if defined(CONFIG_TARGET_SOCFPGA_GEN5) > +#if defined(CONFIG_TARGET_SOCFPGA_ARRIA10) > +#include > +#elif defined(CONFIG_TARGET_SOCFPGA_GEN5) You can use #elif defined(CONFIG_TARGET_SOCFPGA_ARRIA10) instead to keep this list sorted. > #include > #endif > > 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 100755 > index 0000000..2668a86 > --- /dev/null > +++ b/arch/arm/mach-socfpga/include/mach/reset_manager_arria10.h > @@ -0,0 +1,144 @@ > +/* > + * Copyright (C) 2012-2017 Altera Corporation > + * > + * SPDX-License-Identifier: GPL-2.0+ > + */ > + > +#ifndef _RESET_MANAGER_ARRIA10_H_ > +#define _RESET_MANAGER_ARRIA10_H_ Use #ifdef[space]FOO and #define[space]FOO > +void watchdog_disable(void); > +void reset_deassert_noc_ddr_scheduler(void); > +int is_wdt_in_reset(void); > +void emac_manage_reset(ulong emacbase, uint state); > +int reset_deassert_bridges_handoff(void); > +void reset_assert_fpga_connected_peripherals(void); > +void reset_deassert_osc1wd0(void); > +void reset_assert_uart(void); > +void reset_deassert_uart(void); [...] > +#endif /* _RESET_MANAGER_ARRIA10_H_ */ > 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 0000000..01156de > --- /dev/null > +++ b/arch/arm/mach-socfpga/reset_manager_arria10.c > @@ -0,0 +1,406 @@ > +/* > + * Copyright (C) 2016-2017 Intel Corporation > + * > + * SPDX-License-Identifier: GPL-2.0 > + */ > + > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > + > +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; Use the tabs consistently, one or two, but pick one. > +static int get_bridge_init_val(const void *blob, int compat_id); > + > +#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) MSK | \ Keep the spacing please. > +void reset_assert_uart(void) > +{ > + u32 mask = 0; > + unsigned int com_port; > + > + com_port = uart_com_port(gd->fdt_blob); What's this function , is it defined later in the patchset ? > + if (SOCFPGA_UART1_ADDRESS == com_port) > + mask |= ALT_RSTMGR_PER1MODRST_UART1_SET_MSK; > + else if (SOCFPGA_UART0_ADDRESS == com_port) > + mask |= ALT_RSTMGR_PER1MODRST_UART0_SET_MSK; Use if (foo == VALUE) please, not the other way around. Fix globally. > + setbits_le32(&reset_manager_base->per1modrst, mask); You can combine this with the deassert_uart() function and use clrsetbits instead to avoid duplication of the if () else () logic above. > +} > + > +void reset_deassert_uart(void) > +{ > + u32 mask = 0; > + unsigned int com_port; > + > + com_port = uart_com_port(gd->fdt_blob); > + > + if (SOCFPGA_UART1_ADDRESS == com_port) > + mask |= ALT_RSTMGR_PER1MODRST_UART1_SET_MSK; > + else if (SOCFPGA_UART0_ADDRESS == com_port) > + mask |= ALT_RSTMGR_PER1MODRST_UART0_SET_MSK; > + > + clrbits_le32(&reset_manager_base->per1modrst, mask); > +} [...] > +static int get_bridge_init_val(const void *blob, int compat_id) > +{ > + int rval = 0; > + int node; > + u32 val; > + > + node = fdtdec_next_compatible(blob, 0, compat_id); > + if (node >= 0) { Invert the conditions here to make the indent flat ... > + if (!fdtdec_get_int_array(blob, node, "init-val", &val, 1)) { > + if (val == 1) > + rval = val; > + } > + } > + return rval; > +} > + > +/* Enable bridges (hps2fpga, lwhps2fpga, fpga2hps, fpga2sdram) per handoff */ > +int reset_deassert_bridges_handoff(void) > +{ > + u32 mask_noc = 0, mask_rstmgr = 0; > + int i; > + unsigned start = get_timer(0); > + > + 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 */ > + while (readl(&sysmgr_regs->noc_idleack) & mask_noc) { wait_for_bit() ? > + if (get_timer(start) > 1000) { > + printf("Fail: noc_idleack = 0x%08x mask_noc = 0x%08x\n", > + readl(&sysmgr_regs->noc_idleack), > + mask_noc); > + return -ETIMEDOUT; > + } > + } > + return 0; > +} [...] -- Best regards, Marek Vasut