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