1 /*
2 * Misc utility routines for accessing lhl specific features
3 * of the SiliconBackplane-based Broadcom chips.
4 *
5 * Portions of this code are copyright (c) 2022 Cypress Semiconductor Corporation
6 *
7 * Copyright (C) 1999-2017, Broadcom Corporation
8 *
9 * Unless you and Broadcom execute a separate written software license
10 * agreement governing use of this software, this software is licensed to you
11 * under the terms of the GNU General Public License version 2 (the "GPL"),
12 * available at http://www.broadcom.com/licenses/GPLv2.php, with the
13 * following added to such license:
14 *
15 * As a special exception, the copyright holders of this software give you
16 * permission to link this software with independent modules, and to copy and
17 * distribute the resulting executable under terms of your choice, provided that
18 * you also meet, for each linked independent module, the terms and conditions of
19 * the license of that module. An independent module is a module which is not
20 * derived from this software. The special exception does not apply to any
21 * modifications of the software.
22 *
23 * Notwithstanding the above, under no circumstances may you combine this
24 * software in any way with any other Broadcom software provided under a license
25 * other than the GPL, without Broadcom's express prior written consent.
26 *
27 *
28 * <<Broadcom-WL-IPTag/Open:>>
29 *
30 * $Id: hndpmu.c 547757 2015-04-13 10:18:04Z $
31 */
32
33 #include <hndpmu.h>
34 #include <hndlhl.h>
35 #include <sbchipc.h>
36 #include <hndsoc.h>
37 #include <bcmdevs.h>
38 #include <osl.h>
39 #include <sbgci.h>
40 #include <siutils.h>
41 #include <bcmutils.h>
42 #ifdef BCMULP
43 #include <ulp.h>
44 #endif // endif
45
46 #define SI_LHL_EXT_WAKE_REQ_MASK_MAGIC 0x7FBBF7FF /* magic number for LHL EXT */
47
48 /* PmuRev1 has a 24-bit PMU RsrcReq timer. However it pushes all other bits
49 * upward. To make the code to run for all revs we use a variable to tell how
50 * many bits we need to shift.
51 */
52 #define FLAGS_SHIFT 14
53 #define LHL_ERROR(args) printf args
54
55 void
si_lhl_setup(si_t * sih,osl_t * osh)56 si_lhl_setup(si_t *sih, osl_t *osh)
57 {
58 if (CHIPID(sih->chip) == BCM43012_CHIP_ID) {
59 /* Enable PMU sleep mode0 */
60 #ifdef BCMQT
61 LHL_REG(sih, lhl_top_pwrseq_ctl_adr, LHL_PWRSEQ_CTL, PMU_SLEEP_MODE_0);
62 #else
63 LHL_REG(sih, lhl_top_pwrseq_ctl_adr, LHL_PWRSEQ_CTL, PMU_SLEEP_MODE_2);
64 #endif // endif
65 /* Modify as per the
66 BCM43012/LHL#LHL-RecommendedsettingforvariousPMUSleepModes:
67 */
68 LHL_REG(sih, lhl_top_pwrup_ctl_adr, LHL_PWRUP_CTL_MASK, LHL_PWRUP_CTL);
69 LHL_REG(sih, lhl_top_pwrup2_ctl_adr, LHL_PWRUP2_CTL_MASK, LHL_PWRUP2_CTL);
70 LHL_REG(sih, lhl_top_pwrdn_ctl_adr, LHL_PWRDN_CTL_MASK, LHL_PWRDN_SLEEP_CNT);
71 LHL_REG(sih, lhl_top_pwrdn2_ctl_adr, LHL_PWRDN2_CTL_MASK, LHL_PWRDN2_CTL);
72 } else if (BCM4347_CHIP(sih->chip)) {
73 if (LHL_IS_PSMODE_1(sih)) {
74 LHL_REG(sih, lhl_top_pwrseq_ctl_adr, LHL_PWRSEQ_CTL, PMU_SLEEP_MODE_1);
75 } else {
76 LHL_REG(sih, lhl_top_pwrseq_ctl_adr, LHL_PWRSEQ_CTL, PMU_SLEEP_MODE_0);
77 }
78
79 LHL_REG(sih, lhl_top_pwrup_ctl_adr, LHL_PWRUP_CTL_MASK, LHL_PWRUP_CTL_4347);
80 LHL_REG(sih, lhl_top_pwrup2_ctl_adr, LHL_PWRUP2_CTL_MASK, LHL_PWRUP2_CTL);
81 LHL_REG(sih, lhl_top_pwrdn_ctl_adr,
82 LHL_PWRDN_CTL_MASK, LHL_PWRDN_SLEEP_CNT);
83 LHL_REG(sih, lhl_top_pwrdn2_ctl_adr, LHL_PWRDN2_CTL_MASK, LHL_PWRDN2_CTL);
84
85 /*
86 * Enable wakeup on GPIO1, PCIE clkreq and perst signal,
87 * GPIO[0] is mapped to GPIO1
88 * GPIO[1] is mapped to PCIE perst
89 * GPIO[2] is mapped to PCIE clkreq
90 */
91
92 /* GPIO1 */
93 /* Clear any old interrupt status */
94 LHL_REG(sih, gpio_int_st_port_adr[0],
95 1 << PCIE_GPIO1_GPIO_PIN, 1 << PCIE_GPIO1_GPIO_PIN);
96 /* active high level trigger */
97 LHL_REG(sih, gpio_ctrl_iocfg_p_adr[PCIE_GPIO1_GPIO_PIN], ~0,
98 1 << GCI_GPIO_STS_WL_DIN_SELECT);
99 LHL_REG(sih, gpio_int_en_port_adr[0],
100 1 << PCIE_GPIO1_GPIO_PIN, 1 << PCIE_GPIO1_GPIO_PIN);
101 LHL_REG(sih, gpio_int_st_port_adr[0],
102 1 << PCIE_GPIO1_GPIO_PIN, 1 << PCIE_GPIO1_GPIO_PIN);
103 #if !defined(_CFEZ_)
104 si_gci_set_functionsel(sih, 1, CC4347_FNSEL_SAMEASPIN);
105 #endif // endif
106
107 /* PCIE perst */
108 LHL_REG(sih, gpio_int_st_port_adr[0],
109 1 << PCIE_PERST_GPIO_PIN, 1 << PCIE_PERST_GPIO_PIN);
110 LHL_REG(sih, gpio_ctrl_iocfg_p_adr[PCIE_PERST_GPIO_PIN], ~0,
111 (1 << GCI_GPIO_STS_EDGE_TRIG_BIT |
112 1 << GCI_GPIO_STS_WL_DIN_SELECT));
113 LHL_REG(sih, gpio_int_en_port_adr[0],
114 1 << PCIE_PERST_GPIO_PIN, 1 << PCIE_PERST_GPIO_PIN);
115 LHL_REG(sih, gpio_int_st_port_adr[0],
116 1 << PCIE_PERST_GPIO_PIN, 1 << PCIE_PERST_GPIO_PIN);
117
118 /* PCIE clkreq */
119 LHL_REG(sih, gpio_int_st_port_adr[0],
120 1 << PCIE_CLKREQ_GPIO_PIN, 1 << PCIE_CLKREQ_GPIO_PIN);
121 LHL_REG(sih, gpio_ctrl_iocfg_p_adr[PCIE_CLKREQ_GPIO_PIN], ~0,
122 (1 << GCI_GPIO_STS_EDGE_TRIG_BIT |
123 1 << GCI_GPIO_STS_NEG_EDGE_TRIG_BIT |
124 1 << GCI_GPIO_STS_WL_DIN_SELECT));
125 LHL_REG(sih, gpio_int_en_port_adr[0],
126 1 << PCIE_CLKREQ_GPIO_PIN, 1 << PCIE_CLKREQ_GPIO_PIN);
127 LHL_REG(sih, gpio_int_st_port_adr[0],
128 1 << PCIE_CLKREQ_GPIO_PIN, 1 << PCIE_CLKREQ_GPIO_PIN);
129 }
130 }
131
132 /* To skip this function, specify a invalid "lpo_select" value in nvram */
133 int
si_lhl_set_lpoclk(si_t * sih,osl_t * osh,uint32 lpo_force)134 si_lhl_set_lpoclk(si_t *sih, osl_t *osh, uint32 lpo_force)
135 {
136 gciregs_t *gciregs;
137 uint clk_det_cnt, status;
138 int lhl_wlclk_sel;
139 uint32 lpo = 0;
140 int timeout = 0;
141 gciregs = si_setcore(sih, GCI_CORE_ID, 0);
142
143 ASSERT(gciregs != NULL);
144
145 /* Apply nvram override to lpo */
146 if ((lpo_force == LHL_LPO_AUTO) && ((lpo = (uint32)getintvar(NULL, "lpo_select")) == 0)) {
147 lpo = LHL_OSC_32k_ENAB;
148 } else {
149 lpo = lpo_force;
150 }
151
152 /* Power up the desired LPO */
153 switch (lpo) {
154 case LHL_EXT_LPO_ENAB:
155 LHL_REG(sih, lhl_main_ctl_adr, EXTLPO_BUF_PD, 0);
156 lhl_wlclk_sel = LHL_EXT_SEL;
157 break;
158
159 case LHL_LPO1_ENAB:
160 LHL_REG(sih, lhl_main_ctl_adr, LPO1_PD_EN, 0);
161 lhl_wlclk_sel = LHL_LPO1_SEL;
162 break;
163
164 case LHL_LPO2_ENAB:
165 LHL_REG(sih, lhl_main_ctl_adr, LPO2_PD_EN, 0);
166 lhl_wlclk_sel = LHL_LPO2_SEL;
167 break;
168
169 case LHL_OSC_32k_ENAB:
170 LHL_REG(sih, lhl_main_ctl_adr, OSC_32k_PD, 0);
171 lhl_wlclk_sel = LHL_32k_SEL;
172 break;
173
174 default:
175 goto done;
176 }
177
178 LHL_REG(sih, lhl_clk_det_ctl_adr,
179 LHL_CLK_DET_CTL_AD_CNTR_CLK_SEL, lhl_wlclk_sel);
180
181 /* Detect the desired LPO */
182
183 LHL_REG(sih, lhl_clk_det_ctl_adr, LHL_CLK_DET_CTL_ADR_LHL_CNTR_EN, 0);
184 LHL_REG(sih, lhl_clk_det_ctl_adr,
185 LHL_CLK_DET_CTL_ADR_LHL_CNTR_CLR, LHL_CLK_DET_CTL_ADR_LHL_CNTR_CLR);
186 timeout = 0;
187 clk_det_cnt =
188 ((R_REG(osh, &gciregs->lhl_clk_det_ctl_adr) & LHL_CLK_DET_CNT) >>
189 LHL_CLK_DET_CNT_SHIFT);
190 while (clk_det_cnt != 0 && timeout <= LPO_SEL_TIMEOUT) {
191 OSL_DELAY(10);
192 clk_det_cnt =
193 ((R_REG(osh, &gciregs->lhl_clk_det_ctl_adr) & LHL_CLK_DET_CNT) >>
194 LHL_CLK_DET_CNT_SHIFT);
195 timeout++;
196 }
197
198 if (clk_det_cnt != 0) {
199 LHL_ERROR(("Clock not present as clear did not work timeout = %d\n", timeout));
200 goto error;
201 }
202 LHL_REG(sih, lhl_clk_det_ctl_adr, LHL_CLK_DET_CTL_ADR_LHL_CNTR_CLR, 0);
203 LHL_REG(sih, lhl_clk_det_ctl_adr, LHL_CLK_DET_CTL_ADR_LHL_CNTR_EN,
204 LHL_CLK_DET_CTL_ADR_LHL_CNTR_EN);
205 clk_det_cnt =
206 ((R_REG(osh, &gciregs->lhl_clk_det_ctl_adr) & LHL_CLK_DET_CNT) >>
207 LHL_CLK_DET_CNT_SHIFT);
208 timeout = 0;
209
210 while (clk_det_cnt <= CLK_DET_CNT_THRESH && timeout <= LPO_SEL_TIMEOUT) {
211 OSL_DELAY(10);
212 clk_det_cnt =
213 ((R_REG(osh, &gciregs->lhl_clk_det_ctl_adr) & LHL_CLK_DET_CNT) >>
214 LHL_CLK_DET_CNT_SHIFT);
215 timeout++;
216 }
217
218 if (timeout >= LPO_SEL_TIMEOUT) {
219 LHL_ERROR(("LPO is not available timeout = %u\n, timeout", timeout));
220 goto error;
221 }
222
223 /* Select the desired LPO */
224
225 LHL_REG(sih, lhl_main_ctl_adr,
226 LHL_MAIN_CTL_ADR_LHL_WLCLK_SEL, (lhl_wlclk_sel) << LPO_SEL_SHIFT);
227
228 status = ((R_REG(osh, &gciregs->lhl_clk_status_adr) & LHL_MAIN_CTL_ADR_FINAL_CLK_SEL) ==
229 (unsigned)(((1 << lhl_wlclk_sel) << LPO_FINAL_SEL_SHIFT))) ? 1 : 0;
230 timeout = 0;
231 while (!status && timeout <= LPO_SEL_TIMEOUT) {
232 OSL_DELAY(10);
233 status =
234 ((R_REG(osh, &gciregs->lhl_clk_status_adr) & LHL_MAIN_CTL_ADR_FINAL_CLK_SEL) ==
235 (unsigned)(((1 << lhl_wlclk_sel) << LPO_FINAL_SEL_SHIFT))) ? 1 : 0;
236 timeout++;
237 }
238
239 if (timeout >= LPO_SEL_TIMEOUT) {
240 LHL_ERROR(("LPO is not available timeout = %u\n, timeout", timeout));
241 goto error;
242 }
243 /* Power down the rest of the LPOs */
244
245 if (lpo != LHL_EXT_LPO_ENAB) {
246 LHL_REG(sih, lhl_main_ctl_adr, EXTLPO_BUF_PD, EXTLPO_BUF_PD);
247 }
248
249 if (lpo != LHL_LPO1_ENAB) {
250 LHL_REG(sih, lhl_main_ctl_adr, LPO1_PD_EN, LPO1_PD_EN);
251 LHL_REG(sih, lhl_main_ctl_adr, LPO1_PD_SEL, LPO1_PD_SEL_VAL);
252 }
253 if (lpo != LHL_LPO2_ENAB) {
254 LHL_REG(sih, lhl_main_ctl_adr, LPO2_PD_EN, LPO2_PD_EN);
255 LHL_REG(sih, lhl_main_ctl_adr, LPO2_PD_SEL, LPO2_PD_SEL_VAL);
256 }
257 if (lpo != LHL_OSC_32k_ENAB) {
258 LHL_REG(sih, lhl_main_ctl_adr, OSC_32k_PD, OSC_32k_PD);
259 }
260 if (lpo != RADIO_LPO_ENAB) {
261 si_gci_chipcontrol(sih, CC_GCI_CHIPCTRL_06, LPO_SEL, 0);
262 }
263 done:
264 return BCME_OK;
265 error:
266 ROMMABLE_ASSERT(0);
267 return BCME_ERROR;
268 }
269
270 void
si_lhl_timer_config(si_t * sih,osl_t * osh,int timer_type)271 si_lhl_timer_config(si_t *sih, osl_t *osh, int timer_type)
272 {
273 uint origidx;
274 pmuregs_t *pmu = NULL;
275
276 /* Remember original core before switch to chipc/pmu */
277 origidx = si_coreidx(sih);
278 if (AOB_ENAB(sih)) {
279 pmu = si_setcore(sih, PMU_CORE_ID, 0);
280 } else {
281 pmu = si_setcoreidx(sih, SI_CC_IDX);
282 }
283
284 ASSERT(pmu != NULL);
285
286 switch (timer_type) {
287 case LHL_MAC_TIMER:
288 /* Enable MAC Timer interrupt */
289 LHL_REG(sih, lhl_wl_mactim0_intrp_adr,
290 (LHL_WL_MACTIM0_INTRP_EN | LHL_WL_MACTIM0_INTRP_EDGE_TRIGGER),
291 (LHL_WL_MACTIM0_INTRP_EN | LHL_WL_MACTIM0_INTRP_EDGE_TRIGGER));
292
293 /* Programs bits for MACPHY_CLK_AVAIL and all its dependent bits in
294 * MacResourceReqMask0.
295 */
296 PMU_REG(sih, mac_res_req_mask, ~0, si_pmu_rsrc_macphy_clk_deps(sih, osh, 0));
297
298 /* One time init of mac_res_req_timer to enable interrupt and clock request */
299 HND_PMU_SYNC_WR(sih, pmu, pmu, osh,
300 PMUREGADDR(sih, pmu, pmu, mac_res_req_timer),
301 ((PRRT_ALP_REQ | PRRT_HQ_REQ | PRRT_INTEN) << FLAGS_SHIFT));
302
303 if (si_numd11coreunits(sih) > 1) {
304 LHL_REG(sih, lhl_wl_mactim1_intrp_adr,
305 (LHL_WL_MACTIM0_INTRP_EN | LHL_WL_MACTIM0_INTRP_EDGE_TRIGGER),
306 (LHL_WL_MACTIM0_INTRP_EN | LHL_WL_MACTIM0_INTRP_EDGE_TRIGGER));
307
308 PMU_REG(sih, mac_res_req_mask1, ~0,
309 si_pmu_rsrc_macphy_clk_deps(sih, osh, 1));
310
311 HND_PMU_SYNC_WR(sih, pmu, pmu, osh,
312 PMUREGADDR(sih, pmu, pmu, mac_res_req_timer1),
313 ((PRRT_ALP_REQ | PRRT_HQ_REQ | PRRT_INTEN) << FLAGS_SHIFT));
314 }
315
316 break;
317
318 case LHL_ARM_TIMER:
319 /* Enable ARM Timer interrupt */
320 LHL_REG(sih, lhl_wl_armtim0_intrp_adr,
321 (LHL_WL_ARMTIM0_INTRP_EN | LHL_WL_ARMTIM0_INTRP_EDGE_TRIGGER),
322 (LHL_WL_ARMTIM0_INTRP_EN | LHL_WL_ARMTIM0_INTRP_EDGE_TRIGGER));
323
324 /* Programs bits for HT_AVAIL and all its dependent bits in ResourceReqMask0 */
325 PMU_REG(sih, res_req_mask, ~0, si_pmu_rsrc_ht_avail_clk_deps(sih, osh));
326
327 /* One time init of res_req_timer to enable interrupt and clock request
328 * For low power request only ALP (HT_AVAIL is anyway requested by res_req_mask)
329 */
330 HND_PMU_SYNC_WR(sih, pmu, pmu, osh,
331 PMUREGADDR(sih, pmu, pmu, res_req_timer),
332 ((PRRT_ALP_REQ | PRRT_HQ_REQ | PRRT_INTEN) << FLAGS_SHIFT));
333 break;
334 }
335
336 /* Return to original core */
337 si_setcoreidx(sih, origidx);
338 }
339
340 void
si_lhl_timer_enable(si_t * sih)341 si_lhl_timer_enable(si_t *sih)
342 {
343 /* Enable clks for pmu int propagation */
344 PMU_REG(sih, pmuintctrl0, PMU_INTC_ALP_REQ, PMU_INTC_ALP_REQ);
345
346 PMU_REG(sih, pmuintmask0, RSRC_INTR_MASK_TIMER_INT_0, RSRC_INTR_MASK_TIMER_INT_0);
347 #ifndef BCMQT
348 LHL_REG(sih, lhl_main_ctl_adr, LHL_FAST_WRITE_EN, LHL_FAST_WRITE_EN);
349 #endif /* BCMQT */
350 PMU_REG(sih, pmucontrol_ext, PCTL_EXT_USE_LHL_TIMER, PCTL_EXT_USE_LHL_TIMER);
351 }
352
353 void
si_lhl_ilp_config(si_t * sih,osl_t * osh,uint32 ilp_period)354 si_lhl_ilp_config(si_t *sih, osl_t *osh, uint32 ilp_period)
355 {
356 gciregs_t *gciregs;
357 if (CHIPID(sih->chip) == BCM43012_CHIP_ID) {
358 gciregs = si_setcore(sih, GCI_CORE_ID, 0);
359 ASSERT(gciregs != NULL);
360 W_REG(osh, &gciregs->lhl_wl_ilp_val_adr, ilp_period);
361 }
362 }
363
364 #ifdef BCMULP
365 void
si_lhl_disable_sdio_wakeup(si_t * sih)366 si_lhl_disable_sdio_wakeup(si_t *sih)
367 {
368 /* Disable the interrupt */
369 LHL_REG(sih, gpio_int_en_port_adr[0], (1 << ULP_SDIO_CMD_PIN), 0);
370
371 /* Clear the pending interrupt status */
372 LHL_REG(sih, gpio_int_st_port_adr[0], (1 << ULP_SDIO_CMD_PIN), (1 << ULP_SDIO_CMD_PIN));
373 }
374
375 void
si_lhl_enable_sdio_wakeup(si_t * sih,osl_t * osh)376 si_lhl_enable_sdio_wakeup(si_t *sih, osl_t *osh)
377 {
378
379 gciregs_t *gciregs;
380 pmuregs_t *pmu;
381 gciregs = si_setcore(sih, GCI_CORE_ID, 0);
382 ASSERT(gciregs != NULL);
383 if (CHIPID(sih->chip) == BCM43012_CHIP_ID) {
384 /* For SDIO_CMD configure P8 for wake on negedge
385 * LHL 0 -> edge trigger intr mode,
386 * 1 -> neg edge trigger intr mode ,
387 * 6 -> din from wl side enable
388 */
389 OR_REG(osh, &gciregs->gpio_ctrl_iocfg_p_adr[ULP_SDIO_CMD_PIN],
390 (1 << GCI_GPIO_STS_EDGE_TRIG_BIT |
391 1 << GCI_GPIO_STS_NEG_EDGE_TRIG_BIT |
392 1 << GCI_GPIO_STS_WL_DIN_SELECT));
393 /* Clear any old interrupt status */
394 OR_REG(osh, &gciregs->gpio_int_st_port_adr[0], 1 << ULP_SDIO_CMD_PIN);
395
396 /* LHL GPIO[8] intr en , GPIO[8] is mapped to SDIO_CMD */
397 /* Enable P8 to generate interrupt */
398 OR_REG(osh, &gciregs->gpio_int_en_port_adr[0], 1 << ULP_SDIO_CMD_PIN);
399
400 /* Clear LHL GPIO status to trigger GCI Interrupt */
401 OR_REG(osh, &gciregs->gci_intstat, GCI_INTSTATUS_LHLWLWAKE);
402 /* Enable LHL GPIO Interrupt to trigger GCI Interrupt */
403 OR_REG(osh, &gciregs->gci_intmask, GCI_INTMASK_LHLWLWAKE);
404 OR_REG(osh, &gciregs->gci_wakemask, GCI_WAKEMASK_LHLWLWAKE);
405 /* Note ->Enable GCI interrupt to trigger Chipcommon interrupt
406 * Set EciGciIntEn in IntMask and will be done from FCBS saved tuple
407 */
408 /* Enable LHL to trigger extWake upto HT_AVAIL */
409 /* LHL GPIO Interrupt is mapped to extWake[7] */
410 pmu = si_setcore(sih, PMU_CORE_ID, 0);
411 ASSERT(pmu != NULL);
412 /* Set bit 4 and 7 in ExtWakeMask */
413 W_REG(osh, &pmu->extwakemask[0], CI_ECI | CI_WECI);
414 /* Program bits for MACPHY_CLK_AVAIL rsrc in ExtWakeReqMaskN */
415 W_REG(osh, &pmu->extwakereqmask[0], SI_LHL_EXT_WAKE_REQ_MASK_MAGIC);
416 /* Program 0 (no need to request explicitly for any backplane clk) */
417 W_REG(osh, &pmu->extwakectrl, 0x0);
418 /* Note: Configure MAC/Ucode to receive interrupt
419 * it will be done from saved tuple using FCBS code
420 */
421 }
422 }
423 #endif /* BCMULP */
424
425 lhl_reg_set_t lv_sleep_mode_4369_lhl_reg_set[] =
426 {
427 /* set wl_sleep_en */
428 {LHL_REG_OFF(lhl_top_pwrseq_ctl_adr), (1 << 0), (1 << 0)},
429
430 /* set top_pwrsw_en, top_slb_en, top_iso_en */
431 {LHL_REG_OFF(lhl_top_pwrseq_ctl_adr), BCM_MASK32(5, 3), (0x0 << 3)},
432
433 /* set VMUX_asr_sel_en */
434 {LHL_REG_OFF(lhl_top_pwrseq_ctl_adr), (1 << 8), (1 << 8)},
435
436 /* lhl_lp_main_ctl_adr, disable lp_mode_en, set CSR and ASR field enables for LV mode */
437 {LHL_REG_OFF(lhl_lp_main_ctl_adr), BCM_MASK32(21, 0), 0x3F89FF},
438
439 /* lhl_lp_main_ctl1_adr, set CSR field values - CSR_adj - 0.64V and trim_adj -5mV */
440 {LHL_REG_OFF(lhl_lp_main_ctl1_adr), BCM_MASK32(23, 0), 0x9E8F97},
441
442 /* lhl_lp_main_ctl2_adr, set ASR field values - ASR_adj - 0.76V and trim_adj +5mV */
443 {LHL_REG_OFF(lhl_lp_main_ctl2_adr), BCM_MASK32(13, 0), 0x07EE},
444
445 /* lhl_lp_dn_ctl_adr, set down count for CSR fields- adj, mode, overi_dis */
446 {LHL_REG_OFF(lhl_lp_dn_ctl_adr), ~0, ((LHL4369_CSR_OVERI_DIS_DWN_CNT << 16) |
447 (LHL4369_CSR_MODE_DWN_CNT << 8) | (LHL4369_CSR_ADJ_DWN_CNT << 0))},
448
449 /* lhl_lp_up_ctl_adr, set up count for CSR fields- adj, mode, overi_dis */
450 {LHL_REG_OFF(lhl_lp_up_ctl_adr), ~0, ((LHL4369_CSR_OVERI_DIS_UP_CNT << 16) |
451 (LHL4369_CSR_MODE_UP_CNT << 8) | (LHL4369_CSR_ADJ_UP_CNT << 0))},
452
453 /* lhl_lp_dn_ctl1_adr, set down count for hpbg_chop_dis, ASR_adj, vddc_sw_dis */
454 {LHL_REG_OFF(lhl_lp_dn_ctl1_adr), ~0, ((LHL4369_VDDC_SW_DIS_DWN_CNT << 24) |
455 (LHL4369_ASR_ADJ_DWN_CNT << 16) | (LHL4369_HPBG_CHOP_DIS_DWN_CNT << 0))},
456
457 /* lhl_lp_up_ctl1_adr, set up count for hpbg_chop_dis, ASR_adj, vddc_sw_dis */
458 {LHL_REG_OFF(lhl_lp_up_ctl1_adr), ~0, ((LHL4369_VDDC_SW_DIS_UP_CNT << 24) |
459 (LHL4369_ASR_ADJ_UP_CNT << 16) | (LHL4369_HPBG_CHOP_DIS_UP_CNT << 0))},
460
461 /* lhl_lp_dn_ctl4_adr, set down count for ASR fields -
462 * clk4m_dis, lppfm_mode, mode_sel, manual_mode
463 */
464 {LHL_REG_OFF(lhl_lp_dn_ctl4_adr), ~0, ((LHL4369_ASR_MANUAL_MODE_DWN_CNT << 24) |
465 (LHL4369_ASR_MODE_SEL_DWN_CNT << 16) | (LHL4369_ASR_LPPFM_MODE_DWN_CNT << 8) |
466 (LHL4369_ASR_CLK4M_DIS_DWN_CNT << 0))},
467
468 /* lhl_lp_up_ctl4_adr, set up count for ASR fields -
469 * clk4m_dis, lppfm_mode, mode_sel, manual_mode
470 */
471 {LHL_REG_OFF(lhl_lp_up_ctl4_adr), ~0, ((LHL4369_ASR_MANUAL_MODE_UP_CNT << 24) |
472 (LHL4369_ASR_MODE_SEL_UP_CNT << 16)| (LHL4369_ASR_LPPFM_MODE_UP_CNT << 8) |
473 (LHL4369_ASR_CLK4M_DIS_UP_CNT << 0))},
474
475 /* lhl_lp_dn_ctl3_adr, set down count for hpbg_pu, srbg_ref, ASR_overi_dis,
476 * CSR_pfm_pwr_slice_en
477 */
478 {LHL_REG_OFF(lhl_lp_dn_ctl3_adr), ~0, ((LHL4369_PFM_PWR_SLICE_DWN_CNT << 24) |
479 (LHL4369_ASR_OVERI_DIS_DWN_CNT << 16) | (LHL4369_SRBG_REF_SEL_DWN_CNT << 8) |
480 (LHL4369_HPBG_PU_EN_DWN_CNT << 0))},
481
482 /* lhl_lp_up_ctl3_adr, set up count for hpbg_pu, srbg_ref, ASR_overi_dis,
483 * CSR_pfm_pwr_slice_en
484 */
485 {LHL_REG_OFF(lhl_lp_up_ctl3_adr), ~0, ((LHL4369_PFM_PWR_SLICE_UP_CNT << 24) |
486 (LHL4369_ASR_OVERI_DIS_UP_CNT << 16) | (LHL4369_SRBG_REF_SEL_UP_CNT << 8) |
487 (LHL4369_HPBG_PU_EN_UP_CNT << 0))},
488
489 /* lhl_lp_dn_ctl2_adr, set down count for CSR_trim_adj */
490 {LHL_REG_OFF(lhl_lp_dn_ctl2_adr), ~0, (LHL4369_CSR_TRIM_ADJ_DWN_CNT << 16)},
491
492 /* lhl_lp_up_ctl2_adr, set up count for CSR_trim_adj */
493 {LHL_REG_OFF(lhl_lp_up_ctl2_adr), ~0, (LHL4369_CSR_TRIM_ADJ_UP_CNT << 16)},
494
495 /* lhl_lp_dn_ctl5_adr, set down count for ASR_trim_adj */
496 {LHL_REG_OFF(lhl_lp_dn_ctl5_adr), ~0, (LHL4369_ASR_TRIM_ADJ_DWN_CNT << 0)},
497
498 /* lhl_lp_up_ctl5_adr, set down count for ASR_trim_adj */
499 {LHL_REG_OFF(lhl_lp_up_ctl5_adr), ~0, (LHL4369_ASR_TRIM_ADJ_UP_CNT << 0)},
500
501 /* Change the default down count values for the resources */
502 /* lhl_top_pwrdn_ctl_adr, set down count for top_level_sleep, iso, slb and pwrsw */
503 {LHL_REG_OFF(lhl_top_pwrdn_ctl_adr), ~0, ((LHL4369_PWRSW_EN_DWN_CNT << 24) |
504 (LHL4369_SLB_EN_DWN_CNT << 16) | (LHL4369_ISO_EN_DWN_CNT << 8))},
505
506 /* lhl_top_pwrdn2_ctl_adr, set down count for VMUX_asr_sel */
507 {LHL_REG_OFF(lhl_top_pwrdn2_ctl_adr), ~0, (LHL4369_VMUX_ASR_SEL_DWN_CNT << 16)},
508
509 /* Change the default up count values for the resources */
510 /* lhl_top_pwrup_ctl_adr, set up count for top_level_sleep, iso, slb and pwrsw */
511 {LHL_REG_OFF(lhl_top_pwrup_ctl_adr), ~0, ((LHL4369_PWRSW_EN_UP_CNT << 24) |
512 (LHL4369_SLB_EN_UP_CNT << 16) | (LHL4369_ISO_EN_UP_CNT << 8))},
513
514 /* lhl_top_pwrdn2_ctl_adr, set down count for VMUX_asr_sel */
515 {LHL_REG_OFF(lhl_top_pwrup2_ctl_adr), ~0, ((LHL4369_VMUX_ASR_SEL_UP_CNT << 16))},
516
517 /* Enable lhl interrupt */
518 {LHL_REG_OFF(gci_intmask), (1 << 30), (1 << 30)},
519
520 /* Enable LHL Wake up */
521 {LHL_REG_OFF(gci_wakemask), (1 << 30), (1 << 30)},
522
523 /* Making forceOTPpwrOn 0 */
524 {LHL_REG_OFF(otpcontrol), (1 << 16), 0}
525 };
526
527 /* LV sleep mode summary:
528 * LV mode is where both ABUCK and CBUCK are programmed to low voltages during
529 * sleep, and VMUX selects ABUCK as VDDOUT_AON. LPLDO needs to power off.
530 * With ASR ON, LPLDO OFF
531 */
532 void
si_set_lv_sleep_mode_lhl_config_4369(si_t * sih)533 si_set_lv_sleep_mode_lhl_config_4369(si_t *sih)
534 {
535 uint i;
536 uint coreidx = si_findcoreidx(sih, GCI_CORE_ID, 0);
537 lhl_reg_set_t *regs = lv_sleep_mode_4369_lhl_reg_set;
538
539 /* Enable LHL LV mode:
540 * lhl_top_pwrseq_ctl_adr, set wl_sleep_en, iso_en, slb_en, pwrsw_en,VMUX_asr_sel_en
541 */
542 for (i = 0; i < ARRAYSIZE(lv_sleep_mode_4369_lhl_reg_set); i++) {
543 si_corereg(sih, coreidx, regs[i].offset, regs[i].mask, regs[i].val);
544 }
545 }
546