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