1 /* $OpenBSD: exmct.c,v 1.6 2021/10/24 17:52:27 mpi 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 void exmct_stop(void); 49 void exmct_reset(void); 50 51 const struct cfattach exmct_ca = { 52 sizeof (struct exmct_softc), exmct_match, exmct_attach 53 }; 54 55 struct cfdriver exmct_cd = { 56 NULL, "exmct", DV_DULL 57 }; 58 59 int 60 exmct_match(struct device *parent, void *match, void *aux) 61 { 62 struct fdt_attach_args *faa = aux; 63 64 return OF_is_compatible(faa->fa_node, "samsung,exynos4210-mct"); 65 } 66 67 void 68 exmct_attach(struct device *parent, struct device *self, void *aux) 69 { 70 struct exmct_softc *sc = (struct exmct_softc *)self; 71 struct fdt_attach_args *faa = aux; 72 uint32_t i, mask, reg; 73 74 sc->sc_iot = faa->fa_iot; 75 76 if (bus_space_map(sc->sc_iot, faa->fa_reg[0].addr, 77 faa->fa_reg[0].size, 0, &sc->sc_ioh)) 78 panic("%s: bus_space_map failed!", __func__); 79 80 printf("\n"); 81 82 exmct_sc = sc; 83 84 extern void agtimer_delay(u_int); 85 arm_clock_register(NULL, agtimer_delay, NULL, NULL); 86 87 bus_space_write_4(sc->sc_iot, sc->sc_ioh, MCT_CTRL, 88 bus_space_read_4(sc->sc_iot, sc->sc_ioh, MCT_CTRL) | MCT_CTRL_START); 89 90 mask = (1 << 16); 91 92 /* Wait 10 times until written value is applied */ 93 for (i = 0; i < 10; i++) { 94 reg = bus_space_read_4(sc->sc_iot, sc->sc_ioh, MCT_WRITE_STAT); 95 if (reg & mask) { 96 bus_space_write_4(sc->sc_iot, sc->sc_ioh, 97 MCT_WRITE_STAT, mask); 98 return; 99 } 100 cpufunc_nullop(); 101 } 102 103 /* NOTREACHED */ 104 105 panic("%s: can't enable timer!", __func__); 106 } 107