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