aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlan Cox <alan@linux.intel.com>2009-11-30 08:22:49 -0500
committerJeff Garzik <jgarzik@redhat.com>2009-12-03 02:46:36 -0500
commitf20941f334d8fdb6b598658979709b4e94cd034b (patch)
tree1ccca93ec755dea8555c0981e0011dd3e421e286
parent10734fc8d5fbf89e88519d72e58cce83be21941a (diff)
pata_sis: Implement MWDMA for the UDMA 133 capable chips
Bartlomiej pointed out that while this got fixed in the old driver whoever did it didn't port it across. Signed-off-by: Alan Cox <alan@linux.intel.com> Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
-rw-r--r--drivers/ata/pata_sis.c91
1 files changed, 69 insertions, 22 deletions
diff --git a/drivers/ata/pata_sis.c b/drivers/ata/pata_sis.c
index 488e77bcd22b..d70ecece93ee 100644
--- a/drivers/ata/pata_sis.c
+++ b/drivers/ata/pata_sis.c
@@ -252,24 +252,25 @@ static void sis_100_set_piomode (struct ata_port *ap, struct ata_device *adev)
252} 252}
253 253
254/** 254/**
255 * sis_133_set_piomode - Initialize host controller PATA PIO timings 255 * sis_133_do_piomode - Initialize host controller PATA PIO/DMA timings
256 * @ap: Port whose timings we are configuring 256 * @ap: Port whose timings we are configuring
257 * @adev: Device we are configuring for. 257 * @adev: Device we are configuring for.
258 * 258 *
259 * Set PIO mode for device, in host controller PCI config space. This 259 * Set PIO mode for device, in host controller PCI config space. This
260 * function handles PIO set up for the later ATA133 devices. 260 * function handles PIO set up for the later ATA133 devices. The same
261 * timings are used for MWDMA.
261 * 262 *
262 * LOCKING: 263 * LOCKING:
263 * None (inherited from caller). 264 * None (inherited from caller).
264 */ 265 */
265 266
266static void sis_133_set_piomode (struct ata_port *ap, struct ata_device *adev) 267static void sis_133_do_piomode(struct ata_port *ap, struct ata_device *adev,
268 int speed)
267{ 269{
268 struct pci_dev *pdev = to_pci_dev(ap->host->dev); 270 struct pci_dev *pdev = to_pci_dev(ap->host->dev);
269 int port = 0x40; 271 int port = 0x40;
270 u32 t1; 272 u32 t1;
271 u32 reg54; 273 u32 reg54;
272 int speed = adev->pio_mode - XFER_PIO_0;
273 274
274 const u32 timing133[] = { 275 const u32 timing133[] = {
275 0x28269000, /* Recovery << 24 | Act << 16 | Ini << 12 */ 276 0x28269000, /* Recovery << 24 | Act << 16 | Ini << 12 */
@@ -305,6 +306,42 @@ static void sis_133_set_piomode (struct ata_port *ap, struct ata_device *adev)
305} 306}
306 307
307/** 308/**
309 * sis_133_set_piomode - Initialize host controller PATA PIO timings
310 * @ap: Port whose timings we are configuring
311 * @adev: Device we are configuring for.
312 *
313 * Set PIO mode for device, in host controller PCI config space. This
314 * function handles PIO set up for the later ATA133 devices.
315 *
316 * LOCKING:
317 * None (inherited from caller).
318 */
319
320static void sis_133_set_piomode (struct ata_port *ap, struct ata_device *adev)
321{
322
323 sis_133_do_piomode(ap, adev, adev->pio_mode - XFER_PIO_0);
324}
325
326/**
327 * mwdma_clip_to_pio - clip MWDMA mode
328 * @adev: device
329 *
330 * As the SiS shared MWDMA and PIO timings we must program the equivalent
331 * PIO timing for the MWDMA mode but we must not program one higher than
332 * the permitted PIO timing of the device.
333 */
334
335static int mwdma_clip_to_pio(struct ata_device *adev)
336{
337 const int mwdma_to_pio[3] = {
338 XFER_PIO_0, XFER_PIO_3, XFER_PIO_4
339 };
340 return min(mwdma_to_pio[adev->dma_mode - XFER_MW_DMA_0],
341 adev->pio_mode - XFER_PIO_0);
342}
343
344/**
308 * sis_old_set_dmamode - Initialize host controller PATA DMA timings 345 * sis_old_set_dmamode - Initialize host controller PATA DMA timings
309 * @ap: Port whose timings we are configuring 346 * @ap: Port whose timings we are configuring
310 * @adev: Device to program 347 * @adev: Device to program
@@ -332,6 +369,7 @@ static void sis_old_set_dmamode (struct ata_port *ap, struct ata_device *adev)
332 if (adev->dma_mode < XFER_UDMA_0) { 369 if (adev->dma_mode < XFER_UDMA_0) {
333 /* bits 3-0 hold recovery timing bits 8-10 active timing and 370 /* bits 3-0 hold recovery timing bits 8-10 active timing and
334 the higher bits are dependant on the device */ 371 the higher bits are dependant on the device */
372 speed = mwdma_clip_to_pio(adev);
335 timing &= ~0x870F; 373 timing &= ~0x870F;
336 timing |= mwdma_bits[speed]; 374 timing |= mwdma_bits[speed];
337 } else { 375 } else {
@@ -372,6 +410,7 @@ static void sis_66_set_dmamode (struct ata_port *ap, struct ata_device *adev)
372 if (adev->dma_mode < XFER_UDMA_0) { 410 if (adev->dma_mode < XFER_UDMA_0) {
373 /* bits 3-0 hold recovery timing bits 8-10 active timing and 411 /* bits 3-0 hold recovery timing bits 8-10 active timing and
374 the higher bits are dependant on the device, bit 15 udma */ 412 the higher bits are dependant on the device, bit 15 udma */
413 speed = mwdma_clip_to_pio(adev);
375 timing &= ~0x870F; 414 timing &= ~0x870F;
376 timing |= mwdma_bits[speed]; 415 timing |= mwdma_bits[speed];
377 } else { 416 } else {
@@ -389,7 +428,7 @@ static void sis_66_set_dmamode (struct ata_port *ap, struct ata_device *adev)
389 * @adev: Device to program 428 * @adev: Device to program
390 * 429 *
391 * Set UDMA/MWDMA mode for device, in host controller PCI config space. 430 * Set UDMA/MWDMA mode for device, in host controller PCI config space.
392 * Handles UDMA66 and early UDMA100 devices. 431 * Handles later UDMA100 devices.
393 * 432 *
394 * LOCKING: 433 * LOCKING:
395 * None (inherited from caller). 434 * None (inherited from caller).
@@ -400,21 +439,25 @@ static void sis_100_set_dmamode (struct ata_port *ap, struct ata_device *adev)
400 struct pci_dev *pdev = to_pci_dev(ap->host->dev); 439 struct pci_dev *pdev = to_pci_dev(ap->host->dev);
401 int speed = adev->dma_mode - XFER_MW_DMA_0; 440 int speed = adev->dma_mode - XFER_MW_DMA_0;
402 int drive_pci = sis_old_port_base(adev); 441 int drive_pci = sis_old_port_base(adev);
403 u8 timing; 442 u16 timing;
404 443
405 const u8 udma_bits[] = { 0x8B, 0x87, 0x85, 0x83, 0x82, 0x81}; 444 const u16 udma_bits[] = {
445 0x8B00, 0x8700, 0x8500, 0x8300, 0x8200, 0x8100};
446 const u8 mwdma_bits[] = { 0x08, 0x32, 0x31 };
406 447
407 pci_read_config_byte(pdev, drive_pci + 1, &timing); 448 pci_read_config_word(pdev, drive_pci, &timing);
408 449
409 if (adev->dma_mode < XFER_UDMA_0) { 450 if (adev->dma_mode < XFER_UDMA_0) {
410 /* NOT SUPPORTED YET: NEED DATA SHEET. DITTO IN OLD DRIVER */ 451 speed = mwdma_clip_to_pio(adev);
452 timing &= ~0x80FF;
453 timing |= mwdma_bits[speed];
411 } else { 454 } else {
412 /* Bit 7 is UDMA on/off, bit 0-3 are cycle time */ 455 /* Bit 7 is UDMA on/off, bit 0-3 are cycle time */
413 speed = adev->dma_mode - XFER_UDMA_0; 456 speed = adev->dma_mode - XFER_UDMA_0;
414 timing &= ~0x8F; 457 timing &= ~0x8F00;
415 timing |= udma_bits[speed]; 458 timing |= udma_bits[speed];
416 } 459 }
417 pci_write_config_byte(pdev, drive_pci + 1, timing); 460 pci_write_config_word(pdev, drive_pci, timing);
418} 461}
419 462
420/** 463/**
@@ -434,21 +477,26 @@ static void sis_133_early_set_dmamode (struct ata_port *ap, struct ata_device *a
434 struct pci_dev *pdev = to_pci_dev(ap->host->dev); 477 struct pci_dev *pdev = to_pci_dev(ap->host->dev);
435 int speed = adev->dma_mode - XFER_MW_DMA_0; 478 int speed = adev->dma_mode - XFER_MW_DMA_0;
436 int drive_pci = sis_old_port_base(adev); 479 int drive_pci = sis_old_port_base(adev);
437 u8 timing; 480 u16 timing;
438 /* Low 4 bits are timing */ 481 /* Bits 15-12 are timing */
439 static const u8 udma_bits[] = { 0x8F, 0x8A, 0x87, 0x85, 0x83, 0x82, 0x81}; 482 static const u16 udma_bits[] = {
483 0x8F00, 0x8A00, 0x8700, 0x8500, 0x8300, 0x8200, 0x8100
484 };
485 static const u8 mwdma_bits[] = { 0x08, 0x32, 0x31 };
440 486
441 pci_read_config_byte(pdev, drive_pci + 1, &timing); 487 pci_read_config_word(pdev, drive_pci, &timing);
442 488
443 if (adev->dma_mode < XFER_UDMA_0) { 489 if (adev->dma_mode < XFER_UDMA_0) {
444 /* NOT SUPPORTED YET: NEED DATA SHEET. DITTO IN OLD DRIVER */ 490 speed = mwdma_clip_to_pio(adev);
491 timing &= ~0x80FF;
492 timing = mwdma_bits[speed];
445 } else { 493 } else {
446 /* Bit 7 is UDMA on/off, bit 0-3 are cycle time */ 494 /* Bit 7 is UDMA on/off, bit 0-3 are cycle time */
447 speed = adev->dma_mode - XFER_UDMA_0; 495 speed = adev->dma_mode - XFER_UDMA_0;
448 timing &= ~0x8F; 496 timing &= ~0x8F00;
449 timing |= udma_bits[speed]; 497 timing |= udma_bits[speed];
450 } 498 }
451 pci_write_config_byte(pdev, drive_pci + 1, timing); 499 pci_write_config_word(pdev, drive_pci, timing);
452} 500}
453 501
454/** 502/**
@@ -479,13 +527,12 @@ static void sis_133_set_dmamode (struct ata_port *ap, struct ata_device *adev)
479 if (reg54 & 0x40000000) 527 if (reg54 & 0x40000000)
480 port = 0x70; 528 port = 0x70;
481 port += (8 * ap->port_no) + (4 * adev->devno); 529 port += (8 * ap->port_no) + (4 * adev->devno);
482
483 pci_read_config_dword(pdev, port, &t1); 530 pci_read_config_dword(pdev, port, &t1);
484 531
485 if (adev->dma_mode < XFER_UDMA_0) { 532 if (adev->dma_mode < XFER_UDMA_0) {
486 t1 &= ~0x00000004; 533 speed = mwdma_clip_to_pio(adev);
487 /* FIXME: need data sheet to add MWDMA here. Also lacking on 534 sis_133_do_piomode(ap, adev, speed);
488 ide/pci driver */ 535 t1 &= ~4; /* UDMA off */
489 } else { 536 } else {
490 speed = adev->dma_mode - XFER_UDMA_0; 537 speed = adev->dma_mode - XFER_UDMA_0;
491 /* if & 8 no UDMA133 - need info for ... */ 538 /* if & 8 no UDMA133 - need info for ... */