diff options
author | imp <imp@FreeBSD.org> | 2003-02-14 06:21:18 +0000 |
---|---|---|
committer | imp <imp@FreeBSD.org> | 2003-02-14 06:21:18 +0000 |
commit | dd95a3a11a37cf4c36be6183eb8a6eb8fc340ed7 (patch) | |
tree | 38b7fa5367d45c7eb06ad98e5bc39bf39c8bded7 /sys/dev/exca | |
parent | 6d6e9671a534acb2aedf8ddc808b5305d35e1085 (diff) | |
download | FreeBSD-src-dd95a3a11a37cf4c36be6183eb8a6eb8fc340ed7.zip FreeBSD-src-dd95a3a11a37cf4c36be6183eb8a6eb8fc340ed7.tar.gz |
Massive overhaul of exca to help with the isa efforts:
o chip_name arrays ifdef'd out.
o use the OLDCARD-like get/put functions so we can support differnt types
of mappings.
o Write the beggings of is this a valid exca device and introduce more
chipset support.
# this is partially a wip, but also needed because some other cahnges I've
# made require some of these changes.
Diffstat (limited to 'sys/dev/exca')
-rw-r--r-- | sys/dev/exca/exca.c | 252 | ||||
-rw-r--r-- | sys/dev/exca/excareg.h | 17 | ||||
-rw-r--r-- | sys/dev/exca/excavar.h | 35 |
3 files changed, 240 insertions, 64 deletions
diff --git a/sys/dev/exca/exca.c b/sys/dev/exca/exca.c index a6d1658..7160a81 100644 --- a/sys/dev/exca/exca.c +++ b/sys/dev/exca/exca.c @@ -82,6 +82,32 @@ #define DPRINTF(fmt, args...) #endif +#if 0 +static const char *chip_names[] = +{ + "CardBus socket", + "Intel i82365SL-A/B or clone", + "Intel i82365sl-DF step", + "VLSI chip", + "Cirrus Logic PD6710", + "Cirrus logic PD6722", + "Cirrus Logic PD6729", + "Vadem 365", + "Vadem 465", + "Vadem 468", + "Vadem 469", + "Ricoh RF5C296", + "Ricoh RF5C396", + "IBM clone", + "IBM KING PCMCIA Controller" +}; +#endif + +static exca_getb_fn exca_mem_getb; +static exca_putb_fn exca_mem_putb; +static exca_getb_fn exca_io_getb; +static exca_putb_fn exca_io_putb; + /* memory */ #define EXCA_MEMINFO(NUM) { \ @@ -113,6 +139,32 @@ static struct mem_map_index_st { }; #undef EXCA_MEMINFO +static uint8_t +exca_mem_getb(struct exca_softc *sc, int reg) +{ + return (bus_space_read_1(sc->bst, sc->bsh, sc->offset + reg)); +} + +static void +exca_mem_putb(struct exca_softc *sc, int reg, uint8_t val) +{ + return (bus_space_write_1(sc->bst, sc->bsh, sc->offset + reg, val)); +} + +static uint8_t +exca_io_getb(struct exca_softc *sc, int reg) +{ + bus_space_write_1(sc->bst, sc->bsh, EXCA_REG_INDEX, reg + sc->offset); + return (bus_space_read_1(sc->bst, sc->bsh, EXCA_REG_DATA)); +} + +static void +exca_io_putb(struct exca_softc *sc, int reg, uint8_t val) +{ + bus_space_write_1(sc->bst, sc->bsh, EXCA_REG_INDEX, reg + sc->offset); + bus_space_write_1(sc->bst, sc->bsh, EXCA_REG_DATA, val); +} + /* * Helper function. This will map the requested memory slot. We setup the * map before we call this function. This is used to initially force the @@ -127,27 +179,27 @@ exca_do_mem_map(struct exca_softc *sc, int win) map = &mem_map_index[win]; mem = &sc->mem[win]; - exca_write(sc, map->sysmem_start_lsb, + exca_putb(sc, map->sysmem_start_lsb, (mem->addr >> EXCA_SYSMEM_ADDRX_SHIFT) & 0xff); - exca_write(sc, map->sysmem_start_msb, + exca_putb(sc, map->sysmem_start_msb, ((mem->addr >> (EXCA_SYSMEM_ADDRX_SHIFT + 8)) & EXCA_SYSMEM_ADDRX_START_MSB_ADDR_MASK) | 0x80); - exca_write(sc, map->sysmem_stop_lsb, + exca_putb(sc, map->sysmem_stop_lsb, ((mem->addr + mem->realsize - 1) >> EXCA_SYSMEM_ADDRX_SHIFT) & 0xff); - exca_write(sc, map->sysmem_stop_msb, + exca_putb(sc, map->sysmem_stop_msb, (((mem->addr + mem->realsize - 1) >> (EXCA_SYSMEM_ADDRX_SHIFT + 8)) & EXCA_SYSMEM_ADDRX_STOP_MSB_ADDR_MASK) | EXCA_SYSMEM_ADDRX_STOP_MSB_WAIT2); - exca_write(sc, map->sysmem_win, + exca_putb(sc, map->sysmem_win, (mem->addr >> EXCA_MEMREG_WIN_SHIFT) & 0xff); - exca_write(sc, map->cardmem_lsb, + exca_putb(sc, map->cardmem_lsb, (mem->offset >> EXCA_CARDMEM_ADDRX_SHIFT) & 0xff); - exca_write(sc, map->cardmem_msb, + exca_putb(sc, map->cardmem_msb, ((mem->offset >> (EXCA_CARDMEM_ADDRX_SHIFT + 8)) & EXCA_CARDMEM_ADDRX_MSB_ADDR_MASK) | ((mem->kind == PCCARD_MEM_ATTR) ? @@ -160,13 +212,13 @@ exca_do_mem_map(struct exca_softc *sc, int win) #ifdef EXCA_DEBUG { int r1, r2, r3, r4, r5, r6, r7; - r1 = exca_read(sc, map->sysmem_start_msb); - r2 = exca_read(sc, map->sysmem_start_lsb); - r3 = exca_read(sc, map->sysmem_stop_msb); - r4 = exca_read(sc, map->sysmem_stop_lsb); - r5 = exca_read(sc, map->cardmem_msb); - r6 = exca_read(sc, map->cardmem_lsb); - r7 = exca_read(sc, map->sysmem_win); + r1 = exca_getb(sc, map->sysmem_start_msb); + r2 = exca_getb(sc, map->sysmem_start_lsb); + r3 = exca_getb(sc, map->sysmem_stop_msb); + r4 = exca_getb(sc, map->sysmem_stop_lsb); + r5 = exca_getb(sc, map->cardmem_msb); + r6 = exca_getb(sc, map->cardmem_lsb); + r7 = exca_getb(sc, map->sysmem_win); printf("exca_do_mem_map window %d: %02x%02x %02x%02x " "%02x%02x %02x (%08x+%08x.%08x*%08lx)\n", win, r1, r2, r3, r4, r5, r6, r7, @@ -385,11 +437,11 @@ exca_do_io_map(struct exca_softc *sc, int win) map = &io_map_index[win]; io = &sc->io[win]; - exca_write(sc, map->start_lsb, io->addr & 0xff); - exca_write(sc, map->start_msb, (io->addr >> 8) & 0xff); + exca_putb(sc, map->start_lsb, io->addr & 0xff); + exca_putb(sc, map->start_msb, (io->addr >> 8) & 0xff); - exca_write(sc, map->stop_lsb, (io->addr + io->size - 1) & 0xff); - exca_write(sc, map->stop_msb, ((io->addr + io->size - 1) >> 8) & 0xff); + exca_putb(sc, map->stop_lsb, (io->addr + io->size - 1) & 0xff); + exca_putb(sc, map->stop_msb, ((io->addr + io->size - 1) >> 8) & 0xff); exca_clrb(sc, EXCA_IOCTL, map->ioctlmask); exca_setb(sc, EXCA_IOCTL, map->ioctlbits[io->width]); @@ -398,10 +450,10 @@ exca_do_io_map(struct exca_softc *sc, int win) #ifdef EXCA_DEBUG { int r1, r2, r3, r4; - r1 = exca_read(sc, map->start_msb); - r2 = exca_read(sc, map->start_lsb); - r3 = exca_read(sc, map->stop_msb); - r4 = exca_read(sc, map->stop_lsb); + r1 = exca_getb(sc, map->start_msb); + r2 = exca_getb(sc, map->start_lsb); + r3 = exca_getb(sc, map->stop_msb); + r4 = exca_getb(sc, map->stop_lsb); DPRINTF("exca_do_io_map window %d: %02x%02x %02x%02x " "(%08x+%08x)\n", win, r1, r2, r3, r4, io->addr, io->size); @@ -498,14 +550,14 @@ exca_wait_ready(struct exca_softc *sc) { int i; DEVPRINTF(sc->dev, "exca_wait_ready: status 0x%02x\n", - exca_read(sc, EXCA_IF_STATUS)); + exca_getb(sc, EXCA_IF_STATUS)); for (i = 0; i < 10000; i++) { - if (exca_read(sc, EXCA_IF_STATUS) & EXCA_IF_STATUS_READY) + if (exca_getb(sc, EXCA_IF_STATUS) & EXCA_IF_STATUS_READY) return; DELAY(500); } device_printf(sc->dev, "ready never happened, status = %02x\n", - exca_read(sc, EXCA_IF_STATUS)); + exca_getb(sc, EXCA_IF_STATUS)); } /* @@ -530,7 +582,7 @@ exca_reset(struct exca_softc *sc, device_t child) /* enable socket i/o */ exca_setb(sc, EXCA_PWRCTL, EXCA_PWRCTL_OE); - exca_write(sc, EXCA_INTR, EXCA_INTR_ENABLE); + exca_putb(sc, EXCA_INTR, EXCA_INTR_ENABLE); /* hold reset for 30ms */ DELAY(30*1000); /* clear the reset flag */ @@ -541,7 +593,7 @@ exca_reset(struct exca_softc *sc, device_t child) exca_wait_ready(sc); /* disable all address windows */ - exca_write(sc, EXCA_ADDRWIN_ENABLE, 0); + exca_putb(sc, EXCA_ADDRWIN_ENABLE, 0); CARD_GET_TYPE(child, &cardtype); exca_setb(sc, EXCA_INTR, (cardtype == PCCARD_IFTYPE_IO) ? @@ -572,6 +624,114 @@ exca_init(struct exca_softc *sc, device_t dev, sc->bsh = bsh; sc->offset = offset; sc->flags = 0; + sc->getb = exca_mem_getb; + sc->putb = exca_mem_putb; +} + +/* + * Is this socket valid? + */ +static int +exca_valid_slot(struct exca_softc *exca) +{ + uint8_t c; + + /* + * see if there's a PCMCIA controller here + * Intel PCMCIA controllers use 0x82 and 0x83 + * IBM clone chips use 0x88 and 0x89, apparently + */ + c = exca_getb(exca, EXCA_IDENT); + if ((c & EXCA_IDENT_IFTYPE_MASK) != EXCA_IDENT_IFTYPE_MEM_AND_IO) + return (0); + if ((c & EXCA_IDENT_ZERO) != 0) + return (0); + switch (c & EXCA_IDENT_REV_MASK) { + /* + * 82365 or clones. + */ + case EXCA_IDENT_REV_I82365SLR0: + case EXCA_IDENT_REV_I82365SLR1: + exca->chipset = EXCA_I82365; + /* + * Check for Vadem chips by unlocking their extra + * registers and looking for valid ID. Bit 3 in + * the ID register is normally 0, except when + * EXCA_VADEMREV is set. Other bridges appear + * to ignore this frobbing. + */ + bus_space_write_1(exca->bst, exca->bsh, EXCA_REG_INDEX, + EXCA_VADEM_COOKIE1); + bus_space_write_1(exca->bst, exca->bsh, EXCA_REG_INDEX, + EXCA_VADEM_COOKIE2); + exca_setb(exca, EXCA_VADEM_VMISC, EXCA_VADEM_REV); + c = exca_getb(exca, EXCA_IDENT); + if (c & 0x08) { + switch (c & 7) { + case 1: + exca->chipset = EXCA_VG365; + break; + case 2: + exca->chipset = EXCA_VG465; + break; + case 3: + exca->chipset = EXCA_VG468; + break; + default: + exca->chipset = EXCA_VG469; + break; + } + exca_clrb(exca, EXCA_VADEM_VMISC, EXCA_VADEM_REV); + break; + } + /* + * Check for RICOH RF5C[23]96 PCMCIA Controller + */ + c = exca_getb(exca, EXCA_RICOH_ID); + if (c == EXCA_RID_396) { + exca->chipset = EXCA_RF5C396; + break; + } else if (c == EXCA_RID_296) { + exca->chipset = EXCA_RF5C296; + break; + } + /* + * Check for Cirrus logic chips. + */ + exca_putb(exca, EXCA_CIRRUS_CHIP_INFO, 0); + c = exca_getb(exca, EXCA_CIRRUS_CHIP_INFO); + if ((c & EXCA_CIRRUS_CHIP_INFO_CHIP_ID) == + EXCA_CIRRUS_CHIP_INFO_CHIP_ID) { + c = exca_getb(exca, EXCA_CIRRUS_CHIP_INFO); + if ((c & EXCA_CIRRUS_CHIP_INFO_CHIP_ID) == 0) { + if (c & EXCA_CIRRUS_CHIP_INFO_SLOTS) + exca->chipset = EXCA_PD6722; + else + exca->chipset = EXCA_PD6710; + break; + } + } + break; + + case EXCA_IDENT_REV_I82365SLDF: + /* + * Intel i82365sl-DF step or maybe a vlsi 82c146 + * we detected the vlsi case earlier, so if the controller + * isn't set, we know it is a i82365sl step D. + */ + exca->chipset = EXCA_I82365SL_DF; + break; + case EXCA_IDENT_REV_IBM1: + case EXCA_IDENT_REV_IBM2: + exca->chipset = EXCA_IBM; + break; + case EXCA_IDENT_REV_IBM_KING: + exca->chipset = EXCA_IBM_KING; + break; + default: + return (0); + } + return (1); } /* @@ -579,49 +739,31 @@ exca_init(struct exca_softc *sc, device_t dev, * slots too while we're at it. But maybe that belongs to a separate * function. * - * Callers must charantee that there are at least EXCA_NSLOTS (4) in - * the array that they pass the address of the first element in the - * "exca" parameter. + * The caller must guarantee that at least EXCA_NSLOTS are present in exca. */ int -exca_probe_slots(device_t dev, struct exca_softc *exca) +exca_probe_slots(device_t dev, struct exca_softc *exca, bus_space_tag_t iot, + bus_space_handle_t ioh) { - int rid; - struct resource *res; int err; - bus_space_tag_t iot; - bus_space_handle_t ioh; int i; err = ENXIO; - rid = 0; - res = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid, 0, ~0, EXCA_IOSIZE, - RF_ACTIVE); - if (res == NULL) - return (ENXIO); - iot = rman_get_bustag(res); - ioh = rman_get_bushandle(res); - for (i = 0; i < EXCA_NSLOTS; i++) { + for (i = 0; i < EXCA_NSLOTS; i++) { exca_init(&exca[i], dev, iot, ioh, i * EXCA_SOCKET_SIZE); - if (exca_is_pcic(&exca[i])) { + exca->getb = exca_io_getb; + exca->putb = exca_io_putb; + if (exca_valid_slot(&exca[i])) err = 0; - exca[i].flags |= EXCA_SOCKET_PRESENT; - } } - bus_release_resource(dev, SYS_RES_IOPORT, rid, res); return (err); } -int -exca_is_pcic(struct exca_softc *sc) -{ - /* XXX */ - return (0); -} - -static int exca_modevent(module_t mod, int cmd, void *arg) +static int +exca_modevent(module_t mod, int cmd, void *arg) { return 0; } + DEV_MODULE(exca, exca_modevent, NULL); MODULE_VERSION(exca, 1); diff --git a/sys/dev/exca/excareg.h b/sys/dev/exca/excareg.h index 14e95df..bb03ace 100644 --- a/sys/dev/exca/excareg.h +++ b/sys/dev/exca/excareg.h @@ -101,8 +101,12 @@ #define EXCA_IDENT_IFTYPE_RESERVED 0xC0 #define EXCA_IDENT_ZERO 0x30 #define EXCA_IDENT_REV_MASK 0x0F -#define EXCA_IDENT_REV_I82365SLR0 0x02 -#define EXCA_IDENT_REV_I82365SLR1 0x03 +#define EXCA_IDENT_REV_I82365SLR0 0x02 /* step a/b */ +#define EXCA_IDENT_REV_I82365SLR1 0x03 /* step c */ +#define EXCA_IDENT_REV_I82365SLDF 0x04 /* step df */ +#define EXCA_IDENT_REV_IBM1 0x08 /* ibm clone */ +#define EXCA_IDENT_REV_IBM2 0x09 /* ibm clone */ +#define EXCA_IDENT_REV_IBM_KING 0x0a /* ibm king */ #define EXCA_IF_STATUS 0x01 /* RO */ #define EXCA_IF_STATUS_GPI 0x80 /* General Purpose Input */ @@ -382,6 +386,15 @@ #define EXCA_CIRRUS_EXT_CONTROL_1 0x03 #define EXCA_CIRRUS_EXT_CONTROL_1_PCI_INTR_MASK 0x18 +#define EXCA_VADEM_VMISC 0x3a +#define EXCA_VADEM_REV 0x40 +#define EXCA_VADEM_COOKIE1 0x0E +#define EXCA_VADEM_COOKIE2 0x37 + +#define EXCA_RICOH_ID 0x3a +#define EXCA_RID_296 0x32 +#define EXCA_RID_396 0xb2 + /* Plug and play */ #define EXCA_PNP_ACTIONTEC 0x1802A904 /* AEI0218 */ #define EXCA_PNP_IBM3765 0x65374d24 /* IBM3765 */ diff --git a/sys/dev/exca/excavar.h b/sys/dev/exca/excavar.h index 327292c..2f6aca5 100644 --- a/sys/dev/exca/excavar.h +++ b/sys/dev/exca/excavar.h @@ -61,6 +61,8 @@ * Structure to manage the ExCA part of the chip. */ struct exca_softc; +typedef uint8_t (exca_getb_fn)(struct exca_softc *, int); +typedef void (exca_putb_fn)(struct exca_softc *, int, uint8_t); struct exca_softc { @@ -75,6 +77,24 @@ struct exca_softc #define EXCA_SOCKET_PRESENT 0x00000001 #define EXCA_HAS_MEMREG_WIN 0x00000002 uint32_t offset; + int chipset; +#define EXCA_CARDBUS 0 +#define EXCA_I82365 1 /* Intel i82365SL-A/B or clone */ +#define EXCA_I82365SL_DF 2 /* Intel i82365sl-DF step */ +#define EXCA_VLSI 3 /* VLSI chip */ +#define EXCA_PD6710 4 /* Cirrus logic PD6710 */ +#define EXCA_PD6722 5 /* Cirrus logic PD6722 */ +#define EXCA_PD6729 6 /* Cirrus Logic PD6729 */ +#define EXCA_VG365 7 /* Vadem 365 */ +#define EXCA_VG465 8 /* Vadem 465 */ +#define EXCA_VG468 9 /* Vadem 468 */ +#define EXCA_VG469 10 /* Vadem 469 */ +#define EXCA_RF5C296 11 /* Ricoh RF5C296 */ +#define EXCA_RF5C396 12 /* Ricoh RF5C396 */ +#define EXCA_IBM 13 /* IBM clone */ +#define EXCA_IBM_KING 14 /* IBM KING PCMCIA Controller */ + exca_getb_fn *getb; + exca_putb_fn *putb; }; void exca_init(struct exca_softc *sc, device_t dev, @@ -88,31 +108,32 @@ int exca_mem_set_flags(struct exca_softc *sc, struct resource *res, int exca_mem_set_offset(struct exca_softc *sc, struct resource *res, uint32_t cardaddr, uint32_t *deltap); int exca_mem_unmap_res(struct exca_softc *sc, struct resource *res); -int exca_probe_slots(device_t dev, struct exca_softc *); +int exca_probe_slots(device_t dev, struct exca_softc *exca, + bus_space_tag_t iot, bus_space_handle_t ioh); void exca_reset(struct exca_softc *, device_t child); static __inline uint8_t -exca_read(struct exca_softc *sc, int reg) +exca_getb(struct exca_softc *sc, int reg) { - return (bus_space_read_1(sc->bst, sc->bsh, sc->offset + reg)); + return (sc->getb(sc, reg)); } static __inline void -exca_write(struct exca_softc *sc, int reg, uint8_t val) +exca_putb(struct exca_softc *sc, int reg, uint8_t val) { - bus_space_write_1(sc->bst, sc->bsh, sc->offset + reg, val); + sc->putb(sc, reg, val); } static __inline void exca_setb(struct exca_softc *sc, int reg, uint8_t mask) { - exca_write(sc, reg, exca_read(sc, reg) | mask); + exca_putb(sc, reg, exca_getb(sc, reg) | mask); } static __inline void exca_clrb(struct exca_softc *sc, int reg, uint8_t mask) { - exca_write(sc, reg, exca_read(sc, reg) & ~mask); + exca_putb(sc, reg, exca_getb(sc, reg) & ~mask); } #endif /* !_SYS_DEV_EXCA_EXCAVAR_H */ |