1 /*-
2 * Copyright (c) 2016 Landon Fuller <[email protected]>
3 * Copyright (c) 2010, Broadcom Corporation.
4 * All rights reserved.
5 *
6 * This file is derived from the siutils.c source distributed with the
7 * Asus RT-N16 firmware source code release.
8 *
9 * Permission to use, copy, modify, and/or distribute this software for any
10 * purpose with or without fee is hereby granted, provided that the above
11 * copyright notice and this permission notice appear in all copies.
12 *
13 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
14 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
15 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
16 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
17 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
18 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
19 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
20 *
21 * $Id: siutils.c,v 1.821.2.48 2011-02-11 20:59:28 Exp $
22 */
23
24 #include <sys/cdefs.h>
25 #include <sys/param.h>
26 #include <sys/kernel.h>
27 #include <sys/bus.h>
28 #include <sys/limits.h>
29 #include <sys/malloc.h>
30 #include <sys/module.h>
31 #include <sys/systm.h>
32
33 #include <dev/bhnd/bhnd.h>
34 #include <dev/bhnd/bhndb/bhndb_pcireg.h>
35
36 #include <dev/bhnd/cores/chipc/chipc.h>
37 #include <dev/bhnd/cores/chipc/chipcreg.h>
38
39 #include <dev/bhnd/cores/pmu/bhnd_pmuvar.h>
40 #include <dev/bhnd/cores/pmu/bhnd_pmureg.h>
41
42 #include "bhnd_chipc_if.h"
43
44 #include "bhnd_pwrctl_private.h"
45
46 static uint32_t bhnd_pwrctl_factor6(uint32_t x);
47
48 /**
49 * Return the factor value corresponding to a given N3M clock control magic
50 * field value (CHIPC_F6_*).
51 */
52 static uint32_t
bhnd_pwrctl_factor6(uint32_t x)53 bhnd_pwrctl_factor6(uint32_t x)
54 {
55 switch (x) {
56 case CHIPC_F6_2:
57 return (2);
58 case CHIPC_F6_3:
59 return (3);
60 case CHIPC_F6_4:
61 return (4);
62 case CHIPC_F6_5:
63 return (5);
64 case CHIPC_F6_6:
65 return (6);
66 case CHIPC_F6_7:
67 return (7);
68 default:
69 return (0);
70 }
71 }
72
73 /**
74 * Return the backplane clock's chipc 'M' register offset for a given PLL type,
75 * or 0 if a fixed clock speed should be used.
76 *
77 * @param cid Chip identification.
78 * @param pll_type PLL type (CHIPC_PLL_TYPE*)
79 * @param[out] fixed_hz If 0 is returned, will be set to the fixed clock
80 * speed for this device.
81 */
82 bus_size_t
bhnd_pwrctl_si_clkreg_m(const struct bhnd_chipid * cid,uint8_t pll_type,uint32_t * fixed_hz)83 bhnd_pwrctl_si_clkreg_m(const struct bhnd_chipid *cid,
84 uint8_t pll_type, uint32_t *fixed_hz)
85 {
86 switch (pll_type) {
87 case CHIPC_PLL_TYPE6:
88 return (CHIPC_CLKC_M3);
89 case CHIPC_PLL_TYPE3:
90 return (CHIPC_CLKC_M2);
91 default:
92 return (CHIPC_CLKC_SB);
93 }
94 }
95
96 /**
97 * Calculate the backplane clock speed (in Hz) for a given a set of clock
98 * control values.
99 *
100 * @param cid Chip identification.
101 * @param pll_type PLL type (CHIPC_PLL_TYPE*)
102 * @param n clock control N register value.
103 * @param m clock control M register value.
104 */
105 uint32_t
bhnd_pwrctl_si_clock_rate(const struct bhnd_chipid * cid,uint32_t pll_type,uint32_t n,uint32_t m)106 bhnd_pwrctl_si_clock_rate(const struct bhnd_chipid *cid,
107 uint32_t pll_type, uint32_t n, uint32_t m)
108 {
109 uint32_t rate;
110
111 KASSERT(bhnd_pwrctl_si_clkreg_m(cid, pll_type, NULL) != 0,
112 ("can't compute clock rate on fixed clock"));
113
114 rate = bhnd_pwrctl_clock_rate(pll_type, n, m);
115 if (pll_type == CHIPC_PLL_TYPE3)
116 rate /= 2;
117
118 return (rate);
119 }
120
121 /**
122 * Return the CPU clock's chipc 'M' register offset for a given PLL type,
123 * or 0 if a fixed clock speed should be used.
124 *
125 * @param cid Chip identification.
126 * @param pll_type PLL type (CHIPC_PLL_TYPE*)
127 * @param[out] fixed_hz If 0 is returned, will be set to the fixed clock
128 * speed for this device.
129 */
130 bus_size_t
bhnd_pwrctl_cpu_clkreg_m(const struct bhnd_chipid * cid,uint8_t pll_type,uint32_t * fixed_hz)131 bhnd_pwrctl_cpu_clkreg_m(const struct bhnd_chipid *cid,
132 uint8_t pll_type, uint32_t *fixed_hz)
133 {
134 switch (pll_type) {
135 case CHIPC_PLL_TYPE2:
136 case CHIPC_PLL_TYPE4:
137 case CHIPC_PLL_TYPE6:
138 case CHIPC_PLL_TYPE7:
139 return (CHIPC_CLKC_M3);
140
141 case CHIPC_PLL_TYPE5:
142 /* fixed 200MHz */
143 if (fixed_hz != NULL)
144 *fixed_hz = 200 * 1000 * 1000;
145 return (0);
146
147 case CHIPC_PLL_TYPE3:
148 if (cid->chip_id == BHND_CHIPID_BCM5365) {
149 /* fixed 200MHz */
150 if (fixed_hz != NULL)
151 *fixed_hz = 200 * 1000 * 1000;
152 return (0);
153 }
154
155 return (CHIPC_CLKC_M2);
156
157 default:
158 return (CHIPC_CLKC_SB);
159 }
160 }
161
162 /**
163 * Calculate the CPU clock speed (in Hz) for a given a set of clock control
164 * values.
165 *
166 * @param cid Chip identification.
167 * @param pll_type PLL type (CHIPC_PLL_TYPE*)
168 * @param n clock control N register value.
169 * @param m clock control M register value.
170 */
171 uint32_t
bhnd_pwrctl_cpu_clock_rate(const struct bhnd_chipid * cid,uint32_t pll_type,uint32_t n,uint32_t m)172 bhnd_pwrctl_cpu_clock_rate(const struct bhnd_chipid *cid,
173 uint32_t pll_type, uint32_t n, uint32_t m)
174 {
175 KASSERT(bhnd_pwrctl_cpu_clkreg_m(cid, pll_type, NULL) != 0,
176 ("can't compute clock rate on fixed clock"));
177
178 return (bhnd_pwrctl_clock_rate(pll_type, n, m));
179 }
180
181 /**
182 * Calculate the clock speed (in Hz) for a given a set of clockcontrol
183 * values.
184 *
185 * @param pll_type PLL type (CHIPC_PLL_TYPE*)
186 * @param n clock control N register value.
187 * @param m clock control M register value.
188 */
189 uint32_t
bhnd_pwrctl_clock_rate(uint32_t pll_type,uint32_t n,uint32_t m)190 bhnd_pwrctl_clock_rate(uint32_t pll_type, uint32_t n, uint32_t m)
191 {
192 uint32_t clk_base;
193 uint32_t n1, n2, clock, m1, m2, m3, mc;
194
195 n1 = CHIPC_GET_BITS(n, CHIPC_CN_N1);
196 n2 = CHIPC_GET_BITS(n, CHIPC_CN_N2);
197
198 switch (pll_type) {
199 case CHIPC_PLL_TYPE1:
200 case CHIPC_PLL_TYPE3:
201 case CHIPC_PLL_TYPE4:
202 case CHIPC_PLL_TYPE7:
203 n1 = bhnd_pwrctl_factor6(n1);
204 n2 += CHIPC_F5_BIAS;
205 break;
206
207 case CHIPC_PLL_TYPE2:
208 n1 += CHIPC_T2_BIAS;
209 n2 += CHIPC_T2_BIAS;
210 KASSERT(n1 >= 2 && n1 <= 7, ("invalid n1 value"));
211 KASSERT(n2 >= 5 && n2 <= 23, ("invalid n2 value"));
212 break;
213
214 case CHIPC_PLL_TYPE5:
215 return (100000000);
216
217 case CHIPC_PLL_TYPE6:
218 if (m & CHIPC_T6_MMASK)
219 return (CHIPC_T6_M1);
220 else
221 return (CHIPC_T6_M0);
222
223 default:
224 printf("unsupported PLL type %u\n", pll_type);
225 return (0);
226 }
227
228 /* PLL types 3 and 7 use BASE2 (25Mhz) */
229 if (pll_type == CHIPC_PLL_TYPE3 || pll_type == CHIPC_PLL_TYPE7) {
230 clk_base = CHIPC_CLOCK_BASE2;
231 } else {
232 clk_base = CHIPC_CLOCK_BASE1;
233 }
234
235 clock = clk_base * n1 * n2;
236
237 if (clock == 0)
238 return (0);
239
240 m1 = CHIPC_GET_BITS(m, CHIPC_M1);
241 m2 = CHIPC_GET_BITS(m, CHIPC_M2);
242 m3 = CHIPC_GET_BITS(m, CHIPC_M3);
243 mc = CHIPC_GET_BITS(m, CHIPC_MC);
244
245 switch (pll_type) {
246 case CHIPC_PLL_TYPE1:
247 case CHIPC_PLL_TYPE3:
248 case CHIPC_PLL_TYPE4:
249 case CHIPC_PLL_TYPE7:
250 m1 = bhnd_pwrctl_factor6(m1);
251 if (pll_type == CHIPC_PLL_TYPE1 || pll_type == CHIPC_PLL_TYPE3)
252 m2 += CHIPC_F5_BIAS;
253 else
254 m2 = bhnd_pwrctl_factor6(m2);
255
256 m3 = bhnd_pwrctl_factor6(m3);
257
258 switch (mc) {
259 case CHIPC_MC_BYPASS:
260 return (clock);
261 case CHIPC_MC_M1:
262 return (clock / m1);
263 case CHIPC_MC_M1M2:
264 return (clock / (m1 * m2));
265 case CHIPC_MC_M1M2M3:
266 return (clock / (m1 * m2 * m3));
267 case CHIPC_MC_M1M3:
268 return (clock / (m1 * m3));
269 default:
270 printf("unsupported pwrctl mc %#x\n", mc);
271 return (0);
272 }
273 case CHIPC_PLL_TYPE2:
274 m1 += CHIPC_T2_BIAS;
275 m2 += CHIPC_T2M2_BIAS;
276 m3 += CHIPC_T2_BIAS;
277 KASSERT(m1 >= 2 && m1 <= 7, ("invalid m1 value"));
278 KASSERT(m2 >= 3 && m2 <= 10, ("invalid m2 value"));
279 KASSERT(m3 >= 2 && m3 <= 7, ("invalid m3 value"));
280
281 if ((mc & CHIPC_T2MC_M1BYP) == 0)
282 clock /= m1;
283 if ((mc & CHIPC_T2MC_M2BYP) == 0)
284 clock /= m2;
285 if ((mc & CHIPC_T2MC_M3BYP) == 0)
286 clock /= m3;
287
288 return (clock);
289 default:
290 panic("unhandled PLL type %u\n", pll_type);
291 }
292 }
293
294 /**
295 * Return the backplane clock speed in Hz.
296 *
297 * @param sc driver instance state.
298 */
299 uint32_t
bhnd_pwrctl_getclk_speed(struct bhnd_pwrctl_softc * sc)300 bhnd_pwrctl_getclk_speed(struct bhnd_pwrctl_softc *sc)
301 {
302 const struct bhnd_chipid *cid;
303 struct chipc_caps *ccaps;
304 bus_size_t creg;
305 uint32_t n, m;
306 uint32_t rate;
307
308 PWRCTL_LOCK_ASSERT(sc, MA_OWNED);
309
310 cid = bhnd_get_chipid(sc->chipc_dev);
311 ccaps = BHND_CHIPC_GET_CAPS(sc->chipc_dev);
312
313 n = bhnd_bus_read_4(sc->res, CHIPC_CLKC_N);
314
315 /* Get M register offset */
316 creg = bhnd_pwrctl_si_clkreg_m(cid, ccaps->pll_type, &rate);
317 if (creg == 0) /* fixed rate */
318 return (rate);
319
320 /* calculate rate */
321 m = bhnd_bus_read_4(sc->res, creg);
322 return (bhnd_pwrctl_si_clock_rate(cid, ccaps->pll_type, n, m));
323 }
324
325 /* return the slow clock source */
326 static bhnd_clksrc
bhnd_pwrctl_slowclk_src(struct bhnd_pwrctl_softc * sc)327 bhnd_pwrctl_slowclk_src(struct bhnd_pwrctl_softc *sc)
328 {
329 uint32_t clkreg;
330 uint32_t clksrc;
331
332 /* Fetch clock source */
333 if (PWRCTL_QUIRK(sc, PCICLK_CTL)) {
334 return (bhnd_pwrctl_hostb_get_clksrc(sc->chipc_dev,
335 BHND_CLOCK_ILP));
336 } else if (PWRCTL_QUIRK(sc, SLOWCLK_CTL)) {
337 clkreg = bhnd_bus_read_4(sc->res, CHIPC_PLL_SLOWCLK_CTL);
338 clksrc = clkreg & CHIPC_SCC_SS_MASK;
339 } else {
340 /* Instaclock */
341 clksrc = CHIPC_SCC_SS_XTAL;
342 }
343
344 /* Map to bhnd_clksrc */
345 switch (clksrc) {
346 case CHIPC_SCC_SS_PCI:
347 return (BHND_CLKSRC_PCI);
348 case CHIPC_SCC_SS_LPO:
349 return (BHND_CLKSRC_LPO);
350 case CHIPC_SCC_SS_XTAL:
351 return (BHND_CLKSRC_XTAL);
352 default:
353 return (BHND_CLKSRC_UNKNOWN);
354 }
355 }
356
357 /* return the ILP (slowclock) min or max frequency */
358 static uint32_t
bhnd_pwrctl_slowclk_freq(struct bhnd_pwrctl_softc * sc,bool max_freq)359 bhnd_pwrctl_slowclk_freq(struct bhnd_pwrctl_softc *sc, bool max_freq)
360 {
361 bhnd_clksrc slowclk;
362 uint32_t div;
363 uint32_t hz;
364
365 slowclk = bhnd_pwrctl_slowclk_src(sc);
366
367 /* Determine clock divisor */
368 if (PWRCTL_QUIRK(sc, PCICLK_CTL)) {
369 if (slowclk == BHND_CLKSRC_PCI)
370 div = 64;
371 else
372 div = 32;
373 } else if (PWRCTL_QUIRK(sc, SLOWCLK_CTL)) {
374 div = bhnd_bus_read_4(sc->res, CHIPC_PLL_SLOWCLK_CTL);
375 div = CHIPC_GET_BITS(div, CHIPC_SCC_CD);
376 div = 4 * (div + 1);
377 } else if (PWRCTL_QUIRK(sc, INSTACLK_CTL)) {
378 if (max_freq) {
379 div = 1;
380 } else {
381 div = bhnd_bus_read_4(sc->res, CHIPC_SYS_CLK_CTL);
382 div = CHIPC_GET_BITS(div, CHIPC_SYCC_CD);
383 div = 4 * (div + 1);
384 }
385 } else {
386 device_printf(sc->dev, "unknown device type\n");
387 return (0);
388 }
389
390 /* Determine clock frequency */
391 switch (slowclk) {
392 case BHND_CLKSRC_LPO:
393 hz = max_freq ? CHIPC_LPOMAXFREQ : CHIPC_LPOMINFREQ;
394 break;
395 case BHND_CLKSRC_XTAL:
396 hz = max_freq ? CHIPC_XTALMAXFREQ : CHIPC_XTALMINFREQ;
397 break;
398 case BHND_CLKSRC_PCI:
399 hz = max_freq ? CHIPC_PCIMAXFREQ : CHIPC_PCIMINFREQ;
400 break;
401 default:
402 device_printf(sc->dev, "unknown slowclk source %#x\n", slowclk);
403 return (0);
404 }
405
406 return (hz / div);
407 }
408
409 /**
410 * Initialize power control registers.
411 */
412 int
bhnd_pwrctl_init(struct bhnd_pwrctl_softc * sc)413 bhnd_pwrctl_init(struct bhnd_pwrctl_softc *sc)
414 {
415 uint32_t clkctl;
416 uint32_t pll_delay, slowclk, slowmaxfreq;
417 uint32_t pll_on_delay, fref_sel_delay;
418 int error;
419
420 pll_delay = CHIPC_PLL_DELAY;
421
422 /* set all Instaclk chip ILP to 1 MHz */
423 if (PWRCTL_QUIRK(sc, INSTACLK_CTL)) {
424 clkctl = (CHIPC_ILP_DIV_1MHZ << CHIPC_SYCC_CD_SHIFT);
425 clkctl &= CHIPC_SYCC_CD_MASK;
426 bhnd_bus_write_4(sc->res, CHIPC_SYS_CLK_CTL, clkctl);
427 }
428
429 /*
430 * Initialize PLL/FREF delays.
431 *
432 * If the slow clock is not sourced by the xtal, include the
433 * delay required to bring it up.
434 */
435 slowclk = bhnd_pwrctl_slowclk_src(sc);
436 if (slowclk != CHIPC_SCC_SS_XTAL)
437 pll_delay += CHIPC_XTAL_ON_DELAY;
438
439 /* Starting with 4318 it is ILP that is used for the delays */
440 if (PWRCTL_QUIRK(sc, INSTACLK_CTL))
441 slowmaxfreq = bhnd_pwrctl_slowclk_freq(sc, false);
442 else
443 slowmaxfreq = bhnd_pwrctl_slowclk_freq(sc, true);
444
445 pll_on_delay = ((slowmaxfreq * pll_delay) + 999999) / 1000000;
446 fref_sel_delay = ((slowmaxfreq * CHIPC_FREF_DELAY) + 999999) / 1000000;
447
448 bhnd_bus_write_4(sc->res, CHIPC_PLL_ON_DELAY, pll_on_delay);
449 bhnd_bus_write_4(sc->res, CHIPC_PLL_FREFSEL_DELAY, fref_sel_delay);
450
451 /* If required, force HT */
452 if (PWRCTL_QUIRK(sc, FORCE_HT)) {
453 if ((error = bhnd_pwrctl_setclk(sc, BHND_CLOCK_HT)))
454 return (error);
455 }
456
457 return (0);
458 }
459
460 /* return the value suitable for writing to the dot11 core
461 * FAST_PWRUP_DELAY register */
462 u_int
bhnd_pwrctl_fast_pwrup_delay(struct bhnd_pwrctl_softc * sc)463 bhnd_pwrctl_fast_pwrup_delay(struct bhnd_pwrctl_softc *sc)
464 {
465 u_int pll_on_delay, slowminfreq;
466 u_int fpdelay;
467
468 fpdelay = 0;
469
470 slowminfreq = bhnd_pwrctl_slowclk_freq(sc, false);
471
472 pll_on_delay = bhnd_bus_read_4(sc->res, CHIPC_PLL_ON_DELAY) + 2;
473 pll_on_delay *= 1000000;
474 pll_on_delay += (slowminfreq - 1);
475 fpdelay = pll_on_delay / slowminfreq;
476
477 return (fpdelay);
478 }
479
480 /**
481 * Distribute @p clock on backplane.
482 *
483 * @param sc Driver instance state.
484 * @param clock Clock to enable.
485 *
486 * @retval 0 success
487 * @retval ENODEV If @p clock is unsupported, or if the device does not
488 * support dynamic clock control.
489 */
490 int
bhnd_pwrctl_setclk(struct bhnd_pwrctl_softc * sc,bhnd_clock clock)491 bhnd_pwrctl_setclk(struct bhnd_pwrctl_softc *sc, bhnd_clock clock)
492 {
493 uint32_t scc;
494
495 PWRCTL_LOCK_ASSERT(sc, MA_OWNED);
496
497 /* Is dynamic clock control supported? */
498 if (PWRCTL_QUIRK(sc, FIXED_CLK))
499 return (ENODEV);
500
501 /* Chips with ccrev 10 are EOL and they don't have SYCC_HR used below */
502 if (bhnd_get_hwrev(sc->chipc_dev) == 10)
503 return (ENODEV);
504
505 if (PWRCTL_QUIRK(sc, SLOWCLK_CTL))
506 scc = bhnd_bus_read_4(sc->res, CHIPC_PLL_SLOWCLK_CTL);
507 else
508 scc = bhnd_bus_read_4(sc->res, CHIPC_SYS_CLK_CTL);
509
510 switch (clock) {
511 case BHND_CLOCK_HT:
512 /* fast (pll) clock */
513 if (PWRCTL_QUIRK(sc, SLOWCLK_CTL)) {
514 scc &= ~(CHIPC_SCC_XC | CHIPC_SCC_FS | CHIPC_SCC_IP);
515 scc |= CHIPC_SCC_IP;
516
517 /* force xtal back on before clearing SCC_DYN_XTAL.. */
518 bhnd_pwrctl_hostb_ungate_clock(sc->chipc_dev,
519 BHND_CLOCK_HT);
520 } else if (PWRCTL_QUIRK(sc, INSTACLK_CTL)) {
521 scc |= CHIPC_SYCC_HR;
522 } else {
523 return (ENODEV);
524 }
525
526 if (PWRCTL_QUIRK(sc, SLOWCLK_CTL))
527 bhnd_bus_write_4(sc->res, CHIPC_PLL_SLOWCLK_CTL, scc);
528 else
529 bhnd_bus_write_4(sc->res, CHIPC_SYS_CLK_CTL, scc);
530 DELAY(CHIPC_PLL_DELAY);
531
532 break;
533
534 case BHND_CLOCK_DYN:
535 /* enable dynamic clock control */
536 if (PWRCTL_QUIRK(sc, SLOWCLK_CTL)) {
537 scc &= ~(CHIPC_SCC_FS | CHIPC_SCC_IP | CHIPC_SCC_XC);
538 if ((scc & CHIPC_SCC_SS_MASK) != CHIPC_SCC_SS_XTAL)
539 scc |= CHIPC_SCC_XC;
540
541 bhnd_bus_write_4(sc->res, CHIPC_PLL_SLOWCLK_CTL, scc);
542
543 /* for dynamic control, we have to release our xtal_pu
544 * "force on" */
545 if (scc & CHIPC_SCC_XC) {
546 bhnd_pwrctl_hostb_gate_clock(sc->chipc_dev,
547 BHND_CLOCK_HT);
548 }
549 } else if (PWRCTL_QUIRK(sc, INSTACLK_CTL)) {
550 /* Instaclock */
551 scc &= ~CHIPC_SYCC_HR;
552 bhnd_bus_write_4(sc->res, CHIPC_SYS_CLK_CTL, scc);
553 } else {
554 return (ENODEV);
555 }
556
557 break;
558
559 default:
560 return (ENODEV);
561 }
562
563 return (0);
564 }
565