diff options
Diffstat (limited to 'drivers/ide/pci/sl82c105.c')
-rw-r--r-- | drivers/ide/pci/sl82c105.c | 247 |
1 files changed, 100 insertions, 147 deletions
diff --git a/drivers/ide/pci/sl82c105.c b/drivers/ide/pci/sl82c105.c index 3a8a76fc78c7..fe3b4b91f854 100644 --- a/drivers/ide/pci/sl82c105.c +++ b/drivers/ide/pci/sl82c105.c | |||
@@ -11,6 +11,8 @@ | |||
11 | * Merge in Russell's HW workarounds, fix various problems | 11 | * Merge in Russell's HW workarounds, fix various problems |
12 | * with the timing registers setup. | 12 | * with the timing registers setup. |
13 | * -- Benjamin Herrenschmidt (01/11/03) benh@kernel.crashing.org | 13 | * -- Benjamin Herrenschmidt (01/11/03) benh@kernel.crashing.org |
14 | * | ||
15 | * Copyright (C) 2006-2007 MontaVista Software, Inc. <source@mvista.com> | ||
14 | */ | 16 | */ |
15 | 17 | ||
16 | #include <linux/types.h> | 18 | #include <linux/types.h> |
@@ -47,25 +49,19 @@ | |||
47 | #define CTRL_P0EN (1 << 0) | 49 | #define CTRL_P0EN (1 << 0) |
48 | 50 | ||
49 | /* | 51 | /* |
50 | * Convert a PIO mode and cycle time to the required on/off | 52 | * Convert a PIO mode and cycle time to the required on/off times |
51 | * times for the interface. This has protection against run-away | 53 | * for the interface. This has protection against runaway timings. |
52 | * timings. | ||
53 | */ | 54 | */ |
54 | static unsigned int get_timing_sl82c105(ide_pio_data_t *p) | 55 | static unsigned int get_pio_timings(ide_pio_data_t *p) |
55 | { | 56 | { |
56 | unsigned int cmd_on; | 57 | unsigned int cmd_on, cmd_off; |
57 | unsigned int cmd_off; | ||
58 | 58 | ||
59 | cmd_on = (ide_pio_timings[p->pio_mode].active_time + 29) / 30; | 59 | cmd_on = (ide_pio_timings[p->pio_mode].active_time + 29) / 30; |
60 | cmd_off = (p->cycle_time - 30 * cmd_on + 29) / 30; | 60 | cmd_off = (p->cycle_time - 30 * cmd_on + 29) / 30; |
61 | 61 | ||
62 | if (cmd_on > 32) | ||
63 | cmd_on = 32; | ||
64 | if (cmd_on == 0) | 62 | if (cmd_on == 0) |
65 | cmd_on = 1; | 63 | cmd_on = 1; |
66 | 64 | ||
67 | if (cmd_off > 32) | ||
68 | cmd_off = 32; | ||
69 | if (cmd_off == 0) | 65 | if (cmd_off == 0) |
70 | cmd_off = 1; | 66 | cmd_off = 1; |
71 | 67 | ||
@@ -73,100 +69,59 @@ static unsigned int get_timing_sl82c105(ide_pio_data_t *p) | |||
73 | } | 69 | } |
74 | 70 | ||
75 | /* | 71 | /* |
76 | * Configure the drive and chipset for PIO | 72 | * Configure the chipset for PIO mode. |
77 | */ | 73 | */ |
78 | static void config_for_pio(ide_drive_t *drive, int pio, int report, int chipset_only) | 74 | static u8 sl82c105_tune_pio(ide_drive_t *drive, u8 pio) |
79 | { | 75 | { |
80 | ide_hwif_t *hwif = HWIF(drive); | 76 | struct pci_dev *dev = HWIF(drive)->pci_dev; |
81 | struct pci_dev *dev = hwif->pci_dev; | 77 | int reg = 0x44 + drive->dn * 4; |
82 | ide_pio_data_t p; | 78 | ide_pio_data_t p; |
83 | u16 drv_ctrl = 0x909; | 79 | u16 drv_ctrl; |
84 | unsigned int xfer_mode, reg; | ||
85 | 80 | ||
86 | DBG(("config_for_pio(drive:%s, pio:%d, report:%d, chipset_only:%d)\n", | 81 | DBG(("sl82c105_tune_pio(drive:%s, pio:%u)\n", drive->name, pio)); |
87 | drive->name, pio, report, chipset_only)); | ||
88 | |||
89 | reg = (hwif->channel ? 0x4c : 0x44) + (drive->select.b.unit ? 4 : 0); | ||
90 | 82 | ||
91 | pio = ide_get_best_pio_mode(drive, pio, 5, &p); | 83 | pio = ide_get_best_pio_mode(drive, pio, 5, &p); |
92 | 84 | ||
93 | xfer_mode = XFER_PIO_0 + pio; | 85 | drive->drive_data = drv_ctrl = get_pio_timings(&p); |
94 | |||
95 | if (chipset_only || ide_config_drive_speed(drive, xfer_mode) == 0) { | ||
96 | drv_ctrl = get_timing_sl82c105(&p); | ||
97 | drive->pio_speed = xfer_mode; | ||
98 | } else | ||
99 | drive->pio_speed = XFER_PIO_0; | ||
100 | 86 | ||
101 | if (drive->using_dma == 0) { | 87 | if (!drive->using_dma) { |
102 | /* | 88 | /* |
103 | * If we are actually using MW DMA, then we can not | 89 | * If we are actually using MW DMA, then we can not |
104 | * reprogram the interface drive control register. | 90 | * reprogram the interface drive control register. |
105 | */ | 91 | */ |
106 | pci_write_config_word(dev, reg, drv_ctrl); | 92 | pci_write_config_word(dev, reg, drv_ctrl); |
107 | pci_read_config_word(dev, reg, &drv_ctrl); | 93 | pci_read_config_word (dev, reg, &drv_ctrl); |
108 | |||
109 | if (report) { | ||
110 | printk("%s: selected %s (%dns) (%04X)\n", drive->name, | ||
111 | ide_xfer_verbose(xfer_mode), p.cycle_time, drv_ctrl); | ||
112 | } | ||
113 | } | 94 | } |
95 | |||
96 | printk(KERN_DEBUG "%s: selected %s (%dns) (%04X)\n", drive->name, | ||
97 | ide_xfer_verbose(pio + XFER_PIO_0), p.cycle_time, drv_ctrl); | ||
98 | |||
99 | return pio; | ||
114 | } | 100 | } |
115 | 101 | ||
116 | /* | 102 | /* |
117 | * Configure the drive and the chipset for DMA | 103 | * Configure the drive for DMA. |
104 | * We'll program the chipset only when DMA is actually turned on. | ||
118 | */ | 105 | */ |
119 | static int config_for_dma (ide_drive_t *drive) | 106 | static int config_for_dma(ide_drive_t *drive) |
120 | { | 107 | { |
121 | ide_hwif_t *hwif = HWIF(drive); | ||
122 | struct pci_dev *dev = hwif->pci_dev; | ||
123 | unsigned int reg; | ||
124 | |||
125 | DBG(("config_for_dma(drive:%s)\n", drive->name)); | 108 | DBG(("config_for_dma(drive:%s)\n", drive->name)); |
126 | 109 | ||
127 | reg = (hwif->channel ? 0x4c : 0x44) + (drive->select.b.unit ? 4 : 0); | ||
128 | |||
129 | if (ide_config_drive_speed(drive, XFER_MW_DMA_2) != 0) | 110 | if (ide_config_drive_speed(drive, XFER_MW_DMA_2) != 0) |
130 | return 1; | 111 | return 0; |
131 | 112 | ||
132 | pci_write_config_word(dev, reg, 0x0240); | 113 | return ide_dma_enable(drive); |
133 | |||
134 | return 0; | ||
135 | } | 114 | } |
136 | 115 | ||
137 | /* | 116 | /* |
138 | * Check to see if the drive and | 117 | * Check to see if the drive and chipset are capable of DMA mode. |
139 | * chipset is capable of DMA mode | ||
140 | */ | 118 | */ |
141 | 119 | static int sl82c105_ide_dma_check(ide_drive_t *drive) | |
142 | static int sl82c105_check_drive (ide_drive_t *drive) | ||
143 | { | 120 | { |
144 | ide_hwif_t *hwif = HWIF(drive); | 121 | DBG(("sl82c105_ide_dma_check(drive:%s)\n", drive->name)); |
145 | |||
146 | DBG(("sl82c105_check_drive(drive:%s)\n", drive->name)); | ||
147 | |||
148 | do { | ||
149 | struct hd_driveid *id = drive->id; | ||
150 | |||
151 | if (!drive->autodma) | ||
152 | break; | ||
153 | |||
154 | if (!id || !(id->capability & 1)) | ||
155 | break; | ||
156 | 122 | ||
157 | /* Consult the list of known "bad" drives */ | 123 | if (ide_use_dma(drive) && config_for_dma(drive)) |
158 | if (__ide_dma_bad_drive(drive)) | 124 | return 0; |
159 | break; | ||
160 | |||
161 | if (id->field_valid & 2) { | ||
162 | if ((id->dma_mword & hwif->mwdma_mask) || | ||
163 | (id->dma_1word & hwif->swdma_mask)) | ||
164 | return 0; | ||
165 | } | ||
166 | |||
167 | if (__ide_dma_good_drive(drive) && id->eide_dma_time < 150) | ||
168 | return 0; | ||
169 | } while (0); | ||
170 | 125 | ||
171 | return -1; | 126 | return -1; |
172 | } | 127 | } |
@@ -195,14 +150,14 @@ static inline void sl82c105_reset_host(struct pci_dev *dev) | |||
195 | * This function is called when the IDE timer expires, the drive | 150 | * This function is called when the IDE timer expires, the drive |
196 | * indicates that it is READY, and we were waiting for DMA to complete. | 151 | * indicates that it is READY, and we were waiting for DMA to complete. |
197 | */ | 152 | */ |
198 | static int sl82c105_ide_dma_lost_irq(ide_drive_t *drive) | 153 | static int sl82c105_ide_dma_lostirq(ide_drive_t *drive) |
199 | { | 154 | { |
200 | ide_hwif_t *hwif = HWIF(drive); | 155 | ide_hwif_t *hwif = HWIF(drive); |
201 | struct pci_dev *dev = hwif->pci_dev; | 156 | struct pci_dev *dev = hwif->pci_dev; |
202 | u32 val, mask = hwif->channel ? CTRL_IDE_IRQB : CTRL_IDE_IRQA; | 157 | u32 val, mask = hwif->channel ? CTRL_IDE_IRQB : CTRL_IDE_IRQA; |
203 | unsigned long dma_base = hwif->dma_base; | 158 | u8 dma_cmd; |
204 | 159 | ||
205 | printk("sl82c105: lost IRQ: resetting host\n"); | 160 | printk("sl82c105: lost IRQ, resetting host\n"); |
206 | 161 | ||
207 | /* | 162 | /* |
208 | * Check the raw interrupt from the drive. | 163 | * Check the raw interrupt from the drive. |
@@ -215,15 +170,15 @@ static int sl82c105_ide_dma_lost_irq(ide_drive_t *drive) | |||
215 | * Was DMA enabled? If so, disable it - we're resetting the | 170 | * Was DMA enabled? If so, disable it - we're resetting the |
216 | * host. The IDE layer will be handling the drive for us. | 171 | * host. The IDE layer will be handling the drive for us. |
217 | */ | 172 | */ |
218 | val = inb(dma_base); | 173 | dma_cmd = inb(hwif->dma_command); |
219 | if (val & 1) { | 174 | if (dma_cmd & 1) { |
220 | outb(val & ~1, dma_base); | 175 | outb(dma_cmd & ~1, hwif->dma_command); |
221 | printk("sl82c105: DMA was enabled\n"); | 176 | printk("sl82c105: DMA was enabled\n"); |
222 | } | 177 | } |
223 | 178 | ||
224 | sl82c105_reset_host(dev); | 179 | sl82c105_reset_host(dev); |
225 | 180 | ||
226 | /* ide_dmaproc would return 1, so we do as well */ | 181 | /* __ide_dma_lostirq would return 1, so we do as well */ |
227 | return 1; | 182 | return 1; |
228 | } | 183 | } |
229 | 184 | ||
@@ -235,10 +190,10 @@ static int sl82c105_ide_dma_lost_irq(ide_drive_t *drive) | |||
235 | * The generic IDE core will have disabled the BMEN bit before this | 190 | * The generic IDE core will have disabled the BMEN bit before this |
236 | * function is called. | 191 | * function is called. |
237 | */ | 192 | */ |
238 | static void sl82c105_ide_dma_start(ide_drive_t *drive) | 193 | static void sl82c105_dma_start(ide_drive_t *drive) |
239 | { | 194 | { |
240 | ide_hwif_t *hwif = HWIF(drive); | 195 | ide_hwif_t *hwif = HWIF(drive); |
241 | struct pci_dev *dev = hwif->pci_dev; | 196 | struct pci_dev *dev = hwif->pci_dev; |
242 | 197 | ||
243 | sl82c105_reset_host(dev); | 198 | sl82c105_reset_host(dev); |
244 | ide_dma_start(drive); | 199 | ide_dma_start(drive); |
@@ -246,8 +201,8 @@ static void sl82c105_ide_dma_start(ide_drive_t *drive) | |||
246 | 201 | ||
247 | static int sl82c105_ide_dma_timeout(ide_drive_t *drive) | 202 | static int sl82c105_ide_dma_timeout(ide_drive_t *drive) |
248 | { | 203 | { |
249 | ide_hwif_t *hwif = HWIF(drive); | 204 | ide_hwif_t *hwif = HWIF(drive); |
250 | struct pci_dev *dev = hwif->pci_dev; | 205 | struct pci_dev *dev = hwif->pci_dev; |
251 | 206 | ||
252 | DBG(("sl82c105_ide_dma_timeout(drive:%s)\n", drive->name)); | 207 | DBG(("sl82c105_ide_dma_timeout(drive:%s)\n", drive->name)); |
253 | 208 | ||
@@ -255,26 +210,32 @@ static int sl82c105_ide_dma_timeout(ide_drive_t *drive) | |||
255 | return __ide_dma_timeout(drive); | 210 | return __ide_dma_timeout(drive); |
256 | } | 211 | } |
257 | 212 | ||
258 | static int sl82c105_ide_dma_on (ide_drive_t *drive) | 213 | static int sl82c105_ide_dma_on(ide_drive_t *drive) |
259 | { | 214 | { |
215 | struct pci_dev *dev = HWIF(drive)->pci_dev; | ||
216 | int rc, reg = 0x44 + drive->dn * 4; | ||
217 | |||
260 | DBG(("sl82c105_ide_dma_on(drive:%s)\n", drive->name)); | 218 | DBG(("sl82c105_ide_dma_on(drive:%s)\n", drive->name)); |
261 | 219 | ||
262 | if (config_for_dma(drive)) | 220 | rc = __ide_dma_on(drive); |
263 | return 1; | 221 | if (rc == 0) { |
264 | printk(KERN_INFO "%s: DMA enabled\n", drive->name); | 222 | pci_write_config_word(dev, reg, 0x0200); |
265 | return __ide_dma_on(drive); | 223 | |
224 | printk(KERN_INFO "%s: DMA enabled\n", drive->name); | ||
225 | } | ||
226 | return rc; | ||
266 | } | 227 | } |
267 | 228 | ||
268 | static void sl82c105_dma_off_quietly(ide_drive_t *drive) | 229 | static void sl82c105_dma_off_quietly(ide_drive_t *drive) |
269 | { | 230 | { |
270 | u8 speed = XFER_PIO_0; | 231 | struct pci_dev *dev = HWIF(drive)->pci_dev; |
232 | int reg = 0x44 + drive->dn * 4; | ||
271 | 233 | ||
272 | DBG(("sl82c105_dma_off_quietly(drive:%s)\n", drive->name)); | 234 | DBG(("sl82c105_dma_off_quietly(drive:%s)\n", drive->name)); |
273 | 235 | ||
236 | pci_write_config_word(dev, reg, drive->drive_data); | ||
237 | |||
274 | ide_dma_off_quietly(drive); | 238 | ide_dma_off_quietly(drive); |
275 | if (drive->pio_speed) | ||
276 | speed = drive->pio_speed - XFER_PIO_0; | ||
277 | config_for_pio(drive, speed, 0, 1); | ||
278 | } | 239 | } |
279 | 240 | ||
280 | /* | 241 | /* |
@@ -286,8 +247,8 @@ static void sl82c105_dma_off_quietly(ide_drive_t *drive) | |||
286 | */ | 247 | */ |
287 | static void sl82c105_selectproc(ide_drive_t *drive) | 248 | static void sl82c105_selectproc(ide_drive_t *drive) |
288 | { | 249 | { |
289 | ide_hwif_t *hwif = HWIF(drive); | 250 | ide_hwif_t *hwif = HWIF(drive); |
290 | struct pci_dev *dev = hwif->pci_dev; | 251 | struct pci_dev *dev = hwif->pci_dev; |
291 | u32 val, old, mask; | 252 | u32 val, old, mask; |
292 | 253 | ||
293 | //DBG(("sl82c105_selectproc(drive:%s)\n", drive->name)); | 254 | //DBG(("sl82c105_selectproc(drive:%s)\n", drive->name)); |
@@ -323,18 +284,12 @@ static void sl82c105_resetproc(ide_drive_t *drive) | |||
323 | * We only deal with PIO mode here - DMA mode 'using_dma' is not | 284 | * We only deal with PIO mode here - DMA mode 'using_dma' is not |
324 | * initialised at the point that this function is called. | 285 | * initialised at the point that this function is called. |
325 | */ | 286 | */ |
326 | static void tune_sl82c105(ide_drive_t *drive, u8 pio) | 287 | static void sl82c105_tune_drive(ide_drive_t *drive, u8 pio) |
327 | { | 288 | { |
328 | DBG(("tune_sl82c105(drive:%s)\n", drive->name)); | 289 | DBG(("sl82c105_tune_drive(drive:%s, pio:%u)\n", drive->name, pio)); |
329 | |||
330 | config_for_pio(drive, pio, 1, 0); | ||
331 | 290 | ||
332 | /* | 291 | pio = sl82c105_tune_pio(drive, pio); |
333 | * We support 32-bit I/O on this interface, and it | 292 | (void) ide_config_drive_speed(drive, XFER_PIO_0 + pio); |
334 | * doesn't have problems with interrupts. | ||
335 | */ | ||
336 | drive->io_32bit = 1; | ||
337 | drive->unmask = 1; | ||
338 | } | 293 | } |
339 | 294 | ||
340 | /* | 295 | /* |
@@ -393,7 +348,7 @@ static unsigned int __devinit init_chipset_sl82c105(struct pci_dev *dev, const c | |||
393 | } | 348 | } |
394 | 349 | ||
395 | /* | 350 | /* |
396 | * Initialise the chip | 351 | * Initialise IDE channel |
397 | */ | 352 | */ |
398 | static void __devinit init_hwif_sl82c105(ide_hwif_t *hwif) | 353 | static void __devinit init_hwif_sl82c105(ide_hwif_t *hwif) |
399 | { | 354 | { |
@@ -401,24 +356,22 @@ static void __devinit init_hwif_sl82c105(ide_hwif_t *hwif) | |||
401 | 356 | ||
402 | DBG(("init_hwif_sl82c105(hwif: ide%d)\n", hwif->index)); | 357 | DBG(("init_hwif_sl82c105(hwif: ide%d)\n", hwif->index)); |
403 | 358 | ||
404 | hwif->tuneproc = tune_sl82c105; | 359 | hwif->tuneproc = &sl82c105_tune_drive; |
405 | hwif->selectproc = sl82c105_selectproc; | 360 | hwif->selectproc = &sl82c105_selectproc; |
406 | hwif->resetproc = sl82c105_resetproc; | 361 | hwif->resetproc = &sl82c105_resetproc; |
362 | |||
363 | /* | ||
364 | * We support 32-bit I/O on this interface, and | ||
365 | * it doesn't have problems with interrupts. | ||
366 | */ | ||
367 | hwif->drives[0].io_32bit = hwif->drives[1].io_32bit = 1; | ||
368 | hwif->drives[0].unmask = hwif->drives[1].unmask = 1; | ||
407 | 369 | ||
408 | /* | 370 | /* |
409 | * Default to PIO 0 for fallback unless tuned otherwise. | ||
410 | * We always autotune PIO, this is done before DMA is checked, | 371 | * We always autotune PIO, this is done before DMA is checked, |
411 | * so there's no risk of accidentally disabling DMA | 372 | * so there's no risk of accidentally disabling DMA |
412 | */ | 373 | */ |
413 | hwif->drives[0].pio_speed = XFER_PIO_0; | 374 | hwif->drives[0].autotune = hwif->drives[1].autotune = 1; |
414 | hwif->drives[0].autotune = 1; | ||
415 | hwif->drives[1].pio_speed = XFER_PIO_0; | ||
416 | hwif->drives[1].autotune = 1; | ||
417 | |||
418 | hwif->atapi_dma = 0; | ||
419 | hwif->mwdma_mask = 0; | ||
420 | hwif->swdma_mask = 0; | ||
421 | hwif->autodma = 0; | ||
422 | 375 | ||
423 | if (!hwif->dma_base) | 376 | if (!hwif->dma_base) |
424 | return; | 377 | return; |
@@ -429,27 +382,27 @@ static void __devinit init_hwif_sl82c105(ide_hwif_t *hwif) | |||
429 | * Never ever EVER under any circumstances enable | 382 | * Never ever EVER under any circumstances enable |
430 | * DMA when the bridge is this old. | 383 | * DMA when the bridge is this old. |
431 | */ | 384 | */ |
432 | printk(" %s: Winbond 553 bridge revision %d, BM-DMA disabled\n", | 385 | printk(" %s: Winbond W83C553 bridge revision %d, " |
433 | hwif->name, rev); | 386 | "BM-DMA disabled\n", hwif->name, rev); |
434 | } else { | 387 | return; |
435 | hwif->atapi_dma = 1; | ||
436 | hwif->mwdma_mask = 0x04; | ||
437 | |||
438 | hwif->ide_dma_check = &sl82c105_check_drive; | ||
439 | hwif->ide_dma_on = &sl82c105_ide_dma_on; | ||
440 | hwif->dma_off_quietly = &sl82c105_dma_off_quietly; | ||
441 | hwif->ide_dma_lostirq = &sl82c105_ide_dma_lost_irq; | ||
442 | hwif->dma_start = &sl82c105_ide_dma_start; | ||
443 | hwif->ide_dma_timeout = &sl82c105_ide_dma_timeout; | ||
444 | |||
445 | if (!noautodma) | ||
446 | hwif->autodma = 1; | ||
447 | hwif->drives[0].autodma = hwif->autodma; | ||
448 | hwif->drives[1].autodma = hwif->autodma; | ||
449 | |||
450 | if (hwif->mate) | ||
451 | hwif->serialized = hwif->mate->serialized = 1; | ||
452 | } | 388 | } |
389 | |||
390 | hwif->atapi_dma = 1; | ||
391 | hwif->mwdma_mask = 0x04; | ||
392 | |||
393 | hwif->ide_dma_check = &sl82c105_ide_dma_check; | ||
394 | hwif->ide_dma_on = &sl82c105_ide_dma_on; | ||
395 | hwif->dma_off_quietly = &sl82c105_dma_off_quietly; | ||
396 | hwif->ide_dma_lostirq = &sl82c105_ide_dma_lostirq; | ||
397 | hwif->dma_start = &sl82c105_dma_start; | ||
398 | hwif->ide_dma_timeout = &sl82c105_ide_dma_timeout; | ||
399 | |||
400 | if (!noautodma) | ||
401 | hwif->autodma = 1; | ||
402 | hwif->drives[0].autodma = hwif->drives[1].autodma = hwif->autodma; | ||
403 | |||
404 | if (hwif->mate) | ||
405 | hwif->serialized = hwif->mate->serialized = 1; | ||
453 | } | 406 | } |
454 | 407 | ||
455 | static ide_pci_device_t sl82c105_chipset __devinitdata = { | 408 | static ide_pci_device_t sl82c105_chipset __devinitdata = { |