Back to home page

OSCL-LXR

 
 

    


0001 /*
0002  * Copyright (c) 2011 Broadcom Corporation
0003  *
0004  * Permission to use, copy, modify, and/or distribute this software for any
0005  * purpose with or without fee is hereby granted, provided that the above
0006  * copyright notice and this permission notice appear in all copies.
0007  *
0008  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
0009  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
0010  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
0011  * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
0012  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
0013  * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
0014  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
0015  */
0016 
0017 #include <linux/delay.h>
0018 #include <linux/io.h>
0019 
0020 #include <brcm_hw_ids.h>
0021 #include <chipcommon.h>
0022 #include <brcmu_utils.h>
0023 #include "pub.h"
0024 #include "aiutils.h"
0025 #include "pmu.h"
0026 #include "soc.h"
0027 
0028 /*
0029  * external LPO crystal frequency
0030  */
0031 #define EXT_ILP_HZ 32768
0032 
0033 /*
0034  * Duration for ILP clock frequency measurment in milliseconds
0035  *
0036  * remark: 1000 must be an integer multiple of this duration
0037  */
0038 #define ILP_CALC_DUR    10
0039 
0040 /* Fields in pmucontrol */
0041 #define PCTL_ILP_DIV_MASK   0xffff0000
0042 #define PCTL_ILP_DIV_SHIFT  16
0043 #define PCTL_PLL_PLLCTL_UPD 0x00000400  /* rev 2 */
0044 #define PCTL_NOILP_ON_WAIT  0x00000200  /* rev 1 */
0045 #define PCTL_HT_REQ_EN      0x00000100
0046 #define PCTL_ALP_REQ_EN     0x00000080
0047 #define PCTL_XTALFREQ_MASK  0x0000007c
0048 #define PCTL_XTALFREQ_SHIFT 2
0049 #define PCTL_ILP_DIV_EN     0x00000002
0050 #define PCTL_LPO_SEL        0x00000001
0051 
0052 /* ILP clock */
0053 #define ILP_CLOCK       32000
0054 
0055 /* ALP clock on pre-PMU chips */
0056 #define ALP_CLOCK       20000000
0057 
0058 /* pmustatus */
0059 #define PST_EXTLPOAVAIL 0x0100
0060 #define PST_WDRESET 0x0080
0061 #define PST_INTPEND 0x0040
0062 #define PST_SBCLKST 0x0030
0063 #define PST_SBCLKST_ILP 0x0010
0064 #define PST_SBCLKST_ALP 0x0020
0065 #define PST_SBCLKST_HT  0x0030
0066 #define PST_ALPAVAIL    0x0008
0067 #define PST_HTAVAIL 0x0004
0068 #define PST_RESINIT 0x0003
0069 
0070 /* PMU resource bit position */
0071 #define PMURES_BIT(bit) (1 << (bit))
0072 
0073 /* PMU corerev and chip specific PLL controls.
0074  * PMU<rev>_PLL<num>_XX where <rev> is PMU corerev and <num> is an arbitrary
0075  * number to differentiate different PLLs controlled by the same PMU rev.
0076  */
0077 
0078 /* pmu XtalFreqRatio */
0079 #define PMU_XTALFREQ_REG_ILPCTR_MASK    0x00001FFF
0080 #define PMU_XTALFREQ_REG_MEASURE_MASK   0x80000000
0081 #define PMU_XTALFREQ_REG_MEASURE_SHIFT  31
0082 
0083 /* 4313 resources */
0084 #define RES4313_BB_PU_RSRC      0
0085 #define RES4313_ILP_REQ_RSRC        1
0086 #define RES4313_XTAL_PU_RSRC        2
0087 #define RES4313_ALP_AVAIL_RSRC      3
0088 #define RES4313_RADIO_PU_RSRC       4
0089 #define RES4313_BG_PU_RSRC      5
0090 #define RES4313_VREG1P4_PU_RSRC     6
0091 #define RES4313_AFE_PWRSW_RSRC      7
0092 #define RES4313_RX_PWRSW_RSRC       8
0093 #define RES4313_TX_PWRSW_RSRC       9
0094 #define RES4313_BB_PWRSW_RSRC       10
0095 #define RES4313_SYNTH_PWRSW_RSRC    11
0096 #define RES4313_MISC_PWRSW_RSRC     12
0097 #define RES4313_BB_PLL_PWRSW_RSRC   13
0098 #define RES4313_HT_AVAIL_RSRC       14
0099 #define RES4313_MACPHY_CLK_AVAIL_RSRC   15
0100 
0101 u16 si_pmu_fast_pwrup_delay(struct si_pub *sih)
0102 {
0103     uint delay = PMU_MAX_TRANSITION_DLY;
0104 
0105     switch (ai_get_chip_id(sih)) {
0106     case BCMA_CHIP_ID_BCM43224:
0107     case BCMA_CHIP_ID_BCM43225:
0108     case BCMA_CHIP_ID_BCM4313:
0109         delay = 3700;
0110         break;
0111     default:
0112         break;
0113     }
0114 
0115     return (u16) delay;
0116 }
0117 
0118 u32 si_pmu_measure_alpclk(struct si_pub *sih)
0119 {
0120     struct si_info *sii = container_of(sih, struct si_info, pub);
0121     struct bcma_device *core;
0122     u32 alp_khz;
0123 
0124     if (ai_get_pmurev(sih) < 10)
0125         return 0;
0126 
0127     /* Remember original core before switch to chipc */
0128     core = sii->icbus->drv_cc.core;
0129 
0130     if (bcma_read32(core, CHIPCREGOFFS(pmustatus)) & PST_EXTLPOAVAIL) {
0131         u32 ilp_ctr, alp_hz;
0132 
0133         /*
0134          * Enable the reg to measure the freq,
0135          * in case it was disabled before
0136          */
0137         bcma_write32(core, CHIPCREGOFFS(pmu_xtalfreq),
0138                 1U << PMU_XTALFREQ_REG_MEASURE_SHIFT);
0139 
0140         /* Delay for well over 4 ILP clocks */
0141         udelay(1000);
0142 
0143         /* Read the latched number of ALP ticks per 4 ILP ticks */
0144         ilp_ctr = bcma_read32(core, CHIPCREGOFFS(pmu_xtalfreq)) &
0145               PMU_XTALFREQ_REG_ILPCTR_MASK;
0146 
0147         /*
0148          * Turn off the PMU_XTALFREQ_REG_MEASURE_SHIFT
0149          * bit to save power
0150          */
0151         bcma_write32(core, CHIPCREGOFFS(pmu_xtalfreq), 0);
0152 
0153         /* Calculate ALP frequency */
0154         alp_hz = (ilp_ctr * EXT_ILP_HZ) / 4;
0155 
0156         /*
0157          * Round to nearest 100KHz, and at
0158          * the same time convert to KHz
0159          */
0160         alp_khz = (alp_hz + 50000) / 100000 * 100;
0161     } else
0162         alp_khz = 0;
0163 
0164     return alp_khz;
0165 }