blob: 2e0f54a0c566ab81ae663a007a3d1847b1e8e5e9 [file] [log] [blame]
/*
* PMU support interface private to hndpmu.c and hndpmu_dhd.c.
*
* Copyright (C) 2023, 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_priv_h_
#define _hndpmu_priv_h_
#include <typedefs.h>
#include <siutils.h>
/* ******************************************************************** */
/* **** The following are common to both hndpmu.c and hndpmu_dhd.c **** */
/* ******************************************************************** */
#ifdef EVENT_LOG_COMPILE
#include <event_log.h>
#endif
#if defined(EVENT_LOG_COMPILE) && defined(BCMDBG_ERR) && defined(ERR_USE_EVENT_LOG)
#if defined(ERR_USE_EVENT_LOG_RA)
#define PMU_ERROR(args) EVENT_LOG_RA(EVENT_LOG_TAG_PMU_ERROR, args)
#else
#define PMU_ERROR(args) EVENT_LOG_COMPACT_CAST_PAREN_ARGS(EVENT_LOG_TAG_PMU_ERROR, args)
#endif /* ERR_USE_EVENT_LOG_RA */
#elif defined(BCMDBG_ERR)
#define PMU_ERROR(args) printf args
#else
#define PMU_ERROR(args)
#endif /* defined(BCMDBG_ERR) && defined(ERR_USE_EVENT_LOG) */
#ifdef BCMDBG
//#define BCMDBG_PMU
#endif
#ifdef BCMDBG_PMU
#define PMU_MSG(args) printf args
#else
#define PMU_MSG(args)
#endif /* BCMDBG_MPU */
/* To check in verbose debugging messages not intended
* to be on except on private builds.
*/
#define PMU_NONE(args)
#ifndef BCMDONGLEHOST
/* ******************************************************************************************** */
/* **** The following APIs are implemented in hndpmu.c but for chip specific files to call **** */
/* ******************************************************************************************** */
/* setup pll and query clock speed */
typedef struct {
uint32 fref; /* x-tal frequency in [hz] */
uint8 xf; /* x-tal index as contained in PMU control reg, see PMU programmers guide */
uint8 p1div;
uint8 p2div;
uint8 ndiv_int;
uint32 ndiv_frac;
} pmu1_xtaltab0_t;
/* For having the pllcontrol data (info)
* The table with the values of the registers will have one - one mapping.
*/
typedef struct {
uint16 clock; /**< x-tal frequency in [KHz] */
uint8 mode; /**< spur mode */
uint8 xf; /**< corresponds with xf bitfield in PMU control register */
} pllctrl_data_t;
extern const pmu1_xtaltab0_t pmu1_xtaltab0_960[];
extern const pmu1_xtaltab0_t pmu1_xtaltab0_1292[];
void si_pmu_dynamic_clk_switch_enab(si_t *sih);
void si_set_lv_sleep_mode(si_t *sih, osl_t *osh);
void si_set_lv_sleep_mode_pmu(si_t *sih, osl_t *osh);
void si_pmu_fll_preload_enable(si_t *sih);
void si_pmu_fast_lpo_enable(si_t *sih, osl_t *osh);
uint8 si_pmu_pll28nm_calc_ndiv(uint32 fvco, uint32 xtal, uint32 *ndiv_int, uint32 *ndiv_frac);
uint8 si_pmu_pllctrlreg_update(si_t *sih, osl_t *osh, pmuregs_t *pmu, uint32 xtal,
uint8 spur_mode, const pllctrl_data_t *pllctrlreg_update, uint32 array_size,
const uint32 *pllctrlreg_val);
void si_pmu_armpll_write(si_t *sih, uint32 xtal, uint32 pdiv);
uint32 si_pmu_res_deps(si_t *sih, osl_t *osh, pmuregs_t *pmu, uint32 rsrcs, bool all);
#define MISC_LDO_STEPPING_DELAY (150u) /* 150 us, includes 50us additional margin */
extern const char rstr_Invalid_Unsupported_xtal_value_D[];
extern const char rstr_btldo3p3pu[];
extern const char rstr_memlpldo_volt[];
extern const char rstr_lpldo_volt[];
extern const char rstr_abuck_volt[];
extern const char rstr_cbuck_volt[];
#ifdef BCM_PMU_TRIM
extern const char rstr_pmu_trim_dis[];
#endif
/* **************************************************************************************** */
/* **** The following APIs are implemented in chip specific files e.g. hndpmu_<chip>.c **** */
/* **************************************************************************************** */
/* defines to make the code more readable */
/* But 0 is a valid resource number! */
#define NO_SUCH_RESOURCE 0 /**< means: chip does not have such a PMU resource */
/** contains resource bit positions for a specific chip */
struct rsc_per_chip {
uint8 ht_avail;
uint8 macphy_clkavail;
uint8 ht_start;
uint8 otp_pu;
uint8 macphy_aux_clkavail;
uint8 macphy_scan_clkavail;
uint8 cb_ready;
uint8 dig_ready;
uint8 xtal;
};
typedef struct rsc_per_chip rsc_per_chip_t;
const rsc_per_chip_t *si_pmu_get_rsc_positions(si_t *sih);
void si_pmu_min_max_res_masks(si_t *sih, uint32 *pmin, uint32 *pmax);
void si_pmu_res_init(si_t *sih, osl_t *osh);
/* FVCO frequency in [KHz] */
#define FVCO_640 640000u /**< 640MHz */
#define FVCO_880 880000u /**< 880MHz */
#define FVCO_1760 1760000u /**< 1760MHz */
#define FVCO_1440 1440000u /**< 1440MHz */
#define FVCO_960 960000u /**< 960MHz */
#define FVCO_960p1 960100u /**< 960.1MHz */
#define FVCO_960010 960010u /**< 960.0098MHz */
#define FVCO_961 961000u /**< 961MHz */
#define FVCO_960p5 960500u /**< 960.5MHz */
#define FVCO_963 963000u /**< 963MHz */
#define FVCO_963p01 963010u /**< 963.01MHz */
#define FVCO_1000 1000000u /**< 1000MHz */
#define FVCO_1600 1600000u /**< 1600MHz */
#define FVCO_1920 1920000u /**< 1920MHz */
#define FVCO_1938 1938000u /**< 1938MHz */
#define FVCO_385 385000u /**< 385MHz */
#define FVCO_400 400000u /**< 400MHz */
#define FVCO_720 720000u /**< 720MHz */
#define FVCO_2880 2880000u /**< 2880 MHz */
#define FVCO_2946 2946000u /**< 2946 MHz */
#define FVCO_3000 3000000u /**< 3000 MHz */
#define FVCO_3200 3200000u /**< 3200 MHz */
#define FVCO_1002p8 1002823u /**< 1002.823MHz */
#define FVCO_1400 1400000u /**< 1400MHz */
#define FVCO_1292 1292000u /**< 1292MHz for BBPLL used in 4397B0/C0 */
/* uses these defines instead of 'magic' values when writing to register pllcontrol_addr */
#if defined(VLSI_CTRL_REGS) && defined(SKIP_LEGACY_CC_API)
#define PMU_PLL_CTRL_REG0 SI_CTRLREGS_INVALID
#define PMU_PLL_CTRL_REG1 SI_CTRLREGS_INVALID
#define PMU_PLL_CTRL_REG2 SI_CTRLREGS_INVALID
#define PMU_PLL_CTRL_REG3 SI_CTRLREGS_INVALID
#define PMU_PLL_CTRL_REG4 SI_CTRLREGS_INVALID
#define PMU_PLL_CTRL_REG5 SI_CTRLREGS_INVALID
#define PMU_PLL_CTRL_REG6 SI_CTRLREGS_INVALID
#define PMU_PLL_CTRL_REG7 SI_CTRLREGS_INVALID
#define PMU_PLL_CTRL_REG8 SI_CTRLREGS_INVALID
#define PMU_PLL_CTRL_REG9 SI_CTRLREGS_INVALID
#define PMU_PLL_CTRL_REG10 SI_CTRLREGS_INVALID
#define PMU_PLL_CTRL_REG11 SI_CTRLREGS_INVALID
#define PMU_PLL_CTRL_REG12 SI_CTRLREGS_INVALID
#define PMU_PLL_CTRL_REG13 SI_CTRLREGS_INVALID
#define PMU_PLL_CTRL_REG14 SI_CTRLREGS_INVALID
#define PMU_PLL_CTRL_REG15 SI_CTRLREGS_INVALID
#else /* !VLSI_CTRL_REGS || !SKIP_LEGACY_CC_API */
#define PMU_PLL_CTRL_REG0 0u
#define PMU_PLL_CTRL_REG1 1u
#define PMU_PLL_CTRL_REG2 2u
#define PMU_PLL_CTRL_REG3 3u
#define PMU_PLL_CTRL_REG4 4u
#define PMU_PLL_CTRL_REG5 5u
#define PMU_PLL_CTRL_REG6 6u
#define PMU_PLL_CTRL_REG7 7u
#define PMU_PLL_CTRL_REG8 8u
#define PMU_PLL_CTRL_REG9 9u
#define PMU_PLL_CTRL_REG10 10u
#define PMU_PLL_CTRL_REG11 11u
#define PMU_PLL_CTRL_REG12 12u
#define PMU_PLL_CTRL_REG13 13u
#define PMU_PLL_CTRL_REG14 14u
#define PMU_PLL_CTRL_REG15 15u
#endif /* !VLSI_CTRL_REGS || !SKIP_LEGACY_CC_API */
/* Setup resource up/down timers */
typedef struct {
uint8 resnum;
uint32 updown;
} pmu_res_updown_t;
#define PMU_RES_SUBSTATE_SHIFT 8
const pmu_res_updown_t *si_pmu_res_updown_table(si_t *sih, uint32 *pmu_res_updown_table_sz);
const pmu_res_updown_t *si_pmu_res_updown_fixup_table(si_t *sih,
uint32 *pmu_res_updown_fixup_table_sz);
/* Setup resource substate transition timer value */
typedef struct {
uint8 resnum;
uint8 substate;
uint32 tmr;
} pmu_res_subst_trans_tmr_t;
const pmu_res_subst_trans_tmr_t *si_pmu_res_subst_trans_tmr_table(si_t *sih,
uint32 *pmu_res_subst_trans_tmr_table_sz);
/* Resource dependencies mask change action */
#define RES_DEPEND_SET 0 /* Override the dependencies mask */
#define RES_DEPEND_ADD 1 /* Add to the dependencies mask */
#define RES_DEPEND_REMOVE -1 /* Remove from the dependencies mask */
/* Change resource dependencies masks */
typedef struct {
uint32 res_mask; /* resources (chip specific) */
int8 action; /* action, e.g. RES_DEPEND_SET */
uint32 depend_mask; /* changes to the dependencies mask */
bool (*filter)(si_t *sih); /* action is taken when filter is NULL or return TRUE */
} pmu_res_depend_t;
const pmu_res_depend_t *si_pmu_res_depend_table(si_t *sih, uint32 *pmu_res_depend_table_sz);
#define XTAL_FREQ_24000MHZ 24000
#define XTAL_FREQ_29985MHZ 29985
#define XTAL_FREQ_30000MHZ 30000
#define XTAL_FREQ_37400MHZ 37400
#define XTAL_FREQ_48000MHZ 48000
#define XTAL_FREQ_59970MHZ 59970
#define XTAL_FREQ_76800MHZ 76800
#define XTAL_FREQ_79960MHZ 79960
/* 'xf' values corresponding to the 'xf' definition in the PMU control register */
/* unclear why this enum contains '_960_' since the PMU prog guide says nothing about that */
enum xtaltab0_960 {
XTALTAB0_960_12000K = 1,
XTALTAB0_960_13000K,
XTALTAB0_960_14400K,
XTALTAB0_960_15360K,
XTALTAB0_960_16200K,
XTALTAB0_960_16800K,
XTALTAB0_960_19200K,
XTALTAB0_960_19800K,
XTALTAB0_960_20000K,
XTALTAB0_960_24000K, /* warning: unknown in PMU programmers guide. seems incorrect. */
XTALTAB0_960_25000K,
XTALTAB0_960_26000K,
XTALTAB0_960_30000K,
XTALTAB0_960_33600K, /* warning: unknown in PMU programmers guide. seems incorrect. */
XTALTAB0_960_37400K,
XTALTAB0_960_38400K, /* warning: unknown in PMU programmers guide. seems incorrect. */
XTALTAB0_960_40000K,
XTALTAB0_960_48000K, /* warning: unknown in PMU programmers guide. seems incorrect. */
XTALTAB0_960_52000K,
XTALTAB0_960_59970K
};
/* Indices into array pmu1_xtaltab0_960[]. Keep array and these defines synchronized. */
#define PMU1_XTALTAB0_960_12000K 0
#define PMU1_XTALTAB0_960_13000K 1
#define PMU1_XTALTAB0_960_14400K 2
#define PMU1_XTALTAB0_960_15360K 3
#define PMU1_XTALTAB0_960_16200K 4
#define PMU1_XTALTAB0_960_16800K 5
#define PMU1_XTALTAB0_960_19200K 6
#define PMU1_XTALTAB0_960_19800K 7
#define PMU1_XTALTAB0_960_20000K 8
#define PMU1_XTALTAB0_960_24000K 9
#define PMU1_XTALTAB0_960_25000K 10
#define PMU1_XTALTAB0_960_26000K 11
#define PMU1_XTALTAB0_960_30000K 12
#define PMU1_XTALTAB0_960_33600K 13
#define PMU1_XTALTAB0_960_37400K 14
#define PMU1_XTALTAB0_960_38400K 15
#define PMU1_XTALTAB0_960_40000K 16
#define PMU1_XTALTAB0_960_48000K 17
#define PMU1_XTALTAB0_960_52000K 18
#define PMU1_XTALTAB0_960_59970K 19
#define PMU1_XTALTAB0_960_76800K 20
/* Indices into array pmu1_xtaltab0_1292[]. Keep array and these defines synchronized. */
#define PMU1_XTALTAB0_1292_79920K 0
const pmu1_xtaltab0_t *si_pmu1_xtaltab0(si_t *sih);
const pmu1_xtaltab0_t *si_pmu1_xtaldef0(si_t *sih);
uint32 si_pmu1_pllfvco0(si_t *sih);
uint32 si_pmu1_pllfvco0_pll2(si_t *sih);
void si_pmu_ndiv_p_q(si_t *sih, uint32 *ndiv_p, uint32 *ndiv_q);
void si_pmu_armpll_freq_upd(si_t *sih, uint8 p1div, uint32 ndiv_int, uint32 ndiv_frac);
/* The return value 0 indicates to the caller to bail out */
bool si_pmu_armpll_upd(si_t *sih, osl_t *osh, pmuregs_t *pmu,
uint32 xtal, bool upd, bool *write_en);
void si_pmu_ndiv_upd(si_t *sih, const pmu1_xtaltab0_t *xt);
uint32 si_pmu_mdiv(si_t *sih);
uint32 si_pmu_macdiv(si_t *sih);
int si_pmu_fast_lpo_locked(si_t *sih, osl_t *osh);
uint32 si_pmu_fll_dac_out(si_t *sih);
void si_pmu_wait_ht_avail(si_t *sih, pmuregs_t *pmu, uint32 ht_req);
void si_pmu_fis_ctrl_setup(si_t *sih, pmuregs_t *pmu);
void si_pmu_chip_doinit(si_t *sih, osl_t *osh);
void si_pmu_swreg_doinit(si_t *sih);
int si_pmu_soft_start_params(si_t *sih, uint32 bt_or_wl, uint *en_reg, uint32 *en_shift,
uint32 *en_mask, uint32 *en_val, uint *val_reg, uint32 *val_shift, uint32 *val_mask);
int si_pmu_mem_pwr_dooff(si_t *sih, uint core_idx);
int si_pmu_mem_pwr_doon(si_t *sih);
void si_pmu_intr_pwrreq_disa(si_t *sih);
void si_pmu_lvm_csr_upd(si_t *sih, bool lvm);
void si_pmu_WAR_HW4389_836(si_t *sih);
void si_pmu_fll_preload_upd(si_t *sih);
#endif /* !BCMDONGLEHOST */
#endif /* _hndpmu_priv_h_ */