Path: blob/main/sys/contrib/dev/broadcom/brcm80211/brcmsmac/pmu.c
178665 views
/*1* Copyright (c) 2011 Broadcom Corporation2*3* Permission to use, copy, modify, and/or distribute this software for any4* purpose with or without fee is hereby granted, provided that the above5* copyright notice and this permission notice appear in all copies.6*7* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES8* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF9* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY10* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES11* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION12* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN13* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.14*/1516#include <linux/delay.h>17#include <linux/io.h>1819#include <brcm_hw_ids.h>20#include <chipcommon.h>21#include <brcmu_utils.h>22#include "pub.h"23#include "aiutils.h"24#include "pmu.h"25#include "soc.h"2627/*28* external LPO crystal frequency29*/30#define EXT_ILP_HZ 327683132/*33* Duration for ILP clock frequency measurement in milliseconds34*35* remark: 1000 must be an integer multiple of this duration36*/37#define ILP_CALC_DUR 103839/* Fields in pmucontrol */40#define PCTL_ILP_DIV_MASK 0xffff000041#define PCTL_ILP_DIV_SHIFT 1642#define PCTL_PLL_PLLCTL_UPD 0x00000400 /* rev 2 */43#define PCTL_NOILP_ON_WAIT 0x00000200 /* rev 1 */44#define PCTL_HT_REQ_EN 0x0000010045#define PCTL_ALP_REQ_EN 0x0000008046#define PCTL_XTALFREQ_MASK 0x0000007c47#define PCTL_XTALFREQ_SHIFT 248#define PCTL_ILP_DIV_EN 0x0000000249#define PCTL_LPO_SEL 0x000000015051/* ILP clock */52#define ILP_CLOCK 320005354/* ALP clock on pre-PMU chips */55#define ALP_CLOCK 200000005657/* pmustatus */58#define PST_EXTLPOAVAIL 0x010059#define PST_WDRESET 0x008060#define PST_INTPEND 0x004061#define PST_SBCLKST 0x003062#define PST_SBCLKST_ILP 0x001063#define PST_SBCLKST_ALP 0x002064#define PST_SBCLKST_HT 0x003065#define PST_ALPAVAIL 0x000866#define PST_HTAVAIL 0x000467#define PST_RESINIT 0x00036869/* PMU resource bit position */70#define PMURES_BIT(bit) (1 << (bit))7172/* PMU corerev and chip specific PLL controls.73* PMU<rev>_PLL<num>_XX where <rev> is PMU corerev and <num> is an arbitrary74* number to differentiate different PLLs controlled by the same PMU rev.75*/7677/* pmu XtalFreqRatio */78#define PMU_XTALFREQ_REG_ILPCTR_MASK 0x00001FFF79#define PMU_XTALFREQ_REG_MEASURE_MASK 0x8000000080#define PMU_XTALFREQ_REG_MEASURE_SHIFT 318182/* 4313 resources */83#define RES4313_BB_PU_RSRC 084#define RES4313_ILP_REQ_RSRC 185#define RES4313_XTAL_PU_RSRC 286#define RES4313_ALP_AVAIL_RSRC 387#define RES4313_RADIO_PU_RSRC 488#define RES4313_BG_PU_RSRC 589#define RES4313_VREG1P4_PU_RSRC 690#define RES4313_AFE_PWRSW_RSRC 791#define RES4313_RX_PWRSW_RSRC 892#define RES4313_TX_PWRSW_RSRC 993#define RES4313_BB_PWRSW_RSRC 1094#define RES4313_SYNTH_PWRSW_RSRC 1195#define RES4313_MISC_PWRSW_RSRC 1296#define RES4313_BB_PLL_PWRSW_RSRC 1397#define RES4313_HT_AVAIL_RSRC 1498#define RES4313_MACPHY_CLK_AVAIL_RSRC 1599100u16 si_pmu_fast_pwrup_delay(struct si_pub *sih)101{102uint delay = PMU_MAX_TRANSITION_DLY;103104switch (ai_get_chip_id(sih)) {105case BCMA_CHIP_ID_BCM43224:106case BCMA_CHIP_ID_BCM43225:107case BCMA_CHIP_ID_BCM4313:108delay = 3700;109break;110default:111break;112}113114return (u16) delay;115}116117u32 si_pmu_measure_alpclk(struct si_pub *sih)118{119struct si_info *sii = container_of(sih, struct si_info, pub);120struct bcma_device *core;121u32 alp_khz;122123if (ai_get_pmurev(sih) < 10)124return 0;125126/* Remember original core before switch to chipc */127core = sii->icbus->drv_cc.core;128129if (bcma_read32(core, CHIPCREGOFFS(pmustatus)) & PST_EXTLPOAVAIL) {130u32 ilp_ctr, alp_hz;131132/*133* Enable the reg to measure the freq,134* in case it was disabled before135*/136bcma_write32(core, CHIPCREGOFFS(pmu_xtalfreq),1371U << PMU_XTALFREQ_REG_MEASURE_SHIFT);138139/* Delay for well over 4 ILP clocks */140udelay(1000);141142/* Read the latched number of ALP ticks per 4 ILP ticks */143ilp_ctr = bcma_read32(core, CHIPCREGOFFS(pmu_xtalfreq)) &144PMU_XTALFREQ_REG_ILPCTR_MASK;145146/*147* Turn off the PMU_XTALFREQ_REG_MEASURE_SHIFT148* bit to save power149*/150bcma_write32(core, CHIPCREGOFFS(pmu_xtalfreq), 0);151152/* Calculate ALP frequency */153alp_hz = (ilp_ctr * EXT_ILP_HZ) / 4;154155/*156* Round to nearest 100KHz, and at157* the same time convert to KHz158*/159alp_khz = (alp_hz + 50000) / 100000 * 100;160} else161alp_khz = 0;162163return alp_khz;164}165166167