aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ide/via82cxxx.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/ide/via82cxxx.c')
-rw-r--r--drivers/ide/via82cxxx.c132
1 files changed, 108 insertions, 24 deletions
diff --git a/drivers/ide/via82cxxx.c b/drivers/ide/via82cxxx.c
index 028de26a25fe..e65d010b708d 100644
--- a/drivers/ide/via82cxxx.c
+++ b/drivers/ide/via82cxxx.c
@@ -6,7 +6,7 @@
6 * vt8235, vt8237, vt8237a 6 * vt8235, vt8237, vt8237a
7 * 7 *
8 * Copyright (c) 2000-2002 Vojtech Pavlik 8 * Copyright (c) 2000-2002 Vojtech Pavlik
9 * Copyright (c) 2007 Bartlomiej Zolnierkiewicz 9 * Copyright (c) 2007-2010 Bartlomiej Zolnierkiewicz
10 * 10 *
11 * Based on the work of: 11 * Based on the work of:
12 * Michel Aubry 12 * Michel Aubry
@@ -54,6 +54,11 @@
54#define VIA_NO_UNMASK 0x08 /* Doesn't work with IRQ unmasking on */ 54#define VIA_NO_UNMASK 0x08 /* Doesn't work with IRQ unmasking on */
55#define VIA_BAD_ID 0x10 /* Has wrong vendor ID (0x1107) */ 55#define VIA_BAD_ID 0x10 /* Has wrong vendor ID (0x1107) */
56#define VIA_BAD_AST 0x20 /* Don't touch Address Setup Timing */ 56#define VIA_BAD_AST 0x20 /* Don't touch Address Setup Timing */
57#define VIA_SATA_PATA 0x80 /* SATA/PATA combined configuration */
58
59enum {
60 VIA_IDFLAG_SINGLE = (1 << 1), /* single channel controller */
61};
57 62
58/* 63/*
59 * VIA SouthBridge chips. 64 * VIA SouthBridge chips.
@@ -67,11 +72,13 @@ static struct via_isa_bridge {
67 u8 udma_mask; 72 u8 udma_mask;
68 u8 flags; 73 u8 flags;
69} via_isa_bridges[] = { 74} via_isa_bridges[] = {
70 { "vx855", PCI_DEVICE_ID_VIA_VX855, 0x00, 0x2f, ATA_UDMA6, VIA_BAD_AST }, 75 { "vx855", PCI_DEVICE_ID_VIA_VX855, 0x00, 0x2f, ATA_UDMA6, VIA_BAD_AST | VIA_SATA_PATA },
71 { "vx800", PCI_DEVICE_ID_VIA_VX800, 0x00, 0x2f, ATA_UDMA6, VIA_BAD_AST }, 76 { "vx800", PCI_DEVICE_ID_VIA_VX800, 0x00, 0x2f, ATA_UDMA6, VIA_BAD_AST | VIA_SATA_PATA },
72 { "cx700", PCI_DEVICE_ID_VIA_CX700, 0x00, 0x2f, ATA_UDMA6, VIA_BAD_AST }, 77 { "cx700", PCI_DEVICE_ID_VIA_CX700, 0x00, 0x2f, ATA_UDMA6, VIA_BAD_AST | VIA_SATA_PATA },
78 { "vt8261", PCI_DEVICE_ID_VIA_8261, 0x00, 0x2f, ATA_UDMA6, VIA_BAD_AST },
73 { "vt8237s", PCI_DEVICE_ID_VIA_8237S, 0x00, 0x2f, ATA_UDMA6, VIA_BAD_AST }, 79 { "vt8237s", PCI_DEVICE_ID_VIA_8237S, 0x00, 0x2f, ATA_UDMA6, VIA_BAD_AST },
74 { "vt6410", PCI_DEVICE_ID_VIA_6410, 0x00, 0x2f, ATA_UDMA6, VIA_BAD_AST }, 80 { "vt6410", PCI_DEVICE_ID_VIA_6410, 0x00, 0x2f, ATA_UDMA6, VIA_BAD_AST },
81 { "vt6415", PCI_DEVICE_ID_VIA_6410, 0x00, 0xff, ATA_UDMA6, VIA_BAD_AST },
75 { "vt8251", PCI_DEVICE_ID_VIA_8251, 0x00, 0x2f, ATA_UDMA6, VIA_BAD_AST }, 82 { "vt8251", PCI_DEVICE_ID_VIA_8251, 0x00, 0x2f, ATA_UDMA6, VIA_BAD_AST },
76 { "vt8237", PCI_DEVICE_ID_VIA_8237, 0x00, 0x2f, ATA_UDMA6, VIA_BAD_AST }, 83 { "vt8237", PCI_DEVICE_ID_VIA_8237, 0x00, 0x2f, ATA_UDMA6, VIA_BAD_AST },
77 { "vt8237a", PCI_DEVICE_ID_VIA_8237A, 0x00, 0x2f, ATA_UDMA6, VIA_BAD_AST }, 84 { "vt8237a", PCI_DEVICE_ID_VIA_8237A, 0x00, 0x2f, ATA_UDMA6, VIA_BAD_AST },
@@ -92,6 +99,7 @@ static struct via_isa_bridge {
92 { "vt82c586", PCI_DEVICE_ID_VIA_82C586_0, 0x00, 0x0f, 0x00, VIA_SET_FIFO }, 99 { "vt82c586", PCI_DEVICE_ID_VIA_82C586_0, 0x00, 0x0f, 0x00, VIA_SET_FIFO },
93 { "vt82c576", PCI_DEVICE_ID_VIA_82C576, 0x00, 0x2f, 0x00, VIA_SET_FIFO | VIA_NO_UNMASK }, 100 { "vt82c576", PCI_DEVICE_ID_VIA_82C576, 0x00, 0x2f, 0x00, VIA_SET_FIFO | VIA_NO_UNMASK },
94 { "vt82c576", PCI_DEVICE_ID_VIA_82C576, 0x00, 0x2f, 0x00, VIA_SET_FIFO | VIA_NO_UNMASK | VIA_BAD_ID }, 101 { "vt82c576", PCI_DEVICE_ID_VIA_82C576, 0x00, 0x2f, 0x00, VIA_SET_FIFO | VIA_NO_UNMASK | VIA_BAD_ID },
102 { "vtxxxx", PCI_DEVICE_ID_VIA_ANON, 0x00, 0x2f, ATA_UDMA6, VIA_BAD_AST },
95 { NULL } 103 { NULL }
96}; 104};
97 105
@@ -102,6 +110,7 @@ struct via82cxxx_dev
102{ 110{
103 struct via_isa_bridge *via_config; 111 struct via_isa_bridge *via_config;
104 unsigned int via_80w; 112 unsigned int via_80w;
113 u8 cached_device[2];
105}; 114};
106 115
107/** 116/**
@@ -137,30 +146,45 @@ static void via_set_speed(ide_hwif_t *hwif, u8 dn, struct ide_timing *timing)
137 case ATA_UDMA4: t = timing->udma ? (0xe8 | (clamp_val(timing->udma, 2, 9) - 2)) : 0x0f; break; 146 case ATA_UDMA4: t = timing->udma ? (0xe8 | (clamp_val(timing->udma, 2, 9) - 2)) : 0x0f; break;
138 case ATA_UDMA5: t = timing->udma ? (0xe0 | (clamp_val(timing->udma, 2, 9) - 2)) : 0x07; break; 147 case ATA_UDMA5: t = timing->udma ? (0xe0 | (clamp_val(timing->udma, 2, 9) - 2)) : 0x07; break;
139 case ATA_UDMA6: t = timing->udma ? (0xe0 | (clamp_val(timing->udma, 2, 9) - 2)) : 0x07; break; 148 case ATA_UDMA6: t = timing->udma ? (0xe0 | (clamp_val(timing->udma, 2, 9) - 2)) : 0x07; break;
140 default: return;
141 } 149 }
142 150
143 pci_write_config_byte(dev, VIA_UDMA_TIMING + (3 - dn), t); 151 /* Set UDMA unless device is not UDMA capable */
152 if (vdev->via_config->udma_mask) {
153 u8 udma_etc;
154
155 pci_read_config_byte(dev, VIA_UDMA_TIMING + 3 - dn, &udma_etc);
156
157 /* clear transfer mode bit */
158 udma_etc &= ~0x20;
159
160 if (timing->udma) {
161 /* preserve 80-wire cable detection bit */
162 udma_etc &= 0x10;
163 udma_etc |= t;
164 }
165
166 pci_write_config_byte(dev, VIA_UDMA_TIMING + 3 - dn, udma_etc);
167 }
144} 168}
145 169
146/** 170/**
147 * via_set_drive - configure transfer mode 171 * via_set_drive - configure transfer mode
172 * @hwif: port
148 * @drive: Drive to set up 173 * @drive: Drive to set up
149 * @speed: desired speed
150 * 174 *
151 * via_set_drive() computes timing values configures the chipset to 175 * via_set_drive() computes timing values configures the chipset to
152 * a desired transfer mode. It also can be called by upper layers. 176 * a desired transfer mode. It also can be called by upper layers.
153 */ 177 */
154 178
155static void via_set_drive(ide_drive_t *drive, const u8 speed) 179static void via_set_drive(ide_hwif_t *hwif, ide_drive_t *drive)
156{ 180{
157 ide_hwif_t *hwif = drive->hwif;
158 ide_drive_t *peer = ide_get_pair_dev(drive); 181 ide_drive_t *peer = ide_get_pair_dev(drive);
159 struct pci_dev *dev = to_pci_dev(hwif->dev); 182 struct pci_dev *dev = to_pci_dev(hwif->dev);
160 struct ide_host *host = pci_get_drvdata(dev); 183 struct ide_host *host = pci_get_drvdata(dev);
161 struct via82cxxx_dev *vdev = host->host_priv; 184 struct via82cxxx_dev *vdev = host->host_priv;
162 struct ide_timing t, p; 185 struct ide_timing t, p;
163 unsigned int T, UT; 186 unsigned int T, UT;
187 const u8 speed = drive->dma_mode;
164 188
165 T = 1000000000 / via_clock; 189 T = 1000000000 / via_clock;
166 190
@@ -175,7 +199,7 @@ static void via_set_drive(ide_drive_t *drive, const u8 speed)
175 ide_timing_compute(drive, speed, &t, T, UT); 199 ide_timing_compute(drive, speed, &t, T, UT);
176 200
177 if (peer) { 201 if (peer) {
178 ide_timing_compute(peer, peer->current_speed, &p, T, UT); 202 ide_timing_compute(peer, peer->pio_mode, &p, T, UT);
179 ide_timing_merge(&p, &t, &t, IDE_TIMING_8BIT); 203 ide_timing_merge(&p, &t, &t, IDE_TIMING_8BIT);
180 } 204 }
181 205
@@ -184,22 +208,24 @@ static void via_set_drive(ide_drive_t *drive, const u8 speed)
184 208
185/** 209/**
186 * via_set_pio_mode - set host controller for PIO mode 210 * via_set_pio_mode - set host controller for PIO mode
211 * @hwif: port
187 * @drive: drive 212 * @drive: drive
188 * @pio: PIO mode number
189 * 213 *
190 * A callback from the upper layers for PIO-only tuning. 214 * A callback from the upper layers for PIO-only tuning.
191 */ 215 */
192 216
193static void via_set_pio_mode(ide_drive_t *drive, const u8 pio) 217static void via_set_pio_mode(ide_hwif_t *hwif, ide_drive_t *drive)
194{ 218{
195 via_set_drive(drive, XFER_PIO_0 + pio); 219 drive->dma_mode = drive->pio_mode;
220 via_set_drive(hwif, drive);
196} 221}
197 222
198static struct via_isa_bridge *via_config_find(struct pci_dev **isa) 223static struct via_isa_bridge *via_config_find(struct pci_dev **isa)
199{ 224{
200 struct via_isa_bridge *via_config; 225 struct via_isa_bridge *via_config;
201 226
202 for (via_config = via_isa_bridges; via_config->id; via_config++) 227 for (via_config = via_isa_bridges;
228 via_config->id != PCI_DEVICE_ID_VIA_ANON; via_config++)
203 if ((*isa = pci_get_device(PCI_VENDOR_ID_VIA + 229 if ((*isa = pci_get_device(PCI_VENDOR_ID_VIA +
204 !!(via_config->flags & VIA_BAD_ID), 230 !!(via_config->flags & VIA_BAD_ID),
205 via_config->id, NULL))) { 231 via_config->id, NULL))) {
@@ -362,6 +388,9 @@ static u8 via82cxxx_cable_detect(ide_hwif_t *hwif)
362 if (via_cable_override(pdev)) 388 if (via_cable_override(pdev))
363 return ATA_CBL_PATA40_SHORT; 389 return ATA_CBL_PATA40_SHORT;
364 390
391 if ((vdev->via_config->flags & VIA_SATA_PATA) && hwif->channel == 0)
392 return ATA_CBL_SATA;
393
365 if ((vdev->via_80w >> hwif->channel) & 1) 394 if ((vdev->via_80w >> hwif->channel) & 1)
366 return ATA_CBL_PATA80; 395 return ATA_CBL_PATA80;
367 else 396 else
@@ -374,10 +403,66 @@ static const struct ide_port_ops via_port_ops = {
374 .cable_detect = via82cxxx_cable_detect, 403 .cable_detect = via82cxxx_cable_detect,
375}; 404};
376 405
406static void via_write_devctl(ide_hwif_t *hwif, u8 ctl)
407{
408 struct via82cxxx_dev *vdev = hwif->host->host_priv;
409
410 outb(ctl, hwif->io_ports.ctl_addr);
411 outb(vdev->cached_device[hwif->channel], hwif->io_ports.device_addr);
412}
413
414static void __via_dev_select(ide_drive_t *drive, u8 select)
415{
416 ide_hwif_t *hwif = drive->hwif;
417 struct via82cxxx_dev *vdev = hwif->host->host_priv;
418
419 outb(select, hwif->io_ports.device_addr);
420 vdev->cached_device[hwif->channel] = select;
421}
422
423static void via_dev_select(ide_drive_t *drive)
424{
425 __via_dev_select(drive, drive->select | ATA_DEVICE_OBS);
426}
427
428static void via_tf_load(ide_drive_t *drive, struct ide_taskfile *tf, u8 valid)
429{
430 ide_hwif_t *hwif = drive->hwif;
431 struct ide_io_ports *io_ports = &hwif->io_ports;
432
433 if (valid & IDE_VALID_FEATURE)
434 outb(tf->feature, io_ports->feature_addr);
435 if (valid & IDE_VALID_NSECT)
436 outb(tf->nsect, io_ports->nsect_addr);
437 if (valid & IDE_VALID_LBAL)
438 outb(tf->lbal, io_ports->lbal_addr);
439 if (valid & IDE_VALID_LBAM)
440 outb(tf->lbam, io_ports->lbam_addr);
441 if (valid & IDE_VALID_LBAH)
442 outb(tf->lbah, io_ports->lbah_addr);
443 if (valid & IDE_VALID_DEVICE)
444 __via_dev_select(drive, tf->device);
445}
446
447const struct ide_tp_ops via_tp_ops = {
448 .exec_command = ide_exec_command,
449 .read_status = ide_read_status,
450 .read_altstatus = ide_read_altstatus,
451 .write_devctl = via_write_devctl,
452
453 .dev_select = via_dev_select,
454 .tf_load = via_tf_load,
455 .tf_read = ide_tf_read,
456
457 .input_data = ide_input_data,
458 .output_data = ide_output_data,
459};
460
377static const struct ide_port_info via82cxxx_chipset __devinitdata = { 461static const struct ide_port_info via82cxxx_chipset __devinitdata = {
378 .name = DRV_NAME, 462 .name = DRV_NAME,
379 .init_chipset = init_chipset_via82cxxx, 463 .init_chipset = init_chipset_via82cxxx,
380 .enablebits = { { 0x40, 0x02, 0x02 }, { 0x40, 0x01, 0x01 } }, 464 .enablebits = { { 0x40, 0x02, 0x02 }, { 0x40, 0x01, 0x01 } },
465 .tp_ops = &via_tp_ops,
381 .port_ops = &via_port_ops, 466 .port_ops = &via_port_ops,
382 .host_flags = IDE_HFLAG_PIO_NO_BLACKLIST | 467 .host_flags = IDE_HFLAG_PIO_NO_BLACKLIST |
383 IDE_HFLAG_POST_SET_MODE | 468 IDE_HFLAG_POST_SET_MODE |
@@ -402,11 +487,6 @@ static int __devinit via_init_one(struct pci_dev *dev, const struct pci_device_i
402 * Find the ISA bridge and check we know what it is. 487 * Find the ISA bridge and check we know what it is.
403 */ 488 */
404 via_config = via_config_find(&isa); 489 via_config = via_config_find(&isa);
405 if (!via_config->id) {
406 printk(KERN_WARNING DRV_NAME " %s: unknown chipset, skipping\n",
407 pci_name(dev));
408 return -ENODEV;
409 }
410 490
411 /* 491 /*
412 * Print the boot message. 492 * Print the boot message.
@@ -436,10 +516,13 @@ static int __devinit via_init_one(struct pci_dev *dev, const struct pci_device_i
436 via_clock = 33333; 516 via_clock = 33333;
437 } 517 }
438 518
439 if (idx == 0) 519 if (idx == 1)
440 d.host_flags |= IDE_HFLAG_NO_AUTODMA;
441 else
442 d.enablebits[1].reg = d.enablebits[0].reg = 0; 520 d.enablebits[1].reg = d.enablebits[0].reg = 0;
521 else
522 d.host_flags |= IDE_HFLAG_NO_AUTODMA;
523
524 if (idx == VIA_IDFLAG_SINGLE)
525 d.host_flags |= IDE_HFLAG_SINGLE;
443 526
444 if ((via_config->flags & VIA_NO_UNMASK) == 0) 527 if ((via_config->flags & VIA_NO_UNMASK) == 0)
445 d.host_flags |= IDE_HFLAG_UNMASK_IRQS; 528 d.host_flags |= IDE_HFLAG_UNMASK_IRQS;
@@ -475,8 +558,9 @@ static const struct pci_device_id via_pci_tbl[] = {
475 { PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_82C576_1), 0 }, 558 { PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_82C576_1), 0 },
476 { PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_82C586_1), 0 }, 559 { PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_82C586_1), 0 },
477 { PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_CX700_IDE), 0 }, 560 { PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_CX700_IDE), 0 },
478 { PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_VX855_IDE), 0 }, 561 { PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_VX855_IDE), VIA_IDFLAG_SINGLE },
479 { PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_6410), 1 }, 562 { PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_6410), 1 },
563 { PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_6415), 1 },
480 { PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_SATA_EIDE), 1 }, 564 { PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_SATA_EIDE), 1 },
481 { 0, }, 565 { 0, },
482}; 566};
@@ -504,6 +588,6 @@ static void __exit via_ide_exit(void)
504module_init(via_ide_init); 588module_init(via_ide_init);
505module_exit(via_ide_exit); 589module_exit(via_ide_exit);
506 590
507MODULE_AUTHOR("Vojtech Pavlik, Michel Aubry, Jeff Garzik, Andre Hedrick"); 591MODULE_AUTHOR("Vojtech Pavlik, Bartlomiej Zolnierkiewicz, Michel Aubry, Jeff Garzik, Andre Hedrick");
508MODULE_DESCRIPTION("PCI driver module for VIA IDE"); 592MODULE_DESCRIPTION("PCI driver module for VIA IDE");
509MODULE_LICENSE("GPL"); 593MODULE_LICENSE("GPL");