Home | History | Annotate | Download | only in mach-socfpga
      1 // SPDX-License-Identifier: GPL-2.0+
      2 /*
      3  *  Copyright (C) 2013 Altera Corporation <www.altera.com>
      4  */
      5 
      6 
      7 #include <common.h>
      8 #include <asm/io.h>
      9 #include <asm/arch/clock_manager.h>
     10 #include <asm/arch/freeze_controller.h>
     11 #include <linux/errno.h>
     12 
     13 static const struct socfpga_freeze_controller *freeze_controller_base =
     14 		(void *)(SOCFPGA_SYSMGR_ADDRESS + SYSMGR_FRZCTRL_ADDRESS);
     15 
     16 /*
     17  * Default state from cold reset is FREEZE_ALL; the global
     18  * flag is set to TRUE to indicate the IO banks are frozen
     19  */
     20 static uint32_t frzctrl_channel_freeze[FREEZE_CHANNEL_NUM]
     21 	= { FREEZE_CTRL_FROZEN, FREEZE_CTRL_FROZEN,
     22 	FREEZE_CTRL_FROZEN, FREEZE_CTRL_FROZEN};
     23 
     24 /* Freeze HPS IOs */
     25 void sys_mgr_frzctrl_freeze_req(void)
     26 {
     27 	u32 ioctrl_reg_offset;
     28 	u32 reg_value;
     29 	u32 reg_cfg_mask;
     30 	u32 channel_id;
     31 
     32 	/* select software FSM */
     33 	writel(SYSMGR_FRZCTRL_SRC_VIO1_ENUM_SW,	&freeze_controller_base->src);
     34 
     35 	/* Freeze channel 0 to 2 */
     36 	for (channel_id = 0; channel_id <= 2; channel_id++) {
     37 		ioctrl_reg_offset = (u32)(
     38 			&freeze_controller_base->vioctrl + channel_id);
     39 
     40 		/*
     41 		 * Assert active low enrnsl, plniotri
     42 		 * and niotri signals
     43 		 */
     44 		reg_cfg_mask =
     45 			SYSMGR_FRZCTRL_VIOCTRL_SLEW_MASK
     46 			| SYSMGR_FRZCTRL_VIOCTRL_WKPULLUP_MASK
     47 			| SYSMGR_FRZCTRL_VIOCTRL_TRISTATE_MASK;
     48 		clrbits_le32(ioctrl_reg_offset,	reg_cfg_mask);
     49 
     50 		/*
     51 		 * Note: Delay for 20ns at min
     52 		 * Assert active low bhniotri signal and de-assert
     53 		 * active high csrdone
     54 		 */
     55 		reg_cfg_mask
     56 			= SYSMGR_FRZCTRL_VIOCTRL_BUSHOLD_MASK
     57 			| SYSMGR_FRZCTRL_VIOCTRL_CFG_MASK;
     58 		clrbits_le32(ioctrl_reg_offset,	reg_cfg_mask);
     59 
     60 		/* Set global flag to indicate channel is frozen */
     61 		frzctrl_channel_freeze[channel_id] = FREEZE_CTRL_FROZEN;
     62 	}
     63 
     64 	/* Freeze channel 3 */
     65 	/*
     66 	 * Assert active low enrnsl, plniotri and
     67 	 * niotri signals
     68 	 */
     69 	reg_cfg_mask
     70 		= SYSMGR_FRZCTRL_HIOCTRL_SLEW_MASK
     71 		| SYSMGR_FRZCTRL_HIOCTRL_WKPULLUP_MASK
     72 		| SYSMGR_FRZCTRL_HIOCTRL_TRISTATE_MASK;
     73 	clrbits_le32(&freeze_controller_base->hioctrl, reg_cfg_mask);
     74 
     75 	/*
     76 	 * assert active low bhniotri & nfrzdrv signals,
     77 	 * de-assert active high csrdone and assert
     78 	 * active high frzreg and nfrzdrv signals
     79 	 */
     80 	reg_value = readl(&freeze_controller_base->hioctrl);
     81 	reg_cfg_mask
     82 		= SYSMGR_FRZCTRL_HIOCTRL_BUSHOLD_MASK
     83 		| SYSMGR_FRZCTRL_HIOCTRL_CFG_MASK;
     84 	reg_value
     85 		= (reg_value & ~reg_cfg_mask)
     86 		| SYSMGR_FRZCTRL_HIOCTRL_REGRST_MASK
     87 		| SYSMGR_FRZCTRL_HIOCTRL_OCTRST_MASK;
     88 	writel(reg_value, &freeze_controller_base->hioctrl);
     89 
     90 	/*
     91 	 * assert active high reinit signal and de-assert
     92 	 * active high pllbiasen signals
     93 	 */
     94 	reg_value = readl(&freeze_controller_base->hioctrl);
     95 	reg_value
     96 		= (reg_value &
     97 		~SYSMGR_FRZCTRL_HIOCTRL_OCT_CFGEN_CALSTART_MASK)
     98 		| SYSMGR_FRZCTRL_HIOCTRL_DLLRST_MASK;
     99 	writel(reg_value, &freeze_controller_base->hioctrl);
    100 
    101 	/* Set global flag to indicate channel is frozen */
    102 	frzctrl_channel_freeze[channel_id] = FREEZE_CTRL_FROZEN;
    103 }
    104 
    105 /* Unfreeze/Thaw HPS IOs */
    106 void sys_mgr_frzctrl_thaw_req(void)
    107 {
    108 	u32 ioctrl_reg_offset;
    109 	u32 reg_cfg_mask;
    110 	u32 reg_value;
    111 	u32 channel_id;
    112 	unsigned long eosc1_freq;
    113 
    114 	/* select software FSM */
    115 	writel(SYSMGR_FRZCTRL_SRC_VIO1_ENUM_SW,	&freeze_controller_base->src);
    116 
    117 	/* Thaw channel 0 to 2 */
    118 	for (channel_id = 0; channel_id <= 2; channel_id++) {
    119 		ioctrl_reg_offset
    120 			= (u32)(&freeze_controller_base->vioctrl + channel_id);
    121 
    122 		/*
    123 		 * Assert active low bhniotri signal and
    124 		 * de-assert active high csrdone
    125 		 */
    126 		reg_cfg_mask
    127 			= SYSMGR_FRZCTRL_VIOCTRL_BUSHOLD_MASK
    128 			| SYSMGR_FRZCTRL_VIOCTRL_CFG_MASK;
    129 		setbits_le32(ioctrl_reg_offset,	reg_cfg_mask);
    130 
    131 		/*
    132 		 * Note: Delay for 20ns at min
    133 		 * de-assert active low plniotri and niotri signals
    134 		 */
    135 		reg_cfg_mask
    136 			= SYSMGR_FRZCTRL_VIOCTRL_WKPULLUP_MASK
    137 			| SYSMGR_FRZCTRL_VIOCTRL_TRISTATE_MASK;
    138 		setbits_le32(ioctrl_reg_offset,	reg_cfg_mask);
    139 
    140 		/*
    141 		 * Note: Delay for 20ns at min
    142 		 * de-assert active low enrnsl signal
    143 		 */
    144 		setbits_le32(ioctrl_reg_offset,
    145 			SYSMGR_FRZCTRL_VIOCTRL_SLEW_MASK);
    146 
    147 		/* Set global flag to indicate channel is thawed */
    148 		frzctrl_channel_freeze[channel_id] = FREEZE_CTRL_THAWED;
    149 	}
    150 
    151 	/* Thaw channel 3 */
    152 	/* de-assert active high reinit signal */
    153 	clrbits_le32(&freeze_controller_base->hioctrl,
    154 		SYSMGR_FRZCTRL_HIOCTRL_DLLRST_MASK);
    155 
    156 	/*
    157 	 * Note: Delay for 40ns at min
    158 	 * assert active high pllbiasen signals
    159 	 */
    160 	setbits_le32(&freeze_controller_base->hioctrl,
    161 		SYSMGR_FRZCTRL_HIOCTRL_OCT_CFGEN_CALSTART_MASK);
    162 
    163 	/* Delay 1000 intosc cycles. The intosc is based on eosc1. */
    164 	eosc1_freq = cm_get_osc_clk_hz(1) / 1000;	/* kHz */
    165 	udelay(DIV_ROUND_UP(1000000, eosc1_freq));
    166 
    167 	/*
    168 	 * de-assert active low bhniotri signals,
    169 	 * assert active high csrdone and nfrzdrv signal
    170 	 */
    171 	reg_value = readl(&freeze_controller_base->hioctrl);
    172 	reg_value = (reg_value
    173 		| SYSMGR_FRZCTRL_HIOCTRL_BUSHOLD_MASK
    174 		| SYSMGR_FRZCTRL_HIOCTRL_CFG_MASK)
    175 		& ~SYSMGR_FRZCTRL_HIOCTRL_OCTRST_MASK;
    176 	writel(reg_value, &freeze_controller_base->hioctrl);
    177 
    178 	/*
    179 	 * Delay 33 intosc
    180 	 * Use worst case which is fatest eosc1=50MHz, delay required
    181 	 * is 1/50MHz * 33 = 660ns ~= 1us
    182 	 */
    183 	udelay(1);
    184 
    185 	/* de-assert active low plniotri and niotri signals */
    186 	reg_cfg_mask
    187 		= SYSMGR_FRZCTRL_HIOCTRL_WKPULLUP_MASK
    188 		| SYSMGR_FRZCTRL_HIOCTRL_TRISTATE_MASK;
    189 
    190 	setbits_le32(&freeze_controller_base->hioctrl, reg_cfg_mask);
    191 
    192 	/*
    193 	 * Note: Delay for 40ns at min
    194 	 * de-assert active high frzreg signal
    195 	 */
    196 	clrbits_le32(&freeze_controller_base->hioctrl,
    197 		SYSMGR_FRZCTRL_HIOCTRL_REGRST_MASK);
    198 
    199 	/*
    200 	 * Note: Delay for 40ns at min
    201 	 * de-assert active low enrnsl signal
    202 	 */
    203 	setbits_le32(&freeze_controller_base->hioctrl,
    204 		SYSMGR_FRZCTRL_HIOCTRL_SLEW_MASK);
    205 
    206 	/* Set global flag to indicate channel is thawed */
    207 	frzctrl_channel_freeze[channel_id] = FREEZE_CTRL_THAWED;
    208 }
    209