
Hi!
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.
Thanks for the patch.
(What version is it against? Aha, it depends on previous patches, right?)
AFAICT:
FREEZE_CONTROLLER_FSM_HW is unused and can be removed.
frzctrl_channel_freeze[] is write-only and can be removed.
Local variables do not need frzctrl_ prefix.
[I have fixed those, suggested incremental diff is attached. Please review & apply to your tree.]
Is it really neccessary to introduce get_timer_count_masked? Replace the delays with udelay(1) and it should still work?
Thanks, Pavel
diff --git a/arch/arm/cpu/armv7/socfpga/freeze_controller.c b/arch/arm/cpu/armv7/socfpga/freeze_controller.c index af612c9..058d9b5 100644 --- a/arch/arm/cpu/armv7/socfpga/freeze_controller.c +++ b/arch/arm/cpu/armv7/socfpga/freeze_controller.c @@ -9,226 +9,183 @@ #include <asm/io.h> #include <asm/arch/freeze_controller.h> #include <asm/arch/timer.h> +#include <asm/errno.h>
DECLARE_GLOBAL_DATA_PTR;
+ + 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}; - -/* Get current state of freeze channel 1 (VIO) */ -static inline u32 sys_mgr_frzctrl_frzchn1_state_get(void) -{ - u32 frzchn1_state; - frzchn1_state = readl(&freeze_controller_base->hwctrl); - frzchn1_state = SYSMGR_FRZCTRL_HWCTRL_VIO1STATE_GET(frzchn1_state); - return frzchn1_state; -}
/* Freeze HPS IOs */ u32 sys_mgr_frzctrl_freeze_req(FreezeChannelSelect channel_id, - FreezeControllerFSMSelect fsm_select) + FreezeControllerFSMSelect fsm_select) { - u32 frzctrl_ioctrl_reg_offset; - u32 frzctrl_reg_value; - u32 frzctrl_reg_cfg_mask; + u32 ioctrl_reg_offset; + u32 reg_value; + u32 reg_cfg_mask; u32 i;
- if (FREEZE_CONTROLLER_FSM_SW == fsm_select) { - - /* 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 FREEZE_CHANNEL_0: - case FREEZE_CHANNEL_1: - case FREEZE_CHANNEL_2: - frzctrl_ioctrl_reg_offset = (u32)( - &freeze_controller_base->vioctrl + - (channel_id << SYSMGR_FRZCTRL_VIOCTRL_SHIFT)); - - /* - * Assert active low enrnsl, plniotri - * and niotri signals - */ - frzctrl_reg_cfg_mask = - SYSMGR_FRZCTRL_VIOCTRL_SLEW_MASK - | SYSMGR_FRZCTRL_VIOCTRL_WKPULLUP_MASK - | SYSMGR_FRZCTRL_VIOCTRL_TRISTATE_MASK; - clrbits_le32(frzctrl_ioctrl_reg_offset, - frzctrl_reg_cfg_mask); - - /* - * Note: Delay for 20ns at min - * Assert active low bhniotri signal and de-assert - * active high csrdone - */ - frzctrl_reg_cfg_mask - = SYSMGR_FRZCTRL_VIOCTRL_BUSHOLD_MASK - | SYSMGR_FRZCTRL_VIOCTRL_CFG_MASK; - clrbits_le32(frzctrl_ioctrl_reg_offset, - frzctrl_reg_cfg_mask); - - /* Set global flag to indicate channel is frozen */ - frzctrl_channel_freeze[channel_id] = - FREEZE_CTRL_FROZEN; - break; - - case FREEZE_CHANNEL_3: - /* - * Assert active low enrnsl, plniotri and - * niotri signals - */ - frzctrl_reg_cfg_mask - = SYSMGR_FRZCTRL_HIOCTRL_SLEW_MASK - | SYSMGR_FRZCTRL_HIOCTRL_WKPULLUP_MASK - | SYSMGR_FRZCTRL_HIOCTRL_TRISTATE_MASK; - clrbits_le32(&freeze_controller_base->hioctrl, - frzctrl_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 - */ - frzctrl_reg_value = - readl(&freeze_controller_base->hioctrl); - frzctrl_reg_cfg_mask - = SYSMGR_FRZCTRL_HIOCTRL_BUSHOLD_MASK - | SYSMGR_FRZCTRL_HIOCTRL_CFG_MASK; - frzctrl_reg_value - = (frzctrl_reg_value & ~frzctrl_reg_cfg_mask) - | SYSMGR_FRZCTRL_HIOCTRL_REGRST_MASK - | SYSMGR_FRZCTRL_HIOCTRL_OCTRST_MASK; - writel(frzctrl_reg_value, - &freeze_controller_base->hioctrl); - - /* - * Note: Delay for 40ns at min - * assert active high reinit signal and de-assert - * active high pllbiasen signals - */ - frzctrl_reg_value = - readl(&freeze_controller_base->hioctrl); - frzctrl_reg_value - = (frzctrl_reg_value & - ~SYSMGR_FRZCTRL_HIOCTRL_OCT_CFGEN_CALSTART_MASK) - | SYSMGR_FRZCTRL_HIOCTRL_DLLRST_MASK; - writel(frzctrl_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 1; - } - } else if (FREEZE_CONTROLLER_FSM_HW == fsm_select) { - - /* select hardware FSM */ - writel(SYSMGR_FRZCTRL_SRC_VIO1_ENUM_HW, - &freeze_controller_base->src); - - /* write to hwctrl reg to enable freeze req */ - setbits_le32(&freeze_controller_base->hwctrl, - SYSMGR_FRZCTRL_HWCTRL_VIO1REQ_MASK); - - i = 0; - while (SYSMGR_FRZCTRL_HWCTRL_VIO1STATE_ENUM_FROZEN - != sys_mgr_frzctrl_frzchn1_state_get()) { - i++; - if (SYSMGR_FRZCTRL_LOOP_PARAM < i) - return 1; - } /* while ( not frozen) */ - - /* Set global flag to indicate channel is frozen */ - frzctrl_channel_freeze[channel_id] = FREEZE_CTRL_FROZEN; - } else { - return 1; - } /* if-else (fsm_select) */ + if (FREEZE_CONTROLLER_FSM_SW != fsm_select) + return -EINVAL; + + /* 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 FREEZE_CHANNEL_0: + case FREEZE_CHANNEL_1: + case FREEZE_CHANNEL_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 + */ + reg_cfg_mask + = SYSMGR_FRZCTRL_VIOCTRL_BUSHOLD_MASK + | SYSMGR_FRZCTRL_VIOCTRL_CFG_MASK; + clrbits_le32(ioctrl_reg_offset, + reg_cfg_mask); + break; + + case FREEZE_CHANNEL_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 + */ + 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); + break; + + default: + return -EINVAL; + }
return 0; }
/* Unfreeze/Thaw HPS IOs */ u32 sys_mgr_frzctrl_thaw_req(FreezeChannelSelect channel_id, - FreezeControllerFSMSelect fsm_select) + FreezeControllerFSMSelect fsm_select) { - u32 frzctrl_ioctrl_reg_offset; - u32 frzctrl_reg_cfg_mask; - u32 frzctrl_reg_value; + u32 ioctrl_reg_offset; + u32 reg_cfg_mask; + u32 reg_value; u32 i; u32 start_count, clk_cycles_count;
- if (FREEZE_CONTROLLER_FSM_SW == fsm_select) { - /* select software FSM */ - writel(SYSMGR_FRZCTRL_SRC_VIO1_ENUM_SW, - &freeze_controller_base->src); + if (FREEZE_CONTROLLER_FSM_SW != fsm_select) { + return -EINVAL; + } + + + /* 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 FREEZE_CHANNEL_0: case FREEZE_CHANNEL_1: case FREEZE_CHANNEL_2: - frzctrl_ioctrl_reg_offset + ioctrl_reg_offset = (u32)(&freeze_controller_base->vioctrl - + (channel_id << SYSMGR_FRZCTRL_VIOCTRL_SHIFT)); + + (channel_id << SYSMGR_FRZCTRL_VIOCTRL_SHIFT));
/* * Assert active low bhniotri signal and * de-assert active high csrdone */ - frzctrl_reg_cfg_mask + reg_cfg_mask = SYSMGR_FRZCTRL_VIOCTRL_BUSHOLD_MASK | SYSMGR_FRZCTRL_VIOCTRL_CFG_MASK; - setbits_le32(frzctrl_ioctrl_reg_offset, - frzctrl_reg_cfg_mask); + setbits_le32(ioctrl_reg_offset, + reg_cfg_mask);
/* * Note: Delay for 20ns at min * de-assert active low plniotri and niotri signals */ - frzctrl_reg_cfg_mask + reg_cfg_mask = SYSMGR_FRZCTRL_VIOCTRL_WKPULLUP_MASK | SYSMGR_FRZCTRL_VIOCTRL_TRISTATE_MASK; - setbits_le32(frzctrl_ioctrl_reg_offset, - frzctrl_reg_cfg_mask); + setbits_le32(ioctrl_reg_offset, + reg_cfg_mask);
/* * Note: Delay for 20ns at min * de-assert active low enrnsl signal */ - setbits_le32(frzctrl_ioctrl_reg_offset, - SYSMGR_FRZCTRL_VIOCTRL_SLEW_MASK); - - /* Set global flag to indicate channel is thawed */ - frzctrl_channel_freeze[channel_id] = FREEZE_CTRL_THAWED; - + setbits_le32(ioctrl_reg_offset, + SYSMGR_FRZCTRL_VIOCTRL_SLEW_MASK); break;
case FREEZE_CHANNEL_3: /* de-assert active high reinit signal */ clrbits_le32(&freeze_controller_base->hioctrl, - SYSMGR_FRZCTRL_HIOCTRL_DLLRST_MASK); + 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); + SYSMGR_FRZCTRL_HIOCTRL_OCT_CFGEN_CALSTART_MASK);
/* Delay 1000 intosc. intosc is based on eosc1 */ reset_timer_count(); @@ -238,18 +195,18 @@ u32 sys_mgr_frzctrl_thaw_req(FreezeChannelSelect channel_id, clk_cycles_count = get_timer_count(start_count); } while (clk_cycles_count < - SYSMGR_FRZCTRL_INTOSC_1000); + SYSMGR_FRZCTRL_INTOSC_1000);
/* * de-assert active low bhniotri signals, * assert active high csrdone and nfrzdrv signal */ - frzctrl_reg_value = readl(&freeze_controller_base->hioctrl); - frzctrl_reg_value = (frzctrl_reg_value - | SYSMGR_FRZCTRL_HIOCTRL_BUSHOLD_MASK - | SYSMGR_FRZCTRL_HIOCTRL_CFG_MASK) + 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(frzctrl_reg_value, &freeze_controller_base->hioctrl); + writel(reg_value, &freeze_controller_base->hioctrl);
/* Delay 33 intosc */ reset_timer_count(); @@ -259,63 +216,35 @@ u32 sys_mgr_frzctrl_thaw_req(FreezeChannelSelect channel_id, clk_cycles_count = get_timer_count(start_count); } while (clk_cycles_count < - SYSMGR_FRZCTRL_INTOSC_33); + SYSMGR_FRZCTRL_INTOSC_33);
/* de-assert active low plniotri and niotri signals */ - frzctrl_reg_cfg_mask + reg_cfg_mask = SYSMGR_FRZCTRL_HIOCTRL_WKPULLUP_MASK | SYSMGR_FRZCTRL_HIOCTRL_TRISTATE_MASK;
setbits_le32(&freeze_controller_base->hioctrl, - frzctrl_reg_cfg_mask); + 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); + 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; - + SYSMGR_FRZCTRL_HIOCTRL_SLEW_MASK); break;
default: - return 1; + return -EINVAL; }
- } else if (FREEZE_CONTROLLER_FSM_HW == fsm_select) { - - /* select hardware FSM */ - writel(SYSMGR_FRZCTRL_SRC_VIO1_ENUM_HW, - &freeze_controller_base->src); - - /* write to hwctrl reg to enable thaw req; 0: thaw */ - clrbits_le32(&freeze_controller_base->hwctrl, - SYSMGR_FRZCTRL_HWCTRL_VIO1REQ_MASK); - - i = 0; - while (SYSMGR_FRZCTRL_HWCTRL_VIO1STATE_ENUM_THAWED - != sys_mgr_frzctrl_frzchn1_state_get()) { - i++; - if (SYSMGR_FRZCTRL_LOOP_PARAM < i) - return 1; - } /* while (not thaw) */ - - /* Set global flag to indicate channel is thawed */ - frzctrl_channel_freeze[channel_id] = FREEZE_CTRL_THAWED; - } else { - return 1; - } /* if-else (fsm_select) */ - return 0; }