1 1.7 thorpej /* $NetBSD: obio_lpchc.c,v 1.7 2021/08/07 16:18:44 thorpej Exp $ */ 2 1.1 cliff 3 1.1 cliff /* 4 1.1 cliff * obio attachment for GEMINI LPC Host Controller 5 1.1 cliff */ 6 1.1 cliff #include "opt_gemini.h" 7 1.1 cliff #include "locators.h" 8 1.1 cliff 9 1.1 cliff #include <sys/cdefs.h> 10 1.7 thorpej __KERNEL_RCSID(0, "$NetBSD: obio_lpchc.c,v 1.7 2021/08/07 16:18:44 thorpej Exp $"); 11 1.1 cliff 12 1.1 cliff #include <sys/param.h> 13 1.1 cliff #include <sys/callout.h> 14 1.1 cliff #include <sys/cdefs.h> 15 1.1 cliff #include <sys/device.h> 16 1.1 cliff #include <sys/kernel.h> 17 1.1 cliff #include <sys/systm.h> 18 1.1 cliff 19 1.3 dyoung #include <sys/bus.h> 20 1.1 cliff 21 1.1 cliff #include <arm/gemini/gemini_obiovar.h> 22 1.1 cliff #include <arm/gemini/gemini_lpcvar.h> 23 1.1 cliff #include <arm/gemini/gemini_lpchcvar.h> 24 1.1 cliff #include <arm/gemini/gemini_reg.h> 25 1.1 cliff 26 1.4 chs static int gemini_lpchc_match(device_t, cfdata_t, void *); 27 1.4 chs static void gemini_lpchc_attach(device_t, device_t, void *); 28 1.1 cliff static int gemini_lpchc_print(void *, const char *); 29 1.1 cliff 30 1.2 cliff CFATTACH_DECL_NEW(obio_lpchc, sizeof(struct gemini_lpchc_softc), 31 1.1 cliff gemini_lpchc_match, gemini_lpchc_attach, NULL, NULL); 32 1.1 cliff 33 1.1 cliff 34 1.1 cliff static int 35 1.4 chs gemini_lpchc_match(device_t parent, cfdata_t cf, void *aux) 36 1.1 cliff { 37 1.1 cliff struct obio_attach_args *obio = aux; 38 1.1 cliff 39 1.1 cliff if (obio->obio_addr == OBIOCF_ADDR_DEFAULT) 40 1.1 cliff panic("geminilpchc must have addr specified in config."); 41 1.1 cliff 42 1.1 cliff if (obio->obio_addr == GEMINI_LPCHC_BASE) 43 1.1 cliff return 1; 44 1.1 cliff 45 1.1 cliff return 0; 46 1.1 cliff } 47 1.1 cliff 48 1.1 cliff static void 49 1.4 chs gemini_lpchc_attach(device_t parent, device_t self, void *aux) 50 1.1 cliff { 51 1.1 cliff gemini_lpchc_softc_t *sc = device_private(self); 52 1.1 cliff struct obio_attach_args *obio = aux; 53 1.1 cliff struct gemini_lpchc_attach_args lpchc; 54 1.1 cliff uint32_t r; 55 1.1 cliff void *ih=NULL; 56 1.1 cliff 57 1.2 cliff sc->sc_dev = self; 58 1.1 cliff sc->sc_addr = obio->obio_addr; 59 1.1 cliff sc->sc_size = (obio->obio_size == OBIOCF_SIZE_DEFAULT) 60 1.1 cliff ? GEMINI_LPCHC_SIZE : obio->obio_size; 61 1.1 cliff 62 1.1 cliff sc->sc_iot = obio->obio_iot; 63 1.1 cliff 64 1.1 cliff if (bus_space_map(sc->sc_iot, sc->sc_addr, sc->sc_size, 0, &sc->sc_ioh)) 65 1.1 cliff panic("%s: Cannot map registers", device_xname(self)); 66 1.1 cliff 67 1.1 cliff r = bus_space_read_4(sc->sc_iot, sc->sc_ioh, GEMINI_LPCHC_ID); 68 1.1 cliff aprint_normal("\n%s: device %d, rev %#x ", 69 1.1 cliff device_xname(self), _LPCHC_ID_DEVICE(r), _LPCHC_ID_REV(r)); 70 1.1 cliff 71 1.1 cliff 72 1.1 cliff sc->sc_intr = obio->obio_intr; 73 1.1 cliff if (obio->obio_intr != OBIOCF_INTR_DEFAULT) { 74 1.1 cliff ih = intr_establish(obio->obio_intr, IPL_SERIAL, 75 1.1 cliff IST_LEVEL_HIGH, gemini_lpchc_intr, sc); 76 1.1 cliff if (ih == NULL) 77 1.1 cliff panic("%s: cannot register intr %d", 78 1.1 cliff device_xname(self), obio->obio_intr); 79 1.1 cliff } 80 1.1 cliff sc->sc_ih = ih; 81 1.1 cliff 82 1.1 cliff gemini_lpchc_init(sc); 83 1.1 cliff 84 1.1 cliff aprint_normal("\n"); 85 1.1 cliff aprint_naive("\n"); 86 1.1 cliff 87 1.1 cliff lpchc.lpchc_iot = obio->obio_iot; 88 1.1 cliff lpchc.lpchc_addr = GEMINI_LPCIO_BASE; /* XXX sc_addr+offset */ 89 1.1 cliff lpchc.lpchc_size = LPCCF_SIZE_DEFAULT; /* XXX placeholder */ 90 1.1 cliff lpchc.lpchc_tag = sc; 91 1.1 cliff 92 1.6 thorpej config_found(sc->sc_dev, &lpchc, gemini_lpchc_print, 93 1.7 thorpej CFARGS(.iattr = "lpcbus")); 94 1.1 cliff } 95 1.1 cliff 96 1.1 cliff int 97 1.1 cliff gemini_lpchc_print(void *aux, const char *name) 98 1.1 cliff { 99 1.1 cliff struct gemini_lpchc_attach_args *lpchc = aux; 100 1.1 cliff 101 1.1 cliff if (lpchc->lpchc_addr != LPCCF_ADDR_DEFAULT) 102 1.1 cliff aprint_normal(" addr %#lx", lpchc->lpchc_addr); 103 1.1 cliff 104 1.1 cliff return UNCONF; 105 1.1 cliff } 106