1 /* $NetBSD: iteide.c,v 1.9 2008/03/18 20:46:36 cube Exp $ */
4 * Copyright (c) 2004 The NetBSD Foundation, Inc.
6 * This code is derived from software contributed to The NetBSD Foundation
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 * 3. The name of the author may not be used to endorse or promote products
18 * derived from this software without specific prior written permission.
20 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
21 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
22 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
23 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
24 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
25 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
29 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 #include <sys/cdefs.h>
34 __KERNEL_RCSID(0, "$NetBSD: iteide.c,v 1.9 2008/03/18 20:46:36 cube Exp $");
36 #include <sys/param.h>
37 #include <sys/systm.h>
39 #include <dev/pci/pcivar.h>
40 #include <dev/pci/pcidevs.h>
41 #include <dev/pci/pciidereg.h>
42 #include <dev/pci/pciidevar.h>
43 #include <dev/pci/pciide_ite_reg.h>
45 static void ite_chip_map(struct pciide_softc
*, struct pci_attach_args
*);
46 static void ite_setup_channel(struct ata_channel
*);
48 static int iteide_match(device_t
, cfdata_t
, void *);
49 static void iteide_attach(device_t
, device_t
, void *);
51 CFATTACH_DECL_NEW(iteide
, sizeof(struct pciide_softc
),
52 iteide_match
, iteide_attach
, NULL
, NULL
);
54 static const struct pciide_product_desc pciide_ite_products
[] = {
55 { PCI_PRODUCT_ITE_IT8211
,
57 "Integrated Technology Express IDE controller",
60 { PCI_PRODUCT_ITE_IT8212
,
62 "Integrated Technology Express IDE controller",
73 iteide_match(device_t parent
, cfdata_t match
, void *aux
)
75 struct pci_attach_args
*pa
= aux
;
76 if (PCI_VENDOR(pa
->pa_id
) == PCI_VENDOR_ITE
&&
77 PCI_CLASS(pa
->pa_class
) == PCI_CLASS_MASS_STORAGE
) {
78 if (pciide_lookup_product(pa
->pa_id
, pciide_ite_products
))
85 iteide_attach(device_t parent
, device_t self
, void *aux
)
87 struct pci_attach_args
*pa
= aux
;
88 struct pciide_softc
*sc
= device_private(self
);
90 sc
->sc_wdcdev
.sc_atac
.atac_dev
= self
;
92 pciide_common_attach(sc
, pa
,
93 pciide_lookup_product(pa
->pa_id
, pciide_ite_products
));
97 ite_chip_map(struct pciide_softc
*sc
, struct pci_attach_args
*pa
)
99 struct pciide_channel
*cp
;
102 bus_size_t cmdsize
, ctlsize
;
103 pcireg_t cfg
, modectl
;
105 /* fake interface since IT8212 claims to be a RAID device */
106 interface
= PCIIDE_INTERFACE_BUS_MASTER_DMA
|
107 PCIIDE_INTERFACE_PCI(0) | PCIIDE_INTERFACE_PCI(1);
109 cfg
= pci_conf_read(sc
->sc_pc
, sc
->sc_tag
, IT_CFG
);
110 modectl
= pci_conf_read(sc
->sc_pc
, sc
->sc_tag
, IT_MODE
);
111 ATADEBUG_PRINT(("%s: cfg=0x%x, modectl=0x%x\n",
112 device_xname(sc
->sc_wdcdev
.sc_atac
.atac_dev
), cfg
& IT_CFG_MASK
,
113 modectl
& IT_MODE_MASK
), DEBUG_PROBE
);
115 if (pciide_chipen(sc
, pa
) == 0)
118 aprint_verbose_dev(sc
->sc_wdcdev
.sc_atac
.atac_dev
,
119 "bus-master DMA support present");
120 pciide_mapreg_dma(sc
, pa
);
121 aprint_verbose("\n");
123 sc
->sc_wdcdev
.sc_atac
.atac_cap
= ATAC_CAP_DATA16
| ATAC_CAP_DATA32
;
126 sc
->sc_wdcdev
.sc_atac
.atac_cap
|= ATAC_CAP_DMA
| ATAC_CAP_UDMA
;
127 sc
->sc_wdcdev
.irqack
= pciide_irqack
;
129 sc
->sc_wdcdev
.sc_atac
.atac_pio_cap
= 4;
130 sc
->sc_wdcdev
.sc_atac
.atac_dma_cap
= 2;
131 sc
->sc_wdcdev
.sc_atac
.atac_udma_cap
= 6;
133 sc
->sc_wdcdev
.sc_atac
.atac_set_modes
= ite_setup_channel
;
134 sc
->sc_wdcdev
.sc_atac
.atac_channels
= sc
->wdc_chanarray
;
135 sc
->sc_wdcdev
.sc_atac
.atac_nchannels
= PCIIDE_NUM_CHANNELS
;
137 wdc_allocate_regs(&sc
->sc_wdcdev
);
140 modectl
&= ~IT_MODE_RAID1
;
141 /* Disable CPU firmware mode */
142 modectl
&= ~IT_MODE_CPU
;
144 pci_conf_write(sc
->sc_pc
, sc
->sc_tag
, IT_MODE
, modectl
);
146 for (channel
= 0; channel
< sc
->sc_wdcdev
.sc_atac
.atac_nchannels
; channel
++) {
147 cp
= &sc
->pciide_channels
[channel
];
149 if (pciide_chansetup(sc
, channel
, interface
) == 0)
152 pciide_mapchan(pa
, cp
, interface
, &cmdsize
, &ctlsize
,
155 /* Re-read configuration registers after channels setup */
156 cfg
= pci_conf_read(sc
->sc_pc
, sc
->sc_tag
, IT_CFG
);
157 modectl
= pci_conf_read(sc
->sc_pc
, sc
->sc_tag
, IT_MODE
);
158 ATADEBUG_PRINT(("%s: cfg=0x%x, modectl=0x%x\n",
159 device_xname(sc
->sc_wdcdev
.sc_atac
.atac_dev
), cfg
& IT_CFG_MASK
,
160 modectl
& IT_MODE_MASK
), DEBUG_PROBE
);
164 ite_setup_channel(struct ata_channel
*chp
)
166 struct ata_drive_datas
*drvp
;
168 u_int32_t idedma_ctl
;
169 struct pciide_channel
*cp
= CHAN_TO_PCHAN(chp
);
170 struct pciide_softc
*sc
= CHAN_TO_PCIIDE(chp
);
171 int channel
= chp
->ch_channel
;
172 pcireg_t cfg
, modectl
;
175 cfg
= pci_conf_read(sc
->sc_pc
, sc
->sc_tag
, IT_CFG
);
176 modectl
= pci_conf_read(sc
->sc_pc
, sc
->sc_tag
, IT_MODE
);
177 tim
= pci_conf_read(sc
->sc_pc
, sc
->sc_tag
, IT_TIM(channel
));
178 ATADEBUG_PRINT(("%s:%d: tim=0x%x\n",
179 device_xname(sc
->sc_wdcdev
.sc_atac
.atac_dev
),
180 channel
, tim
), DEBUG_PROBE
);
182 /* Setup DMA if needed */
183 pciide_channel_dma_setup(cp
);
185 /* Clear all bits for this channel */
188 /* Per channel settings */
189 for (drive
= 0; drive
< 2; drive
++) {
190 drvp
= &chp
->ch_drive
[drive
];
192 /* If no drive, skip */
193 if ((drvp
->drive_flags
& DRIVE
) == 0)
196 if ((chp
->ch_atac
->atac_cap
& ATAC_CAP_UDMA
) != 0 &&
197 (drvp
->drive_flags
& DRIVE_UDMA
) != 0) {
198 /* Setup UltraDMA mode */
199 drvp
->drive_flags
&= ~DRIVE_DMA
;
200 modectl
&= ~IT_MODE_DMA(channel
, drive
);
203 /* Check cable, only works in CPU firmware mode */
204 if (drvp
->UDMA_mode
> 2 &&
205 (cfg
& IT_CFG_CABLE(channel
, drive
)) == 0) {
206 ATADEBUG_PRINT(("(%s:%d:%d): "
207 "80-wire cable not detected\n",
208 device_xname(&sc
->sc_wdcdev
.sc_atac
.atac_dev
),
209 channel
, drive
), DEBUG_PROBE
);
214 if (drvp
->UDMA_mode
>= 5)
215 tim
|= IT_TIM_UDMA5(drive
);
217 tim
&= ~IT_TIM_UDMA5(drive
);
219 mode
= drvp
->PIO_mode
;
220 } else if ((chp
->ch_atac
->atac_cap
& ATAC_CAP_DMA
) != 0 &&
221 (drvp
->drive_flags
& DRIVE_DMA
) != 0) {
222 /* Setup multiword DMA mode */
223 drvp
->drive_flags
&= ~DRIVE_UDMA
;
224 modectl
|= IT_MODE_DMA(channel
, drive
);
226 /* mode = min(pio, dma + 2) */
227 if (drvp
->PIO_mode
<= (drvp
->DMA_mode
+ 2))
228 mode
= drvp
->PIO_mode
;
230 mode
= drvp
->DMA_mode
+ 2;
234 idedma_ctl
|= IDEDMA_CTL_DRV_DMA(drive
);
243 drvp
->PIO_mode
= mode
;
244 drvp
->DMA_mode
= mode
- 2;
247 /* Enable IORDY if PIO mode >= 3 */
248 if (drvp
->PIO_mode
>= 3)
249 cfg
|= IT_CFG_IORDY(channel
);
252 ATADEBUG_PRINT(("%s: tim=0x%x\n",
253 device_xname(sc
->sc_wdcdev
.sc_atac
.atac_dev
), tim
), DEBUG_PROBE
);
255 pci_conf_write(sc
->sc_pc
, sc
->sc_tag
, IT_CFG
, cfg
);
256 pci_conf_write(sc
->sc_pc
, sc
->sc_tag
, IT_MODE
, modectl
);
257 pci_conf_write(sc
->sc_pc
, sc
->sc_tag
, IT_TIM(channel
), tim
);
259 if (idedma_ctl
!= 0) {
260 /* Add software bits in status register */
261 bus_space_write_1(sc
->sc_dma_iot
,
262 cp
->dma_iohs
[IDEDMA_CTL
], 0, idedma_ctl
);