xref: /f-stack/freebsd/mips/ingenic/jz4780_clock.c (revision 22ce4aff)
1 /*-
2  * Copyright 2015 Alexander Kabaev <[email protected]>
3  * 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 THE 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 THE 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 /*
28  * Ingenic JZ4780 CGU driver.
29  *
30  */
31 
32 #include <sys/cdefs.h>
33 __FBSDID("$FreeBSD$");
34 
35 #include <sys/param.h>
36 #include <sys/systm.h>
37 #include <sys/conf.h>
38 #include <sys/bus.h>
39 #include <sys/kernel.h>
40 #include <sys/module.h>
41 #include <sys/lock.h>
42 #include <sys/mutex.h>
43 #include <sys/resource.h>
44 #include <sys/rman.h>
45 
46 #include <machine/bus.h>
47 
48 #include <dev/fdt/fdt_common.h>
49 #include <dev/ofw/ofw_bus.h>
50 #include <dev/ofw/ofw_bus_subr.h>
51 
52 #include <mips/ingenic/jz4780_clk.h>
53 #include <mips/ingenic/jz4780_regs.h>
54 #include <mips/ingenic/jz4780_clock.h>
55 
56 #include "clkdev_if.h"
57 
58 #include <dt-bindings/clock/jz4780-cgu.h>
59 
60 /**********************************************************************
61  *  JZ4780 CGU clock domain
62  **********************************************************************/
63 struct jz4780_clock_softc {
64 	device_t	dev;
65 	struct resource	*res[1];
66 	struct mtx	mtx;
67 	struct clkdom	*clkdom;
68 };
69 
70 static struct resource_spec jz4780_clock_spec[] = {
71 	{ SYS_RES_MEMORY, 0, RF_ACTIVE },
72 	{ -1, 0 }
73 };
74 
75 struct jz4780_clk_pll_def {
76 	uint16_t   clk_id;
77 	uint16_t   clk_reg;
78 	const char *clk_name;
79 	const char *clk_pname[1];
80 };
81 
82 #define PLL(_id, cname, pname, reg) {		\
83 	.clk_id		= _id,			\
84 	.clk_reg	= reg,			\
85 	.clk_name	= cname,		\
86 	.clk_pname[0]	= pname,		\
87 }
88 
89 struct jz4780_clk_gate_def {
90 	uint16_t   clk_id;
91 	uint16_t   clk_bit;
92 	const char *clk_name;
93 	const char *clk_pname[1];
94 };
95 
96 #define GATE(_id, cname, pname, bit) {		\
97 	.clk_id		= _id,			\
98 	.clk_bit	= bit,			\
99 	.clk_name	= cname,		\
100 	.clk_pname[0]	= pname,		\
101 }
102 
103 #define MUX(reg, shift, bits, map)			\
104     .clk_mux.mux_reg = (reg),				\
105     .clk_mux.mux_shift = (shift),			\
106     .clk_mux.mux_bits = (bits),				\
107     .clk_mux.mux_map = (map),
108 #define NO_MUX
109 
110 #define DIV(reg, shift, lg, bits, ce, st, bb)		\
111     .clk_div.div_reg = (reg),				\
112     .clk_div.div_shift = (shift),			\
113     .clk_div.div_bits = (bits),				\
114     .clk_div.div_lg = (lg),				\
115     .clk_div.div_ce_bit = (ce),				\
116     .clk_div.div_st_bit = (st),				\
117     .clk_div.div_busy_bit = (bb),
118 #define NO_DIV						\
119 
120 #define GATEBIT(bit)					\
121     .clk_gate_bit = (bit),
122 #define NO_GATE						\
123     .clk_gate_bit = (-1),
124 
125 #define PLIST(pnames...)				\
126     .clk_pnames = { pnames },
127 
128 #define GENCLK(id, name, type, parents, mux, div, gt) {	\
129 	.clk_id		= id,				\
130 	.clk_type       = type,				\
131 	.clk_name	= name,				\
132 	parents						\
133 	mux						\
134 	div						\
135 	gt						\
136 }
137 
138 /* PLL definitions */
139 static struct jz4780_clk_pll_def pll_clks[] = {
140 	PLL(JZ4780_CLK_APLL, "apll", "ext", JZ_CPAPCR),
141 	PLL(JZ4780_CLK_MPLL, "mpll", "ext", JZ_CPMPCR),
142 	PLL(JZ4780_CLK_EPLL, "epll", "ext", JZ_CPEPCR),
143 	PLL(JZ4780_CLK_VPLL, "vpll", "ext", JZ_CPVPCR),
144 };
145 
146 /* OTG PHY clock (reuse gate def structure */
147 static struct jz4780_clk_gate_def otg_clks[] = {
148 	GATE(JZ4780_CLK_OTGPHY,	"otg_phy",	"ext", 0),
149 };
150 
151 static const struct jz4780_clk_descr gen_clks[] = {
152 	GENCLK(JZ4780_CLK_SCLKA, "sclk_a", CLK_MASK_MUX,
153 	    PLIST("apll", "ext", "rtc"),
154 	    MUX(JZ_CPCCR, 30, 2, 0x7),
155 	    NO_DIV,
156 	    NO_GATE
157 	),
158 
159 	GENCLK(JZ4780_CLK_CPUMUX, "cpumux", CLK_MASK_MUX,
160 	    PLIST("sclk_a", "mpll", "epll"),
161 	    MUX(JZ_CPCCR, 28, 2, 0x7),
162 	    NO_DIV,
163 	    NO_GATE
164 	),
165 
166 	GENCLK(JZ4780_CLK_CPU, "cpu", CLK_MASK_DIV,
167 	    PLIST("cpumux"),
168 	    NO_MUX,
169 	    DIV(JZ_CPCCR, 0, 0, 4, 22, -1, -1),
170 	    NO_GATE
171 	),
172 
173 	GENCLK(JZ4780_CLK_L2CACHE, "l2cache", CLK_MASK_DIV,
174 	    PLIST("cpumux"),
175 	    NO_MUX,
176 	    DIV(JZ_CPCCR, 4, 0, 4, -1, -1, -1),
177 	    NO_GATE
178 	),
179 
180 	GENCLK(JZ4780_CLK_AHB0, "ahb0", CLK_MASK_MUX | CLK_MASK_DIV,
181 	    PLIST("sclk_a", "mpll", "epll"),
182 	    MUX(JZ_CPCCR, 26, 2, 0x7),
183 	    DIV(JZ_CPCCR, 8, 0, 4, 21, -1, -1),
184 	    NO_GATE
185 	),
186 
187 	GENCLK(JZ4780_CLK_AHB2PMUX, "ahb2_apb_mux", CLK_MASK_MUX,
188 	    PLIST("sclk_a", "mpll", "rtc"),
189 	    MUX(JZ_CPCCR, 24, 2, 0x7),
190 	    NO_DIV,
191 	    NO_GATE
192 	),
193 
194 	GENCLK(JZ4780_CLK_AHB2, "ahb2", CLK_MASK_DIV,
195 	    PLIST("ahb2_apb_mux"),
196 	    NO_MUX,
197 	    DIV(JZ_CPCCR, 12, 0, 4, 20, -1, -1),
198 	    NO_GATE
199 	),
200 
201 	GENCLK(JZ4780_CLK_PCLK, "pclk", CLK_MASK_DIV,
202 	    PLIST("ahb2_apb_mux"),
203 	    NO_MUX,
204 	    DIV(JZ_CPCCR, 16, 0, 4, 20, -1, -1),
205 	    NO_GATE
206 	),
207 
208 	GENCLK(JZ4780_CLK_DDR, "ddr", CLK_MASK_MUX | CLK_MASK_DIV,
209 	    PLIST("sclk_a", "mpll"),
210 	    MUX(JZ_DDCDR, 30, 2, 0x6),
211 	    DIV(JZ_DDCDR, 0, 0, 4, 29, 28, 27),
212 	    NO_GATE
213 	),
214 
215 	GENCLK(JZ4780_CLK_VPU, "vpu", CLK_MASK_MUX | CLK_MASK_DIV | CLK_MASK_GATE,
216 	    PLIST("sclk_a", "mpll", "epll"),
217 	    MUX(JZ_VPUCDR, 30, 2, 0xe),
218 	    DIV(JZ_VPUCDR, 0, 0, 4, 29, 28, 27),
219 	    GATEBIT(32 + 2)
220 	),
221 
222 	GENCLK(JZ4780_CLK_I2SPLL, "i2s_pll", CLK_MASK_MUX | CLK_MASK_DIV,
223 	    PLIST("sclk_a", "epll"),
224 	    MUX(JZ_I2SCDR, 30, 1, 0xc),
225 	    DIV(JZ_I2SCDR, 0, 0, 8, 29, 28, 27),
226 	    NO_GATE
227 	),
228 
229 	GENCLK(JZ4780_CLK_I2S, "i2s", CLK_MASK_MUX,
230 	    PLIST("ext", "i2s_pll"),
231 	    MUX(JZ_I2SCDR, 31, 1, 0xc),
232 	    NO_DIV,
233 	    NO_GATE
234 	),
235 
236 	GENCLK(JZ4780_CLK_LCD0PIXCLK, "lcd0pixclk", CLK_MASK_MUX | CLK_MASK_DIV,
237 	    PLIST("sclk_a", "mpll", "vpll"),
238 	    MUX(JZ_LP0CDR, 30, 2, 0xe),
239 	    DIV(JZ_LP0CDR, 0, 0, 8, 28, 27, 26),
240 	    NO_GATE
241 	),
242 
243 	GENCLK(JZ4780_CLK_LCD1PIXCLK, "lcd1pixclk", CLK_MASK_MUX | CLK_MASK_DIV,
244 	    PLIST("sclk_a", "mpll", "vpll"),
245 	    MUX(JZ_LP1CDR, 30, 2, 0xe),
246 	    DIV(JZ_LP1CDR, 0, 0, 8, 28, 27, 26),
247 	    NO_GATE
248 	),
249 
250 	GENCLK(JZ4780_CLK_MSCMUX, "msc_mux", CLK_MASK_MUX,
251 	    PLIST("sclk_a", "mpll"),
252 	    MUX(JZ_MSC0CDR, 30, 2, 0x6),
253 	    NO_DIV,
254 	    NO_GATE
255 	),
256 
257 	GENCLK(JZ4780_CLK_MSC0, "msc0", CLK_MASK_DIV | CLK_MASK_GATE,
258 	    PLIST("msc_mux"),
259 	    NO_MUX,
260 	    DIV(JZ_MSC0CDR, 0, 1, 8, 29, 28, 27),
261 	    GATEBIT(3)
262 	),
263 
264 	GENCLK(JZ4780_CLK_MSC1, "msc1", CLK_MASK_DIV | CLK_MASK_GATE,
265 	    PLIST("msc_mux"),
266 	    NO_MUX,
267 	    DIV(JZ_MSC1CDR, 0, 1, 8, 29, 28, 27),
268 	    GATEBIT(11)
269 	),
270 
271 	GENCLK(JZ4780_CLK_MSC2, "msc2", CLK_MASK_DIV | CLK_MASK_GATE,
272 	    PLIST("msc_mux"),
273 	    NO_MUX,
274 	    DIV(JZ_MSC2CDR, 0, 1, 8, 29, 28, 27),
275 	    GATEBIT(12)
276 	),
277 
278 	GENCLK(JZ4780_CLK_UHC, "uhc", CLK_MASK_MUX | CLK_MASK_DIV | CLK_MASK_GATE,
279 	    PLIST("sclk_a", "mpll", "epll", "otg_phy"),
280 	    MUX(JZ_UHCCDR, 30, 2, 0xf),
281 	    DIV(JZ_UHCCDR, 0, 0, 8, 29, 28, 27),
282 	    GATEBIT(24)
283 	),
284 
285 	GENCLK(JZ4780_CLK_SSIPLL, "ssi_pll", CLK_MASK_MUX | CLK_MASK_DIV,
286 	    PLIST("sclk_a", "mpll"),
287 	    MUX(JZ_SSICDR, 30, 1, 0xc),
288 	    DIV(JZ_SSICDR, 0, 0, 8, 29, 28, 27),
289 	    NO_GATE
290 	),
291 
292 	GENCLK(JZ4780_CLK_SSI, "ssi", CLK_MASK_MUX,
293 	    PLIST("ext", "ssi_pll"),
294 	    MUX(JZ_SSICDR, 31, 1, 0xc),
295 	    NO_DIV,
296 	    NO_GATE
297 	),
298 
299 	GENCLK(JZ4780_CLK_CIMMCLK, "cim_mclk", CLK_MASK_MUX | CLK_MASK_DIV,
300 	    PLIST("sclk_a", "mpll"),
301 	    MUX(JZ_CIMCDR, 31, 1, 0xc),
302 	    DIV(JZ_CIMCDR, 0, 0, 8, 30, 29, 28),
303 	    NO_GATE
304 	),
305 
306 	GENCLK(JZ4780_CLK_PCMPLL, "pcm_pll", CLK_MASK_MUX | CLK_MASK_DIV,
307 	    PLIST("sclk_a", "mpll", "epll", "vpll"),
308 	    MUX(JZ_PCMCDR, 29, 2, 0xf),
309 	    DIV(JZ_PCMCDR, 0, 0, 8, 28, 27, 26),
310 	    NO_GATE
311 	),
312 
313 	GENCLK(JZ4780_CLK_PCM, "pcm", CLK_MASK_MUX | CLK_MASK_GATE,
314 	    PLIST("ext", "pcm_pll"),
315 	    MUX(JZ_PCMCDR, 31, 1, 0xc),
316 	    NO_DIV,
317 	    GATEBIT(32 + 3)
318 	),
319 
320 	GENCLK(JZ4780_CLK_GPU, "gpu", CLK_MASK_MUX | CLK_MASK_DIV | CLK_MASK_GATE,
321 	    PLIST("sclk_a", "mpll", "epll"),
322 	    MUX(JZ_GPUCDR, 30, 2, 0x7),
323 	    DIV(JZ_GPUCDR, 0, 0, 4, 29, 28, 27),
324 	    GATEBIT(32 + 4)
325 	),
326 
327 	GENCLK(JZ4780_CLK_HDMI, "hdmi", CLK_MASK_MUX | CLK_MASK_DIV | CLK_MASK_GATE,
328 	    PLIST("sclk_a", "mpll", "vpll"),
329 	    MUX(JZ_HDMICDR, 30, 2, 0xe),
330 	    DIV(JZ_HDMICDR, 0, 0, 8, 29, 28, 26),
331 	    GATEBIT(32 + 9)
332 	),
333 
334 	GENCLK(JZ4780_CLK_BCH, "bch", CLK_MASK_MUX | CLK_MASK_DIV | CLK_MASK_GATE,
335 	    PLIST("sclk_a", "mpll", "epll"),
336 	    MUX(JZ_BCHCDR, 30, 2, 0x7),
337 	    DIV(JZ_BCHCDR, 0, 0, 4, 29, 28, 27),
338 	    GATEBIT(1)
339 	),
340 };
341 
342 static struct jz4780_clk_gate_def gate_clks[] = {
343 	GATE(JZ4780_CLK_NEMC,	"nemc",		"ahb2", 0),
344 	GATE(JZ4780_CLK_OTG0,	"otg0",		"ext",	2),
345 	GATE(JZ4780_CLK_SSI0,	"ssi0",		"ssi",	4),
346 	GATE(JZ4780_CLK_SMB0,	"smb0",		"pclk", 5),
347 	GATE(JZ4780_CLK_SMB1,	"smb1",		"pclk", 6),
348 	GATE(JZ4780_CLK_SCC,	"scc",		"ext",	7),
349 	GATE(JZ4780_CLK_AIC,	"aic",		"ext",	8),
350 	GATE(JZ4780_CLK_TSSI0,	"tssi0",	"ext",	9),
351 	GATE(JZ4780_CLK_OWI,	"owi",		"ext",	10),
352 	GATE(JZ4780_CLK_KBC,	"kbc",		"ext",	13),
353 	GATE(JZ4780_CLK_SADC,	"sadc",		"ext",	14),
354 	GATE(JZ4780_CLK_UART0,	"uart0",	"ext",	15),
355 	GATE(JZ4780_CLK_UART1,	"uart1",	"ext",	16),
356 	GATE(JZ4780_CLK_UART2,	"uart2",	"ext",	17),
357 	GATE(JZ4780_CLK_UART3,	"uart3",	"ext",	18),
358 	GATE(JZ4780_CLK_SSI1,	"ssi1",		"ssi",	19),
359 	GATE(JZ4780_CLK_SSI2,	"ssi2",		"ssi",	20),
360 	GATE(JZ4780_CLK_PDMA,	"pdma",		"ext",	21),
361 	GATE(JZ4780_CLK_GPS,	"gps",		"ext",	22),
362 	GATE(JZ4780_CLK_MAC,	"mac",		"ext",	23),
363 	GATE(JZ4780_CLK_SMB2,	"smb2",		"pclk",	25),
364 	GATE(JZ4780_CLK_CIM,	"cim",		"ext",	26),
365 	GATE(JZ4780_CLK_LCD,	"lcd",		"ext",	28),
366 	GATE(JZ4780_CLK_TVE,	"tve",		"lcd",	27),
367 	GATE(JZ4780_CLK_IPU,	"ipu",		"ext",	29),
368 	GATE(JZ4780_CLK_DDR0,	"ddr0",		"ddr",	30),
369 	GATE(JZ4780_CLK_DDR1,	"ddr1",		"ddr",	31),
370 	GATE(JZ4780_CLK_SMB3,	"smb3",		"pclk",	32 + 0),
371 	GATE(JZ4780_CLK_TSSI1,	"tssi1",	"ext",	32 + 1),
372 	GATE(JZ4780_CLK_COMPRESS, "compress",	"ext",	32 + 5),
373 	GATE(JZ4780_CLK_AIC1,	"aic1",		"ext",	32 + 6),
374 	GATE(JZ4780_CLK_GPVLC,	"gpvlc",	"ext",	32 + 7),
375 	GATE(JZ4780_CLK_OTG1,	"otg1",		"ext",	32 + 8),
376 	GATE(JZ4780_CLK_UART4,	"uart4",	"ext",	32 + 10),
377 	GATE(JZ4780_CLK_AHBMON,	"ahb_mon",	"ext",	32 + 11),
378 	GATE(JZ4780_CLK_SMB4,	"smb4",		"pclk", 32 + 12),
379 	GATE(JZ4780_CLK_DES,	"des",		"ext",	32 + 13),
380 	GATE(JZ4780_CLK_X2D,	"x2d",		"ext",	32 + 14),
381 	GATE(JZ4780_CLK_CORE1,	"core1",	"cpu",	32 + 15),
382 };
383 
384 static int
jz4780_clock_register(struct jz4780_clock_softc * sc)385 jz4780_clock_register(struct jz4780_clock_softc *sc)
386 {
387 	int i, ret;
388 
389 	/* Register PLLs */
390 	for (i = 0; i < nitems(pll_clks); i++) {
391 		struct clknode_init_def clkdef;
392 
393 		clkdef.id = pll_clks[i].clk_id;
394 		clkdef.name = __DECONST(char *, pll_clks[i].clk_name);
395 		clkdef.parent_names = pll_clks[i].clk_pname;
396 		clkdef.parent_cnt = 1;
397 		clkdef.flags = CLK_NODE_STATIC_STRINGS;
398 
399 		ret = jz4780_clk_pll_register(sc->clkdom, &clkdef, &sc->mtx,
400 		    sc->res[0], pll_clks[i].clk_reg);
401 		if (ret != 0)
402 			return (ret);
403 	}
404 
405 	/* Register OTG clock */
406 	for (i = 0; i < nitems(otg_clks); i++) {
407 		struct clknode_init_def clkdef;
408 
409 		clkdef.id = otg_clks[i].clk_id;
410 		clkdef.name = __DECONST(char *, otg_clks[i].clk_name);
411 		clkdef.parent_names = otg_clks[i].clk_pname;
412 		clkdef.parent_cnt = 1;
413 		clkdef.flags = CLK_NODE_STATIC_STRINGS;
414 
415 		ret = jz4780_clk_otg_register(sc->clkdom, &clkdef, &sc->mtx,
416 		    sc->res[0]);
417 		if (ret != 0)
418 			return (ret);
419 	}
420 
421 	/* Register muxes and divisors */
422 	for (i = 0; i < nitems(gen_clks); i++) {
423 		ret = jz4780_clk_gen_register(sc->clkdom, &gen_clks[i],
424 		    &sc->mtx, sc->res[0]);
425 		if (ret != 0)
426 			return (ret);
427 	}
428 
429 	/* Register simple gates */
430 	for (i = 0; i < nitems(gate_clks); i++) {
431 		struct clk_gate_def gatedef;
432 
433 		gatedef.clkdef.id = gate_clks[i].clk_id;
434 		gatedef.clkdef.name = __DECONST(char *, gate_clks[i].clk_name);
435 		gatedef.clkdef.parent_names = gate_clks[i].clk_pname;
436 		gatedef.clkdef.parent_cnt = 1;
437 		gatedef.clkdef.flags = CLK_NODE_STATIC_STRINGS;
438 
439 		if (gate_clks[i].clk_bit < 32) {
440 			gatedef.offset = JZ_CLKGR0;
441 			gatedef.shift = gate_clks[i].clk_bit;
442 		} else {
443 			gatedef.offset = JZ_CLKGR1;
444 			gatedef.shift = gate_clks[i].clk_bit - 32;
445 		}
446 		gatedef.mask = 1;
447 		gatedef.on_value = 0;
448 		gatedef.off_value = 1;
449 		gatedef.gate_flags = 0;
450 
451 		ret = clknode_gate_register(sc->clkdom, &gatedef);
452 		if (ret != 0)
453 			return (ret);
454 	}
455 
456 	return (0);
457 }
458 
459 static int
jz4780_clock_fixup(struct jz4780_clock_softc * sc)460 jz4780_clock_fixup(struct jz4780_clock_softc *sc)
461 {
462 	struct clknode *clk_uhc;
463 	int ret;
464 
465 	/*
466 	 * Make UHC mux use MPLL as the source. It defaults to OTG_PHY
467 	 * and that somehow just does not work.
468 	 */
469 	clkdom_xlock(sc->clkdom);
470 
471 	/* Assume the worst */
472 	ret = ENXIO;
473 
474 	clk_uhc = clknode_find_by_id(sc->clkdom, JZ4780_CLK_UHC);
475 	if (clk_uhc != NULL) {
476 		ret = clknode_set_parent_by_name(clk_uhc, "mpll");
477 		if (ret != 0)
478 			device_printf(sc->dev,
479 			    "unable to reparent uhc clock\n");
480 		else
481 			ret = clknode_set_freq(clk_uhc, 48000000, 0, 0);
482 		if (ret != 0)
483 			device_printf(sc->dev, "unable to init uhc clock\n");
484 	} else
485 		device_printf(sc->dev, "unable to lookup uhc clock\n");
486 
487 	clkdom_unlock(sc->clkdom);
488 	return (ret);
489 }
490 
491 #define	CGU_LOCK(sc)		mtx_lock(&(sc)->mtx)
492 #define	CGU_UNLOCK(sc)		mtx_unlock(&(sc)->mtx)
493 #define	CGU_LOCK_INIT(sc)	\
494     mtx_init(&(sc)->mtx, device_get_nameunit((sc)->dev),	\
495     "jz4780-cgu", MTX_DEF)
496 #define	CGU_LOCK_DESTROY(sc)	mtx_destroy(&(sc)->mtx);
497 
498 #define CSR_WRITE_4(sc, reg, val)	bus_write_4((sc)->res[0], (reg), (val))
499 #define CSR_READ_4(sc, reg)		bus_read_4((sc)->res[0], (reg))
500 
501 static int
jz4780_clock_probe(device_t dev)502 jz4780_clock_probe(device_t dev)
503 {
504 
505 	if (!ofw_bus_status_okay(dev))
506 		return (ENXIO);
507 
508 	if (!ofw_bus_is_compatible(dev, "ingenic,jz4780-cgu"))
509 		return (ENXIO);
510 
511 	device_set_desc(dev, "Ingenic jz4780 CGU");
512 
513 	return (BUS_PROBE_DEFAULT);
514 }
515 
516 static int
jz4780_clock_attach(device_t dev)517 jz4780_clock_attach(device_t dev)
518 {
519 	struct jz4780_clock_softc *sc;
520 
521 	sc = device_get_softc(dev);
522 	if (bus_alloc_resources(dev, jz4780_clock_spec, sc->res)) {
523 		device_printf(dev, "could not allocate resources for device\n");
524 		return (ENXIO);
525 	}
526 
527 	sc->dev = dev;
528 	CGU_LOCK_INIT(sc);
529 
530 	sc->clkdom = clkdom_create(dev);
531 	if (sc->clkdom == NULL)
532 		goto fail;
533 	if (jz4780_clock_register(sc) != 0)
534 		goto fail;
535 	if (clkdom_finit(sc->clkdom) != 0)
536 		goto fail;
537 	if (jz4780_clock_fixup(sc) != 0)
538 		goto fail;
539 	if (bootverbose)
540 		clkdom_dump(sc->clkdom);
541 
542 	return (0);
543 fail:
544 	bus_release_resources(dev, jz4780_clock_spec, sc->res);
545 	CGU_LOCK_DESTROY(sc);
546 
547 	return (ENXIO);
548 }
549 
550 static int
jz4780_clock_detach(device_t dev)551 jz4780_clock_detach(device_t dev)
552 {
553 	struct jz4780_clock_softc *sc;
554 
555 	sc = device_get_softc(dev);
556 	bus_release_resources(dev, jz4780_clock_spec, sc->res);
557 	CGU_LOCK_DESTROY(sc);
558 
559 	return (0);
560 }
561 
562 static int
jz4780_clock_write_4(device_t dev,bus_addr_t addr,uint32_t val)563 jz4780_clock_write_4(device_t dev, bus_addr_t addr, uint32_t val)
564 {
565 	struct jz4780_clock_softc *sc;
566 
567 	sc = device_get_softc(dev);
568 	CSR_WRITE_4(sc, addr, val);
569 	return (0);
570 }
571 
572 static int
jz4780_clock_read_4(device_t dev,bus_addr_t addr,uint32_t * val)573 jz4780_clock_read_4(device_t dev, bus_addr_t addr, uint32_t *val)
574 {
575 	struct jz4780_clock_softc *sc;
576 
577 	sc = device_get_softc(dev);
578 	*val = CSR_READ_4(sc, addr);
579 	return (0);
580 }
581 
582 static int
jz4780_clock_modify_4(device_t dev,bus_addr_t addr,uint32_t clear_mask,uint32_t set_mask)583 jz4780_clock_modify_4(device_t dev, bus_addr_t addr, uint32_t clear_mask,
584     uint32_t set_mask)
585 {
586 	struct jz4780_clock_softc *sc;
587 	uint32_t val;
588 
589 	sc = device_get_softc(dev);
590 	val = CSR_READ_4(sc, addr);
591 	val &= ~clear_mask;
592 	val |= set_mask;
593 	CSR_WRITE_4(sc, addr, val);
594 	return (0);
595 }
596 
597 static void
jz4780_clock_device_lock(device_t dev)598 jz4780_clock_device_lock(device_t dev)
599 {
600 	struct jz4780_clock_softc *sc;
601 
602 	sc = device_get_softc(dev);
603 	CGU_LOCK(sc);
604 }
605 
606 static void
jz4780_clock_device_unlock(device_t dev)607 jz4780_clock_device_unlock(device_t dev)
608 {
609 	struct jz4780_clock_softc *sc;
610 
611 	sc = device_get_softc(dev);
612 	CGU_UNLOCK(sc);
613 }
614 
615 static device_method_t jz4780_clock_methods[] = {
616 	/* Device interface */
617 	DEVMETHOD(device_probe,		jz4780_clock_probe),
618 	DEVMETHOD(device_attach,	jz4780_clock_attach),
619 	DEVMETHOD(device_detach,	jz4780_clock_detach),
620 
621 	/* Clock device interface */
622 	DEVMETHOD(clkdev_write_4,	jz4780_clock_write_4),
623 	DEVMETHOD(clkdev_read_4,	jz4780_clock_read_4),
624 	DEVMETHOD(clkdev_modify_4,	jz4780_clock_modify_4),
625 	DEVMETHOD(clkdev_device_lock,	jz4780_clock_device_lock),
626 	DEVMETHOD(clkdev_device_unlock,	jz4780_clock_device_unlock),
627 
628 	DEVMETHOD_END
629 };
630 
631 static driver_t jz4780_clock_driver = {
632 	"cgu",
633 	jz4780_clock_methods,
634 	sizeof(struct jz4780_clock_softc),
635 };
636 
637 static devclass_t jz4780_clock_devclass;
638 
639 EARLY_DRIVER_MODULE(jz4780_clock, simplebus, jz4780_clock_driver,
640     jz4780_clock_devclass, 0, 0,  BUS_PASS_CPU + BUS_PASS_ORDER_LATE);
641 
642 static int
jz4780_ehci_clk_config(struct jz4780_clock_softc * sc)643 jz4780_ehci_clk_config(struct jz4780_clock_softc *sc)
644 {
645 	clk_t phy_clk, ext_clk;
646 	uint64_t phy_freq;
647 	int err;
648 
649 	phy_clk = NULL;
650 	ext_clk = NULL;
651 	err = -1;
652 
653 	/* Set phy timing by copying it from ext */
654 	if (clk_get_by_id(sc->dev, sc->clkdom, JZ4780_CLK_OTGPHY,
655 	    &phy_clk) != 0)
656 		goto done;
657 	if (clk_get_parent(phy_clk, &ext_clk) != 0)
658 		goto done;
659 	if (clk_get_freq(ext_clk, &phy_freq) != 0)
660 		goto done;
661 	if (clk_set_freq(phy_clk, phy_freq, 0) != 0)
662 		goto done;
663 	err = 0;
664 done:
665 	clk_release(ext_clk);
666 	clk_release(phy_clk);
667 
668 	return (err);
669 }
670 
671 int
jz4780_ohci_enable(void)672 jz4780_ohci_enable(void)
673 {
674 	device_t dev;
675 	struct jz4780_clock_softc *sc;
676 	uint32_t reg;
677 
678 	dev = devclass_get_device(jz4780_clock_devclass, 0);
679 	if (dev == NULL)
680 		return (-1);
681 
682 	sc = device_get_softc(dev);
683 	CGU_LOCK(sc);
684 
685 	/* Do not force port1 to suspend mode */
686 	reg = CSR_READ_4(sc, JZ_OPCR);
687 	reg |= OPCR_SPENDN1;
688 	CSR_WRITE_4(sc, JZ_OPCR, reg);
689 
690 	CGU_UNLOCK(sc);
691 	return (0);
692 }
693 
694 int
jz4780_ehci_enable(void)695 jz4780_ehci_enable(void)
696 {
697 	device_t dev;
698 	struct jz4780_clock_softc *sc;
699 	uint32_t reg;
700 
701 	dev = devclass_get_device(jz4780_clock_devclass, 0);
702 	if (dev == NULL)
703 		return (-1);
704 
705 	sc = device_get_softc(dev);
706 
707 	/*
708 	 * EHCI should use MPPL as a parent, but Linux configures OTG
709 	 * clock anyway. Follow their lead blindly.
710 	 */
711 	if (jz4780_ehci_clk_config(sc) != 0)
712 		return (-1);
713 
714 	CGU_LOCK(sc);
715 
716 	/* Enable OTG, should not be necessary since we use PLL clock */
717 	reg = CSR_READ_4(sc, JZ_USBPCR);
718 	reg &= ~(PCR_OTG_DISABLE);
719 	CSR_WRITE_4(sc, JZ_USBPCR, reg);
720 
721 	/* Do not force port1 to suspend mode */
722 	reg = CSR_READ_4(sc, JZ_OPCR);
723 	reg |= OPCR_SPENDN1;
724 	CSR_WRITE_4(sc, JZ_OPCR, reg);
725 
726 	/* D- pulldown */
727 	reg = CSR_READ_4(sc, JZ_USBPCR1);
728 	reg |= PCR_DMPD1;
729 	CSR_WRITE_4(sc, JZ_USBPCR1, reg);
730 
731 	/* D+ pulldown */
732 	reg = CSR_READ_4(sc, JZ_USBPCR1);
733 	reg |= PCR_DPPD1;
734 	CSR_WRITE_4(sc, JZ_USBPCR1, reg);
735 
736 	/* 16 bit bus witdth for port 1*/
737 	reg = CSR_READ_4(sc, JZ_USBPCR1);
738 	reg |= PCR_WORD_I_F1 | PCR_WORD_I_F0;
739 	CSR_WRITE_4(sc, JZ_USBPCR1, reg);
740 
741 	/* Reset USB */
742 	reg = CSR_READ_4(sc, JZ_USBPCR);
743 	reg |= PCR_POR;
744 	CSR_WRITE_4(sc, JZ_USBPCR, reg);
745 	DELAY(1);
746 	reg = CSR_READ_4(sc, JZ_USBPCR);
747 	reg &= ~(PCR_POR);
748 	CSR_WRITE_4(sc, JZ_USBPCR, reg);
749 
750 	/* Soft-reset USB */
751 	reg = CSR_READ_4(sc, JZ_SRBC);
752 	reg |= SRBC_UHC_SR;
753 	CSR_WRITE_4(sc, JZ_SRBC, reg);
754 	/* 300ms */
755 	DELAY(300*hz/1000);
756 
757 	reg = CSR_READ_4(sc, JZ_SRBC);
758 	reg &= ~(SRBC_UHC_SR);
759 	CSR_WRITE_4(sc, JZ_SRBC, reg);
760 
761 	/* 300ms */
762 	DELAY(300*hz/1000);
763 
764 	CGU_UNLOCK(sc);
765 	return (0);
766 }
767 
768 #define	USBRESET_DETECT_TIME	0x96
769 
770 int
jz4780_otg_enable(void)771 jz4780_otg_enable(void)
772 {
773 	device_t dev;
774 	struct jz4780_clock_softc *sc;
775 	uint32_t reg;
776 
777 	dev = devclass_get_device(jz4780_clock_devclass, 0);
778 	if (dev == NULL)
779 		return (-1);
780 
781 	sc = device_get_softc(dev);
782 
783 	CGU_LOCK(sc);
784 
785 	/* Select Synopsys OTG mode */
786 	reg = CSR_READ_4(sc, JZ_USBPCR1);
787 	reg |= PCR_SYNOPSYS;
788 
789 	/* Set UTMI bus width to 16 bit */
790 	reg |= PCR_WORD_I_F0 | PCR_WORD_I_F1;
791 	CSR_WRITE_4(sc, JZ_USBPCR1, reg);
792 
793 	/* Blah */
794 	reg = CSR_READ_4(sc, JZ_USBVBFIL);
795 	reg = REG_SET(reg, USBVBFIL_IDDIGFIL, 0);
796 	reg = REG_SET(reg, USBVBFIL_USBVBFIL, 0);
797 	CSR_WRITE_4(sc, JZ_USBVBFIL, reg);
798 
799 	/* Setup reset detect time */
800 	reg = CSR_READ_4(sc, JZ_USBRDT);
801 	reg = REG_SET(reg, USBRDT_USBRDT, USBRESET_DETECT_TIME);
802 	reg |= USBRDT_VBFIL_LD_EN;
803 	CSR_WRITE_4(sc, JZ_USBRDT, reg);
804 
805 	/* Setup USBPCR bits */
806 	reg = CSR_READ_4(sc, JZ_USBPCR);
807 	reg |= PCR_USB_MODE;
808 	reg |= PCR_COMMONONN;
809 	reg |= PCR_VBUSVLDEXT;
810 	reg |= PCR_VBUSVLDEXTSEL;
811 	reg &= ~(PCR_OTG_DISABLE);
812 	CSR_WRITE_4(sc, JZ_USBPCR, reg);
813 
814 	/* Reset USB */
815 	reg = CSR_READ_4(sc, JZ_USBPCR);
816 	reg |= PCR_POR;
817 	CSR_WRITE_4(sc, JZ_USBPCR, reg);
818 	DELAY(1000);
819 	reg = CSR_READ_4(sc, JZ_USBPCR);
820 	reg &= ~(PCR_POR);
821 	CSR_WRITE_4(sc, JZ_USBPCR, reg);
822 
823 	/* Unsuspend OTG port */
824 	reg = CSR_READ_4(sc, JZ_OPCR);
825 	reg |= OPCR_SPENDN0;
826 	CSR_WRITE_4(sc, JZ_OPCR, reg);
827 
828 	CGU_UNLOCK(sc);
829 	return (0);
830 }
831