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