1*cf087682SMitchell Horne /*-
2*cf087682SMitchell Horne  * SPDX-License-Identifier: BSD-2-Clause
3*cf087682SMitchell Horne  *
4*cf087682SMitchell Horne  * Copyright (c) 2024 The FreeBSD Foundation
5*cf087682SMitchell Horne  *
6*cf087682SMitchell Horne  * This software was developed by Mitchell Horne <mhorne@FreeBSD.org> under
7*cf087682SMitchell Horne  * sponsorship from the FreeBSD Foundation.
8*cf087682SMitchell Horne  */
9*cf087682SMitchell Horne 
10*cf087682SMitchell Horne /*
11*cf087682SMitchell Horne  * StarFive syscon driver.
12*cf087682SMitchell Horne  *
13*cf087682SMitchell Horne  * On the JH7110, the PLL clock driver is a child of the sys-syscon device.
14*cf087682SMitchell Horne  * This needs to probe very early (BUS_PASS_BUS + BUS_PASS_ORDER_EARLY).
15*cf087682SMitchell Horne  */
16*cf087682SMitchell Horne 
17*cf087682SMitchell Horne #include <sys/param.h>
18*cf087682SMitchell Horne #include <sys/bus.h>
19*cf087682SMitchell Horne #include <sys/kernel.h>
20*cf087682SMitchell Horne #include <sys/module.h>
21*cf087682SMitchell Horne #include <sys/mutex.h>
22*cf087682SMitchell Horne 
23*cf087682SMitchell Horne #include <machine/bus.h>
24*cf087682SMitchell Horne 
25*cf087682SMitchell Horne #include <dev/ofw/openfirm.h>
26*cf087682SMitchell Horne #include <dev/ofw/ofw_bus.h>
27*cf087682SMitchell Horne #include <dev/ofw/ofw_bus_subr.h>
28*cf087682SMitchell Horne 
29*cf087682SMitchell Horne #include <dev/syscon/syscon.h>
30*cf087682SMitchell Horne #include <dev/syscon/syscon_generic.h>
31*cf087682SMitchell Horne 
32*cf087682SMitchell Horne #include <dev/fdt/simple_mfd.h>
33*cf087682SMitchell Horne 
34*cf087682SMitchell Horne enum starfive_syscon_type {
35*cf087682SMitchell Horne 	JH7110_SYSCON_SYS = 1,
36*cf087682SMitchell Horne 	JH7110_SYSCON_AON,
37*cf087682SMitchell Horne 	JH7110_SYSCON_STG,
38*cf087682SMitchell Horne };
39*cf087682SMitchell Horne 
40*cf087682SMitchell Horne static struct ofw_compat_data compat_data[] = {
41*cf087682SMitchell Horne 	{ "starfive,jh7110-sys-syscon",	JH7110_SYSCON_SYS },
42*cf087682SMitchell Horne 	{ "starfive,jh7110-aon-syscon",	JH7110_SYSCON_AON },
43*cf087682SMitchell Horne 	{ "starfive,jh7110-stg-syscon",	JH7110_SYSCON_STG },
44*cf087682SMitchell Horne 
45*cf087682SMitchell Horne 	{ NULL, 0 }
46*cf087682SMitchell Horne };
47*cf087682SMitchell Horne 
48*cf087682SMitchell Horne static int
starfive_syscon_probe(device_t dev)49*cf087682SMitchell Horne starfive_syscon_probe(device_t dev)
50*cf087682SMitchell Horne {
51*cf087682SMitchell Horne 	enum starfive_syscon_type type;
52*cf087682SMitchell Horne 
53*cf087682SMitchell Horne 	if (!ofw_bus_status_okay(dev))
54*cf087682SMitchell Horne 		return (ENXIO);
55*cf087682SMitchell Horne 
56*cf087682SMitchell Horne 	type = ofw_bus_search_compatible(dev, compat_data)->ocd_data;
57*cf087682SMitchell Horne 	if (type == 0)
58*cf087682SMitchell Horne 		return (ENXIO);
59*cf087682SMitchell Horne 
60*cf087682SMitchell Horne 	switch (type) {
61*cf087682SMitchell Horne 	case JH7110_SYSCON_SYS:
62*cf087682SMitchell Horne 		device_set_desc(dev, "JH7110 SYS syscon");
63*cf087682SMitchell Horne 		break;
64*cf087682SMitchell Horne 	case JH7110_SYSCON_AON:
65*cf087682SMitchell Horne 		device_set_desc(dev, "JH7110 AON syscon");
66*cf087682SMitchell Horne 		break;
67*cf087682SMitchell Horne 	case JH7110_SYSCON_STG:
68*cf087682SMitchell Horne 		device_set_desc(dev, "JH7110 STG syscon");
69*cf087682SMitchell Horne 		break;
70*cf087682SMitchell Horne 	}
71*cf087682SMitchell Horne 
72*cf087682SMitchell Horne 	return (BUS_PROBE_DEFAULT);
73*cf087682SMitchell Horne }
74*cf087682SMitchell Horne 
75*cf087682SMitchell Horne 
76*cf087682SMitchell Horne static device_method_t starfive_syscon_methods[] = {
77*cf087682SMitchell Horne 	DEVMETHOD(device_probe, starfive_syscon_probe),
78*cf087682SMitchell Horne 
79*cf087682SMitchell Horne 	DEVMETHOD_END
80*cf087682SMitchell Horne };
81*cf087682SMitchell Horne 
82*cf087682SMitchell Horne DEFINE_CLASS_1(starfive_syscon, starfive_syscon_driver, starfive_syscon_methods,
83*cf087682SMitchell Horne     sizeof(struct syscon_generic_softc), simple_mfd_driver);
84*cf087682SMitchell Horne 
85*cf087682SMitchell Horne EARLY_DRIVER_MODULE(starfive_syscon, simplebus, starfive_syscon_driver, 0, 0,
86*cf087682SMitchell Horne     BUS_PASS_BUS + BUS_PASS_ORDER_EARLY);
87*cf087682SMitchell Horne MODULE_VERSION(starfive_syscon, 1);
88