On Fri, 2013-09-20 at 00:08 -0500, Chin Liang See wrote: > Adding Freeze Controller driver. All HPS IOs need to be > in freeze state during pin mux or IO buffer configuration. > It is to avoid any glitch which might happen > during the configuration from propagating to external devices. > > Signed-off-by: Chin Liang See <cl...@altera.com> > Cc: Wolfgang Denk <w...@denx.de> > CC: Pavel Machek <pa...@denx.de> > Cc: Dinh Nguyen <dingu...@altera.com> > --- > Changes for v3 > - Removed unused macro in freeze_controller.h > Changes for v2 > - Removed FREEZE_CONTROLLER_FSM_HW > - Removed the get_timer_count_masked and convert to use delay in us > - Used shorter local variables > --- > arch/arm/cpu/armv7/socfpga/Makefile | 2 +- > arch/arm/cpu/armv7/socfpga/freeze_controller.c | 242 > ++++++++++++++++++++ > arch/arm/cpu/armv7/socfpga/spl.c | 16 ++ > .../include/asm/arch-socfpga/freeze_controller.h | 50 ++++ > 4 files changed, 309 insertions(+), 1 deletion(-) > create mode 100644 arch/arm/cpu/armv7/socfpga/freeze_controller.c > create mode 100644 arch/arm/include/asm/arch-socfpga/freeze_controller.h > > diff --git a/arch/arm/cpu/armv7/socfpga/Makefile > b/arch/arm/cpu/armv7/socfpga/Makefile > index 0859e44..10d20f2 100644 > --- a/arch/arm/cpu/armv7/socfpga/Makefile > +++ b/arch/arm/cpu/armv7/socfpga/Makefile > @@ -14,7 +14,7 @@ LIB = $(obj)lib$(SOC).o > > SOBJS := lowlevel_init.o > COBJS-y := misc.o timer.o reset_manager.o system_manager.o > -COBJS-$(CONFIG_SPL_BUILD) += spl.o > +COBJS-$(CONFIG_SPL_BUILD) += spl.o freeze_controller.o > > COBJS := $(COBJS-y) > SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) > diff --git a/arch/arm/cpu/armv7/socfpga/freeze_controller.c > b/arch/arm/cpu/armv7/socfpga/freeze_controller.c > new file mode 100644 > index 0000000..93ad22a > --- /dev/null > +++ b/arch/arm/cpu/armv7/socfpga/freeze_controller.c > @@ -0,0 +1,242 @@ > +/* > + * Copyright (C) 2013 Altera Corporation <www.altera.com> > + * > + * SPDX-License-Identifier: GPL-2.0+ > + */ > + > +
Remove extra line here... > +#include <common.h> > +#include <asm/io.h> > +#include <asm/arch/freeze_controller.h> > +#include <asm/arch/timer.h> > +#include <asm/errno.h> > + > +DECLARE_GLOBAL_DATA_PTR; > + > + > + Remove extra lines here... > +static const struct socfpga_freeze_controller *freeze_controller_base = > + (void *)(SOCFPGA_SYSMGR_ADDRESS + SYSMGR_FRZCTRL_ADDRESS); > + > +/* > + * Default state from cold reset is FREEZE_ALL; the global > + * flag is set to TRUE to indicate the IO banks are frozen > + */ > +static uint32_t frzctrl_channel_freeze[FREEZE_CHANNEL_NUM] > + = { FREEZE_CTRL_FROZEN, FREEZE_CTRL_FROZEN, > + FREEZE_CTRL_FROZEN, FREEZE_CTRL_FROZEN}; > + > + Ditto... > +/* Freeze HPS IOs */ > +u32 sys_mgr_frzctrl_freeze_req(u32 channel_id) > +{ > + u32 ioctrl_reg_offset; > + u32 reg_value; > + u32 reg_cfg_mask; > + > + /* select software FSM */ > + writel(SYSMGR_FRZCTRL_SRC_VIO1_ENUM_SW, &freeze_controller_base->src); > + > + /* Freeze channel ID checking and base address */ > + switch (channel_id) { > + case 0: > + case 1: > + case 2: > + ioctrl_reg_offset = (u32)( > + &freeze_controller_base->vioctrl + > + (channel_id << SYSMGR_FRZCTRL_VIOCTRL_SHIFT)); > + > + /* > + * Assert active low enrnsl, plniotri > + * and niotri signals > + */ > + reg_cfg_mask = > + SYSMGR_FRZCTRL_VIOCTRL_SLEW_MASK > + | SYSMGR_FRZCTRL_VIOCTRL_WKPULLUP_MASK > + | SYSMGR_FRZCTRL_VIOCTRL_TRISTATE_MASK; > + clrbits_le32(ioctrl_reg_offset, reg_cfg_mask); > + > + /* > + * Note: Delay for 20ns at min > + * Assert active low bhniotri signal and de-assert > + * active high csrdone > + */ Where's the delay? > + reg_cfg_mask > + = SYSMGR_FRZCTRL_VIOCTRL_BUSHOLD_MASK > + | SYSMGR_FRZCTRL_VIOCTRL_CFG_MASK; > + clrbits_le32(ioctrl_reg_offset, reg_cfg_mask); > + > + /* Set global flag to indicate channel is frozen */ > + frzctrl_channel_freeze[channel_id] = FREEZE_CTRL_FROZEN; > + break; > + > + case 3: > + /* > + * Assert active low enrnsl, plniotri and > + * niotri signals > + */ > + reg_cfg_mask > + = SYSMGR_FRZCTRL_HIOCTRL_SLEW_MASK > + | SYSMGR_FRZCTRL_HIOCTRL_WKPULLUP_MASK > + | SYSMGR_FRZCTRL_HIOCTRL_TRISTATE_MASK; > + clrbits_le32(&freeze_controller_base->hioctrl, reg_cfg_mask); > + > + /* > + * Note: Delay for 40ns at min > + * assert active low bhniotri & nfrzdrv signals, > + * de-assert active high csrdone and assert > + * active high frzreg and nfrzdrv signals > + */ Where's the delay? > + reg_value = readl(&freeze_controller_base->hioctrl); > + reg_cfg_mask > + = SYSMGR_FRZCTRL_HIOCTRL_BUSHOLD_MASK > + | SYSMGR_FRZCTRL_HIOCTRL_CFG_MASK; > + reg_value > + = (reg_value & ~reg_cfg_mask) > + | SYSMGR_FRZCTRL_HIOCTRL_REGRST_MASK > + | SYSMGR_FRZCTRL_HIOCTRL_OCTRST_MASK; > + writel(reg_value, &freeze_controller_base->hioctrl); > + > + /* > + * Note: Delay for 40ns at min > + * assert active high reinit signal and de-assert > + * active high pllbiasen signals > + */ > + reg_value = readl(&freeze_controller_base->hioctrl); > + reg_value > + = (reg_value & > + ~SYSMGR_FRZCTRL_HIOCTRL_OCT_CFGEN_CALSTART_MASK) > + | SYSMGR_FRZCTRL_HIOCTRL_DLLRST_MASK; > + writel(reg_value, &freeze_controller_base->hioctrl); > + > + /* Set global flag to indicate channel is frozen */ > + frzctrl_channel_freeze[channel_id] = FREEZE_CTRL_FROZEN; > + break; > + > + default: > + return -EINVAL; > + } > + > + return 0; > +} > + > +/* Unfreeze/Thaw HPS IOs */ > +u32 sys_mgr_frzctrl_thaw_req(u32 channel_id) > +{ > + u32 ioctrl_reg_offset; > + u32 reg_cfg_mask; > + u32 reg_value; > + > + Extra line.. > + /* select software FSM */ > + writel(SYSMGR_FRZCTRL_SRC_VIO1_ENUM_SW, &freeze_controller_base->src); > + > + /* Freeze channel ID checking and base address */ > + switch (channel_id) { > + case 0: > + case 1: > + case 2: > + ioctrl_reg_offset > + = (u32)(&freeze_controller_base->vioctrl > + + (channel_id << SYSMGR_FRZCTRL_VIOCTRL_SHIFT)); > + > + /* > + * Assert active low bhniotri signal and > + * de-assert active high csrdone > + */ > + reg_cfg_mask > + = SYSMGR_FRZCTRL_VIOCTRL_BUSHOLD_MASK > + | SYSMGR_FRZCTRL_VIOCTRL_CFG_MASK; > + setbits_le32(ioctrl_reg_offset, reg_cfg_mask); > + > + /* > + * Note: Delay for 20ns at min > + * de-assert active low plniotri and niotri signals > + */ > + reg_cfg_mask > + = SYSMGR_FRZCTRL_VIOCTRL_WKPULLUP_MASK > + | SYSMGR_FRZCTRL_VIOCTRL_TRISTATE_MASK; > + setbits_le32(ioctrl_reg_offset, reg_cfg_mask); > + > + /* > + * Note: Delay for 20ns at min > + * de-assert active low enrnsl signal > + */ > + setbits_le32(ioctrl_reg_offset, > + SYSMGR_FRZCTRL_VIOCTRL_SLEW_MASK); > + > + /* Set global flag to indicate channel is thawed */ > + frzctrl_channel_freeze[channel_id] = FREEZE_CTRL_THAWED; > + > + break; > + > + case 3: > + /* de-assert active high reinit signal */ > + clrbits_le32(&freeze_controller_base->hioctrl, > + SYSMGR_FRZCTRL_HIOCTRL_DLLRST_MASK); > + > + /* > + * Note: Delay for 40ns at min > + * assert active high pllbiasen signals > + */ > + setbits_le32(&freeze_controller_base->hioctrl, > + SYSMGR_FRZCTRL_HIOCTRL_OCT_CFGEN_CALSTART_MASK); > + > + /* > + * Delay 1000 intosc. intosc is based on eosc1 > + * Use worst case which is fatest eosc1=50MHz, delay required > + * is 1/50MHz * 1000 = 20us > + */ > + udelay(20); > + > + /* > + * de-assert active low bhniotri signals, > + * assert active high csrdone and nfrzdrv signal > + */ > + reg_value = readl(&freeze_controller_base->hioctrl); > + reg_value = (reg_value > + | SYSMGR_FRZCTRL_HIOCTRL_BUSHOLD_MASK > + | SYSMGR_FRZCTRL_HIOCTRL_CFG_MASK) > + & ~SYSMGR_FRZCTRL_HIOCTRL_OCTRST_MASK; > + writel(reg_value, &freeze_controller_base->hioctrl); > + > + /* > + * Delay 33 intosc > + * Use worst case which is fatest eosc1=50MHz, delay required > + * is 1/50MHz * 33 = 660ns ~= 1us > + */ > + udelay(1); > + > + /* de-assert active low plniotri and niotri signals */ > + reg_cfg_mask > + = SYSMGR_FRZCTRL_HIOCTRL_WKPULLUP_MASK > + | SYSMGR_FRZCTRL_HIOCTRL_TRISTATE_MASK; > + > + setbits_le32(&freeze_controller_base->hioctrl, reg_cfg_mask); > + > + /* > + * Note: Delay for 40ns at min > + * de-assert active high frzreg signal > + */ > + clrbits_le32(&freeze_controller_base->hioctrl, > + SYSMGR_FRZCTRL_HIOCTRL_REGRST_MASK); > + > + /* > + * Note: Delay for 40ns at min > + * de-assert active low enrnsl signal > + */ > + setbits_le32(&freeze_controller_base->hioctrl, > + SYSMGR_FRZCTRL_HIOCTRL_SLEW_MASK); > + > + /* Set global flag to indicate channel is thawed */ > + frzctrl_channel_freeze[channel_id] = FREEZE_CTRL_THAWED; > + > + break; > + > + default: > + return -EINVAL; > + } > + > + return 0; > +} > + > diff --git a/arch/arm/cpu/armv7/socfpga/spl.c > b/arch/arm/cpu/armv7/socfpga/spl.c > index 74bceab..e9cdfb87 100644 > --- a/arch/arm/cpu/armv7/socfpga/spl.c > +++ b/arch/arm/cpu/armv7/socfpga/spl.c > @@ -13,6 +13,8 @@ > #include <asm/arch/reset_manager.h> > #include <spl.h> > #include <asm/arch/system_manager.h> > +#include <asm/arch/freeze_controller.h> > + Extra line.. > > DECLARE_GLOBAL_DATA_PTR; > > @@ -27,6 +29,13 @@ u32 spl_boot_device(void) > void spl_board_init(void) > { > #ifndef CONFIG_SOCFPGA_VIRTUAL_TARGET > + debug("Freezing all I/O banks\n"); > + /* freeze all IO banks */ > + sys_mgr_frzctrl_freeze_req(0); > + sys_mgr_frzctrl_freeze_req(1); > + sys_mgr_frzctrl_freeze_req(2); > + sys_mgr_frzctrl_freeze_req(3); Are there any situation where you wouldn't freeze/unfreeze all 4 banks of IO? If not then, then you could simplify sys_mgr_frzctrl_freeze_req() to be only called once. Dinh > + > /* configure the pin muxing through system manager */ > sysmgr_pinmux_init(); > #endif /* CONFIG_SOCFPGA_VIRTUAL_TARGET */ > @@ -34,6 +43,13 @@ void spl_board_init(void) > /* de-assert reset for peripherals and bridges based on handoff */ > reset_deassert_peripherals_handoff(); > > + debug("Unfreezing/Thaw all I/O banks\n"); > + /* unfreeze / thaw all IO banks */ > + sys_mgr_frzctrl_thaw_req(0); > + sys_mgr_frzctrl_thaw_req(1); > + sys_mgr_frzctrl_thaw_req(2); > + sys_mgr_frzctrl_thaw_req(3); > + > /* enable console uart printing */ > preloader_console_init(); > } > diff --git a/arch/arm/include/asm/arch-socfpga/freeze_controller.h > b/arch/arm/include/asm/arch-socfpga/freeze_controller.h > new file mode 100644 > index 0000000..9512b32 > --- /dev/null > +++ b/arch/arm/include/asm/arch-socfpga/freeze_controller.h > @@ -0,0 +1,50 @@ > +/* > + * Copyright (C) 2013 Altera Corporation <www.altera.com> > + * > + * SPDX-License-Identifier: GPL-2.0+ > + */ > + > +#ifndef _FREEZE_CONTROLLER_H_ > +#define _FREEZE_CONTROLLER_H_ > + > +struct socfpga_freeze_controller { > + u32 vioctrl; > + u32 padding[3]; > + u32 hioctrl; > + u32 src; > + u32 hwctrl; > +}; > + > +#define FREEZE_CHANNEL_NUM (4) > + > +typedef enum { > + FREEZE_CTRL_FROZEN = 0, > + FREEZE_CTRL_THAWED = 1 > +} FREEZE_CTRL_CHAN_STATE; > + > +#define SYSMGR_FRZCTRL_ADDRESS 0x40 > +#define SYSMGR_FRZCTRL_SRC_VIO1_ENUM_SW 0x0 > +#define SYSMGR_FRZCTRL_SRC_VIO1_ENUM_HW 0x1 > +#define SYSMGR_FRZCTRL_VIOCTRL_SLEW_MASK 0x00000010 > +#define SYSMGR_FRZCTRL_VIOCTRL_WKPULLUP_MASK 0x00000008 > +#define SYSMGR_FRZCTRL_VIOCTRL_TRISTATE_MASK 0x00000004 > +#define SYSMGR_FRZCTRL_VIOCTRL_BUSHOLD_MASK 0x00000002 > +#define SYSMGR_FRZCTRL_VIOCTRL_CFG_MASK 0x00000001 > +#define SYSMGR_FRZCTRL_HIOCTRL_SLEW_MASK 0x00000010 > +#define SYSMGR_FRZCTRL_HIOCTRL_WKPULLUP_MASK 0x00000008 > +#define SYSMGR_FRZCTRL_HIOCTRL_TRISTATE_MASK 0x00000004 > +#define SYSMGR_FRZCTRL_HIOCTRL_BUSHOLD_MASK 0x00000002 > +#define SYSMGR_FRZCTRL_HIOCTRL_CFG_MASK 0x00000001 > +#define SYSMGR_FRZCTRL_HIOCTRL_REGRST_MASK 0x00000080 > +#define SYSMGR_FRZCTRL_HIOCTRL_OCTRST_MASK 0x00000040 > +#define SYSMGR_FRZCTRL_HIOCTRL_OCT_CFGEN_CALSTART_MASK 0x00000100 > +#define SYSMGR_FRZCTRL_HIOCTRL_DLLRST_MASK 0x00000020 > +#define SYSMGR_FRZCTRL_HWCTRL_VIO1REQ_MASK 0x00000001 > +#define SYSMGR_FRZCTRL_HWCTRL_VIO1STATE_ENUM_FROZEN 0x2 > +#define SYSMGR_FRZCTRL_HWCTRL_VIO1STATE_ENUM_THAWED 0x1 > +#define SYSMGR_FRZCTRL_VIOCTRL_SHIFT 0x2 > + > +u32 sys_mgr_frzctrl_freeze_req(u32 channel_id); > +u32 sys_mgr_frzctrl_thaw_req(u32 channel_id); > + > +#endif /* _FREEZE_CONTROLLER_H_ */ _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot