1*83d290c5STom Rini // SPDX-License-Identifier: GPL-2.0+
205a21721SMasahiro Yamada /*
305a21721SMasahiro Yamada * Copyright (C) 2013 Altera Corporation <www.altera.com>
405a21721SMasahiro Yamada */
505a21721SMasahiro Yamada
605a21721SMasahiro Yamada
705a21721SMasahiro Yamada #include <common.h>
805a21721SMasahiro Yamada #include <asm/io.h>
9a8535c30SMarek Vasut #include <asm/arch/clock_manager.h>
1005a21721SMasahiro Yamada #include <asm/arch/freeze_controller.h>
111221ce45SMasahiro Yamada #include <linux/errno.h>
1205a21721SMasahiro Yamada
1305a21721SMasahiro Yamada static const struct socfpga_freeze_controller *freeze_controller_base =
1405a21721SMasahiro Yamada (void *)(SOCFPGA_SYSMGR_ADDRESS + SYSMGR_FRZCTRL_ADDRESS);
1505a21721SMasahiro Yamada
1605a21721SMasahiro Yamada /*
1705a21721SMasahiro Yamada * Default state from cold reset is FREEZE_ALL; the global
1805a21721SMasahiro Yamada * flag is set to TRUE to indicate the IO banks are frozen
1905a21721SMasahiro Yamada */
2005a21721SMasahiro Yamada static uint32_t frzctrl_channel_freeze[FREEZE_CHANNEL_NUM]
2105a21721SMasahiro Yamada = { FREEZE_CTRL_FROZEN, FREEZE_CTRL_FROZEN,
2205a21721SMasahiro Yamada FREEZE_CTRL_FROZEN, FREEZE_CTRL_FROZEN};
2305a21721SMasahiro Yamada
2405a21721SMasahiro Yamada /* Freeze HPS IOs */
sys_mgr_frzctrl_freeze_req(void)2505a21721SMasahiro Yamada void sys_mgr_frzctrl_freeze_req(void)
2605a21721SMasahiro Yamada {
2705a21721SMasahiro Yamada u32 ioctrl_reg_offset;
2805a21721SMasahiro Yamada u32 reg_value;
2905a21721SMasahiro Yamada u32 reg_cfg_mask;
3005a21721SMasahiro Yamada u32 channel_id;
3105a21721SMasahiro Yamada
3205a21721SMasahiro Yamada /* select software FSM */
3305a21721SMasahiro Yamada writel(SYSMGR_FRZCTRL_SRC_VIO1_ENUM_SW, &freeze_controller_base->src);
3405a21721SMasahiro Yamada
3505a21721SMasahiro Yamada /* Freeze channel 0 to 2 */
3605a21721SMasahiro Yamada for (channel_id = 0; channel_id <= 2; channel_id++) {
3705a21721SMasahiro Yamada ioctrl_reg_offset = (u32)(
3805a21721SMasahiro Yamada &freeze_controller_base->vioctrl + channel_id);
3905a21721SMasahiro Yamada
4005a21721SMasahiro Yamada /*
4105a21721SMasahiro Yamada * Assert active low enrnsl, plniotri
4205a21721SMasahiro Yamada * and niotri signals
4305a21721SMasahiro Yamada */
4405a21721SMasahiro Yamada reg_cfg_mask =
4505a21721SMasahiro Yamada SYSMGR_FRZCTRL_VIOCTRL_SLEW_MASK
4605a21721SMasahiro Yamada | SYSMGR_FRZCTRL_VIOCTRL_WKPULLUP_MASK
4705a21721SMasahiro Yamada | SYSMGR_FRZCTRL_VIOCTRL_TRISTATE_MASK;
4805a21721SMasahiro Yamada clrbits_le32(ioctrl_reg_offset, reg_cfg_mask);
4905a21721SMasahiro Yamada
5005a21721SMasahiro Yamada /*
5105a21721SMasahiro Yamada * Note: Delay for 20ns at min
5205a21721SMasahiro Yamada * Assert active low bhniotri signal and de-assert
5305a21721SMasahiro Yamada * active high csrdone
5405a21721SMasahiro Yamada */
5505a21721SMasahiro Yamada reg_cfg_mask
5605a21721SMasahiro Yamada = SYSMGR_FRZCTRL_VIOCTRL_BUSHOLD_MASK
5705a21721SMasahiro Yamada | SYSMGR_FRZCTRL_VIOCTRL_CFG_MASK;
5805a21721SMasahiro Yamada clrbits_le32(ioctrl_reg_offset, reg_cfg_mask);
5905a21721SMasahiro Yamada
6005a21721SMasahiro Yamada /* Set global flag to indicate channel is frozen */
6105a21721SMasahiro Yamada frzctrl_channel_freeze[channel_id] = FREEZE_CTRL_FROZEN;
6205a21721SMasahiro Yamada }
6305a21721SMasahiro Yamada
6405a21721SMasahiro Yamada /* Freeze channel 3 */
6505a21721SMasahiro Yamada /*
6605a21721SMasahiro Yamada * Assert active low enrnsl, plniotri and
6705a21721SMasahiro Yamada * niotri signals
6805a21721SMasahiro Yamada */
6905a21721SMasahiro Yamada reg_cfg_mask
7005a21721SMasahiro Yamada = SYSMGR_FRZCTRL_HIOCTRL_SLEW_MASK
7105a21721SMasahiro Yamada | SYSMGR_FRZCTRL_HIOCTRL_WKPULLUP_MASK
7205a21721SMasahiro Yamada | SYSMGR_FRZCTRL_HIOCTRL_TRISTATE_MASK;
7305a21721SMasahiro Yamada clrbits_le32(&freeze_controller_base->hioctrl, reg_cfg_mask);
7405a21721SMasahiro Yamada
7505a21721SMasahiro Yamada /*
7605a21721SMasahiro Yamada * assert active low bhniotri & nfrzdrv signals,
7705a21721SMasahiro Yamada * de-assert active high csrdone and assert
7805a21721SMasahiro Yamada * active high frzreg and nfrzdrv signals
7905a21721SMasahiro Yamada */
8005a21721SMasahiro Yamada reg_value = readl(&freeze_controller_base->hioctrl);
8105a21721SMasahiro Yamada reg_cfg_mask
8205a21721SMasahiro Yamada = SYSMGR_FRZCTRL_HIOCTRL_BUSHOLD_MASK
8305a21721SMasahiro Yamada | SYSMGR_FRZCTRL_HIOCTRL_CFG_MASK;
8405a21721SMasahiro Yamada reg_value
8505a21721SMasahiro Yamada = (reg_value & ~reg_cfg_mask)
8605a21721SMasahiro Yamada | SYSMGR_FRZCTRL_HIOCTRL_REGRST_MASK
8705a21721SMasahiro Yamada | SYSMGR_FRZCTRL_HIOCTRL_OCTRST_MASK;
8805a21721SMasahiro Yamada writel(reg_value, &freeze_controller_base->hioctrl);
8905a21721SMasahiro Yamada
9005a21721SMasahiro Yamada /*
9105a21721SMasahiro Yamada * assert active high reinit signal and de-assert
9205a21721SMasahiro Yamada * active high pllbiasen signals
9305a21721SMasahiro Yamada */
9405a21721SMasahiro Yamada reg_value = readl(&freeze_controller_base->hioctrl);
9505a21721SMasahiro Yamada reg_value
9605a21721SMasahiro Yamada = (reg_value &
9705a21721SMasahiro Yamada ~SYSMGR_FRZCTRL_HIOCTRL_OCT_CFGEN_CALSTART_MASK)
9805a21721SMasahiro Yamada | SYSMGR_FRZCTRL_HIOCTRL_DLLRST_MASK;
9905a21721SMasahiro Yamada writel(reg_value, &freeze_controller_base->hioctrl);
10005a21721SMasahiro Yamada
10105a21721SMasahiro Yamada /* Set global flag to indicate channel is frozen */
10205a21721SMasahiro Yamada frzctrl_channel_freeze[channel_id] = FREEZE_CTRL_FROZEN;
10305a21721SMasahiro Yamada }
10405a21721SMasahiro Yamada
10505a21721SMasahiro Yamada /* Unfreeze/Thaw HPS IOs */
sys_mgr_frzctrl_thaw_req(void)10605a21721SMasahiro Yamada void sys_mgr_frzctrl_thaw_req(void)
10705a21721SMasahiro Yamada {
10805a21721SMasahiro Yamada u32 ioctrl_reg_offset;
10905a21721SMasahiro Yamada u32 reg_cfg_mask;
11005a21721SMasahiro Yamada u32 reg_value;
11105a21721SMasahiro Yamada u32 channel_id;
112a8535c30SMarek Vasut unsigned long eosc1_freq;
11305a21721SMasahiro Yamada
11405a21721SMasahiro Yamada /* select software FSM */
11505a21721SMasahiro Yamada writel(SYSMGR_FRZCTRL_SRC_VIO1_ENUM_SW, &freeze_controller_base->src);
11605a21721SMasahiro Yamada
11705a21721SMasahiro Yamada /* Thaw channel 0 to 2 */
11805a21721SMasahiro Yamada for (channel_id = 0; channel_id <= 2; channel_id++) {
11905a21721SMasahiro Yamada ioctrl_reg_offset
12005a21721SMasahiro Yamada = (u32)(&freeze_controller_base->vioctrl + channel_id);
12105a21721SMasahiro Yamada
12205a21721SMasahiro Yamada /*
12305a21721SMasahiro Yamada * Assert active low bhniotri signal and
12405a21721SMasahiro Yamada * de-assert active high csrdone
12505a21721SMasahiro Yamada */
12605a21721SMasahiro Yamada reg_cfg_mask
12705a21721SMasahiro Yamada = SYSMGR_FRZCTRL_VIOCTRL_BUSHOLD_MASK
12805a21721SMasahiro Yamada | SYSMGR_FRZCTRL_VIOCTRL_CFG_MASK;
12905a21721SMasahiro Yamada setbits_le32(ioctrl_reg_offset, reg_cfg_mask);
13005a21721SMasahiro Yamada
13105a21721SMasahiro Yamada /*
13205a21721SMasahiro Yamada * Note: Delay for 20ns at min
13305a21721SMasahiro Yamada * de-assert active low plniotri and niotri signals
13405a21721SMasahiro Yamada */
13505a21721SMasahiro Yamada reg_cfg_mask
13605a21721SMasahiro Yamada = SYSMGR_FRZCTRL_VIOCTRL_WKPULLUP_MASK
13705a21721SMasahiro Yamada | SYSMGR_FRZCTRL_VIOCTRL_TRISTATE_MASK;
13805a21721SMasahiro Yamada setbits_le32(ioctrl_reg_offset, reg_cfg_mask);
13905a21721SMasahiro Yamada
14005a21721SMasahiro Yamada /*
14105a21721SMasahiro Yamada * Note: Delay for 20ns at min
14205a21721SMasahiro Yamada * de-assert active low enrnsl signal
14305a21721SMasahiro Yamada */
14405a21721SMasahiro Yamada setbits_le32(ioctrl_reg_offset,
14505a21721SMasahiro Yamada SYSMGR_FRZCTRL_VIOCTRL_SLEW_MASK);
14605a21721SMasahiro Yamada
14705a21721SMasahiro Yamada /* Set global flag to indicate channel is thawed */
14805a21721SMasahiro Yamada frzctrl_channel_freeze[channel_id] = FREEZE_CTRL_THAWED;
14905a21721SMasahiro Yamada }
15005a21721SMasahiro Yamada
15105a21721SMasahiro Yamada /* Thaw channel 3 */
15205a21721SMasahiro Yamada /* de-assert active high reinit signal */
15305a21721SMasahiro Yamada clrbits_le32(&freeze_controller_base->hioctrl,
15405a21721SMasahiro Yamada SYSMGR_FRZCTRL_HIOCTRL_DLLRST_MASK);
15505a21721SMasahiro Yamada
15605a21721SMasahiro Yamada /*
15705a21721SMasahiro Yamada * Note: Delay for 40ns at min
15805a21721SMasahiro Yamada * assert active high pllbiasen signals
15905a21721SMasahiro Yamada */
16005a21721SMasahiro Yamada setbits_le32(&freeze_controller_base->hioctrl,
16105a21721SMasahiro Yamada SYSMGR_FRZCTRL_HIOCTRL_OCT_CFGEN_CALSTART_MASK);
16205a21721SMasahiro Yamada
163a8535c30SMarek Vasut /* Delay 1000 intosc cycles. The intosc is based on eosc1. */
164a8535c30SMarek Vasut eosc1_freq = cm_get_osc_clk_hz(1) / 1000; /* kHz */
165a8535c30SMarek Vasut udelay(DIV_ROUND_UP(1000000, eosc1_freq));
16605a21721SMasahiro Yamada
16705a21721SMasahiro Yamada /*
16805a21721SMasahiro Yamada * de-assert active low bhniotri signals,
16905a21721SMasahiro Yamada * assert active high csrdone and nfrzdrv signal
17005a21721SMasahiro Yamada */
17105a21721SMasahiro Yamada reg_value = readl(&freeze_controller_base->hioctrl);
17205a21721SMasahiro Yamada reg_value = (reg_value
17305a21721SMasahiro Yamada | SYSMGR_FRZCTRL_HIOCTRL_BUSHOLD_MASK
17405a21721SMasahiro Yamada | SYSMGR_FRZCTRL_HIOCTRL_CFG_MASK)
17505a21721SMasahiro Yamada & ~SYSMGR_FRZCTRL_HIOCTRL_OCTRST_MASK;
17605a21721SMasahiro Yamada writel(reg_value, &freeze_controller_base->hioctrl);
17705a21721SMasahiro Yamada
17805a21721SMasahiro Yamada /*
17905a21721SMasahiro Yamada * Delay 33 intosc
18005a21721SMasahiro Yamada * Use worst case which is fatest eosc1=50MHz, delay required
18105a21721SMasahiro Yamada * is 1/50MHz * 33 = 660ns ~= 1us
18205a21721SMasahiro Yamada */
18305a21721SMasahiro Yamada udelay(1);
18405a21721SMasahiro Yamada
18505a21721SMasahiro Yamada /* de-assert active low plniotri and niotri signals */
18605a21721SMasahiro Yamada reg_cfg_mask
18705a21721SMasahiro Yamada = SYSMGR_FRZCTRL_HIOCTRL_WKPULLUP_MASK
18805a21721SMasahiro Yamada | SYSMGR_FRZCTRL_HIOCTRL_TRISTATE_MASK;
18905a21721SMasahiro Yamada
19005a21721SMasahiro Yamada setbits_le32(&freeze_controller_base->hioctrl, reg_cfg_mask);
19105a21721SMasahiro Yamada
19205a21721SMasahiro Yamada /*
19305a21721SMasahiro Yamada * Note: Delay for 40ns at min
19405a21721SMasahiro Yamada * de-assert active high frzreg signal
19505a21721SMasahiro Yamada */
19605a21721SMasahiro Yamada clrbits_le32(&freeze_controller_base->hioctrl,
19705a21721SMasahiro Yamada SYSMGR_FRZCTRL_HIOCTRL_REGRST_MASK);
19805a21721SMasahiro Yamada
19905a21721SMasahiro Yamada /*
20005a21721SMasahiro Yamada * Note: Delay for 40ns at min
20105a21721SMasahiro Yamada * de-assert active low enrnsl signal
20205a21721SMasahiro Yamada */
20305a21721SMasahiro Yamada setbits_le32(&freeze_controller_base->hioctrl,
20405a21721SMasahiro Yamada SYSMGR_FRZCTRL_HIOCTRL_SLEW_MASK);
20505a21721SMasahiro Yamada
20605a21721SMasahiro Yamada /* Set global flag to indicate channel is thawed */
20705a21721SMasahiro Yamada frzctrl_channel_freeze[channel_id] = FREEZE_CTRL_THAWED;
20805a21721SMasahiro Yamada }
209