1/* $OpenBSD: aplrtk.c,v 1.3 2022/11/09 19:18:11 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 40struct 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 53int aplrtk_match(struct device *, void *, void *); 54void aplrtk_attach(struct device *, struct device *, void *); 55 56const struct cfattach aplrtk_ca = { 57 sizeof (struct aplrtk_softc), aplrtk_match, aplrtk_attach 58}; 59 60struct cfdriver aplrtk_cd = { 61 NULL, "aplrtk", DV_DULL 62}; 63 64int 65aplrtk_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 72void 73aplrtk_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 97int 98aplrtk_do_start(struct aplrtk_softc *sc) 99{ 100 uint32_t ctrl; 101 int error; 102 103 ctrl = HREAD4(sc, CPU_CTRL); 104 HWRITE4(sc, CPU_CTRL, ctrl | CPU_CTRL_RUN); 105 106 sc->sc_rtkit.rk_cookie = sc; 107 sc->sc_rtkit.rk_dmat = sc->sc_dmat; 108 sc->sc_state = rtkit_init(sc->sc_node, NULL, 0, &sc->sc_rtkit); 109 if (sc->sc_state == NULL) 110 return EIO; 111 112 error = rtkit_boot(sc->sc_state); 113 if (error) 114 return error; 115 116 return rtkit_set_ap_pwrstate(sc->sc_state, RTKIT_MGMT_PWR_STATE_ON); 117} 118 119int 120aplrtk_start(uint32_t phandle) 121{ 122 struct aplrtk_softc *sc; 123 int i; 124 125 for (i = 0; i < aplrtk_cd.cd_ndevs; i++) { 126 sc = aplrtk_cd.cd_devs[i]; 127 if (sc == NULL) 128 continue; 129 if (sc->sc_phandle == phandle) 130 return aplrtk_do_start(sc); 131 } 132 133 return ENXIO; 134} 135