drivers/mipi: Add support for KD_KD110N11_51IE panel
[coreboot2.git] / src / soc / mediatek / mt8186 / pmic_wrap.c
blob62cb72dc94fdf0774ed3bb080c6cdb8c26ffdb2d
1 /* SPDX-License-Identifier: GPL-2.0-only */
3 /*
4 * This file is created based on MT8186 Functional Specification
5 * Chapter number: 3.7
6 */
8 #include <device/mmio.h>
9 #include <soc/infracfg.h>
10 #include <soc/pll.h>
11 #include <soc/pmic_wrap.h>
12 #include <timer.h>
14 #define PRIORITY_FIELD(x) ((x % 4) * 8)
15 #define PRIORITY_IN(id, priority) (id << PRIORITY_FIELD(priority))
16 #define PRIORITY_OUT(id, priority) (priority << PRIORITY_FIELD(id))
18 enum {
19 MD_ADCINF0 = 8,
20 MD_ADCINF1 = 9,
21 STAUPD = 10,
22 GPSINF0 = 11,
24 PRIORITY_IN_SEL_2 = PRIORITY_IN(MD_ADCINF0, 9) |
25 PRIORITY_IN(MD_ADCINF1, 10) |
26 PRIORITY_IN(STAUPD, 8) |
27 PRIORITY_IN(GPSINF0, 11),
29 PRIORITY_OUT_SEL_2 = PRIORITY_OUT(MD_ADCINF0, 9) |
30 PRIORITY_OUT(MD_ADCINF1, 10) |
31 PRIORITY_OUT(STAUPD, 8) |
32 PRIORITY_OUT(GPSINF0, 11),
35 #define PENDING_US(x) x
36 enum {
37 STARVE_ENABLE = 0x1 << 10,
38 COUNTER0_PENDING_THRES = STARVE_ENABLE | PENDING_US(0x2),
39 COUNTER1_PENDING_THRES = STARVE_ENABLE | PENDING_US(0x3),
40 COUNTER2_PENDING_THRES = STARVE_ENABLE | PENDING_US(0x3),
41 COUNTER3_PENDING_THRES = STARVE_ENABLE | PENDING_US(0x3),
42 COUNTER4_PENDING_THRES = STARVE_ENABLE | PENDING_US(0xf),
43 COUNTER5_PENDING_THRES = STARVE_ENABLE | PENDING_US(0x20),
44 COUNTER6_PENDING_THRES = STARVE_ENABLE | PENDING_US(0x28),
45 COUNTER7_PENDING_THRES = STARVE_ENABLE | PENDING_US(0x28),
46 COUNTER8_PENDING_THRES = STARVE_ENABLE | PENDING_US(0x13),
47 COUNTER9_PENDING_THRES = STARVE_ENABLE | PENDING_US(0x17),
48 COUNTER10_PENDING_THRES = STARVE_ENABLE | PENDING_US(0x17),
49 COUNTER11_PENDING_THRES = STARVE_ENABLE | PENDING_US(0x7c),
50 COUNTER12_PENDING_THRES = STARVE_ENABLE | PENDING_US(0x7c),
51 COUNTER13_PENDING_THRES = STARVE_ENABLE | PENDING_US(0x340),
52 COUNTER16_PENDING_THRES = STARVE_ENABLE | PENDING_US(0x340),
55 static void pwrap_soft_reset(void)
57 write32(&mt8186_infracfg_ao->infra_globalcon_rst2_set, 0x1);
58 write32(&mt8186_infracfg_ao->infra_globalcon_rst2_clr, 0x1);
61 static void pwrap_spi_clk_set(void)
63 write32(&mt8186_infracfg_ao->module_sw_cg_0_set, 0x0000000f);
64 write32(&mt8186_infracfg_ao->module_sw_cg_2_set, 0x00000100);
66 write32(&mtk_topckgen->clk_cfg_8_clr, 0x00970000);
67 write32(&mtk_topckgen->clk_cfg_8_set, 0x00040000);
68 write32(&mtk_topckgen->clk_cfg_update1, (0x1 << 3));
70 write32(&mt8186_infracfg_ao->pmicw_clock_ctrl,
71 read32(&mt8186_infracfg_ao->pmicw_clock_ctrl) & ~(0x1 << 2));
73 pwrap_soft_reset();
75 write32(&mt8186_infracfg_ao->module_sw_cg_0_clr, 0x0000000f);
76 write32(&mt8186_infracfg_ao->module_sw_cg_2_clr, 0x00000100);
79 static s32 pwrap_init_dio(u16 dio_en)
81 pwrap_write_nochk(PMIC_DEW_DIO_EN, dio_en);
83 if (!wait_us(100,
84 !wait_for_idle_and_sync(read32(&mtk_pwrap->wacs2_rdata))))
85 return -1;
87 write32(&mtk_pwrap->dio_en, dio_en);
88 return 0;
91 static void pwrap_lock_spislvreg(void)
93 pwrap_write_nochk(PMIC_SPISLV_KEY, 0x0);
96 static void pwrap_initstaupd(void)
98 write32(&mtk_pwrap->staupd_grpen,
99 SIG_PMIC_0 | INT_STA_PMIC_0 | MD_ADC_DATA0 |
100 MD_ADC_DATA1 | GPS_ADC_DATA0 | GPS_ADC_DATA1);
102 /* CRC */
103 pwrap_write_nochk(PMIC_DEW_CRC_EN, 0x1);
104 write32(&mtk_pwrap->crc_en, 0x1);
105 write32(&mtk_pwrap->sig_adr, PMIC_DEW_CRC_VAL);
107 write32(&mtk_pwrap->eint_sta0_adr, PMIC_CPU_INT_STA);
109 /* MD ADC Interface */
110 write32(&mtk_pwrap->md_auxadc_rdata_latest_addr,
111 (PMIC_AUXADC_ADC35 << 16) + PMIC_AUXADC_ADC31);
112 write32(&mtk_pwrap->md_auxadc_rdata_wp_addr,
113 (PMIC_AUXADC_ADC35 << 16) + PMIC_AUXADC_ADC31);
114 for (size_t i = 0; i < 32; i++)
115 write32(&mtk_pwrap->md_auxadc_rdata[i],
116 (PMIC_AUXADC_ADC35 << 16) + PMIC_AUXADC_ADC31);
118 write32(&mtk_pwrap->int_gps_auxadc_cmd_addr,
119 (PMIC_AUXADC_RQST1 << 16) + PMIC_AUXADC_RQST0);
120 write32(&mtk_pwrap->int_gps_auxadc_cmd, (GPS_MAIN << 16) + GPS_SUBSYS);
121 write32(&mtk_pwrap->int_gps_auxadc_rdata_addr,
122 (PMIC_AUXADC_ADC32 << 16) + PMIC_AUXADC_ADC17);
124 write32(&mtk_pwrap->ext_gps_auxadc_rdata_addr, PMIC_AUXADC_ADC31);
127 static void pwrap_starve_set(void)
129 write32(&mtk_pwrap->harb_hprio, ARB_PRIORITY);
130 write32(&mtk_pwrap->starv_counter_0, COUNTER0_PENDING_THRES);
131 write32(&mtk_pwrap->starv_counter_1, COUNTER1_PENDING_THRES);
132 write32(&mtk_pwrap->starv_counter_2, COUNTER2_PENDING_THRES);
133 write32(&mtk_pwrap->starv_counter_3, COUNTER3_PENDING_THRES);
134 write32(&mtk_pwrap->starv_counter_4, COUNTER4_PENDING_THRES);
135 write32(&mtk_pwrap->starv_counter_5, COUNTER5_PENDING_THRES);
136 write32(&mtk_pwrap->starv_counter_6, COUNTER6_PENDING_THRES);
137 write32(&mtk_pwrap->starv_counter_7, COUNTER7_PENDING_THRES);
138 write32(&mtk_pwrap->starv_counter_8, COUNTER8_PENDING_THRES);
139 write32(&mtk_pwrap->starv_counter_9, COUNTER9_PENDING_THRES);
140 write32(&mtk_pwrap->starv_counter_10, COUNTER10_PENDING_THRES);
141 write32(&mtk_pwrap->starv_counter_11, COUNTER11_PENDING_THRES);
142 write32(&mtk_pwrap->starv_counter_12, COUNTER12_PENDING_THRES);
143 write32(&mtk_pwrap->starv_counter_13, COUNTER13_PENDING_THRES);
144 write32(&mtk_pwrap->starv_counter_16, COUNTER16_PENDING_THRES);
147 static void pwrap_enable(void)
149 write32(&mtk_pwrap->hiprio_arb_en, ARB_USER_EN);
150 write32(&mtk_pwrap->wacs0_en, 0x1);
151 write32(&mtk_pwrap->wacs2_en, 0x1);
152 write32(&mtk_pwrap->wacs_p2p_en, 0x1);
153 write32(&mtk_pwrap->wacs_md32_en, 0x1);
154 write32(&mtk_pwrap->staupd_ctrl, STA_PD_98_5_US);
155 write32(&mtk_pwrap->wdt_ctrl, WATCHDOG_TIMER_7_5_MS);
156 write32(&mtk_pwrap->wdt_src_en_0, WDT_MONITOR_ALL);
157 write32(&mtk_pwrap->wdt_src_en_1, WDT_MONITOR_ALL);
158 write32(&mtk_pwrap->timer_ctrl, 0x1);
159 write32(&mtk_pwrap->int0_en, INT0_MONITOR);
160 write32(&mtk_pwrap->int1_en, INT1_MONITOR);
163 static s32 pwrap_init_sistrobe(void)
165 u16 rdata;
166 int si_sample_ctrl;
167 int test_data[30] = {
168 0x6996, 0x9669, 0x6996, 0x9669, 0x6996, 0x9669, 0x6996,
169 0x9669, 0x6996, 0x9669, 0x5AA5, 0xA55A, 0x5AA5, 0xA55A,
170 0x5AA5, 0xA55A, 0x5AA5, 0xA55A, 0x5AA5, 0xA55A, 0x1B27,
171 0x1B27, 0x1B27, 0x1B27, 0x1B27, 0x1B27, 0x1B27, 0x1B27,
172 0x1B27, 0x1B27};
174 for (si_sample_ctrl = 0; si_sample_ctrl < 16; si_sample_ctrl++) {
175 write32(&mtk_pwrap->si_sample_ctrl, si_sample_ctrl << 5);
177 pwrap_read_nochk(PMIC_DEW_READ_TEST, &rdata);
178 if (rdata == DEFAULT_VALUE_READ_TEST)
179 break;
182 if (si_sample_ctrl == 16)
183 return E_CLK_EDGE;
185 if (si_sample_ctrl == 15)
186 return E_CLK_LAST_SETTING;
189 * Add the delay time of SPI data from PMIC to align the start boundary
190 * to current sampling clock edge.
192 for (int si_dly = 0; si_dly < 10; si_dly++) {
193 pwrap_write_nochk(PMIC_RG_SPI_CON2, si_dly);
195 int start_boundary_found = 0;
196 for (size_t i = 0; i < 30; i++) {
197 pwrap_write_nochk(PMIC_DEW_WRITE_TEST, test_data[i]);
198 pwrap_read_nochk(PMIC_DEW_WRITE_TEST, &rdata);
199 if ((rdata & 0x7fff) != (test_data[i] & 0x7fff)) {
200 start_boundary_found = 1;
201 break;
204 if (start_boundary_found == 1)
205 break;
209 * Change the sampling clock edge to the next one which is the middle
210 * of SPI data window.
212 write32(&mtk_pwrap->si_sample_ctrl, ++si_sample_ctrl << 5);
214 /* Read Test */
215 pwrap_read_nochk(PMIC_DEW_READ_TEST, &rdata);
216 if (rdata != DEFAULT_VALUE_READ_TEST) {
217 pwrap_err("rdata = %#x, exp = %#x\n", rdata,
218 DEFAULT_VALUE_READ_TEST);
219 return E_PWR_READ_TEST_FAIL;
222 return 0;
225 static void pwrap_init_spislv(void)
227 /* Turn on IO filter function */
228 pwrap_write_nochk(PMIC_FILTER_CON0, SPI_FILTER);
229 /* Turn on IO SMT function to improve noise immunity */
230 pwrap_write_nochk(PMIC_SMT_CON1, SPI_SMT);
231 /* Turn off IO pull function for power saving */
232 pwrap_write_nochk(PMIC_GPIO_PULLEN0_CLR, SPI_PULL_DISABLE);
233 /* Enable SPI R/W in suspend mode */
234 pwrap_write_nochk(PMIC_RG_SPI_CON0, 0x1);
235 /* Set PMIC GPIO driving current to 4mA */
236 pwrap_write_nochk(PMIC_DRV_CON1, SPI_DRIVING);
239 static void pwrap_init_reg_clock(void)
241 write32(&mtk_pwrap->ext_ck_write, 0x1);
243 pwrap_write_nochk(PMIC_DEW_RDDMY_NO, DUMMY_READ_CYCLES);
244 write32(&mtk_pwrap->rddmy, DUMMY_READ_CYCLES);
246 write32(&mtk_pwrap->cshext_write, 0);
247 write32(&mtk_pwrap->cshext_read, 0);
248 write32(&mtk_pwrap->cslext_write, 0);
249 write32(&mtk_pwrap->cslext_read, 0);
252 s32 pwrap_init(void)
254 s32 sub_return = 0, sub_return1 = 0;
255 u16 rdata;
257 pwrap_spi_clk_set();
259 /* Reset spislv */
260 sub_return = pwrap_reset_spislv();
261 if (sub_return != 0) {
262 pwrap_err("reset_spislv fail, ret=%d\n", sub_return);
263 return E_PWR_INIT_RESET_SPI;
266 /* Enable WRAP */
267 write32(&mtk_pwrap->wrap_en, 0x1);
269 /* Enable WACS2 */
270 write32(&mtk_pwrap->wacs2_en, 0x1);
271 write32(&mtk_pwrap->hiprio_arb_en, WACS2); /* ONLY WACS2 */
273 /* SPI Waveform Configuration */
274 pwrap_init_reg_clock();
276 /* SPI Slave Configuration */
277 pwrap_init_spislv();
279 /* Enable DIO mode */
280 sub_return = pwrap_init_dio(1);
281 if (sub_return != 0) {
282 pwrap_err("dio test error, ret=%d\n", sub_return);
283 return E_PWR_INIT_DIO;
286 /* Input data calibration flow; */
287 sub_return = pwrap_init_sistrobe();
288 if (sub_return != 0) {
289 pwrap_err("InitSiStrobe fail,ret=%d\n", sub_return);
290 return E_PWR_INIT_SIDLY;
294 * Write test using WACS2,
295 * make sure the read/write function ready.
297 sub_return = pwrap_write_nochk(PMIC_DEW_WRITE_TEST, WRITE_TEST_VALUE);
298 sub_return1 = pwrap_read_nochk(PMIC_DEW_WRITE_TEST, &rdata);
299 if (rdata != WRITE_TEST_VALUE || sub_return || sub_return1) {
300 pwrap_err("write error, rdata=%#x, return=%d, return1=%d\n",
301 rdata, sub_return, sub_return1);
302 return E_PWR_INIT_WRITE_TEST;
306 * Status update function initialization
307 * 1. Signature Checking using CRC (CRC 0 only)
308 * 2. EINT update
309 * 3. Read back Auxadc thermal data for GPS
311 pwrap_initstaupd();
313 write32(&mtk_pwrap->priority_user_sel_2, PRIORITY_IN_SEL_2);
314 write32(&mtk_pwrap->arbiter_out_sel_2, PRIORITY_OUT_SEL_2);
316 pwrap_starve_set();
318 pwrap_enable();
320 /* Initialization Done */
321 write32(&mtk_pwrap->init_done0, 0x1);
322 write32(&mtk_pwrap->init_done2, 0x1);
323 write32(&mtk_pwrap->init_done_p2p, 0x1);
324 write32(&mtk_pwrap->init_done_md32, 0x1);
326 /* Lock SPISLV Registers */
327 pwrap_lock_spislvreg();
329 return 0;