Message ID | 1491384774-49629-7-git-send-email-ley.foon.tan@intel.com |
---|---|
State | Superseded |
Delegated to: | Marek Vasut |
Headers | show |
On Wed, Apr 5, 2017 at 4:32 AM, Ley Foon Tan <ley.foon.tan@intel.com> wrote: > Add reset driver support for Arria 10. > > Signed-off-by: Tien Fong Chee <tien.fong.chee@intel.com> > Signed-off-by: Ley Foon Tan <ley.foon.tan@intel.com> > --- > arch/arm/mach-socfpga/Makefile | 2 + > arch/arm/mach-socfpga/include/mach/reset_manager.h | 2 + > .../include/mach/reset_manager_arria10.h | 144 ++++++++ > arch/arm/mach-socfpga/reset_manager_arria10.c | 389 +++++++++++++++++++++ > include/dt-bindings/reset/altr,rst-mgr-a10.h | 103 ++++++ > 5 files changed, 640 insertions(+) > create mode 100644 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 c99efa7..a0d611b 100644 > --- a/arch/arm/mach-socfpga/include/mach/reset_manager.h > +++ b/arch/arm/mach-socfpga/include/mach/reset_manager.h > @@ -45,6 +45,8 @@ void socfpga_per_reset_all(void); > > #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 0000000..878c1b6 > --- /dev/null > +++ b/arch/arm/mach-socfpga/include/mach/reset_manager_arria10.h > @@ -0,0 +1,144 @@ > +/* > + * Copyright (C) 2016-2017 Intel Corporation > + * > + * SPDX-License-Identifier: GPL-2.0 > + */ > + > +#ifndef _RESET_MANAGER_ARRIA10_H_ > +#define _RESET_MANAGER_ARRIA10_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); > + > +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) Are the above MACRO's still needed if we're using the dt-bindings? > + > +#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/reset_manager_arria10.c b/arch/arm/mach-socfpga/reset_manager_arria10.c > new file mode 100644 > index 0000000..e24f2f2 > --- /dev/null > +++ b/arch/arm/mach-socfpga/reset_manager_arria10.c > @@ -0,0 +1,389 @@ > +/* > + * 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) > +{ > + u32 mask = 0; > + unsigned int com_port; > + > + com_port = uart_com_port(gd->fdt_blob); > + > + if (com_port == SOCFPGA_UART1_ADDRESS) > + mask |= ALT_RSTMGR_PER1MODRST_UART1_SET_MSK; > + else if (com_port == SOCFPGA_UART0_ADDRESS) > + mask |= ALT_RSTMGR_PER1MODRST_UART0_SET_MSK; > + > + if (assert) > + setbits_le32(&reset_manager_base->per1modrst, mask); > + else > + clrbits_le32(&reset_manager_base->per1modrst, mask); > +} Why do you need the above function? Couldn't you just used: socfpga_per_reset(SOCFPGA_RESET(UART<#>)); > + > +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/include/dt-bindings/reset/altr,rst-mgr-a10.h b/include/dt-bindings/reset/altr,rst-mgr-a10.h > new file mode 100644 > index 0000000..99875de > --- /dev/null > +++ b/include/dt-bindings/reset/altr,rst-mgr-a10.h > @@ -0,0 +1,103 @@ > +/* > + * Copyright (C) 2016-2017 Intel Corporation > + * > + * SPDX-License-Identifier: GPL-2.0 > + */ Hmm...did you by chance copy this file from the Linux kernel? It looks awfully the same, and if so, please keep the Copyright from the original. Dinh
On Fri, Apr 7, 2017 at 3:37 AM, Dinh Nguyen <dinh.linux@gmail.com> wrote: > On Wed, Apr 5, 2017 at 4:32 AM, Ley Foon Tan <ley.foon.tan@intel.com> wrote: >> Add reset driver support for Arria 10. >> >> Signed-off-by: Tien Fong Chee <tien.fong.chee@intel.com> >> Signed-off-by: Ley Foon Tan <ley.foon.tan@intel.com> >> --- >> arch/arm/mach-socfpga/Makefile | 2 + >> arch/arm/mach-socfpga/include/mach/reset_manager.h | 2 + >> .../include/mach/reset_manager_arria10.h | 144 ++++++++ >> arch/arm/mach-socfpga/reset_manager_arria10.c | 389 +++++++++++++++++++++ >> include/dt-bindings/reset/altr,rst-mgr-a10.h | 103 ++++++ >> 5 files changed, 640 insertions(+) >> create mode 100644 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 c99efa7..a0d611b 100644 >> --- a/arch/arm/mach-socfpga/include/mach/reset_manager.h >> +++ b/arch/arm/mach-socfpga/include/mach/reset_manager.h >> @@ -45,6 +45,8 @@ void socfpga_per_reset_all(void); >> >> #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 0000000..878c1b6 >> --- /dev/null >> +++ b/arch/arm/mach-socfpga/include/mach/reset_manager_arria10.h >> @@ -0,0 +1,144 @@ >> +/* >> + * Copyright (C) 2016-2017 Intel Corporation >> + * >> + * SPDX-License-Identifier: GPL-2.0 >> + */ >> + >> +#ifndef _RESET_MANAGER_ARRIA10_H_ >> +#define _RESET_MANAGER_ARRIA10_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); >> + >> +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) > > Are the above MACRO's still needed if we're using the dt-bindings? We still need them now. The reset function framework also used for Gen5, so it is massive change if we change it now. But, we can consider to convert them later. > >> + >> +#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/reset_manager_arria10.c b/arch/arm/mach-socfpga/reset_manager_arria10.c >> new file mode 100644 >> index 0000000..e24f2f2 >> --- /dev/null >> +++ b/arch/arm/mach-socfpga/reset_manager_arria10.c >> @@ -0,0 +1,389 @@ >> +/* >> + * 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) >> +{ >> + u32 mask = 0; >> + unsigned int com_port; >> + >> + com_port = uart_com_port(gd->fdt_blob); >> + >> + if (com_port == SOCFPGA_UART1_ADDRESS) >> + mask |= ALT_RSTMGR_PER1MODRST_UART1_SET_MSK; >> + else if (com_port == SOCFPGA_UART0_ADDRESS) >> + mask |= ALT_RSTMGR_PER1MODRST_UART0_SET_MSK; >> + >> + if (assert) >> + setbits_le32(&reset_manager_base->per1modrst, mask); >> + else >> + clrbits_le32(&reset_manager_base->per1modrst, mask); >> +} > > Why do you need the above function? Couldn't you just used: > > socfpga_per_reset(SOCFPGA_RESET(UART<#>)); Okay, will refactor this function to something like this: 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/include/dt-bindings/reset/altr,rst-mgr-a10.h b/include/dt-bindings/reset/altr,rst-mgr-a10.h >> new file mode 100644 >> index 0000000..99875de >> --- /dev/null >> +++ b/include/dt-bindings/reset/altr,rst-mgr-a10.h >> @@ -0,0 +1,103 @@ >> +/* >> + * Copyright (C) 2016-2017 Intel Corporation >> + * >> + * SPDX-License-Identifier: GPL-2.0 >> + */ > > Hmm...did you by chance copy this file from the Linux kernel? It looks awfully > the same, and if so, please keep the Copyright from the original. > Okay, will copy its original copyright header. Regards Ley Foon
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 c99efa7..a0d611b 100644 --- a/arch/arm/mach-socfpga/include/mach/reset_manager.h +++ b/arch/arm/mach-socfpga/include/mach/reset_manager.h @@ -45,6 +45,8 @@ void socfpga_per_reset_all(void); #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 0000000..878c1b6 --- /dev/null +++ b/arch/arm/mach-socfpga/include/mach/reset_manager_arria10.h @@ -0,0 +1,144 @@ +/* + * Copyright (C) 2016-2017 Intel Corporation + * + * SPDX-License-Identifier: GPL-2.0 + */ + +#ifndef _RESET_MANAGER_ARRIA10_H_ +#define _RESET_MANAGER_ARRIA10_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); + +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/reset_manager_arria10.c b/arch/arm/mach-socfpga/reset_manager_arria10.c new file mode 100644 index 0000000..e24f2f2 --- /dev/null +++ b/arch/arm/mach-socfpga/reset_manager_arria10.c @@ -0,0 +1,389 @@ +/* + * 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) +{ + u32 mask = 0; + unsigned int com_port; + + com_port = uart_com_port(gd->fdt_blob); + + if (com_port == SOCFPGA_UART1_ADDRESS) + mask |= ALT_RSTMGR_PER1MODRST_UART1_SET_MSK; + else if (com_port == SOCFPGA_UART0_ADDRESS) + mask |= ALT_RSTMGR_PER1MODRST_UART0_SET_MSK; + + if (assert) + setbits_le32(&reset_manager_base->per1modrst, mask); + else + clrbits_le32(&reset_manager_base->per1modrst, mask); +} + +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/include/dt-bindings/reset/altr,rst-mgr-a10.h b/include/dt-bindings/reset/altr,rst-mgr-a10.h new file mode 100644 index 0000000..99875de --- /dev/null +++ b/include/dt-bindings/reset/altr,rst-mgr-a10.h @@ -0,0 +1,103 @@ +/* + * Copyright (C) 2016-2017 Intel Corporation + * + * SPDX-License-Identifier: GPL-2.0 + */ + +#ifndef _DT_BINDINGS_RESET_ALTR_RST_MGR_A10_H +#define _DT_BINDINGS_RESET_ALTR_RST_MGR_A10_H + +/* MPUMODRST */ +#define CPU0_RESET 0 +#define CPU1_RESET 1 +#define WDS_RESET 2 +#define SCUPER_RESET 3 + +/* PER0MODRST */ +#define EMAC0_RESET 32 +#define EMAC1_RESET 33 +#define EMAC2_RESET 34 +#define USB0_RESET 35 +#define USB1_RESET 36 +#define NAND_RESET 37 +#define QSPI_RESET 38 +#define SDMMC_RESET 39 +#define EMAC0_OCP_RESET 40 +#define EMAC1_OCP_RESET 41 +#define EMAC2_OCP_RESET 42 +#define USB0_OCP_RESET 43 +#define USB1_OCP_RESET 44 +#define NAND_OCP_RESET 45 +#define QSPI_OCP_RESET 46 +#define SDMMC_OCP_RESET 47 +#define DMA_RESET 48 +#define SPIM0_RESET 49 +#define SPIM1_RESET 50 +#define SPIS0_RESET 51 +#define SPIS1_RESET 52 +#define DMA_OCP_RESET 53 +#define EMAC_PTP_RESET 54 +/* 55 is empty*/ +#define DMAIF0_RESET 56 +#define DMAIF1_RESET 57 +#define DMAIF2_RESET 58 +#define DMAIF3_RESET 59 +#define DMAIF4_RESET 60 +#define DMAIF5_RESET 61 +#define DMAIF6_RESET 62 +#define DMAIF7_RESET 63 + +/* PER1MODRST */ +#define L4WD0_RESET 64 +#define L4WD1_RESET 65 +#define L4SYSTIMER0_RESET 66 +#define L4SYSTIMER1_RESET 67 +#define SPTIMER0_RESET 68 +#define SPTIMER1_RESET 69 +/* 70-71 is reserved */ +#define I2C0_RESET 72 +#define I2C1_RESET 73 +#define I2C2_RESET 74 +#define I2C3_RESET 75 +#define I2C4_RESET 76 +/* 77-79 is reserved */ +#define UART0_RESET 80 +#define UART1_RESET 81 +/* 82-87 is reserved */ +#define GPIO0_RESET 88 +#define GPIO1_RESET 89 +#define GPIO2_RESET 90 + +/* BRGMODRST */ +#define HPS2FPGA_RESET 96 +#define LWHPS2FPGA_RESET 97 +#define FPGA2HPS_RESET 98 +#define F2SSDRAM0_RESET 99 +#define F2SSDRAM1_RESET 100 +#define F2SSDRAM2_RESET 101 +#define DDRSCH_RESET 102 + +/* SYSMODRST*/ +#define ROM_RESET 128 +#define OCRAM_RESET 129 +/* 130 is reserved */ +#define FPGAMGR_RESET 131 +#define S2F_RESET 132 +#define SYSDBG_RESET 133 +#define OCRAM_OCP_RESET 134 + +/* COLDMODRST */ +#define CLKMGRCOLD_RESET 160 +/* 161-162 is reserved */ +#define S2FCOLD_RESET 163 +#define TIMESTAMPCOLD_RESET 164 +#define TAPCOLD_RESET 165 +#define HMCCOLD_RESET 166 +#define IOMGRCOLD_RESET 167 + +/* NRSTMODRST */ +#define NRSTPINOE_RESET 192 + +/* DBGMODRST */ +#define DBG_RESET 224 +#endif