1 /* $NetBSD: cypide.c,v 1.32 2017/10/20 07:06:08 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.32 2017/10/20 07:06:08 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
cypide_match(device_t parent,cfdata_t match,void * aux)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
cypide_attach(device_t parent,device_t self,void * aux)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
cy693_chip_map(struct pciide_softc * sc,const struct pci_attach_args * pa)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
152 aprint_normal_dev(sc->sc_wdcdev.sc_atac.atac_dev,
153 "primary channel %s to ",
154 (interface & PCIIDE_INTERFACE_SETTABLE(0)) ?
155 "configured" : "wired");
156 if (interface & PCIIDE_INTERFACE_PCI(0)) {
157 aprint_normal("native-PCI mode\n");
158 pciide_mapregs_native(pa, cp, pciide_pci_intr);
159 } else {
160 aprint_normal("compatibility mode\n");
161 pciide_mapregs_compat(pa, cp, sc->sc_cy_compatchan);
162 if ((cp->ata_channel.ch_flags & ATACH_DISABLED) == 0)
163 pciide_map_compat_intr(pa, cp, sc->sc_cy_compatchan);
164 }
165 wdcattach(&cp->ata_channel);
166 }
167
168 static void
cy693_setup_channel(struct ata_channel * chp)169 cy693_setup_channel(struct ata_channel *chp)
170 {
171 struct ata_drive_datas *drvp;
172 int drive;
173 u_int32_t cy_cmd_ctrl;
174 u_int32_t idedma_ctl;
175 struct pciide_channel *cp = CHAN_TO_PCHAN(chp);
176 struct pciide_softc *sc = CHAN_TO_PCIIDE(chp);
177 int dma_mode = -1;
178
179 ATADEBUG_PRINT(("cy693_chip_map: old timings reg 0x%x\n",
180 pci_conf_read(sc->sc_pc, sc->sc_tag, CY_CMD_CTRL)),DEBUG_PROBE);
181
182 cy_cmd_ctrl = idedma_ctl = 0;
183
184 /* setup DMA if needed */
185 pciide_channel_dma_setup(cp);
186
187 for (drive = 0; drive < 2; drive++) {
188 drvp = &chp->ch_drive[drive];
189 /* If no drive, skip */
190 if (drvp->drive_type == ATA_DRIVET_NONE)
191 continue;
192 /* add timing values, setup DMA if needed */
193 if (drvp->drive_flags & ATA_DRIVE_DMA) {
194 idedma_ctl |= IDEDMA_CTL_DRV_DMA(drive);
195 /* use Multiword DMA */
196 if (dma_mode == -1 || dma_mode > drvp->DMA_mode)
197 dma_mode = drvp->DMA_mode;
198 }
199 cy_cmd_ctrl |= (cy_pio_pulse[drvp->PIO_mode] <<
200 CY_CMD_CTRL_IOW_PULSE_OFF(drive));
201 cy_cmd_ctrl |= (cy_pio_rec[drvp->PIO_mode] <<
202 CY_CMD_CTRL_IOW_REC_OFF(drive));
203 cy_cmd_ctrl |= (cy_pio_pulse[drvp->PIO_mode] <<
204 CY_CMD_CTRL_IOR_PULSE_OFF(drive));
205 cy_cmd_ctrl |= (cy_pio_rec[drvp->PIO_mode] <<
206 CY_CMD_CTRL_IOR_REC_OFF(drive));
207 }
208 pci_conf_write(sc->sc_pc, sc->sc_tag, CY_CMD_CTRL, cy_cmd_ctrl);
209 chp->ch_drive[0].DMA_mode = dma_mode;
210 chp->ch_drive[1].DMA_mode = dma_mode;
211
212 if (dma_mode == -1)
213 dma_mode = 0;
214
215 if (sc->sc_cy_handle != NULL) {
216 /* Note: `multiple' is implied. */
217 cy82c693_write(sc->sc_cy_handle,
218 (sc->sc_cy_compatchan == 0) ?
219 CY_DMA_IDX_PRIMARY : CY_DMA_IDX_SECONDARY, dma_mode);
220 }
221
222 if (idedma_ctl != 0) {
223 /* Add software bits in status register */
224 bus_space_write_1(sc->sc_dma_iot, cp->dma_iohs[IDEDMA_CTL], 0,
225 idedma_ctl);
226 }
227 ATADEBUG_PRINT(("cy693_chip_map: new timings reg 0x%x\n",
228 pci_conf_read(sc->sc_pc, sc->sc_tag, CY_CMD_CTRL)), DEBUG_PROBE);
229 }
230