xref: /rk3399_ARM-atf/plat/rockchip/rk3576/drivers/dmc/suspend.c (revision 06f3c7058c42a9f1a9f7df75ea2de71a000855e8)
1 // SPDX-License-Identifier: BSD-3-Clause
2 /*
3  * Copyright (c) 2025, Rockchip Electronics Co., Ltd.
4  */
5 
6 #include <assert.h>
7 #include <errno.h>
8 
9 #include <arch_helpers.h>
10 #include <bl31/bl31.h>
11 #include <common/debug.h>
12 #include <drivers/console.h>
13 #include <drivers/delay_timer.h>
14 #include <lib/mmio.h>
15 #include <platform.h>
16 #include <platform_def.h>
17 
18 #include <dmc_rk3576.h>
19 #include <rk3576_def.h>
20 #include <soc.h>
21 
22 struct rk3576_dmc_config dmc_config;
23 
24 /* DDR_PHY */
25 #define LP_CON0				0x0018
26 #define DFI_LP_CON0			0x0e04
27 /* DDR_CTL */
28 #define DDRCTL_STAT			0x10014
29 #define DDRCTL_PWRCTL			0x10180
30 #define DDRCTL_CLKGATECTL		0x1018c
31 
32 /* LP_CON0 */
33 #define DS_IO_PD			BIT(14)
34 #define SCHD_HW_CLOCK_GATING_DISABLE	BIT(13)
35 #define PCL_PD				BIT(12)
36 #define DQS_ENABLE			BIT(10)
37 #define WCK_ENABLE			BIT(9)
38 #define CTRL_DQS_DRV_OFF		BIT(8)
39 #define CTRL_SCHEDULER_EN		BIT(6)
40 
41 /* DFI_LP_CON0 0x0e04 */
42 #define DFI_LP_MODE_APB			BIT(31)
43 
44 /* DDRCTL_STAT 0x10014 */
45 #define CTL_SELFREF_STATE_SHIFT		(12)
46 #define CTL_SELFREF_STATE_MASK		(0x7 << CTL_SELFREF_STATE_SHIFT)
47 #define CTL_NOT_IN_SELF_REFRESH		(0x0 << CTL_SELFREF_STATE_SHIFT)
48 #define CTL_SELF_REFRESH_1		(0x1 << CTL_SELFREF_STATE_SHIFT)
49 #define CTL_SELF_REFRESH_POWER_DOWN	(0x2 << CTL_SELFREF_STATE_SHIFT)
50 #define CTL_SELF_REFRESH_2		(0x3 << CTL_SELFREF_STATE_SHIFT)
51 #define CTL_SELF_REFRESH_DEEP_SLEEP	(0x4 << CTL_SELFREF_STATE_SHIFT)
52 #define CTL_SELFREF_TYPE_SHIFT		(4)
53 #define CTL_SELFREF_TYPE_MASK		(0x3 << CTL_SELFREF_TYPE_SHIFT)
54 #define CTL_SELFREF_NOT_BY_PHY		(0x1 << CTL_SELFREF_TYPE_SHIFT)
55 #define CTL_SELFREF_NOT_BY_AUTO		(0x2 << CTL_SELFREF_TYPE_SHIFT)
56 #define CTL_SELFREF_BY_AUTO		(0x3 << CTL_SELFREF_TYPE_SHIFT)
57 #define CTL_OPERATING_MODE_MASK		(0x7)
58 #define CTL_OPERATING_MODE_INIT		(0x0)
59 #define CTL_OPERATING_MODE_NORMAL	(0x1)
60 #define CTL_OPERATING_MODE_PD		(0x2)
61 #define CTL_OPERATING_MODE_SR_SRPD	(0x3)
62 
63 /* DDRCTL_PWRCTL 0x10180 */
64 #define CTL_DSM_EN			BIT(18)
65 #define CTL_STAY_IN_SELFREF		BIT(15)
66 #define CTL_SELFREF_SW			BIT(11)
67 #define CTL_EN_DFI_DRAM_CLK_DISABLE	BIT(9)
68 #define CTL_POWERDOWN_EN_MASK		(0xf)
69 #define CTL_POWERDOWN_EN_SHIFT		(4)
70 #define CTL_SELFREF_EN_MASK		(0xf)
71 #define CTL_SELFREF_EN_SHIFT		(0)
72 
73 #define SYS_REG_DEC_CHINFO(n, ch)	(((n) >> (28 + (ch))) & 0x1)
74 #define SYS_REG_DEC_CHINFO_V3(reg2, ch) SYS_REG_DEC_CHINFO(reg2, ch)
75 
76 #define SYS_REG_DEC_NUM_CH(n)		(1 + (((n) >> 12) & 0x1))
77 #define SYS_REG_DEC_NUM_CH_V3(reg2)	SYS_REG_DEC_NUM_CH(reg2)
78 
79 static void exit_low_power(uint32_t ch, struct rk3576_dmc_config *configs)
80 {
81 	/* LP_CON0: [12]pcl_pd */
82 	configs->low_power[ch].pcl_pd = mmio_read_32(DDRPHY_BASE_CH(0) + LP_CON0) & PCL_PD;
83 	mmio_clrbits_32(DDRPHY_BASE_CH(ch) + LP_CON0, PCL_PD);
84 
85 	/* Disable low power activities */
86 	configs->low_power[ch].pwrctl = mmio_read_32(UMCTL_BASE_CH(ch) + DDRCTL_PWRCTL);
87 	mmio_clrbits_32(UMCTL_BASE_CH(ch) + DDRCTL_PWRCTL,
88 			CTL_DSM_EN | (CTL_POWERDOWN_EN_MASK << CTL_POWERDOWN_EN_SHIFT) |
89 			(CTL_SELFREF_EN_MASK << CTL_SELFREF_EN_SHIFT));
90 	while ((mmio_read_32(UMCTL_BASE_CH(ch) + DDRCTL_STAT) & CTL_OPERATING_MODE_MASK) !=
91 		CTL_OPERATING_MODE_NORMAL)
92 		continue;
93 
94 	/* DDR_GRF_CHA_CON6: [6:0]rd_lat_delay, [14:8]wr_lat_delay, [15]cmd_dly_eq0_en */
95 	configs->low_power[ch].grf_ddr_con6 =
96 		mmio_read_32(DDR_GRF_BASE + GRF_CH_CON(ch, 6)) & 0xff7f;
97 	mmio_write_32(DDR_GRF_BASE + GRF_CH_CON(ch, 6), (0x1ul << (15 + 16)));
98 
99 	/* DDR_GRF_CHA_CON0: [12:8]ddrctl_axi_cg_en */
100 	configs->low_power[ch].grf_ddr_con0 =
101 		mmio_read_32(DDR_GRF_BASE + GRF_CH_CON(ch, 0)) & 0x1f00;
102 	mmio_write_32(DDR_GRF_BASE + GRF_CH_CON(ch, 0), 0x1f000000);
103 
104 	/*
105 	 * DDR_GRF_CHA_CON1:
106 	 * [15]ddrctl_apb_pclk_cg_en, [12]ddrmon_pclk_cg_en, [7]dfi_scramble_cg_en,
107 	 * [6]ddrctl_mem_cg_en, [5]bsm_clk_cg_en, [2]ddrctl_core_cg_en, [1]ddrctl_apb_cg_en
108 	 */
109 	configs->low_power[ch].grf_ddr_con1 =
110 		mmio_read_32(DDR_GRF_BASE + GRF_CH_CON(ch, 1)) & 0x90e6;
111 	mmio_write_32(DDR_GRF_BASE + GRF_CH_CON(ch, 1), 0x90e60000);
112 
113 	configs->low_power[ch].hwlp_0 = mmio_read_32(HWLP_BASE_CH(ch) + 0x0);
114 	mmio_write_32(HWLP_BASE_CH(ch) + 0x0, 0x0);
115 	configs->low_power[ch].hwlp_c = mmio_read_32(HWLP_BASE_CH(ch) + 0xc);
116 	mmio_write_32(HWLP_BASE_CH(ch) + 0xc, 0x0);
117 
118 	/* DDR_GRF_CHA_PHY_CON0: [14]ddrphy_pclk_cg_en */
119 	configs->low_power[ch].grf_ddrphy_con0 =
120 		mmio_read_32(DDR_GRF_BASE + GRF_DDRPHY_CON0(ch)) & BIT(14);
121 	mmio_write_32(DDR_GRF_BASE + GRF_DDRPHY_CON0(ch), BIT(14 + 16));
122 
123 	/* CLKGATECTL: [5:0]bsm_clk_on */
124 	configs->low_power[ch].clkgatectl =
125 		mmio_read_32(UMCTL_BASE_CH(ch) + DDRCTL_CLKGATECTL) & 0x3f;
126 	/* DFI_LP_CON0: [31]dfi_lp_mode_apb */
127 	configs->low_power[ch].dfi_lp_mode_apb =
128 		(mmio_read_32(DDRPHY_BASE_CH(ch) + DFI_LP_CON0) >> 31) & 0x1;
129 }
130 
131 static void resume_low_power(uint32_t ch, struct rk3576_dmc_config *configs)
132 {
133 	/* DFI_LP_CON0: [31]dfi_lp_mode_apb */
134 	if (configs->low_power[ch].dfi_lp_mode_apb != 0)
135 		mmio_setbits_32(DDRPHY_BASE_CH(ch) + DFI_LP_CON0, DFI_LP_MODE_APB);
136 
137 	/* CLKGATECTL: [5:0]bsm_clk_on */
138 	mmio_clrsetbits_32(UMCTL_BASE_CH(ch) + DDRCTL_CLKGATECTL,
139 			   0x3f, configs->low_power[ch].clkgatectl & 0x3f);
140 
141 	/* DDR_GRF_CHA_CON6: [6:0]rd_lat_delay, [14:8]wr_lat_delay, [15]cmd_dly_eq0_en */
142 	mmio_write_32(DDR_GRF_BASE + GRF_CH_CON(ch, 6),
143 		      (0xff7ful << 16) | configs->low_power[ch].grf_ddr_con6);
144 
145 	mmio_write_32(HWLP_BASE_CH(ch) + 0xc, configs->low_power[ch].hwlp_c);
146 	mmio_write_32(HWLP_BASE_CH(ch) + 0x0, configs->low_power[ch].hwlp_0);
147 
148 	/* DDR_GRF_CHA_CON0: [12:8]ddrctl_axi_cg_en */
149 	mmio_write_32(DDR_GRF_BASE + GRF_CH_CON(ch, 0),
150 		      (0x1f00ul << 16) | configs->low_power[ch].grf_ddr_con0);
151 
152 	/*
153 	 * DDR_GRF_CHA_CON1:
154 	 * [15]ddrctl_apb_pclk_cg_en, [12]ddrmon_pclk_cg_en, [7]dfi_scramble_cg_en,
155 	 * [6]ddrctl_mem_cg_en, [5]bsm_clk_cg_en, [2]ddrctl_core_cg_en, [1]ddrctl_apb_cg_en
156 	 */
157 	mmio_write_32(DDR_GRF_BASE + GRF_CH_CON(ch, 1),
158 		      (0x90e6ul << 16) | configs->low_power[ch].grf_ddr_con1);
159 
160 	/* DDR_GRF_CHA_PHY_CON0: [14]ddrphy_pclk_cg_en */
161 	mmio_write_32(DDR_GRF_BASE + GRF_DDRPHY_CON0(ch),
162 		      BIT(14 + 16) | configs->low_power[ch].grf_ddrphy_con0);
163 
164 	/* reset low power activities */
165 	mmio_write_32(UMCTL_BASE_CH(ch) + DDRCTL_PWRCTL, configs->low_power[ch].pwrctl);
166 
167 	/* LP_CON0: [12]pcl_pd */
168 	if (configs->low_power[ch].pcl_pd != 0)
169 		mmio_setbits_32(DDRPHY_BASE_CH(ch) + LP_CON0, PCL_PD);
170 }
171 
172 void dmc_save(void)
173 {
174 	uint32_t i, channel_num;
175 
176 	channel_num =
177 		SYS_REG_DEC_NUM_CH_V3(mmio_read_32(PMU1_GRF_BASE + PMUGRF_OS_REG(2)));
178 
179 	for (i = 0; i < channel_num; i++)
180 		exit_low_power(i, &dmc_config);
181 }
182 
183 void dmc_restore(void)
184 {
185 	uint32_t i, channel_num;
186 
187 	channel_num = SYS_REG_DEC_NUM_CH_V3(mmio_read_32(PMU1_GRF_BASE + PMUGRF_OS_REG(2)));
188 
189 	for (i = 0; i < channel_num; i++)
190 		resume_low_power(i, &dmc_config);
191 }
192