coreboot
coreboot is an Open Source project aimed at replacing the proprietary BIOS found in most computers.
pmic_wrap.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 
3 /*
4  * This file is created based on MT8186 Functional Specification
5  * Chapter number: 3.7
6  */
7 
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>
13 
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))
17 
18 enum {
21  STAUPD = 10,
22  GPSINF0 = 11,
23 
25  PRIORITY_IN(MD_ADCINF1, 10) |
26  PRIORITY_IN(STAUPD, 8) |
28 
31  PRIORITY_OUT(STAUPD, 8) |
33 };
34 
35 #define PENDING_US(x) x
36 enum {
37  STARVE_ENABLE = 0x1 << 10,
53 };
54 
55 static void pwrap_soft_reset(void)
56 {
59 }
60 
61 static void pwrap_spi_clk_set(void)
62 {
65 
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));
69 
71  read32(&mt8186_infracfg_ao->pmicw_clock_ctrl) & ~(0x1 << 2));
72 
74 
77 }
78 
79 static s32 pwrap_init_dio(u16 dio_en)
80 {
82 
83  if (!wait_us(100,
85  return -1;
86 
87  write32(&mtk_pwrap->dio_en, dio_en);
88  return 0;
89 }
90 
91 static void pwrap_lock_spislvreg(void)
92 {
94 }
95 
96 static void pwrap_initstaupd(void)
97 {
101 
102  /* CRC */
104  write32(&mtk_pwrap->crc_en, 0x1);
106 
107  write32(&mtk_pwrap->eint_sta0_adr, PMIC_CPU_INT_STA);
108 
109  /* MD ADC Interface */
110  write32(&mtk_pwrap->md_auxadc_rdata_latest_addr,
112  write32(&mtk_pwrap->md_auxadc_rdata_wp_addr,
114  for (size_t i = 0; i < 32; i++)
115  write32(&mtk_pwrap->md_auxadc_rdata[i],
117 
118  write32(&mtk_pwrap->int_gps_auxadc_cmd_addr,
120  write32(&mtk_pwrap->int_gps_auxadc_cmd, (GPS_MAIN << 16) + GPS_SUBSYS);
121  write32(&mtk_pwrap->int_gps_auxadc_rdata_addr,
123 
124  write32(&mtk_pwrap->ext_gps_auxadc_rdata_addr, PMIC_AUXADC_ADC31);
125 }
126 
127 static void pwrap_starve_set(void)
128 {
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);
145 }
146 
147 static void pwrap_enable(void)
148 {
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);
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);
161 }
162 
164 {
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};
173 
174  for (si_sample_ctrl = 0; si_sample_ctrl < 16; si_sample_ctrl++) {
175  write32(&mtk_pwrap->si_sample_ctrl, si_sample_ctrl << 5);
176 
178  if (rdata == DEFAULT_VALUE_READ_TEST)
179  break;
180  }
181 
182  if (si_sample_ctrl == 16)
183  return E_CLK_EDGE;
184 
185  if (si_sample_ctrl == 15)
186  return E_CLK_LAST_SETTING;
187 
188  /*
189  * Add the delay time of SPI data from PMIC to align the start boundary
190  * to current sampling clock edge.
191  */
192  for (int si_dly = 0; si_dly < 10; si_dly++) {
194 
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]);
199  if ((rdata & 0x7fff) != (test_data[i] & 0x7fff)) {
200  start_boundary_found = 1;
201  break;
202  }
203  }
204  if (start_boundary_found == 1)
205  break;
206  }
207 
208  /*
209  * Change the sampling clock edge to the next one which is the middle
210  * of SPI data window.
211  */
212  write32(&mtk_pwrap->si_sample_ctrl, ++si_sample_ctrl << 5);
213 
214  /* Read Test */
216  if (rdata != DEFAULT_VALUE_READ_TEST) {
217  pwrap_err("rdata = %#x, exp = %#x\n", rdata,
219  return E_PWR_READ_TEST_FAIL;
220  }
221 
222  return 0;
223 }
224 
225 static void pwrap_init_spislv(void)
226 {
227  /* Turn on IO filter function */
229  /* Turn on IO SMT function to improve noise immunity */
231  /* Turn off IO pull function for power saving */
233  /* Enable SPI R/W in suspend mode */
235  /* Set PMIC GPIO driving current to 4mA */
237 }
238 
239 static void pwrap_init_reg_clock(void)
240 {
241  write32(&mtk_pwrap->ext_ck_write, 0x1);
242 
245 
248  write32(&mtk_pwrap->cslext_write, 0);
249  write32(&mtk_pwrap->cslext_read, 0);
250 }
251 
253 {
254  s32 sub_return = 0, sub_return1 = 0;
255  u16 rdata;
256 
258 
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;
264  }
265 
266  /* Enable WRAP */
267  write32(&mtk_pwrap->wrap_en, 0x1);
268 
269  /* Enable WACS2 */
270  write32(&mtk_pwrap->wacs2_en, 0x1);
271  write32(&mtk_pwrap->hiprio_arb_en, WACS2); /* ONLY WACS2 */
272 
273  /* SPI Waveform Configuration */
275 
276  /* SPI Slave Configuration */
278 
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;
284  }
285 
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;
291  }
292 
293  /*
294  * Write test using WACS2,
295  * make sure the read/write function ready.
296  */
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;
303  }
304 
305  /*
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
310  */
312 
313  write32(&mtk_pwrap->priority_user_sel_2, PRIORITY_IN_SEL_2);
314  write32(&mtk_pwrap->arbiter_out_sel_2, PRIORITY_OUT_SEL_2);
315 
317 
318  pwrap_enable();
319 
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);
325 
326  /* Lock SPISLV Registers */
328 
329  return 0;
330 }
static void write32(void *addr, uint32_t val)
Definition: mmio.h:40
static uint32_t read32(const void *addr)
Definition: mmio.h:22
s32 pwrap_reset_spislv(void)
Definition: pmic_wrap.c:66
#define wait_us(timeout_us, condition)
Definition: timer.h:198
static struct mt8173_pwrap_regs *const mtk_pwrap
Definition: pmic_wrap.h:10
@ WACS2
Definition: pmic_wrap.h:13
s32 pwrap_init(void)
Definition: pmic_wrap.c:154
@ ARB_PRIORITY
Definition: pmic_wrap.h:331
@ ARB_USER_EN
Definition: pmic_wrap.h:348
@ GPS_MAIN
Definition: pmic_wrap.h:291
@ GPS_SUBSYS
Definition: pmic_wrap.h:292
@ INT0_MONITOR
Definition: pmic_wrap.h:370
@ INT1_MONITOR
Definition: pmic_wrap.h:371
@ MD_ADC_DATA0
Definition: pmic_wrap.h:320
@ MD_ADC_DATA1
Definition: pmic_wrap.h:321
@ GPS_ADC_DATA0
Definition: pmic_wrap.h:322
@ INT_STA_PMIC_0
Definition: pmic_wrap.h:319
@ SIG_PMIC_0
Definition: pmic_wrap.h:318
@ GPS_ADC_DATA1
Definition: pmic_wrap.h:323
@ PMIC_AUXADC_ADC35
Definition: pmic_wrap.h:280
@ PMIC_AUXADC_ADC17
Definition: pmic_wrap.h:277
@ PMIC_CPU_INT_STA
Definition: pmic_wrap.h:266
@ PMIC_AUXADC_ADC32
Definition: pmic_wrap.h:279
@ PMIC_AUXADC_RQST1
Definition: pmic_wrap.h:282
@ PMIC_AUXADC_ADC31
Definition: pmic_wrap.h:278
@ WDT_MONITOR_ALL
Definition: pmic_wrap.h:362
@ STA_PD_98_5_US
Definition: pmic_wrap.h:354
@ WATCHDOG_TIMER_7_5_MS
Definition: pmic_wrap.h:358
@ COUNTER13_PENDING_THRES
Definition: pmic_wrap.c:46
@ COUNTER7_PENDING_THRES
Definition: pmic_wrap.c:40
@ COUNTER11_PENDING_THRES
Definition: pmic_wrap.c:44
@ COUNTER8_PENDING_THRES
Definition: pmic_wrap.c:41
@ COUNTER9_PENDING_THRES
Definition: pmic_wrap.c:42
@ COUNTER12_PENDING_THRES
Definition: pmic_wrap.c:45
@ COUNTER4_PENDING_THRES
Definition: pmic_wrap.c:37
@ COUNTER0_PENDING_THRES
Definition: pmic_wrap.c:33
@ COUNTER6_PENDING_THRES
Definition: pmic_wrap.c:39
@ COUNTER1_PENDING_THRES
Definition: pmic_wrap.c:34
@ COUNTER5_PENDING_THRES
Definition: pmic_wrap.c:38
@ COUNTER16_PENDING_THRES
Definition: pmic_wrap.c:47
@ COUNTER3_PENDING_THRES
Definition: pmic_wrap.c:36
@ COUNTER10_PENDING_THRES
Definition: pmic_wrap.c:43
@ COUNTER2_PENDING_THRES
Definition: pmic_wrap.c:35
@ STARVE_ENABLE
Definition: pmic_wrap.c:32
@ STAUPD
Definition: pmic_wrap.c:16
@ MD_ADCINF0
Definition: pmic_wrap.c:14
@ MD_ADCINF1
Definition: pmic_wrap.c:15
@ GPSINF0
Definition: pmic_wrap.c:17
@ PRIORITY_IN_SEL_2
Definition: pmic_wrap.c:19
@ PRIORITY_OUT_SEL_2
Definition: pmic_wrap.c:24
static struct mt8186_infracfg_ao_regs *const mt8186_infracfg_ao
Definition: infracfg.h:544
static void pwrap_init_reg_clock(void)
Definition: pmic_wrap.c:239
static void pwrap_soft_reset(void)
Definition: pmic_wrap.c:55
static s32 pwrap_init_dio(u16 dio_en)
Definition: pmic_wrap.c:79
#define PRIORITY_IN(id, priority)
Definition: pmic_wrap.c:15
static void pwrap_init_spislv(void)
Definition: pmic_wrap.c:225
static void pwrap_starve_set(void)
Definition: pmic_wrap.c:127
static void pwrap_initstaupd(void)
Definition: pmic_wrap.c:96
static void pwrap_enable(void)
Definition: pmic_wrap.c:147
static s32 pwrap_init_sistrobe(void)
Definition: pmic_wrap.c:163
static void pwrap_lock_spislvreg(void)
Definition: pmic_wrap.c:91
static void pwrap_spi_clk_set(void)
Definition: pmic_wrap.c:61
#define PENDING_US(x)
Definition: pmic_wrap.c:35
#define PRIORITY_OUT(id, priority)
Definition: pmic_wrap.c:16
#define mtk_topckgen
Definition: pll_common.h:11
static s32 pwrap_write_nochk(u16 addr, u16 wdata)
#define pwrap_err(fmt, arg ...)
static u32 wait_for_idle_and_sync(u32 x)
@ WRITE_TEST_VALUE
static s32 pwrap_read_nochk(u16 addr, u16 *rdata)
@ E_PWR_INIT_SIDLY
@ E_PWR_INIT_DIO
@ E_PWR_READ_TEST_FAIL
@ E_PWR_INIT_WRITE_TEST
@ E_PWR_INIT_RESET_SPI
@ PMIC_DEW_CRC_EN
Definition: pmif_spi.h:49
@ PMIC_DEW_READ_TEST
Definition: pmif_spi.h:47
@ PMIC_DEW_DIO_EN
Definition: pmif_spi.h:46
@ PMIC_DEW_WRITE_TEST
Definition: pmif_spi.h:48
@ PMIC_DEW_RDDMY_NO
Definition: pmif_spi.h:51
@ PMIC_AUXADC_RQST0
Definition: pmif_spi.h:57
@ PMIC_FILTER_CON0
Definition: pmif_spi.h:43
@ PMIC_GPIO_PULLEN0_CLR
Definition: pmif_spi.h:44
@ PMIC_SMT_CON1
Definition: pmif_spi.h:41
@ PMIC_DEW_CRC_VAL
Definition: pmif_spi.h:50
@ PMIC_RG_SPI_CON2
Definition: pmif_spi.h:52
@ PMIC_DRV_CON1
Definition: pmif_spi.h:42
@ PMIC_SPISLV_KEY
Definition: pmif_spi.h:53
@ PMIC_RG_SPI_CON0
Definition: pmif_spi.h:45
@ DUMMY_READ_CYCLES
Definition: pmif_spi.h:109
@ SPI_DRIVING
Definition: pmif_spi.h:92
@ SPI_SMT
Definition: pmif_spi.h:79
@ SPI_FILTER
Definition: pmif_spi.h:78
@ SPI_PULL_DISABLE
Definition: pmif_spi.h:80
@ E_CLK_EDGE
Definition: pmif_spi.h:113
@ E_CLK_LAST_SETTING
Definition: pmif_spi.h:114
#define DEFAULT_VALUE_READ_TEST
Definition: pmif_spmi.h:9
uint16_t u16
Definition: stdint.h:48
int32_t s32
Definition: stdint.h:50