blob: 4d195b79f0959ba49dda3a4bd2b7a5f0968c5ffb [file] [log] [blame]
Angel Ponse67ab182020-04-04 18:51:11 +02001/* SPDX-License-Identifier: GPL-2.0-only */
Hsin-Hsiung Wanga6db8f32018-10-24 17:57:55 +08002
Kyösti Mälkki13f66502019-03-03 08:01:05 +02003#include <device/mmio.h>
Hsin-Hsiung Wanga6db8f32018-10-24 17:57:55 +08004#include <soc/infracfg.h>
5#include <soc/pll.h>
6#include <soc/pmic_wrap.h>
Elyes HAOUASadd76f92019-03-21 09:55:49 +01007#include <timer.h>
Hsin-Hsiung Wanga6db8f32018-10-24 17:57:55 +08008
9#define PRIORITY_FIELD(x) ((x % 4) * 8)
10#define PRIORITY_IN(id, priority) (id << PRIORITY_FIELD(priority))
11#define PRIORITY_OUT(id, priority) (priority << PRIORITY_FIELD(id))
12
13enum {
14 MD_ADCINF0 = 8,
15 MD_ADCINF1 = 9,
16 STAUPD = 10,
17 GPSINF0 = 11,
18
19 PRIORITY_IN_SEL_2 = PRIORITY_IN(MD_ADCINF0, 9) |
20 PRIORITY_IN(MD_ADCINF1, 10) |
21 PRIORITY_IN(STAUPD, 8) |
22 PRIORITY_IN(GPSINF0, 11),
23
24 PRIORITY_OUT_SEL_2 = PRIORITY_OUT(MD_ADCINF0, 9) |
25 PRIORITY_OUT(MD_ADCINF1, 10) |
26 PRIORITY_OUT(STAUPD, 8) |
27 PRIORITY_OUT(GPSINF0, 11),
28};
29
30#define PENDING_US(x) x
31enum {
32 STARVE_ENABLE = 0x1 << 10,
33 COUNTER0_PENDING_THRES = STARVE_ENABLE | PENDING_US(0x2),
34 COUNTER1_PENDING_THRES = STARVE_ENABLE | PENDING_US(0x3),
35 COUNTER2_PENDING_THRES = STARVE_ENABLE | PENDING_US(0x3),
36 COUNTER3_PENDING_THRES = STARVE_ENABLE | PENDING_US(0x3),
37 COUNTER4_PENDING_THRES = STARVE_ENABLE | PENDING_US(0xf),
38 COUNTER5_PENDING_THRES = STARVE_ENABLE | PENDING_US(0x20),
39 COUNTER6_PENDING_THRES = STARVE_ENABLE | PENDING_US(0x28),
40 COUNTER7_PENDING_THRES = STARVE_ENABLE | PENDING_US(0x28),
41 COUNTER8_PENDING_THRES = STARVE_ENABLE | PENDING_US(0x13),
42 COUNTER9_PENDING_THRES = STARVE_ENABLE | PENDING_US(0x17),
43 COUNTER10_PENDING_THRES = STARVE_ENABLE | PENDING_US(0x17),
44 COUNTER11_PENDING_THRES = STARVE_ENABLE | PENDING_US(0x7c),
45 COUNTER12_PENDING_THRES = STARVE_ENABLE | PENDING_US(0x7c),
46 COUNTER13_PENDING_THRES = STARVE_ENABLE | PENDING_US(0x340),
47 COUNTER16_PENDING_THRES = STARVE_ENABLE | PENDING_US(0x340),
48};
49
Hsin-Hsiung Wanga6db8f32018-10-24 17:57:55 +080050static void pwrap_soft_reset(void)
51{
52 write32(&mt8183_infracfg->infra_globalcon_rst2_set, 0x1);
53 write32(&mt8183_infracfg->infra_globalcon_rst2_clr, 0x1);
54}
55
56static void pwrap_spi_clk_set(void)
57{
58 write32(&mtk_topckgen->clk_cfg_5_clr,
59 ULPOSC_OFF | ULPOSC_INV | ULPOSC_SEL_1 | ULPOSC_SEL_2);
60 write32(&mtk_topckgen->clk_cfg_5_set, ULPOSC_SEL_1);
61 write32(&mtk_topckgen->clk_cfg_update, ULPOSC_CLK);
62
63 write32(&mt8183_infracfg->module_sw_cg_0_set,
64 TIMER_CG | AP_CG | MD_CG | CONN_CG);
65 write32(&mt8183_infracfg->module_sw_cg_2_set, MODEM_TEMP_SHARE_CG);
66
67 pwrap_soft_reset();
68
69 write32(&mt8183_infracfg->module_sw_cg_0_clr,
70 TIMER_CG | AP_CG | MD_CG | CONN_CG);
71 write32(&mt8183_infracfg->module_sw_cg_2_clr, MODEM_TEMP_SHARE_CG);
72}
73
74static s32 pwrap_init_dio(u16 dio_en)
75{
76 pwrap_write_nochk(PMIC_DEW_DIO_EN, dio_en);
77
78 if (!wait_us(100,
79 !wait_for_idle_and_sync(read32(&mtk_pwrap->wacs2_rdata))))
80 return -1;
81
82 write32(&mtk_pwrap->dio_en, dio_en);
83 return 0;
84}
85
86static void pwrap_lock_spislvreg(void)
87{
88 pwrap_write_nochk(PMIC_SPISLV_KEY, 0x0);
89}
90
91static void pwrap_initstaupd(void)
92{
93 write32(&mtk_pwrap->staupd_grpen,
94 SIG_PMIC_0 | INT_STA_PMIC_0 | MD_ADC_DATA0 |
95 MD_ADC_DATA1 | GPS_ADC_DATA0 | GPS_ADC_DATA1);
96
97 /* CRC */
98 pwrap_write_nochk(PMIC_DEW_CRC_EN, 0x1);
99 write32(&mtk_pwrap->crc_en, 0x1);
100 write32(&mtk_pwrap->sig_adr, PMIC_DEW_CRC_VAL);
101
102 write32(&mtk_pwrap->eint_sta0_adr, PMIC_CPU_INT_STA);
103
104 /* MD ADC Interface */
105 write32(&mtk_pwrap->md_auxadc_rdata_latest_addr,
106 (PMIC_AUXADC_ADC35 << 16) + PMIC_AUXADC_ADC31);
107 write32(&mtk_pwrap->md_auxadc_rdata_wp_addr,
108 (PMIC_AUXADC_ADC35 << 16) + PMIC_AUXADC_ADC31);
109 for (size_t i = 0; i < 32; i++)
110 write32(&mtk_pwrap->md_auxadc_rdata[i],
111 (PMIC_AUXADC_ADC35 << 16) + PMIC_AUXADC_ADC31);
112
113 write32(&mtk_pwrap->int_gps_auxadc_cmd_addr,
114 (PMIC_AUXADC_RQST1 << 16) + PMIC_AUXADC_RQST0);
115 write32(&mtk_pwrap->int_gps_auxadc_cmd, (GPS_MAIN << 16) + GPS_SUBSYS);
116 write32(&mtk_pwrap->int_gps_auxadc_rdata_addr,
117 (PMIC_AUXADC_ADC32 << 16) + PMIC_AUXADC_ADC17);
118
119 write32(&mtk_pwrap->ext_gps_auxadc_rdata_addr, PMIC_AUXADC_ADC31);
120}
121
122static void pwrap_starve_set(void)
123{
124 write32(&mtk_pwrap->harb_hprio, ARB_PRIORITY);
125 write32(&mtk_pwrap->starv_counter_0, COUNTER0_PENDING_THRES);
126 write32(&mtk_pwrap->starv_counter_1, COUNTER1_PENDING_THRES);
127 write32(&mtk_pwrap->starv_counter_2, COUNTER2_PENDING_THRES);
128 write32(&mtk_pwrap->starv_counter_3, COUNTER3_PENDING_THRES);
129 write32(&mtk_pwrap->starv_counter_4, COUNTER4_PENDING_THRES);
130 write32(&mtk_pwrap->starv_counter_5, COUNTER5_PENDING_THRES);
131 write32(&mtk_pwrap->starv_counter_6, COUNTER6_PENDING_THRES);
132 write32(&mtk_pwrap->starv_counter_7, COUNTER7_PENDING_THRES);
133 write32(&mtk_pwrap->starv_counter_8, COUNTER8_PENDING_THRES);
134 write32(&mtk_pwrap->starv_counter_9, COUNTER9_PENDING_THRES);
135 write32(&mtk_pwrap->starv_counter_10, COUNTER10_PENDING_THRES);
136 write32(&mtk_pwrap->starv_counter_11, COUNTER11_PENDING_THRES);
137 write32(&mtk_pwrap->starv_counter_12, COUNTER12_PENDING_THRES);
138 write32(&mtk_pwrap->starv_counter_13, COUNTER13_PENDING_THRES);
139 write32(&mtk_pwrap->starv_counter_16, COUNTER16_PENDING_THRES);
140}
141
142static void pwrap_enable(void)
143{
144 write32(&mtk_pwrap->hiprio_arb_en, ARB_USER_EN);
145 write32(&mtk_pwrap->wacs0_en, 0x1);
146 write32(&mtk_pwrap->wacs2_en, 0x1);
147 write32(&mtk_pwrap->wacs_p2p_en, 0x1);
148 write32(&mtk_pwrap->wacs_md32_en, 0x1);
149 write32(&mtk_pwrap->staupd_ctrl, STA_PD_98_5_US);
150 write32(&mtk_pwrap->wdt_unit, WATCHDOG_TIMER_7_5_MS);
151 write32(&mtk_pwrap->wdt_src_en_0, WDT_MONITOR_ALL);
152 write32(&mtk_pwrap->wdt_src_en_1, WDT_MONITOR_ALL);
153 write32(&mtk_pwrap->timer_en, 0x1);
154 write32(&mtk_pwrap->int0_en, INT0_MONITOR);
155 write32(&mtk_pwrap->int1_en, INT1_MONITOR);
156}
157
158static s32 pwrap_init_sistrobe(void)
159{
160 u16 rdata;
161 int si_sample_ctrl;
162 int test_data[30] = {
163 0x6996, 0x9669, 0x6996, 0x9669, 0x6996, 0x9669, 0x6996,
164 0x9669, 0x6996, 0x9669, 0x5AA5, 0xA55A, 0x5AA5, 0xA55A,
165 0x5AA5, 0xA55A, 0x5AA5, 0xA55A, 0x5AA5, 0xA55A, 0x1B27,
166 0x1B27, 0x1B27, 0x1B27, 0x1B27, 0x1B27, 0x1B27, 0x1B27,
167 0x1B27, 0x1B27};
168
169 for (si_sample_ctrl = 0; si_sample_ctrl < 16; si_sample_ctrl++) {
170 write32(&mtk_pwrap->si_sample_ctrl, si_sample_ctrl << 5);
171
172 pwrap_read_nochk(PMIC_DEW_READ_TEST, &rdata);
173 if (rdata == DEFAULT_VALUE_READ_TEST)
174 break;
175 }
176
177 if (si_sample_ctrl == 16)
178 return E_CLK_EDGE;
179
180 if (si_sample_ctrl == 15)
181 return E_CLK_LAST_SETTING;
182
183 /*
184 * Add the delay time of SPI data from PMIC to align the start boundary
185 * to current sampling clock edge.
186 */
187 for (int si_dly = 0; si_dly < 10; si_dly++) {
188 pwrap_write_nochk(PMIC_RG_SPI_CON2, si_dly);
189
190 int start_boundary_found = 0;
191 for (size_t i = 0; i < 30; i++) {
192 pwrap_write_nochk(PMIC_DEW_WRITE_TEST, test_data[i]);
193 pwrap_read_nochk(PMIC_DEW_WRITE_TEST, &rdata);
194 if ((rdata & 0x7fff) != (test_data[i] & 0x7fff)) {
195 start_boundary_found = 1;
196 break;
197 }
198 }
199 if (start_boundary_found == 1)
200 break;
201 }
202
203 /*
204 * Change the sampling clock edge to the next one which is the middle
205 * of SPI data window.
206 */
207 write32(&mtk_pwrap->si_sample_ctrl, ++si_sample_ctrl << 5);
208
209 /* Read Test */
210 pwrap_read_nochk(PMIC_DEW_READ_TEST, &rdata);
211 if (rdata != DEFAULT_VALUE_READ_TEST) {
212 pwrap_err("rdata = %#x, exp = %#x\n", rdata,
213 DEFAULT_VALUE_READ_TEST);
214 return E_PWR_READ_TEST_FAIL;
215 }
216
217 return 0;
218}
219
220static void pwrap_init_spislv(void)
221{
222 /* Turn on IO filter function */
223 pwrap_write_nochk(PMIC_FILTER_CON0, SPI_FILTER);
224 /* Turn on IO SMT function to improve noise immunity */
225 pwrap_write_nochk(PMIC_SMT_CON1, SPI_SMT);
226 /* Turn off IO pull function for power saving */
227 pwrap_write_nochk(PMIC_GPIO_PULLEN0_CLR, SPI_PULL_DISABLE);
228 /* Enable SPI R/W in suspend mode */
229 pwrap_write_nochk(PMIC_RG_SPI_CON0, 0x1);
230 /* Set PMIC GPIO driving current to 4mA */
231 pwrap_write_nochk(PMIC_DRV_CON1, SPI_DRIVING);
232}
233
234static void pwrap_init_reg_clock(void)
235{
236 write32(&mtk_pwrap->ext_ck_write, 0x1);
237
238 pwrap_write_nochk(PMIC_DEW_RDDMY_NO, DUMMY_READ_CYCLES);
239 write32(&mtk_pwrap->rddmy, DUMMY_READ_CYCLES);
240
241 write32(&mtk_pwrap->cshext_write, 0);
242 write32(&mtk_pwrap->cshext_read, 0);
243 write32(&mtk_pwrap->cslext_write, 0);
244 write32(&mtk_pwrap->cslext_read, 0);
245}
246
247s32 pwrap_init(void)
248{
249 s32 sub_return = 0, sub_return1 = 0;
250 u16 rdata;
251
252 pwrap_spi_clk_set();
253
254 /* Reset spislv */
255 sub_return = pwrap_reset_spislv();
256 if (sub_return != 0) {
257 pwrap_err("reset_spislv fail, ret=%d\n", sub_return);
258 return E_PWR_INIT_RESET_SPI;
259 }
260
261 /* Enable WRAP */
262 write32(&mtk_pwrap->wrap_en, 0x1);
263
264 /* Enable WACS2 */
265 write32(&mtk_pwrap->wacs2_en, 0x1);
266 write32(&mtk_pwrap->hiprio_arb_en, WACS2); /* ONLY WACS2 */
267
268 /* SPI Waveform Configuration */
269 pwrap_init_reg_clock();
270
271 /* SPI Slave Configuration */
272 pwrap_init_spislv();
273
274 /* Enable DIO mode */
275 sub_return = pwrap_init_dio(1);
276 if (sub_return != 0) {
277 pwrap_err("dio test error, ret=%d\n", sub_return);
278 return E_PWR_INIT_DIO;
279 }
280
281 /* Input data calibration flow; */
282 sub_return = pwrap_init_sistrobe();
283 if (sub_return != 0) {
284 pwrap_err("InitSiStrobe fail,ret=%d\n", sub_return);
285 return E_PWR_INIT_SIDLY;
286 }
287
288 /*
289 * Write test using WACS2,
290 * make sure the read/write function ready.
291 */
292 sub_return = pwrap_write_nochk(PMIC_DEW_WRITE_TEST, WRITE_TEST_VALUE);
293 sub_return1 = pwrap_read_nochk(PMIC_DEW_WRITE_TEST, &rdata);
294 if (rdata != WRITE_TEST_VALUE || sub_return || sub_return1) {
295 pwrap_err("write error, rdata=%#x, return=%d, return1=%d\n",
296 rdata, sub_return, sub_return1);
297 return E_PWR_INIT_WRITE_TEST;
298 }
299
300 /*
301 * Status update function initialization
302 * 1. Signature Checking using CRC (CRC 0 only)
303 * 2. EINT update
304 * 3. Read back Auxadc thermal data for GPS
305 */
306 pwrap_initstaupd();
307
308 write32(&mtk_pwrap->priority_user_sel_2, PRIORITY_IN_SEL_2);
309 write32(&mtk_pwrap->arbiter_out_sel_2, PRIORITY_OUT_SEL_2);
310
311 pwrap_starve_set();
312
313 pwrap_enable();
314
315 /* Initialization Done */
316 write32(&mtk_pwrap->init_done0, 0x1);
317 write32(&mtk_pwrap->init_done2, 0x1);
318 write32(&mtk_pwrap->init_done_p2p, 0x1);
319 write32(&mtk_pwrap->init_done_md32, 0x1);
320
321 /* Lock SPISLV Registers */
322 pwrap_lock_spislvreg();
323
324 return 0;
325}