update atp870u driver to 0.78 from D-Link source
[linux-2.4.git] / drivers / ide / pci / slc90e66.c
1 /*
2  *  linux/drivers/ide/pci/slc90e66.c    Version 0.11    September 11, 2002
3  *
4  *  Copyright (C) 2000-2002 Andre Hedrick <andre@linux-ide.org>
5  *
6  * This a look-a-like variation of the ICH0 PIIX4 Ultra-66,
7  * but this keeps the ISA-Bridge and slots alive.
8  *
9  */
10
11 #include <linux/config.h>
12 #include <linux/types.h>
13 #include <linux/module.h>
14 #include <linux/kernel.h>
15 #include <linux/ioport.h>
16 #include <linux/pci.h>
17 #include <linux/hdreg.h>
18 #include <linux/ide.h>
19 #include <linux/delay.h>
20 #include <linux/init.h>
21
22 #include <asm/io.h>
23
24 #include "ide_modes.h"
25 #include "slc90e66.h"
26
27 #if defined(DISPLAY_SLC90E66_TIMINGS) && defined(CONFIG_PROC_FS)
28 #include <linux/stat.h>
29 #include <linux/proc_fs.h>
30
31 static u8 slc90e66_proc = 0;
32 static struct pci_dev *bmide_dev;
33
34 static int slc90e66_get_info (char *buffer, char **addr, off_t offset, int count)
35 {
36         char *p = buffer;
37         int len;
38         unsigned long bibma = pci_resource_start(bmide_dev, 4);
39         u16 reg40 = 0, psitre = 0, reg42 = 0, ssitre = 0;
40         u8  c0 = 0, c1 = 0;
41         u8  reg44 = 0, reg47 = 0, reg48 = 0, reg4a = 0, reg4b = 0;
42
43         pci_read_config_word(bmide_dev, 0x40, &reg40);
44         pci_read_config_word(bmide_dev, 0x42, &reg42);
45         pci_read_config_byte(bmide_dev, 0x44, &reg44);
46         pci_read_config_byte(bmide_dev, 0x47, &reg47);
47         pci_read_config_byte(bmide_dev, 0x48, &reg48);
48         pci_read_config_byte(bmide_dev, 0x4a, &reg4a);
49         pci_read_config_byte(bmide_dev, 0x4b, &reg4b);
50
51         psitre = (reg40 & 0x4000) ? 1 : 0;
52         ssitre = (reg42 & 0x4000) ? 1 : 0;
53
54         /*
55          * at that point bibma+0x2 et bibma+0xa are byte registers
56          * to investigate:
57          */
58         c0 = inb_p(bibma + 0x02);
59         c1 = inb_p(bibma + 0x0a);
60
61         p += sprintf(p, "                                SLC90E66 Chipset.\n");
62         p += sprintf(p, "--------------- Primary Channel "
63                         "---------------- Secondary Channel "
64                         "-------------\n");
65         p += sprintf(p, "                %sabled "
66                         "                        %sabled\n",
67                         (c0&0x80) ? "dis" : " en",
68                         (c1&0x80) ? "dis" : " en");
69         p += sprintf(p, "--------------- drive0 --------- drive1 "
70                         "-------- drive0 ---------- drive1 ------\n");
71         p += sprintf(p, "DMA enabled:    %s              %s "
72                         "            %s               %s\n",
73                         (c0&0x20) ? "yes" : "no ",
74                         (c0&0x40) ? "yes" : "no ",
75                         (c1&0x20) ? "yes" : "no ",
76                         (c1&0x40) ? "yes" : "no " );
77         p += sprintf(p, "UDMA enabled:   %s              %s "
78                         "            %s               %s\n",
79                         (reg48&0x01) ? "yes" : "no ",
80                         (reg48&0x02) ? "yes" : "no ",
81                         (reg48&0x04) ? "yes" : "no ",
82                         (reg48&0x08) ? "yes" : "no " );
83         p += sprintf(p, "UDMA enabled:   %s                %s "
84                         "              %s                 %s\n",
85                         ((reg4a&0x04)==0x04) ? "4" :
86                         ((reg4a&0x03)==0x03) ? "3" :
87                         (reg4a&0x02) ? "2" :
88                         (reg4a&0x01) ? "1" :
89                         (reg4a&0x00) ? "0" : "X",
90                         ((reg4a&0x40)==0x40) ? "4" :
91                         ((reg4a&0x30)==0x30) ? "3" :
92                         (reg4a&0x20) ? "2" :
93                         (reg4a&0x10) ? "1" :
94                         (reg4a&0x00) ? "0" : "X",
95                         ((reg4b&0x04)==0x04) ? "4" :
96                         ((reg4b&0x03)==0x03) ? "3" :
97                         (reg4b&0x02) ? "2" :
98                         (reg4b&0x01) ? "1" :
99                         (reg4b&0x00) ? "0" : "X",
100                         ((reg4b&0x40)==0x40) ? "4" :
101                         ((reg4b&0x30)==0x30) ? "3" :
102                         (reg4b&0x20) ? "2" :
103                         (reg4b&0x10) ? "1" :
104                         (reg4b&0x00) ? "0" : "X");
105
106         p += sprintf(p, "UDMA\n");
107         p += sprintf(p, "DMA\n");
108         p += sprintf(p, "PIO\n");
109
110 /*
111  *      FIXME.... Add configuration junk data....blah blah......
112  */
113
114         /* p - buffer must be less than 4k! */
115         len = (p - buffer) - offset;
116         *addr = buffer + offset;
117         
118         return len > count ? count : len;
119 }
120 #endif  /* defined(DISPLAY_SLC90E66_TIMINGS) && defined(CONFIG_PROC_FS) */
121
122 static u8 slc90e66_ratemask (ide_drive_t *drive)
123 {
124         u8 mode = 2;
125
126         if (!eighty_ninty_three(drive))
127                 mode = min(mode, (u8)1);
128         return mode;
129 }
130
131 static u8 slc90e66_dma_2_pio (u8 xfer_rate) {
132         switch(xfer_rate) {
133                 case XFER_UDMA_4:
134                 case XFER_UDMA_3:
135                 case XFER_UDMA_2:
136                 case XFER_UDMA_1:
137                 case XFER_UDMA_0:
138                 case XFER_MW_DMA_2:
139                 case XFER_PIO_4:
140                         return 4;
141                 case XFER_MW_DMA_1:
142                 case XFER_PIO_3:
143                         return 3;
144                 case XFER_SW_DMA_2:
145                 case XFER_PIO_2:
146                         return 2;
147                 case XFER_MW_DMA_0:
148                 case XFER_SW_DMA_1:
149                 case XFER_SW_DMA_0:
150                 case XFER_PIO_1:
151                 case XFER_PIO_0:
152                 case XFER_PIO_SLOW:
153                 default:
154                         return 0;
155         }
156 }
157
158 /*
159  *  Based on settings done by AMI BIOS
160  *  (might be useful if drive is not registered in CMOS for any reason).
161  */
162 static void slc90e66_tune_drive (ide_drive_t *drive, u8 pio)
163 {
164         ide_hwif_t *hwif        = HWIF(drive);
165         struct pci_dev *dev     = hwif->pci_dev;
166         int is_slave            = (&hwif->drives[1] == drive);
167         int master_port         = hwif->channel ? 0x42 : 0x40;
168         int slave_port          = 0x44;
169         unsigned long flags;
170         u16 master_data;
171         u8 slave_data;
172                                  /* ISP  RTC */
173         u8 timings[][2] = { { 0, 0 },
174                                     { 0, 0 },
175                                     { 1, 0 },
176                                     { 2, 1 },
177                                     { 2, 3 }, };
178
179         pio = ide_get_best_pio_mode(drive, pio, 5, NULL);
180         spin_lock_irqsave(&ide_lock, flags);
181         pci_read_config_word(dev, master_port, &master_data);
182         if (is_slave) {
183                 master_data = master_data | 0x4000;
184                 if (pio > 1)
185                         /* enable PPE, IE and TIME */
186                         master_data = master_data | 0x0070;
187                 pci_read_config_byte(dev, slave_port, &slave_data);
188                 slave_data = slave_data & (hwif->channel ? 0x0f : 0xf0);
189                 slave_data = slave_data | (((timings[pio][0] << 2) | timings[pio][1]) << (hwif->channel ? 4 : 0));
190         } else {
191                 master_data = master_data & 0xccf8;
192                 if (pio > 1)
193                         /* enable PPE, IE and TIME */
194                         master_data = master_data | 0x0007;
195                 master_data = master_data | (timings[pio][0] << 12) | (timings[pio][1] << 8);
196         }
197         pci_write_config_word(dev, master_port, master_data);
198         if (is_slave)
199                 pci_write_config_byte(dev, slave_port, slave_data);
200         spin_unlock_irqrestore(&ide_lock, flags);
201 }
202
203 static int slc90e66_tune_chipset (ide_drive_t *drive, u8 xferspeed)
204 {
205         ide_hwif_t *hwif        = HWIF(drive);
206         struct pci_dev *dev     = hwif->pci_dev;
207         u8 maslave              = hwif->channel ? 0x42 : 0x40;
208         u8 speed        = ide_rate_filter(slc90e66_ratemask(drive), xferspeed);
209         int sitre = 0, a_speed  = 7 << (drive->dn * 4);
210         int u_speed = 0, u_flag = 1 << drive->dn;
211         u16                     reg4042, reg44, reg48, reg4a;
212
213         pci_read_config_word(dev, maslave, &reg4042);
214         sitre = (reg4042 & 0x4000) ? 1 : 0;
215         pci_read_config_word(dev, 0x44, &reg44);
216         pci_read_config_word(dev, 0x48, &reg48);
217         pci_read_config_word(dev, 0x4a, &reg4a);
218
219         switch(speed) {
220 #ifdef CONFIG_BLK_DEV_IDEDMA
221                 case XFER_UDMA_4:       u_speed = 4 << (drive->dn * 4); break;
222                 case XFER_UDMA_3:       u_speed = 3 << (drive->dn * 4); break;
223                 case XFER_UDMA_2:       u_speed = 2 << (drive->dn * 4); break;
224                 case XFER_UDMA_1:       u_speed = 1 << (drive->dn * 4); break;
225                 case XFER_UDMA_0:       u_speed = 0 << (drive->dn * 4); break;
226                 case XFER_MW_DMA_2:
227                 case XFER_MW_DMA_1:
228                 case XFER_SW_DMA_2:     break;
229 #endif /* CONFIG_BLK_DEV_IDEDMA */
230                 case XFER_PIO_4:
231                 case XFER_PIO_3:
232                 case XFER_PIO_2:
233                 case XFER_PIO_0:        break;
234                 default:                return -1;
235         }
236
237         if (speed >= XFER_UDMA_0) {
238                 if (!(reg48 & u_flag))
239                         pci_write_config_word(dev, 0x48, reg48|u_flag);
240                 if ((reg4a & u_speed) != u_speed) {
241                         pci_write_config_word(dev, 0x4a, reg4a & ~a_speed);
242                         pci_read_config_word(dev, 0x4a, &reg4a);
243                         pci_write_config_word(dev, 0x4a, reg4a|u_speed);
244                 }
245         } else {
246                 if (reg48 & u_flag)
247                         pci_write_config_word(dev, 0x48, reg48 & ~u_flag);
248                 if (reg4a & a_speed)
249                         pci_write_config_word(dev, 0x4a, reg4a & ~a_speed);
250         }
251
252         slc90e66_tune_drive(drive, slc90e66_dma_2_pio(speed));
253         return (ide_config_drive_speed(drive, speed));
254 }
255
256 #ifdef CONFIG_BLK_DEV_IDEDMA
257 static int slc90e66_config_drive_for_dma (ide_drive_t *drive)
258 {
259         u8 speed = ide_dma_speed(drive, slc90e66_ratemask(drive));
260
261         if (!(speed)) {
262                 u8 tspeed = ide_get_best_pio_mode(drive, 255, 5, NULL);
263                 speed = slc90e66_dma_2_pio(XFER_PIO_0 + tspeed);
264         }
265
266         (void) slc90e66_tune_chipset(drive, speed);
267         return ide_dma_enable(drive);
268 }
269
270 static int slc90e66_config_drive_xfer_rate (ide_drive_t *drive)
271 {
272         ide_hwif_t *hwif        = HWIF(drive);
273         struct hd_driveid *id   = drive->id;
274
275         drive->init_speed = 0;
276
277         if ((id->capability & 1) && drive->autodma) {
278                 /* Consult the list of known "bad" drives */
279                 if (hwif->ide_dma_bad_drive(drive))
280                         goto fast_ata_pio;
281
282                 if (id->field_valid & 4) {
283                         if (id->dma_ultra & hwif->ultra_mask) {
284                                 /* Force if Capable UltraDMA */
285                                 int dma = slc90e66_config_drive_for_dma(drive);
286                                 if ((id->field_valid & 2) && !dma)
287                                         goto try_dma_modes;
288                         }
289                 } else if (id->field_valid & 2) {
290 try_dma_modes:
291                         if ((id->dma_mword & hwif->mwdma_mask) ||
292                             (id->dma_1word & hwif->swdma_mask)) {
293                                 /* Force if Capable regular DMA modes */
294                                 if (!slc90e66_config_drive_for_dma(drive))
295                                         goto no_dma_set;
296                         }
297                 } else if (hwif->ide_dma_good_drive(drive) &&
298                            (id->eide_dma_time < 150)) {
299                         /* Consult the list of known "good" drives */
300                         if (!slc90e66_config_drive_for_dma(drive))
301                                 goto no_dma_set;
302                 } else {
303                         goto fast_ata_pio;
304                 }
305                 return hwif->ide_dma_on(drive);
306         } else if ((id->capability & 8) || (id->field_valid & 2)) {
307 fast_ata_pio:
308 no_dma_set:
309                 hwif->tuneproc(drive, 5);
310                 return hwif->ide_dma_off_quietly(drive);
311         }
312         /* IORDY not supported */
313         return 0;
314 }
315 #endif /* CONFIG_BLK_DEV_IDEDMA */
316
317 static unsigned int __init init_chipset_slc90e66 (struct pci_dev *dev, const char *name)
318 {
319 #if defined(DISPLAY_SLC90E66_TIMINGS) && defined(CONFIG_PROC_FS)
320         if (!slc90e66_proc) {
321                 slc90e66_proc = 1;
322                 bmide_dev = dev;
323                 ide_pci_register_host_proc(&slc90e66_procs[0]);
324         }
325 #endif /* DISPLAY_SLC90E66_TIMINGS && CONFIG_PROC_FS */
326         return 0;
327 }
328
329 static void __init init_hwif_slc90e66 (ide_hwif_t *hwif)
330 {
331         u8 reg47 = 0;
332         u8 mask = hwif->channel ? 0x01 : 0x02;  /* bit0:Primary */
333
334         hwif->autodma = 0;
335
336         if (!hwif->irq)
337                 hwif->irq = hwif->channel ? 15 : 14;
338
339         hwif->speedproc = &slc90e66_tune_chipset;
340         hwif->tuneproc = &slc90e66_tune_drive;
341
342         pci_read_config_byte(hwif->pci_dev, 0x47, &reg47);
343
344         if (!hwif->dma_base) {
345                 hwif->drives[0].autotune = 1;
346                 hwif->drives[1].autotune = 1;
347                 return;
348         }
349
350         hwif->atapi_dma = 1;
351         hwif->ultra_mask = 0x1f;
352         hwif->mwdma_mask = 0x07;
353         hwif->swdma_mask = 0x07;
354
355 #ifdef CONFIG_BLK_DEV_IDEDMA 
356         if (!(hwif->udma_four))
357                 /* bit[0(1)]: 0:80, 1:40 */
358                 hwif->udma_four = (reg47 & mask) ? 0 : 1;
359
360         hwif->ide_dma_check = &slc90e66_config_drive_xfer_rate;
361         if (!noautodma)
362                 hwif->autodma = 1;
363         hwif->drives[0].autodma = hwif->autodma;
364         hwif->drives[1].autodma = hwif->autodma;
365 #endif /* !CONFIG_BLK_DEV_IDEDMA */
366 }
367
368 static void __init init_dma_slc90e66 (ide_hwif_t *hwif, unsigned long dmabase)
369 {
370         ide_setup_dma(hwif, dmabase, 8);
371 }
372
373 extern void ide_setup_pci_device(struct pci_dev *, ide_pci_device_t *);
374
375
376 static int __devinit slc90e66_init_one(struct pci_dev *dev, const struct pci_device_id *id)
377 {
378         ide_pci_device_t *d = &slc90e66_chipsets[id->driver_data];
379         if (dev->device != d->device)
380                 BUG();
381         ide_setup_pci_device(dev, d);
382         MOD_INC_USE_COUNT;
383         return 0;
384 }
385
386 static struct pci_device_id slc90e66_pci_tbl[] __devinitdata = {
387         { PCI_VENDOR_ID_EFAR, PCI_DEVICE_ID_EFAR_SLC90E66_1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
388         { 0, },
389 };
390
391 static struct pci_driver driver = {
392         .name           = "SLC90e66 IDE",
393         .id_table       = slc90e66_pci_tbl,
394         .probe          = slc90e66_init_one,
395 };
396
397 static int slc90e66_ide_init(void)
398 {
399         return ide_pci_register_driver(&driver);
400 }
401
402 static void slc90e66_ide_exit(void)
403 {
404         ide_pci_unregister_driver(&driver);
405 }
406
407 module_init(slc90e66_ide_init);
408 module_exit(slc90e66_ide_exit);
409
410 MODULE_AUTHOR("Andre Hedrick");
411 MODULE_DESCRIPTION("PCI driver module for SLC90E66 IDE");
412 MODULE_LICENSE("GPL");
413
414 EXPORT_NO_SYMBOLS;