1/*-
2 * Copyright (c) 2006 M. Warner Losh.  All rights reserved.
3 * Copyright (c) 2010 Greg Ansley.  All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 *    notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 *    notice, this list of conditions and the following disclaimer in the
12 *    documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED.  IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 */
26
27#include <sys/cdefs.h>
28__FBSDID("$FreeBSD$");
29
30#include <sys/param.h>
31#include <sys/systm.h>
32#include <sys/kernel.h>
33#include <sys/malloc.h>
34#include <sys/module.h>
35#include <sys/time.h>
36#include <sys/bus.h>
37#include <sys/resource.h>
38#include <sys/rman.h>
39#include <sys/timetc.h>
40
41#include <machine/bus.h>
42#include <machine/cpu.h>
43#include <machine/cpufunc.h>
44#include <machine/resource.h>
45#include <machine/frame.h>
46#include <machine/intr.h>
47#include <arm/at91/at91reg.h>
48#include <arm/at91/at91var.h>
49
50#include <arm/at91/at91_pmcreg.h>
51#include <arm/at91/at91_pmcvar.h>
52
53static struct at91_pmc_softc {
54	bus_space_tag_t		sc_st;
55	bus_space_handle_t	sc_sh;
56	struct resource	*mem_res;	/* Memory resource */
57	device_t		dev;
58	unsigned int		main_clock_hz;
59	uint32_t		pllb_init;
60} *pmc_softc;
61
62MALLOC_DECLARE(M_PMC);
63MALLOC_DEFINE(M_PMC, "at91_pmc_clocks", "AT91 PMC Clock descriptors");
64
65static void at91_pmc_set_pllb_mode(struct at91_pmc_clock *, int);
66static void at91_pmc_set_sys_mode(struct at91_pmc_clock *, int);
67static void at91_pmc_set_periph_mode(struct at91_pmc_clock *, int);
68static void at91_pmc_clock_alias(const char *name, const char *alias);
69
70static struct at91_pmc_clock slck = {
71	.name = "slck",		// 32,768 Hz slow clock
72	.hz = 32768,
73	.refcnt = 1,
74	.id = 0,
75	.primary = 1,
76};
77
78/*
79 * NOTE: Clocks for "ordinary peripheral" devices e.g. spi0, udp0, uhp0 etc.
80 * are now created automatically. Only "system" clocks need be defined here.
81 */
82static struct at91_pmc_clock main_ck = {
83	.name = "main",		// Main clock
84	.refcnt = 0,
85	.id = 1,
86	.primary = 1,
87	.pmc_mask = PMC_IER_MOSCS,
88};
89
90static struct at91_pmc_clock plla = {
91	.name = "plla",		// PLLA Clock, used for CPU clocking
92	.parent = &main_ck,
93	.refcnt = 1,
94	.id = 0,
95	.primary = 1,
96	.pll = 1,
97	.pmc_mask = PMC_IER_LOCKA,
98};
99
100static struct at91_pmc_clock pllb = {
101	.name = "pllb",		// PLLB Clock, used for USB functions
102	.parent = &main_ck,
103	.refcnt = 0,
104	.id = 0,
105	.primary = 1,
106	.pll = 1,
107	.pmc_mask = PMC_IER_LOCKB,
108	.set_mode = &at91_pmc_set_pllb_mode,
109};
110
111static struct at91_pmc_clock udpck = {
112	.name = "udpck",
113	.parent = &pllb,
114	.pmc_mask = PMC_SCER_UDP,
115	.set_mode = at91_pmc_set_sys_mode
116};
117
118static struct at91_pmc_clock uhpck = {
119	.name = "uhpck",
120	.parent = &pllb,
121	.pmc_mask = PMC_SCER_UHP,
122	.set_mode = at91_pmc_set_sys_mode
123};
124
125static struct at91_pmc_clock mck = {
126	.name = "mck",		// Master (Peripheral) Clock
127	.pmc_mask = PMC_IER_MCKRDY,
128	.refcnt = 0,
129};
130
131static struct at91_pmc_clock cpu = {
132	.name = "cpu",		// CPU Clock
133	.parent = &plla,
134	.pmc_mask = PMC_SCER_PCK,
135	.refcnt = 0,
136};
137
138/* "+32" or the automatic peripheral clocks */
139static struct at91_pmc_clock *clock_list[16+32] = {
140	&slck,
141	&main_ck,
142	&plla,
143	&pllb,
144	&udpck,
145	&uhpck,
146	&mck,
147	&cpu
148};
149
150#if !defined(AT91C_MAIN_CLOCK)
151static const unsigned int at91_mainf_tbl[] = {
152	3000000, 3276800, 3686400, 3840000, 4000000,
153	4433619, 4915200, 5000000, 5242880, 6000000,
154	6144000, 6400000, 6553600, 7159090, 7372800,
155	7864320, 8000000, 9830400, 10000000, 11059200,
156	12000000, 12288000, 13560000, 14318180, 14745600,
157	16000000, 17344700, 18432000, 20000000
158};
159#define	MAINF_TBL_LEN	(sizeof(at91_mainf_tbl) / sizeof(*at91_mainf_tbl))
160#endif
161
162static inline uint32_t
163RD4(struct at91_pmc_softc *sc, bus_size_t off)
164{
165
166	return (bus_read_4(sc->mem_res, off));
167}
168
169static inline void
170WR4(struct at91_pmc_softc *sc, bus_size_t off, uint32_t val)
171{
172
173	bus_write_4(sc->mem_res, off, val);
174}
175
176void
177at91_pmc_set_pllb_mode(struct at91_pmc_clock *clk, int on)
178{
179	struct at91_pmc_softc *sc = pmc_softc;
180	uint32_t value;
181
182	if (on) {
183		on = PMC_IER_LOCKB;
184		value = sc->pllb_init;
185	} else
186		value = 0;
187
188	/* Workaround RM9200 Errata #26 */
189	if (at91_is_rm92() &&
190	   ((value ^ RD4(sc, CKGR_PLLBR)) & 0x03f0ff) != 0) {
191		WR4(sc, CKGR_PLLBR, value ^ 1);
192		while ((RD4(sc, PMC_SR) & PMC_IER_LOCKB) != on)
193			continue;
194	}
195
196	WR4(sc, CKGR_PLLBR, value);
197	while ((RD4(sc, PMC_SR) & PMC_IER_LOCKB) != on)
198		continue;
199}
200
201static void
202at91_pmc_set_sys_mode(struct at91_pmc_clock *clk, int on)
203{
204	struct at91_pmc_softc *sc = pmc_softc;
205
206	WR4(sc, on ? PMC_SCER : PMC_SCDR, clk->pmc_mask);
207	if (on)
208		while ((RD4(sc, PMC_SCSR) & clk->pmc_mask) != clk->pmc_mask)
209			continue;
210	else
211		while ((RD4(sc, PMC_SCSR) & clk->pmc_mask) == clk->pmc_mask)
212			continue;
213}
214
215static void
216at91_pmc_set_periph_mode(struct at91_pmc_clock *clk, int on)
217{
218	struct at91_pmc_softc *sc = pmc_softc;
219
220	WR4(sc, on ? PMC_PCER : PMC_PCDR, clk->pmc_mask);
221	if (on)
222		while ((RD4(sc, PMC_PCSR) & clk->pmc_mask) != clk->pmc_mask)
223			continue;
224	else
225		while ((RD4(sc, PMC_PCSR) & clk->pmc_mask) == clk->pmc_mask)
226			continue;
227}
228
229struct at91_pmc_clock *
230at91_pmc_clock_add(const char *name, uint32_t irq,
231    struct at91_pmc_clock *parent)
232{
233	struct at91_pmc_clock *clk;
234	int i, buflen;
235
236	clk = malloc(sizeof(*clk), M_PMC, M_NOWAIT | M_ZERO);
237	if (clk == NULL)
238		goto err;
239
240	buflen = strlen(name) + 1;
241	clk->name = malloc(buflen, M_PMC, M_NOWAIT);
242	if (clk->name == NULL)
243		goto err;
244
245	strlcpy(clk->name, name, buflen);
246	clk->pmc_mask = 1 << irq;
247	clk->set_mode = &at91_pmc_set_periph_mode;
248	if (parent == NULL)
249		clk->parent = &mck;
250	else
251		clk->parent = parent;
252
253	for (i = 0; i < sizeof(clock_list) / sizeof(clock_list[0]); i++) {
254		if (clock_list[i] == NULL) {
255			clock_list[i] = clk;
256			return (clk);
257		}
258	}
259err:
260	if (clk != NULL) {
261		if (clk->name != NULL)
262			free(clk->name, M_PMC);
263		free(clk, M_PMC);
264	}
265
266	panic("could not allocate pmc clock '%s'", name);
267	return (NULL);
268}
269
270static void
271at91_pmc_clock_alias(const char *name, const char *alias)
272{
273	struct at91_pmc_clock *clk, *alias_clk;
274
275	clk = at91_pmc_clock_ref(name);
276	if (clk)
277		alias_clk = at91_pmc_clock_add(alias, 0, clk->parent);
278
279	if (clk && alias_clk) {
280		alias_clk->hz = clk->hz;
281		alias_clk->pmc_mask = clk->pmc_mask;
282		alias_clk->set_mode = clk->set_mode;
283	}
284}
285
286struct at91_pmc_clock *
287at91_pmc_clock_ref(const char *name)
288{
289	int i;
290
291	for (i = 0; i < sizeof(clock_list) / sizeof(clock_list[0]); i++) {
292		if (clock_list[i] == NULL)
293		    break;
294		if (strcmp(name, clock_list[i]->name) == 0)
295			return (clock_list[i]);
296	}
297
298	//printf("at91_pmc: Warning - did not find clock '%s'", name);
299	return (NULL);
300}
301
302void
303at91_pmc_clock_deref(struct at91_pmc_clock *clk)
304{
305
306}
307
308void
309at91_pmc_clock_enable(struct at91_pmc_clock *clk)
310{
311
312	/* XXX LOCKING? XXX */
313	if (clk->parent)
314		at91_pmc_clock_enable(clk->parent);
315	if (clk->refcnt++ == 0 && clk->set_mode)
316		clk->set_mode(clk, 1);
317}
318
319void
320at91_pmc_clock_disable(struct at91_pmc_clock *clk)
321{
322
323	/* XXX LOCKING? XXX */
324	if (--clk->refcnt == 0 && clk->set_mode)
325		clk->set_mode(clk, 0);
326	if (clk->parent)
327		at91_pmc_clock_disable(clk->parent);
328}
329
330static int
331at91_pmc_pll_rate(struct at91_pmc_clock *clk, uint32_t reg)
332{
333	uint32_t mul, div, freq;
334
335	freq = clk->parent->hz;
336	div = (reg >> clk->pll_div_shift) & clk->pll_div_mask;
337	mul = (reg >> clk->pll_mul_shift) & clk->pll_mul_mask;
338
339#if 0
340	printf("pll = (%d /  %d) * %d = %d\n",
341	    freq, div, mul + 1, (freq/div) * (mul+1));
342#endif
343
344	if (div != 0 && mul != 0) {
345		freq /= div;
346		freq *= mul + 1;
347	} else
348		freq = 0;
349	clk->hz = freq;
350
351	return (freq);
352}
353
354static uint32_t
355at91_pmc_pll_calc(struct at91_pmc_clock *clk, uint32_t out_freq)
356{
357	uint32_t i, div = 0, mul = 0, diff = 1 << 30;
358
359	unsigned ret = 0x3e00;
360
361	if (out_freq > clk->pll_max_out)
362		goto fail;
363
364	for (i = 1; i < 256; i++) {
365		int32_t diff1;
366		uint32_t input, mul1;
367
368		input = clk->parent->hz / i;
369		if (input < clk->pll_min_in)
370			break;
371		if (input > clk->pll_max_in)
372			continue;
373
374		mul1 = out_freq / input;
375		if (mul1 > (clk->pll_mul_mask + 1))
376			continue;
377		if (mul1 == 0)
378			break;
379
380		diff1 = out_freq - input * mul1;
381		if (diff1 < 0)
382			diff1 = -diff1;
383		if (diff > diff1) {
384			diff = diff1;
385			div = i;
386			mul = mul1;
387			if (diff == 0)
388				break;
389		}
390	}
391	if (diff > (out_freq >> PMC_PLL_SHIFT_TOL))
392		goto fail;
393
394	if (clk->set_outb != NULL)
395		ret |= clk->set_outb(out_freq);
396
397	return (ret |
398		((mul - 1) << clk->pll_mul_shift) |
399		(div << clk->pll_div_shift));
400fail:
401	return (0);
402}
403
404static void
405at91_pmc_init_clock(struct at91_pmc_softc *sc, unsigned int main_clock)
406{
407	uint32_t mckr;
408	uint32_t mdiv;
409
410	if (at91_is_sam9() || at91_is_sam9xe()) {
411		uhpck.pmc_mask = PMC_SCER_UHP_SAM9;
412		udpck.pmc_mask = PMC_SCER_UDP_SAM9;
413	}
414	mckr = RD4(sc, PMC_MCKR);
415	sc->main_clock_hz = main_clock;
416	main_ck.hz = main_clock;
417
418	at91_pmc_pll_rate(&plla, RD4(sc, CKGR_PLLAR));
419
420	if (at91_cpu_is(AT91_CPU_SAM9G45) && (mckr & PMC_MCKR_PLLADIV2))
421		plla.hz /= 2;
422
423	/*
424	 * Initialize the usb clock.  This sets up pllb, but disables the
425	 * actual clock.
426	 */
427	sc->pllb_init = at91_pmc_pll_calc(&pllb, 48000000 * 2) | 0x10000000;
428	at91_pmc_pll_rate(&pllb, sc->pllb_init);
429
430#if 0
431	/* Turn off USB clocks */
432	at91_pmc_set_periph_mode(&ohci_clk, 0);
433	at91_pmc_set_periph_mode(&udc_clk, 0);
434#endif
435
436	if (at91_is_rm92()) {
437		WR4(sc, PMC_SCDR, PMC_SCER_UHP | PMC_SCER_UDP);
438		WR4(sc, PMC_SCER, PMC_SCER_MCKUDP);
439	} else
440		WR4(sc, PMC_SCDR, PMC_SCER_UHP_SAM9 | PMC_SCER_UDP_SAM9);
441	WR4(sc, CKGR_PLLBR, 0);
442
443	/*
444	 * MCK and PCU derive from one of the primary clocks.  Initialize
445	 * this relationship.
446	 */
447	mck.parent = clock_list[mckr & 0x3];
448	mck.parent->refcnt++;
449
450	cpu.hz = mck.hz = mck.parent->hz /
451	    (1 << ((mckr & PMC_MCKR_PRES_MASK) >> 2));
452
453	mdiv = (mckr & PMC_MCKR_MDIV_MASK) >> 8;
454	if (at91_is_sam9() || at91_is_sam9xe()) {
455		if (mdiv > 0)
456			mck.hz /= mdiv * 2;
457	} else
458		mck.hz /= (1 + mdiv);
459
460	/* Only found on SAM9G20 */
461	if (at91_cpu_is(AT91_CPU_SAM9G20))
462		cpu.hz /= (mckr & PMC_MCKR_PDIV) ?  2 : 1;
463
464	at91_master_clock = mck.hz;
465
466	device_printf(sc->dev,
467	    "Primary: %d Hz PLLA: %d MHz CPU: %d MHz MCK: %d MHz\n",
468	    sc->main_clock_hz,
469	    plla.hz / 1000000,
470	    cpu.hz / 1000000, mck.hz / 1000000);
471
472	/* Turn off "Progamable" clocks */
473	WR4(sc, PMC_SCDR, PMC_SCER_PCK0 | PMC_SCER_PCK1 | PMC_SCER_PCK2 |
474	    PMC_SCER_PCK3);
475
476	/* XXX kludge, turn on all peripherals */
477	WR4(sc, PMC_PCER, 0xffffffff);
478
479	/* Disable all interrupts for PMC */
480	WR4(sc, PMC_IDR, 0xffffffff);
481}
482
483static void
484at91_pmc_deactivate(device_t dev)
485{
486	struct at91_pmc_softc *sc;
487
488	sc = device_get_softc(dev);
489	bus_generic_detach(sc->dev);
490	if (sc->mem_res)
491		bus_release_resource(dev, SYS_RES_IOPORT,
492		    rman_get_rid(sc->mem_res), sc->mem_res);
493	sc->mem_res = 0;
494}
495
496static int
497at91_pmc_activate(device_t dev)
498{
499	struct at91_pmc_softc *sc;
500	int rid;
501
502	sc = device_get_softc(dev);
503	rid = 0;
504	sc->mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
505	    RF_ACTIVE);
506	if (sc->mem_res == NULL)
507		goto errout;
508	return (0);
509errout:
510	at91_pmc_deactivate(dev);
511	return (ENOMEM);
512}
513
514static int
515at91_pmc_probe(device_t dev)
516{
517
518	device_set_desc(dev, "PMC");
519	return (0);
520}
521
522#if !defined(AT91C_MAIN_CLOCK)
523static unsigned int
524at91_pmc_sense_mainf(struct at91_pmc_softc *sc)
525{
526	unsigned int ckgr_val;
527	unsigned int diff, matchdiff;
528	int i, match;
529
530	ckgr_val = (RD4(sc, CKGR_MCFR) & CKGR_MCFR_MAINF_MASK) << 11;
531
532	/*
533	 * Try to find the standard frequency that match best.
534	 */
535	match = 0;
536	matchdiff = abs(ckgr_val - at91_mainf_tbl[0]);
537	for (i = 1; i < MAINF_TBL_LEN; i++) {
538		diff = abs(ckgr_val - at91_mainf_tbl[i]);
539		if (diff < matchdiff) {
540			match = i;
541			matchdiff = diff;
542		}
543	}
544	return (at91_mainf_tbl[match]);
545}
546#endif
547
548static int
549at91_pmc_attach(device_t dev)
550{
551	unsigned int mainf;
552	int err;
553
554	pmc_softc = device_get_softc(dev);
555	pmc_softc->dev = dev;
556	if ((err = at91_pmc_activate(dev)) != 0)
557		return (err);
558
559	/*
560	 * Configure main clock frequency.
561	 */
562#if !defined(AT91C_MAIN_CLOCK)
563	mainf = at91_pmc_sense_mainf(pmc_softc);
564#else
565	mainf = AT91C_MAIN_CLOCK;
566#endif
567	at91_pmc_init_clock(pmc_softc, mainf);
568
569	/* These clocks refrenced by "special" names */
570	at91_pmc_clock_alias("ohci0", "ohci_clk");
571	at91_pmc_clock_alias("udp0",  "udp_clk");
572
573	return (0);
574}
575
576static device_method_t at91_pmc_methods[] = {
577	DEVMETHOD(device_probe, at91_pmc_probe),
578	DEVMETHOD(device_attach, at91_pmc_attach),
579	DEVMETHOD_END
580};
581
582static driver_t at91_pmc_driver = {
583	"at91_pmc",
584	at91_pmc_methods,
585	sizeof(struct at91_pmc_softc),
586};
587static devclass_t at91_pmc_devclass;
588
589DRIVER_MODULE(at91_pmc, atmelarm, at91_pmc_driver, at91_pmc_devclass, NULL,
590    NULL);
591