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 <console/console.h>
5 #include <delay.h>
6 #include <soc/infracfg.h>
7 #include <soc/pmic_wrap.h>
8 
9 static s32 pwrap_init_dio(u32 dio_en)
10 {
11  u16 rdata = 0;
12  u32 return_value = 0;
13 
15 
16  /* Check IDLE in advance */
17  return_value =
21  0);
22  if (return_value != 0) {
23  pwrap_err("%s fail,return_value=%#x\n", __func__, return_value);
24  return return_value;
25  }
26  write32(&mtk_pwrap->dio_en, dio_en);
27  /* Read Test */
29  if (rdata != DEFAULT_VALUE_READ_TEST) {
30  pwrap_err("fail,dio_en = %#x, READ_TEST rdata=%#x\n", dio_en,
31  rdata);
32  return E_PWR_READ_TEST_FAIL;
33  }
34 
35  return 0;
36 }
37 
38 /*
39  * pwrap_init_sidly - configure serial input delay
40  *
41  * This configures the serial input delay. We can configure 0, 2, 4 or 6ns
42  * delay. Do a read test with all possible values and chose the best delay.
43  */
44 static s32 pwrap_init_sidly(void)
45 {
46  u16 rdata;
47  u32 i;
48  u32 pass = 0;
49  u32 sidly = 0;
50 
51  for (i = 0; i < 4; i++) {
52  write32(&mtk_pwrap->sidly, i);
53  pwrap_wacs2(0, DEW_READ_TEST, 0, &rdata, 0);
54  if (rdata == DEFAULT_VALUE_READ_TEST)
55  pass |= 1 << i;
56  }
57 
58  /*
59  * Config SIDLY according to results
60  * Pass range should be continuously or return failed
61  */
62  switch (pass) {
63  /* only 1 pass, choose it */
64  case 1 << 0:
65  sidly = 0;
66  break;
67  case 1 << 1:
68  sidly = 1;
69  break;
70  case 1 << 2:
71  sidly = 2;
72  break;
73  case 1 << 3:
74  sidly = 3;
75  break;
76  /* two pass, choose the one on SIDLY boundary */
77  case (1 << 0) | (1 << 1):
78  sidly = 0;
79  break;
80  case (1 << 1) | (1 << 2): /* no boundary, choose smaller one */
81  sidly = 1;
82  break;
83  case (1 << 2) | (1 << 3):
84  sidly = 3;
85  break;
86  /* three pass, choose the middle one */
87  case (1 << 0) | (1 << 1) | (1 << 2):
88  sidly = 1;
89  break;
90  case (1 << 1) | (1 << 2) | (1 << 3):
91  sidly = 2;
92  break;
93  /* four pass, choose the smaller middle one */
94  case (1 << 0) | (1 << 1) | (1 << 2) | (1 << 3):
95  sidly = 1;
96  break;
97  /* pass range not continuous, should not happen */
98  default:
99  die("sidly pass range not continuous\n");
100  }
101 
102  write32(&mtk_pwrap->sidly, sidly);
103 
104  return 0;
105 }
106 
107 static s32 pwrap_init_reg_clock(enum pmic_regck regck_sel)
108 {
109  u16 wdata = 0;
110  u16 rdata = 0;
111 
112  /* Set reg clk freq */
114 
115  if (regck_sel == REG_CLOCK_18MHZ)
116  wdata = (rdata & (~(0x3 << 10))) | (0x1 << 10);
117  else
118  wdata = rdata & (~(0x3 << 10));
119 
122  if (rdata != wdata) {
123  pwrap_err("%s,rdata=%#x\n", __func__, rdata);
124  return E_PWR_INIT_REG_CLOCK;
125  }
126  /* Config SPI Waveform according to reg clk */
127  switch (regck_sel) {
128  case REG_CLOCK_18MHZ:
129  write32(&mtk_pwrap->rddmy, 0xc);
131  write32(&mtk_pwrap->cshext_read, 0x4);
133  write32(&mtk_pwrap->cslext_end, 0x4);
134  break;
135  case REG_CLOCK_26MHZ:
136  write32(&mtk_pwrap->rddmy, 0xc);
138  write32(&mtk_pwrap->cshext_read, 0x4);
140  write32(&mtk_pwrap->cslext_end, 0x2);
141  break;
142  default:
143  write32(&mtk_pwrap->rddmy, 0xf);
145  write32(&mtk_pwrap->cshext_read, 0xf);
147  write32(&mtk_pwrap->cslext_end, 0xf);
148  break;
149  }
150 
151  return 0;
152 }
153 
155 {
156  s32 sub_return = 0;
157  s32 sub_return1 = 0;
158  u16 rdata = 0x0;
159 
161  /* add 1us delay for toggling SW reset */
162  udelay(1);
163  /* clear reset bit */
165 
166  /* Enable DCM */
167  write32(&mtk_pwrap->dcm_en, 3);
169 
170  /* Reset SPISLV */
171  sub_return = pwrap_reset_spislv();
172  if (sub_return != 0) {
173  pwrap_err("error,pwrap_reset_spislv fail,sub_return=%#x\n",
174  sub_return);
175  return E_PWR_INIT_RESET_SPI;
176  }
177  /* Enable WACS2 */
178  write32(&mtk_pwrap->wrap_en, 1);
180  write32(&mtk_pwrap->wacs2_en, 1);
181 
182  /* SIDLY setting */
183  sub_return = pwrap_init_sidly();
184  if (sub_return != 0) {
185  pwrap_err("error,pwrap_init_sidly fail,sub_return=%#x\n",
186  sub_return);
187  return E_PWR_INIT_SIDLY;
188  }
189  /*
190  * SPI Waveform Configuration
191  * 18MHz/26MHz/safe mode/
192  */
194  if (sub_return != 0) {
195  pwrap_err("error,pwrap_init_reg_clock fail,sub_return=%#x\n",
196  sub_return);
197  return E_PWR_INIT_REG_CLOCK;
198  }
199  /*
200  * Enable PMIC
201  */
203  sub_return = pwrap_write_nochk(PMIC_WRP_CKPDN, rdata & 0x50);
204  /* clear dewrap reset bit */
205  sub_return1 = pwrap_write_nochk(PMIC_WRP_RST_CON, 0);
206  if ((sub_return != 0) || (sub_return1 != 0)) {
207  pwrap_err("Enable PMIC fail, sub_return=%#x sub_return1=%#x\n",
208  sub_return, sub_return1);
209  return E_PWR_INIT_ENABLE_PMIC;
210  }
211  /* Enable DIO mode */
212  sub_return = pwrap_init_dio(1);
213  if (sub_return != 0) {
214  pwrap_err("pwrap_init_dio error code=%#x, sub_return=%#x\n",
215  0x11, sub_return);
216  return E_PWR_INIT_DIO;
217  }
218 
219  /*
220  * Write test using WACS2,
221  * make sure the read/write function ready
222  */
224  sub_return1 = pwrap_read_nochk(DEW_WRITE_TEST, &rdata);
225  if ((rdata != WRITE_TEST_VALUE) || (sub_return != 0)
226  || (sub_return1 != 0)) {
227  pwrap_err("write error, rdata=%#x, return=%#x, return1=%#x\n",
228  rdata, sub_return, sub_return1);
229  return E_PWR_INIT_WRITE_TEST;
230  }
231 
232  /* Signature Checking - Using CRC
233  * should be the last to modify WRITE_TEST
234  */
235  sub_return = pwrap_write_nochk(DEW_CRC_EN, 0x1);
236  if (sub_return != 0) {
237  pwrap_err("enable CRC fail,sub_return=%#x\n", sub_return);
238  return E_PWR_INIT_ENABLE_CRC;
239  }
240  write32(&mtk_pwrap->crc_en, 0x1);
241  write32(&mtk_pwrap->sig_mode, 0x0);
243 
244  /* PMIC_WRAP enables */
245  write32(&mtk_pwrap->hiprio_arb_en, 0x1ff);
246  write32(&mtk_pwrap->wacs0_en, 0x1);
247  write32(&mtk_pwrap->wacs1_en, 0x1);
248 
249  /*
250  * switch event pin from usbdl mode to normal mode for pmic interrupt,
251  * NEW@MT6397
252  */
254  sub_return = pwrap_write_nochk(PMIC_TOP_CKCON3, (rdata & 0x0007));
255  if (sub_return != 0)
256  pwrap_err("!!switch event pin fail,sub_return=%d\n",
257  sub_return);
258 
259  /* Initialization Done */
260  write32(&mtk_pwrap->init_done2, 0x1);
261  write32(&mtk_pwrap->init_done0, 0x1);
262  write32(&mtk_pwrap->init_done1, 0x1);
263 
264  return 0;
265 }
static void write32(void *addr, uint32_t val)
Definition: mmio.h:40
s32 pwrap_reset_spislv(void)
Definition: pmic_wrap.c:66
u32 wait_for_state_ready(loop_condition_fp fp, u32 timeout_us, void *wacs_register, u32 *read_reg)
Definition: pmic_wrap.c:46
s32 pwrap_wacs2(u32 write, u16 addr, u16 wdata, u16 *rdata, u32 init_check)
Definition: pmic_wrap.c:99
void __noreturn die(const char *fmt,...)
Definition: die.c:17
#define setbits32(addr, set)
Definition: mmio.h:21
#define clrbits32(addr, clear)
Definition: mmio.h:26
@ INFRA_PMIC_WRAP_RST
Definition: infracfg.h:104
static struct mt8173_infracfg_regs *const mt8173_infracfg
Definition: infracfg.h:100
@ PMIC_WRP_RST_CON
Definition: pmic_wrap.h:24
@ PMIC_TOP_CKCON3
Definition: pmic_wrap.h:26
@ PMIC_WRP_CKPDN
Definition: pmic_wrap.h:23
@ PMIC_TOP_CKCON2
Definition: pmic_wrap.h:25
static struct mt8173_pwrap_regs *const mtk_pwrap
Definition: pmic_wrap.h:10
@ DEW_READ_TEST
Definition: pmic_wrap.h:122
@ DEW_CRC_EN
Definition: pmic_wrap.h:124
@ DEW_CRC_VAL
Definition: pmic_wrap.h:125
@ DEW_DIO_EN
Definition: pmic_wrap.h:118
@ DEW_WRITE_TEST
Definition: pmic_wrap.h:123
pmic_regck
Definition: pmic_wrap.h:144
@ REG_CLOCK_26MHZ
Definition: pmic_wrap.h:146
@ REG_CLOCK_18MHZ
Definition: pmic_wrap.h:145
@ WACS2
Definition: pmic_wrap.h:13
static s32 pwrap_init_dio(u32 dio_en)
Definition: pmic_wrap.c:9
s32 pwrap_init(void)
Definition: pmic_wrap.c:154
static s32 pwrap_init_reg_clock(enum pmic_regck regck_sel)
Definition: pmic_wrap.c:107
static s32 pwrap_init_sidly(void)
Definition: pmic_wrap.c:44
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_ENABLE_PMIC
@ E_PWR_INIT_DIO
@ E_PWR_READ_TEST_FAIL
@ E_PWR_INIT_WRITE_TEST
@ E_PWR_INIT_REG_CLOCK
@ E_PWR_INIT_ENABLE_CRC
@ E_PWR_INIT_RESET_SPI
@ TIMEOUT_WAIT_IDLE_US
#define DEFAULT_VALUE_READ_TEST
Definition: pmif_spmi.h:9
uint32_t u32
Definition: stdint.h:51
uint16_t u16
Definition: stdint.h:48
int32_t s32
Definition: stdint.h:50
void udelay(uint32_t us)
Definition: udelay.c:15