1*7a52a123Sderaadt /* $OpenBSD: cy_pci.c,v 1.5 2000/12/10 11:12:07 deraadt Exp $ */ 2ded20a09Sderaadt 3ded20a09Sderaadt /* 4ded20a09Sderaadt * cy.c 5ded20a09Sderaadt * 6ded20a09Sderaadt * Driver for Cyclades Cyclom-8/16/32 multiport serial cards 7ded20a09Sderaadt * (currently not tested with Cyclom-32 cards) 8ded20a09Sderaadt * 9ded20a09Sderaadt * Timo Rossi, 1996 10ded20a09Sderaadt * 11ded20a09Sderaadt * Supports both ISA and PCI Cyclom cards 12ded20a09Sderaadt * 13ded20a09Sderaadt * Uses CD1400 automatic CTS flow control, and 14ded20a09Sderaadt * if CY_HW_RTS is defined, uses CD1400 automatic input flow control. 15ded20a09Sderaadt * This requires a special cable that exchanges the RTS and DTR lines. 16ded20a09Sderaadt * 17ded20a09Sderaadt * Lots of debug output can be enabled by defining CY_DEBUG 18ded20a09Sderaadt * Some debugging counters (number of receive/transmit interrupts etc.) 19ded20a09Sderaadt * can be enabled by defining CY_DEBUG1 20ded20a09Sderaadt * 21ded20a09Sderaadt * This version uses the bus_mem/io_??() stuff 22ded20a09Sderaadt * 23ded20a09Sderaadt * NOT TESTED !!! 24ded20a09Sderaadt * 25ded20a09Sderaadt */ 26ded20a09Sderaadt 27ded20a09Sderaadt #undef CY_DEBUG 28ded20a09Sderaadt #undef CY_DEBUG1 29ded20a09Sderaadt 30ded20a09Sderaadt #include <sys/types.h> 31ded20a09Sderaadt #include <sys/param.h> 32ded20a09Sderaadt #include <sys/ioctl.h> 33ded20a09Sderaadt #include <sys/syslog.h> 34ded20a09Sderaadt #include <sys/fcntl.h> 35ded20a09Sderaadt #include <sys/tty.h> 36ded20a09Sderaadt #include <sys/proc.h> 37ded20a09Sderaadt #include <sys/conf.h> 38ded20a09Sderaadt #include <sys/user.h> 39ded20a09Sderaadt #include <sys/ioctl.h> 40ded20a09Sderaadt #include <sys/select.h> 41ded20a09Sderaadt #include <sys/device.h> 42ded20a09Sderaadt #include <sys/malloc.h> 43ded20a09Sderaadt #include <sys/systm.h> 44c0981ad2Sniklas #include <machine/bus.h> 45ded20a09Sderaadt #include <dev/pci/pcivar.h> 46ded20a09Sderaadt #include <dev/pci/pcireg.h> 47ded20a09Sderaadt #include <dev/pci/pcidevs.h> 48ded20a09Sderaadt 49ded20a09Sderaadt #include <dev/ic/cd1400reg.h> 50ded20a09Sderaadt #include <dev/ic/cyreg.h> 51ded20a09Sderaadt 52ded20a09Sderaadt /* Macros to clear/set/test flags. */ 53ded20a09Sderaadt #define SET(t, f) (t) |= (f) 54ded20a09Sderaadt #define CLR(t, f) (t) &= ~(f) 55ded20a09Sderaadt #define ISSET(t, f) ((t) & (f)) 56ded20a09Sderaadt 57ded20a09Sderaadt int cy_probe_pci __P((struct device *, void *, void *)); 58c0981ad2Sniklas int cy_probe_common __P((int card, bus_space_tag_t, 59c0981ad2Sniklas bus_space_handle_t, int bustype)); 60ded20a09Sderaadt 61ded20a09Sderaadt void cyattach __P((struct device *, struct device *, void *)); 62ded20a09Sderaadt 63ded20a09Sderaadt struct cfattach cy_pci_ca = { 64ded20a09Sderaadt sizeof(struct cy_softc), cy_probe_pci, cyattach 65ded20a09Sderaadt }; 66ded20a09Sderaadt 67ded20a09Sderaadt /* 68ded20a09Sderaadt * PCI probe 69ded20a09Sderaadt */ 70ded20a09Sderaadt int 71ded20a09Sderaadt cy_probe_pci(parent, match, aux) 72ded20a09Sderaadt struct device *parent; 73ded20a09Sderaadt void *match, *aux; 74ded20a09Sderaadt { 75ded20a09Sderaadt int card = ((struct device *)match)->dv_unit; 76ded20a09Sderaadt struct pci_attach_args *pa = aux; 77c0981ad2Sniklas bus_space_tag_t memt; 78c0981ad2Sniklas bus_space_handle_t memh; 79c0981ad2Sniklas bus_addr_t memaddr; 80c0981ad2Sniklas bus_size_t memsize; 81c0981ad2Sniklas bus_space_tag_t iot; 82c0981ad2Sniklas bus_space_handle_t ioh; 83c0981ad2Sniklas bus_addr_t iobase; 84c0981ad2Sniklas bus_size_t iosize; 85ded20a09Sderaadt int cacheable; 86*7a52a123Sderaadt int plx_ver; 87ded20a09Sderaadt 88ded20a09Sderaadt if(!(PCI_VENDOR(pa->pa_id) == PCI_VENDOR_CYCLADES && 89ded20a09Sderaadt (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_CYCLADES_CYCLOMY_1 || 90ded20a09Sderaadt PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_CYCLADES_CYCLOMY_2))) 91ded20a09Sderaadt return 0; 92ded20a09Sderaadt 93ded20a09Sderaadt #ifdef CY_DEBUG 94ded20a09Sderaadt printf("cy: Found Cyclades PCI device, id = 0x%x\n", pa->pa_id); 95ded20a09Sderaadt #endif 96ded20a09Sderaadt 97c0981ad2Sniklas memt = pa->pa_memt; 98c0981ad2Sniklas iot = pa->pa_iot; 99ded20a09Sderaadt 100ded20a09Sderaadt if(pci_mem_find(pa->pa_pc, pa->pa_tag, 0x18, 101ded20a09Sderaadt &memaddr, &memsize, &cacheable) != 0) { 102ded20a09Sderaadt printf("cy%d: can't find PCI card memory", card); 103ded20a09Sderaadt return 0; 104ded20a09Sderaadt } 105ded20a09Sderaadt 106ded20a09Sderaadt /* map the memory (non-cacheable) */ 107c0981ad2Sniklas if(bus_space_map(memt, memaddr, memsize, 0, &memh) != 0) { 108ded20a09Sderaadt printf("cy%d: couldn't map PCI memory region\n", card); 109ded20a09Sderaadt return 0; 110ded20a09Sderaadt } 111ded20a09Sderaadt 112ded20a09Sderaadt /* the PCI Cyclom IO space is only used for enabling interrupts */ 113ded20a09Sderaadt if(pci_io_find(pa->pa_pc, pa->pa_tag, 0x14, &iobase, &iosize) != 0) { 114c0981ad2Sniklas bus_space_unmap(memt, memh, memsize); 115ded20a09Sderaadt printf("cy%d: couldn't find PCI io region\n", card); 116ded20a09Sderaadt return 0; 117ded20a09Sderaadt } 118ded20a09Sderaadt 119562a9f8eSniklas if(bus_space_map(iot, iobase, iosize, 0, &ioh) != 0) { 120c0981ad2Sniklas bus_space_unmap(memt, memh, memsize); 121ded20a09Sderaadt printf("cy%d: couldn't map PCI io region\n", card); 122ded20a09Sderaadt return 0; 123ded20a09Sderaadt } 124ded20a09Sderaadt 125ded20a09Sderaadt #ifdef CY_DEBUG 126ded20a09Sderaadt printf("cy%d: pci mapped mem 0x%lx (size %d), io 0x%x (size %d)\n", 127ded20a09Sderaadt card, memaddr, memsize, iobase, iosize); 128ded20a09Sderaadt #endif 129ded20a09Sderaadt 130c0981ad2Sniklas if(cy_probe_common(card, memt, memh, CY_BUSTYPE_PCI) == 0) { 131c0981ad2Sniklas bus_space_unmap(memt, memh, memsize); 132c0981ad2Sniklas bus_space_unmap(iot, ioh, iosize); 133ded20a09Sderaadt printf("cy%d: PCI Cyclom card with no CD1400s!?\n", card); 134ded20a09Sderaadt return 0; 135ded20a09Sderaadt } 136ded20a09Sderaadt 137*7a52a123Sderaadt /* Get PLX version */ 138*7a52a123Sderaadt plx_ver = bus_space_read_1(memt, memh, CY_PLX_VER) & 0x0f; 139*7a52a123Sderaadt 140ded20a09Sderaadt /* Enable PCI card interrupts */ 141*7a52a123Sderaadt switch (plx_ver) { 142*7a52a123Sderaadt case CY_PLX_9050: 143*7a52a123Sderaadt bus_space_write_2(iot, ioh, CY_PCI_INTENA_9050, 144*7a52a123Sderaadt bus_space_read_2(iot, ioh, CY_PCI_INTENA_9050) | 0x40); 145*7a52a123Sderaadt break; 146*7a52a123Sderaadt case CY_PLX_9060: 147*7a52a123Sderaadt case CY_PLX_9080: 148*7a52a123Sderaadt default: 149c0981ad2Sniklas bus_space_write_2(iot, ioh, CY_PCI_INTENA, 150c0981ad2Sniklas bus_space_read_2(iot, ioh, CY_PCI_INTENA) | 0x900); 151*7a52a123Sderaadt } 152ded20a09Sderaadt return 1; 153ded20a09Sderaadt } 154