aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSergei Shtylyov <sshtylyov@ru.mvista.com>2007-03-03 11:48:53 -0500
committerBartlomiej Zolnierkiewicz <bzolnier@gmail.com>2007-03-03 11:48:53 -0500
commitf92d50e6fd14f6e4601f59aac4cffe617b7b2ce6 (patch)
treecb5859a3087788c579ad051dd679f1acdc33ff1c
parent21b824771309927172247546b0bff0c4e6831875 (diff)
cmd64x: fix PIO mode setup (take 3)
The driver's tuneproc() method fails to set the drive's own speed -- fix this by renaming the function to cmd64x_tune_pio(), making it return the mode set, and "wrapping" the new tuneproc() method around it; while at it, also get rid of the non-working prefetch control code (filtering out related argument values in the "wrapper"), remove redundant PIO5 mode limitation, make cmdprintk() give more sensible mode info, and remove mention about the obsolete /proc/ interface. Get rid of the broken config_chipset_for_pio() which always tried to set PIO4, switch to always auto-tuning PIO instead. Oh, and add the missing PIO5 support to the speedproc() method while at it. :-) Warning: compile tested only -- getting to the real hardware isn't that easy... On Tuesday 06 February 2007 22:11, Mikael Pettersson <mikpe@it.uu.se> wrote: > > Worked fine on my SPARC Ultra5 with a CMD646 IDE controller. Signed-off-by: Sergei Shtylyov <sshtylyov@ru.mvista.com> Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
-rw-r--r--drivers/ide/pci/cmd64x.c108
1 files changed, 43 insertions, 65 deletions
diff --git a/drivers/ide/pci/cmd64x.c b/drivers/ide/pci/cmd64x.c
index 49df27513da7..b0d4825c56a9 100644
--- a/drivers/ide/pci/cmd64x.c
+++ b/drivers/ide/pci/cmd64x.c
@@ -1,6 +1,6 @@
1/* $Id: cmd64x.c,v 1.21 2000/01/30 23:23:16 1/* $Id: cmd64x.c,v 1.21 2000/01/30 23:23:16
2 * 2 *
3 * linux/drivers/ide/pci/cmd64x.c Version 1.30 Sept 10, 2002 3 * linux/drivers/ide/pci/cmd64x.c Version 1.41 Feb 3, 2007
4 * 4 *
5 * cmd64x.c: Enable interrupts at initialization time on Ultra/PCI machines. 5 * cmd64x.c: Enable interrupts at initialization time on Ultra/PCI machines.
6 * Note, this driver is not used at all on other systems because 6 * Note, this driver is not used at all on other systems because
@@ -12,6 +12,7 @@
12 * Copyright (C) 1998 David S. Miller (davem@redhat.com) 12 * Copyright (C) 1998 David S. Miller (davem@redhat.com)
13 * 13 *
14 * Copyright (C) 1999-2002 Andre Hedrick <andre@linux-ide.org> 14 * Copyright (C) 1999-2002 Andre Hedrick <andre@linux-ide.org>
15 * Copyright (C) 2007 MontaVista Software, Inc. <source@mvista.com>
15 */ 16 */
16 17
17#include <linux/module.h> 18#include <linux/module.h>
@@ -262,43 +263,25 @@ static void program_drive_counts (ide_drive_t *drive, int setup_count, int activ
262} 263}
263 264
264/* 265/*
265 * Attempts to set the interface PIO mode. 266 * This routine selects drive's best PIO mode, calculates setup/active/recovery
266 * The preferred method of selecting PIO modes (e.g. mode 4) is 267 * counts, and then writes them into the chipset registers.
267 * "echo 'piomode:4' > /proc/ide/hdx/settings". Special cases are
268 * 8: prefetch off, 9: prefetch on, 255: auto-select best mode.
269 * Called with 255 at boot time.
270 */ 268 */
271 269static u8 cmd64x_tune_pio (ide_drive_t *drive, u8 mode_wanted)
272static void cmd64x_tuneproc (ide_drive_t *drive, u8 mode_wanted)
273{ 270{
274 int setup_time, active_time, recovery_time; 271 int setup_time, active_time, recovery_time;
275 int clock_time, pio_mode, cycle_time; 272 int clock_time, pio_mode, cycle_time;
276 u8 recovery_count2, cycle_count; 273 u8 recovery_count2, cycle_count;
277 int setup_count, active_count, recovery_count; 274 int setup_count, active_count, recovery_count;
278 int bus_speed = system_bus_clock(); 275 int bus_speed = system_bus_clock();
279 /*byte b;*/
280 ide_pio_data_t d; 276 ide_pio_data_t d;
281 277
282 switch (mode_wanted) { 278 pio_mode = ide_get_best_pio_mode(drive, mode_wanted, 5, &d);
283 case 8: /* set prefetch off */
284 case 9: /* set prefetch on */
285 mode_wanted &= 1;
286 /*set_prefetch_mode(index, mode_wanted);*/
287 cmdprintk("%s: %sabled cmd640 prefetch\n",
288 drive->name, mode_wanted ? "en" : "dis");
289 return;
290 }
291
292 mode_wanted = ide_get_best_pio_mode (drive, mode_wanted, 5, &d);
293 pio_mode = d.pio_mode;
294 cycle_time = d.cycle_time; 279 cycle_time = d.cycle_time;
295 280
296 /* 281 /*
297 * I copied all this complicated stuff from cmd640.c and made a few 282 * I copied all this complicated stuff from cmd640.c and made a few
298 * minor changes. For now I am just going to pray that it is correct. 283 * minor changes. For now I am just going to pray that it is correct.
299 */ 284 */
300 if (pio_mode > 5)
301 pio_mode = 5;
302 setup_time = ide_pio_timings[pio_mode].setup_time; 285 setup_time = ide_pio_timings[pio_mode].setup_time;
303 active_time = ide_pio_timings[pio_mode].active_time; 286 active_time = ide_pio_timings[pio_mode].active_time;
304 recovery_time = cycle_time - (setup_time + active_time); 287 recovery_time = cycle_time - (setup_time + active_time);
@@ -320,22 +303,33 @@ static void cmd64x_tuneproc (ide_drive_t *drive, u8 mode_wanted)
320 if (active_count > 16) 303 if (active_count > 16)
321 active_count = 16; /* maximum allowed by cmd646 */ 304 active_count = 16; /* maximum allowed by cmd646 */
322 305
323 /*
324 * In a perfect world, we might set the drive pio mode here
325 * (using WIN_SETFEATURE) before continuing.
326 *
327 * But we do not, because:
328 * 1) this is the wrong place to do it
329 * (proper is do_special() in ide.c)
330 * 2) in practice this is rarely, if ever, necessary
331 */
332 program_drive_counts (drive, setup_count, active_count, recovery_count); 306 program_drive_counts (drive, setup_count, active_count, recovery_count);
333 307
334 cmdprintk("%s: selected cmd646 PIO mode%d : %d (%dns)%s, " 308 cmdprintk("%s: PIO mode wanted %d, selected %d (%dns)%s, "
335 "clocks=%d/%d/%d\n", 309 "clocks=%d/%d/%d\n",
336 drive->name, pio_mode, mode_wanted, cycle_time, 310 drive->name, mode_wanted, pio_mode, cycle_time,
337 d.overridden ? " (overriding vendor mode)" : "", 311 d.overridden ? " (overriding vendor mode)" : "",
338 setup_count, active_count, recovery_count); 312 setup_count, active_count, recovery_count);
313
314 return pio_mode;
315}
316
317/*
318 * Attempts to set drive's PIO mode.
319 * Special cases are 8: prefetch off, 9: prefetch on (both never worked),
320 * and 255: auto-select best mode (used at boot time).
321 */
322static void cmd64x_tune_drive (ide_drive_t *drive, u8 pio)
323{
324 /*
325 * Filter out the prefetch control values
326 * to prevent PIO5 from being programmed
327 */
328 if (pio == 8 || pio == 9)
329 return;
330
331 pio = cmd64x_tune_pio(drive, pio);
332 (void) ide_config_drive_speed(drive, XFER_PIO_0 + pio);
339} 333}
340 334
341static u8 cmd64x_ratemask (ide_drive_t *drive) 335static u8 cmd64x_ratemask (ide_drive_t *drive)
@@ -387,22 +381,6 @@ static u8 cmd64x_ratemask (ide_drive_t *drive)
387 return mode; 381 return mode;
388} 382}
389 383
390static void config_cmd64x_chipset_for_pio (ide_drive_t *drive, u8 set_speed)
391{
392 u8 speed = 0x00;
393 u8 set_pio = ide_get_best_pio_mode(drive, 4, 5, NULL);
394
395 cmd64x_tuneproc(drive, set_pio);
396 speed = XFER_PIO_0 + set_pio;
397 if (set_speed)
398 (void) ide_config_drive_speed(drive, speed);
399}
400
401static void config_chipset_for_pio (ide_drive_t *drive, u8 set_speed)
402{
403 config_cmd64x_chipset_for_pio(drive, set_speed);
404}
405
406static int cmd64x_tune_chipset (ide_drive_t *drive, u8 xferspeed) 384static int cmd64x_tune_chipset (ide_drive_t *drive, u8 xferspeed)
407{ 385{
408 ide_hwif_t *hwif = HWIF(drive); 386 ide_hwif_t *hwif = HWIF(drive);
@@ -414,7 +392,7 @@ static int cmd64x_tune_chipset (ide_drive_t *drive, u8 xferspeed)
414 392
415 u8 speed = ide_rate_filter(cmd64x_ratemask(drive), xferspeed); 393 u8 speed = ide_rate_filter(cmd64x_ratemask(drive), xferspeed);
416 394
417 if (speed > XFER_PIO_4) { 395 if (speed >= XFER_SW_DMA_0) {
418 (void) pci_read_config_byte(dev, pciD, &regD); 396 (void) pci_read_config_byte(dev, pciD, &regD);
419 (void) pci_read_config_byte(dev, pciU, &regU); 397 (void) pci_read_config_byte(dev, pciU, &regU);
420 regD &= ~(unit ? 0x40 : 0x20); 398 regD &= ~(unit ? 0x40 : 0x20);
@@ -438,17 +416,20 @@ static int cmd64x_tune_chipset (ide_drive_t *drive, u8 xferspeed)
438 case XFER_SW_DMA_2: regD |= (unit ? 0x40 : 0x10); break; 416 case XFER_SW_DMA_2: regD |= (unit ? 0x40 : 0x10); break;
439 case XFER_SW_DMA_1: regD |= (unit ? 0x80 : 0x20); break; 417 case XFER_SW_DMA_1: regD |= (unit ? 0x80 : 0x20); break;
440 case XFER_SW_DMA_0: regD |= (unit ? 0xC0 : 0x30); break; 418 case XFER_SW_DMA_0: regD |= (unit ? 0xC0 : 0x30); break;
441 case XFER_PIO_4: cmd64x_tuneproc(drive, 4); break; 419 case XFER_PIO_5:
442 case XFER_PIO_3: cmd64x_tuneproc(drive, 3); break; 420 case XFER_PIO_4:
443 case XFER_PIO_2: cmd64x_tuneproc(drive, 2); break; 421 case XFER_PIO_3:
444 case XFER_PIO_1: cmd64x_tuneproc(drive, 1); break; 422 case XFER_PIO_2:
445 case XFER_PIO_0: cmd64x_tuneproc(drive, 0); break; 423 case XFER_PIO_1:
424 case XFER_PIO_0:
425 (void) cmd64x_tune_pio(drive, speed - XFER_PIO_0);
426 break;
446 427
447 default: 428 default:
448 return 1; 429 return 1;
449 } 430 }
450 431
451 if (speed > XFER_PIO_4) { 432 if (speed >= XFER_SW_DMA_0) {
452 (void) pci_write_config_byte(dev, pciU, regU); 433 (void) pci_write_config_byte(dev, pciU, regU);
453 regD |= (unit ? 0x40 : 0x20); 434 regD |= (unit ? 0x40 : 0x20);
454 (void) pci_write_config_byte(dev, pciD, regD); 435 (void) pci_write_config_byte(dev, pciD, regD);
@@ -461,8 +442,6 @@ static int config_chipset_for_dma (ide_drive_t *drive)
461{ 442{
462 u8 speed = ide_dma_speed(drive, cmd64x_ratemask(drive)); 443 u8 speed = ide_dma_speed(drive, cmd64x_ratemask(drive));
463 444
464 config_chipset_for_pio(drive, !speed);
465
466 if (!speed) 445 if (!speed)
467 return 0; 446 return 0;
468 447
@@ -478,7 +457,7 @@ static int cmd64x_config_drive_for_dma (ide_drive_t *drive)
478 return 0; 457 return 0;
479 458
480 if (ide_use_fast_pio(drive)) 459 if (ide_use_fast_pio(drive))
481 config_chipset_for_pio(drive, 1); 460 cmd64x_tune_drive(drive, 255);
482 461
483 return -1; 462 return -1;
484} 463}
@@ -679,14 +658,13 @@ static void __devinit init_hwif_cmd64x(ide_hwif_t *hwif)
679 pci_read_config_dword(dev, PCI_CLASS_REVISION, &class_rev); 658 pci_read_config_dword(dev, PCI_CLASS_REVISION, &class_rev);
680 class_rev &= 0xff; 659 class_rev &= 0xff;
681 660
682 hwif->tuneproc = &cmd64x_tuneproc; 661 hwif->tuneproc = &cmd64x_tune_drive;
683 hwif->speedproc = &cmd64x_tune_chipset; 662 hwif->speedproc = &cmd64x_tune_chipset;
684 663
685 if (!hwif->dma_base) { 664 hwif->drives[0].autotune = hwif->drives[1].autotune = 1;
686 hwif->drives[0].autotune = 1; 665
687 hwif->drives[1].autotune = 1; 666 if (!hwif->dma_base)
688 return; 667 return;
689 }
690 668
691 hwif->atapi_dma = 1; 669 hwif->atapi_dma = 1;
692 670