root/drivers/net/wireless/broadcom/brcm80211/brcmsmac/pmu.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. si_pmu_fast_pwrup_delay
  2. si_pmu_measure_alpclk

   1 /*
   2  * Copyright (c) 2011 Broadcom Corporation
   3  *
   4  * Permission to use, copy, modify, and/or distribute this software for any
   5  * purpose with or without fee is hereby granted, provided that the above
   6  * copyright notice and this permission notice appear in all copies.
   7  *
   8  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
   9  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  10  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
  11  * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  12  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
  13  * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
  14  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  15  */
  16 
  17 #include <linux/delay.h>
  18 #include <linux/io.h>
  19 
  20 #include <brcm_hw_ids.h>
  21 #include <chipcommon.h>
  22 #include <brcmu_utils.h>
  23 #include "pub.h"
  24 #include "aiutils.h"
  25 #include "pmu.h"
  26 #include "soc.h"
  27 
  28 /*
  29  * external LPO crystal frequency
  30  */
  31 #define EXT_ILP_HZ 32768
  32 
  33 /*
  34  * Duration for ILP clock frequency measurment in milliseconds
  35  *
  36  * remark: 1000 must be an integer multiple of this duration
  37  */
  38 #define ILP_CALC_DUR    10
  39 
  40 /* Fields in pmucontrol */
  41 #define PCTL_ILP_DIV_MASK       0xffff0000
  42 #define PCTL_ILP_DIV_SHIFT      16
  43 #define PCTL_PLL_PLLCTL_UPD     0x00000400      /* rev 2 */
  44 #define PCTL_NOILP_ON_WAIT      0x00000200      /* rev 1 */
  45 #define PCTL_HT_REQ_EN          0x00000100
  46 #define PCTL_ALP_REQ_EN         0x00000080
  47 #define PCTL_XTALFREQ_MASK      0x0000007c
  48 #define PCTL_XTALFREQ_SHIFT     2
  49 #define PCTL_ILP_DIV_EN         0x00000002
  50 #define PCTL_LPO_SEL            0x00000001
  51 
  52 /* ILP clock */
  53 #define ILP_CLOCK               32000
  54 
  55 /* ALP clock on pre-PMU chips */
  56 #define ALP_CLOCK               20000000
  57 
  58 /* pmustatus */
  59 #define PST_EXTLPOAVAIL 0x0100
  60 #define PST_WDRESET     0x0080
  61 #define PST_INTPEND     0x0040
  62 #define PST_SBCLKST     0x0030
  63 #define PST_SBCLKST_ILP 0x0010
  64 #define PST_SBCLKST_ALP 0x0020
  65 #define PST_SBCLKST_HT  0x0030
  66 #define PST_ALPAVAIL    0x0008
  67 #define PST_HTAVAIL     0x0004
  68 #define PST_RESINIT     0x0003
  69 
  70 /* PMU resource bit position */
  71 #define PMURES_BIT(bit) (1 << (bit))
  72 
  73 /* PMU corerev and chip specific PLL controls.
  74  * PMU<rev>_PLL<num>_XX where <rev> is PMU corerev and <num> is an arbitrary
  75  * number to differentiate different PLLs controlled by the same PMU rev.
  76  */
  77 
  78 /* pmu XtalFreqRatio */
  79 #define PMU_XTALFREQ_REG_ILPCTR_MASK    0x00001FFF
  80 #define PMU_XTALFREQ_REG_MEASURE_MASK   0x80000000
  81 #define PMU_XTALFREQ_REG_MEASURE_SHIFT  31
  82 
  83 /* 4313 resources */
  84 #define RES4313_BB_PU_RSRC              0
  85 #define RES4313_ILP_REQ_RSRC            1
  86 #define RES4313_XTAL_PU_RSRC            2
  87 #define RES4313_ALP_AVAIL_RSRC          3
  88 #define RES4313_RADIO_PU_RSRC           4
  89 #define RES4313_BG_PU_RSRC              5
  90 #define RES4313_VREG1P4_PU_RSRC         6
  91 #define RES4313_AFE_PWRSW_RSRC          7
  92 #define RES4313_RX_PWRSW_RSRC           8
  93 #define RES4313_TX_PWRSW_RSRC           9
  94 #define RES4313_BB_PWRSW_RSRC           10
  95 #define RES4313_SYNTH_PWRSW_RSRC        11
  96 #define RES4313_MISC_PWRSW_RSRC         12
  97 #define RES4313_BB_PLL_PWRSW_RSRC       13
  98 #define RES4313_HT_AVAIL_RSRC           14
  99 #define RES4313_MACPHY_CLK_AVAIL_RSRC   15
 100 
 101 u16 si_pmu_fast_pwrup_delay(struct si_pub *sih)
 102 {
 103         uint delay = PMU_MAX_TRANSITION_DLY;
 104 
 105         switch (ai_get_chip_id(sih)) {
 106         case BCMA_CHIP_ID_BCM43224:
 107         case BCMA_CHIP_ID_BCM43225:
 108         case BCMA_CHIP_ID_BCM4313:
 109                 delay = 3700;
 110                 break;
 111         default:
 112                 break;
 113         }
 114 
 115         return (u16) delay;
 116 }
 117 
 118 u32 si_pmu_measure_alpclk(struct si_pub *sih)
 119 {
 120         struct si_info *sii = container_of(sih, struct si_info, pub);
 121         struct bcma_device *core;
 122         u32 alp_khz;
 123 
 124         if (ai_get_pmurev(sih) < 10)
 125                 return 0;
 126 
 127         /* Remember original core before switch to chipc */
 128         core = sii->icbus->drv_cc.core;
 129 
 130         if (bcma_read32(core, CHIPCREGOFFS(pmustatus)) & PST_EXTLPOAVAIL) {
 131                 u32 ilp_ctr, alp_hz;
 132 
 133                 /*
 134                  * Enable the reg to measure the freq,
 135                  * in case it was disabled before
 136                  */
 137                 bcma_write32(core, CHIPCREGOFFS(pmu_xtalfreq),
 138                             1U << PMU_XTALFREQ_REG_MEASURE_SHIFT);
 139 
 140                 /* Delay for well over 4 ILP clocks */
 141                 udelay(1000);
 142 
 143                 /* Read the latched number of ALP ticks per 4 ILP ticks */
 144                 ilp_ctr = bcma_read32(core, CHIPCREGOFFS(pmu_xtalfreq)) &
 145                           PMU_XTALFREQ_REG_ILPCTR_MASK;
 146 
 147                 /*
 148                  * Turn off the PMU_XTALFREQ_REG_MEASURE_SHIFT
 149                  * bit to save power
 150                  */
 151                 bcma_write32(core, CHIPCREGOFFS(pmu_xtalfreq), 0);
 152 
 153                 /* Calculate ALP frequency */
 154                 alp_hz = (ilp_ctr * EXT_ILP_HZ) / 4;
 155 
 156                 /*
 157                  * Round to nearest 100KHz, and at
 158                  * the same time convert to KHz
 159                  */
 160                 alp_khz = (alp_hz + 50000) / 100000 * 100;
 161         } else
 162                 alp_khz = 0;
 163 
 164         return alp_khz;
 165 }

/* [<][>][^][v][top][bottom][index][help] */