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 #include <device/mmio.h>
4 #include <soc/infracfg.h>
5 #include <soc/pll.h>
6 #include <soc/pmic_wrap.h>
7 #include <timer.h>
8 
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 
13 enum {
16  STAUPD = 10,
17  GPSINF0 = 11,
18 
20  PRIORITY_IN(MD_ADCINF1, 10) |
21  PRIORITY_IN(STAUPD, 8) |
23 
26  PRIORITY_OUT(STAUPD, 8) |
28 };
29 
30 #define PENDING_US(x) x
31 enum {
32  STARVE_ENABLE = 0x1 << 10,
48 };
49 
50 static void pwrap_soft_reset(void)
51 {
54 }
55 
56 static void pwrap_spi_clk_set(void)
57 {
58  write32(&mtk_topckgen->clk_cfg_5_clr,
60  write32(&mtk_topckgen->clk_cfg_5_set, ULPOSC_SEL_1);
61  write32(&mtk_topckgen->clk_cfg_update, ULPOSC_CLK);
62 
64  TIMER_CG | AP_CG | MD_CG | CONN_CG);
66 
68 
70  TIMER_CG | AP_CG | MD_CG | CONN_CG);
72 }
73 
74 static s32 pwrap_init_dio(u16 dio_en)
75 {
77 
78  if (!wait_us(100,
80  return -1;
81 
82  write32(&mtk_pwrap->dio_en, dio_en);
83  return 0;
84 }
85 
86 static void pwrap_lock_spislvreg(void)
87 {
89 }
90 
91 static void pwrap_initstaupd(void)
92 {
96 
97  /* CRC */
99  write32(&mtk_pwrap->crc_en, 0x1);
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,
107  write32(&mtk_pwrap->md_auxadc_rdata_wp_addr,
109  for (size_t i = 0; i < 32; i++)
110  write32(&mtk_pwrap->md_auxadc_rdata[i],
112 
113  write32(&mtk_pwrap->int_gps_auxadc_cmd_addr,
115  write32(&mtk_pwrap->int_gps_auxadc_cmd, (GPS_MAIN << 16) + GPS_SUBSYS);
116  write32(&mtk_pwrap->int_gps_auxadc_rdata_addr,
118 
119  write32(&mtk_pwrap->ext_gps_auxadc_rdata_addr, PMIC_AUXADC_ADC31);
120 }
121 
122 static void pwrap_starve_set(void)
123 {
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 
142 static void pwrap_enable(void)
143 {
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);
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 
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 
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++) {
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]);
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 */
211  if (rdata != DEFAULT_VALUE_READ_TEST) {
212  pwrap_err("rdata = %#x, exp = %#x\n", rdata,
214  return E_PWR_READ_TEST_FAIL;
215  }
216 
217  return 0;
218 }
219 
220 static void pwrap_init_spislv(void)
221 {
222  /* Turn on IO filter function */
224  /* Turn on IO SMT function to improve noise immunity */
226  /* Turn off IO pull function for power saving */
228  /* Enable SPI R/W in suspend mode */
230  /* Set PMIC GPIO driving current to 4mA */
232 }
233 
234 static void pwrap_init_reg_clock(void)
235 {
236  write32(&mtk_pwrap->ext_ck_write, 0x1);
237 
240 
243  write32(&mtk_pwrap->cslext_write, 0);
244  write32(&mtk_pwrap->cslext_read, 0);
245 }
246 
248 {
249  s32 sub_return = 0, sub_return1 = 0;
250  u16 rdata;
251 
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 */
270 
271  /* SPI Slave Configuration */
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  */
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  */
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 
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 */
323 
324  return 0;
325 }
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
static struct mt8183_infracfg_regs *const mt8183_infracfg
Definition: infracfg.h:275
@ ULPOSC_SEL_2
Definition: pmic_wrap.h:303
@ ULPOSC_INV
Definition: pmic_wrap.h:301
@ ULPOSC_OFF
Definition: pmic_wrap.h:300
@ ULPOSC_SEL_1
Definition: pmic_wrap.h:302
@ 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
@ ULPOSC_CLK
Definition: pmic_wrap.h:296
@ 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
@ MODEM_TEMP_SHARE_CG
Definition: pmic_wrap.h:314
@ STA_PD_98_5_US
Definition: pmic_wrap.h:354
@ TIMER_CG
Definition: pmic_wrap.h:307
@ CONN_CG
Definition: pmic_wrap.h:310
@ MD_CG
Definition: pmic_wrap.h:309
@ AP_CG
Definition: pmic_wrap.h:308
@ WATCHDOG_TIMER_7_5_MS
Definition: pmic_wrap.h:358
static void pwrap_init_reg_clock(void)
Definition: pmic_wrap.c:234
static void pwrap_soft_reset(void)
Definition: pmic_wrap.c:50
static s32 pwrap_init_dio(u16 dio_en)
Definition: pmic_wrap.c:74
@ 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
#define PRIORITY_IN(id, priority)
Definition: pmic_wrap.c:10
static void pwrap_init_spislv(void)
Definition: pmic_wrap.c:220
static void pwrap_starve_set(void)
Definition: pmic_wrap.c:122
static void pwrap_initstaupd(void)
Definition: pmic_wrap.c:91
static void pwrap_enable(void)
Definition: pmic_wrap.c:142
@ 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 s32 pwrap_init_sistrobe(void)
Definition: pmic_wrap.c:158
static void pwrap_lock_spislvreg(void)
Definition: pmic_wrap.c:86
static void pwrap_spi_clk_set(void)
Definition: pmic_wrap.c:56
#define PENDING_US(x)
Definition: pmic_wrap.c:30
#define PRIORITY_OUT(id, priority)
Definition: pmic_wrap.c:11
#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
u32 infra_globalcon_rst2_set
Definition: infracfg.h:48
u32 infra_globalcon_rst2_clr
Definition: infracfg.h:49