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