cypide.c revision 1.31 1 /* $NetBSD: cypide.c,v 1.31 2017/10/07 16:05:33 jdolecek Exp $ */
2
3 /*
4 * Copyright (c) 1999, 2000, 2001 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
28 #include <sys/cdefs.h>
29 __KERNEL_RCSID(0, "$NetBSD: cypide.c,v 1.31 2017/10/07 16:05:33 jdolecek Exp $");
30
31 #include <sys/param.h>
32 #include <sys/systm.h>
33
34 #include <dev/pci/pcivar.h>
35 #include <dev/pci/pcidevs.h>
36 #include <dev/pci/pciidereg.h>
37 #include <dev/pci/pciidevar.h>
38 #include <dev/pci/pciide_cy693_reg.h>
39 #include <dev/pci/cy82c693var.h>
40
41 static void cy693_chip_map(struct pciide_softc*, const struct pci_attach_args*);
42 static void cy693_setup_channel(struct ata_channel*);
43
44 static int cypide_match(device_t, cfdata_t, void *);
45 static void cypide_attach(device_t, device_t, void *);
46
47 CFATTACH_DECL_NEW(cypide, sizeof(struct pciide_softc),
48 cypide_match, cypide_attach, pciide_detach, NULL);
49
50 static const struct pciide_product_desc pciide_cypress_products[] = {
51 { PCI_PRODUCT_CONTAQ_82C693,
52 IDE_16BIT_IOSPACE,
53 "Cypress 82C693 IDE Controller",
54 cy693_chip_map,
55 },
56 { 0,
57 0,
58 NULL,
59 NULL
60 }
61 };
62
63 static int
64 cypide_match(device_t parent, cfdata_t match, void *aux)
65 {
66 struct pci_attach_args *pa = aux;
67
68 if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_CONTAQ &&
69 PCI_CLASS(pa->pa_class) == PCI_CLASS_MASS_STORAGE &&
70 PCI_SUBCLASS(pa->pa_class) == PCI_SUBCLASS_MASS_STORAGE_IDE) {
71 if (pciide_lookup_product(pa->pa_id, pciide_cypress_products))
72 return (2);
73 }
74 return (0);
75 }
76
77 static void
78 cypide_attach(device_t parent, device_t self, void *aux)
79 {
80 struct pci_attach_args *pa = aux;
81 struct pciide_softc *sc = device_private(self);
82
83 sc->sc_wdcdev.sc_atac.atac_dev = self;
84
85 pciide_common_attach(sc, pa,
86 pciide_lookup_product(pa->pa_id, pciide_cypress_products));
87
88 }
89
90 static void
91 cy693_chip_map(struct pciide_softc *sc, const struct pci_attach_args *pa)
92 {
93 struct pciide_channel *cp;
94 pcireg_t interface = PCI_INTERFACE(pa->pa_class);
95
96 if (pciide_chipen(sc, pa) == 0)
97 return;
98
99 /*
100 * this chip has 2 PCI IDE functions, one for primary and one for
101 * secondary. So we need to call pciide_mapregs_compat() with
102 * the real channel
103 */
104 if (pa->pa_function == 1) {
105 sc->sc_cy_compatchan = 0;
106 } else if (pa->pa_function == 2) {
107 sc->sc_cy_compatchan = 1;
108 } else {
109 aprint_error_dev(sc->sc_wdcdev.sc_atac.atac_dev,
110 "unexpected PCI function %d\n", pa->pa_function);
111 return;
112 }
113 if (interface & PCIIDE_INTERFACE_BUS_MASTER_DMA) {
114 aprint_verbose_dev(sc->sc_wdcdev.sc_atac.atac_dev,
115 "bus-master DMA support present\n");
116 pciide_mapreg_dma(sc, pa);
117 } else {
118 aprint_normal_dev(sc->sc_wdcdev.sc_atac.atac_dev,
119 "hardware does not support DMA\n");
120 sc->sc_dma_ok = 0;
121 }
122
123 sc->sc_cy_handle = cy82c693_init(pa->pa_iot);
124 if (sc->sc_cy_handle == NULL) {
125 aprint_error_dev(sc->sc_wdcdev.sc_atac.atac_dev,
126 "unable to map hyperCache control registers\n");
127 sc->sc_dma_ok = 0;
128 }
129
130 sc->sc_wdcdev.sc_atac.atac_cap = ATAC_CAP_DATA16 | ATAC_CAP_DATA32;
131 if (sc->sc_dma_ok) {
132 sc->sc_wdcdev.sc_atac.atac_cap |= ATAC_CAP_DMA;
133 sc->sc_wdcdev.irqack = pciide_irqack;
134 }
135 sc->sc_wdcdev.sc_atac.atac_pio_cap = 4;
136 sc->sc_wdcdev.sc_atac.atac_dma_cap = 2;
137 sc->sc_wdcdev.sc_atac.atac_set_modes = cy693_setup_channel;
138
139 sc->sc_wdcdev.sc_atac.atac_channels = sc->wdc_chanarray;
140 sc->sc_wdcdev.sc_atac.atac_nchannels = 1;
141 sc->sc_wdcdev.wdc_maxdrives = 2;
142
143 wdc_allocate_regs(&sc->sc_wdcdev);
144
145 /* Only one channel for this chip; if we are here it's enabled */
146 cp = &sc->pciide_channels[0];
147 sc->wdc_chanarray[0] = &cp->ata_channel;
148 cp->name = PCIIDE_CHANNEL_NAME(0);
149 cp->ata_channel.ch_channel = 0;
150 cp->ata_channel.ch_atac = &sc->sc_wdcdev.sc_atac;
151 cp->ata_channel.ch_queue = ata_queue_alloc(1);
152 if (cp->ata_channel.ch_queue == NULL) {
153 aprint_error("%s primary channel: "
154 "can't allocate memory for command queue",
155 device_xname(sc->sc_wdcdev.sc_atac.atac_dev));
156 return;
157 }
158 aprint_normal_dev(sc->sc_wdcdev.sc_atac.atac_dev,
159 "primary channel %s to ",
160 (interface & PCIIDE_INTERFACE_SETTABLE(0)) ?
161 "configured" : "wired");
162 if (interface & PCIIDE_INTERFACE_PCI(0)) {
163 aprint_normal("native-PCI mode\n");
164 pciide_mapregs_native(pa, cp, pciide_pci_intr);
165 } else {
166 aprint_normal("compatibility mode\n");
167 pciide_mapregs_compat(pa, cp, sc->sc_cy_compatchan);
168 if ((cp->ata_channel.ch_flags & ATACH_DISABLED) == 0)
169 pciide_map_compat_intr(pa, cp, sc->sc_cy_compatchan);
170 }
171 wdcattach(&cp->ata_channel);
172 }
173
174 static void
175 cy693_setup_channel(struct ata_channel *chp)
176 {
177 struct ata_drive_datas *drvp;
178 int drive;
179 u_int32_t cy_cmd_ctrl;
180 u_int32_t idedma_ctl;
181 struct pciide_channel *cp = CHAN_TO_PCHAN(chp);
182 struct pciide_softc *sc = CHAN_TO_PCIIDE(chp);
183 int dma_mode = -1;
184
185 ATADEBUG_PRINT(("cy693_chip_map: old timings reg 0x%x\n",
186 pci_conf_read(sc->sc_pc, sc->sc_tag, CY_CMD_CTRL)),DEBUG_PROBE);
187
188 cy_cmd_ctrl = idedma_ctl = 0;
189
190 /* setup DMA if needed */
191 pciide_channel_dma_setup(cp);
192
193 for (drive = 0; drive < 2; drive++) {
194 drvp = &chp->ch_drive[drive];
195 /* If no drive, skip */
196 if (drvp->drive_type == ATA_DRIVET_NONE)
197 continue;
198 /* add timing values, setup DMA if needed */
199 if (drvp->drive_flags & ATA_DRIVE_DMA) {
200 idedma_ctl |= IDEDMA_CTL_DRV_DMA(drive);
201 /* use Multiword DMA */
202 if (dma_mode == -1 || dma_mode > drvp->DMA_mode)
203 dma_mode = drvp->DMA_mode;
204 }
205 cy_cmd_ctrl |= (cy_pio_pulse[drvp->PIO_mode] <<
206 CY_CMD_CTRL_IOW_PULSE_OFF(drive));
207 cy_cmd_ctrl |= (cy_pio_rec[drvp->PIO_mode] <<
208 CY_CMD_CTRL_IOW_REC_OFF(drive));
209 cy_cmd_ctrl |= (cy_pio_pulse[drvp->PIO_mode] <<
210 CY_CMD_CTRL_IOR_PULSE_OFF(drive));
211 cy_cmd_ctrl |= (cy_pio_rec[drvp->PIO_mode] <<
212 CY_CMD_CTRL_IOR_REC_OFF(drive));
213 }
214 pci_conf_write(sc->sc_pc, sc->sc_tag, CY_CMD_CTRL, cy_cmd_ctrl);
215 chp->ch_drive[0].DMA_mode = dma_mode;
216 chp->ch_drive[1].DMA_mode = dma_mode;
217
218 if (dma_mode == -1)
219 dma_mode = 0;
220
221 if (sc->sc_cy_handle != NULL) {
222 /* Note: `multiple' is implied. */
223 cy82c693_write(sc->sc_cy_handle,
224 (sc->sc_cy_compatchan == 0) ?
225 CY_DMA_IDX_PRIMARY : CY_DMA_IDX_SECONDARY, dma_mode);
226 }
227
228 if (idedma_ctl != 0) {
229 /* Add software bits in status register */
230 bus_space_write_1(sc->sc_dma_iot, cp->dma_iohs[IDEDMA_CTL], 0,
231 idedma_ctl);
232 }
233 ATADEBUG_PRINT(("cy693_chip_map: new timings reg 0x%x\n",
234 pci_conf_read(sc->sc_pc, sc->sc_tag, CY_CMD_CTRL)), DEBUG_PROBE);
235 }
236