coreboot
coreboot is an Open Source project aimed at replacing the proprietary BIOS found in most computers.
mt6359p.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 
3 #include <assert.h>
4 #include <console/console.h>
5 #include <delay.h>
6 #include <soc/mt6359p.h>
7 #include <soc/pmif.h>
8 #include <timer.h>
9 
10 static const struct pmic_setting key_protect_setting[] = {
11  {0x3A8, 0x9CA6, 0xFFFF, 0},
12  {0x44A, 0xBADE, 0xFFFF, 0},
13  {0xA3A, 0x4729, 0xFFFF, 0},
14  {0xC58, 0x1605, 0xFFFF, 0},
15  {0xC5A, 0x1706, 0xFFFF, 0},
16  {0xC5C, 0x1807, 0xFFFF, 0},
17  {0xFB4, 0x6359, 0xFFFF, 0},
18  {0x1432, 0x5543, 0xFFFF, 0},
19 };
20 
21 static const struct pmic_efuse efuse_setting[] = {
22  {79, 0xa0e, 0x1, 0xf},
23  {886, 0x198c, 0xf, 0x8},
24  {890, 0x198e, 0xf, 0x0},
25  {902, 0x1998, 0xf, 0x8},
26  {906, 0x1998, 0xf, 0xc},
27  {918, 0x19a2, 0xf, 0x8},
28  {922, 0x19a2, 0xf, 0xc},
29  {1014, 0x19ae, 0xf, 0x7},
30  {1018, 0x19ae, 0xf, 0xb},
31  {1158, 0x1a0a, 0xf, 0x7},
32  {1162, 0x1a0a, 0xf, 0xb},
33  {1206, 0x1a16, 0xf, 0x7},
34  {1210, 0x1a16, 0xf, 0xb},
35  {1254, 0x1a22, 0xf, 0x7},
36  {1258, 0x1a22, 0xf, 0xb},
37  {1304, 0x1a2c, 0x7, 0x4},
38  {1307, 0x1a32, 0x7, 0x8},
39  {1336, 0x1a34, 0x7, 0x4},
40  {1339, 0x1a3a, 0x7, 0x8},
41  {1683, 0x79c, 0xf, 0x4},
42  {1688, 0xc8a, 0x1, 0x3},
43  {1689, 0xc88, 0x1, 0x3},
44  {1690, 0xc88, 0x7, 0x0},
45 };
46 
47 static struct pmif *pmif_arb = NULL;
48 static void mt6359p_write(u32 reg, u32 data)
49 {
50  pmif_arb->write(pmif_arb, 0, reg, data);
51 }
52 
53 static u32 mt6359p_read_field(u32 reg, u32 mask, u32 shift)
54 {
55  return pmif_arb->read_field(pmif_arb, 0, reg, mask, shift);
56 }
57 
59 {
60  pmif_arb->write_field(pmif_arb, 0, reg, val, mask, shift);
61 }
62 
63 static void pmic_set_power_hold(void)
64 {
65  mt6359p_write_field(PMIC_PWRHOLD, 0x1, 0x1, 0);
66 }
67 
68 static void pmic_wdt_set(void)
69 {
70  /* [5]=1, RG_WDTRSTB_DEB */
72  /* [1]=0, RG_WDTRSTB_MODE */
74  /* [0]=1, RG_WDTRSTB_EN */
76 }
77 
78 static void pmic_protect_key_setting(bool lock)
79 {
80  for (int i = 0; i < ARRAY_SIZE(key_protect_setting); i++)
82  lock ? 0 : key_protect_setting[i].val);
83 }
84 
85 static int check_idle(u32 timeout, u32 addr, u32 mask)
86 {
87  if (!wait_us(timeout, !mt6359p_read_field(addr, mask, 0)))
88  return -1;
89 
90  return 0;
91 }
92 
93 static u32 pmic_read_efuse(u32 efuse_bit, u32 mask)
94 {
95  u32 efuse_data;
96  int index, shift;
97 
98  index = efuse_bit / 16;
99  shift = efuse_bit % 16;
103  mt6359p_write_field(PMIC_OTP_CON0, index * 2, 0xFF, 0);
106  else
108 
109  udelay(300);
111  die("[%s] timeout after %d usecs\n", __func__, EFUSE_WAIT_US);
112 
113  udelay(100);
114 
115  efuse_data = mt6359p_read_field(PMIC_OTP_CON12, 0xFFFF, 0);
116  efuse_data = (efuse_data >> shift) & mask;
117 
120 
121  return efuse_data;
122 }
123 
124 static void pmic_efuse_setting(void)
125 {
126  u32 efuse_data;
127  struct stopwatch sw;
128 
129  stopwatch_init(&sw);
130 
131  for (int i = 0; i < ARRAY_SIZE(efuse_setting); i++) {
132  efuse_data = pmic_read_efuse(efuse_setting[i].efuse_bit, efuse_setting[i].mask);
133  mt6359p_write_field(efuse_setting[i].addr, efuse_data,
134  efuse_setting[i].mask, efuse_setting[i].shift);
135  }
136 
137  efuse_data = pmic_read_efuse(EFUSE_RG_VPA_OC_FT, 0x1);
138  if (efuse_data) {
139  /* restore VPA_DLC initial setting */
142  }
143 
144  printk(BIOS_DEBUG, "%s: Set efuses in %ld msecs\n",
145  __func__, stopwatch_duration_msecs(&sw));
146 }
147 
148 static void pmic_wk_vs2_voter_setting(void)
149 {
150  /*
151  * 1. Set VS2_VOTER_VOSEL = 1.35V
152  * 2. Clear VS2_VOTER
153  * 3. Set VS2_VOSEL = 1.4V
154  */
155  mt6359p_write_field(PMIC_VS2_VOTER_CFG, 0x2C, 0x7F, 0);
156  mt6359p_write_field(PMIC_VS2_VOTER, 0, 0xFFF, 0);
157  mt6359p_write_field(PMIC_VS2_ELR0, 0x30, 0x7F, 0);
158 }
159 
160 void mt6359p_buck_set_voltage(u32 buck_id, u32 buck_uv)
161 {
162  u32 vol_offset, vol_reg, vol;
163 
164  if (!pmif_arb)
165  die("ERROR: pmif_arb not initialized");
166 
167  switch (buck_id) {
168  case MT6359P_GPU11:
169  vol_offset = 400000;
170  vol_reg = PMIC_VGPU11_ELR0;
171  break;
172  case MT6359P_SRAM_PROC1:
173  vol_offset = 500000;
174  vol_reg = PMIC_VSRAM_PROC1_ELR;
175  break;
176  case MT6359P_SRAM_PROC2:
177  vol_offset = 500000;
178  vol_reg = PMIC_VSRAM_PROC2_ELR;
179  break;
180  case MT6359P_CORE:
181  vol_offset = 506250;
182  vol_reg = PMIC_VCORE_ELR0;
183  break;
184  default:
185  die("ERROR: Unknown buck_id %u", buck_id);
186  return;
187  };
188 
189  vol = (buck_uv - vol_offset) / 6250;
190  mt6359p_write_field(vol_reg, vol, 0x7F, 0);
191 }
192 
194 {
195  u32 vol_shift, vol_offset, vol_reg, vol;
196 
197  if (!pmif_arb)
198  die("ERROR: pmif_arb not initialized");
199 
200  switch (buck_id) {
201  case MT6359P_GPU11:
202  vol_shift = 0;
203  vol_offset = 400000;
204  vol_reg = PMIC_VGPU11_DBG0;
205  break;
206  case MT6359P_SRAM_PROC1:
207  vol_shift = 8;
208  vol_offset = 500000;
209  vol_reg = PMIC_VSRAM_PROC1_VOSEL1;
210  break;
211  case MT6359P_SRAM_PROC2:
212  vol_shift = 8;
213  vol_offset = 500000;
214  vol_reg = PMIC_VSRAM_PROC2_VOSEL1;
215  break;
216  case MT6359P_CORE:
217  vol_shift = 0;
218  vol_offset = 506250;
219  vol_reg = PMIC_VCORE_DBG0;
220  break;
221  default:
222  die("ERROR: Unknown buck_id %u", buck_id);
223  return 0;
224  };
225 
226  vol = mt6359p_read_field(vol_reg, 0x7F, vol_shift);
227  return vol_offset + vol * 6250;
228 }
229 
231 {
232  u32 reg_vol, reg_cali;
233 
234  if (!pmif_arb)
235  die("ERROR: pmif_arb not initialized");
236 
237  assert(vm18_uv >= 1700000);
238  assert(vm18_uv < 2000000);
239 
240  reg_vol = (vm18_uv / 1000 - VM18_VOL_OFFSET) / 100;
241  reg_cali = ((vm18_uv / 1000) % 100) / 10;
242  mt6359p_write(PMIC_VM18_ANA_CON0, (reg_vol << VM18_VOL_REG_SHIFT) | reg_cali);
243 }
244 
246 {
247  u32 reg_vol, reg_cali;
248 
249  if (!pmif_arb)
250  die("ERROR: pmif_arb not initialized");
251 
253  reg_cali = 10 * mt6359p_read_field(PMIC_VM18_ANA_CON0, 0xF, 0);
254  return 1000 * (VM18_VOL_OFFSET + reg_vol + reg_cali);
255 }
256 
257 static void init_pmif_arb(void)
258 {
259  if (!pmif_arb) {
261  if (!pmif_arb)
262  die("ERROR: No spi device");
263  }
264 
266  die("ERROR - Failed to initialize pmif spi");
267 }
268 
269 void mt6359p_init(void)
270 {
271  init_pmif_arb();
273  pmic_wdt_set();
276  pmic_lp_setting();
280 }
#define assert(statement)
Definition: assert.h:74
#define ARRAY_SIZE(a)
Definition: helpers.h:12
static u32 addr
Definition: cirrus.c:14
static void mt6359p_write(u32 reg, u32 data)
Definition: mt6359p.c:48
void mt6359p_set_vm18_voltage(u32 vm18_uv)
Definition: mt6359p.c:230
static void pmic_wdt_set(void)
Definition: mt6359p.c:68
static void pmic_wk_vs2_voter_setting(void)
Definition: mt6359p.c:148
void mt6359p_write_field(u32 reg, u32 val, u32 mask, u32 shift)
Definition: mt6359p.c:58
static void pmic_efuse_setting(void)
Definition: mt6359p.c:124
static const struct pmic_setting key_protect_setting[]
Definition: mt6359p.c:10
static void init_pmif_arb(void)
Definition: mt6359p.c:257
u32 mt6359p_buck_get_voltage(u32 buck_id)
Definition: mt6359p.c:193
static void pmic_protect_key_setting(bool lock)
Definition: mt6359p.c:78
void mt6359p_init(void)
Definition: mt6359p.c:269
static void pmic_set_power_hold(void)
Definition: mt6359p.c:63
static u32 mt6359p_read_field(u32 reg, u32 mask, u32 shift)
Definition: mt6359p.c:53
static int check_idle(u32 timeout, u32 addr, u32 mask)
Definition: mt6359p.c:85
static u32 pmic_read_efuse(u32 efuse_bit, u32 mask)
Definition: mt6359p.c:93
static struct pmif * pmif_arb
Definition: mt6359p.c:47
static const struct pmic_efuse efuse_setting[]
Definition: mt6359p.c:21
void mt6359p_buck_set_voltage(u32 buck_id, u32 buck_uv)
Definition: mt6359p.c:160
u32 mt6359p_get_vm18_voltage(void)
Definition: mt6359p.c:245
#define printk(level,...)
Definition: stdlib.h:16
void __noreturn die(const char *fmt,...)
Definition: die.c:17
#define wait_us(timeout_us, condition)
Definition: timer.h:198
static void stopwatch_init(struct stopwatch *sw)
Definition: timer.h:117
static long stopwatch_duration_msecs(struct stopwatch *sw)
Definition: timer.h:182
#define BIOS_DEBUG
BIOS_DEBUG - Verbose output.
Definition: loglevel.h:128
@ MT6359P_SRAM_PROC2
Definition: mt6359p.h:54
@ MT6359P_SRAM_PROC1
Definition: mt6359p.h:53
@ MT6359P_CORE
Definition: mt6359p.h:55
@ MT6359P_GPU11
Definition: mt6359p.h:52
@ PMIC_TOP_RST_MISC_CLR
Definition: mt6359p.h:14
@ PMIC_BUCK_VPA_DLC_CON0
Definition: mt6359p.h:28
@ PMIC_TOP_CKPDN_CON0
Definition: mt6359p.h:11
@ PMIC_TOP_RST_MISC_SET
Definition: mt6359p.h:13
@ PMIC_BUCK_VPA_DLC_CON1
Definition: mt6359p.h:29
@ PMIC_VSRAM_PROC1_VOSEL1
Definition: mt6359p.h:32
@ PMIC_OTP_CON13
Definition: mt6359p.h:19
@ PMIC_OTP_CON0
Definition: mt6359p.h:15
@ PMIC_PWRHOLD
Definition: mt6359p.h:20
@ PMIC_VCORE_ELR0
Definition: mt6359p.h:22
@ PMIC_VSRAM_PROC2_VOSEL1
Definition: mt6359p.h:33
@ PMIC_VS2_ELR0
Definition: mt6359p.h:27
@ PMIC_VS2_VOTER_CFG
Definition: mt6359p.h:26
@ PMIC_VGPU11_DBG0
Definition: mt6359p.h:23
@ PMIC_VS2_VOTER
Definition: mt6359p.h:25
@ PMIC_VSRAM_PROC2_ELR
Definition: mt6359p.h:31
@ PMIC_VM18_ANA_CON0
Definition: mt6359p.h:34
@ PMIC_VSRAM_PROC1_ELR
Definition: mt6359p.h:30
@ PMIC_OTP_CON11
Definition: mt6359p.h:17
@ PMIC_VGPU11_ELR0
Definition: mt6359p.h:24
@ PMIC_TOP_CKHWEN_CON0
Definition: mt6359p.h:12
@ PMIC_VCORE_DBG0
Definition: mt6359p.h:21
@ PMIC_OTP_CON8
Definition: mt6359p.h:16
@ PMIC_OTP_CON12
Definition: mt6359p.h:18
#define VM18_VOL_REG_SHIFT
Definition: mt6359p.h:59
#define EFUSE_WAIT_US
Definition: mt6359p.h:62
#define EFUSE_BUSY
Definition: mt6359p.h:63
#define VM18_VOL_OFFSET
Definition: mt6359p.h:60
#define EFUSE_RG_VPA_OC_FT
Definition: mt6359p.h:65
void pmic_lp_setting(void)
Definition: mt6359p.c:293
void pmic_init_setting(void)
Definition: mt6359p.c:286
@ PMIF_SPI
Definition: pmif_common.h:39
struct pmif * get_pmif_controller(int inf, int mstid)
Definition: pmif.c:168
static void lock(void *unused)
Definition: lockdown.c:58
static const int mask[4]
Definition: gpio.c:308
#define NULL
Definition: stddef.h:19
uint32_t u32
Definition: stdint.h:51
void(* write)(struct pmif *arb, u32 slvid, u32 reg, u32 data)
Definition: pmif_common.h:32
int(* is_pmif_init_done)(struct pmif *arb)
Definition: pmif_common.h:35
void(* write_field)(struct pmif *arb, u32 slvid, u32 reg, u32 val, u32 mask, u32 shift)
Definition: pmif_common.h:34
u32(* read_field)(struct pmif *arb, u32 slvid, u32 reg, u32 mask, u32 shift)
Definition: pmif_common.h:33
u8 val
Definition: sys.c:300
void udelay(uint32_t us)
Definition: udelay.c:15