From d3ec4c6f75195bf79f15804024036a5eb6c0b94d Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Sat, 26 Jun 2010 20:41:59 +0000 Subject: remove the brcm-2.4 target, it will no longer be supported in future releases. please use brcm47xx with broadcom-wl instead git-svn-id: svn://svn.openwrt.org/openwrt/trunk@21946 3c298f89-4303-0410-b956-a3cf2f4a3e73 --- .../brcm-2.4/files/arch/mips/bcm947xx/hndpmu.c | 1256 -------------------- 1 file changed, 1256 deletions(-) delete mode 100644 target/linux/brcm-2.4/files/arch/mips/bcm947xx/hndpmu.c (limited to 'target/linux/brcm-2.4/files/arch/mips/bcm947xx/hndpmu.c') diff --git a/target/linux/brcm-2.4/files/arch/mips/bcm947xx/hndpmu.c b/target/linux/brcm-2.4/files/arch/mips/bcm947xx/hndpmu.c deleted file mode 100644 index 0e95f2cfe9..0000000000 --- a/target/linux/brcm-2.4/files/arch/mips/bcm947xx/hndpmu.c +++ /dev/null @@ -1,1256 +0,0 @@ -/* - * Misc utility routines for accessing PMU corerev specific features - * of the SiliconBackplane-based Broadcom chips. - * - * Copyright 2007, Broadcom Corporation - * All Rights Reserved. - * - * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY - * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM - * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -/* debug/trace */ -#define PMU_ERROR(args) - -#ifdef BCMDBG -#define PMU_MSG(args) printf args -#else -#define PMU_MSG(args) -#endif /* BCMDBG */ - -/* PMU & control */ -/* PMU rev 0 pll control for BCM4328 and BCM5354 */ -static void sb_pmu0_pllinit0 (sb_t * sbh, osl_t * osh, chipcregs_t * cc, - uint32 xtal); -static uint32 sb_pmu0_alpclk0 (sb_t * sbh, osl_t * osh, chipcregs_t * cc); -static uint32 sb_pmu0_cpuclk0 (sb_t * sbh, osl_t * osh, chipcregs_t * cc); -/* PMU rev 0 pll control for BCM4325 BCM4329 */ -static void sb_pmu1_pllinit0 (sb_t * sbh, osl_t * osh, chipcregs_t * cc, - uint32 xtal); -static uint32 sb_pmu1_cpuclk0 (sb_t * sbh, osl_t * osh, chipcregs_t * cc); -static uint32 sb_pmu1_alpclk0 (sb_t * sbh, osl_t * osh, chipcregs_t * cc); - -/* Setup switcher voltage */ -void -BCMINITFN (sb_pmu_set_switcher_voltage) (sb_t * sbh, osl_t * osh, - uint8 bb_voltage, uint8 rf_voltage) -{ - chipcregs_t *cc; - uint origidx; - - ASSERT (sbh->cccaps & CC_CAP_PMU); - - /* Remember original core before switch to chipc */ - origidx = sb_coreidx (sbh); - cc = sb_setcore (sbh, SB_CC, 0); - ASSERT (cc); - - W_REG (osh, &cc->regcontrol_addr, 0x01); - W_REG (osh, &cc->regcontrol_data, (uint32) (bb_voltage & 0x1f) << 22); - - W_REG (osh, &cc->regcontrol_addr, 0x00); - W_REG (osh, &cc->regcontrol_data, (uint32) (rf_voltage & 0x1f) << 14); - - /* Return to original core */ - sb_setcoreidx (sbh, origidx); -} - -void -sb_pmu_set_ldo_voltage (sb_t * sbh, osl_t * osh, uint8 ldo, uint8 voltage) -{ - uint8 sr_cntl_shift, rc_shift, shift, mask; - uint32 addr; - - ASSERT (sbh->cccaps & CC_CAP_PMU); - - switch (sbh->chip) - { - case BCM4328_CHIP_ID: - case BCM5354_CHIP_ID: - switch (ldo) - { - case SET_LDO_VOLTAGE_LDO1: - addr = 2; - sr_cntl_shift = 8; - rc_shift = 17; - mask = 0xf; - break; - case SET_LDO_VOLTAGE_LDO2: - addr = 3; - sr_cntl_shift = 0; - rc_shift = 1; - mask = 0xf; - break; - case SET_LDO_VOLTAGE_LDO3: - addr = 3; - sr_cntl_shift = 0; - rc_shift = 9; - mask = 0xf; - break; - case SET_LDO_VOLTAGE_PAREF: - addr = 3; - sr_cntl_shift = 0; - rc_shift = 17; - mask = 0x3f; - break; - default: - ASSERT (FALSE); - return; - } - break; - case BCM4312_CHIP_ID: - switch (ldo) - { - case SET_LDO_VOLTAGE_PAREF: - addr = 0; - sr_cntl_shift = 0; - rc_shift = 21; - mask = 0x3f; - break; - default: - ASSERT (FALSE); - return; - } - break; - default: - ASSERT (FALSE); - return; - } - - shift = sr_cntl_shift + rc_shift; - - sb_corereg (sbh, SB_CC_IDX, OFFSETOF (chipcregs_t, regcontrol_addr), - ~0, addr); - sb_corereg (sbh, SB_CC_IDX, OFFSETOF (chipcregs_t, regcontrol_data), - mask << shift, (voltage & mask) << shift); -} - -void -sb_pmu_paref_ldo_enable (sb_t * sbh, osl_t * osh, bool enable) -{ - uint ldo = 0; - - ASSERT (sbh->cccaps & CC_CAP_PMU); - - switch (sbh->chip) - { - case BCM4328_CHIP_ID: - ldo = RES4328_PA_REF_LDO; - break; - case BCM5354_CHIP_ID: - ldo = RES5354_PA_REF_LDO; - break; - case BCM4312_CHIP_ID: - ldo = RES4312_PA_REF_LDO; - break; - default: - return; - } - - sb_corereg (sbh, SB_CC_IDX, OFFSETOF (chipcregs_t, min_res_mask), - PMURES_BIT (ldo), enable ? PMURES_BIT (ldo) : 0); -} - -uint16 BCMINITFN (sb_pmu_fast_pwrup_delay) (sb_t * sbh, osl_t * osh) -{ - uint16 delay = PMU_MAX_TRANSITION_DLY; - - ASSERT (sbh->cccaps & CC_CAP_PMU); - - switch (sbh->chip) - { - case BCM4328_CHIP_ID: - delay = 7000; - break; - - case BCM4325_CHIP_ID: - case BCM4312_CHIP_ID: -#ifdef BCMQT - delay = 70; -#else - delay = 2800; -#endif - break; - - default: - PMU_MSG (("No PMU fast power up delay specified " - "for chip %x rev %d, using default %d us\n", - sbh->chip, sbh->chiprev, delay)); - break; - } - - return delay; -} - -uint32 BCMINITFN (sb_pmu_force_ilp) (sb_t * sbh, osl_t * osh, bool force) -{ - chipcregs_t *cc; - uint origidx; - uint32 oldpmucontrol; - - ASSERT (sbh->cccaps & CC_CAP_PMU); - - /* Remember original core before switch to chipc */ - origidx = sb_coreidx (sbh); - cc = sb_setcore (sbh, SB_CC, 0); - ASSERT (cc); - - oldpmucontrol = R_REG (osh, &cc->pmucontrol); - if (force) - W_REG (osh, &cc->pmucontrol, oldpmucontrol & - ~(PCTL_HT_REQ_EN | PCTL_ALP_REQ_EN)); - else - W_REG (osh, &cc->pmucontrol, oldpmucontrol | - (PCTL_HT_REQ_EN | PCTL_ALP_REQ_EN)); - - /* Return to original core */ - sb_setcoreidx (sbh, origidx); - - return oldpmucontrol; -} - -/* Setup min/max resources and up/down timers */ -typedef struct -{ - uint8 resnum; - uint16 updown; -} pmu_res_updown_t; - -typedef struct -{ - uint8 resnum; - int8 action; /* 0 - set, 1 - add, -1 - remove */ - uint32 depend_mask; -} pmu_res_depend_t; - -static const pmu_res_updown_t -BCMINITDATA (bcm4328a0_res_updown)[] = -{ - { - RES4328_EXT_SWITCHER_PWM, 0x0101}, - { - RES4328_BB_SWITCHER_PWM, 0x1f01}, - { - RES4328_BB_SWITCHER_BURST, 0x010f}, - { - RES4328_BB_EXT_SWITCHER_BURST, 0x0101}, - { - RES4328_ILP_REQUEST, 0x0202}, - { - RES4328_RADIO_SWITCHER_PWM, 0x0f01}, - { - RES4328_RADIO_SWITCHER_BURST, 0x0f01}, - { - RES4328_ROM_SWITCH, 0x0101}, - { - RES4328_PA_REF_LDO, 0x0f01}, - { - RES4328_RADIO_LDO, 0x0f01}, - { - RES4328_AFE_LDO, 0x0f01}, - { - RES4328_PLL_LDO, 0x0f01}, - { - RES4328_BG_FILTBYP, 0x0101}, - { - RES4328_TX_FILTBYP, 0x0101}, - { - RES4328_RX_FILTBYP, 0x0101}, - { - RES4328_XTAL_PU, 0x0101}, - { - RES4328_XTAL_EN, 0xa001}, - { - RES4328_BB_PLL_FILTBYP, 0x0101}, - { - RES4328_RF_PLL_FILTBYP, 0x0101}, - { - RES4328_BB_PLL_PU, 0x0701} -}; - -static const pmu_res_depend_t -BCMINITDATA (bcm4328a0_res_depend)[] = -{ - /* Adjust ILP request resource not to force ext/BB switchers into burst mode */ - { - RES4328_ILP_REQUEST, 0, - PMURES_BIT (RES4328_EXT_SWITCHER_PWM) | - PMURES_BIT (RES4328_BB_SWITCHER_PWM)} -}; - -#ifdef BCMQT /* for power save on slow QT/small beacon interval */ -static const pmu_res_updown_t -BCMINITDATA (bcm4325a0_res_updown_qt)[] = -{ - { - RES4325_HT_AVAIL, 0x0300}, - { - RES4325_BBPLL_PWRSW_PU, 0x0101}, - { - RES4325_RFPLL_PWRSW_PU, 0x0101}, - { - RES4325_ALP_AVAIL, 0x0100}, - { - RES4325_XTAL_PU, 0x1000}, - { - RES4325_LNLDO1_PU, 0x0800}, - { - RES4325_CLDO_CBUCK_PWM, 0x0101}, - { - RES4325_CBUCK_PWM, 0x0803} -}; -#else -static const pmu_res_updown_t -BCMINITDATA (bcm4325a0_res_updown)[] = -{ - { - RES4325_XTAL_PU, 0x1501} -}; -#endif /* !BCMQT */ - -static const pmu_res_depend_t -BCMINITDATA (bcm4325a0_res_depend)[] = -{ - /* Adjust HT Avail resource dependencies */ - { - RES4325_HT_AVAIL, 1, - PMURES_BIT (RES4325_RX_PWRSW_PU) | PMURES_BIT (RES4325_TX_PWRSW_PU) | - PMURES_BIT (RES4325_LOGEN_PWRSW_PU) | PMURES_BIT (RES4325_AFE_PWRSW_PU)} -}; - -void BCMINITFN (sb_pmu_res_init) (sb_t * sbh, osl_t * osh) -{ - chipcregs_t *cc; - uint origidx; - const pmu_res_updown_t *pmu_res_updown_table = NULL; - int pmu_res_updown_table_sz = 0; - const pmu_res_depend_t *pmu_res_depend_table = NULL; - int pmu_res_depend_table_sz = 0; - uint32 min_mask = 0, max_mask = 0; - - ASSERT (sbh->cccaps & CC_CAP_PMU); - - /* Remember original core before switch to chipc */ - origidx = sb_coreidx (sbh); - cc = sb_setcore (sbh, SB_CC, 0); - ASSERT (cc); - - switch (sbh->chip) - { - case BCM4328_CHIP_ID: - /* Down to ILP request excluding ROM */ - min_mask = PMURES_BIT (RES4328_EXT_SWITCHER_PWM) | - PMURES_BIT (RES4328_BB_SWITCHER_PWM) | PMURES_BIT (RES4328_XTAL_EN); -#ifdef BCMROMOFFLOAD - /* Including ROM */ - min_mask |= PMURES_BIT (RES4328_ROM_SWITCH); -#endif - /* Allow (but don't require) PLL to turn on */ - max_mask = 0xfffff; - pmu_res_updown_table = bcm4328a0_res_updown; - pmu_res_updown_table_sz = ARRAYSIZE (bcm4328a0_res_updown); - pmu_res_depend_table = bcm4328a0_res_depend; - pmu_res_depend_table_sz = ARRAYSIZE (bcm4328a0_res_depend); - break; - case BCM4312_CHIP_ID: - /* keep default - * min_mask = 0xcbb; max_mask = 0x7ffff; - * pmu_res_updown_table_sz = 0; - * pmu_res_depend_table_sz = 0; - */ - break; - case BCM5354_CHIP_ID: - /* Allow (but don't require) PLL to turn on */ - max_mask = 0xfffff; - break; - - case BCM4325_CHIP_ID: - /* Leave OTP powered up and power it down later. */ - min_mask = - PMURES_BIT (RES4325_CBUCK_BURST) | PMURES_BIT (RES4325_LNLDO2_PU); - if (((sbh->chipst & CST4325_PMUTOP_2B_MASK) >> - CST4325_PMUTOP_2B_SHIFT) == 1) - min_mask |= PMURES_BIT (RES4325_CLDO_CBUCK_BURST); - /* Allow (but don't require) PLL to turn on */ - max_mask = 0x3fffff; -#ifdef BCMQT - pmu_res_updown_table = bcm4325a0_res_updown_qt; - pmu_res_updown_table_sz = ARRAYSIZE (bcm4325a0_res_updown_qt); -#else - pmu_res_updown_table = bcm4325a0_res_updown; - pmu_res_updown_table_sz = ARRAYSIZE (bcm4325a0_res_updown); - pmu_res_depend_table = bcm4325a0_res_depend; - pmu_res_depend_table_sz = ARRAYSIZE (bcm4325a0_res_depend); -#endif - break; - - default: - break; - } - - /* Program up/down timers */ - while (pmu_res_updown_table_sz--) - { - ASSERT (pmu_res_updown_table); - W_REG (osh, &cc->res_table_sel, - pmu_res_updown_table[pmu_res_updown_table_sz].resnum); - W_REG (osh, &cc->res_updn_timer, - pmu_res_updown_table[pmu_res_updown_table_sz].updown); - } - - /* Program resource dependencies table */ - while (pmu_res_depend_table_sz--) - { - ASSERT (pmu_res_depend_table); - W_REG (osh, &cc->res_table_sel, - pmu_res_depend_table[pmu_res_depend_table_sz].resnum); - switch (pmu_res_depend_table[pmu_res_depend_table_sz].action) - { - case 0: - W_REG (osh, &cc->res_dep_mask, - pmu_res_depend_table[pmu_res_depend_table_sz].depend_mask); - break; - case 1: - OR_REG (osh, &cc->res_dep_mask, - pmu_res_depend_table[pmu_res_depend_table_sz].depend_mask); - break; - case -1: - AND_REG (osh, &cc->res_dep_mask, - ~pmu_res_depend_table[pmu_res_depend_table_sz]. - depend_mask); - break; - default: - ASSERT (0); - break; - } - } - - /* program min resource mask */ - if (min_mask) - { - PMU_MSG (("Changing min_res_mask to 0x%x\n", min_mask)); - W_REG (osh, &cc->min_res_mask, min_mask); - } - /* program max resource mask */ - if (max_mask) - { - PMU_MSG (("Changing max_res_mask to 0x%x\n", max_mask)); - W_REG (osh, &cc->max_res_mask, max_mask); - } - - /* Return to original core */ - sb_setcoreidx (sbh, origidx); -} - -/* setup pll and query clock speed */ -typedef struct -{ - uint16 freq; - uint8 xf; - uint8 wbint; - uint32 wbfrac; -} pmu0_xtaltab0_t; - -/* the following table is based on 880Mhz Fvco */ -#define PMU0_PLL0_FVCO 880000 /* Fvco 880Mhz */ -static const pmu0_xtaltab0_t -BCMINITDATA (pmu0_xtaltab0)[] = -{ - { - 12000, 1, 73, 349525}, - { - 13000, 2, 67, 725937}, - { - 14400, 3, 61, 116508}, - { - 15360, 4, 57, 305834}, - { - 16200, 5, 54, 336579}, - { - 16800, 6, 52, 399457}, - { - 19200, 7, 45, 873813}, - { - 19800, 8, 44, 466033}, - { - 20000, 9, 44, 0}, - { - 25000, 10, 70, 419430}, - { - 26000, 11, 67, 725937}, - { - 30000, 12, 58, 699050}, - { - 38400, 13, 45, 873813}, - { - 40000, 14, 45, 0}, - { - 0, 0, 0, 0} -}; - -#ifdef BCMUSBDEV -#define PMU0_XTAL0_DEFAULT 11 -#else -#define PMU0_XTAL0_DEFAULT 8 -#endif - -#ifdef BCMUSBDEV -/* - * Set new backplane PLL clock frequency - */ -static void BCMINITFN (sb_pmu0_sbclk4328) (sb_t * sbh, int freq) -{ - uint32 tmp, oldmax, oldmin, origidx; - chipcregs_t *cc; - - /* Remember original core before switch to chipc */ - origidx = sb_coreidx (sbh); - cc = sb_setcore (sbh, SB_CC, 0); - ASSERT (cc); - - /* Set new backplane PLL clock */ - W_REG (osh, &cc->pllcontrol_addr, PMU0_PLL0_PLLCTL0); - tmp = R_REG (osh, &cc->pllcontrol_data); - tmp &= ~(PMU0_PLL0_PC0_DIV_ARM_MASK); - tmp |= freq << PMU0_PLL0_PC0_DIV_ARM_SHIFT; - W_REG (osh, &cc->pllcontrol_data, tmp); - - /* Power cycle BB_PLL_PU by disabling/enabling it to take on new freq */ - /* Disable PLL */ - oldmin = R_REG (osh, &cc->min_res_mask); - oldmax = R_REG (osh, &cc->max_res_mask); - W_REG (osh, &cc->min_res_mask, oldmin & ~PMURES_BIT (RES4328_BB_PLL_PU)); - W_REG (osh, &cc->max_res_mask, oldmax & ~PMURES_BIT (RES4328_BB_PLL_PU)); - - /* It takes over several hundred usec to re-enable the PLL since the - * sequencer state machines run on ILP clock. Set delay at 450us to be safe. - * - * Be sure PLL is powered down first before re-enabling it. - */ - - OSL_DELAY (PLL_DELAY); - SPINWAIT ((R_REG (osh, &cc->res_state) & PMURES_BIT (RES4328_BB_PLL_PU)), - PLL_DELAY * 3); - - if (R_REG (osh, &cc->res_state) & PMURES_BIT (RES4328_BB_PLL_PU)) - { - /* If BB_PLL not powered down yet, new backplane PLL clock - * may not take effect. - * - * Still early during bootup so no serial output here. - */ - PMU_ERROR (("Fatal: BB_PLL not power down yet!\n")); - ASSERT (! - (R_REG (osh, &cc->res_state) & PMURES_BIT (RES4328_BB_PLL_PU))); - } - - /* Enable PLL */ - W_REG (osh, &cc->max_res_mask, oldmax); - - /* Return to original core */ - sb_setcoreidx (sbh, origidx); -} -#endif /* BCMUSBDEV */ - -/* Set up PLL registers in the PMU as per the crystal speed. - * Uses xtalfreq variable, or passed-in default. - */ -static void -BCMINITFN (sb_pmu0_pllinit0) (sb_t * sbh, osl_t * osh, chipcregs_t * cc, - uint32 xtal) -{ - uint32 tmp; - const pmu0_xtaltab0_t *xt; - - if ((sb_chip (sbh) == BCM5354_CHIP_ID) && (xtal == 0)) - { - /* 5354 has xtal freq of 25MHz */ - xtal = 25000; - } - - /* Find the frequency in the table */ - for (xt = pmu0_xtaltab0; xt->freq; xt++) - if (xt->freq == xtal) - break; - if (xt->freq == 0) - xt = &pmu0_xtaltab0[PMU0_XTAL0_DEFAULT]; - - PMU_MSG (("XTAL %d (%d)\n", xtal, xt->xf)); - - /* Check current PLL state */ - tmp = (R_REG (osh, &cc->pmucontrol) & PCTL_XTALFREQ_MASK) >> - PCTL_XTALFREQ_SHIFT; - if (tmp == xt->xf) - { - PMU_MSG (("PLL already programmed for %d.%d MHz\n", - (xt->freq / 1000), (xt->freq % 1000))); - -#ifdef BCMUSBDEV - if (sbh->chip == BCM4328_CHIP_ID) - sb_pmu0_sbclk4328 (sbh, PMU0_PLL0_PC0_DIV_ARM_88MHZ); -#endif - return; - } - - if (tmp) - { - PMU_MSG (("Reprogramming PLL for %d.%d MHz (was %d.%dMHz)\n", - (xt->freq / 1000), (xt->freq % 1000), - (pmu0_xtaltab0[tmp - 1].freq / 1000), - (pmu0_xtaltab0[tmp - 1].freq % 1000))); - } - else - { - PMU_MSG (("Programming PLL for %d.%d MHz\n", (xt->freq / 1000), - (xt->freq % 1000))); - } - - /* Make sure the PLL is off */ - switch (sbh->chip) - { - case BCM4328_CHIP_ID: - AND_REG (osh, &cc->min_res_mask, ~PMURES_BIT (RES4328_BB_PLL_PU)); - AND_REG (osh, &cc->max_res_mask, ~PMURES_BIT (RES4328_BB_PLL_PU)); - break; - case BCM5354_CHIP_ID: - AND_REG (osh, &cc->min_res_mask, ~PMURES_BIT (RES5354_BB_PLL_PU)); - AND_REG (osh, &cc->max_res_mask, ~PMURES_BIT (RES5354_BB_PLL_PU)); - break; - default: - ASSERT (0); - } - SPINWAIT (R_REG (osh, &cc->clk_ctl_st) & CCS0_HTAVAIL, - PMU_MAX_TRANSITION_DLY); - ASSERT (!(R_REG (osh, &cc->clk_ctl_st) & CCS0_HTAVAIL)); - - PMU_MSG (("Done masking\n")); - - /* Write PDIV in pllcontrol[0] */ - W_REG (osh, &cc->pllcontrol_addr, PMU0_PLL0_PLLCTL0); - tmp = R_REG (osh, &cc->pllcontrol_data); - if (xt->freq >= PMU0_PLL0_PC0_PDIV_FREQ) - tmp |= PMU0_PLL0_PC0_PDIV_MASK; - else - tmp &= ~PMU0_PLL0_PC0_PDIV_MASK; - W_REG (osh, &cc->pllcontrol_data, tmp); - - /* Write WILD in pllcontrol[1] */ - W_REG (osh, &cc->pllcontrol_addr, PMU0_PLL0_PLLCTL1); - tmp = R_REG (osh, &cc->pllcontrol_data); - tmp = - ((tmp & ~(PMU0_PLL0_PC1_WILD_INT_MASK | PMU0_PLL0_PC1_WILD_FRAC_MASK)) | - (((xt-> - wbint << PMU0_PLL0_PC1_WILD_INT_SHIFT) & PMU0_PLL0_PC1_WILD_INT_MASK) - | ((xt->wbfrac << PMU0_PLL0_PC1_WILD_FRAC_SHIFT) & - PMU0_PLL0_PC1_WILD_FRAC_MASK))); - if (xt->wbfrac == 0) - tmp |= PMU0_PLL0_PC1_STOP_MOD; - else - tmp &= ~PMU0_PLL0_PC1_STOP_MOD; - W_REG (osh, &cc->pllcontrol_data, tmp); - - /* Write WILD in pllcontrol[2] */ - W_REG (osh, &cc->pllcontrol_addr, PMU0_PLL0_PLLCTL2); - tmp = R_REG (osh, &cc->pllcontrol_data); - tmp = ((tmp & ~PMU0_PLL0_PC2_WILD_INT_MASK) | - ((xt->wbint >> PMU0_PLL0_PC2_WILD_INT_SHIFT) & - PMU0_PLL0_PC2_WILD_INT_MASK)); - W_REG (osh, &cc->pllcontrol_data, tmp); - - PMU_MSG (("Done pll\n")); - - /* Write XtalFreq. Set the divisor also. */ - tmp = R_REG (osh, &cc->pmucontrol); - tmp = ((tmp & ~PCTL_ILP_DIV_MASK) | - (((((xt->freq + 127) / 128) - 1) << PCTL_ILP_DIV_SHIFT) & - PCTL_ILP_DIV_MASK)); - tmp = ((tmp & ~PCTL_XTALFREQ_MASK) | - ((xt->xf << PCTL_XTALFREQ_SHIFT) & PCTL_XTALFREQ_MASK)); - W_REG (osh, &cc->pmucontrol, tmp); -} - -static uint32 -BCMINITFN (sb_pmu0_alpclk0) (sb_t * sbh, osl_t * osh, chipcregs_t * cc) -{ - const pmu0_xtaltab0_t *xt; - uint32 xf; - - /* Find the frequency in the table */ - xf = (R_REG (osh, &cc->pmucontrol) & PCTL_XTALFREQ_MASK) >> - PCTL_XTALFREQ_SHIFT; - for (xt = pmu0_xtaltab0; xt->freq; xt++) - if (xt->xf == xf) - break; - if (xt->freq == 0) - xt = &pmu0_xtaltab0[PMU0_XTAL0_DEFAULT]; - - return xt->freq * 1000; -} - -static uint32 -BCMINITFN (sb_pmu0_cpuclk0) (sb_t * sbh, osl_t * osh, chipcregs_t * cc) -{ - const pmu0_xtaltab0_t *xt; - uint32 xf, tmp, divarm; -#ifdef BCMDBG - uint32 pdiv, wbint, wbfrac, fvco; -#endif - - if (sb_chip (sbh) == BCM5354_CHIP_ID) - { - /* 5354 gets sb clock of 120MHz from main pll */ - return 120000000; - } - - /* Find the xtal frequency in the table */ - xf = (R_REG (osh, &cc->pmucontrol) & PCTL_XTALFREQ_MASK) >> - PCTL_XTALFREQ_SHIFT; - for (xt = pmu0_xtaltab0; xt->freq; xt++) - if (xt->xf == xf) - break; - if (xt->freq == 0) - xt = &pmu0_xtaltab0[PMU0_XTAL0_DEFAULT]; - - /* Read divarm from pllcontrol[0] */ - W_REG (osh, &cc->pllcontrol_addr, PMU0_PLL0_PLLCTL0); - tmp = R_REG (osh, &cc->pllcontrol_data); - divarm = (tmp & PMU0_PLL0_PC0_DIV_ARM_MASK) >> PMU0_PLL0_PC0_DIV_ARM_SHIFT; - -#ifdef BCMDBG - /* Calculate Fvco based on xtal freq, pdiv, and wild */ - pdiv = tmp & PMU0_PLL0_PC0_PDIV_MASK; - - W_REG (osh, &cc->pllcontrol_addr, PMU0_PLL0_PLLCTL1); - tmp = R_REG (osh, &cc->pllcontrol_data); - wbfrac = - (tmp & PMU0_PLL0_PC1_WILD_FRAC_MASK) >> PMU0_PLL0_PC1_WILD_FRAC_SHIFT; - wbint = (tmp & PMU0_PLL0_PC1_WILD_INT_MASK) >> PMU0_PLL0_PC1_WILD_INT_SHIFT; - - W_REG (osh, &cc->pllcontrol_addr, PMU0_PLL0_PLLCTL2); - tmp = R_REG (osh, &cc->pllcontrol_data); - wbint += - (tmp & PMU0_PLL0_PC2_WILD_INT_MASK) << PMU0_PLL0_PC2_WILD_INT_SHIFT; - - fvco = (xt->freq * wbint) << 8; - fvco += (xt->freq * (wbfrac >> 10)) >> 2; - fvco += (xt->freq * (wbfrac & 0x3ff)) >> 10; - fvco >>= 8; - fvco >>= pdiv; - fvco /= 1000; - fvco *= 1000; - - PMU_MSG (("sb_pmu0_cpuclk0: wbint %u wbfrac %u fvco %u\n", - wbint, wbfrac, fvco)); - ASSERT (fvco == PMU0_PLL0_FVCO); -#endif /* BCMDBG */ - - /* Return ARM/SB clock */ - return PMU0_PLL0_FVCO / (divarm + PMU0_PLL0_PC0_DIV_ARM_BASE) * 1000; -} - -/* PMU corerev 1 pll programming for BCM4325 */ -/* setup pll and query clock speed */ -typedef struct -{ - uint16 fref; - uint8 xf; - uint8 p1div; - uint8 p2div; - uint8 ndiv_int; - uint32 ndiv_frac; -} pmu1_xtaltab0_t; - -/* the following table is based on 880Mhz Fvco */ -#define PMU1_PLL0_FVCO 880000 /* Fvco 880Mhz */ -static const pmu1_xtaltab0_t -BCMINITDATA (pmu1_xtaltab0)[] = -{ - { - 12000, 1, 3, 22, 0x9, 0xFFFFEF}, - { - 13000, 2, 1, 6, 0xb, 0x483483}, - { - 14400, 3, 1, 10, 0xa, 0x1C71C7}, - { - 15360, 4, 1, 5, 0xb, 0x755555}, - { - 16200, 5, 1, 10, 0x5, 0x6E9E06}, - { - 16800, 6, 1, 10, 0x5, 0x3Cf3Cf}, - { - 19200, 7, 1, 9, 0x5, 0x17B425}, - { - 19800, 8, 1, 11, 0x4, 0xA57EB}, - { - 20000, 9, 1, 11, 0x4, 0x0}, - { - 24000, 10, 3, 11, 0xa, 0x0}, - { - 25000, 11, 5, 16, 0xb, 0x0}, - { - 26000, 12, 1, 2, 0x10, 0xEC4EC4}, - { - 30000, 13, 3, 8, 0xb, 0x0}, - { - 38400, 14, 1, 5, 0x4, 0x955555}, - { - 40000, 15, 1, 2, 0xb, 0}, - { - 0, 0, 0, 0, 0, 0} -}; - -/* Default to 15360Khz crystal */ -#define PMU1_XTAL0_DEFAULT 3 - -static uint32 -BCMINITFN (sb_pmu1_alpclk0) (sb_t * sbh, osl_t * osh, chipcregs_t * cc) -{ - const pmu1_xtaltab0_t *xt; - uint32 xf; - - /* Find the frequency in the table */ - xf = (R_REG (osh, &cc->pmucontrol) & PCTL_XTALFREQ_MASK) >> - PCTL_XTALFREQ_SHIFT; - for (xt = pmu1_xtaltab0; xt->fref; xt++) - if (xt->xf == xf) - break; - if (xt->fref == 0) - xt = &pmu1_xtaltab0[PMU1_XTAL0_DEFAULT]; - - return xt->fref * 1000; -} - -/* Set up PLL registers in the PMU as per the crystal speed. - * Uses xtalfreq variable, or passed-in default. - */ -static void -BCMINITFN (sb_pmu1_pllinit0) (sb_t * sbh, osl_t * osh, chipcregs_t * cc, - uint32 xtal) -{ - const pmu1_xtaltab0_t *xt; - uint32 tmp; - uint32 buf_strength = 0; - - /* 4312: assume default works */ - if (sbh->chip == BCM4312_CHIP_ID) - return; - - /* Find the frequency in the table */ - for (xt = pmu1_xtaltab0; xt->fref; xt++) - if (xt->fref == xtal) - break; - if (xt->fref == 0) - xt = &pmu1_xtaltab0[PMU1_XTAL0_DEFAULT]; - - PMU_MSG (("XTAL %d (%d)\n", xtal, xt->xf)); - - /* Check current PLL state */ - if (((R_REG (osh, &cc->pmucontrol) & PCTL_XTALFREQ_MASK) >> - PCTL_XTALFREQ_SHIFT) == xt->xf) - { - PMU_MSG (("PLL already programmed for %d.%d MHz\n", - (xt->fref / 1000), (xt->fref % 1000))); - return; - } - - PMU_MSG (("Programming PLL for %d.%d MHz\n", (xt->fref / 1000), - (xt->fref % 1000))); - - /* Make sure the PLL is off */ - switch (sbh->chip) - { - case BCM4325_CHIP_ID: - AND_REG (osh, &cc->min_res_mask, - ~(PMURES_BIT (RES4325_BBPLL_PWRSW_PU) | - PMURES_BIT (RES4325_HT_AVAIL))); - AND_REG (osh, &cc->max_res_mask, - ~(PMURES_BIT (RES4325_BBPLL_PWRSW_PU) | - PMURES_BIT (RES4325_HT_AVAIL))); - - /* Change the BBPLL drive strength to 2 for all channels */ - buf_strength = 0x222222; - break; - default: - ASSERT (0); - } - SPINWAIT (R_REG (osh, &cc->clk_ctl_st) & CCS_HTAVAIL, - PMU_MAX_TRANSITION_DLY); - ASSERT (!(R_REG (osh, &cc->clk_ctl_st) & CCS_HTAVAIL)); - - PMU_MSG (("Done masking\n")); - - /* Write p1div and p2div to pllcontrol[0] */ - W_REG (osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0); - tmp = R_REG (osh, &cc->pllcontrol_data) & - ~(PMU1_PLL0_PC0_P1DIV_MASK | PMU1_PLL0_PC0_P2DIV_MASK); - tmp |= - ((xt-> - p1div << PMU1_PLL0_PC0_P1DIV_SHIFT) & PMU1_PLL0_PC0_P1DIV_MASK) | ((xt-> - p2div - << - PMU1_PLL0_PC0_P2DIV_SHIFT) - & - PMU1_PLL0_PC0_P2DIV_MASK); - W_REG (osh, &cc->pllcontrol_data, tmp); - - /* Write ndiv_int and ndiv_mode to pllcontrol[2] */ - W_REG (osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2); - tmp = R_REG (osh, &cc->pllcontrol_data) & - ~(PMU1_PLL0_PC2_NDIV_INT_MASK | PMU1_PLL0_PC2_NDIV_MODE_MASK); - tmp |= - ((xt-> - ndiv_int << PMU1_PLL0_PC2_NDIV_INT_SHIFT) & PMU1_PLL0_PC2_NDIV_INT_MASK) - | ((1 << PMU1_PLL0_PC2_NDIV_MODE_SHIFT) & PMU1_PLL0_PC2_NDIV_MODE_MASK); - W_REG (osh, &cc->pllcontrol_data, tmp); - - /* Write ndiv_frac to pllcontrol[3] */ - W_REG (osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL3); - tmp = R_REG (osh, &cc->pllcontrol_data) & ~PMU1_PLL0_PC3_NDIV_FRAC_MASK; - tmp |= ((xt->ndiv_frac << PMU1_PLL0_PC3_NDIV_FRAC_SHIFT) & - PMU1_PLL0_PC3_NDIV_FRAC_MASK); - W_REG (osh, &cc->pllcontrol_data, tmp); - - if (buf_strength) - { - PMU_MSG (("Adjusting PLL buffer drive strength: %x\n", buf_strength)); - - W_REG (osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL5); - tmp = R_REG (osh, &cc->pllcontrol_data) & ~PMU1_PLL0_PC5_CLK_DRV_MASK; - tmp |= (buf_strength << PMU1_PLL0_PC5_CLK_DRV_SHIFT); - W_REG (osh, &cc->pllcontrol_data, tmp); - } - - PMU_MSG (("Done pll\n")); - - /* Write XtalFreq. Set the divisor also. */ - tmp = R_REG (osh, &cc->pmucontrol) & - ~(PCTL_ILP_DIV_MASK | PCTL_XTALFREQ_MASK); - tmp |= (((((xt->fref + 127) / 128) - 1) << PCTL_ILP_DIV_SHIFT) & - PCTL_ILP_DIV_MASK) | - ((xt->xf << PCTL_XTALFREQ_SHIFT) & PCTL_XTALFREQ_MASK); - W_REG (osh, &cc->pmucontrol, tmp); -} - - -static uint32 -BCMINITFN (sb_pmu1_cpuclk0) (sb_t * sbh, osl_t * osh, chipcregs_t * cc) -{ - const pmu1_xtaltab0_t *xt; - uint32 xf, tmp, m1div; -#ifdef BCMDBG - uint32 ndiv_int, ndiv_frac, p2div, p1div, fvco; -#endif - - /* Find the xtal frequency in the table */ - xf = (R_REG (osh, &cc->pmucontrol) & PCTL_XTALFREQ_MASK) >> - PCTL_XTALFREQ_SHIFT; - for (xt = pmu1_xtaltab0; xt->fref; xt++) - if (xt->xf == xf) - break; - if (xt->fref == 0) - xt = &pmu1_xtaltab0[PMU1_XTAL0_DEFAULT]; - - /* Read m1div from pllcontrol[1] */ - W_REG (osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL1); - tmp = R_REG (osh, &cc->pllcontrol_data); - m1div = (tmp & PMU1_PLL0_PC1_M1DIV_MASK) >> PMU1_PLL0_PC1_M1DIV_SHIFT; - -#ifdef BCMDBG - /* Read p2div/p1div from pllcontrol[0] */ - W_REG (osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0); - tmp = R_REG (osh, &cc->pllcontrol_data); - p2div = (tmp & PMU1_PLL0_PC0_P2DIV_MASK) >> PMU1_PLL0_PC0_P2DIV_SHIFT; - p1div = (tmp & PMU1_PLL0_PC0_P1DIV_MASK) >> PMU1_PLL0_PC0_P1DIV_SHIFT; - - /* Calculate Fvco based on xtal freq and ndiv and pdiv */ - W_REG (osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2); - tmp = R_REG (osh, &cc->pllcontrol_data); - ndiv_int = - (tmp & PMU1_PLL0_PC2_NDIV_INT_MASK) >> PMU1_PLL0_PC2_NDIV_INT_SHIFT; - - W_REG (osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL3); - tmp = R_REG (osh, &cc->pllcontrol_data); - ndiv_frac = - (tmp & PMU1_PLL0_PC3_NDIV_FRAC_MASK) >> PMU1_PLL0_PC3_NDIV_FRAC_SHIFT; - - fvco = (xt->fref * ndiv_int) << 8; - fvco += (xt->fref * (ndiv_frac >> 12)) >> 4; - fvco += (xt->fref * (ndiv_frac & 0xfff)) >> 12; - fvco >>= 8; - fvco *= p2div; - fvco /= p1div; - fvco /= 1000; - fvco *= 1000; - - PMU_MSG (("sb_pmu0_cpuclk0: ndiv_int %u ndiv_frac %u " - "p2div %u p1div %u fvco %u\n", - ndiv_int, ndiv_frac, p2div, p1div, fvco)); - ASSERT (fvco == PMU1_PLL0_FVCO); -#endif /* BCMDBG */ - - /* Return ARM/SB clock */ - return PMU1_PLL0_FVCO / m1div * 1000; -} - -void BCMINITFN (sb_pmu_pll_init) (sb_t * sbh, osl_t * osh, uint xtalfreq) -{ - chipcregs_t *cc; - uint origidx; - - ASSERT (sbh->cccaps & CC_CAP_PMU); - - /* Remember original core before switch to chipc */ - origidx = sb_coreidx (sbh); - cc = sb_setcore (sbh, SB_CC, 0); - ASSERT (cc); - - switch (sbh->chip) - { - case BCM4328_CHIP_ID: - sb_pmu0_pllinit0 (sbh, osh, cc, xtalfreq); - break; - case BCM5354_CHIP_ID: - sb_pmu0_pllinit0 (sbh, osh, cc, xtalfreq); - break; - case BCM4325_CHIP_ID: - sb_pmu1_pllinit0 (sbh, osh, cc, xtalfreq); - break; - case BCM4312_CHIP_ID: - sb_pmu1_pllinit0 (sbh, osh, cc, xtalfreq); - break; - default: - PMU_MSG (("No PLL init done for chip %x rev %d pmurev %d\n", - sbh->chip, sbh->chiprev, sbh->pmurev)); - break; - } - - /* Return to original core */ - sb_setcoreidx (sbh, origidx); -} - -uint32 BCMINITFN (sb_pmu_alp_clock) (sb_t * sbh, osl_t * osh) -{ - chipcregs_t *cc; - uint origidx; - uint32 clock = ALP_CLOCK; - - ASSERT (sbh->cccaps & CC_CAP_PMU); - - /* Remember original core before switch to chipc */ - origidx = sb_coreidx (sbh); - cc = sb_setcore (sbh, SB_CC, 0); - ASSERT (cc); - - switch (sbh->chip) - { - case BCM4328_CHIP_ID: - clock = sb_pmu0_alpclk0 (sbh, osh, cc); - break; - case BCM5354_CHIP_ID: - clock = sb_pmu0_alpclk0 (sbh, osh, cc); - break; - case BCM4325_CHIP_ID: - clock = sb_pmu1_alpclk0 (sbh, osh, cc); - break; - case BCM4312_CHIP_ID: - clock = sb_pmu1_alpclk0 (sbh, osh, cc); - /* always 20Mhz */ - clock = 20000 * 1000; - break; - default: - PMU_MSG (("No ALP clock specified " - "for chip %x rev %d pmurev %d, using default %d Hz\n", - sbh->chip, sbh->chiprev, sbh->pmurev, clock)); - break; - } - - /* Return to original core */ - sb_setcoreidx (sbh, origidx); - return clock; -} - -uint BCMINITFN (sb_pmu_cpu_clock) (sb_t * sbh, osl_t * osh) -{ - chipcregs_t *cc; - uint origidx; - uint32 clock = HT_CLOCK; - - ASSERT (sbh->cccaps & CC_CAP_PMU); - - /* Remember original core before switch to chipc */ - origidx = sb_coreidx (sbh); - cc = sb_setcore (sbh, SB_CC, 0); - ASSERT (cc); - - switch (sbh->chip) - { - case BCM4328_CHIP_ID: - clock = sb_pmu0_cpuclk0 (sbh, osh, cc); - break; - case BCM5354_CHIP_ID: - clock = sb_pmu0_cpuclk0 (sbh, osh, cc); - break; - case BCM4325_CHIP_ID: - clock = sb_pmu1_cpuclk0 (sbh, osh, cc); - break; - case BCM4312_CHIP_ID: - clock = sb_pmu1_cpuclk0 (sbh, osh, cc); - break; - default: - PMU_MSG (("No CPU clock specified " - "for chip %x rev %d pmurev %d, using default %d Hz\n", - sbh->chip, sbh->chiprev, sbh->pmurev, clock)); - break; - } - - /* Return to original core */ - sb_setcoreidx (sbh, origidx); - return clock; -} - -void BCMINITFN (sb_pmu_init) (sb_t * sbh, osl_t * osh) -{ - chipcregs_t *cc; - uint origidx; - - ASSERT (sbh->cccaps & CC_CAP_PMU); - - /* Remember original core before switch to chipc */ - origidx = sb_coreidx (sbh); - cc = sb_setcore (sbh, SB_CC, 0); - ASSERT (cc); - - if (sbh->pmurev >= 1) - { - if (sbh->chip == BCM4325_CHIP_ID && sbh->chiprev <= 1) - AND_REG (osh, &cc->pmucontrol, ~PCTL_NOILP_ON_WAIT); - else - OR_REG (osh, &cc->pmucontrol, PCTL_NOILP_ON_WAIT); - } - - /* Return to original core */ - sb_setcoreidx (sbh, origidx); -} - -void BCMINITFN (sb_pmu_otp_power) (sb_t * sbh, osl_t * osh, bool on) -{ - chipcregs_t *cc; - uint origidx; - - ASSERT (sbh->cccaps & CC_CAP_PMU); - - /* Remember original core before switch to chipc */ - origidx = sb_coreidx (sbh); - cc = sb_setcore (sbh, SB_CC, 0); - ASSERT (cc); - - switch (sbh->chip) - { - case BCM4325_CHIP_ID: - if (on) - { - OR_REG (osh, &cc->min_res_mask, PMURES_BIT (RES4325_LNLDO2_PU)); - if (sbh->boardflags & BFL_BUCKBOOST) - AND_REG (osh, &cc->min_res_mask, - ~PMURES_BIT (RES4325_BUCK_BOOST_PWM)); - OSL_DELAY (500); - } - else - { - if (sbh->boardflags & BFL_BUCKBOOST) - OR_REG (osh, &cc->min_res_mask, - PMURES_BIT (RES4325_BUCK_BOOST_PWM)); - AND_REG (osh, &cc->min_res_mask, ~PMURES_BIT (RES4325_LNLDO2_PU)); - } - break; - default: - break; - } - - /* Return to original core */ - sb_setcoreidx (sbh, origidx); -} - -void -sb_pmu_rcal (sb_t * sbh, osl_t * osh) -{ - chipcregs_t *cc; - uint origidx; - - ASSERT (sbh->cccaps & CC_CAP_PMU); - - /* Remember original core before switch to chipc */ - origidx = sb_coreidx (sbh); - cc = sb_setcore (sbh, SB_CC, 0); - ASSERT (cc); - - switch (sbh->chip) - { - case BCM4325_CHIP_ID: - { - uint8 rcal_code; - uint32 val; - - /* Kick RCal */ - W_REG (osh, &cc->chipcontrol_addr, 1); - AND_REG (osh, &cc->chipcontrol_data, ~0x04); - OR_REG (osh, &cc->chipcontrol_data, 0x04); - - /* Wait for completion */ - SPINWAIT (0 == (R_REG (osh, &cc->chipstatus) & 0x08), - 10 * 1000 * 1000); - ASSERT (R_REG (osh, &cc->chipstatus) & 0x08); - - /* Drop the LSB to convert from 5 bit code to 4 bit code */ - rcal_code = (uint8) (R_REG (osh, &cc->chipstatus) >> 5) & 0x0f; - PMU_MSG (("RCal completed, status 0x%x, code 0x%x\n", - R_REG (osh, &cc->chipstatus), rcal_code)); - - /* Write RCal code into pmu_vreg_ctrl[32:29] */ - W_REG (osh, &cc->regcontrol_addr, 0); - val = R_REG (osh, &cc->regcontrol_data) & ~((uint32) 0x07 << 29); - val |= (uint32) (rcal_code & 0x07) << 29; - W_REG (osh, &cc->regcontrol_data, val); - W_REG (osh, &cc->regcontrol_addr, 1); - val = R_REG (osh, &cc->regcontrol_data) & ~(uint32) 0x01; - val |= (uint32) ((rcal_code >> 3) & 0x01); - W_REG (osh, &cc->regcontrol_data, val); - - /* Write RCal code into pmu_chip_ctrl[33:30] */ - W_REG (osh, &cc->chipcontrol_addr, 0); - val = R_REG (osh, &cc->chipcontrol_data) & ~((uint32) 0x03 << 30); - val |= (uint32) (rcal_code & 0x03) << 30; - W_REG (osh, &cc->chipcontrol_data, val); - W_REG (osh, &cc->chipcontrol_addr, 1); - val = R_REG (osh, &cc->chipcontrol_data) & ~(uint32) 0x03; - val |= (uint32) ((rcal_code >> 2) & 0x03); - W_REG (osh, &cc->chipcontrol_data, val); - - /* Set override in pmu_chip_ctrl[29] */ - W_REG (osh, &cc->chipcontrol_addr, 0); - OR_REG (osh, &cc->chipcontrol_data, (0x01 << 29)); - - /* Power off RCal block */ - W_REG (osh, &cc->chipcontrol_addr, 1); - AND_REG (osh, &cc->chipcontrol_data, ~0x04); - - break; - } - default: - break; - } - - /* Return to original core */ - sb_setcoreidx (sbh, origidx); -} -- cgit v1.2.3