aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ide/pci/pdc202xx_new.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-16 18:20:36 -0400
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-16 18:20:36 -0400
commit1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 (patch)
tree0bba044c4ce775e45a88a51686b5d9f90697ea9d /drivers/ide/pci/pdc202xx_new.c
Linux-2.6.12-rc2v2.6.12-rc2
Initial git repository build. I'm not bothering with the full history, even though we have it. We can create a separate "historical" git archive of that later if we want to, and in the meantime it's about 3.2GB when imported into git - space that would just make the early git days unnecessarily complicated, when we don't have a lot of good infrastructure for it. Let it rip!
Diffstat (limited to 'drivers/ide/pci/pdc202xx_new.c')
-rw-r--r--drivers/ide/pci/pdc202xx_new.c508
1 files changed, 508 insertions, 0 deletions
diff --git a/drivers/ide/pci/pdc202xx_new.c b/drivers/ide/pci/pdc202xx_new.c
new file mode 100644
index 000000000000..211641a54398
--- /dev/null
+++ b/drivers/ide/pci/pdc202xx_new.c
@@ -0,0 +1,508 @@
1/*
2 * Promise TX2/TX4/TX2000/133 IDE driver
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version
7 * 2 of the License, or (at your option) any later version.
8 *
9 * Split from:
10 * linux/drivers/ide/pdc202xx.c Version 0.35 Mar. 30, 2002
11 * Copyright (C) 1998-2002 Andre Hedrick <andre@linux-ide.org>
12 * Portions Copyright (C) 1999 Promise Technology, Inc.
13 * Author: Frank Tiernan (frankt@promise.com)
14 * Released under terms of General Public License
15 */
16
17#include <linux/config.h>
18#include <linux/module.h>
19#include <linux/types.h>
20#include <linux/kernel.h>
21#include <linux/delay.h>
22#include <linux/timer.h>
23#include <linux/mm.h>
24#include <linux/ioport.h>
25#include <linux/blkdev.h>
26#include <linux/hdreg.h>
27#include <linux/interrupt.h>
28#include <linux/pci.h>
29#include <linux/init.h>
30#include <linux/ide.h>
31
32#include <asm/io.h>
33#include <asm/irq.h>
34
35#ifdef CONFIG_PPC_PMAC
36#include <asm/prom.h>
37#include <asm/pci-bridge.h>
38#endif
39
40#define PDC202_DEBUG_CABLE 0
41
42const static char *pdc_quirk_drives[] = {
43 "QUANTUM FIREBALLlct08 08",
44 "QUANTUM FIREBALLP KA6.4",
45 "QUANTUM FIREBALLP KA9.1",
46 "QUANTUM FIREBALLP LM20.4",
47 "QUANTUM FIREBALLP KX13.6",
48 "QUANTUM FIREBALLP KX20.5",
49 "QUANTUM FIREBALLP KX27.3",
50 "QUANTUM FIREBALLP LM20.5",
51 NULL
52};
53
54#define set_2regs(a, b) \
55 do { \
56 hwif->OUTB((a + adj), indexreg); \
57 hwif->OUTB(b, datareg); \
58 } while(0)
59
60#define set_ultra(a, b, c) \
61 do { \
62 set_2regs(0x10,(a)); \
63 set_2regs(0x11,(b)); \
64 set_2regs(0x12,(c)); \
65 } while(0)
66
67#define set_ata2(a, b) \
68 do { \
69 set_2regs(0x0e,(a)); \
70 set_2regs(0x0f,(b)); \
71 } while(0)
72
73#define set_pio(a, b, c) \
74 do { \
75 set_2regs(0x0c,(a)); \
76 set_2regs(0x0d,(b)); \
77 set_2regs(0x13,(c)); \
78 } while(0)
79
80static u8 pdcnew_ratemask (ide_drive_t *drive)
81{
82 u8 mode;
83
84 switch(HWIF(drive)->pci_dev->device) {
85 case PCI_DEVICE_ID_PROMISE_20277:
86 case PCI_DEVICE_ID_PROMISE_20276:
87 case PCI_DEVICE_ID_PROMISE_20275:
88 case PCI_DEVICE_ID_PROMISE_20271:
89 case PCI_DEVICE_ID_PROMISE_20269:
90 mode = 4;
91 break;
92 case PCI_DEVICE_ID_PROMISE_20270:
93 case PCI_DEVICE_ID_PROMISE_20268:
94 mode = 3;
95 break;
96 default:
97 return 0;
98 }
99 if (!eighty_ninty_three(drive))
100 mode = min(mode, (u8)1);
101 return mode;
102}
103
104static int check_in_drive_lists (ide_drive_t *drive, const char **list)
105{
106 struct hd_driveid *id = drive->id;
107
108 if (pdc_quirk_drives == list) {
109 while (*list) {
110 if (strstr(id->model, *list++)) {
111 return 2;
112 }
113 }
114 } else {
115 while (*list) {
116 if (!strcmp(*list++,id->model)) {
117 return 1;
118 }
119 }
120 }
121 return 0;
122}
123
124static int pdcnew_new_tune_chipset (ide_drive_t *drive, u8 xferspeed)
125{
126 ide_hwif_t *hwif = HWIF(drive);
127 unsigned long indexreg = hwif->dma_vendor1;
128 unsigned long datareg = hwif->dma_vendor3;
129 u8 thold = 0x10;
130 u8 adj = (drive->dn%2) ? 0x08 : 0x00;
131 u8 speed = ide_rate_filter(pdcnew_ratemask(drive), xferspeed);
132
133 if (speed == XFER_UDMA_2) {
134 hwif->OUTB((thold + adj), indexreg);
135 hwif->OUTB((hwif->INB(datareg) & 0x7f), datareg);
136 }
137
138 switch (speed) {
139 case XFER_UDMA_7:
140 speed = XFER_UDMA_6;
141 case XFER_UDMA_6: set_ultra(0x1a, 0x01, 0xcb); break;
142 case XFER_UDMA_5: set_ultra(0x1a, 0x02, 0xcb); break;
143 case XFER_UDMA_4: set_ultra(0x1a, 0x03, 0xcd); break;
144 case XFER_UDMA_3: set_ultra(0x1a, 0x05, 0xcd); break;
145 case XFER_UDMA_2: set_ultra(0x2a, 0x07, 0xcd); break;
146 case XFER_UDMA_1: set_ultra(0x3a, 0x0a, 0xd0); break;
147 case XFER_UDMA_0: set_ultra(0x4a, 0x0f, 0xd5); break;
148 case XFER_MW_DMA_2: set_ata2(0x69, 0x25); break;
149 case XFER_MW_DMA_1: set_ata2(0x6b, 0x27); break;
150 case XFER_MW_DMA_0: set_ata2(0xdf, 0x5f); break;
151 case XFER_PIO_4: set_pio(0x23, 0x09, 0x25); break;
152 case XFER_PIO_3: set_pio(0x27, 0x0d, 0x35); break;
153 case XFER_PIO_2: set_pio(0x23, 0x26, 0x64); break;
154 case XFER_PIO_1: set_pio(0x46, 0x29, 0xa4); break;
155 case XFER_PIO_0: set_pio(0xfb, 0x2b, 0xac); break;
156 default:
157 ;
158 }
159
160 return (ide_config_drive_speed(drive, speed));
161}
162
163/* 0 1 2 3 4 5 6 7 8
164 * 960, 480, 390, 300, 240, 180, 120, 90, 60
165 * 180, 150, 120, 90, 60
166 * DMA_Speed
167 * 180, 120, 90, 90, 90, 60, 30
168 * 11, 5, 4, 3, 2, 1, 0
169 */
170static void pdcnew_tune_drive(ide_drive_t *drive, u8 pio)
171{
172 u8 speed;
173
174 if (pio == 5) pio = 4;
175 speed = XFER_PIO_0 + ide_get_best_pio_mode(drive, 255, pio, NULL);
176
177 (void)pdcnew_new_tune_chipset(drive, speed);
178}
179
180static u8 pdcnew_new_cable_detect (ide_hwif_t *hwif)
181{
182 hwif->OUTB(0x0b, hwif->dma_vendor1);
183 return ((u8)((hwif->INB(hwif->dma_vendor3) & 0x04)));
184}
185static int config_chipset_for_dma (ide_drive_t *drive)
186{
187 struct hd_driveid *id = drive->id;
188 ide_hwif_t *hwif = HWIF(drive);
189 u8 speed = -1;
190 u8 cable;
191
192 u8 ultra_66 = ((id->dma_ultra & 0x0010) ||
193 (id->dma_ultra & 0x0008)) ? 1 : 0;
194
195 cable = pdcnew_new_cable_detect(hwif);
196
197 if (ultra_66 && cable) {
198 printk(KERN_WARNING "Warning: %s channel requires an 80-pin cable for operation.\n", hwif->channel ? "Secondary":"Primary");
199 printk(KERN_WARNING "%s reduced to Ultra33 mode.\n", drive->name);
200 }
201
202 if (drive->media != ide_disk)
203 return 0;
204 if (id->capability & 4) { /* IORDY_EN & PREFETCH_EN */
205 hwif->OUTB((0x13 + ((drive->dn%2) ? 0x08 : 0x00)), hwif->dma_vendor1);
206 hwif->OUTB((hwif->INB(hwif->dma_vendor3)|0x03), hwif->dma_vendor3);
207 }
208
209 speed = ide_dma_speed(drive, pdcnew_ratemask(drive));
210
211 if (!(speed)) {
212 hwif->tuneproc(drive, 5);
213 return 0;
214 }
215
216 (void) hwif->speedproc(drive, speed);
217 return ide_dma_enable(drive);
218}
219
220static int pdcnew_config_drive_xfer_rate (ide_drive_t *drive)
221{
222 ide_hwif_t *hwif = HWIF(drive);
223 struct hd_driveid *id = drive->id;
224
225 drive->init_speed = 0;
226
227 if (id && (id->capability & 1) && drive->autodma) {
228
229 if (ide_use_dma(drive)) {
230 if (config_chipset_for_dma(drive))
231 return hwif->ide_dma_on(drive);
232 }
233
234 goto fast_ata_pio;
235
236 } else if ((id->capability & 8) || (id->field_valid & 2)) {
237fast_ata_pio:
238 hwif->tuneproc(drive, 5);
239 return hwif->ide_dma_off_quietly(drive);
240 }
241 /* IORDY not supported */
242 return 0;
243}
244
245static int pdcnew_quirkproc (ide_drive_t *drive)
246{
247 return ((int) check_in_drive_lists(drive, pdc_quirk_drives));
248}
249
250static int pdcnew_ide_dma_lostirq(ide_drive_t *drive)
251{
252 if (HWIF(drive)->resetproc != NULL)
253 HWIF(drive)->resetproc(drive);
254 return __ide_dma_lostirq(drive);
255}
256
257static int pdcnew_ide_dma_timeout(ide_drive_t *drive)
258{
259 if (HWIF(drive)->resetproc != NULL)
260 HWIF(drive)->resetproc(drive);
261 return __ide_dma_timeout(drive);
262}
263
264static void pdcnew_new_reset (ide_drive_t *drive)
265{
266 /*
267 * Deleted this because it is redundant from the caller.
268 */
269 printk(KERN_WARNING "PDC202XX: %s channel reset.\n",
270 HWIF(drive)->channel ? "Secondary" : "Primary");
271}
272
273#ifdef CONFIG_PPC_PMAC
274static void __devinit apple_kiwi_init(struct pci_dev *pdev)
275{
276 struct device_node *np = pci_device_to_OF_node(pdev);
277 unsigned int class_rev = 0;
278 void __iomem *mmio;
279 u8 conf;
280
281 if (np == NULL || !device_is_compatible(np, "kiwi-root"))
282 return;
283
284 pci_read_config_dword(pdev, PCI_CLASS_REVISION, &class_rev);
285 class_rev &= 0xff;
286
287 if (class_rev >= 0x03) {
288 /* Setup chip magic config stuff (from darwin) */
289 pci_read_config_byte(pdev, 0x40, &conf);
290 pci_write_config_byte(pdev, 0x40, conf | 0x01);
291 }
292 mmio = ioremap(pci_resource_start(pdev, 5),
293 pci_resource_len(pdev, 5));
294
295 /* Setup some PLL stuffs */
296 switch (pdev->device) {
297 case PCI_DEVICE_ID_PROMISE_20270:
298 writew(0x0d2b, mmio + 0x1202);
299 mdelay(30);
300 break;
301 case PCI_DEVICE_ID_PROMISE_20271:
302 writew(0x0826, mmio + 0x1202);
303 mdelay(30);
304 break;
305 }
306
307 iounmap(mmio);
308}
309#endif /* CONFIG_PPC_PMAC */
310
311static unsigned int __devinit init_chipset_pdcnew(struct pci_dev *dev, const char *name)
312{
313 if (dev->resource[PCI_ROM_RESOURCE].start) {
314 pci_write_config_dword(dev, PCI_ROM_ADDRESS,
315 dev->resource[PCI_ROM_RESOURCE].start | PCI_ROM_ADDRESS_ENABLE);
316 printk(KERN_INFO "%s: ROM enabled at 0x%08lx\n",
317 name, dev->resource[PCI_ROM_RESOURCE].start);
318 }
319
320#ifdef CONFIG_PPC_PMAC
321 apple_kiwi_init(dev);
322#endif
323
324 return dev->irq;
325}
326
327static void __devinit init_hwif_pdc202new(ide_hwif_t *hwif)
328{
329 hwif->autodma = 0;
330
331 hwif->tuneproc = &pdcnew_tune_drive;
332 hwif->quirkproc = &pdcnew_quirkproc;
333 hwif->speedproc = &pdcnew_new_tune_chipset;
334 hwif->resetproc = &pdcnew_new_reset;
335
336 hwif->drives[0].autotune = hwif->drives[1].autotune = 1;
337
338 hwif->ultra_mask = 0x7f;
339 hwif->mwdma_mask = 0x07;
340
341 hwif->ide_dma_check = &pdcnew_config_drive_xfer_rate;
342 hwif->ide_dma_lostirq = &pdcnew_ide_dma_lostirq;
343 hwif->ide_dma_timeout = &pdcnew_ide_dma_timeout;
344 if (!(hwif->udma_four))
345 hwif->udma_four = (pdcnew_new_cable_detect(hwif)) ? 0 : 1;
346 if (!noautodma)
347 hwif->autodma = 1;
348 hwif->drives[0].autodma = hwif->drives[1].autodma = hwif->autodma;
349#if PDC202_DEBUG_CABLE
350 printk(KERN_DEBUG "%s: %s-pin cable\n",
351 hwif->name, hwif->udma_four ? "80" : "40");
352#endif /* PDC202_DEBUG_CABLE */
353}
354
355static int __devinit init_setup_pdcnew(struct pci_dev *dev, ide_pci_device_t *d)
356{
357 return ide_setup_pci_device(dev, d);
358}
359
360static int __devinit init_setup_pdc20270(struct pci_dev *dev,
361 ide_pci_device_t *d)
362{
363 struct pci_dev *findev = NULL;
364
365 if ((dev->bus->self &&
366 dev->bus->self->vendor == PCI_VENDOR_ID_DEC) &&
367 (dev->bus->self->device == PCI_DEVICE_ID_DEC_21150)) {
368 if (PCI_SLOT(dev->devfn) & 2)
369 return -ENODEV;
370 d->extra = 0;
371 while ((findev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, findev)) != NULL) {
372 if ((findev->vendor == dev->vendor) &&
373 (findev->device == dev->device) &&
374 (PCI_SLOT(findev->devfn) & 2)) {
375 if (findev->irq != dev->irq) {
376 findev->irq = dev->irq;
377 }
378 return ide_setup_pci_devices(dev, findev, d);
379 }
380 }
381 }
382 return ide_setup_pci_device(dev, d);
383}
384
385static int __devinit init_setup_pdc20276(struct pci_dev *dev,
386 ide_pci_device_t *d)
387{
388 if ((dev->bus->self) &&
389 (dev->bus->self->vendor == PCI_VENDOR_ID_INTEL) &&
390 ((dev->bus->self->device == PCI_DEVICE_ID_INTEL_I960) ||
391 (dev->bus->self->device == PCI_DEVICE_ID_INTEL_I960RM))) {
392 printk(KERN_INFO "ide: Skipping Promise PDC20276 "
393 "attached to I2O RAID controller.\n");
394 return -ENODEV;
395 }
396 return ide_setup_pci_device(dev, d);
397}
398
399static ide_pci_device_t pdcnew_chipsets[] __devinitdata = {
400 { /* 0 */
401 .name = "PDC20268",
402 .init_setup = init_setup_pdcnew,
403 .init_chipset = init_chipset_pdcnew,
404 .init_hwif = init_hwif_pdc202new,
405 .channels = 2,
406 .autodma = AUTODMA,
407 .bootable = OFF_BOARD,
408 },{ /* 1 */
409 .name = "PDC20269",
410 .init_setup = init_setup_pdcnew,
411 .init_chipset = init_chipset_pdcnew,
412 .init_hwif = init_hwif_pdc202new,
413 .channels = 2,
414 .autodma = AUTODMA,
415 .bootable = OFF_BOARD,
416 },{ /* 2 */
417 .name = "PDC20270",
418 .init_setup = init_setup_pdc20270,
419 .init_chipset = init_chipset_pdcnew,
420 .init_hwif = init_hwif_pdc202new,
421 .channels = 2,
422 .autodma = AUTODMA,
423#ifndef CONFIG_PDC202XX_FORCE
424 .enablebits = {{0x50,0x02,0x02}, {0x50,0x04,0x04}},
425#endif
426 .bootable = OFF_BOARD,
427 },{ /* 3 */
428 .name = "PDC20271",
429 .init_setup = init_setup_pdcnew,
430 .init_chipset = init_chipset_pdcnew,
431 .init_hwif = init_hwif_pdc202new,
432 .channels = 2,
433 .autodma = AUTODMA,
434 .bootable = OFF_BOARD,
435 },{ /* 4 */
436 .name = "PDC20275",
437 .init_setup = init_setup_pdcnew,
438 .init_chipset = init_chipset_pdcnew,
439 .init_hwif = init_hwif_pdc202new,
440 .channels = 2,
441 .autodma = AUTODMA,
442 .bootable = OFF_BOARD,
443 },{ /* 5 */
444 .name = "PDC20276",
445 .init_setup = init_setup_pdc20276,
446 .init_chipset = init_chipset_pdcnew,
447 .init_hwif = init_hwif_pdc202new,
448 .channels = 2,
449 .autodma = AUTODMA,
450#ifndef CONFIG_PDC202XX_FORCE
451 .enablebits = {{0x50,0x02,0x02}, {0x50,0x04,0x04}},
452#endif
453 .bootable = OFF_BOARD,
454 },{ /* 6 */
455 .name = "PDC20277",
456 .init_setup = init_setup_pdcnew,
457 .init_chipset = init_chipset_pdcnew,
458 .init_hwif = init_hwif_pdc202new,
459 .channels = 2,
460 .autodma = AUTODMA,
461 .bootable = OFF_BOARD,
462 }
463};
464
465/**
466 * pdc202new_init_one - called when a pdc202xx is found
467 * @dev: the pdc202new device
468 * @id: the matching pci id
469 *
470 * Called when the PCI registration layer (or the IDE initialization)
471 * finds a device matching our IDE device tables.
472 */
473
474static int __devinit pdc202new_init_one(struct pci_dev *dev, const struct pci_device_id *id)
475{
476 ide_pci_device_t *d = &pdcnew_chipsets[id->driver_data];
477
478 return d->init_setup(dev, d);
479}
480
481static struct pci_device_id pdc202new_pci_tbl[] = {
482 { PCI_VENDOR_ID_PROMISE, PCI_DEVICE_ID_PROMISE_20268, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
483 { PCI_VENDOR_ID_PROMISE, PCI_DEVICE_ID_PROMISE_20269, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1},
484 { PCI_VENDOR_ID_PROMISE, PCI_DEVICE_ID_PROMISE_20270, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 2},
485 { PCI_VENDOR_ID_PROMISE, PCI_DEVICE_ID_PROMISE_20271, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 3},
486 { PCI_VENDOR_ID_PROMISE, PCI_DEVICE_ID_PROMISE_20275, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 4},
487 { PCI_VENDOR_ID_PROMISE, PCI_DEVICE_ID_PROMISE_20276, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 5},
488 { PCI_VENDOR_ID_PROMISE, PCI_DEVICE_ID_PROMISE_20277, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 6},
489 { 0, },
490};
491MODULE_DEVICE_TABLE(pci, pdc202new_pci_tbl);
492
493static struct pci_driver driver = {
494 .name = "Promise_IDE",
495 .id_table = pdc202new_pci_tbl,
496 .probe = pdc202new_init_one,
497};
498
499static int pdc202new_ide_init(void)
500{
501 return ide_pci_register_driver(&driver);
502}
503
504module_init(pdc202new_ide_init);
505
506MODULE_AUTHOR("Andre Hedrick, Frank Tiernan");
507MODULE_DESCRIPTION("PCI driver module for Promise PDC20268 and higher");
508MODULE_LICENSE("GPL");