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
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
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
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
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
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
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
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
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
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
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
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
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