Import 2.3.51
[davej-history.git] / drivers / block / aec6210.c
blobcc0aca5fd9740a803c5a795b1960d461a0a1703f
1 /*
2 * linux/drivers/block/aec6210.c Version 0.05 Feb. 10, 2000
4 * Copyright (C) 1998-2000 Andre Hedrick (andre@suse.com)
5 * May be copied or modified under the terms of the GNU General Public License
7 * pio 0 :: 40: 00 07 00 00 00 00 00 00 02 07 a6 04 00 02 00 02
8 * pio 1 :: 40: 0a 07 00 00 00 00 00 00 02 07 a6 05 00 02 00 02
9 * pio 2 :: 40: 08 07 00 00 00 00 00 00 02 07 a6 05 00 02 00 02
10 * pio 3 :: 40: 03 04 00 00 00 00 00 00 02 05 a6 05 00 02 00 02
11 * pio 4 :: 40: 01 04 00 00 00 00 00 00 02 05 a6 05 00 02 00 02
12 * dma 0 :: 40: 0a 07 00 00 00 00 00 00 02 05 a6 05 00 02 00 02
13 * dma 1 :: 40: 02 04 00 00 00 00 00 00 02 05 a6 05 00 02 00 02
14 * dma 2 :: 40: 01 04 00 00 00 00 00 00 02 05 a6 05 00 02 00 02
15 * 50: ff ff ff ff 00 06 04 00 00 00 00 00 00 00 00 00
17 * udma 0 :: 40: 01 04 00 00 00 00 00 00 02 05 a6 05 00 02 00 02
18 * 50: ff ff ff ff 01 06 04 00 00 00 00 00 00 00 00 00
20 * udma 1 :: 40: 01 04 00 00 00 00 00 00 02 05 a6 05 00 02 00 02
21 * 50: ff ff ff ff 01 06 04 00 00 00 00 00 00 00 00 00
23 * udma 2 :: 40: 01 04 00 00 00 00 00 00 02 05 a6 05 00 02 00 02
24 * 50: ff ff ff ff 02 06 04 00 00 00 00 00 00 00 00 00
26 * auto :: 40: 01 04 00 00 00 00 00 00 02 05 a6 05 00 02 00 02
27 * 50: ff ff ff ff 02 06 04 00 00 00 00 00 00 00 00 00
29 * auto :: 40: 01 04 01 04 01 04 01 04 02 05 a6 cf 00 02 00 02
30 * 50: ff ff ff ff aa 06 04 00 00 00 00 00 00 00 00 00
32 * NO-Devices
33 * 40: 00 00 00 00 00 00 00 00 02 05 a6 00 00 02 00 02
34 * 50: ff ff ff ff 00 06 00 00 00 00 00 00 00 00 00 00
37 #include <linux/config.h>
38 #include <linux/types.h>
39 #include <linux/kernel.h>
40 #include <linux/delay.h>
41 #include <linux/timer.h>
42 #include <linux/mm.h>
43 #include <linux/ioport.h>
44 #include <linux/blkdev.h>
45 #include <linux/hdreg.h>
47 #include <linux/interrupt.h>
48 #include <linux/pci.h>
49 #include <linux/init.h>
50 #include <linux/ide.h>
52 #include <asm/io.h>
53 #include <asm/irq.h>
55 #include "ide_modes.h"
57 #define ACARD_DEBUG_DRIVE_INFO 0
59 #undef DISPLAY_AEC6210_TIMINGS
61 #if defined(DISPLAY_AEC6210_TIMINGS) && defined(CONFIG_PROC_FS)
62 #include <linux/stat.h>
63 #include <linux/proc_fs.h>
65 static int aec6210_get_info(char *, char **, off_t, int);
66 extern int (*aec6210_display_info)(char *, char **, off_t, int); /* ide-proc.c */
67 extern char *ide_media_verbose(ide_drive_t *);
68 static struct pci_dev *bmide_dev;
70 static int aec6210_get_info (char *buffer, char **addr, off_t offset, int count)
72 char *p = buffer;
74 u32 bibma = bmide_dev->resource[4].start;
75 u8 c0 = 0, c1 = 0;
77 p += sprintf(p, "\n AEC6210 Chipset.\n");
80 * at that point bibma+0x2 et bibma+0xa are byte registers
81 * to investigate:
83 c0 = inb_p((unsigned short)bibma + 0x02);
84 c1 = inb_p((unsigned short)bibma + 0x0a);
86 p += sprintf(p, "--------------- Primary Channel ---------------- Secondary Channel -------------\n");
87 p += sprintf(p, " %sabled %sabled\n",
88 (c0&0x80) ? "dis" : " en",
89 (c1&0x80) ? "dis" : " en");
90 p += sprintf(p, "--------------- drive0 --------- drive1 -------- drive0 ---------- drive1 ------\n");
91 p += sprintf(p, "DMA enabled: %s %s %s %s\n",
92 (c0&0x20) ? "yes" : "no ", (c0&0x40) ? "yes" : "no ",
93 (c1&0x20) ? "yes" : "no ", (c1&0x40) ? "yes" : "no " );
95 p += sprintf(p, "UDMA\n");
96 p += sprintf(p, "DMA\n");
97 p += sprintf(p, "PIO\n");
98 return p-buffer;/* => must be less than 4k! */
100 #endif /* defined(DISPLAY_AEC6210_TIMINGS) && defined(CONFIG_PROC_FS) */
102 byte aec6210_proc = 0;
104 #ifdef CONFIG_AEC6210_TUNING
106 struct chipset_bus_clock_list_entry {
107 byte xfer_speed;
108 unsigned short chipset_settings;
109 byte ultra_settings;
112 struct chipset_bus_clock_list_entry aec6210_base [] = {
113 { XFER_UDMA_2, 0x0401, 0x02 },
114 { XFER_UDMA_1, 0x0401, 0x01 },
115 { XFER_UDMA_0, 0x0401, 0x01 },
117 { XFER_MW_DMA_2, 0x0401, 0x00 },
118 { XFER_MW_DMA_1, 0x0402, 0x00 },
119 { XFER_MW_DMA_0, 0x070a, 0x00 },
121 { XFER_PIO_4, 0x0401, 0x00 },
122 { XFER_PIO_3, 0x0403, 0x00 },
123 { XFER_PIO_2, 0x0708, 0x00 },
124 { XFER_PIO_1, 0x070a, 0x00 },
125 { XFER_PIO_0, 0x0700, 0x00 },
126 { 0, 0x0000, 0x00 }
129 extern char *ide_xfer_verbose (byte xfer_rate);
132 * TO DO: active tuning and correction of cards without a bios.
135 static unsigned short pci_bus_clock_list (byte speed, struct chipset_bus_clock_list_entry * chipset_table)
137 for ( ; chipset_table->xfer_speed ; chipset_table++)
138 if (chipset_table->xfer_speed == speed) {
139 return chipset_table->chipset_settings;
141 return 0x0000;
144 static byte pci_bus_clock_list_ultra (byte speed, struct chipset_bus_clock_list_entry * chipset_table)
146 for ( ; chipset_table->xfer_speed ; chipset_table++)
147 if (chipset_table->xfer_speed == speed) {
148 return chipset_table->ultra_settings;
150 return 0x00;
153 static int aec6210_tune_chipset (ide_drive_t *drive, byte speed)
155 ide_hwif_t *hwif = HWIF(drive);
157 int err;
158 byte drive_pci;
159 unsigned short drive_conf = 0x0000;
160 byte ultra = 0x00, ultra_conf = 0x00;
161 byte tmp1 = 0x00, tmp2 = 0x00;
163 int drive_number = ((hwif->channel ? 2 : 0) + (drive->select.b.unit & 0x01));
165 switch(drive_number) {
166 case 0: drive_pci = 0x40; break;
167 case 1: drive_pci = 0x42; break;
168 case 2: drive_pci = 0x44; break;
169 case 3: drive_pci = 0x46; break;
170 default: return -1;
173 pci_read_config_word(HWIF(drive)->pci_dev, drive_pci, &drive_conf);
174 drive_conf = pci_bus_clock_list(speed, aec6210_base);
175 pci_write_config_word(HWIF(drive)->pci_dev, drive_pci, drive_conf);
177 pci_read_config_byte(HWIF(drive)->pci_dev, 0x54, &ultra);
178 tmp1 = ((0x00 << (2*drive_number)) | (ultra & ~(3 << (2*drive_number))));
179 ultra_conf = pci_bus_clock_list_ultra(speed, aec6210_base);
180 tmp2 = ((ultra_conf << (2*drive_number)) | (tmp1 & ~(3 << (2*drive_number))));
181 pci_write_config_byte(HWIF(drive)->pci_dev, 0x54, tmp2);
183 err = ide_config_drive_speed(drive, speed);
185 #if ACARD_DEBUG_DRIVE_INFO
186 printk("%s: %s drive%d 0x04%x 0x02%x 0x02%x 0x02%x 0x02%x\n",
187 drive->name, ide_xfer_verbose(speed), drive_number,
188 drive_conf, ultra, tmp1, ultra_conf, tmp2);
189 #endif /* ACARD_DEBUG_DRIVE_INFO */
191 return(err);
194 static int config_chipset_for_dma (ide_drive_t *drive, byte ultra)
196 struct hd_driveid *id = drive->id;
197 byte speed = -1;
199 if (drive->media != ide_disk)
200 return ((int) ide_dma_off_quietly);
202 if (((id->dma_ultra & 0x0010) ||
203 (id->dma_ultra & 0x0008) ||
204 (id->dma_ultra & 0x0004)) && (ultra)) {
205 speed = XFER_UDMA_2;
206 } else if ((id->dma_ultra & 0x0002) && (ultra)) {
207 speed = XFER_UDMA_1;
208 } else if ((id->dma_ultra & 0x0001) && (ultra)) {
209 speed = XFER_UDMA_0;
210 } else if (id->dma_mword & 0x0004) {
211 speed = XFER_MW_DMA_2;
212 } else if (id->dma_mword & 0x0002) {
213 speed = XFER_MW_DMA_1;
214 } else if (id->dma_mword & 0x0001) {
215 speed = XFER_MW_DMA_0;
216 } else if (id->dma_1word & 0x0004) {
217 speed = XFER_SW_DMA_2;
218 } else if (id->dma_1word & 0x0002) {
219 speed = XFER_SW_DMA_1;
220 } else if (id->dma_1word & 0x0001) {
221 speed = XFER_SW_DMA_0;
222 } else {
223 return ((int) ide_dma_off_quietly);
225 (void) aec6210_tune_chipset(drive, speed);
227 return ((int) ((id->dma_ultra >> 11) & 3) ? ide_dma_off :
228 ((id->dma_ultra >> 8) & 7) ? ide_dma_on :
229 ((id->dma_mword >> 8) & 7) ? ide_dma_on :
230 ((id->dma_1word >> 8) & 7) ? ide_dma_on :
231 ide_dma_off_quietly);
234 static void aec6210_tune_drive (ide_drive_t *drive, byte pio)
236 byte speed;
238 switch(pio) {
239 case 5:
240 speed = XFER_PIO_0 + ide_get_best_pio_mode(drive, 255, 5, NULL);
241 case 4:
242 speed = XFER_PIO_4; break;
243 case 3:
244 speed = XFER_PIO_3; break;
245 case 2:
246 speed = XFER_PIO_2; break;
247 case 1:
248 speed = XFER_PIO_1; break;
249 default:
250 speed = XFER_PIO_0; break;
252 (void) aec6210_tune_chipset(drive, speed);
255 static int config_drive_xfer_rate (ide_drive_t *drive)
257 struct hd_driveid *id = drive->id;
258 ide_dma_action_t dma_func = ide_dma_on;
260 if (id && (id->capability & 1) && HWIF(drive)->autodma) {
261 /* Consult the list of known "bad" drives */
262 if (ide_dmaproc(ide_dma_bad_drive, drive)) {
263 dma_func = ide_dma_off;
264 goto fast_ata_pio;
266 dma_func = ide_dma_off_quietly;
267 if (id->field_valid & 4) {
268 if (id->dma_ultra & 0x001F) {
269 /* Force if Capable UltraDMA */
270 dma_func = config_chipset_for_dma(drive, 1);
271 if ((id->field_valid & 2) &&
272 (dma_func != ide_dma_on))
273 goto try_dma_modes;
275 } else if (id->field_valid & 2) {
276 try_dma_modes:
277 if ((id->dma_mword & 0x0007) ||
278 (id->dma_1word & 0x0007)) {
279 /* Force if Capable regular DMA modes */
280 dma_func = config_chipset_for_dma(drive, 0);
281 if (dma_func != ide_dma_on)
282 goto no_dma_set;
284 } else if (ide_dmaproc(ide_dma_good_drive, drive)) {
285 if (id->eide_dma_time > 150) {
286 goto no_dma_set;
288 /* Consult the list of known "good" drives */
289 dma_func = config_chipset_for_dma(drive, 0);
290 if (dma_func != ide_dma_on)
291 goto no_dma_set;
292 } else {
293 goto fast_ata_pio;
295 } else if ((id->capability & 8) || (id->field_valid & 2)) {
296 fast_ata_pio:
297 dma_func = ide_dma_off_quietly;
298 no_dma_set:
299 aec6210_tune_drive(drive, 5);
301 return HWIF(drive)->dmaproc(dma_func, drive);
305 * aec6210_dmaproc() initiates/aborts (U)DMA read/write operations on a drive.
307 int aec6210_dmaproc (ide_dma_action_t func, ide_drive_t *drive)
309 switch (func) {
310 case ide_dma_check:
311 return config_drive_xfer_rate(drive);
312 default:
313 break;
315 return ide_dmaproc(func, drive); /* use standard DMA stuff */
317 #endif /* CONFIG_AEC6210_TUNING */
319 unsigned int __init pci_init_aec6210 (struct pci_dev *dev, const char *name)
321 if (dev->resource[PCI_ROM_RESOURCE].start) {
322 pci_write_config_dword(dev, PCI_ROM_ADDRESS, dev->resource[PCI_ROM_RESOURCE].start | PCI_ROM_ADDRESS_ENABLE);
323 printk("%s: ROM enabled at 0x%08lx\n", name, dev->resource[PCI_ROM_RESOURCE].start);
326 #if defined(DISPLAY_AEC6210_TIMINGS) && defined(CONFIG_PROC_FS)
327 aec6210_proc = 1;
328 bmide_dev = dev;
329 aec6210_display_info = &aec6210_get_info;
330 #endif /* DISPLAY_AEC6210_TIMINGS && CONFIG_PROC_FS */
332 return dev->irq;
335 void __init ide_init_aec6210 (ide_hwif_t *hwif)
337 #ifdef CONFIG_AEC6210_TUNING
338 hwif->tuneproc = &aec6210_tune_drive;
340 if (hwif->dma_base) {
341 hwif->dmaproc = &aec6210_dmaproc;
342 } else {
343 hwif->drives[0].autotune = 1;
344 hwif->drives[1].autotune = 1;
346 #endif /* CONFIG_AEC6210_TUNING */
349 void __init ide_dmacapable_aec6210 (ide_hwif_t *hwif, unsigned long dmabase)
351 byte dma_new = 0;
352 byte dma_old = inb(dmabase+2);
353 byte reg54h = 0;
354 byte masterdma = hwif->channel ? 0x30 : 0x03;
355 byte slavedma = hwif->channel ? 0xc0 : 0x0c;
356 unsigned long flags;
358 __save_flags(flags); /* local CPU only */
359 __cli(); /* local CPU only */
361 dma_new = dma_old;
363 pci_read_config_byte(hwif->pci_dev, 0x54, &reg54h);
365 if (reg54h & masterdma) dma_new |= 0x20;
366 if (reg54h & slavedma) dma_new |= 0x40;
367 if (dma_new != dma_old) outb(dma_new, dmabase+2);
369 __restore_flags(flags); /* local CPU only */
371 ide_setup_dma(hwif, dmabase, 8);