aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/bcma/driver_chipcommon_pmu.c
diff options
context:
space:
mode:
authorRafał Miłecki <zajec5@gmail.com>2013-06-26 04:02:11 -0400
committerJohn W. Linville <linville@tuxdriver.com>2013-06-27 13:42:16 -0400
commit88f9b65d444794bb607f71644362ba0642585206 (patch)
tree79b35a37ff7dbff438e572ce39b0aa8c43b2ff24 /drivers/bcma/driver_chipcommon_pmu.c
parent8960400eeefa73e7fe32dc2b6b5ac529d43a9593 (diff)
bcma: add support for BCM43142
Signed-off-by: Rafał Miłecki <zajec5@gmail.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/bcma/driver_chipcommon_pmu.c')
-rw-r--r--drivers/bcma/driver_chipcommon_pmu.c123
1 files changed, 123 insertions, 0 deletions
diff --git a/drivers/bcma/driver_chipcommon_pmu.c b/drivers/bcma/driver_chipcommon_pmu.c
index edca73af3cc0..5081a8c439cc 100644
--- a/drivers/bcma/driver_chipcommon_pmu.c
+++ b/drivers/bcma/driver_chipcommon_pmu.c
@@ -56,6 +56,109 @@ void bcma_chipco_regctl_maskset(struct bcma_drv_cc *cc, u32 offset, u32 mask,
56} 56}
57EXPORT_SYMBOL_GPL(bcma_chipco_regctl_maskset); 57EXPORT_SYMBOL_GPL(bcma_chipco_regctl_maskset);
58 58
59static u32 bcma_pmu_xtalfreq(struct bcma_drv_cc *cc)
60{
61 u32 ilp_ctl, alp_hz;
62
63 if (!(bcma_cc_read32(cc, BCMA_CC_PMU_STAT) &
64 BCMA_CC_PMU_STAT_EXT_LPO_AVAIL))
65 return 0;
66
67 bcma_cc_write32(cc, BCMA_CC_PMU_XTAL_FREQ,
68 BIT(BCMA_CC_PMU_XTAL_FREQ_MEASURE_SHIFT));
69 usleep_range(1000, 2000);
70
71 ilp_ctl = bcma_cc_read32(cc, BCMA_CC_PMU_XTAL_FREQ);
72 ilp_ctl &= BCMA_CC_PMU_XTAL_FREQ_ILPCTL_MASK;
73
74 bcma_cc_write32(cc, BCMA_CC_PMU_XTAL_FREQ, 0);
75
76 alp_hz = ilp_ctl * 32768 / 4;
77 return (alp_hz + 50000) / 100000 * 100;
78}
79
80static void bcma_pmu2_pll_init0(struct bcma_drv_cc *cc, u32 xtalfreq)
81{
82 struct bcma_bus *bus = cc->core->bus;
83 u32 freq_tgt_target = 0, freq_tgt_current;
84 u32 pll0, mask;
85
86 switch (bus->chipinfo.id) {
87 case BCMA_CHIP_ID_BCM43142:
88 /* pmu2_xtaltab0_adfll_485 */
89 switch (xtalfreq) {
90 case 12000:
91 freq_tgt_target = 0x50D52;
92 break;
93 case 20000:
94 freq_tgt_target = 0x307FE;
95 break;
96 case 26000:
97 freq_tgt_target = 0x254EA;
98 break;
99 case 37400:
100 freq_tgt_target = 0x19EF8;
101 break;
102 case 52000:
103 freq_tgt_target = 0x12A75;
104 break;
105 }
106 break;
107 }
108
109 if (!freq_tgt_target) {
110 bcma_err(bus, "Unknown TGT frequency for xtalfreq %d\n",
111 xtalfreq);
112 return;
113 }
114
115 pll0 = bcma_chipco_pll_read(cc, BCMA_CC_PMU15_PLL_PLLCTL0);
116 freq_tgt_current = (pll0 & BCMA_CC_PMU15_PLL_PC0_FREQTGT_MASK) >>
117 BCMA_CC_PMU15_PLL_PC0_FREQTGT_SHIFT;
118
119 if (freq_tgt_current == freq_tgt_target) {
120 bcma_debug(bus, "Target TGT frequency already set\n");
121 return;
122 }
123
124 /* Turn off PLL */
125 switch (bus->chipinfo.id) {
126 case BCMA_CHIP_ID_BCM43142:
127 mask = (u32)~(BCMA_RES_4314_HT_AVAIL |
128 BCMA_RES_4314_MACPHY_CLK_AVAIL);
129
130 bcma_cc_mask32(cc, BCMA_CC_PMU_MINRES_MSK, mask);
131 bcma_cc_mask32(cc, BCMA_CC_PMU_MAXRES_MSK, mask);
132 bcma_wait_value(cc->core, BCMA_CLKCTLST,
133 BCMA_CLKCTLST_HAVEHT, 0, 20000);
134 break;
135 }
136
137 pll0 &= ~BCMA_CC_PMU15_PLL_PC0_FREQTGT_MASK;
138 pll0 |= freq_tgt_target << BCMA_CC_PMU15_PLL_PC0_FREQTGT_SHIFT;
139 bcma_chipco_pll_write(cc, BCMA_CC_PMU15_PLL_PLLCTL0, pll0);
140
141 /* Flush */
142 if (cc->pmu.rev >= 2)
143 bcma_cc_set32(cc, BCMA_CC_PMU_CTL, BCMA_CC_PMU_CTL_PLL_UPD);
144
145 /* TODO: Do we need to update OTP? */
146}
147
148static void bcma_pmu_pll_init(struct bcma_drv_cc *cc)
149{
150 struct bcma_bus *bus = cc->core->bus;
151 u32 xtalfreq = bcma_pmu_xtalfreq(cc);
152
153 switch (bus->chipinfo.id) {
154 case BCMA_CHIP_ID_BCM43142:
155 if (xtalfreq == 0)
156 xtalfreq = 20000;
157 bcma_pmu2_pll_init0(cc, xtalfreq);
158 break;
159 }
160}
161
59static void bcma_pmu_resources_init(struct bcma_drv_cc *cc) 162static void bcma_pmu_resources_init(struct bcma_drv_cc *cc)
60{ 163{
61 struct bcma_bus *bus = cc->core->bus; 164 struct bcma_bus *bus = cc->core->bus;
@@ -66,6 +169,25 @@ static void bcma_pmu_resources_init(struct bcma_drv_cc *cc)
66 min_msk = 0x200D; 169 min_msk = 0x200D;
67 max_msk = 0xFFFF; 170 max_msk = 0xFFFF;
68 break; 171 break;
172 case BCMA_CHIP_ID_BCM43142:
173 min_msk = BCMA_RES_4314_LPLDO_PU |
174 BCMA_RES_4314_PMU_SLEEP_DIS |
175 BCMA_RES_4314_PMU_BG_PU |
176 BCMA_RES_4314_CBUCK_LPOM_PU |
177 BCMA_RES_4314_CBUCK_PFM_PU |
178 BCMA_RES_4314_CLDO_PU |
179 BCMA_RES_4314_LPLDO2_LVM |
180 BCMA_RES_4314_WL_PMU_PU |
181 BCMA_RES_4314_LDO3P3_PU |
182 BCMA_RES_4314_OTP_PU |
183 BCMA_RES_4314_WL_PWRSW_PU |
184 BCMA_RES_4314_LQ_AVAIL |
185 BCMA_RES_4314_LOGIC_RET |
186 BCMA_RES_4314_MEM_SLEEP |
187 BCMA_RES_4314_MACPHY_RET |
188 BCMA_RES_4314_WL_CORE_READY;
189 max_msk = 0x3FFFFFFF;
190 break;
69 default: 191 default:
70 bcma_debug(bus, "PMU resource config unknown or not needed for device 0x%04X\n", 192 bcma_debug(bus, "PMU resource config unknown or not needed for device 0x%04X\n",
71 bus->chipinfo.id); 193 bus->chipinfo.id);
@@ -165,6 +287,7 @@ void bcma_pmu_init(struct bcma_drv_cc *cc)
165 bcma_cc_set32(cc, BCMA_CC_PMU_CTL, 287 bcma_cc_set32(cc, BCMA_CC_PMU_CTL,
166 BCMA_CC_PMU_CTL_NOILPONW); 288 BCMA_CC_PMU_CTL_NOILPONW);
167 289
290 bcma_pmu_pll_init(cc);
168 bcma_pmu_resources_init(cc); 291 bcma_pmu_resources_init(cc);
169 bcma_pmu_workarounds(cc); 292 bcma_pmu_workarounds(cc);
170} 293}