[BACK]Return to geodesc.c CVS log [TXT][DIR] Up to [local] / sys / arch / i386 / pci

Annotation of sys/arch/i386/pci/geodesc.c, Revision 1.1

1.1     ! nbrk        1: /*     $OpenBSD: geodesc.c,v 1.9 2006/12/11 20:57:40 deraadt Exp $     */
        !             2:
        !             3: /*
        !             4:  * Copyright (c) 2003 Markus Friedl <markus@openbsd.org>
        !             5:  *
        !             6:  * Permission to use, copy, modify, and distribute this software for any
        !             7:  * purpose with or without fee is hereby granted, provided that the above
        !             8:  * copyright notice and this permission notice appear in all copies.
        !             9:  *
        !            10:  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
        !            11:  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
        !            12:  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
        !            13:  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
        !            14:  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
        !            15:  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
        !            16:  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
        !            17:  */
        !            18:
        !            19: /*
        !            20:  * Geode SC1100 Information Appliance On a Chip
        !            21:  * http://www.national.com/ds.cgi/SC/SC1100.pdf
        !            22:  */
        !            23:
        !            24: #include <sys/cdefs.h>
        !            25: #include <sys/param.h>
        !            26: #include <sys/systm.h>
        !            27: #include <sys/device.h>
        !            28: #ifdef __HAVE_TIMECOUNTER
        !            29: #include <sys/timetc.h>
        !            30: #endif
        !            31:
        !            32: #include <machine/bus.h>
        !            33:
        !            34: #include <dev/pci/pcivar.h>
        !            35: #include <dev/pci/pcidevs.h>
        !            36:
        !            37: #include <arch/i386/pci/geodescreg.h>
        !            38:
        !            39: struct geodesc_softc {
        !            40:        struct device           sc_dev;
        !            41:        bus_space_tag_t         sc_iot;
        !            42:        bus_space_handle_t      sc_ioh;
        !            43: };
        !            44:
        !            45: int    geodesc_match(struct device *, void *, void *);
        !            46: void   geodesc_attach(struct device *, struct device *, void *);
        !            47: void   sc1100_sysreset(void);
        !            48:
        !            49: #ifndef SMALL_KERNEL
        !            50: int    geodesc_wdogctl_cb(void *, int);
        !            51: #endif /* SMALL_KERNEL */
        !            52:
        !            53: struct cfattach geodesc_ca = {
        !            54:        sizeof(struct geodesc_softc), geodesc_match, geodesc_attach
        !            55: };
        !            56:
        !            57: struct cfdriver geodesc_cd = {
        !            58:        NULL, "geodesc", DV_DULL
        !            59: };
        !            60:
        !            61: #ifdef __HAVE_TIMECOUNTER
        !            62: u_int   geodesc_get_timecount(struct timecounter *tc);
        !            63:
        !            64: struct timecounter geodesc_timecounter = {
        !            65:        geodesc_get_timecount,  /* get_timecount */
        !            66:        0,                      /* no poll_pps */
        !            67:        0xffffffff,             /* counter_mask */
        !            68:        27000000,               /* frequency */
        !            69:        "GEOTSC",               /* name */
        !            70:        2000                    /* quality */
        !            71: };
        !            72: #endif /* __HAVE_TIMECOUNTER */
        !            73:
        !            74: int
        !            75: geodesc_match(struct device *parent, void *match, void *aux)
        !            76: {
        !            77:        struct pci_attach_args *pa = aux;
        !            78:
        !            79:        if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_NS &&
        !            80:            (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_NS_SC1100_XBUS ||
        !            81:             PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_NS_SCx200_XBUS))
        !            82:                return (1);
        !            83:        return (0);
        !            84: }
        !            85:
        !            86: #define WDSTSBITS "\20\x04WDRST\x03WDSMI\x02WDINT\x01WDOVF"
        !            87:
        !            88: void
        !            89: geodesc_attach(struct device *parent, struct device *self, void *aux)
        !            90: {
        !            91:        struct geodesc_softc *sc = (void *) self;
        !            92:        struct pci_attach_args *pa = aux;
        !            93:        uint16_t cnfg, cba;
        !            94:        uint8_t sts, rev, iid;
        !            95:        pcireg_t reg;
        !            96:        extern void (*cpuresetfn)(void);
        !            97:
        !            98:        reg = pci_conf_read(pa->pa_pc, pa->pa_tag, SC1100_F5_SCRATCHPAD);
        !            99:        sc->sc_iot = pa->pa_iot;
        !           100:        if (reg == 0 ||
        !           101:            bus_space_map(sc->sc_iot, reg, 64, 0, &sc->sc_ioh)) {
        !           102:                printf(": unable to map registers at 0x%x\n", reg);
        !           103:                return;
        !           104:        }
        !           105:        cba = bus_space_read_2(sc->sc_iot, sc->sc_ioh, GCB_CBA);
        !           106:        if (cba != reg) {
        !           107:                printf(": cba mismatch: cba 0x%x != reg 0x%x\n", cba, reg);
        !           108:                bus_space_unmap(sc->sc_iot, sc->sc_ioh, 64);
        !           109:                return;
        !           110:        }
        !           111:        sts = bus_space_read_1(sc->sc_iot, sc->sc_ioh, GCB_WDSTS);
        !           112:        cnfg = bus_space_read_2(sc->sc_iot, sc->sc_ioh, GCB_WDCNFG);
        !           113:        iid = bus_space_read_1(sc->sc_iot, sc->sc_ioh, GCB_IID);
        !           114:        rev = bus_space_read_1(sc->sc_iot, sc->sc_ioh, GCB_REV);
        !           115:
        !           116:        printf(": iid %d revision %d wdstatus %b\n", iid, rev, sts, WDSTSBITS);
        !           117:
        !           118: #ifndef SMALL_KERNEL
        !           119:        /* setup and register watchdog */
        !           120:        bus_space_write_2(sc->sc_iot, sc->sc_ioh, GCB_WDTO, 0);
        !           121:        sts |= WDOVF_CLEAR;
        !           122:        bus_space_write_1(sc->sc_iot, sc->sc_ioh, GCB_WDSTS, sts);
        !           123:        cnfg &= ~WDCNFG_MASK;
        !           124:        cnfg |= WDTYPE1_RESET|WDPRES_DIV_512;
        !           125:        bus_space_write_2(sc->sc_iot, sc->sc_ioh, GCB_WDCNFG, cnfg);
        !           126:
        !           127:        wdog_register(sc, geodesc_wdogctl_cb);
        !           128: #endif /* SMALL_KERNEL */
        !           129:
        !           130: #ifdef __HAVE_TIMECOUNTER
        !           131:        bus_space_write_4(sc->sc_iot, sc->sc_ioh, GCB_TSCNFG, TSC_ENABLE);
        !           132:        /* Hook into the kern_tc */
        !           133:        geodesc_timecounter.tc_priv = sc;
        !           134:        tc_init(&geodesc_timecounter);
        !           135: #endif /* __HAVE_TIMECOUNTER */
        !           136:
        !           137:        /* We have a special way to reset the CPU on the SC1100 */
        !           138:        cpuresetfn = sc1100_sysreset;
        !           139: }
        !           140:
        !           141: #ifndef SMALL_KERNEL
        !           142: int
        !           143: geodesc_wdogctl_cb(void *self, int period)
        !           144: {
        !           145:        struct geodesc_softc *sc = self;
        !           146:
        !           147:        if (period > 0x03ff)
        !           148:                period = 0x03ff;
        !           149:        bus_space_write_2(sc->sc_iot, sc->sc_ioh, GCB_WDTO, period * 64);
        !           150:        return (period);
        !           151: }
        !           152: #endif /* SMALL_KERNEL */
        !           153:
        !           154: #ifdef __HAVE_TIMECOUNTER
        !           155: u_int
        !           156: geodesc_get_timecount(struct timecounter *tc)
        !           157: {
        !           158:        struct geodesc_softc *sc = tc->tc_priv;
        !           159:
        !           160:        return (bus_space_read_4(sc->sc_iot, sc->sc_ioh, GCB_TSC));
        !           161: }
        !           162: #endif /* __HAVE_TIMECOUNTER */
        !           163:
        !           164: void
        !           165: sc1100_sysreset(void)
        !           166: {
        !           167:        /*
        !           168:         * Reset AMD Geode SC1100.
        !           169:         *
        !           170:         * 1) Write PCI Configuration Address Register (0xcf8) to
        !           171:         *    select Function 0, Register 0x44: Bridge Configuration,
        !           172:         *    GPIO and LPC Configuration Register Space, Reset
        !           173:         *    Control Register.
        !           174:         *
        !           175:         * 2) Write 0xf to PCI Configuration Data Register (0xcfc)
        !           176:         *    to reset IDE controller, IDE bus, and PCI bus, and
        !           177:         *    to trigger a system-wide reset.
        !           178:         *
        !           179:         * See AMD Geode SC1100 Processor Data Book, Revision 2.0,
        !           180:         * sections 6.3.1, 6.3.2, and 6.4.1.
        !           181:         */
        !           182:        outl(0xCF8, 0x80009044UL);
        !           183:        outb(0xCFC, 0x0F);
        !           184: }

CVSweb