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