xref: /openbsd-src/sys/arch/arm64/dev/aplrtk.c (revision 44aabc179b474a8312765241465fb752139a1bb1)
1*44aabc17Skettenis /*	$OpenBSD: aplrtk.c,v 1.4 2024/10/29 21:19:25 kettenis Exp $	*/
2f1e4522dSkettenis /*
3f1e4522dSkettenis  * Copyright (c) 2022 Mark Kettenis <kettenis@openbsd.org>
4f1e4522dSkettenis  *
5f1e4522dSkettenis  * Permission to use, copy, modify, and distribute this software for any
6f1e4522dSkettenis  * purpose with or without fee is hereby granted, provided that the above
7f1e4522dSkettenis  * copyright notice and this permission notice appear in all copies.
8f1e4522dSkettenis  *
9f1e4522dSkettenis  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10f1e4522dSkettenis  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11f1e4522dSkettenis  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12f1e4522dSkettenis  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13f1e4522dSkettenis  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14f1e4522dSkettenis  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15f1e4522dSkettenis  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16f1e4522dSkettenis  */
17f1e4522dSkettenis 
18f1e4522dSkettenis #include <sys/param.h>
19f1e4522dSkettenis #include <sys/systm.h>
20f1e4522dSkettenis #include <sys/device.h>
21f1e4522dSkettenis #include <sys/malloc.h>
22f1e4522dSkettenis 
23f1e4522dSkettenis #include <machine/bus.h>
24f1e4522dSkettenis #include <machine/fdt.h>
25f1e4522dSkettenis 
26f1e4522dSkettenis #include <dev/ofw/openfirm.h>
27f1e4522dSkettenis #include <dev/ofw/ofw_misc.h>
28f1e4522dSkettenis #include <dev/ofw/fdt.h>
29f1e4522dSkettenis 
30f1e4522dSkettenis #include <arm64/dev/rtkit.h>
31f1e4522dSkettenis 
32f1e4522dSkettenis #define CPU_CTRL		0x0044
33f1e4522dSkettenis #define CPU_CTRL_RUN		(1 << 4)
34f1e4522dSkettenis 
35f1e4522dSkettenis #define HREAD4(sc, reg)							\
36f1e4522dSkettenis 	(bus_space_read_4((sc)->sc_iot, (sc)->sc_ioh, (reg)))
37f1e4522dSkettenis #define HWRITE4(sc, reg, val)						\
38f1e4522dSkettenis 	bus_space_write_4((sc)->sc_iot, (sc)->sc_ioh, (reg), (val))
39f1e4522dSkettenis 
40f1e4522dSkettenis struct aplrtk_softc {
41f1e4522dSkettenis 	struct device		sc_dev;
42f1e4522dSkettenis 	bus_space_tag_t		sc_iot;
43f1e4522dSkettenis 	bus_space_handle_t	sc_ioh;
44f1e4522dSkettenis 	bus_dma_tag_t		sc_dmat;
45f1e4522dSkettenis 
46f1e4522dSkettenis 	int			sc_node;
47f1e4522dSkettenis 	uint32_t		sc_phandle;
48f1e4522dSkettenis 
49f1e4522dSkettenis 	struct rtkit		sc_rtkit;
5064cf32f9Skettenis 	struct rtkit_state	*sc_state;
51f1e4522dSkettenis };
52f1e4522dSkettenis 
53f1e4522dSkettenis int	aplrtk_match(struct device *, void *, void *);
54f1e4522dSkettenis void	aplrtk_attach(struct device *, struct device *, void *);
55f1e4522dSkettenis 
56f1e4522dSkettenis const struct cfattach aplrtk_ca = {
57f1e4522dSkettenis 	sizeof (struct aplrtk_softc), aplrtk_match, aplrtk_attach
58f1e4522dSkettenis };
59f1e4522dSkettenis 
60f1e4522dSkettenis struct cfdriver aplrtk_cd = {
61f1e4522dSkettenis 	NULL, "aplrtk", DV_DULL
62f1e4522dSkettenis };
63f1e4522dSkettenis 
64f1e4522dSkettenis int
65f1e4522dSkettenis aplrtk_match(struct device *parent, void *match, void *aux)
66f1e4522dSkettenis {
67f1e4522dSkettenis 	struct fdt_attach_args *faa = aux;
68f1e4522dSkettenis 
69f1e4522dSkettenis 	return OF_is_compatible(faa->fa_node, "apple,rtk-helper-asc4");
70f1e4522dSkettenis }
71f1e4522dSkettenis 
72f1e4522dSkettenis void
73f1e4522dSkettenis aplrtk_attach(struct device *parent, struct device *self, void *aux)
74f1e4522dSkettenis {
75f1e4522dSkettenis 	struct aplrtk_softc *sc = (struct aplrtk_softc *)self;
76f1e4522dSkettenis 	struct fdt_attach_args *faa = aux;
77f1e4522dSkettenis 
78f1e4522dSkettenis 	if (faa->fa_nreg < 1) {
79f1e4522dSkettenis 		printf(": no registers\n");
80f1e4522dSkettenis 		return;
81f1e4522dSkettenis 	}
82f1e4522dSkettenis 
83f1e4522dSkettenis 	sc->sc_iot = faa->fa_iot;
84f1e4522dSkettenis 	if (bus_space_map(sc->sc_iot, faa->fa_reg[0].addr,
85f1e4522dSkettenis 	    faa->fa_reg[0].size, 0, &sc->sc_ioh)) {
86f1e4522dSkettenis 		printf(": can't map registers\n");
87f1e4522dSkettenis 		return;
88f1e4522dSkettenis 	}
89f1e4522dSkettenis 
90f1e4522dSkettenis 	sc->sc_dmat = faa->fa_dmat;
91f1e4522dSkettenis 	sc->sc_node = faa->fa_node;
92f1e4522dSkettenis 	sc->sc_phandle = OF_getpropint(faa->fa_node, "phandle", 0);
93f1e4522dSkettenis 
94f1e4522dSkettenis 	printf("\n");
95f1e4522dSkettenis }
96f1e4522dSkettenis 
97f1e4522dSkettenis int
98f1e4522dSkettenis aplrtk_do_start(struct aplrtk_softc *sc)
99f1e4522dSkettenis {
100f1e4522dSkettenis 	uint32_t ctrl;
101f1e4522dSkettenis 
102f1e4522dSkettenis 	ctrl = HREAD4(sc, CPU_CTRL);
103f1e4522dSkettenis 	HWRITE4(sc, CPU_CTRL, ctrl | CPU_CTRL_RUN);
104f1e4522dSkettenis 
105f1e4522dSkettenis 	sc->sc_rtkit.rk_cookie = sc;
106f1e4522dSkettenis 	sc->sc_rtkit.rk_dmat = sc->sc_dmat;
1073b6109e0Skettenis 	sc->sc_state = rtkit_init(sc->sc_node, NULL, 0, &sc->sc_rtkit);
10864cf32f9Skettenis 	if (sc->sc_state == NULL)
109f1e4522dSkettenis 		return EIO;
110f1e4522dSkettenis 
111*44aabc17Skettenis 	return rtkit_boot(sc->sc_state);
112f1e4522dSkettenis }
113f1e4522dSkettenis 
114f1e4522dSkettenis int
115f1e4522dSkettenis aplrtk_start(uint32_t phandle)
116f1e4522dSkettenis {
117f1e4522dSkettenis 	struct aplrtk_softc *sc;
118f1e4522dSkettenis 	int i;
119f1e4522dSkettenis 
120f1e4522dSkettenis 	for (i = 0; i < aplrtk_cd.cd_ndevs; i++) {
121f1e4522dSkettenis 		sc = aplrtk_cd.cd_devs[i];
122f1e4522dSkettenis 		if (sc == NULL)
123f1e4522dSkettenis 			continue;
124f1e4522dSkettenis 		if (sc->sc_phandle == phandle)
125f1e4522dSkettenis 			return aplrtk_do_start(sc);
126f1e4522dSkettenis 	}
127f1e4522dSkettenis 
128f1e4522dSkettenis 	return ENXIO;
129f1e4522dSkettenis }
130