xref: /freebsd/sys/arm/nvidia/tegra124/tegra124_pmc.c (revision 3fc36ee018bb836bd1796067cf4ef8683f166ebc)
1 /*-
2  * Copyright (c) 2016 Michal Meloun <mmel@FreeBSD.org>
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  * $FreeBSD$
27  */
28 
29 #include <sys/param.h>
30 #include <sys/systm.h>
31 #include <sys/bus.h>
32 #include <sys/kernel.h>
33 #include <sys/module.h>
34 #include <sys/malloc.h>
35 #include <sys/rman.h>
36 
37 #include <machine/bus.h>
38 
39 #include <dev/extres/clk/clk.h>
40 #include <dev/extres/hwreset/hwreset.h>
41 #include <dev/fdt/fdt_common.h>
42 #include <dev/ofw/ofw_bus.h>
43 #include <dev/ofw/ofw_bus_subr.h>
44 
45 #include <arm/nvidia/tegra_pmc.h>
46 
47 #define	PMC_CNTRL			0x000
48 #define	 PMC_CNTRL_CPUPWRGOOD_SEL_MASK		(0x3 << 20)
49 #define	 PMC_CNTRL_CPUPWRGOOD_SEL_SHIFT		20
50 #define	 PMC_CNTRL_CPUPWRGOOD_EN		(1 << 19)
51 #define	 PMC_CNTRL_FUSE_OVERRIDE		(1 << 18)
52 #define	 PMC_CNTRL_INTR_POLARITY		(1 << 17)
53 #define	 PMC_CNTRL_CPU_PWRREQ_OE		(1 << 16)
54 #define	 PMC_CNTRL_CPU_PWRREQ_POLARITY		(1 << 15)
55 #define	 PMC_CNTRL_SIDE_EFFECT_LP0		(1 << 14)
56 #define	 PMC_CNTRL_AOINIT			(1 << 13)
57 #define	 PMC_CNTRL_PWRGATE_DIS			(1 << 12)
58 #define	 PMC_CNTRL_SYSCLK_OE			(1 << 11)
59 #define	 PMC_CNTRL_SYSCLK_POLARITY		(1 << 10)
60 #define	 PMC_CNTRL_PWRREQ_OE			(1 <<  9)
61 #define	 PMC_CNTRL_PWRREQ_POLARITY		(1 <<  8)
62 #define	 PMC_CNTRL_BLINK_EN			(1 <<  7)
63 #define	 PMC_CNTRL_GLITCHDET_DIS		(1 <<  6)
64 #define	 PMC_CNTRL_LATCHWAKE_EN			(1 <<  5)
65 #define	 PMC_CNTRL_MAIN_RST			(1 <<  4)
66 #define	 PMC_CNTRL_KBC_RST			(1 <<  3)
67 #define	 PMC_CNTRL_RTC_RST			(1 <<  2)
68 #define	 PMC_CNTRL_RTC_CLK_DIS			(1 <<  1)
69 #define	 PMC_CNTRL_KBC_CLK_DIS			(1 <<  0)
70 
71 #define	PMC_DPD_SAMPLE			0x020
72 
73 #define	PMC_CLAMP_STATUS		0x02C
74 #define	  PMC_CLAMP_STATUS_PARTID(x)		(1 << ((x) & 0x1F))
75 
76 #define	PMC_PWRGATE_TOGGLE		0x030
77 #define	 PMC_PWRGATE_TOGGLE_START		(1 << 8)
78 #define	 PMC_PWRGATE_TOGGLE_PARTID(x)		(((x) & 0x1F) << 0)
79 
80 #define	PMC_REMOVE_CLAMPING_CMD		0x034
81 #define	  PMC_REMOVE_CLAMPING_CMD_PARTID(x)	(1 << ((x) & 0x1F))
82 
83 #define	PMC_PWRGATE_STATUS		0x038
84 #define	PMC_PWRGATE_STATUS_PARTID(x)		(1 << ((x) & 0x1F))
85 
86 #define	PMC_SCRATCH0			0x050
87 #define	 PMC_SCRATCH0_MODE_RECOVERY		(1 << 31)
88 #define	 PMC_SCRATCH0_MODE_BOOTLOADER		(1 << 30)
89 #define	 PMC_SCRATCH0_MODE_RCM			(1 << 1)
90 #define	 PMC_SCRATCH0_MODE_MASK			(PMC_SCRATCH0_MODE_RECOVERY | \
91 						PMC_SCRATCH0_MODE_BOOTLOADER | \
92 						PMC_SCRATCH0_MODE_RCM)
93 
94 #define	PMC_CPUPWRGOOD_TIMER		0x0c8
95 #define	PMC_CPUPWROFF_TIMER		0x0cc
96 
97 #define	PMC_SCRATCH41			0x140
98 
99 #define	PMC_SENSOR_CTRL			0x1b0
100 #define	PMC_SENSOR_CTRL_BLOCK_SCRATCH_WRITE	(1 << 2)
101 #define	PMC_SENSOR_CTRL_ENABLE_RST		(1 << 1)
102 #define	PMC_SENSOR_CTRL_ENABLE_PG		(1 << 0)
103 
104 #define	PMC_IO_DPD_REQ			0x1b8
105 #define	 PMC_IO_DPD_REQ_CODE_IDLE		(0 << 30)
106 #define	 PMC_IO_DPD_REQ_CODE_OFF		(1 << 30)
107 #define	 PMC_IO_DPD_REQ_CODE_ON			(2 << 30)
108 #define	 PMC_IO_DPD_REQ_CODE_MASK		(3 << 30)
109 
110 #define	PMC_IO_DPD_STATUS		0x1bc
111 #define	 PMC_IO_DPD_STATUS_HDMI			(1 << 28)
112 #define	PMC_IO_DPD2_REQ			0x1c0
113 #define	PMC_IO_DPD2_STATUS		0x1c4
114 #define	 PMC_IO_DPD2_STATUS_HV			(1 << 6)
115 #define	PMC_SEL_DPD_TIM			0x1c8
116 
117 #define	PMC_SCRATCH54			0x258
118 #define	PMC_SCRATCH54_DATA_SHIFT		8
119 #define	PMC_SCRATCH54_ADDR_SHIFT		0
120 
121 #define	PMC_SCRATCH55			0x25c
122 #define	PMC_SCRATCH55_RST_ENABLE		(1 << 31)
123 #define	PMC_SCRATCH55_CNTRL_TYPE		(1 << 30)
124 #define	PMC_SCRATCH55_CNTRL_ID_SHIFT		27
125 #define	PMC_SCRATCH55_CNTRL_ID_MASK		0x07
126 #define	PMC_SCRATCH55_PINMUX_SHIFT		24
127 #define	PMC_SCRATCH55_PINMUX_MASK		0x07
128 #define	PMC_SCRATCH55_CHECKSUM_SHIFT		16
129 #define	PMC_SCRATCH55_CHECKSUM_MASK		0xFF
130 #define	PMC_SCRATCH55_16BITOP			(1 << 15)
131 #define	PMC_SCRATCH55_I2CSLV1_SHIFT		0
132 #define	PMC_SCRATCH55_I2CSLV1_MASK		0x7F
133 
134 #define	PMC_GPU_RG_CNTRL		0x2d4
135 
136 #define	WR4(_sc, _r, _v)	bus_write_4((_sc)->mem_res, (_r), (_v))
137 #define	RD4(_sc, _r)		bus_read_4((_sc)->mem_res, (_r))
138 
139 #define	PMC_LOCK(_sc)		mtx_lock(&(_sc)->mtx)
140 #define	PMC_UNLOCK(_sc)		mtx_unlock(&(_sc)->mtx)
141 #define	PMC_LOCK_INIT(_sc)	mtx_init(&(_sc)->mtx, 			\
142 	    device_get_nameunit(_sc->dev), "tegra124_pmc", MTX_DEF)
143 #define	PMC_LOCK_DESTROY(_sc)	mtx_destroy(&(_sc)->mtx);
144 #define	PMC_ASSERT_LOCKED(_sc)	mtx_assert(&(_sc)->mtx, MA_OWNED);
145 #define	PMC_ASSERT_UNLOCKED(_sc) mtx_assert(&(_sc)->mtx, MA_NOTOWNED);
146 
147 struct tegra124_pmc_softc {
148 	device_t		dev;
149 	struct resource		*mem_res;
150 	clk_t			clk;
151 	struct mtx		mtx;
152 
153 	uint32_t		rate;
154 	enum tegra_suspend_mode suspend_mode;
155 	uint32_t		cpu_good_time;
156 	uint32_t		cpu_off_time;
157 	uint32_t		core_osc_time;
158 	uint32_t		core_pmu_time;
159 	uint32_t		core_off_time;
160 	int			corereq_high;
161 	int			sysclkreq_high;
162 	int			combined_req;
163 	int			cpu_pwr_good_en;
164 	uint32_t		lp0_vec_phys;
165 	uint32_t		lp0_vec_size;
166 };
167 
168 static struct ofw_compat_data compat_data[] = {
169 	{"nvidia,tegra124-pmc",		1},
170 	{NULL,				0},
171 };
172 
173 static struct tegra124_pmc_softc *pmc_sc;
174 
175 static inline struct tegra124_pmc_softc *
176 tegra124_pmc_get_sc(void)
177 {
178 	if (pmc_sc == NULL)
179 		panic("To early call to Tegra PMC driver.\n");
180 	return (pmc_sc);
181 }
182 
183 static int
184 tegra124_pmc_set_powergate(struct tegra124_pmc_softc *sc,
185     enum tegra_powergate_id id, int ena)
186 {
187 	uint32_t reg;
188 	int i;
189 
190 	PMC_LOCK(sc);
191 
192 	reg = RD4(sc, PMC_PWRGATE_STATUS) & PMC_PWRGATE_STATUS_PARTID(id);
193 	if (((reg != 0) && ena) || ((reg == 0) && !ena)) {
194 		PMC_UNLOCK(sc);
195 		return (0);
196 	}
197 
198 	for (i = 100; i > 0; i--) {
199 		reg = RD4(sc, PMC_PWRGATE_TOGGLE);
200 		if ((reg & PMC_PWRGATE_TOGGLE_START) == 0)
201 			break;
202 		DELAY(1);
203 	}
204 	if (i <= 0)
205 		device_printf(sc->dev,
206 		    "Timeout when waiting for TOGGLE_START\n");
207 
208 	WR4(sc, PMC_PWRGATE_TOGGLE,
209 	    PMC_PWRGATE_TOGGLE_START | PMC_PWRGATE_TOGGLE_PARTID(id));
210 
211 	for (i = 100; i > 0; i--) {
212 		reg = RD4(sc, PMC_PWRGATE_TOGGLE);
213 		if ((reg & PMC_PWRGATE_TOGGLE_START) == 0)
214 			break;
215 		DELAY(1);
216 	}
217 	if (i <= 0)
218 		device_printf(sc->dev,
219 		    "Timeout when waiting for TOGGLE_START\n");
220 		PMC_UNLOCK(sc);
221 	return (0);
222 }
223 
224 int
225 tegra_powergate_remove_clamping(enum tegra_powergate_id  id)
226 {
227 	struct tegra124_pmc_softc *sc;
228 	uint32_t reg;
229 	enum tegra_powergate_id swid;
230 	int i;
231 
232 	sc = tegra124_pmc_get_sc();
233 
234 	if (id == TEGRA_POWERGATE_3D) {
235 		WR4(sc, PMC_GPU_RG_CNTRL, 0);
236 		return (0);
237 	}
238 
239 	reg = RD4(sc, PMC_PWRGATE_STATUS);
240 	if ((reg & PMC_PWRGATE_STATUS_PARTID(id)) == 0)
241 		panic("Attempt to remove clamping for unpowered partition.\n");
242 
243 	if (id == TEGRA_POWERGATE_PCX)
244 		swid = TEGRA_POWERGATE_VDE;
245 	else if (id == TEGRA_POWERGATE_VDE)
246 		swid = TEGRA_POWERGATE_PCX;
247 	else
248 		swid = id;
249 	WR4(sc, PMC_REMOVE_CLAMPING_CMD, PMC_REMOVE_CLAMPING_CMD_PARTID(swid));
250 
251 	for (i = 100; i > 0; i--) {
252 		reg = RD4(sc, PMC_REMOVE_CLAMPING_CMD);
253 		if ((reg & PMC_REMOVE_CLAMPING_CMD_PARTID(swid)) == 0)
254 			break;
255 		DELAY(1);
256 	}
257 	if (i <= 0)
258 		device_printf(sc->dev, "Timeout when remove clamping\n");
259 
260 	reg = RD4(sc, PMC_CLAMP_STATUS);
261 	if ((reg & PMC_CLAMP_STATUS_PARTID(id)) != 0)
262 		panic("Cannot remove clamping\n");
263 
264 	return (0);
265 }
266 
267 int
268 tegra_powergate_is_powered(enum tegra_powergate_id id)
269 {
270 	struct tegra124_pmc_softc *sc;
271 	uint32_t reg;
272 
273 	sc = tegra124_pmc_get_sc();
274 
275 	reg = RD4(sc, PMC_PWRGATE_STATUS);
276 	return ((reg & PMC_PWRGATE_STATUS_PARTID(id)) ? 1 : 0);
277 }
278 
279 int
280 tegra_powergate_power_on(enum tegra_powergate_id id)
281 {
282 	struct tegra124_pmc_softc *sc;
283 	int rv, i;
284 
285 	sc = tegra124_pmc_get_sc();
286 
287 	rv = tegra124_pmc_set_powergate(sc, id, 1);
288 	if (rv != 0) {
289 		device_printf(sc->dev, "Cannot set powergate: %d\n", id);
290 		return (rv);
291 	}
292 
293 	for (i = 100; i > 0; i--) {
294 		if (tegra_powergate_is_powered(id))
295 			break;
296 		DELAY(1);
297 	}
298 	if (i <= 0)
299 		device_printf(sc->dev, "Timeout when waiting on power up\n");
300 
301 	return (rv);
302 }
303 
304 int
305 tegra_powergate_power_off(enum tegra_powergate_id id)
306 {
307 	struct tegra124_pmc_softc *sc;
308 	int rv, i;
309 
310 	sc = tegra124_pmc_get_sc();
311 
312 	rv = tegra124_pmc_set_powergate(sc, id, 0);
313 	if (rv != 0) {
314 		device_printf(sc->dev, "Cannot set powergate: %d\n", id);
315 		return (rv);
316 	}
317 	for (i = 100; i > 0; i--) {
318 		if (!tegra_powergate_is_powered(id))
319 			break;
320 		DELAY(1);
321 	}
322 	if (i <= 0)
323 		device_printf(sc->dev, "Timeout when waiting on power off\n");
324 
325 	return (rv);
326 }
327 
328 int
329 tegra_powergate_sequence_power_up(enum tegra_powergate_id id, clk_t clk,
330     hwreset_t rst)
331 {
332 	struct tegra124_pmc_softc *sc;
333 	int rv;
334 
335 	sc = tegra124_pmc_get_sc();
336 
337 	rv = hwreset_assert(rst);
338 	if (rv != 0) {
339 		device_printf(sc->dev, "Cannot assert reset\n");
340 		return (rv);
341 	}
342 
343 	rv = clk_stop(clk);
344 	if (rv != 0) {
345 		device_printf(sc->dev, "Cannot stop clock\n");
346 		goto clk_fail;
347 	}
348 
349 	rv = tegra_powergate_power_on(id);
350 	if (rv != 0) {
351 		device_printf(sc->dev, "Cannot power on powergate\n");
352 		goto clk_fail;
353 	}
354 
355 	rv = clk_enable(clk);
356 	if (rv != 0) {
357 		device_printf(sc->dev, "Cannot enable clock\n");
358 		goto clk_fail;
359 	}
360 	DELAY(20);
361 
362 	rv = tegra_powergate_remove_clamping(id);
363 	if (rv != 0) {
364 		device_printf(sc->dev, "Cannot remove clamping\n");
365 		goto fail;
366 	}
367 	rv = hwreset_deassert(rst);
368 	if (rv != 0) {
369 		device_printf(sc->dev, "Cannot unreset reset\n");
370 		goto fail;
371 	}
372 	return 0;
373 
374 fail:
375 	clk_disable(clk);
376 clk_fail:
377 	hwreset_assert(rst);
378 	tegra_powergate_power_off(id);
379 	return (rv);
380 }
381 
382 static int
383 tegra124_pmc_parse_fdt(struct tegra124_pmc_softc *sc, phandle_t node)
384 {
385 	int rv;
386 	uint32_t tmp;
387 	uint32_t tmparr[2];
388 
389 	rv = OF_getencprop(node, "nvidia,suspend-mode", &tmp, sizeof(tmp));
390 	if (rv > 0) {
391 		switch (tmp) {
392 		case 0:
393 			sc->suspend_mode = TEGRA_SUSPEND_LP0;
394 			break;
395 
396 		case 1:
397 			sc->suspend_mode = TEGRA_SUSPEND_LP1;
398 			break;
399 
400 		case 2:
401 			sc->suspend_mode = TEGRA_SUSPEND_LP2;
402 			break;
403 
404 		default:
405 			sc->suspend_mode = TEGRA_SUSPEND_NONE;
406 			break;
407 		}
408 	}
409 
410 	rv = OF_getencprop(node, "nvidia,cpu-pwr-good-time", &tmp, sizeof(tmp));
411 	if (rv > 0) {
412 		sc->cpu_good_time = tmp;
413 		sc->suspend_mode = TEGRA_SUSPEND_NONE;
414 	}
415 
416 	rv = OF_getencprop(node, "nvidia,cpu-pwr-off-time", &tmp, sizeof(tmp));
417 	if (rv > 0) {
418 		sc->cpu_off_time = tmp;
419 		sc->suspend_mode = TEGRA_SUSPEND_NONE;
420 	}
421 
422 	rv = OF_getencprop(node, "nvidia,core-pwr-good-time", tmparr,
423 	    sizeof(tmparr));
424 	if (rv == sizeof(tmparr)) {
425 		sc->core_osc_time = tmparr[0];
426 		sc->core_pmu_time = tmparr[1];
427 		sc->suspend_mode = TEGRA_SUSPEND_NONE;
428 	}
429 
430 	rv = OF_getencprop(node, "nvidia,core-pwr-off-time", &tmp, sizeof(tmp));
431 	if (rv > 0) {
432 		sc->core_off_time = tmp;
433 		sc->suspend_mode = TEGRA_SUSPEND_NONE;
434 	}
435 
436 	sc->corereq_high =
437 	    OF_hasprop(node, "nvidia,core-power-req-active-high");
438 	sc->sysclkreq_high =
439 	    OF_hasprop(node, "nvidia,sys-clock-req-active-high");
440 	sc->combined_req =
441 	    OF_hasprop(node, "nvidia,combined-power-req");
442 	sc->cpu_pwr_good_en =
443 	    OF_hasprop(node, "nvidia,cpu-pwr-good-en");
444 
445 	rv = OF_getencprop(node, "nvidia,lp0-vec", tmparr, sizeof(tmparr));
446 	if (rv == sizeof(tmparr)) {
447 
448 		sc->lp0_vec_phys = tmparr[0];
449 		sc->core_pmu_time = tmparr[1];
450 		sc->lp0_vec_size = TEGRA_SUSPEND_NONE;
451 		if (sc->suspend_mode == TEGRA_SUSPEND_LP0)
452 			sc->suspend_mode = TEGRA_SUSPEND_LP1;
453 	}
454 	return 0;
455 }
456 
457 static int
458 tegra124_pmc_probe(device_t dev)
459 {
460 
461 	if (!ofw_bus_status_okay(dev))
462 		return (ENXIO);
463 
464 	if (!ofw_bus_search_compatible(dev, compat_data)->ocd_data)
465 		return (ENXIO);
466 
467 	device_set_desc(dev, "Tegra PMC");
468 	return (BUS_PROBE_DEFAULT);
469 }
470 
471 static int
472 tegra124_pmc_detach(device_t dev)
473 {
474 
475 	/* This device is always present. */
476 	return (EBUSY);
477 }
478 
479 static int
480 tegra124_pmc_attach(device_t dev)
481 {
482 	struct tegra124_pmc_softc *sc;
483 	int rid, rv;
484 	uint32_t reg;
485 	phandle_t node;
486 
487 	sc = device_get_softc(dev);
488 	sc->dev = dev;
489 	node = ofw_bus_get_node(dev);
490 
491 	rv = tegra124_pmc_parse_fdt(sc, node);
492 	if (rv != 0) {
493 		device_printf(sc->dev, "Cannot parse FDT data\n");
494 		return (rv);
495 	}
496 
497 	rv = clk_get_by_ofw_name(sc->dev, 0, "pclk", &sc->clk);
498 	if (rv != 0) {
499 		device_printf(sc->dev, "Cannot get \"pclk\" clock\n");
500 		return (ENXIO);
501 	}
502 
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 		device_printf(dev, "Cannot allocate memory resources\n");
508 		return (ENXIO);
509 	}
510 
511 	PMC_LOCK_INIT(sc);
512 
513 	/* Enable CPU power request. */
514 	reg = RD4(sc, PMC_CNTRL);
515 	reg |= PMC_CNTRL_CPU_PWRREQ_OE;
516 	WR4(sc, PMC_CNTRL, reg);
517 
518 	/* Set sysclk output polarity */
519 	reg = RD4(sc, PMC_CNTRL);
520 	if (sc->sysclkreq_high)
521 		reg &= ~PMC_CNTRL_SYSCLK_POLARITY;
522 	else
523 		reg |= PMC_CNTRL_SYSCLK_POLARITY;
524 	WR4(sc, PMC_CNTRL, reg);
525 
526 	/* Enable sysclk request. */
527 	reg = RD4(sc, PMC_CNTRL);
528 	reg |= PMC_CNTRL_SYSCLK_OE;
529 	WR4(sc, PMC_CNTRL, reg);
530 
531 	/*
532 	 * Remove HDMI from deep power down mode.
533 	 * XXX mote this to HDMI driver
534 	 */
535 	reg = RD4(sc, PMC_IO_DPD_STATUS);
536 	reg &= ~ PMC_IO_DPD_STATUS_HDMI;
537 	WR4(sc, PMC_IO_DPD_STATUS, reg);
538 
539 	reg = RD4(sc, PMC_IO_DPD2_STATUS);
540 	reg &= ~ PMC_IO_DPD2_STATUS_HV;
541 	WR4(sc, PMC_IO_DPD2_STATUS, reg);
542 
543 	if (pmc_sc != NULL)
544 		panic("tegra124_pmc: double driver attach");
545 	pmc_sc = sc;
546 	return (0);
547 }
548 
549 static device_method_t tegra124_pmc_methods[] = {
550 	/* Device interface */
551 	DEVMETHOD(device_probe,		tegra124_pmc_probe),
552 	DEVMETHOD(device_attach,	tegra124_pmc_attach),
553 	DEVMETHOD(device_detach,	tegra124_pmc_detach),
554 
555 	DEVMETHOD_END
556 };
557 
558 static driver_t tegra124_pmc_driver = {
559 	"tegra124_pmc",
560 	tegra124_pmc_methods,
561 	sizeof(struct tegra124_pmc_softc),
562 };
563 
564 static devclass_t tegra124_pmc_devclass;
565 EARLY_DRIVER_MODULE(tegra124_pmc, simplebus, tegra124_pmc_driver,
566     tegra124_pmc_devclass, 0, 0, 70);
567