diff options
author | Dale Rahn <drahn@cvs.openbsd.org> | 2003-06-05 05:17:05 +0000 |
---|---|---|
committer | Dale Rahn <drahn@cvs.openbsd.org> | 2003-06-05 05:17:05 +0000 |
commit | be41fa0de43abfa7a51f476c6d90897a9314a97b (patch) | |
tree | 8e26b1cad2339f315e9f06ebf42cb39a4ac4265c /sys/arch/macppc | |
parent | a08a6093e43c6e356f025a4d809206c547c99f04 (diff) |
ATA100 driver for apple's new machines, aka kauai.
This is working with udma on a 12" PBG4, but dma is disabled for now,
too many hardcoded values. 'wdc...flags 0x1' will enable it.
Diffstat (limited to 'sys/arch/macppc')
-rw-r--r-- | sys/arch/macppc/conf/GENERIC | 4 | ||||
-rw-r--r-- | sys/arch/macppc/conf/RAMDISK | 4 | ||||
-rw-r--r-- | sys/arch/macppc/conf/files.macppc | 11 | ||||
-rw-r--r-- | sys/arch/macppc/dev/wdc_obio.c | 145 | ||||
-rw-r--r-- | sys/arch/macppc/pci/kauaiata.c | 162 |
5 files changed, 319 insertions, 7 deletions
diff --git a/sys/arch/macppc/conf/GENERIC b/sys/arch/macppc/conf/GENERIC index 989a865a3d6..6b0b5bcdead 100644 --- a/sys/arch/macppc/conf/GENERIC +++ b/sys/arch/macppc/conf/GENERIC @@ -1,4 +1,4 @@ -# $OpenBSD: GENERIC,v 1.43 2003/05/02 00:53:27 jason Exp $g +# $OpenBSD: GENERIC,v 1.44 2003/06/05 05:17:04 drahn Exp $g # # PPC GENERIC config file # @@ -54,6 +54,8 @@ ahc* at pci? dev ? function ? # Adaptec 294x, aic78x0 SCSI #ami* at pci? dev ? function ? #pcscp* at pci? dev ? function ? # AMD Am53c974 PCscsi-PCI SCSI pciide* at pci? dev ? function ? +kauaiata* at pci? dev ? function ? # Apple ATA 100 +wdc* at kauaiata? flags 0x0 macobio0 at pci? dev ? function ? gem* at pci? dev ? function ? # GMAC ethernet hme* at pci? dev ? function ? # HME ethernet diff --git a/sys/arch/macppc/conf/RAMDISK b/sys/arch/macppc/conf/RAMDISK index 4da29e9a955..22541450e8b 100644 --- a/sys/arch/macppc/conf/RAMDISK +++ b/sys/arch/macppc/conf/RAMDISK @@ -1,4 +1,4 @@ -# $OpenBSD: RAMDISK,v 1.22 2003/03/21 15:06:43 drahn Exp $ +# $OpenBSD: RAMDISK,v 1.23 2003/06/05 05:17:04 drahn Exp $ # # PPC GENERIC config file # @@ -55,6 +55,8 @@ ahc* at pci? dev ? function ? # Adaptec 294x, aic78x0 SCSI #bha* at pci? dev ? function ? # BusLogic 9xx SCSI #pcscp* at pci? dev ? function ? # AMD Am53c974 PCscsi-PCI SCSI pciide* at pci? dev ? function ? +kauaiata* at pci? dev ? function ? # Apple ATA 100 +wdc* at kauaiata? flags 0x0 macobio0 at pci? dev ? function ? gem* at pci? dev ? function ? # GMAC ethernet hme* at pci? dev ? function ? # HME ethernet diff --git a/sys/arch/macppc/conf/files.macppc b/sys/arch/macppc/conf/files.macppc index 17d5829c9df..9824b10baae 100644 --- a/sys/arch/macppc/conf/files.macppc +++ b/sys/arch/macppc/conf/files.macppc @@ -1,4 +1,4 @@ -# $OpenBSD: files.macppc,v 1.16 2002/09/14 11:02:09 deraadt Exp $ +# $OpenBSD: files.macppc,v 1.17 2003/06/05 05:17:04 drahn Exp $ # # macppc-specific configuration info @@ -104,6 +104,12 @@ device macobio {} attach macobio at pci file arch/macppc/pci/macobio.c macobio + +# kauai ATA glue +device kauaiata {} +attach kauaiata at pci +file arch/macppc/pci/kauaiata.c kauaiata needs-flag + #device esp: scsi, ncr53c9x #attach esp at macobio #file arch/macppc/dev/esp.c esp @@ -177,7 +183,7 @@ attach gpio at macobio with gpio_obio attach gpio at gpio with gpio_gpio file arch/macppc/dev/gpio.c gpio -attach wdc at macobio with wdc_obio +attach wdc at macobio, kauaiata with wdc_obio file arch/macppc/dev/wdc_obio.c wdc_obio attach wi at macobio with wi_obio @@ -195,7 +201,6 @@ file arch/macppc/pci/vgafb.c vgafb & vgafb_pci attach vgafb at pci with vgafb_pci file arch/macppc/pci/vgafb_pci.c vgafb_pci needs-flag - # # CARDBUS # diff --git a/sys/arch/macppc/dev/wdc_obio.c b/sys/arch/macppc/dev/wdc_obio.c index 722e997b614..18fd2a5ac32 100644 --- a/sys/arch/macppc/dev/wdc_obio.c +++ b/sys/arch/macppc/dev/wdc_obio.c @@ -1,4 +1,4 @@ -/* $OpenBSD: wdc_obio.c,v 1.8 2002/09/15 09:01:58 deraadt Exp $ */ +/* $OpenBSD: wdc_obio.c,v 1.9 2003/06/05 05:17:04 drahn Exp $ */ /* $NetBSD: wdc_obio.c,v 1.15 2001/07/25 20:26:33 bouyer Exp $ */ /*- @@ -106,6 +106,7 @@ void wdc_obio_dma_start(void *, int, int); int wdc_obio_dma_finish(void *, int, int); void wdc_obio_adjust_timing(struct channel_softc *); void wdc_obio_ata4_adjust_timing(struct channel_softc *); +void wdc_obio_ata6_adjust_timing(struct channel_softc *); int wdc_obio_probe(parent, match, aux) @@ -178,6 +179,9 @@ wdc_obio_attach(parent, self, aux) cmdbase = ca->ca_reg[0]; cmdsize = ca->ca_reg[1]; + printf("wdc_obio map %x %x %x %x\n", cmdbase, cmdsize, ca->ca_reg[2], + ca->ca_reg[2]); + if (bus_space_map(chp->cmd_iot, cmdbase, cmdsize, 0, &chp->cmd_ioh) || bus_space_subregion(chp->cmd_iot, chp->cmd_ioh, /* WDC_AUXREG_OFFSET<<4 */ 0x160, 1, &chp->ctl_ioh)) @@ -196,8 +200,10 @@ wdc_obio_attach(parent, self, aux) if (use_dma) { sc->sc_dbdma = dbdma_alloc(sc->sc_dmat, WDC_DMALIST_MAX + 1); sc->sc_dmacmd = sc->sc_dbdma->d_addr; + sc->sc_dmareg = mapiodev(ca->ca_baseaddr + ca->ca_reg[2], - ca->ca_reg[3]); + ca->ca_reg[3]); + sc->sc_wdcdev.cap |= WDC_CAPABILITY_DMA; sc->sc_wdcdev.DMA_cap = 2; if (strcmp(ca->ca_name, "ata-4") == 0) { @@ -206,6 +212,12 @@ wdc_obio_attach(parent, self, aux) sc->sc_wdcdev.UDMA_cap = 4; sc->sc_wdcdev.set_modes = wdc_obio_ata4_adjust_timing; } + if (strcmp(ca->ca_name, "ata-6") == 0) { + sc->sc_wdcdev.cap |= WDC_CAPABILITY_UDMA | + WDC_CAPABILITY_MODE; + sc->sc_wdcdev.UDMA_cap = 6; + sc->sc_wdcdev.set_modes = wdc_obio_ata6_adjust_timing; + } } sc->sc_wdcdev.cap |= WDC_CAPABILITY_DATA16; sc->sc_wdcdev.PIO_cap = 4; @@ -259,6 +271,53 @@ static const struct ide_timings udma_timing[] = { { 25, 100} /* Mode 4 */ }; +/* these number _guessed_ from linux driver. */ +static u_int32_t kauai_pio_timing[] = { + #if 0 + /*120*/ 0x04000148, /* Mode 0 */ + /*180*/ 0x05000249, /* Mode 1 */ + /*240*/ 0x0800038b, /* Mode 2 */ + /*360*/ 0x08000392, /* Mode 3 */ + /*600*/ 0x08000a92 /* Mode 4 */ + #endif + /*120*/ 0x06000246, /* Mode 0 */ + /*180*/ 0x06000246, /* Mode 1 */ + /*240*/ 0x06000246, /* Mode 2 */ + /*360*/ 0x06000246, /* Mode 3 */ + /*600*/ 0x06000246 /* Mode 4 */ + +}; +static u_int32_t kauai_dma_timing[] = { + #if 0 + /*120*/ 0x00148000, /* Mode 0 */ + /*150*/ 0x00209000, /* Mode 1 */ + /*240*/ 0x0030c000, /* Mode 2 */ + /*360*/ 0x00492000, /* Mode 3 */ + /*480*/ 0x00618000 /* Mode 4 */ + #endif + /*120*/ 0x00149000, /* Mode 0 */ + /*150*/ 0x00149000, /* Mode 1 */ + /*240*/ 0x00149000, /* Mode 2 */ + /*360*/ 0x00149000, /* Mode 3 */ + /*480*/ 0x00149000 /* Mode 4 */ +}; +static u_int32_t kauai_udma_timing[] = { + #if 0 + /* 20*/ 0x00002921, /* Mode 0 */ + /* 30*/ 0x00002a30, /* Mode 1 */ + /* 45*/ 0x00003a50, /* Mode 2 */ + /* 60*/ 0x00004a60, /* Mode 3 */ + /* 90*/ 0x00005d80, /* Mode 4 */ + /*120*/ 0x000070c0 /* Mode 5 */ + #endif + /* 20*/ 0x00002921, /* Mode 0 */ + /* 30*/ 0x00002921, /* Mode 1 */ + /* 45*/ 0x00002921, /* Mode 2 */ + /* 60*/ 0x00002921, /* Mode 3 */ + /* 90*/ 0x00002921, /* Mode 4 */ + /*120*/ 0x00002921 /* Mode 5 */ +}; + #define TIME_TO_TICK(time) howmany((time), 30) #define PIO_REC_OFFSET 4 #define PIO_REC_MIN 1 @@ -270,6 +329,15 @@ static const struct ide_timings udma_timing[] = { #define ATA4_TIME_TO_TICK(time) howmany((time) * 1000, 7500) #define CONFIG_REG (0x200) /* IDE access timing register */ +#define CONFIG_REG (0x200) /* IDE access timing register */ +#define KAUAI_ULTRA_CONFIG (0x210) /* secondary config register (kauai)*/ + +#define KAUAI_PIO_MASK 0xff000fff +#define KAUAI_DMA_MASK 0x00fff000 +#define KAUAI_UDMA_MASK 0x0000ffff +#define KAUAI_UDMA_EN 0x00000001 + + void wdc_obio_adjust_timing(chp) @@ -425,6 +493,79 @@ wdc_obio_ata4_adjust_timing(chp) #endif } +void +wdc_obio_ata6_adjust_timing(struct channel_softc *chp) +{ + struct ata_drive_datas *drvp; + u_int conf, conf1; + int drive; + int piomode = -1, dmamode = -1; + int udmamode = -1; + + + for (drive = 0; drive < 2; drive++) { + drvp = &chp->ch_drive[drive]; + if ((drvp->drive_flags & DRIVE) == 0) + continue; + if (piomode == -1 || piomode > drvp->PIO_mode) + piomode = drvp->PIO_mode; + if (drvp->drive_flags & DRIVE_DMA) { + if (dmamode == -1 || dmamode > drvp->DMA_mode) + dmamode = drvp->DMA_mode; + } + if (drvp->drive_flags & DRIVE_UDMA) { + if (udmamode == -1 || udmamode > drvp->UDMA_mode) + udmamode = drvp->UDMA_mode; + } else { + udmamode = -2; + } + } + if (piomode == -1) + return; /* No drive */ + for (drive = 0; drive < 2; drive++) { + drvp = &chp->ch_drive[drive]; + if (drvp->drive_flags & DRIVE) { + drvp->PIO_mode = piomode; + if (drvp->drive_flags & DRIVE_DMA) + drvp->DMA_mode = dmamode; + if (drvp->drive_flags & DRIVE_UDMA) { + if (udmamode == -2) { + drvp->drive_flags &= ~DRIVE_UDMA; + } else { + drvp->UDMA_mode = udmamode; + } + } + } + } + + if (udmamode == -2) + udmamode = -1; + + + conf = bus_space_read_4(chp->cmd_iot, chp->cmd_ioh, CONFIG_REG); + conf1 = bus_space_read_4(chp->cmd_iot, chp->cmd_ioh, + KAUAI_ULTRA_CONFIG); + + printf("ata6 conf old: 0x%x, %x", conf, conf1); + conf = (conf & ~KAUAI_PIO_MASK) | kauai_pio_timing[piomode]; + + if (dmamode != -1) { + conf = (conf & ~KAUAI_DMA_MASK) | kauai_dma_timing[dmamode]; + } + if (udmamode != -1) { + conf1 = (conf1 & ~KAUAI_UDMA_MASK) | + kauai_udma_timing[udmamode] | KAUAI_UDMA_EN; + } else + conf1 = conf1 & ~KAUAI_UDMA_EN; + + bus_space_write_4(chp->cmd_iot, chp->cmd_ioh, CONFIG_REG, conf); + bus_space_write_4(chp->cmd_iot, chp->cmd_ioh, KAUAI_ULTRA_CONFIG, + conf1); +#if 1 + printf("new : 0x%x, %x\n", conf, conf1); +#endif +} + int wdc_obio_dma_init(v, channel, drive, databuf, datalen, read) void *v; diff --git a/sys/arch/macppc/pci/kauaiata.c b/sys/arch/macppc/pci/kauaiata.c new file mode 100644 index 00000000000..c325a0e2d1b --- /dev/null +++ b/sys/arch/macppc/pci/kauaiata.c @@ -0,0 +1,162 @@ +/* $OpenBSD: kauaiata.c,v 1.1 2003/06/05 05:17:04 drahn Exp $ */ + +/* + * Copyright (c) 2003 Dale Rahn + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + */ + +/* + * Glue to to attach kauai ata to the macobio_wdc + * which it heavily resembles. + */ + +#include <sys/types.h> +#include <sys/param.h> +#include <sys/systm.h> +#include <sys/device.h> + +#include <machine/bus.h> + +#include <dev/pci/pcivar.h> +#include <dev/pci/pcireg.h> +#include <dev/pci/pcidevs.h> + +#include <dev/ofw/openfirm.h> + +#include <machine/autoconf.h> + + +struct kauaiata_softc { + struct device sc_dev; + struct ppc_bus_space sc_membus_space; + /* XXX */ +}; + +int kauaiatamatch(struct device *parent, void *match, void *aux); +void kauaiataattach(struct device *parent, struct device *self, void *aux); +int kauaiata_print(void *aux, const char *dev); + + +struct cfattach kauaiata_ca = { + sizeof(struct kauaiata_softc), kauaiatamatch, kauaiataattach, +}; + +struct cfdriver kauaiata_cd = { + NULL, "kauaiata", DV_DULL, +}; + +int +kauaiatamatch(struct device *parent, void *match, void *aux) +{ + struct pci_attach_args *pa = aux; + + /* + * Match the adapter + * XXX match routine?? + */ + switch(PCI_VENDOR(pa->pa_id)) { + case PCI_VENDOR_APPLE: + switch (PCI_PRODUCT(pa->pa_id)) { + case PCI_PRODUCT_APPLE_UNINORTH_ATA: + case PCI_PRODUCT_APPLE_INTREPID_ATA: + return (1); + } + break; + } + return 0; +} + +void +kauaiataattach(struct device *parent, struct device *self, void *aux) +{ + int node; + struct confargs ca; + int namelen; + u_int32_t reg[20]; + char name[32]; + int32_t intr[8]; + + struct kauaiata_softc *sc = (struct kauaiata_softc *)self; + struct pci_attach_args *pa = aux; + pci_chipset_tag_t pc = pa->pa_pc; + + /* XXX assumes that this is /pci@f400000/ata-6 */ + + /* +vendor 0x106b product 0x003b (class undefined unknown subclass 0x00, rev 0x00) at pci2 dev 13 function 0 not configured + */ + + node = OF_finddevice("/pci@f4000000/ata-6"); + + ca.ca_nreg = OF_getprop(node, "reg", reg, sizeof(reg)); + printf("nreg %x\n", ca.ca_nreg); + + intr[0] = PCI_INTERRUPT_LINE(pci_conf_read(pc, pa->pa_tag, + PCI_INTERRUPT_REG)); + ca.ca_nintr = 4; /* XXX */ + intr[0] = 0x27; /* XXXX */ + + namelen = OF_getprop(node, "name", name, sizeof(name)); + if (namelen < 0) + return; + if (namelen >= sizeof(name)) + return; + + name[namelen] = 0; + + /* config read */ + sc->sc_membus_space.bus_base = + pci_conf_read(pc, pa->pa_tag, PCI_MAPREG_START); +#if 0 + pci_conf_write(pc, pa->pa_tag, PCI_MAPREG_START, 0xffffffff); + size = ~(pci_conf_read(pc, pa->pa_tag, PCI_MAPREG_START)); + pci_conf_write(pc, pa->pa_tag, PCI_MAPREG_START, + sc->sc_membus_space.bus_base); +#endif + + ca.ca_baseaddr = 0; + + sc->sc_membus_space.bus_reverse = 1; + + ca.ca_name = name; + ca.ca_iot = &sc->sc_membus_space; + ca.ca_dmat = pa->pa_dmat; + + ca.ca_reg = reg; + reg[0] = sc->sc_membus_space.bus_base + 0x2000; + reg[1] = reg[9]; /* XXX */ + reg[2] = sc->sc_membus_space.bus_base + 0x1000; + reg[3] = 0x1000; /* XXX */ + ca.ca_intr = intr; + + printf("\n"); + + config_found(self, &ca, kauaiata_print); +} + +int +kauaiata_print(void *aux, const char *dev) +{ + return QUIET; +} |