diff options
Diffstat (limited to 'drivers/ide/pci/cs5530.c')
-rw-r--r-- | drivers/ide/pci/cs5530.c | 50 |
1 files changed, 9 insertions, 41 deletions
diff --git a/drivers/ide/pci/cs5530.c b/drivers/ide/pci/cs5530.c index 741507b4cd93..e4121577cef0 100644 --- a/drivers/ide/pci/cs5530.c +++ b/drivers/ide/pci/cs5530.c | |||
@@ -30,22 +30,6 @@ | |||
30 | #include <asm/io.h> | 30 | #include <asm/io.h> |
31 | #include <asm/irq.h> | 31 | #include <asm/irq.h> |
32 | 32 | ||
33 | /** | ||
34 | * cs5530_xfer_set_mode - set a new transfer mode at the drive | ||
35 | * @drive: drive to tune | ||
36 | * @mode: new mode | ||
37 | * | ||
38 | * Logging wrapper to the IDE driver speed configuration. This can | ||
39 | * probably go away now. | ||
40 | */ | ||
41 | |||
42 | static int cs5530_set_xfer_mode (ide_drive_t *drive, u8 mode) | ||
43 | { | ||
44 | printk(KERN_DEBUG "%s: cs5530_set_xfer_mode(%s)\n", | ||
45 | drive->name, ide_xfer_verbose(mode)); | ||
46 | return (ide_config_drive_speed(drive, mode)); | ||
47 | } | ||
48 | |||
49 | /* | 33 | /* |
50 | * Here are the standard PIO mode 0-4 timings for each "format". | 34 | * Here are the standard PIO mode 0-4 timings for each "format". |
51 | * Format-0 uses fast data reg timings, with slower command reg timings. | 35 | * Format-0 uses fast data reg timings, with slower command reg timings. |
@@ -62,20 +46,12 @@ static unsigned int cs5530_pio_timings[2][5] = { | |||
62 | #define CS5530_BAD_PIO(timings) (((timings)&~0x80000000)==0x0000e132) | 46 | #define CS5530_BAD_PIO(timings) (((timings)&~0x80000000)==0x0000e132) |
63 | #define CS5530_BASEREG(hwif) (((hwif)->dma_base & ~0xf) + ((hwif)->channel ? 0x30 : 0x20)) | 47 | #define CS5530_BASEREG(hwif) (((hwif)->dma_base & ~0xf) + ((hwif)->channel ? 0x30 : 0x20)) |
64 | 48 | ||
65 | static void cs5530_tunepio(ide_drive_t *drive, u8 pio) | ||
66 | { | ||
67 | unsigned long basereg = CS5530_BASEREG(drive->hwif); | ||
68 | unsigned int format = (inl(basereg + 4) >> 31) & 1; | ||
69 | |||
70 | outl(cs5530_pio_timings[format][pio], basereg + ((drive->dn & 1)<<3)); | ||
71 | } | ||
72 | |||
73 | /** | 49 | /** |
74 | * cs5530_set_pio_mode - set PIO mode | 50 | * cs5530_set_pio_mode - set host controller for PIO mode |
75 | * @drive: drive | 51 | * @drive: drive |
76 | * @pio: PIO mode number | 52 | * @pio: PIO mode number |
77 | * | 53 | * |
78 | * Handles setting of PIO mode for both the chipset and drive. | 54 | * Handles setting of PIO mode for the chipset. |
79 | * | 55 | * |
80 | * The init_hwif_cs5530() routine guarantees that all drives | 56 | * The init_hwif_cs5530() routine guarantees that all drives |
81 | * will have valid default PIO timings set up before we get here. | 57 | * will have valid default PIO timings set up before we get here. |
@@ -83,8 +59,10 @@ static void cs5530_tunepio(ide_drive_t *drive, u8 pio) | |||
83 | 59 | ||
84 | static void cs5530_set_pio_mode(ide_drive_t *drive, const u8 pio) | 60 | static void cs5530_set_pio_mode(ide_drive_t *drive, const u8 pio) |
85 | { | 61 | { |
86 | if (cs5530_set_xfer_mode(drive, XFER_PIO_0 + pio) == 0) | 62 | unsigned long basereg = CS5530_BASEREG(drive->hwif); |
87 | cs5530_tunepio(drive, pio); | 63 | unsigned int format = (inl(basereg + 4) >> 31) & 1; |
64 | |||
65 | outl(cs5530_pio_timings[format][pio], basereg + ((drive->dn & 1)<<3)); | ||
88 | } | 66 | } |
89 | 67 | ||
90 | /** | 68 | /** |
@@ -142,20 +120,11 @@ static int cs5530_config_dma(ide_drive_t *drive) | |||
142 | return 1; | 120 | return 1; |
143 | } | 121 | } |
144 | 122 | ||
145 | static int cs5530_tune_chipset(ide_drive_t *drive, const u8 mode) | 123 | static void cs5530_set_dma_mode(ide_drive_t *drive, const u8 mode) |
146 | { | 124 | { |
147 | unsigned long basereg; | 125 | unsigned long basereg; |
148 | unsigned int reg, timings = 0; | 126 | unsigned int reg, timings = 0; |
149 | 127 | ||
150 | /* | ||
151 | * Tell the drive to switch to the new mode; abort on failure. | ||
152 | */ | ||
153 | if (cs5530_set_xfer_mode(drive, mode)) | ||
154 | return 1; /* failure */ | ||
155 | |||
156 | /* | ||
157 | * Now tune the chipset to match the drive: | ||
158 | */ | ||
159 | switch (mode) { | 128 | switch (mode) { |
160 | case XFER_UDMA_0: timings = 0x00921250; break; | 129 | case XFER_UDMA_0: timings = 0x00921250; break; |
161 | case XFER_UDMA_1: timings = 0x00911140; break; | 130 | case XFER_UDMA_1: timings = 0x00911140; break; |
@@ -180,8 +149,6 @@ static int cs5530_tune_chipset(ide_drive_t *drive, const u8 mode) | |||
180 | outl(reg, basereg + 4); /* write drive0 config register */ | 149 | outl(reg, basereg + 4); /* write drive0 config register */ |
181 | outl(timings, basereg + 12); /* write drive1 config register */ | 150 | outl(timings, basereg + 12); /* write drive1 config register */ |
182 | } | 151 | } |
183 | |||
184 | return 0; /* success */ | ||
185 | } | 152 | } |
186 | 153 | ||
187 | /** | 154 | /** |
@@ -299,7 +266,7 @@ static void __devinit init_hwif_cs5530 (ide_hwif_t *hwif) | |||
299 | hwif->serialized = hwif->mate->serialized = 1; | 266 | hwif->serialized = hwif->mate->serialized = 1; |
300 | 267 | ||
301 | hwif->set_pio_mode = &cs5530_set_pio_mode; | 268 | hwif->set_pio_mode = &cs5530_set_pio_mode; |
302 | hwif->speedproc = &cs5530_tune_chipset; | 269 | hwif->set_dma_mode = &cs5530_set_dma_mode; |
303 | 270 | ||
304 | basereg = CS5530_BASEREG(hwif); | 271 | basereg = CS5530_BASEREG(hwif); |
305 | d0_timings = inl(basereg + 0); | 272 | d0_timings = inl(basereg + 0); |
@@ -340,6 +307,7 @@ static ide_pci_device_t cs5530_chipset __devinitdata = { | |||
340 | .autodma = AUTODMA, | 307 | .autodma = AUTODMA, |
341 | .bootable = ON_BOARD, | 308 | .bootable = ON_BOARD, |
342 | .pio_mask = ATA_PIO4, | 309 | .pio_mask = ATA_PIO4, |
310 | .host_flags = IDE_HFLAG_POST_SET_MODE, | ||
343 | }; | 311 | }; |
344 | 312 | ||
345 | static int __devinit cs5530_init_one(struct pci_dev *dev, const struct pci_device_id *id) | 313 | static int __devinit cs5530_init_one(struct pci_dev *dev, const struct pci_device_id *id) |