ide: remove <asm/ide.h> for some archs
[deliverable/linux.git] / drivers / ide / pci / pdc202xx_old.c
CommitLineData
1da177e4 1/*
1da177e4 2 * Copyright (C) 1998-2002 Andre Hedrick <andre@linux-ide.org>
fed21641 3 * Copyright (C) 2006-2007 MontaVista Software, Inc.
4fce3164 4 * Copyright (C) 2007 Bartlomiej Zolnierkiewicz
1da177e4 5 *
1da177e4
LT
6 * Portions Copyright (C) 1999 Promise Technology, Inc.
7 * Author: Frank Tiernan (frankt@promise.com)
8 * Released under terms of General Public License
9 */
10
1da177e4
LT
11#include <linux/types.h>
12#include <linux/module.h>
13#include <linux/kernel.h>
14#include <linux/delay.h>
1da177e4
LT
15#include <linux/blkdev.h>
16#include <linux/hdreg.h>
1da177e4
LT
17#include <linux/pci.h>
18#include <linux/init.h>
19#include <linux/ide.h>
20
21#include <asm/io.h>
1da177e4 22
1da177e4
LT
23#define PDC202XX_DEBUG_DRIVE_INFO 0
24
25static const char *pdc_quirk_drives[] = {
26 "QUANTUM FIREBALLlct08 08",
27 "QUANTUM FIREBALLP KA6.4",
28 "QUANTUM FIREBALLP KA9.1",
29 "QUANTUM FIREBALLP LM20.4",
30 "QUANTUM FIREBALLP KX13.6",
31 "QUANTUM FIREBALLP KX20.5",
32 "QUANTUM FIREBALLP KX27.3",
33 "QUANTUM FIREBALLP LM20.5",
34 NULL
35};
36
4fce3164 37static void pdc_old_disable_66MHz_clock(ide_hwif_t *);
1da177e4 38
88b2b32b 39static void pdc202xx_set_mode(ide_drive_t *drive, const u8 speed)
1da177e4
LT
40{
41 ide_hwif_t *hwif = HWIF(drive);
36501650 42 struct pci_dev *dev = to_pci_dev(hwif->dev);
1da177e4 43 u8 drive_pci = 0x60 + (drive->dn << 2);
1da177e4 44
4fce3164 45 u8 AP = 0, BP = 0, CP = 0;
1da177e4
LT
46 u8 TA = 0, TB = 0, TC = 0;
47
4fce3164
BZ
48#if PDC202XX_DEBUG_DRIVE_INFO
49 u32 drive_conf = 0;
1da177e4 50 pci_read_config_dword(dev, drive_pci, &drive_conf);
4fce3164 51#endif
1da177e4 52
4fce3164
BZ
53 /*
54 * TODO: do this once per channel
55 */
56 if (dev->device != PCI_DEVICE_ID_PROMISE_20246)
57 pdc_old_disable_66MHz_clock(hwif);
1da177e4 58
4fce3164
BZ
59 pci_read_config_byte(dev, drive_pci, &AP);
60 pci_read_config_byte(dev, drive_pci + 1, &BP);
61 pci_read_config_byte(dev, drive_pci + 2, &CP);
1da177e4
LT
62
63 switch(speed) {
1da177e4
LT
64 case XFER_UDMA_5:
65 case XFER_UDMA_4: TB = 0x20; TC = 0x01; break;
66 case XFER_UDMA_2: TB = 0x20; TC = 0x01; break;
67 case XFER_UDMA_3:
68 case XFER_UDMA_1: TB = 0x40; TC = 0x02; break;
69 case XFER_UDMA_0:
70 case XFER_MW_DMA_2: TB = 0x60; TC = 0x03; break;
71 case XFER_MW_DMA_1: TB = 0x60; TC = 0x04; break;
4fce3164 72 case XFER_MW_DMA_0: TB = 0xE0; TC = 0x0F; break;
1da177e4
LT
73 case XFER_PIO_4: TA = 0x01; TB = 0x04; break;
74 case XFER_PIO_3: TA = 0x02; TB = 0x06; break;
75 case XFER_PIO_2: TA = 0x03; TB = 0x08; break;
76 case XFER_PIO_1: TA = 0x05; TB = 0x0C; break;
77 case XFER_PIO_0:
78 default: TA = 0x09; TB = 0x13; break;
79 }
80
81 if (speed < XFER_SW_DMA_0) {
4fce3164
BZ
82 /*
83 * preserve SYNC_INT / ERDDY_EN bits while clearing
84 * Prefetch_EN / IORDY_EN / PA[3:0] bits of register A
85 */
86 AP &= ~0x3f;
87 if (drive->id->capability & 4)
88 AP |= 0x20; /* set IORDY_EN bit */
89 if (drive->media == ide_disk)
90 AP |= 0x10; /* set Prefetch_EN bit */
91 /* clear PB[4:0] bits of register B */
92 BP &= ~0x1f;
93 pci_write_config_byte(dev, drive_pci, AP | TA);
94 pci_write_config_byte(dev, drive_pci + 1, BP | TB);
1da177e4 95 } else {
4fce3164
BZ
96 /* clear MB[2:0] bits of register B */
97 BP &= ~0xe0;
98 /* clear MC[3:0] bits of register C */
99 CP &= ~0x0f;
100 pci_write_config_byte(dev, drive_pci + 1, BP | TB);
101 pci_write_config_byte(dev, drive_pci + 2, CP | TC);
1da177e4
LT
102 }
103
104#if PDC202XX_DEBUG_DRIVE_INFO
105 printk(KERN_DEBUG "%s: %s drive%d 0x%08x ",
106 drive->name, ide_xfer_verbose(speed),
107 drive->dn, drive_conf);
4fce3164 108 pci_read_config_dword(dev, drive_pci, &drive_conf);
1da177e4 109 printk("0x%08x\n", drive_conf);
4fce3164 110#endif
1da177e4
LT
111}
112
26bcb879 113static void pdc202xx_set_pio_mode(ide_drive_t *drive, const u8 pio)
1da177e4 114{
88b2b32b 115 pdc202xx_set_mode(drive, XFER_PIO_0 + pio);
1da177e4
LT
116}
117
ac95beed 118static u8 __devinit pdc2026x_cable_detect(ide_hwif_t *hwif)
1da177e4 119{
36501650 120 struct pci_dev *dev = to_pci_dev(hwif->dev);
1bee4d1d 121 u16 CIS, mask = hwif->channel ? (1 << 11) : (1 << 10);
49521f97 122
36501650 123 pci_read_config_word(dev, 0x50, &CIS);
49521f97
BZ
124
125 return (CIS & mask) ? ATA_CBL_PATA40 : ATA_CBL_PATA80;
1da177e4
LT
126}
127
128/*
129 * Set the control register to use the 66MHz system
130 * clock for UDMA 3/4/5 mode operation when necessary.
131 *
4fce3164
BZ
132 * FIXME: this register is shared by both channels, some locking is needed
133 *
1da177e4
LT
134 * It may also be possible to leave the 66MHz clock on
135 * and readjust the timing parameters.
136 */
137static void pdc_old_enable_66MHz_clock(ide_hwif_t *hwif)
138{
1c029fd6 139 unsigned long clock_reg = hwif->extra_base + 0x01;
0ecdca26 140 u8 clock = inb(clock_reg);
1da177e4 141
0ecdca26 142 outb(clock | (hwif->channel ? 0x08 : 0x02), clock_reg);
1da177e4
LT
143}
144
145static void pdc_old_disable_66MHz_clock(ide_hwif_t *hwif)
146{
1c029fd6 147 unsigned long clock_reg = hwif->extra_base + 0x01;
0ecdca26 148 u8 clock = inb(clock_reg);
1da177e4 149
0ecdca26 150 outb(clock & ~(hwif->channel ? 0x08 : 0x02), clock_reg);
1da177e4
LT
151}
152
f01393e4 153static void pdc202xx_quirkproc(ide_drive_t *drive)
1da177e4 154{
d24ec426
SS
155 const char **list, *model = drive->id->model;
156
157 for (list = pdc_quirk_drives; *list != NULL; list++)
f01393e4
BZ
158 if (strstr(model, *list) != NULL) {
159 drive->quirk_list = 2;
160 return;
161 }
162
163 drive->quirk_list = 0;
1da177e4
LT
164}
165
5e37bdc0 166static void pdc202xx_dma_start(ide_drive_t *drive)
1da177e4
LT
167{
168 if (drive->current_speed > XFER_UDMA_2)
169 pdc_old_enable_66MHz_clock(drive->hwif);
f3d5b34c 170 if (drive->media != ide_disk || drive->addressing == 1) {
1da177e4
LT
171 struct request *rq = HWGROUP(drive)->rq;
172 ide_hwif_t *hwif = HWIF(drive);
1c029fd6 173 unsigned long high_16 = hwif->extra_base - 16;
1da177e4
LT
174 unsigned long atapi_reg = high_16 + (hwif->channel ? 0x24 : 0x20);
175 u32 word_count = 0;
0ecdca26 176 u8 clock = inb(high_16 + 0x11);
1da177e4 177
0ecdca26 178 outb(clock | (hwif->channel ? 0x08 : 0x02), high_16 + 0x11);
1da177e4
LT
179 word_count = (rq->nr_sectors << 8);
180 word_count = (rq_data_dir(rq) == READ) ?
181 word_count | 0x05000000 :
182 word_count | 0x06000000;
0ecdca26 183 outl(word_count, atapi_reg);
1da177e4
LT
184 }
185 ide_dma_start(drive);
186}
187
5e37bdc0 188static int pdc202xx_dma_end(ide_drive_t *drive)
1da177e4 189{
f3d5b34c 190 if (drive->media != ide_disk || drive->addressing == 1) {
1da177e4 191 ide_hwif_t *hwif = HWIF(drive);
1c029fd6 192 unsigned long high_16 = hwif->extra_base - 16;
1da177e4
LT
193 unsigned long atapi_reg = high_16 + (hwif->channel ? 0x24 : 0x20);
194 u8 clock = 0;
195
0ecdca26
BZ
196 outl(0, atapi_reg); /* zero out extra */
197 clock = inb(high_16 + 0x11);
198 outb(clock & ~(hwif->channel ? 0x08:0x02), high_16 + 0x11);
1da177e4
LT
199 }
200 if (drive->current_speed > XFER_UDMA_2)
201 pdc_old_disable_66MHz_clock(drive->hwif);
202 return __ide_dma_end(drive);
203}
204
5e37bdc0 205static int pdc202xx_dma_test_irq(ide_drive_t *drive)
1da177e4
LT
206{
207 ide_hwif_t *hwif = HWIF(drive);
1c029fd6 208 unsigned long high_16 = hwif->extra_base - 16;
cab7f8ed 209 u8 dma_stat = inb(hwif->dma_base + ATA_DMA_STATUS);
0ecdca26 210 u8 sc1d = inb(high_16 + 0x001d);
1da177e4
LT
211
212 if (hwif->channel) {
213 /* bit7: Error, bit6: Interrupting, bit5: FIFO Full, bit4: FIFO Empty */
214 if ((sc1d & 0x50) == 0x50)
215 goto somebody_else;
216 else if ((sc1d & 0x40) == 0x40)
217 return (dma_stat & 4) == 4;
218 } else {
219 /* bit3: Error, bit2: Interrupting, bit1: FIFO Full, bit0: FIFO Empty */
220 if ((sc1d & 0x05) == 0x05)
221 goto somebody_else;
222 else if ((sc1d & 0x04) == 0x04)
223 return (dma_stat & 4) == 4;
224 }
225somebody_else:
226 return (dma_stat & 4) == 4; /* return 1 if INTR asserted */
227}
228
1da177e4
LT
229static void pdc202xx_reset_host (ide_hwif_t *hwif)
230{
1c029fd6 231 unsigned long high_16 = hwif->extra_base - 16;
0ecdca26 232 u8 udma_speed_flag = inb(high_16 | 0x001f);
1da177e4 233
0ecdca26 234 outb(udma_speed_flag | 0x10, high_16 | 0x001f);
1da177e4 235 mdelay(100);
0ecdca26 236 outb(udma_speed_flag & ~0x10, high_16 | 0x001f);
1da177e4
LT
237 mdelay(2000); /* 2 seconds ?! */
238
239 printk(KERN_WARNING "PDC202XX: %s channel reset.\n",
240 hwif->channel ? "Secondary" : "Primary");
241}
242
243static void pdc202xx_reset (ide_drive_t *drive)
244{
245 ide_hwif_t *hwif = HWIF(drive);
246 ide_hwif_t *mate = hwif->mate;
26bcb879 247
1da177e4
LT
248 pdc202xx_reset_host(hwif);
249 pdc202xx_reset_host(mate);
26bcb879
BZ
250
251 ide_set_max_pio(drive);
1da177e4
LT
252}
253
ac95beed
BZ
254static void pdc202xx_dma_lost_irq(ide_drive_t *drive)
255{
256 pdc202xx_reset(drive);
257 ide_dma_lost_irq(drive);
258}
259
260static void pdc202xx_dma_timeout(ide_drive_t *drive)
261{
262 pdc202xx_reset(drive);
263 ide_dma_timeout(drive);
264}
265
73369d2a
BZ
266static unsigned int __devinit init_chipset_pdc202xx(struct pci_dev *dev,
267 const char *name)
1da177e4 268{
73369d2a 269 unsigned long dmabase = pci_resource_start(dev, 4);
1da177e4
LT
270 u8 udma_speed_flag = 0, primary_mode = 0, secondary_mode = 0;
271
73369d2a
BZ
272 if (dmabase == 0)
273 goto out;
1da177e4 274
0ecdca26
BZ
275 udma_speed_flag = inb(dmabase | 0x1f);
276 primary_mode = inb(dmabase | 0x1a);
277 secondary_mode = inb(dmabase | 0x1b);
1da177e4
LT
278 printk(KERN_INFO "%s: (U)DMA Burst Bit %sABLED " \
279 "Primary %s Mode " \
5e59c236 280 "Secondary %s Mode.\n", pci_name(dev),
1da177e4
LT
281 (udma_speed_flag & 1) ? "EN" : "DIS",
282 (primary_mode & 1) ? "MASTER" : "PCI",
283 (secondary_mode & 1) ? "MASTER" : "PCI" );
284
1da177e4
LT
285 if (!(udma_speed_flag & 1)) {
286 printk(KERN_INFO "%s: FORCING BURST BIT 0x%02x->0x%02x ",
5e59c236 287 pci_name(dev), udma_speed_flag,
1da177e4 288 (udma_speed_flag|1));
0ecdca26
BZ
289 outb(udma_speed_flag | 1, dmabase | 0x1f);
290 printk("%sACTIVE\n", (inb(dmabase | 0x1f) & 1) ? "" : "IN");
1da177e4 291 }
73369d2a
BZ
292out:
293 return dev->irq;
1da177e4
LT
294}
295
97f84baa
BZ
296static void __devinit pdc202ata4_fixup_irq(struct pci_dev *dev,
297 const char *name)
1da177e4
LT
298{
299 if ((dev->class >> 8) != PCI_CLASS_STORAGE_IDE) {
300 u8 irq = 0, irq2 = 0;
301 pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &irq);
302 /* 0xbc */
303 pci_read_config_byte(dev, (PCI_INTERRUPT_LINE)|0x80, &irq2);
304 if (irq != irq2) {
305 pci_write_config_byte(dev,
306 (PCI_INTERRUPT_LINE)|0x80, irq); /* 0xbc */
97f84baa
BZ
307 printk(KERN_INFO "%s: PCI config space interrupt "
308 "mirror fixed\n", name);
1da177e4
LT
309 }
310 }
1da177e4
LT
311}
312
4db90a14
BZ
313#define IDE_HFLAGS_PDC202XX \
314 (IDE_HFLAG_ERROR_STOPS_FIFO | \
4db90a14
BZ
315 IDE_HFLAG_OFF_BOARD)
316
ac95beed
BZ
317static const struct ide_port_ops pdc20246_port_ops = {
318 .set_pio_mode = pdc202xx_set_pio_mode,
319 .set_dma_mode = pdc202xx_set_mode,
320 .quirkproc = pdc202xx_quirkproc,
321};
322
323static const struct ide_port_ops pdc2026x_port_ops = {
324 .set_pio_mode = pdc202xx_set_pio_mode,
325 .set_dma_mode = pdc202xx_set_mode,
326 .quirkproc = pdc202xx_quirkproc,
327 .resetproc = pdc202xx_reset,
328 .cable_detect = pdc2026x_cable_detect,
329};
330
f37afdac
BZ
331static const struct ide_dma_ops pdc20246_dma_ops = {
332 .dma_host_set = ide_dma_host_set,
333 .dma_setup = ide_dma_setup,
334 .dma_exec_cmd = ide_dma_exec_cmd,
335 .dma_start = ide_dma_start,
336 .dma_end = __ide_dma_end,
5e37bdc0
BZ
337 .dma_test_irq = pdc202xx_dma_test_irq,
338 .dma_lost_irq = pdc202xx_dma_lost_irq,
339 .dma_timeout = pdc202xx_dma_timeout,
340};
341
f37afdac
BZ
342static const struct ide_dma_ops pdc2026x_dma_ops = {
343 .dma_host_set = ide_dma_host_set,
344 .dma_setup = ide_dma_setup,
345 .dma_exec_cmd = ide_dma_exec_cmd,
5e37bdc0
BZ
346 .dma_start = pdc202xx_dma_start,
347 .dma_end = pdc202xx_dma_end,
348 .dma_test_irq = pdc202xx_dma_test_irq,
349 .dma_lost_irq = pdc202xx_dma_lost_irq,
350 .dma_timeout = pdc202xx_dma_timeout,
351};
352
272a3709 353#define DECLARE_PDC2026X_DEV(name_str, udma, extra_flags) \
5ef8cb5d
BZ
354 { \
355 .name = name_str, \
356 .init_chipset = init_chipset_pdc202xx, \
ac95beed 357 .port_ops = &pdc2026x_port_ops, \
5e37bdc0 358 .dma_ops = &pdc2026x_dma_ops, \
4db90a14 359 .host_flags = IDE_HFLAGS_PDC202XX | extra_flags, \
5ef8cb5d
BZ
360 .pio_mask = ATA_PIO4, \
361 .mwdma_mask = ATA_MWDMA2, \
362 .udma_mask = udma, \
363 }
364
85620436 365static const struct ide_port_info pdc202xx_chipsets[] __devinitdata = {
1da177e4
LT
366 { /* 0 */
367 .name = "PDC20246",
1da177e4 368 .init_chipset = init_chipset_pdc202xx,
ac95beed 369 .port_ops = &pdc20246_port_ops,
5e37bdc0 370 .dma_ops = &pdc20246_dma_ops,
4db90a14 371 .host_flags = IDE_HFLAGS_PDC202XX,
4099d143 372 .pio_mask = ATA_PIO4,
5f8b6c34
BZ
373 .mwdma_mask = ATA_MWDMA2,
374 .udma_mask = ATA_UDMA2,
5ef8cb5d
BZ
375 },
376
272a3709
BZ
377 /* 1 */ DECLARE_PDC2026X_DEV("PDC20262", ATA_UDMA4, 0),
378 /* 2 */ DECLARE_PDC2026X_DEV("PDC20263", ATA_UDMA4, 0),
379 /* 3 */ DECLARE_PDC2026X_DEV("PDC20265", ATA_UDMA5, IDE_HFLAG_RQSIZE_256),
380 /* 4 */ DECLARE_PDC2026X_DEV("PDC20267", ATA_UDMA5, IDE_HFLAG_RQSIZE_256),
1da177e4
LT
381};
382
383/**
384 * pdc202xx_init_one - called when a PDC202xx is found
385 * @dev: the pdc202xx device
386 * @id: the matching pci id
387 *
388 * Called when the PCI registration layer (or the IDE initialization)
389 * finds a device matching our IDE device tables.
390 */
391
392static int __devinit pdc202xx_init_one(struct pci_dev *dev, const struct pci_device_id *id)
393{
85620436 394 const struct ide_port_info *d;
97f84baa
BZ
395 u8 idx = id->driver_data;
396
397 d = &pdc202xx_chipsets[idx];
398
399 if (idx < 3)
400 pdc202ata4_fixup_irq(dev, d->name);
401
402 if (idx == 3) {
403 struct pci_dev *bridge = dev->bus->self;
1da177e4 404
97f84baa
BZ
405 if (bridge &&
406 bridge->vendor == PCI_VENDOR_ID_INTEL &&
407 (bridge->device == PCI_DEVICE_ID_INTEL_I960 ||
408 bridge->device == PCI_DEVICE_ID_INTEL_I960RM)) {
409 printk(KERN_INFO "ide: Skipping Promise PDC20265 "
410 "attached to I2O RAID controller\n");
411 return -ENODEV;
412 }
413 }
414
6cdf6eb3 415 return ide_pci_init_one(dev, d, NULL);
1da177e4
LT
416}
417
9cbcc5e3
BZ
418static const struct pci_device_id pdc202xx_pci_tbl[] = {
419 { PCI_VDEVICE(PROMISE, PCI_DEVICE_ID_PROMISE_20246), 0 },
420 { PCI_VDEVICE(PROMISE, PCI_DEVICE_ID_PROMISE_20262), 1 },
421 { PCI_VDEVICE(PROMISE, PCI_DEVICE_ID_PROMISE_20263), 2 },
422 { PCI_VDEVICE(PROMISE, PCI_DEVICE_ID_PROMISE_20265), 3 },
423 { PCI_VDEVICE(PROMISE, PCI_DEVICE_ID_PROMISE_20267), 4 },
1da177e4
LT
424 { 0, },
425};
426MODULE_DEVICE_TABLE(pci, pdc202xx_pci_tbl);
427
428static struct pci_driver driver = {
429 .name = "Promise_Old_IDE",
430 .id_table = pdc202xx_pci_tbl,
431 .probe = pdc202xx_init_one,
574a1c24 432 .remove = ide_pci_remove,
1da177e4
LT
433};
434
82ab1eec 435static int __init pdc202xx_ide_init(void)
1da177e4
LT
436{
437 return ide_pci_register_driver(&driver);
438}
439
574a1c24
BZ
440static void __exit pdc202xx_ide_exit(void)
441{
442 pci_unregister_driver(&driver);
443}
444
1da177e4 445module_init(pdc202xx_ide_init);
574a1c24 446module_exit(pdc202xx_ide_exit);
1da177e4
LT
447
448MODULE_AUTHOR("Andre Hedrick, Frank Tiernan");
449MODULE_DESCRIPTION("PCI driver module for older Promise IDE");
450MODULE_LICENSE("GPL");
This page took 0.360038 seconds and 5 git commands to generate.