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