1/*	$NetBSD: hptide.c,v 1.35 2022/05/28 22:16:44 andvar 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#include <sys/cdefs.h>
28__KERNEL_RCSID(0, "$NetBSD: hptide.c,v 1.35 2022/05/28 22:16:44 andvar 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/pciide_hpt_reg.h>
38
39static void hpt_chip_map(struct pciide_softc*, const struct pci_attach_args*);
40static void hpt_setup_channel(struct ata_channel*);
41static int  hpt_pci_intr(void *);
42
43static int  hptide_match(device_t, cfdata_t, void *);
44static void hptide_attach(device_t, device_t, void *);
45
46CFATTACH_DECL_NEW(hptide, sizeof(struct pciide_softc),
47    hptide_match, hptide_attach, pciide_detach, NULL);
48
49static const struct pciide_product_desc pciide_triones_products[] =  {
50	{ PCI_PRODUCT_TRIONES_HPT302,
51	  0,
52	  NULL,
53	  hpt_chip_map
54	},
55	{ PCI_PRODUCT_TRIONES_HPT366,
56	  0,
57	  NULL,
58	  hpt_chip_map,
59	},
60	{ PCI_PRODUCT_TRIONES_HPT371,
61	  0,
62	  NULL,
63	  hpt_chip_map,
64	},
65	{ PCI_PRODUCT_TRIONES_HPT372A,
66	  0,
67	  NULL,
68	  hpt_chip_map
69	},
70	{ PCI_PRODUCT_TRIONES_HPT374,
71	  0,
72	  NULL,
73	  hpt_chip_map
74	},
75	{ 0,
76	  0,
77	  NULL,
78	  NULL
79	}
80};
81
82static int
83hptide_match(device_t parent, cfdata_t match, void *aux)
84{
85	struct pci_attach_args *pa = aux;
86
87	if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_TRIONES) {
88		if (pciide_lookup_product(pa->pa_id, pciide_triones_products))
89			return (2);
90	}
91	return (0);
92}
93
94static void
95hptide_attach(device_t parent, device_t self, void *aux)
96{
97	struct pci_attach_args *pa = aux;
98	struct pciide_softc *sc = device_private(self);
99
100	sc->sc_wdcdev.sc_atac.atac_dev = self;
101
102	pciide_common_attach(sc, pa,
103	    pciide_lookup_product(pa->pa_id, pciide_triones_products));
104
105}
106
107static void
108hpt_chip_map(struct pciide_softc *sc, const struct pci_attach_args *pa)
109{
110	struct pciide_channel *cp;
111	int i, compatchan, revision;
112	pcireg_t interface;
113
114	if (pciide_chipen(sc, pa) == 0)
115		return;
116
117	revision = PCI_REVISION(pa->pa_class);
118	aprint_normal_dev(sc->sc_wdcdev.sc_atac.atac_dev,
119	    "Triones/Highpoint ");
120	switch (sc->sc_pp->ide_product) {
121	case PCI_PRODUCT_TRIONES_HPT302:
122		aprint_normal("HPT302 IDE Controller\n");
123		break;
124	case PCI_PRODUCT_TRIONES_HPT371:
125		aprint_normal("HPT371 IDE Controller\n");
126		break;
127	case PCI_PRODUCT_TRIONES_HPT374:
128		aprint_normal("HPT374 IDE Controller\n");
129		break;
130	case PCI_PRODUCT_TRIONES_HPT372A:
131		aprint_normal("HPT372A IDE Controller\n");
132		break;
133	case PCI_PRODUCT_TRIONES_HPT366:
134		if (revision == HPT372_REV)
135			aprint_normal("HPT372 IDE Controller\n");
136		else if (revision == HPT370_REV)
137			aprint_normal("HPT370 IDE Controller\n");
138		else if (revision == HPT370A_REV)
139			aprint_normal("HPT370A IDE Controller\n");
140		else if (revision == HPT368_REV)
141			aprint_normal("HPT368 IDE Controller\n");
142		else if (revision == HPT366_REV)
143			aprint_normal("HPT366 IDE Controller\n");
144		else
145			aprint_normal("unknown HPT IDE controller rev %d\n",
146			    revision);
147		break;
148	default:
149		aprint_normal("unknown HPT IDE controller 0x%x\n",
150		    sc->sc_pp->ide_product);
151	}
152
153	/*
154	 * when the chip is in native mode it identifies itself as a
155	 * 'misc mass storage'. Fake interface in this case.
156	 */
157	if (PCI_SUBCLASS(pa->pa_class) == PCI_SUBCLASS_MASS_STORAGE_IDE) {
158		interface = PCI_INTERFACE(pa->pa_class);
159	} else {
160		interface = PCIIDE_INTERFACE_BUS_MASTER_DMA |
161		    PCIIDE_INTERFACE_PCI(0);
162		if ((sc->sc_pp->ide_product == PCI_PRODUCT_TRIONES_HPT366 &&
163		    (revision == HPT368_REV || revision == HPT370_REV || revision == HPT370A_REV ||
164		     revision == HPT372_REV)) ||
165		    sc->sc_pp->ide_product == PCI_PRODUCT_TRIONES_HPT302 ||
166		    sc->sc_pp->ide_product == PCI_PRODUCT_TRIONES_HPT371 ||
167		    sc->sc_pp->ide_product == PCI_PRODUCT_TRIONES_HPT372A ||
168		    sc->sc_pp->ide_product == PCI_PRODUCT_TRIONES_HPT374)
169			interface |= PCIIDE_INTERFACE_PCI(1);
170	}
171
172	aprint_verbose_dev(sc->sc_wdcdev.sc_atac.atac_dev,
173	    "bus-master DMA support present");
174	pciide_mapreg_dma(sc, pa);
175	aprint_verbose("\n");
176	sc->sc_wdcdev.sc_atac.atac_cap = ATAC_CAP_DATA16 | ATAC_CAP_DATA32;
177	if (sc->sc_dma_ok) {
178		sc->sc_wdcdev.sc_atac.atac_cap |= ATAC_CAP_DMA | ATAC_CAP_UDMA;
179		sc->sc_wdcdev.irqack = pciide_irqack;
180	}
181	sc->sc_wdcdev.sc_atac.atac_pio_cap = 4;
182	sc->sc_wdcdev.sc_atac.atac_dma_cap = 2;
183
184	sc->sc_wdcdev.sc_atac.atac_set_modes = hpt_setup_channel;
185	sc->sc_wdcdev.sc_atac.atac_channels = sc->wdc_chanarray;
186	if (sc->sc_pp->ide_product == PCI_PRODUCT_TRIONES_HPT366 &&
187	    (revision == HPT366_REV || revision == HPT368_REV)) {
188		sc->sc_wdcdev.sc_atac.atac_nchannels = 1;
189		sc->sc_wdcdev.sc_atac.atac_udma_cap = 4;
190	} else {
191		sc->sc_wdcdev.sc_atac.atac_nchannels = 2;
192		if (sc->sc_pp->ide_product == PCI_PRODUCT_TRIONES_HPT374 ||
193		    sc->sc_pp->ide_product == PCI_PRODUCT_TRIONES_HPT372A ||
194		    sc->sc_pp->ide_product == PCI_PRODUCT_TRIONES_HPT371 ||
195		    sc->sc_pp->ide_product == PCI_PRODUCT_TRIONES_HPT302 ||
196		    (sc->sc_pp->ide_product == PCI_PRODUCT_TRIONES_HPT366 &&
197		    revision == HPT372_REV))
198			sc->sc_wdcdev.sc_atac.atac_udma_cap = 6;
199		else
200			sc->sc_wdcdev.sc_atac.atac_udma_cap = 5;
201	}
202	sc->sc_wdcdev.wdc_maxdrives = 2;
203
204	wdc_allocate_regs(&sc->sc_wdcdev);
205
206	for (i = 0; i < sc->sc_wdcdev.sc_atac.atac_nchannels; i++) {
207		cp = &sc->pciide_channels[i];
208		if (sc->sc_wdcdev.sc_atac.atac_nchannels > 1) {
209			compatchan = i;
210			if((pciide_pci_read(sc->sc_pc, sc->sc_tag,
211			   HPT370_CTRL1(i)) & HPT370_CTRL1_EN) == 0) {
212				aprint_normal(
213				    "%s: %s channel ignored (disabled)\n",
214				    device_xname(
215				      sc->sc_wdcdev.sc_atac.atac_dev),
216				    cp->name);
217				cp->ata_channel.ch_flags |= ATACH_DISABLED;
218				continue;
219			}
220		} else {
221			/*
222			 * The 366 has 2 PCI IDE functions, one for primary and
223			 * one for secondary. So we need to call
224			 * pciide_mapregs_compat() with the real channel.
225			 */
226			if (pa->pa_function == 0)
227				compatchan = 0;
228			else if (pa->pa_function == 1)
229				compatchan = 1;
230			else {
231				aprint_error_dev(
232				    sc->sc_wdcdev.sc_atac.atac_dev,
233				    "unexpected PCI function %d\n",
234				    pa->pa_function);
235				return;
236			}
237		}
238		if (pciide_chansetup(sc, i, interface) == 0)
239			continue;
240		if (interface & PCIIDE_INTERFACE_PCI(i)) {
241			pciide_mapregs_native(pa, cp, hpt_pci_intr);
242		} else {
243			pciide_mapregs_compat(pa, cp, compatchan);
244			if ((cp->ata_channel.ch_flags & ATACH_DISABLED) == 0)
245				pciide_map_compat_intr(pa, cp,
246				    sc->sc_cy_compatchan);
247		}
248		wdcattach(&cp->ata_channel);
249	}
250	if ((sc->sc_pp->ide_product == PCI_PRODUCT_TRIONES_HPT366 &&
251	    (revision == HPT368_REV || revision == HPT370_REV || revision == HPT370A_REV ||
252	     revision == HPT372_REV)) ||
253	    sc->sc_pp->ide_product == PCI_PRODUCT_TRIONES_HPT302 ||
254	    sc->sc_pp->ide_product == PCI_PRODUCT_TRIONES_HPT371 ||
255	    sc->sc_pp->ide_product == PCI_PRODUCT_TRIONES_HPT372A ||
256	    sc->sc_pp->ide_product == PCI_PRODUCT_TRIONES_HPT374) {
257		/*
258		 * HPT370_REV and higher has a bit to disable interrupts,
259		 * make sure to clear it
260		 */
261		pciide_pci_write(sc->sc_pc, sc->sc_tag, HPT_CSEL,
262		    pciide_pci_read(sc->sc_pc, sc->sc_tag, HPT_CSEL) &
263		    ~HPT_CSEL_IRQDIS);
264	}
265	/* set clocks, etc (mandatory on 372/4, optional otherwise) */
266	if ((sc->sc_pp->ide_product == PCI_PRODUCT_TRIONES_HPT366 &&
267	     revision == HPT372_REV ) ||
268	    sc->sc_pp->ide_product == PCI_PRODUCT_TRIONES_HPT302 ||
269	    sc->sc_pp->ide_product == PCI_PRODUCT_TRIONES_HPT371 ||
270	    sc->sc_pp->ide_product == PCI_PRODUCT_TRIONES_HPT372A ||
271	    sc->sc_pp->ide_product == PCI_PRODUCT_TRIONES_HPT374)
272		pciide_pci_write(sc->sc_pc, sc->sc_tag, HPT_SC2,
273		    (pciide_pci_read(sc->sc_pc, sc->sc_tag, HPT_SC2) &
274		     HPT_SC2_MAEN) | HPT_SC2_OSC_EN);
275	return;
276}
277
278static void
279hpt_setup_channel(struct ata_channel *chp)
280{
281	struct ata_drive_datas *drvp;
282	int drive, s;
283	int cable;
284	u_int32_t before, after;
285	u_int32_t idedma_ctl;
286	struct pciide_channel *cp = CHAN_TO_PCHAN(chp);
287	struct pciide_softc *sc = CHAN_TO_PCIIDE(chp);
288	int revision =
289	     PCI_REVISION(pci_conf_read(sc->sc_pc, sc->sc_tag, PCI_CLASS_REG));
290	const u_int32_t *tim_pio, *tim_dma, *tim_udma;
291
292	cable = pciide_pci_read(sc->sc_pc, sc->sc_tag, HPT_CSEL);
293
294	/* setup DMA if needed */
295	pciide_channel_dma_setup(cp);
296
297	idedma_ctl = 0;
298
299	/* select the timing arrays for the chip */
300	switch (sc->sc_pp->ide_product) {
301	case PCI_PRODUCT_TRIONES_HPT374:
302		tim_udma = hpt374_udma;
303		tim_dma = hpt374_dma;
304		tim_pio = hpt374_pio;
305		break;
306	case PCI_PRODUCT_TRIONES_HPT302:
307	case PCI_PRODUCT_TRIONES_HPT371:
308	case PCI_PRODUCT_TRIONES_HPT372A:
309		tim_udma = hpt372_udma;
310		tim_dma = hpt372_dma;
311		tim_pio = hpt372_pio;
312		break;
313	case PCI_PRODUCT_TRIONES_HPT366:
314	default:
315		switch (revision) {
316		case HPT372_REV:
317			tim_udma = hpt372_udma;
318			tim_dma = hpt372_dma;
319			tim_pio = hpt372_pio;
320			break;
321		case HPT370_REV:
322		case HPT370A_REV:
323			tim_udma = hpt370_udma;
324			tim_dma = hpt370_dma;
325			tim_pio = hpt370_pio;
326			break;
327		case HPT368_REV:
328		case HPT366_REV:
329		default:
330			tim_udma = hpt366_udma;
331			tim_dma = hpt366_dma;
332			tim_pio = hpt366_pio;
333			break;
334		}
335	}
336
337	/* Per drive settings */
338	for (drive = 0; drive < chp->ch_ndrives; drive++) {
339		drvp = &chp->ch_drive[drive];
340		/* If no drive, skip */
341		if (drvp->drive_type == ATA_DRIVET_NONE)
342			continue;
343		before = pci_conf_read(sc->sc_pc, sc->sc_tag,
344					HPT_IDETIM(chp->ch_channel, drive));
345
346		/* add timing values, setup DMA if needed */
347		if (drvp->drive_flags & ATA_DRIVE_UDMA) {
348			/* use Ultra/DMA */
349			s = splbio();
350			drvp->drive_flags &= ~ATA_DRIVE_DMA;
351			splx(s);
352			if ((cable & HPT_CSEL_CBLID(chp->ch_channel)) != 0 &&
353			    drvp->UDMA_mode > 2)
354				drvp->UDMA_mode = 2;
355			after = tim_udma[drvp->UDMA_mode];
356			idedma_ctl |= IDEDMA_CTL_DRV_DMA(drive);
357		} else if (drvp->drive_flags & ATA_DRIVE_DMA) {
358			/*
359			 * use Multiword DMA.
360			 * Timings will be used for both PIO and DMA, so adjust
361			 * DMA mode if needed
362			 */
363			if (drvp->PIO_mode >= 3 &&
364			    (drvp->DMA_mode + 2) > drvp->PIO_mode) {
365				drvp->DMA_mode = drvp->PIO_mode - 2;
366			}
367			after = tim_dma[drvp->DMA_mode];
368			idedma_ctl |= IDEDMA_CTL_DRV_DMA(drive);
369		} else {
370			/* PIO only */
371			after = tim_pio[drvp->PIO_mode];
372		}
373		pci_conf_write(sc->sc_pc, sc->sc_tag,
374		    HPT_IDETIM(chp->ch_channel, drive), after);
375		ATADEBUG_PRINT(("%s: bus speed register set to 0x%08x "
376		    "(BIOS 0x%08x)\n", device_xname(drvp->drv_softc),
377		    after, before), DEBUG_PROBE);
378	}
379	if (idedma_ctl != 0) {
380		/* Add software bits in status register */
381		bus_space_write_1(sc->sc_dma_iot, cp->dma_iohs[IDEDMA_CTL], 0,
382		    idedma_ctl);
383	}
384}
385
386static int
387hpt_pci_intr(void *arg)
388{
389	struct pciide_softc *sc = arg;
390	struct pciide_channel *cp;
391	struct ata_channel *wdc_cp;
392	int rv = 0;
393	int dmastat, i, crv;
394
395	for (i = 0; i < sc->sc_wdcdev.sc_atac.atac_nchannels; i++) {
396		cp = &sc->pciide_channels[i];
397		dmastat = bus_space_read_1(sc->sc_dma_iot,
398		    cp->dma_iohs[IDEDMA_CTL], 0);
399		if((dmastat & ( IDEDMA_CTL_ACT | IDEDMA_CTL_INTR)) !=
400		    IDEDMA_CTL_INTR)
401			continue;
402		wdc_cp = &cp->ata_channel;
403		crv = wdcintr(wdc_cp);
404		if (crv == 0) {
405			aprint_error("%s:%d: bogus intr\n",
406			    device_xname(sc->sc_wdcdev.sc_atac.atac_dev), i);
407			bus_space_write_1(sc->sc_dma_iot,
408			    cp->dma_iohs[IDEDMA_CTL], 0, dmastat);
409		} else
410			rv = 1;
411	}
412	return rv;
413}
414