hc
2024-05-10 cde9070d9970eef1f7ec2360586c802a16230ad8
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
/*
 * HND SiliconBackplane PMU support.
 *
 * Copyright (C) 2020, Broadcom.
 *
 *      Unless you and Broadcom execute a separate written software license
 * agreement governing use of this software, this software is licensed to you
 * under the terms of the GNU General Public License version 2 (the "GPL"),
 * available at http://www.broadcom.com/licenses/GPLv2.php, with the
 * following added to such license:
 *
 *      As a special exception, the copyright holders of this software give you
 * permission to link this software with independent modules, and to copy and
 * distribute the resulting executable under terms of your choice, provided that
 * you also meet, for each linked independent module, the terms and conditions of
 * the license of that module.  An independent module is a module which is not
 * derived from this software.  The special exception does not apply to any
 * modifications of the software.
 *
 *
 * <<Broadcom-WL-IPTag/Dual:>>
 */
 
#ifndef _hndpmu_h_
#define _hndpmu_h_
 
#include <typedefs.h>
#include <osl_decl.h>
#include <siutils.h>
#include <sbchipc.h>
#if defined(BTOVERPCIE) || defined(BT_WLAN_REG_ON_WAR)
#include <hnd_gcisem.h>
#endif /* BTOVERPCIE || BT_WLAN_REG_ON_WAR */
 
#if !defined(BCMDONGLEHOST)
 
#define SET_LDO_VOLTAGE_LDO1        1
#define SET_LDO_VOLTAGE_LDO2        2
#define SET_LDO_VOLTAGE_LDO3        3
#define SET_LDO_VOLTAGE_PAREF        4
#define SET_LDO_VOLTAGE_CLDO_PWM    5
#define SET_LDO_VOLTAGE_CLDO_BURST    6
#define SET_LDO_VOLTAGE_CBUCK_PWM    7
#define SET_LDO_VOLTAGE_CBUCK_BURST    8
#define SET_LDO_VOLTAGE_LNLDO1        9
#define SET_LDO_VOLTAGE_LNLDO2_SEL    10
#define SET_LNLDO_PWERUP_LATCH_CTRL    11
#define SET_LDO_VOLTAGE_LDO3P3        12
 
#define BBPLL_NDIV_FRAC_BITS        24
#define P1_DIV_SCALE_BITS            12
 
#define PMUREQTIMER (1 << 0)
 
#define XTAL_FREQ_40MHZ        40000
#define XTAL_FREQ_54MHZ        54000
 
/* selects core based on AOB_ENAB() */
#define PMUREGADDR(sih, pmur, ccr, member) \
   (AOB_ENAB(sih) ? (&(pmur)->member) : (&(ccr)->member))
 
/* prevents backplane stall caused by subsequent writes to 'ilp domain' PMU registers */
#define HND_PMU_SYNC_WR(sih, pmur, ccr, osh, r, v) do { \
   if ((sih) && (sih)->pmurev >= 22) { \
       while (R_REG(osh, PMUREGADDR(sih, pmur, ccr, pmustatus)) & \
              PST_SLOW_WR_PENDING) { \
           ; /* empty */ \
       } \
   } \
   W_REG(osh, r, v); \
   (void)R_REG(osh, r); \
} while (0)
 
/* PMU Stat Timer */
 
/* for count mode */
enum {
   PMU_STATS_LEVEL_HIGH = 0,
   PMU_STATS_LEVEL_LOW,
   PMU_STATS_EDGE_RISE,
   PMU_STATS_EDGE_FALL
};
 
typedef struct {
   uint8 src_num; /* predefined source hw signal num to map timer */
   bool  enable;  /* timer enable/disable */
   bool  int_enable; /* overflow interrupts enable/disable */
   uint8 cnt_mode;
} pmu_stats_timer_t;
 
/* internal hw signal source number for Timer  */
#define SRC_PMU_RESRC_OFFSET 0x40
 
#define SRC_LINK_IN_L12 0
#define SRC_LINK_IN_L23 1
#define SRC_PM_ST_IN_D0 2
#define SRC_PM_ST_IN_D3 3
 
#define SRC_XTAL_PU (SRC_PMU_RESRC_OFFSET + RES4347_XTAL_PU)
#define SRC_CORE_RDY_MAIN (SRC_PMU_RESRC_OFFSET + RES4347_CORE_RDY_MAIN)
#define SRC_CORE_RDY_AUX (SRC_PMU_RESRC_OFFSET + RES4347_CORE_RDY_AUX)
 
#ifdef BCMPMU_STATS
extern bool _pmustatsenab;
#if defined(ROM_ENAB_RUNTIME_CHECK)
   #define PMU_STATS_ENAB()    (_pmustatsenab)
#elif defined(BCMPMU_STATS_DISABLED)
   #define PMU_STATS_ENAB()    (0)
#else
   #define PMU_STATS_ENAB()    (1)
#endif
#else
   #define PMU_STATS_ENAB()    (0)
#endif /* BCMPMU_STATS */
 
#define RES4369_HTAVAIL_VAL 0x00a80022
 
#if defined(BTOVERPCIE) && defined(BT_WLAN_REG_ON_WAR)
#error "'BT over PCIe' and 'WLAN/BT REG_ON WAR' are mutually exclusive as "
   "both share the same GCI semaphore - THREAD_0_GCI_SEM_3_ID"
#endif /* BTOVERPCIE && BT_WLAN_REG_ON_WAR */
 
#if defined(BTOVERPCIE)
#define GCI_PLL_LOCK_SEM            THREAD_0_GCI_SEM_3_ID
/* changed from msec to usec */
#define GCI_PLL_LOCK_SEM_TIMEOUT        (GCI_SEM_TIMEOUT_AFTER_RESERVE * 1000)
#endif /* BTOVERPCIE */
 
#if defined(BT_WLAN_REG_ON_WAR)
#define GCI_BT_WLAN_REG_ON_WAR_SEM        THREAD_0_GCI_SEM_3_ID
#define GCI_BT_WLAN_REG_ON_WAR_SEM_TIMEOUT    (GCI_SEM_TIMEOUT_AFTER_RESERVE * 1000)
#endif /* BT_WLAN_REG_ON_WAR */
 
#define GCI_INDIRECT_ACCESS_SEM                 THREAD_0_GCI_SEM_2_ID
#define GCI_INDIRECT_ACCESS_SEM_TIMEOUT         (GCI_SEM_TIMEOUT_AFTER_RESERVE * 1000)
 
#define GCI_TREFUP_DS_SEM                       THREAD_0_GCI_SEM_5_ID
#define GCI_TREFUP_DS_SEM_TIMEOUT               (GCI_SEM_TIMEOUT_AFTER_RESERVE * 1000)
 
#define GCI_BT_BOOTSTAGE_MEMOFFSET              (0x570u)
#define GCI_BT_BOOTSTAGE_FW_WAIT                0u  /* BT ROM code waiting on FW boot */
#define GCI_BT_BOOTSTAGE_FW_BOOT                2u  /* upon FW boot/start */
#define GCI_BT_BOOTSTAGE_FW_TRAP                3u  /* upon a trap */
#define GCI_BT_BOOTSTAGE_FW_INVALID             0xFFu
 
#define GCI_TREFUP_DS_MEMOFFSET                 (0x57Cu)
#define GCI_TREFUP_DS_WLAN                      (1u << 0u)
#define GCI_TREFUP_DS_BT                        (1u << 1u)
#define GCI_SHARED_SFLASH_RSVD                  (1u << 2u)
 
#define GCI_SHARED_SFLASH_SEM            THREAD_0_GCI_SEM_6_ID
#define GCI_SHARED_SFLASH_SEM_TIMEOUT    GCI_SEM_TIMEOUT_AFTER_RESERVE * 1000
#define GCI_SHARED_SFLASH_SEM_ERASE_RSVD_TIMEOUT        50 + 30 /* 50 us + headroom */
 
#define SLEW_RATE_VALUE_REG_4369    (PMU_VREG_6)
#define SLEW_RATE_SHIFT_4369(x)        (9u + (x * 8u))
#define SLEW_RATE_SIZE_4369        (3u)
#define SLEW_RATE_MASK_4369        ((1u << SLEW_RATE_SIZE_4369) - 1u)
#define SOFT_START_EN_REG_4369        (PMU_VREG_5)
#define SOFT_START_EN_SHIFT_4369(x)    (4u + x)
#define SOFT_START_EN_SIZE_4369        (1u)
#define SOFT_START_EN_MASK_4369        ((1u << SOFT_START_EN_SIZE_4369) - 1u)
#define SOFT_START_EN_VALUE_4369    (1u)
 
#define SLEW_RATE_VALUE_REG_4378    (PMU_VREG_6)
#define SLEW_RATE_SHIFT_4378(x)        (9u + (x * 8u))
#define SLEW_RATE_SIZE_4378        (3u)
#define SLEW_RATE_MASK_4378        ((1u << SLEW_RATE_SIZE_4378) - 1u)
#define SOFT_START_EN_REG_4378        (PMU_VREG_5)
#define SOFT_START_EN_SHIFT_4378(x)    (4u + x)
#define SOFT_START_EN_SIZE_4378        (1u)
#define SOFT_START_EN_MASK_4378        ((1u << SOFT_START_EN_SIZE_4378) - 1u)
#define SOFT_START_EN_VALUE_4378    (1u)
#define SOFT_START_EN_VALUE_4378_REV37    (0u)
 
#define SLEW_RATE_VALUE_REG_4387    (PMU_VREG_6)
#define SLEW_RATE_SHIFT_4387(x)        (18u)
#define SLEW_RATE_SIZE_4387        (2u)
#define SLEW_RATE_MASK_4387        ((1u << SLEW_RATE_SIZE_4387) - 1u)
#define SOFT_START_EN_REG_4387        (PMU_VREG_6)
#define SOFT_START_EN_SHIFT_4387(x)    (17u)
#define SOFT_START_EN_SIZE_4387        (1u)
#define SOFT_START_EN_MASK_4387        ((1u << SOFT_START_EN_SIZE_4387) - 1u)
#define SOFT_START_EN_VALUE_4387    (0u)
 
extern void si_pmu_init(si_t *sih, osl_t *osh);
extern void si_pmu_chip_init(si_t *sih, osl_t *osh);
extern void si_pmu_pll_init(si_t *sih, osl_t *osh, uint32 xtalfreq);
extern void si_pmu_res_init(si_t *sih, osl_t *osh);
extern void si_pmu_swreg_init(si_t *sih, osl_t *osh);
extern void si_pmu_res_minmax_update(si_t *sih, osl_t *osh);
extern void si_pmu_clear_intmask(si_t *sih);
 
extern uint32 si_pmu_si_clock(si_t *sih, osl_t *osh);   /* returns [Hz] units */
extern uint32 si_pmu_cpu_clock(si_t *sih, osl_t *osh);  /* returns [hz] units */
extern uint32 si_pmu_mem_clock(si_t *sih, osl_t *osh);  /* returns [Hz] units */
extern uint32 si_pmu_alp_clock(si_t *sih, osl_t *osh);  /* returns [Hz] units */
extern void si_pmu_ilp_clock_set(uint32 cycles);
extern uint32 si_pmu_ilp_clock(si_t *sih, osl_t *osh);  /* returns [Hz] units */
 
extern void si_pmu_set_ldo_voltage(si_t *sih, osl_t *osh, uint8 ldo, uint8 voltage);
extern uint16 si_pmu_fast_pwrup_delay(si_t *sih, osl_t *osh);
extern uint si_pmu_fast_pwrup_delay_dig(si_t *sih, osl_t *osh);
extern void si_pmu_pllupd(si_t *sih);
extern void si_pmu_spuravoid(si_t *sih, osl_t *osh, uint8 spuravoid);
extern void si_pmu_pll_off_PARR(si_t *sih, osl_t *osh, uint32 *min_res_mask,
   uint32 *max_res_mask, uint32 *clk_ctl_st);
extern uint32 si_pmu_pll28nm_fvco(si_t *sih);
/* below function are only for BBPLL parallel purpose */
extern void si_pmu_gband_spurwar(si_t *sih, osl_t *osh);
 
extern bool si_pmu_is_otp_powered(si_t *sih, osl_t *osh);
extern uint32 si_pmu_measure_alpclk(si_t *sih, osl_t *osh);
 
extern uint32 si_pmu_chipcontrol(si_t *sih, uint reg, uint32 mask, uint32 val);
#if defined(SAVERESTORE)
extern void si_set_abuck_mode_4362(si_t *sih, uint8 mode);
#endif /* SAVERESTORE */
 
#define si_pmu_regcontrol si_pmu_vreg_control /* prevents build err because of usage in PHY */
extern uint32 si_pmu_vreg_control(si_t *sih, uint reg, uint32 mask, uint32 val);
extern uint32 si_pmu_pllcontrol(si_t *sih, uint reg, uint32 mask, uint32 val);
extern void si_pmu_pllupd(si_t *sih);
 
extern uint32 si_pmu_waitforclk_on_backplane(si_t *sih, osl_t *osh, uint32 clk, uint32 delay);
extern uint32 si_pmu_get_bb_vcofreq(si_t *sih, osl_t *osh, int xtalfreq);
typedef void (*si_pmu_callback_t)(void* arg);
 
extern uint32 si_mac_clk(si_t *sih, osl_t *osh);
extern void si_pmu_switch_on_PARLDO(si_t *sih, osl_t *osh);
extern void si_pmu_switch_off_PARLDO(si_t *sih, osl_t *osh);
 
/* TODO: need a better fn name or better abstraction than the raw fvco
 * and MAC clock channel divisor...
 */
extern int si_pmu_fvco_macdiv(si_t *sih, uint32 *fvco, uint32 *div);
 
extern bool si_pmu_reset_ret_sleep_log(si_t *sih, osl_t *osh);
extern bool si_pmu_reset_chip_sleep_log(si_t *sih, osl_t *osh);
extern int si_pmu_openloop_cal(si_t *sih, uint16 currtemp);
 
#ifdef LDO3P3_MIN_RES_MASK
extern int si_pmu_min_res_ldo3p3_set(si_t *sih, osl_t *osh, bool on);
extern int si_pmu_min_res_ldo3p3_get(si_t *sih, osl_t *osh, int *res);
#endif /* LDO3P3_MIN_RES_MASK */
 
void si_pmu_bt_ldo_pu(si_t *sih, bool up);
 
int si_pmu_ldo3p3_soft_start_wl_get(si_t *sih, osl_t *osh, int *res);
int si_pmu_ldo3p3_soft_start_wl_set(si_t *sih, osl_t *osh, uint32 slew_rate);
int si_pmu_ldo3p3_soft_start_bt_get(si_t *sih, osl_t *osh, int *res);
int si_pmu_ldo3p3_soft_start_bt_set(si_t *sih, osl_t *osh, uint32 slew_rate);
extern int si_pmu_min_res_otp_pu_set(si_t *sih, osl_t *osh, bool on);
#endif /* !defined(BCMDONGLEHOST) */
 
#if defined(EDV)
extern uint32 si_pmu_get_backplaneclkspeed(si_t *sih);
extern void si_pmu_update_backplane_clock(si_t *sih, osl_t *osh, uint reg, uint32 mask, uint32 val);
#endif
 
extern uint32 si_pmu_rsrc_macphy_clk_deps(si_t *sih, osl_t *osh, int maccore_index);
extern uint32 si_pmu_rsrc_ht_avail_clk_deps(si_t *sih, osl_t *osh);
extern uint32 si_pmu_rsrc_cb_ready_deps(si_t *sih, osl_t *osh);
 
extern void si_pmu_otp_power(si_t *sih, osl_t *osh, bool on, uint32* min_res_mask);
extern void si_sdiod_drive_strength_init(si_t *sih, osl_t *osh, uint32 drivestrength);
 
extern void si_pmu_slow_clk_reinit(si_t *sih, osl_t *osh);
extern void si_pmu_avbtimer_enable(si_t *sih, osl_t *osh, bool set_flag);
extern uint32 si_pmu_dump_pmucap_binary(si_t *sih, uchar *p);
extern uint32 si_pmu_dump_buf_size_pmucap(si_t *sih);
extern int si_pmu_wait_for_steady_state(si_t *sih, osl_t *osh, pmuregs_t *pmu);
#ifdef ATE_BUILD
extern void hnd_pmu_clr_int_sts_req_active(osl_t *hnd_osh, si_t *hnd_sih);
#endif
extern uint32 si_pmu_wake_bit_offset(si_t *sih);
extern uint32 si_pmu_get_pmutimer(si_t *sih);
extern void si_pmu_set_min_res_mask(si_t *sih, osl_t *osh, uint min_res_mask);
extern void si_pmu_set_mac_rsrc_req(si_t *sih, int macunit);
extern void si_pmu_set_mac_rsrc_req_sc(si_t *sih, osl_t *osh);
extern bool si_pmu_fast_lpo_enable_pcie(si_t *sih);
extern bool si_pmu_fast_lpo_enable_pmu(si_t *sih);
extern uint32 si_cur_pmu_time(si_t *sih);
extern bool si_pmu_cap_fast_lpo(si_t *sih);
extern int si_pmu_fast_lpo_disable(si_t *sih);
extern void si_pmu_dmn1_perst_wakeup(si_t *sih, bool set);
#ifdef BCMPMU_STATS
extern void si_pmustatstimer_init(si_t *sih);
extern void si_pmustatstimer_dump(si_t *sih);
extern void si_pmustatstimer_start(si_t *sih, uint8 timerid);
extern void si_pmustatstimer_stop(si_t *sih, uint8 timerid);
extern void si_pmustatstimer_clear(si_t *sih, uint8 timerid);
extern void si_pmustatstimer_clear_overflow(si_t *sih);
extern uint32 si_pmustatstimer_read(si_t *sih, uint8 timerid);
extern void si_pmustatstimer_cfg_src_num(si_t *sih, uint8 src_num, uint8 timerid);
extern void si_pmustatstimer_cfg_cnt_mode(si_t *sih, uint8 cnt_mode, uint8 timerid);
extern void si_pmustatstimer_int_enable(si_t *sih);
extern void si_pmustatstimer_int_disable(si_t *sih);
#endif /* BCMPMU_STATS */
extern int si_pmu_min_res_set(si_t *sih, osl_t *osh, uint min_mask, bool set);
extern void si_pmu_disable_intr_pwrreq(si_t *sih);
 
#ifdef DONGLEBUILD
/* Get PMU registers in rodata */
extern int si_pmu_regs_in_rodata_dump(void *sih, void *arg2, uint32 *bufptr, uint16 *len);
#endif
 
extern void si_pmu_fis_setup(si_t *sih);
 
extern uint si_pmu_get_mac_rsrc_req_tmr_cnt(si_t *sih);
extern uint si_pmu_get_pmu_interrupt_rcv_cnt(si_t *sih);
 
extern bool _bcm_pwr_opt_dis;
#define BCM_PWR_OPT_ENAB()    (FALSE)
 
extern int si_pmu_mem_pwr_off(si_t *sih, int core_idx);
extern int si_pmu_mem_pwr_on(si_t *sih);
extern int si_pmu_lvm_csr_update(si_t *sih, bool lvm);
 
#if defined(BT_WLAN_REG_ON_WAR)
#define REG_ON_WAR_PMU_EXT_WAKE_REQ_MASK0_VAL 0x060000CDu
 
extern void si_pmu_reg_on_war_ext_wake_perst_set(si_t *sih);
extern void si_pmu_reg_on_war_ext_wake_perst_clear(si_t *sih);
#endif /* BT_WLAN_REG_ON_WAR */
 
#if defined (BCMSRTOPOFF)
   extern bool _srtopoff_enab;
#if defined(ROM_ENAB_RUNTIME_CHECK) || !defined(DONGLEBUILD)
   #define BCMSRTOPOFF_ENAB()    (_srtopoff_enab)
#elif defined(BCMSRTOPOFF_DISABLED)
   #define BCMSRTOPOFF_ENAB()    (0)
#else
   #define BCMSRTOPOFF_ENAB()    (_srtopoff_enab)
#endif
#else
   #define BCMSRTOPOFF_ENAB()    (0)
#endif /* BCMSRTOPOFF */
 
#ifdef BCM_PMU_FLL_PU_MANAGE
#define PMU_FLL_PU_ENAB()    (TRUE)
#else
#define PMU_FLL_PU_ENAB()    (FALSE)
#endif
 
extern pmuregs_t *hnd_pmur;    /* PMU core regs */
extern void si_pmu_res_state_wait(si_t *sih, uint rsrc);
#endif /* _hndpmu_h_ */