Home | History | Annotate | Line # | Download | only in pci
      1 /*	$NetBSD: rdcide.c,v 1.8 2014/07/08 18:01:26 msaitoh Exp $	*/
      2 
      3 /*
      4  * Copyright (c) 2011 Manuel Bouyer.
      5  *
      6  * Redistribution and use in source and binary forms, with or without
      7  * modification, are permitted provided that the following conditions
      8  * are met:
      9  * 1. Redistributions of source code must retain the above copyright
     10  *    notice, this list of conditions and the following disclaimer.
     11  * 2. Redistributions in binary form must reproduce the above copyright
     12  *    notice, this list of conditions and the following disclaimer in the
     13  *    documentation and/or other materials provided with the distribution.
     14  *
     15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     16  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     17  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     18  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
     19  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     20  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     21  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     22  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     23  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     24  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     25  */
     26 
     27 #include <sys/cdefs.h>
     28 __KERNEL_RCSID(0, "$NetBSD: rdcide.c,v 1.8 2014/07/08 18:01:26 msaitoh Exp $");
     29 
     30 #include <sys/param.h>
     31 #include <sys/systm.h>
     32 
     33 #include <dev/pci/pcivar.h>
     34 #include <dev/pci/pcidevs.h>
     35 #include <dev/pci/pciidereg.h>
     36 #include <dev/pci/pciidevar.h>
     37 #include <dev/pci/rdcide_reg.h>
     38 
     39 static void rdcide_chip_map(struct pciide_softc *,
     40     const struct pci_attach_args *);
     41 static void rdcide_setup_channel(struct ata_channel *);
     42 
     43 static bool rdcide_resume(device_t, const pmf_qual_t *);
     44 static bool rdcide_suspend(device_t, const pmf_qual_t *);
     45 static int  rdcide_match(device_t, cfdata_t, void *);
     46 static void rdcide_attach(device_t, device_t, void *);
     47 
     48 static const struct pciide_product_desc pciide_intel_products[] =  {
     49 	{ PCI_PRODUCT_RDC_R1011_IDE,
     50 	  0,
     51 	  "RDC R1011 IDE controller",
     52 	  rdcide_chip_map,
     53 	},
     54 	{ PCI_PRODUCT_RDC_R1012_IDE,
     55 	  0,
     56 	  "RDC R1012 IDE controller",
     57 	  rdcide_chip_map,
     58 	},
     59 };
     60 
     61 CFATTACH_DECL_NEW(rdcide, sizeof(struct pciide_softc),
     62     rdcide_match, rdcide_attach, NULL, NULL);
     63 
     64 static int
     65 rdcide_match(device_t parent, cfdata_t match, void *aux)
     66 {
     67 	struct pci_attach_args *pa = aux;
     68 
     69 	if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_RDC) {
     70 		if (pciide_lookup_product(pa->pa_id, pciide_intel_products))
     71 			return (2);
     72 	}
     73 	return (0);
     74 }
     75 
     76 static void
     77 rdcide_attach(device_t parent, device_t self, void *aux)
     78 {
     79 	struct pci_attach_args *pa = aux;
     80 	struct pciide_softc *sc = device_private(self);
     81 
     82 	sc->sc_wdcdev.sc_atac.atac_dev = self;
     83 
     84 	pciide_common_attach(sc, pa,
     85 	    pciide_lookup_product(pa->pa_id, pciide_intel_products));
     86 
     87 	if (!pmf_device_register(self, rdcide_suspend, rdcide_resume))
     88 		aprint_error_dev(self, "couldn't establish power handler\n");
     89 }
     90 
     91 static bool
     92 rdcide_resume(device_t dv, const pmf_qual_t *qual)
     93 {
     94 	struct pciide_softc *sc = device_private(dv);
     95 
     96 	pci_conf_write(sc->sc_pc, sc->sc_tag, RDCIDE_PATR,
     97 	    sc->sc_pm_reg[0]);
     98 	pci_conf_write(sc->sc_pc, sc->sc_tag, RDCIDE_PSD1ATR,
     99 	    sc->sc_pm_reg[1]);
    100 	pci_conf_write(sc->sc_pc, sc->sc_tag, RDCIDE_UDCCR,
    101 	    sc->sc_pm_reg[2]);
    102 	pci_conf_write(sc->sc_pc, sc->sc_tag, RDCIDE_IIOCR,
    103 	    sc->sc_pm_reg[3]);
    104 
    105 	return true;
    106 }
    107 
    108 static bool
    109 rdcide_suspend(device_t dv, const pmf_qual_t *qual)
    110 {
    111 	struct pciide_softc *sc = device_private(dv);
    112 
    113 	sc->sc_pm_reg[0] = pci_conf_read(sc->sc_pc, sc->sc_tag,
    114 	    RDCIDE_PATR);
    115 	sc->sc_pm_reg[1] = pci_conf_read(sc->sc_pc, sc->sc_tag,
    116 	    RDCIDE_PSD1ATR);
    117 	sc->sc_pm_reg[2] = pci_conf_read(sc->sc_pc, sc->sc_tag,
    118 	    RDCIDE_UDCCR);
    119 	sc->sc_pm_reg[3] = pci_conf_read(sc->sc_pc, sc->sc_tag,
    120 	    RDCIDE_IIOCR);
    121 
    122 	return true;
    123 }
    124 
    125 static void
    126 rdcide_chip_map(struct pciide_softc *sc, const struct pci_attach_args *pa)
    127 {
    128 	struct pciide_channel *cp;
    129 	int channel;
    130 	u_int32_t patr;
    131 	pcireg_t interface = PCI_INTERFACE(pa->pa_class);
    132 
    133 	if (pciide_chipen(sc, pa) == 0)
    134 		return;
    135 
    136 	aprint_verbose_dev(sc->sc_wdcdev.sc_atac.atac_dev,
    137 	    "bus-master DMA support present");
    138 	pciide_mapreg_dma(sc, pa);
    139 	aprint_verbose("\n");
    140 	sc->sc_wdcdev.sc_atac.atac_cap |= ATAC_CAP_DATA16 | ATAC_CAP_DATA32;
    141 	if (sc->sc_dma_ok) {
    142 		sc->sc_wdcdev.sc_atac.atac_cap |= ATAC_CAP_DMA | ATAC_CAP_UDMA;
    143 		sc->sc_wdcdev.irqack = pciide_irqack;
    144 		sc->sc_wdcdev.dma_init = pciide_dma_init;
    145 	}
    146 	sc->sc_wdcdev.sc_atac.atac_pio_cap = 4;
    147 	sc->sc_wdcdev.sc_atac.atac_dma_cap = 2;
    148 	sc->sc_wdcdev.sc_atac.atac_udma_cap = 5;
    149 	sc->sc_wdcdev.sc_atac.atac_set_modes = rdcide_setup_channel;
    150 	sc->sc_wdcdev.sc_atac.atac_channels = sc->wdc_chanarray;
    151 	sc->sc_wdcdev.sc_atac.atac_nchannels = PCIIDE_NUM_CHANNELS;
    152 	sc->sc_wdcdev.wdc_maxdrives = 2;
    153 
    154 	ATADEBUG_PRINT(("rdcide_setup_chip: old PATR=0x%x",
    155 	    pci_conf_read(sc->sc_pc, sc->sc_tag, RDCIDE_PATR)),
    156 	    DEBUG_PROBE);
    157 	ATADEBUG_PRINT((", PSD1ATR=0x%x",
    158 	    pci_conf_read(sc->sc_pc, sc->sc_tag, RDCIDE_PSD1ATR)),
    159 	    DEBUG_PROBE);
    160 	ATADEBUG_PRINT((", UDCCR 0x%x",
    161 	    pci_conf_read(sc->sc_pc, sc->sc_tag, RDCIDE_UDCCR)),
    162 	    DEBUG_PROBE);
    163 	ATADEBUG_PRINT((", IIOCR 0x%x",
    164 	    pci_conf_read(sc->sc_pc, sc->sc_tag, RDCIDE_IIOCR)),
    165 	    DEBUG_PROBE);
    166 	ATADEBUG_PRINT(("\n"), DEBUG_PROBE);
    167 
    168 	wdc_allocate_regs(&sc->sc_wdcdev);
    169 
    170 	for (channel = 0; channel < sc->sc_wdcdev.sc_atac.atac_nchannels;
    171 	     channel++) {
    172 		cp = &sc->pciide_channels[channel];
    173 		if (pciide_chansetup(sc, channel, interface) == 0)
    174 			continue;
    175 		patr = pci_conf_read(sc->sc_pc, sc->sc_tag, RDCIDE_PATR);
    176 		if ((patr & RDCIDE_PATR_EN(channel)) == 0) {
    177 			aprint_normal_dev(sc->sc_wdcdev.sc_atac.atac_dev,
    178 			    "%s channel ignored (disabled)\n", cp->name);
    179 			cp->ata_channel.ch_flags |= ATACH_DISABLED;
    180 			continue;
    181 		}
    182 		pciide_mapchan(pa, cp, interface, pciide_pci_intr);
    183 	}
    184 	ATADEBUG_PRINT(("rdcide_setup_chip: PATR=0x%x",
    185 	    pci_conf_read(sc->sc_pc, sc->sc_tag, RDCIDE_PATR)),
    186 	    DEBUG_PROBE);
    187 	ATADEBUG_PRINT((", PSD1ATR=0x%x",
    188 	    pci_conf_read(sc->sc_pc, sc->sc_tag, RDCIDE_PSD1ATR)),
    189 	    DEBUG_PROBE);
    190 	ATADEBUG_PRINT((", UDCCR 0x%x",
    191 	    pci_conf_read(sc->sc_pc, sc->sc_tag, RDCIDE_UDCCR)),
    192 	    DEBUG_PROBE);
    193 	ATADEBUG_PRINT((", IIOCR 0x%x",
    194 	    pci_conf_read(sc->sc_pc, sc->sc_tag, RDCIDE_IIOCR)),
    195 	    DEBUG_PROBE);
    196 	ATADEBUG_PRINT(("\n"), DEBUG_PROBE);
    197 
    198 }
    199 
    200 static void
    201 rdcide_setup_channel(struct ata_channel *chp)
    202 {
    203 	u_int8_t drive;
    204 	u_int32_t patr, psd1atr, udccr, iiocr;
    205 	struct pciide_channel *cp = CHAN_TO_PCHAN(chp);
    206 	struct pciide_softc *sc = CHAN_TO_PCIIDE(chp);
    207 	struct ata_drive_datas *drvp = cp->ata_channel.ch_drive;
    208 
    209 	patr = pci_conf_read(sc->sc_pc, sc->sc_tag, RDCIDE_PATR);
    210 	psd1atr = pci_conf_read(sc->sc_pc, sc->sc_tag, RDCIDE_PSD1ATR);
    211 	udccr = pci_conf_read(sc->sc_pc, sc->sc_tag, RDCIDE_UDCCR);
    212 	iiocr = pci_conf_read(sc->sc_pc, sc->sc_tag, RDCIDE_IIOCR);
    213 
    214 	/* setup DMA */
    215 	pciide_channel_dma_setup(cp);
    216 
    217 	/* clear modes */
    218 	patr = patr & (RDCIDE_PATR_EN(0) | RDCIDE_PATR_EN(1));
    219 	psd1atr &= ~RDCIDE_PSD1ATR_SETUP_MASK(chp->ch_channel);
    220 	psd1atr &= ~RDCIDE_PSD1ATR_HOLD_MASK(chp->ch_channel);
    221 	for (drive = 0; drive < 2; drive++) {
    222 		udccr &= ~RDCIDE_UDCCR_EN(chp->ch_channel, drive);
    223 		udccr &= ~RDCIDE_UDCCR_TIM_MASK(chp->ch_channel, drive);
    224 		iiocr &= ~RDCIDE_IIOCR_CLK_MASK(chp->ch_channel, drive);
    225 	}
    226 	/* now setup modes */
    227 	for (drive = 0; drive < 2; drive++) {
    228 		if (drvp[drive].drive_type == ATA_DRIVET_NONE)
    229 			continue;
    230 		if (drvp[drive].drive_type == ATA_DRIVET_ATAPI)
    231 			patr |= RDCIDE_PATR_ATA(chp->ch_channel, drive);
    232 		if (drive == 0) {
    233 			patr |= RDCIDE_PATR_SETUP(
    234 			    rdcide_setup[drvp[drive].PIO_mode],
    235 			    chp->ch_channel);
    236 			patr |= RDCIDE_PATR_HOLD(
    237 			    rdcide_hold[drvp[drive].PIO_mode],
    238 			    chp->ch_channel);
    239 		} else {
    240 			patr |= RDCIDE_PATR_DEV1_TEN(chp->ch_channel);
    241 			psd1atr |= RDCIDE_PSD1ATR_SETUP(
    242 			    rdcide_setup[drvp[drive].PIO_mode],
    243 			    chp->ch_channel);
    244 			psd1atr |= RDCIDE_PSD1ATR_HOLD(
    245 			    rdcide_hold[drvp[drive].PIO_mode],
    246 			    chp->ch_channel);
    247 		}
    248 		if (drvp[drive].PIO_mode > 0) {
    249 			patr |= RDCIDE_PATR_FTIM(chp->ch_channel, drive);
    250 			patr |= RDCIDE_PATR_IORDY(chp->ch_channel, drive);
    251 		}
    252 		if (drvp[drive].drive_flags & ATA_DRIVE_DMA) {
    253 			patr |= RDCIDE_PATR_DMAEN(chp->ch_channel, drive);
    254 		}
    255 		if ((drvp[drive].drive_flags & ATA_DRIVE_UDMA) == 0)
    256 			continue;
    257 
    258 		if ((iiocr & RDCIDE_IIOCR_CABLE(chp->ch_channel, drive)) == 0
    259 		    && drvp[drive].UDMA_mode > 2)
    260 			drvp[drive].UDMA_mode = 2;
    261 		udccr |= RDCIDE_UDCCR_EN(chp->ch_channel, drive);
    262 		udccr |= RDCIDE_UDCCR_TIM(
    263 		    rdcide_udmatim[drvp[drive].UDMA_mode],
    264 		    chp->ch_channel, drive);
    265 		iiocr |= RDCIDE_IIOCR_CLK(
    266 		    rdcide_udmaclk[drvp[drive].UDMA_mode],
    267 		    chp->ch_channel, drive);
    268 	}
    269 
    270 	pci_conf_write(sc->sc_pc, sc->sc_tag, RDCIDE_PATR, patr);
    271 	pci_conf_write(sc->sc_pc, sc->sc_tag, RDCIDE_PSD1ATR, psd1atr);
    272 	pci_conf_write(sc->sc_pc, sc->sc_tag, RDCIDE_UDCCR, udccr);
    273 	pci_conf_write(sc->sc_pc, sc->sc_tag, RDCIDE_IIOCR, iiocr);
    274 }
    275