1 /* $OpenBSD: exmct.c,v 1.7 2024/05/13 01:15:50 jsg Exp $ */ 2 /* 3 * Copyright (c) 2012-2013 Patrick Wildt <patrick@blueri.se> 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 22 #include <arm/cpufunc.h> 23 24 #include <machine/intr.h> 25 #include <machine/bus.h> 26 #include <machine/fdt.h> 27 28 #include <dev/ofw/openfirm.h> 29 #include <dev/ofw/fdt.h> 30 31 /* registers */ 32 #define MCT_CTRL 0x240 33 #define MCT_WRITE_STAT 0x24C 34 35 /* bits and bytes */ 36 #define MCT_CTRL_START (1 << 8) 37 38 struct exmct_softc { 39 struct device sc_dev; 40 bus_space_tag_t sc_iot; 41 bus_space_handle_t sc_ioh; 42 }; 43 44 struct exmct_softc *exmct_sc; 45 46 int exmct_match(struct device *, void *, void *); 47 void exmct_attach(struct device *, struct device *, void *); 48 49 const struct cfattach exmct_ca = { 50 sizeof (struct exmct_softc), exmct_match, exmct_attach 51 }; 52 53 struct cfdriver exmct_cd = { 54 NULL, "exmct", DV_DULL 55 }; 56 57 int 58 exmct_match(struct device *parent, void *match, void *aux) 59 { 60 struct fdt_attach_args *faa = aux; 61 62 return OF_is_compatible(faa->fa_node, "samsung,exynos4210-mct"); 63 } 64 65 void 66 exmct_attach(struct device *parent, struct device *self, void *aux) 67 { 68 struct exmct_softc *sc = (struct exmct_softc *)self; 69 struct fdt_attach_args *faa = aux; 70 uint32_t i, mask, reg; 71 72 sc->sc_iot = faa->fa_iot; 73 74 if (bus_space_map(sc->sc_iot, faa->fa_reg[0].addr, 75 faa->fa_reg[0].size, 0, &sc->sc_ioh)) 76 panic("%s: bus_space_map failed!", __func__); 77 78 printf("\n"); 79 80 exmct_sc = sc; 81 82 extern void agtimer_delay(u_int); 83 arm_clock_register(NULL, agtimer_delay, NULL, NULL); 84 85 bus_space_write_4(sc->sc_iot, sc->sc_ioh, MCT_CTRL, 86 bus_space_read_4(sc->sc_iot, sc->sc_ioh, MCT_CTRL) | MCT_CTRL_START); 87 88 mask = (1 << 16); 89 90 /* Wait 10 times until written value is applied */ 91 for (i = 0; i < 10; i++) { 92 reg = bus_space_read_4(sc->sc_iot, sc->sc_ioh, MCT_WRITE_STAT); 93 if (reg & mask) { 94 bus_space_write_4(sc->sc_iot, sc->sc_ioh, 95 MCT_WRITE_STAT, mask); 96 return; 97 } 98 cpufunc_nullop(); 99 } 100 101 /* NOTREACHED */ 102 103 panic("%s: can't enable timer!", __func__); 104 } 105