2 * linux/drivers/ide/amd7409.c Version 0.05 June 9, 2000
4 * Copyright (C) 1999-2000 Andre Hedrick <andre@linux-ide.org>
5 * May be copied or modified under the terms of the GNU General Public License
9 #include <linux/config.h>
10 #include <linux/types.h>
11 #include <linux/kernel.h>
12 #include <linux/delay.h>
13 #include <linux/timer.h>
15 #include <linux/ioport.h>
16 #include <linux/blkdev.h>
17 #include <linux/hdreg.h>
19 #include <linux/interrupt.h>
20 #include <linux/init.h>
21 #include <linux/pci.h>
22 #include <linux/ide.h>
27 #include "ide_modes.h"
29 #define DISPLAY_VIPER_TIMINGS
31 #if defined(DISPLAY_VIPER_TIMINGS) && defined(CONFIG_PROC_FS)
32 #include <linux/stat.h>
33 #include <linux/proc_fs.h>
35 static int amd7409_get_info(char *, char **, off_t
, int);
36 extern int (*amd7409_display_info
)(char *, char **, off_t
, int); /* ide-proc.c */
37 extern char *ide_media_verbose(ide_drive_t
*);
38 static struct pci_dev
*bmide_dev
;
40 static int amd7409_get_info (char *buffer
, char **addr
, off_t offset
, int count
)
43 u32 bibma
= pci_resource_start(bmide_dev
, 4);
47 * at that point bibma+0x2 et bibma+0xa are byte registers
50 c0
= inb_p((unsigned short)bibma
+ 0x02);
51 c1
= inb_p((unsigned short)bibma
+ 0x0a);
53 p
+= sprintf(p
, "\n AMD 7409 VIPER Chipset.\n");
54 p
+= sprintf(p
, "--------------- Primary Channel ---------------- Secondary Channel -------------\n");
55 p
+= sprintf(p
, " %sabled %sabled\n",
56 (c0
&0x80) ? "dis" : " en",
57 (c1
&0x80) ? "dis" : " en");
58 p
+= sprintf(p
, "--------------- drive0 --------- drive1 -------- drive0 ---------- drive1 ------\n");
59 p
+= sprintf(p
, "DMA enabled: %s %s %s %s\n",
60 (c0
&0x20) ? "yes" : "no ", (c0
&0x40) ? "yes" : "no ",
61 (c1
&0x20) ? "yes" : "no ", (c1
&0x40) ? "yes" : "no " );
62 p
+= sprintf(p
, "UDMA\n");
63 p
+= sprintf(p
, "DMA\n");
64 p
+= sprintf(p
, "PIO\n");
66 return p
-buffer
; /* => must be less than 4k! */
68 #endif /* defined(DISPLAY_VIPER_TIMINGS) && defined(CONFIG_PROC_FS) */
70 byte amd7409_proc
= 0;
72 extern char *ide_xfer_verbose (byte xfer_rate
);
74 static unsigned int amd7409_swdma_check (struct pci_dev
*dev
)
76 unsigned int class_rev
;
77 pci_read_config_dword(dev
, PCI_CLASS_REVISION
, &class_rev
);
79 return ((int) (class_rev
>= 7) ? 1 : 0);
82 static int amd7409_swdma_error(ide_drive_t
*drive
)
84 printk("%s: single-word DMA not support (revision < C4)\n", drive
->name
);
89 * Here is where all the hard work goes to program the chipset.
92 static int amd7409_tune_chipset (ide_drive_t
*drive
, byte speed
)
94 ide_hwif_t
*hwif
= HWIF(drive
);
95 struct pci_dev
*dev
= hwif
->pci_dev
;
97 byte unit
= (drive
->select
.b
.unit
& 0x01);
98 #ifdef CONFIG_BLK_DEV_IDEDMA
99 unsigned long dma_base
= hwif
->dma_base
;
100 #endif /* CONFIG_BLK_DEV_IDEDMA */
101 byte drive_pci
= 0x00;
102 byte drive_pci2
= 0x00;
103 byte ultra_timing
= 0x00;
104 byte dma_pio_timing
= 0x00;
105 byte pio_timing
= 0x00;
108 case 0: drive_pci
= 0x53; drive_pci2
= 0x4b; break;
109 case 1: drive_pci
= 0x52; drive_pci2
= 0x4a; break;
110 case 2: drive_pci
= 0x51; drive_pci2
= 0x49; break;
111 case 3: drive_pci
= 0x50; drive_pci2
= 0x48; break;
116 pci_read_config_byte(dev
, drive_pci
, &ultra_timing
);
117 pci_read_config_byte(dev
, drive_pci2
, &dma_pio_timing
);
118 pci_read_config_byte(dev
, 0x4c, &pio_timing
);
121 printk("%s: UDMA 0x%02x DMAPIO 0x%02x PIO 0x%02x ",
122 drive
->name
, ultra_timing
, dma_pio_timing
, pio_timing
);
125 ultra_timing
&= ~0xC7;
126 dma_pio_timing
&= ~0xFF;
127 pio_timing
&= ~(0x03 << drive
->dn
);
130 printk(":: UDMA 0x%02x DMAPIO 0x%02x PIO 0x%02x ",
131 ultra_timing
, dma_pio_timing
, pio_timing
);
135 #ifdef CONFIG_BLK_DEV_IDEDMA
137 ultra_timing
|= 0x45;
138 dma_pio_timing
|= 0x20;
141 ultra_timing
|= 0x44;
142 dma_pio_timing
|= 0x20;
145 ultra_timing
|= 0x40;
146 dma_pio_timing
|= 0x20;
149 ultra_timing
|= 0x41;
150 dma_pio_timing
|= 0x20;
153 ultra_timing
|= 0x42;
154 dma_pio_timing
|= 0x20;
157 dma_pio_timing
|= 0x20;
160 dma_pio_timing
|= 0x21;
163 dma_pio_timing
|= 0x77;
166 if (!amd7409_swdma_check(dev
))
167 return amd7409_swdma_error(drive
);
168 dma_pio_timing
|= 0x42;
171 if (!amd7409_swdma_check(dev
))
172 return amd7409_swdma_error(drive
);
173 dma_pio_timing
|= 0x65;
176 if (!amd7409_swdma_check(dev
))
177 return amd7409_swdma_error(drive
);
178 dma_pio_timing
|= 0xA8;
180 #endif /* CONFIG_BLK_DEV_IDEDMA */
182 dma_pio_timing
|= 0x20;
185 dma_pio_timing
|= 0x22;
188 dma_pio_timing
|= 0x42;
191 dma_pio_timing
|= 0x65;
195 dma_pio_timing
|= 0xA8;
199 pio_timing
|= (0x03 << drive
->dn
);
201 if (!drive
->init_speed
)
202 drive
->init_speed
= speed
;
204 #ifdef CONFIG_BLK_DEV_IDEDMA
205 pci_write_config_byte(dev
, drive_pci
, ultra_timing
);
206 #endif /* CONFIG_BLK_DEV_IDEDMA */
207 pci_write_config_byte(dev
, drive_pci2
, dma_pio_timing
);
208 pci_write_config_byte(dev
, 0x4c, pio_timing
);
211 printk(":: UDMA 0x%02x DMAPIO 0x%02x PIO 0x%02x\n",
212 ultra_timing
, dma_pio_timing
, pio_timing
);
215 #ifdef CONFIG_BLK_DEV_IDEDMA
216 if (speed
> XFER_PIO_4
) {
217 outb(inb(dma_base
+2)|(1<<(5+unit
)), dma_base
+2);
219 outb(inb(dma_base
+2) & ~(1<<(5+unit
)), dma_base
+2);
221 #endif /* CONFIG_BLK_DEV_IDEDMA */
223 err
= ide_config_drive_speed(drive
, speed
);
224 drive
->current_speed
= speed
;
228 static void config_chipset_for_pio (ide_drive_t
*drive
)
230 unsigned short eide_pio_timing
[6] = {960, 480, 240, 180, 120, 90};
231 unsigned short xfer_pio
= drive
->id
->eide_pio_modes
;
232 byte timing
, speed
, pio
;
234 pio
= ide_get_best_pio_mode(drive
, 255, 5, NULL
);
239 if (drive
->id
->eide_pio_iordy
> 0) {
242 drive
->id
->eide_pio_iordy
>eide_pio_timing
[xfer_pio
];
245 xfer_pio
= (drive
->id
->eide_pio_modes
& 4) ? 0x05 :
246 (drive
->id
->eide_pio_modes
& 2) ? 0x04 :
247 (drive
->id
->eide_pio_modes
& 1) ? 0x03 :
248 (drive
->id
->tPIO
& 2) ? 0x02 :
249 (drive
->id
->tPIO
& 1) ? 0x01 : xfer_pio
;
252 timing
= (xfer_pio
>= pio
) ? xfer_pio
: pio
;
255 case 4: speed
= XFER_PIO_4
;break;
256 case 3: speed
= XFER_PIO_3
;break;
257 case 2: speed
= XFER_PIO_2
;break;
258 case 1: speed
= XFER_PIO_1
;break;
260 speed
= (!drive
->id
->tPIO
) ? XFER_PIO_0
: XFER_PIO_SLOW
;
263 (void) amd7409_tune_chipset(drive
, speed
);
264 drive
->current_speed
= speed
;
267 static void amd7409_tune_drive (ide_drive_t
*drive
, byte pio
)
271 case 4: speed
= XFER_PIO_4
;break;
272 case 3: speed
= XFER_PIO_3
;break;
273 case 2: speed
= XFER_PIO_2
;break;
274 case 1: speed
= XFER_PIO_1
;break;
275 default: speed
= XFER_PIO_0
;break;
277 (void) amd7409_tune_chipset(drive
, speed
);
280 #ifdef CONFIG_BLK_DEV_IDEDMA
282 * This allows the configuration of ide_pci chipset registers
283 * for cards that learn about the drive's UDMA, DMA, PIO capabilities
284 * after the drive is reported by the OS.
286 static int config_chipset_for_dma (ide_drive_t
*drive
)
288 struct hd_driveid
*id
= drive
->id
;
289 byte udma_66
= eighty_ninty_three(drive
);
294 if ((id
->dma_ultra
& 0x0020) && (udma_66
)&& (udma_100
)) {
296 } else if ((id
->dma_ultra
& 0x0010) && (udma_66
)) {
298 } else if ((id
->dma_ultra
& 0x0008) && (udma_66
)) {
300 } else if (id
->dma_ultra
& 0x0004) {
302 } else if (id
->dma_ultra
& 0x0002) {
304 } else if (id
->dma_ultra
& 0x0001) {
306 } else if (id
->dma_mword
& 0x0004) {
307 speed
= XFER_MW_DMA_2
;
308 } else if (id
->dma_mword
& 0x0002) {
309 speed
= XFER_MW_DMA_1
;
310 } else if (id
->dma_mword
& 0x0001) {
311 speed
= XFER_MW_DMA_0
;
313 return ((int) ide_dma_off_quietly
);
316 (void) amd7409_tune_chipset(drive
, speed
);
318 rval
= (int)( ((id
->dma_ultra
>> 11) & 3) ? ide_dma_on
:
319 ((id
->dma_ultra
>> 8) & 7) ? ide_dma_on
:
320 ((id
->dma_mword
>> 8) & 7) ? ide_dma_on
:
321 ide_dma_off_quietly
);
328 static int config_drive_xfer_rate (ide_drive_t
*drive
)
330 struct hd_driveid
*id
= drive
->id
;
331 ide_dma_action_t dma_func
= ide_dma_on
;
333 if (id
&& (id
->capability
& 1) && HWIF(drive
)->autodma
) {
334 /* Consult the list of known "bad" drives */
335 if (ide_dmaproc(ide_dma_bad_drive
, drive
)) {
336 dma_func
= ide_dma_off
;
339 dma_func
= ide_dma_off_quietly
;
340 if (id
->field_valid
& 4) {
341 if (id
->dma_ultra
& 0x002F) {
342 /* Force if Capable UltraDMA */
343 dma_func
= config_chipset_for_dma(drive
);
344 if ((id
->field_valid
& 2) &&
345 (dma_func
!= ide_dma_on
))
348 } else if (id
->field_valid
& 2) {
350 if ((id
->dma_mword
& 0x0007) ||
351 ((id
->dma_1word
& 0x007) &&
352 (amd7409_swdma_check(HWIF(drive
)->pci_dev
)))) {
353 /* Force if Capable regular DMA modes */
354 dma_func
= config_chipset_for_dma(drive
);
355 if (dma_func
!= ide_dma_on
)
359 } else if (ide_dmaproc(ide_dma_good_drive
, drive
)) {
360 if (id
->eide_dma_time
> 150) {
363 /* Consult the list of known "good" drives */
364 dma_func
= config_chipset_for_dma(drive
);
365 if (dma_func
!= ide_dma_on
)
370 } else if ((id
->capability
& 8) || (id
->field_valid
& 2)) {
372 dma_func
= ide_dma_off_quietly
;
375 config_chipset_for_pio(drive
);
377 return HWIF(drive
)->dmaproc(dma_func
, drive
);
381 * amd7409_dmaproc() initiates/aborts (U)DMA read/write operations on a drive.
384 int amd7409_dmaproc (ide_dma_action_t func
, ide_drive_t
*drive
)
388 return config_drive_xfer_rate(drive
);
392 return ide_dmaproc(func
, drive
); /* use standard DMA stuff */
394 #endif /* CONFIG_BLK_DEV_IDEDMA */
396 unsigned int __init
pci_init_amd7409 (struct pci_dev
*dev
, const char *name
)
398 unsigned long fixdma_base
= pci_resource_start(dev
, 4);
400 #ifdef CONFIG_BLK_DEV_IDEDMA
401 if (!amd7409_swdma_check(dev
))
402 printk("%s: disabling single-word DMA support (revision < C4)\n", name
);
403 #endif /* CONFIG_BLK_DEV_IDEDMA */
411 * enable DMA capable bit, and "not" simplex only
413 outb(inb(fixdma_base
+2) & 0x60, fixdma_base
+2);
415 if (inb(fixdma_base
+2) & 0x80)
416 printk("%s: simplex device: DMA will fail!!\n", name
);
418 #if defined(DISPLAY_VIPER_TIMINGS) && defined(CONFIG_PROC_FS)
422 amd7409_display_info
= &amd7409_get_info
;
424 #endif /* DISPLAY_VIPER_TIMINGS && CONFIG_PROC_FS */
429 unsigned int __init
ata66_amd7409 (ide_hwif_t
*hwif
)
431 #ifdef CONFIG_AMD7409_OVERRIDE
435 #endif /* CONFIG_AMD7409_OVERRIDE */
438 pci_read_config_byte(hwif
->pci_dev
, 0x48, &ata66
);
439 return ((ata66
& 0x02) ? 0 : 1);
444 void __init
ide_init_amd7409 (ide_hwif_t
*hwif
)
446 hwif
->tuneproc
= &amd7409_tune_drive
;
447 hwif
->speedproc
= &amd7409_tune_chipset
;
449 #ifndef CONFIG_BLK_DEV_IDEDMA
450 hwif
->drives
[0].autotune
= 1;
451 hwif
->drives
[1].autotune
= 1;
456 if (hwif
->dma_base
) {
457 hwif
->dmaproc
= &amd7409_dmaproc
;
461 hwif
->drives
[0].autotune
= 1;
462 hwif
->drives
[1].autotune
= 1;
464 #endif /* CONFIG_BLK_DEV_IDEDMA */
467 void ide_dmacapable_amd7409 (ide_hwif_t
*hwif
, unsigned long dmabase
)
469 ide_setup_dma(hwif
, dmabase
, 8);