diff options
-rw-r--r-- | sys/arch/loongson/conf/GENERIC | 3 | ||||
-rw-r--r-- | sys/arch/loongson/conf/files.loongson | 6 | ||||
-rw-r--r-- | sys/arch/loongson/dev/glxclk.c | 396 | ||||
-rw-r--r-- | sys/arch/loongson/dev/mainbus.c | 8 | ||||
-rw-r--r-- | sys/arch/loongson/loongson/machdep.c | 7 | ||||
-rw-r--r-- | sys/arch/loongson/loongson/yeeloong_machdep.c | 11 | ||||
-rw-r--r-- | sys/arch/mips64/mips64/mips64_machdep.c | 5 | ||||
-rw-r--r-- | sys/dev/pci/files.pci | 4 | ||||
-rw-r--r-- | sys/dev/pci/glxpcib.c | 49 | ||||
-rw-r--r-- | sys/dev/pci/glxvar.h | 10 |
10 files changed, 483 insertions, 16 deletions
diff --git a/sys/arch/loongson/conf/GENERIC b/sys/arch/loongson/conf/GENERIC index 4a959035546..7b3e943d238 100644 --- a/sys/arch/loongson/conf/GENERIC +++ b/sys/arch/loongson/conf/GENERIC @@ -1,4 +1,4 @@ -# $OpenBSD: GENERIC,v 1.37 2012/09/27 14:01:35 jsg Exp $ +# $OpenBSD: GENERIC,v 1.38 2013/01/14 21:18:47 pirofti Exp $ # # For further information on compiling OpenBSD kernels, see the config(8) # man page. @@ -40,6 +40,7 @@ pci* at bonito? glxpcib* at pci? gpio* at glxpcib? isa0 at glxpcib? +glxclk* at glxpcib? mcclock0 at isa? port 0x70 pckbc0 at isa? # Yeeloong only pckbd* at pckbc? # Yeeloong only diff --git a/sys/arch/loongson/conf/files.loongson b/sys/arch/loongson/conf/files.loongson index 12844557fae..6b9a3dfa95c 100644 --- a/sys/arch/loongson/conf/files.loongson +++ b/sys/arch/loongson/conf/files.loongson @@ -1,4 +1,4 @@ -# $OpenBSD: files.loongson,v 1.13 2010/10/14 21:23:04 pirofti Exp $ +# $OpenBSD: files.loongson,v 1.14 2013/01/14 21:18:47 pirofti Exp $ # Standard stanzas config(8) can't run without maxpartitions 16 @@ -119,3 +119,7 @@ file arch/loongson/dev/sisfb.c sisfb needs-flag device apm attach apm at mainbus file arch/loongson/dev/apm.c apm needs-flag + +device glxclk +attach glxclk at glxpcib +file arch/loongson/dev/glxclk.c glxclk diff --git a/sys/arch/loongson/dev/glxclk.c b/sys/arch/loongson/dev/glxclk.c new file mode 100644 index 00000000000..a8c1a19f271 --- /dev/null +++ b/sys/arch/loongson/dev/glxclk.c @@ -0,0 +1,396 @@ +/* $OpenBSD: glxclk.c,v 1.1 2013/01/14 21:18:47 pirofti Exp $ */ + +/* + * Copyright (c) 2013 Paul Irofti. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <sys/param.h> +#include <sys/systm.h> +#include <sys/device.h> +#include <sys/proc.h> + +#include <machine/bus.h> +#include <machine/autoconf.h> + +#include <dev/isa/isavar.h> + +#include <dev/pci/pcireg.h> +#include <dev/pci/pcivar.h> +#include <dev/pci/pcidevs.h> + +#include <dev/pci/glxreg.h> +#include <dev/pci/glxvar.h> + +struct glxclk_softc { + struct device sc_dev; + + bus_space_tag_t sc_iot; + bus_space_handle_t sc_ioh; +}; + +struct cfdriver glxclk_cd = { + NULL, "glxclk", DV_DULL +}; + +int glxclk_match(struct device *, void *, void *); +void glxclk_attach(struct device *, struct device *, void *); +int glxclk_intr(void *); +void glxclk_startclock(struct cpu_info *); + +struct cfattach glxclk_ca = { + sizeof(struct glxclk_softc), glxclk_match, glxclk_attach, +}; + +#define MSR_LBAR_ENABLE 0x100000000ULL +#define MSR_LBAR_MFGPT DIVIL_LBAR_MFGPT +#define MSR_MFGPT_SIZE 0x40 +#define MSR_MFGPT_ADDR_MASK 0xffc0 + +#define AMD5536_MFGPT1_CMP2 0x0000000a /* Compare value for CMP2 */ +#define AMD5536_MFGPT1_CNT 0x0000000c /* Up counter */ +#define AMD5536_MFGPT1_SETUP 0x0000000e /* Setup register */ + +#define AMD5536_MFGPT_CNT_EN (1 << 15) /* Enable counting */ +#define AMD5536_MFGPT_CMP2 (1 << 14) /* Compare 2 output */ +#define AMD5536_MFGPT_CMP1 (1 << 13) /* Compare 1 output */ +#define AMD5536_MFGPT_SETUP (1 << 12) /* Set to 1 after 1st write */ +#define AMD5536_MFGPT_STOP_EN (1 << 11) /* Stop enable */ +#define AMD5536_MFGPT_CMP2MODE (1 << 9)|(1 << 8)/* Set to GE + activate IRQ */ +#define AMD5536_MFGPT_SCALE 0x7 /* Set to 128 */ +#define AMD5536_MFGPT_CLKSEL (1 << 4) /* Clock select 14MHz */ + +#define AMD5536_MFGPT1_C2_NMIM (1 << 9) /* Enable NMIs for MFGPT1 */ +#define AMD5536_MFGPT1_C2_RSTEN 0x02000000 +#define AMD5536_MFGPT1_C2_IRQM 0x00000200 +#define AMD5536_MFGPT5_C2_IRQM 0x00002000 + +struct glxclk_softc *glxclk_sc; + +int +glxclk_match(struct device *parent, void *match, void *aux) +{ + struct glxpcib_attach_args *gaa = aux; + struct cfdata *cf = match; + + if (gaa->gaa_name == NULL || strcmp(gaa->gaa_name, + cf->cf_driver->cd_name) != 0) + return 0; + + return 1; +} + +void +glxclk_attach(struct device *parent, struct device *self, void *aux) +{ + glxclk_sc = (struct glxclk_softc *)self; + struct glxpcib_attach_args *gaa = aux; + u_int64_t wa; + + glxclk_sc->sc_iot = gaa->gaa_iot; + glxclk_sc->sc_ioh = gaa->gaa_ioh; + + wa = rdmsr(MSR_LBAR_MFGPT); + + if ((wa & MSR_LBAR_ENABLE) == 0) { + printf(" not configured\n"); + return; + } + + if (bus_space_map(glxclk_sc->sc_iot, wa & MSR_MFGPT_ADDR_MASK, + MSR_MFGPT_SIZE, 0, &glxclk_sc->sc_ioh)) { + printf(" not configured\n"); + return; + } + + /* Set comparator 2 */ + bus_space_write_2(glxclk_sc->sc_iot, glxclk_sc->sc_ioh, + AMD5536_MFGPT1_CMP2, 1); + + /* Reset counter to 0 */ + bus_space_write_2(glxclk_sc->sc_iot, glxclk_sc->sc_ioh, + AMD5536_MFGPT1_CNT, 0); + + /* + * All the bits in the range 11:0 have to be written at once. + * After they're set the first time all further writes are + * ignored. + */ + uint16_t setup = (AMD5536_MFGPT_SCALE | AMD5536_MFGPT_CMP2MODE | + AMD5536_MFGPT_CMP1 | AMD5536_MFGPT_CMP2 | + AMD5536_MFGPT_CNT_EN); + + bus_space_write_2(glxclk_sc->sc_iot, glxclk_sc->sc_ioh, + AMD5536_MFGPT1_SETUP, setup); + + /* Check to see if the MFGPT_SETUP bit was set */ + setup = bus_space_read_2(glxclk_sc->sc_iot, glxclk_sc->sc_ioh, + AMD5536_MFGPT1_SETUP); + if ((setup & AMD5536_MFGPT_SETUP) == 0) { + printf(" not configured\n"); + } + + /* Enable MFGPT1 Comparator 2 Output to the Interrupt Mapper */ + wa = rdmsr(MFGPT_IRQ); + wa |= AMD5536_MFGPT1_C2_IRQM; + wrmsr(MFGPT_IRQ, wa); + + /* + * Tie PIC input 5 to IG7 for glxclk(4). + */ + wa = rdmsr(PIC_ZSEL_LOW); + wa &= ~(0xfUL << 20); + wa |= 7 << 20; + wrmsr(PIC_ZSEL_LOW, wa); + + /* Start the counter */ + setup = (AMD5536_MFGPT_CNT_EN | AMD5536_MFGPT_CMP2); + bus_space_write_2(glxclk_sc->sc_iot, glxclk_sc->sc_ioh, + AMD5536_MFGPT1_SETUP, setup); + + /* + * The interrupt argument is NULL in order to notify the dispatcher + * to pass the clock frame as argument. This trick also forces keeping + * the soft state global because during the interrupt we need to clear + * the comp2 event in the MFGPT setup register. + */ + isa_intr_establish(sys_platform->isa_chipset, 7, IST_PULSE, IPL_CLOCK, + glxclk_intr, NULL, self->dv_xname); + + md_startclock = glxclk_startclock; + + printf(": MFGPT1\n"); +} + +void +glxclk_startclock(struct cpu_info *ci) +{ + /* Start the clock. */ + int s = splclock(); + ci->ci_clock_started++; + splx(s); +} + +int +glxclk_intr(void *arg) +{ + struct clockframe *frame = arg; + uint16_t setup = 0; + struct cpu_info *ci = curcpu(); + + /* Clear the current event */ + setup = bus_space_read_2(glxclk_sc->sc_iot, glxclk_sc->sc_ioh, + AMD5536_MFGPT1_SETUP); + setup |= AMD5536_MFGPT_CMP2; + bus_space_write_2(glxclk_sc->sc_iot, glxclk_sc->sc_ioh, + AMD5536_MFGPT1_SETUP, setup); + + if (ci->ci_clock_started == 0) + return 1; + + hardclock(frame); + + return 1; +} +/* $OpenBSD: glxclk.c,v 1.1 2013/01/14 21:18:47 pirofti Exp $ */ + +/* + * Copyright (c) 2010 Paul Irofti. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <sys/param.h> +#include <sys/systm.h> +#include <sys/device.h> + +#include <machine/bus.h> +#include <machine/autoconf.h> + +#include <dev/isa/isavar.h> + +#include <dev/pci/pcireg.h> +#include <dev/pci/pcivar.h> +#include <dev/pci/pcidevs.h> + +#include <dev/pci/glxreg.h> +#include <dev/pci/glxvar.h> + +struct glxclk_softc { + struct device sc_dev; + + bus_space_tag_t sc_iot; + bus_space_handle_t sc_ioh; +}; + +struct cfdriver glxclk_cd = { + NULL, "glxclk", DV_DULL +}; + +int glxclk_match(struct device *, void *, void *); +void glxclk_attach(struct device *, struct device *, void *); +int glxclk_activate(struct device *, int); +int glxclk_intr(void *); + +struct cfattach glxclk_ca = { + sizeof(struct glxclk_softc), glxclk_match, glxclk_attach, + NULL, glxclk_activate +}; + +#define MSR_LBAR_ENABLE 0x100000000ULL +#define MSR_LBAR_MFGPT DIVIL_LBAR_MFGPT +#define MSR_MFGPT_SIZE 0x40 +#define MSR_MFGPT_ADDR_MASK 0xffc0 + +#define AMD5536_MFGPT1_CMP2 0x0000000a /* Compare value for CMP2 */ +#define AMD5536_MFGPT1_CNT 0x0000000c /* Up counter */ +#define AMD5536_MFGPT1_SETUP 0x0000000e /* Setup register */ + +#define AMD5536_MFGPT_CNT_EN (1 << 15) /* Enable counting */ +#define AMD5536_MFGPT_CMP2 (1 << 14) /* Compare 2 output */ +#define AMD5536_MFGPT_CMP1 (1 << 13) /* Compare 1 output */ +#define AMD5536_MFGPT_SETUP (1 << 12) /* Set to 1 after 1st write */ +#define AMD5536_MFGPT_STOP_EN (1 << 11) /* Stop enable */ +#define AMD5536_MFGPT_CMP2MODE (1 << 9)|(1 << 8)/* Set to GE + activate IRQ */ +#define AMD5536_MFGPT_SCALE 0x0f /* Set to 32768 */ +#define AMD5536_MFGPT_CLKSEL (1 << 4) /* Clock select 14MHz */ + +#define AMD5536_MFGPT1_C2_NMIM (1 << 9) /* Enable NMIs for MFGPT1 */ +#define AMD5536_MFGPT1_C2_RSTEN 0x02000000 +#define AMD5536_MFGPT1_C2_IRQM 0x00000200 +#define AMD5536_MFGPT5_C2_IRQM 0x00002000 + +/* XXX: overflow */ +#define MFGPT_TICK 14318000 +#define COMP2 ((MFGPT_TICK + HZ / 2) / HZ) + +int +glxclk_match(struct device *parent, void *match, void *aux) +{ + struct glxpcib_attach_args *gaa = aux; + struct cfdata *cf = match; + + if (gaa->gaa_name == NULL || strcmp(gaa->gaa_name, + cf->cf_driver->cd_name) != 0) + return 0; + + return 1; +} + +void +glxclk_attach(struct device *parent, struct device *self, void *aux) +{ + struct glxclk_softc *sc = (struct glxclk_softc *)self; + struct glxpcib_attach_args *gaa = aux; + u_int64_t wa; + + sc->sc_iot = gaa->gaa_iot; + sc->sc_ioh = gaa->gaa_ioh; + + wa = rdmsr(MSR_LBAR_MFGPT); + + if ((wa & MSR_LBAR_ENABLE) == 0) { + printf(" not configured\n"); + return; + } + + if (bus_space_map(sc->sc_iot, wa & MSR_MFGPT_ADDR_MASK, + MSR_MFGPT_SIZE, 0, &sc->sc_ioh)) { + printf(" not configured\n"); + return; + } + + /* Set comparator 2 */ + bus_space_write_2(sc->sc_iot, sc->sc_ioh, AMD5536_MFGPT1_CMP2, 0xffff); + + /* Reset counter to 0 */ + bus_space_write_2(sc->sc_iot, sc->sc_ioh, AMD5536_MFGPT1_CNT, 0); + + /* count in seconds (as upper level desires) */ + + /* + * All the bits in the range 11:0 have to be written at once. + * After they're set the first time all further writes are + * ignored. + */ + uint16_t setup = (AMD5536_MFGPT_CLKSEL | AMD5536_MFGPT_CMP2MODE | + AMD5536_MFGPT_CMP1 | AMD5536_MFGPT_CMP2 | AMD5536_MFGPT_CNT_EN); + + bus_space_write_2(sc->sc_iot, sc->sc_ioh, AMD5536_MFGPT1_SETUP, setup); + + /* Check to see if the MFGPT_SETUP bit was set */ + setup = bus_space_read_2(sc->sc_iot, sc->sc_ioh, AMD5536_MFGPT1_SETUP); + if ((setup & AMD5536_MFGPT_SETUP) == 0) { + printf(" not configured\n"); + } + +#if 0 + /* Enable NMI's for MFGPT1 */ + wa = rdmsr(MFGPT_NR); + wa |= AMD5536_MFGPT1_C2_RSTEN; + wrmsr(MFGPT_NR, wa); +#endif + + /* Enable MFGPT1 Comparator 2 Output to the Interrupt Mapper */ + wa = rdmsr(MFGPT_IRQ); + wa |= AMD5536_MFGPT1_C2_IRQM; + wrmsr(MFGPT_IRQ, wa); + + /* + * Tie PIC input 5 to IG5 for glxclk(4). + */ + wa = rdmsr(PIC_ZSEL_LOW); + wa &= ~(0xfUL << 20); + wa |= 7 << 20; + wrmsr(PIC_ZSEL_LOW, wa); + + /* Start the counter */ + setup = (AMD5536_MFGPT_CNT_EN | AMD5536_MFGPT_CMP2); + bus_space_write_2(sc->sc_iot, sc->sc_ioh, AMD5536_MFGPT1_SETUP, setup); + + isa_intr_establish(sys_platform->isa_chipset, 7, IST_PULSE, IPL_CLOCK, + glxclk_intr, sc, self->dv_xname); + + printf(": MFGPT1\n"); +} + +int +glxclk_intr(void *arg) +{ + struct glxclk_softc *sc = (struct glxclk_softc *)arg; + uint16_t setup = 0; + + /* Clear the current event */ + setup = bus_space_read_2(sc->sc_iot, sc->sc_ioh, AMD5536_MFGPT1_SETUP); + setup |= AMD5536_MFGPT_CMP2; + bus_space_write_2(sc->sc_iot, sc->sc_ioh, AMD5536_MFGPT1_SETUP, setup); + + return 1; +} + +int +glxclk_activate(struct device *self, int act) +{ + return 0; +} diff --git a/sys/arch/loongson/dev/mainbus.c b/sys/arch/loongson/dev/mainbus.c index f9d2cd1903b..b423aef7051 100644 --- a/sys/arch/loongson/dev/mainbus.c +++ b/sys/arch/loongson/dev/mainbus.c @@ -1,4 +1,4 @@ -/* $OpenBSD: mainbus.c,v 1.6 2010/09/23 14:12:05 pirofti Exp $ */ +/* $OpenBSD: mainbus.c,v 1.7 2013/01/14 21:18:47 pirofti Exp $ */ /* * Copyright (c) 2001-2003 Opsycon AB (www.opsycon.se / www.opsycon.com) @@ -71,8 +71,10 @@ mainbus_attach(struct device *parent, struct device *self, void *aux) caa.caa_maa.maa_name = "bonito"; config_found(self, &caa.caa_maa, mainbus_print); - caa.caa_maa.maa_name = "clock"; - config_found(self, &caa.caa_maa, mainbus_print); + if (md_startclock == NULL) { + caa.caa_maa.maa_name = "clock"; + config_found(self, &caa.caa_maa, mainbus_print); + } caa.caa_maa.maa_name = "apm"; config_found(self, &caa.caa_maa, mainbus_print); diff --git a/sys/arch/loongson/loongson/machdep.c b/sys/arch/loongson/loongson/machdep.c index 5c2afe19934..82f228b4855 100644 --- a/sys/arch/loongson/loongson/machdep.c +++ b/sys/arch/loongson/loongson/machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: machdep.c,v 1.39 2012/10/08 21:47:48 deraadt Exp $ */ +/* $OpenBSD: machdep.c,v 1.40 2013/01/14 21:18:47 pirofti Exp $ */ /* * Copyright (c) 2009, 2010 Miodrag Vallat. @@ -419,6 +419,11 @@ mips_init(int32_t argc, int32_t argv, int32_t envp, int32_t cv, bootcpu_hwinfo.clock = cpuspeed; /* + * MFGPT runs on powers of two, adjust the hz value accordingly. + */ + hz = 128; + + /* * Look at arguments passed to us and compute boothowto. */ diff --git a/sys/arch/loongson/loongson/yeeloong_machdep.c b/sys/arch/loongson/loongson/yeeloong_machdep.c index dba75f0c4c3..6f426fe9a61 100644 --- a/sys/arch/loongson/loongson/yeeloong_machdep.c +++ b/sys/arch/loongson/loongson/yeeloong_machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: yeeloong_machdep.c,v 1.20 2012/10/03 21:44:51 miod Exp $ */ +/* $OpenBSD: yeeloong_machdep.c,v 1.21 2013/01/14 21:18:47 pirofti Exp $ */ /* * Copyright (c) 2009, 2010 Miodrag Vallat. @@ -389,8 +389,15 @@ lemote_isa_intr(uint32_t hwpend, struct trap_frame *frame) rc = 0; for (ih = bonito_intrhand[BONITO_ISA_IRQ(bitno)]; ih != NULL; ih = ih->ih_next) { + void *arg; + splraise(ih->ih_level); - ret = (*ih->ih_fun)(ih->ih_arg); + if (ih->ih_arg != NULL) + arg = ih->ih_arg; + else + /* clock interrupt */ + arg = frame; + ret = (*ih->ih_fun)(arg); if (ret) { rc = 1; ih->ih_count.ec_count++; diff --git a/sys/arch/mips64/mips64/mips64_machdep.c b/sys/arch/mips64/mips64/mips64_machdep.c index 17eb0386186..47cf4a77431 100644 --- a/sys/arch/mips64/mips64/mips64_machdep.c +++ b/sys/arch/mips64/mips64/mips64_machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: mips64_machdep.c,v 1.8 2012/10/03 11:18:23 miod Exp $ */ +/* $OpenBSD: mips64_machdep.c,v 1.9 2013/01/14 21:18:47 pirofti Exp $ */ /* * Copyright (c) 2009, 2010, 2012 Miodrag Vallat. @@ -326,8 +326,7 @@ cpu_initclocks() { struct cpu_info *ci = curcpu(); - hz = 100; - profhz = 100; + profhz = hz; stathz = 0; /* XXX no stat clock yet */ tick = 1000000 / hz; /* number of micro-seconds between interrupts */ diff --git a/sys/dev/pci/files.pci b/sys/dev/pci/files.pci index b4af38167a9..a9359be20c1 100644 --- a/sys/dev/pci/files.pci +++ b/sys/dev/pci/files.pci @@ -1,4 +1,4 @@ -# $OpenBSD: files.pci,v 1.291 2013/01/12 13:02:22 sf Exp $ +# $OpenBSD: files.pci,v 1.292 2013/01/14 21:18:47 pirofti Exp $ # $NetBSD: files.pci,v 1.20 1996/09/24 17:47:15 christos Exp $ # # Config file and device description for machine-independent PCI code. @@ -819,7 +819,7 @@ attach itherm at pci file dev/pci/itherm.c itherm # AMD Geode CS5536 PCI-ISA bridge -device glxpcib: isabus, gpiobus, i2cbus +device glxpcib{}: isabus, gpiobus, i2cbus attach glxpcib at pci file dev/pci/glxpcib.c glxpcib diff --git a/sys/dev/pci/glxpcib.c b/sys/dev/pci/glxpcib.c index 9f89180cde7..5ae0ef9978e 100644 --- a/sys/dev/pci/glxpcib.c +++ b/sys/dev/pci/glxpcib.c @@ -1,4 +1,4 @@ -/* $OpenBSD: glxpcib.c,v 1.7 2012/10/17 22:32:01 deraadt Exp $ */ +/* $OpenBSD: glxpcib.c,v 1.8 2013/01/14 21:18:47 pirofti Exp $ */ /* * Copyright (c) 2007 Marc Balmer <mbalmer@openbsd.org> @@ -211,6 +211,8 @@ struct cfdriver glxpcib_cd = { int glxpcib_match(struct device *, void *, void *); void glxpcib_attach(struct device *, struct device *, void *); int glxpcib_activate(struct device *, int); +int glxpcib_search(struct device *, void *, void *); +int glxpcib_print(void *, const char *); struct cfattach glxpcib_ca = { sizeof(struct glxpcib_softc), glxpcib_match, glxpcib_attach, @@ -300,7 +302,8 @@ glxpcib_attach(struct device *parent, struct device *self, void *aux) /* count in seconds (as upper level desires) */ bus_space_write_2(sc->sc_iot, sc->sc_ioh, AMD5536_MFGPT0_SETUP, AMD5536_MFGPT_CNT_EN | AMD5536_MFGPT_CMP2EV | - AMD5536_MFGPT_CMP2 | AMD5536_MFGPT_DIV_MASK); + AMD5536_MFGPT_CMP2 | AMD5536_MFGPT_DIV_MASK | + AMD5536_MFGPT_STOP_EN); wdog_register(glxpcib_wdogctl_cb, sc); sc->sc_wdog = 1; printf(", watchdog"); @@ -396,6 +399,8 @@ glxpcib_attach(struct device *parent, struct device *self, void *aux) if (i2c) config_found(&sc->sc_dev, &iba, iicbus_print); #endif + + config_search(glxpcib_search, self, pa); } int @@ -684,6 +689,46 @@ glxpcib_smb_read_byte(void *arg, uint8_t *bytep, int flags) } int +glxpcib_print(void *args, const char *parentname) +{ + struct glxpcib_attach_args *gaa = (struct glxpcib_attach_args *)args; + + if (parentname != NULL) + printf("%s at %s", gaa->gaa_name, parentname); + + return UNCONF; +} + +int +glxpcib_search(struct device *parent, void *gcf, void *args) +{ + struct glxpcib_softc *sc = (struct glxpcib_softc *)parent; + struct cfdata *cf = (struct cfdata *)gcf; + struct pci_attach_args *pa = (struct pci_attach_args *)args; + struct glxpcib_attach_args gaa; + + gaa.gaa_name = cf->cf_driver->cd_name; + gaa.gaa_pa = pa; + gaa.gaa_iot = sc->sc_iot; + gaa.gaa_ioh = sc->sc_ioh; + + /* + * These devices are attached directly, either from + * glxpcib_attach() or later in time from pcib_callback(). + */ + if (strcmp(cf->cf_driver->cd_name, "gpio") == 0 || + strcmp(cf->cf_driver->cd_name, "iic") == 0 || + strcmp(cf->cf_driver->cd_name, "isa") == 0) + return 0; + + if (cf->cf_attach->ca_match(parent, cf, &gaa) == 0) + return 0; + + config_attach(parent, cf, &gaa, glxpcib_print); + return 1; +} + +int glxpcib_smb_write_byte(void *arg, uint8_t byte, int flags) { struct glxpcib_softc *sc = arg; diff --git a/sys/dev/pci/glxvar.h b/sys/dev/pci/glxvar.h index 93c80a7ccba..2eef5ced737 100644 --- a/sys/dev/pci/glxvar.h +++ b/sys/dev/pci/glxvar.h @@ -1,4 +1,4 @@ -/* $OpenBSD: glxvar.h,v 1.1 2010/10/14 21:23:05 pirofti Exp $ */ +/* $OpenBSD: glxvar.h,v 1.2 2013/01/14 21:18:47 pirofti Exp $ */ /* * Copyright (c) 2009 Miodrag Vallat. @@ -20,3 +20,11 @@ void glx_init(pci_chipset_tag_t, pcitag_t, int); uint64_t rdmsr(uint); void wrmsr(uint, uint64_t); + +struct glxpcib_attach_args { + const char *gaa_name; + + struct pci_attach_args *gaa_pa; + bus_space_tag_t gaa_iot; + bus_space_handle_t gaa_ioh; +}; |