xref: /rk3399_ARM-atf/plat/mediatek/mt8173/drivers/mtcmos/mtcmos.c (revision 82cb2c1ad9897473743f08437d0a3995bed561b9)
1 /*
2  * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved.
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 #include <mmio.h>
7 #include <mt8173_def.h>
8 #include <debug.h>
9 #include <mtcmos.h>
10 #include <spm.h>
11 #include <spm_mcdi.h>
12 #include <delay_timer.h>
13 
14 enum {
15 	SRAM_ISOINT_B	= 1U << 6,
16 	SRAM_CKISO	= 1U << 5,
17 	PWR_CLK_DIS	= 1U << 4,
18 	PWR_ON_2ND	= 1U << 3,
19 	PWR_ON		= 1U << 2,
20 	PWR_ISO		= 1U << 1,
21 	PWR_RST_B	= 1U << 0
22 };
23 
24 enum {
25 	L1_PDN_ACK	= 1U << 8,
26 	L1_PDN		= 1U << 0
27 };
28 
29 enum {
30 	LITTLE_CPU3	= 1U << 12,
31 	LITTLE_CPU2	= 1U << 11,
32 	LITTLE_CPU1	= 1U << 10,
33 };
34 
35 enum {
36 	SRAM_PDN           = 0xf << 8,
37 	DIS_SRAM_ACK       = 0x1 << 12,
38 	AUD_SRAM_ACK       = 0xf << 12,
39 };
40 
41 enum {
42 	DIS_PWR_STA_MASK   = 0x1 << 3,
43 	AUD_PWR_STA_MASK   = 0x1 << 24,
44 };
45 
46 #define SPM_VDE_PWR_CON				0x0210
47 #define SPM_MFG_PWR_CON				0x0214
48 #define SPM_VEN_PWR_CON				0x0230
49 #define SPM_ISP_PWR_CON				0x0238
50 #define SPM_DIS_PWR_CON				0x023c
51 #define SPM_VEN2_PWR_CON			0x0298
52 #define SPM_AUDIO_PWR_CON			0x029c
53 #define SPM_MFG_2D_PWR_CON			0x02c0
54 #define SPM_MFG_ASYNC_PWR_CON			0x02c4
55 #define SPM_USB_PWR_CON				0x02cc
56 
57 #define MTCMOS_CTRL_SUCCESS			0
58 #define MTCMOS_CTRL_ERROR			-1
59 
60 #define MTCMOS_CTRL_EN				(0x1 << 18)
61 
62 #define VDE_PWR_ON				0
63 #define VEN_PWR_ON				1
64 #define ISP_PWR_ON				2
65 #define DIS_PWR_ON				3
66 #define VEN2_PWR_ON				4
67 #define AUDIO_PWR_ON				5
68 #define MFG_ASYNC_PWR_ON			6
69 #define MFG_2D_PWR_ON				7
70 #define MFG_PWR_ON				8
71 #define USB_PWR_ON				9
72 
73 #define VDE_PWR_OFF				10
74 #define VEN_PWR_OFF				11
75 #define ISP_PWR_OFF				12
76 #define DIS_PWR_OFF				13
77 #define VEN2_PWR_OFF				14
78 #define AUDIO_PWR_OFF				15
79 #define MFG_ASYNC_PWR_OFF			16
80 #define MFG_2D_PWR_OFF				17
81 #define MFG_PWR_OFF				18
82 #define USB_PWR_OFF				19
83 
84 #define VDE_PWR_CON_PWR_STA			7
85 #define VEN_PWR_CON_PWR_STA			21
86 #define ISP_PWR_CON_PWR_STA			5
87 #define DIS_PWR_CON_PWR_STA			3
88 #define VEN2_PWR_CON_PWR_STA			20
89 #define AUDIO_PWR_CON_PWR_STA			24
90 #define MFG_ASYNC_PWR_CON_PWR_STA		23
91 #define MFG_2D_PWR_CON_PWR_STA			22
92 #define MFG_PWR_CON_PWR_STA			4
93 #define USB_PWR_CON_PWR_STA			25
94 
95 /*
96  * Timeout if the ack is not signled after 1 second.
97  * According to designer, one mtcmos operation should be done
98  * around 10us.
99  */
100 #define MTCMOS_ACK_POLLING_MAX_COUNT			10000
101 #define MTCMOS_ACK_POLLING_INTERVAL			10
102 
103 static void mtcmos_ctrl_little_off(unsigned int linear_id)
104 {
105 	uint32_t reg_pwr_con;
106 	uint32_t reg_l1_pdn;
107 	uint32_t bit_cpu;
108 
109 	switch (linear_id) {
110 	case 1:
111 		reg_pwr_con = SPM_CA7_CPU1_PWR_CON;
112 		reg_l1_pdn = SPM_CA7_CPU1_L1_PDN;
113 		bit_cpu = LITTLE_CPU1;
114 		break;
115 	case 2:
116 		reg_pwr_con = SPM_CA7_CPU2_PWR_CON;
117 		reg_l1_pdn = SPM_CA7_CPU2_L1_PDN;
118 		bit_cpu = LITTLE_CPU2;
119 		break;
120 	case 3:
121 		reg_pwr_con = SPM_CA7_CPU3_PWR_CON;
122 		reg_l1_pdn = SPM_CA7_CPU3_L1_PDN;
123 		bit_cpu = LITTLE_CPU3;
124 		break;
125 	default:
126 		/* should never come to here */
127 		return;
128 	}
129 
130 	/* enable register control */
131 	mmio_write_32(SPM_POWERON_CONFIG_SET,
132 			(SPM_PROJECT_CODE << 16) | (1U << 0));
133 
134 	mmio_setbits_32(reg_pwr_con, PWR_ISO);
135 	mmio_setbits_32(reg_pwr_con, SRAM_CKISO);
136 	mmio_clrbits_32(reg_pwr_con, SRAM_ISOINT_B);
137 	mmio_setbits_32(reg_l1_pdn, L1_PDN);
138 
139 	while (!(mmio_read_32(reg_l1_pdn) & L1_PDN_ACK))
140 		continue;
141 
142 	mmio_clrbits_32(reg_pwr_con, PWR_RST_B);
143 	mmio_setbits_32(reg_pwr_con, PWR_CLK_DIS);
144 	mmio_clrbits_32(reg_pwr_con, PWR_ON);
145 	mmio_clrbits_32(reg_pwr_con, PWR_ON_2ND);
146 
147 	while ((mmio_read_32(SPM_PWR_STATUS) & bit_cpu) ||
148 	       (mmio_read_32(SPM_PWR_STATUS_2ND) & bit_cpu))
149 		continue;
150 }
151 
152 void mtcmos_little_cpu_off(void)
153 {
154 	/* turn off little cpu 1 - 3 */
155 	mtcmos_ctrl_little_off(1);
156 	mtcmos_ctrl_little_off(2);
157 	mtcmos_ctrl_little_off(3);
158 }
159 
160 uint32_t wait_mtcmos_ack(uint32_t on, uint32_t pwr_ctrl, uint32_t spm_pwr_sta)
161 {
162 	int i = 0;
163 	uint32_t cmp, pwr_sta, pwr_sta_2nd;
164 
165 	while (1) {
166 		cmp = mmio_read_32(SPM_PCM_PASR_DPD_3) & pwr_ctrl;
167 		pwr_sta = (mmio_read_32(SPM_PWR_STATUS) >> spm_pwr_sta) & 1;
168 		pwr_sta_2nd =
169 			(mmio_read_32(SPM_PWR_STATUS_2ND) >> spm_pwr_sta) & 1;
170 		if (cmp && (pwr_sta == on) && (pwr_sta_2nd == on)) {
171 			mmio_write_32(SPM_PCM_RESERVE2, 0);
172 			return MTCMOS_CTRL_SUCCESS;
173 		}
174 		udelay(MTCMOS_ACK_POLLING_INTERVAL);
175 		i++;
176 		if (i > MTCMOS_ACK_POLLING_MAX_COUNT) {
177 			INFO("MTCMOS control failed(%d), SPM_PWR_STA(%d),\n"
178 				"SPM_PCM_RESERVE=0x%x,SPM_PCM_RESERVE2=0x%x,\n"
179 				"SPM_PWR_STATUS=0x%x,SPM_PWR_STATUS_2ND=0x%x\n"
180 				"SPM_PCM_PASR_DPD_3 = 0x%x\n",
181 				on, spm_pwr_sta, mmio_read_32(SPM_PCM_RESERVE),
182 				mmio_read_32(SPM_PCM_RESERVE2),
183 				mmio_read_32(SPM_PWR_STATUS),
184 				mmio_read_32(SPM_PWR_STATUS_2ND),
185 				mmio_read_32(SPM_PCM_PASR_DPD_3));
186 			mmio_write_32(SPM_PCM_RESERVE2, 0);
187 			return MTCMOS_CTRL_ERROR;
188 		}
189 	}
190 }
191 
192 uint32_t mtcmos_non_cpu_ctrl(uint32_t on, uint32_t mtcmos_num)
193 {
194 	uint32_t ret = MTCMOS_CTRL_SUCCESS;
195 	uint32_t power_on;
196 	uint32_t power_off;
197 	uint32_t power_ctrl;
198 	uint32_t power_status;
199 
200 	spm_lock_get();
201 	spm_mcdi_prepare_for_mtcmos();
202 	mmio_setbits_32(SPM_PCM_RESERVE, MTCMOS_CTRL_EN);
203 
204 	switch (mtcmos_num) {
205 	case SPM_VDE_PWR_CON:
206 		power_on = VDE_PWR_ON;
207 		power_off = VDE_PWR_OFF;
208 		power_status = VDE_PWR_CON_PWR_STA;
209 		break;
210 	case SPM_MFG_PWR_CON:
211 		power_on = MFG_PWR_ON;
212 		power_off = MFG_PWR_OFF;
213 		power_status = MFG_PWR_CON_PWR_STA;
214 		break;
215 	case SPM_VEN_PWR_CON:
216 		power_on = VEN_PWR_ON;
217 		power_off = VEN_PWR_OFF;
218 		power_status = VEN_PWR_CON_PWR_STA;
219 		break;
220 	case SPM_ISP_PWR_CON:
221 		power_on = ISP_PWR_ON;
222 		power_off = ISP_PWR_OFF;
223 		power_status = ISP_PWR_CON_PWR_STA;
224 		break;
225 	case SPM_DIS_PWR_CON:
226 		power_on = DIS_PWR_ON;
227 		power_off = DIS_PWR_OFF;
228 		power_status = DIS_PWR_CON_PWR_STA;
229 		break;
230 	case SPM_VEN2_PWR_CON:
231 		power_on = VEN2_PWR_ON;
232 		power_off = VEN2_PWR_OFF;
233 		power_status = VEN2_PWR_CON_PWR_STA;
234 		break;
235 	case SPM_AUDIO_PWR_CON:
236 		power_on = AUDIO_PWR_ON;
237 		power_off = AUDIO_PWR_OFF;
238 		power_status = AUDIO_PWR_CON_PWR_STA;
239 		break;
240 	case SPM_MFG_2D_PWR_CON:
241 		power_on = MFG_2D_PWR_ON;
242 		power_off = MFG_2D_PWR_OFF;
243 		power_status = MFG_2D_PWR_CON_PWR_STA;
244 		break;
245 	case SPM_MFG_ASYNC_PWR_CON:
246 		power_on = MFG_ASYNC_PWR_ON;
247 		power_off = MFG_ASYNC_PWR_OFF;
248 		power_status = MFG_ASYNC_PWR_CON_PWR_STA;
249 		break;
250 	case SPM_USB_PWR_CON:
251 		power_on = USB_PWR_ON;
252 		power_off = USB_PWR_OFF;
253 		power_status = USB_PWR_CON_PWR_STA;
254 		break;
255 	default:
256 		ret = MTCMOS_CTRL_ERROR;
257 		INFO("No mapping MTCMOS(%d), ret = %d\n", mtcmos_num, ret);
258 		break;
259 	}
260 	if (ret == MTCMOS_CTRL_SUCCESS) {
261 		power_ctrl = on ? (1 << power_on) : (1 << power_off);
262 		mmio_setbits_32(SPM_PCM_RESERVE2, power_ctrl);
263 		ret = wait_mtcmos_ack(on, power_ctrl, power_status);
264 		VERBOSE("0x%x(%d), PWR_STATUS(0x%x), ret(%d)\n",
265 			power_ctrl, on, mmio_read_32(SPM_PWR_STATUS), ret);
266 	}
267 
268 	mmio_clrbits_32(SPM_PCM_RESERVE, MTCMOS_CTRL_EN);
269 	spm_lock_release();
270 
271 	return ret;
272 }
273