2 * linux/drivers/block/via82c586.c Version 0.03 Nov. 19, 1998
4 * Copyright (C) 1998 Michel Aubry, Maintainer
5 * Copyright (C) 1998 Andre Hedrick, Integrater
7 * The VIA MVP-3 is reported OK with UDMA.
8 * The TX Pro III is also reported OK with UDMA.
10 * VIA chips also have a single FIFO, with the same 64 bytes deep
11 * buffer (16 levels of 4 bytes each).
13 * However, VIA chips can have the buffer split either 8:8 levels,
14 * 16:0 levels or 0:16 levels between both channels. One could think
15 * of using this feature, as even if no level of FIFO is given to a
16 * given channel, one can for instance always reach ATAPI drives through
17 * it, or, if one channel is unused, configuration defaults to
18 * an even split FIFO levels.
20 * This feature is available only through a kernel command line :
21 * "splitfifo=Chan,Thr0,Thr1" or "splitfifo=Chan".
22 * where: Chan =1,2,3 or 4 and Thrx = 1,2,3,or 4.
25 * gives all the fifo to channel 0,
26 * sets its threshold to Thr0/4,
27 * and disables any dma access to channel 1.
30 * gives all the fifo to channel 1,
31 * sets its threshold to Thr1/4,
32 * and disables any dma access to channel 0.
35 * shares evenly fifo between channels,
36 * gives channel 0 a threshold of Thr0/4,
37 * and channel 1 a threshold of Thr1/4.
39 * Note that by default (if no command line is provided) and if a channel
40 * has been disabled in Bios, all the fifo is given to the active channel,
41 * and its threshold is set to 3/4.
44 #include <linux/config.h>
45 #include <linux/types.h>
46 #include <linux/kernel.h>
47 #include <linux/timer.h>
49 #include <linux/ioport.h>
50 #include <linux/interrupt.h>
51 #include <linux/blkdev.h>
52 #include <linux/hdreg.h>
53 #include <linux/pci.h>
54 #include <linux/init.h>
55 #include <linux/delay.h>
56 #include <linux/ide.h>
60 #define DISPLAY_VIA_TIMINGS
62 #if defined(DISPLAY_VIA_TIMINGS) && defined(CONFIG_PROC_FS)
63 #include <linux/stat.h>
64 #include <linux/proc_fs.h>
66 static char *FIFO_str
[] = {
73 static char *control3_str
[] = {
80 static int via_get_info(char *, char **, off_t
, int, int);
81 extern int (*via_display_info
)(char *, char **, off_t
, int, int); /* ide-proc.c */
82 static struct pci_dev
*bmide_dev
;
84 static char * print_apollo_drive_config (char *buf
, struct pci_dev
*dev
)
91 /* Drive Timing Control */
92 rc
= pci_read_config_dword(dev
, 0x48, &time
);
93 p
+= sprintf(p
, "Act Pls Width: %02d %02d %02d %02d\n",
94 ((time
& 0xf0000000)>>28) + 1,
95 ((time
& 0xf00000)>>20) + 1,
96 ((time
& 0xf000)>>12) + 1,
97 ((time
& 0xf0)>>4) + 1 );
98 p
+= sprintf(p
, "Recovery Time: %02d %02d %02d %02d\n",
99 ((time
& 0x0f000000)>>24) + 1,
100 ((time
& 0x0f0000)>>16) + 1,
101 ((time
& 0x0f00)>>8) + 1,
104 /* Address Setup Time */
105 rc
= pci_read_config_byte(dev
, 0x4C, &tm
);
106 p
+= sprintf(p
, "Add. Setup T.: %01dT %01dT %01dT %01dT\n",
107 ((tm
& 0xc0)>>6) + 1,
108 ((tm
& 0x30)>>4) + 1,
109 ((tm
& 0x0c)>>2) + 1,
112 /* UltraDMA33 Extended Timing Control */
113 rc
= pci_read_config_dword(dev
, 0x50, &time
);
114 p
+= sprintf(p
, "------------------UDMA-Timing-Control------------------------\n");
115 p
+= sprintf(p
, "Enable Meth.: %01d %01d %01d %01d\n",
116 (time
& 0x80000000) ? 1 : 0,
117 (time
& 0x800000) ? 1 : 0,
118 (time
& 0x8000) ? 1 : 0,
119 (time
& 0x80) ? 1 : 0 );
120 p
+= sprintf(p
, "Enable: %s %s %s %s\n",
121 (time
& 0x40000000) ? "yes" : "no ",
122 (time
& 0x400000) ? "yes" : "no ",
123 (time
& 0x4000) ? "yes" : "no ",
124 (time
& 0x40) ? "yes" : "no " );
125 p
+= sprintf(p
, "Transfer Mode: %s %s %s %s\n",
126 (time
& 0x20000000) ? "PIO" : "DMA",
127 (time
& 0x200000) ? "PIO" : "DMA",
128 (time
& 0x2000) ? "PIO" : "DMA",
129 (time
& 0x20) ? "PIO" : "DMA" );
130 p
+= sprintf(p
, "Cycle Time: %01dT %01dT %01dT %01dT\n",
131 ((time
& 0x03000000)>>24) + 2,
132 ((time
& 0x030000)>>16) + 2,
133 ((time
& 0x0300)>>8) + 2,
139 static char * print_apollo_ide_config (char *buf
, struct pci_dev
*dev
)
142 unsigned short size0
, size1
;
146 rc
= pci_read_config_byte(dev
, 0x41, &time
);
147 p
+= sprintf(p
, "Prefetch Buffer : %s %s\n",
148 (time
& 128) ? "on " : "off",
149 (time
& 32) ? "on " : "off" );
150 p
+= sprintf(p
, "Post Write Buffer: %s %s\n",
151 (time
& 64) ? "on " : "off",
152 (time
& 16) ? "on " : "off" );
154 /* FIFO configuration */
155 rc
= pci_read_config_byte(dev
, 0x43, &time
);
156 tmp
= ((time
& 0x20)>>2) + ((time
& 0x40)>>3);
157 p
+= sprintf(p
, "FIFO Conf/Chan. : %02d %02d\n",
159 tmp
= (time
& 0x0F)>>2;
160 p
+= sprintf(p
, "Threshold Prim. : %s %s\n",
162 FIFO_str
[time
& 0x03] );
164 /* chipset Control3 */
165 rc
= pci_read_config_byte(dev
, 0x46, &time
);
166 p
+= sprintf(p
, "Read DMA FIFO flush: %s %s\n",
167 (time
& 0x80) ? "on " : "off",
168 (time
& 0x40) ? "on " : "off" );
169 p
+= sprintf(p
, "End Sect. FIFO flush: %s %s\n",
170 (time
& 0x20) ? "on " : "off",
171 (time
& 0x10) ? "on " : "off" );
172 p
+= sprintf(p
, "Max DRDY Pulse Width: %s %s\n",
173 control3_str
[(time
& 0x03)],
174 (time
& 0x03) ? "PCI clocks" : "" );
176 /* Primary and Secondary sector sizes */
177 rc
= pci_read_config_word(dev
, 0x60, &size0
);
178 rc
= pci_read_config_word(dev
, 0x68, &size1
);
179 p
+= sprintf(p
, "Bytes Per Sector: %03d %03d\n",
186 static char * print_apollo_chipset_control1 (char *buf
, struct pci_dev
*dev
)
194 rc
= pci_read_config_word(dev
, 0x04, &c
);
195 rc
= pci_read_config_byte(dev
, 0x44, &t
);
196 rc
= pci_read_config_byte(dev
, 0x0d, &l
);
197 rc
= pci_read_config_byte(dev
, 0x3f, &l_max
);
199 p
+= sprintf(p
, "Command register = 0x%x\n", c
);
200 p
+= sprintf(p
, "Master Read Cycle IRDY %d Wait State\n",
202 p
+= sprintf(p
, "Master Write Cycle IRDY %d Wait State\n",
204 p
+= sprintf(p
, "FIFO Output Data 1/2 Clock Advance: %s\n",
205 (t
& 16) ? "on " : "off" );
206 p
+= sprintf(p
, "Bus Master IDE Status Register Read Retry: %s\n",
207 (t
& 8) ? "on " : "off" );
208 p
+= sprintf(p
, "Latency timer = %d (max. = %d)\n",
214 static char * print_apollo_chipset_control2 (char *buf
, struct pci_dev
*dev
)
219 rc
= pci_read_config_byte(dev
, 0x45, &t
);
220 p
+= sprintf(p
, "Interrupt Steering Swap: %s\n",
221 (t
& 64) ? "on ":"off" );
226 static char * print_apollo_chipset_control3 (char *buf
, struct pci_dev
*dev
,
230 * at that point we can be sure that register 0x20 of the
231 * chipset contains the right address...
238 rc
= pci_read_config_dword(dev
, 0x20, &bibma
);
239 bibma
= (bibma
& 0xfff0) ;
242 * at that point bibma+0x2 et bibma+0xa are byte registers
245 c0
= inb((unsigned short)bibma
+ 0x02);
246 c1
= inb((unsigned short)bibma
+ 0x0a);
249 /*p = sprintf(p,"--------------------Primary IDE------------Secondary IDE-----");*/
250 p
+= sprintf(p
, "both channels togth: %s %s\n",
251 (c0
&0x80) ? "no" : "yes",
252 (c1
&0x80) ? "no" : "yes" );
254 /*p = sprintf(p,"--------------drive0------drive1-------drive0------drive1----");*/
255 p
+= sprintf(p
, "DMA enabled: %s %s %s %s\n",
256 (c0
&0x20) ? "yes" : "no ",
257 (c0
&0x40) ? "yes" : "no ",
258 (c1
&0x20) ? "yes" : "no ",
259 (c1
&0x40) ? "yes" : "no " );
265 static int via_get_info (char *buffer
, char **addr
, off_t offset
, int count
, int dummy
)
268 * print what /proc/via displays,
269 * if required from DISPLAY_APOLLO_TIMINGS
272 /* Parameter of chipset : */
274 /* Miscellaneous control 1 */
275 p
= print_apollo_chipset_control1(buffer
, bmide_dev
);
277 /* Miscellaneous control 2 */
278 p
= print_apollo_chipset_control2(p
, bmide_dev
);
279 /* Parameters of drives: */
282 p
+= sprintf(p
, "------------------Primary IDE------------Secondary IDE-----\n");
283 p
= print_apollo_chipset_control3(p
, bmide_dev
, 0);
284 p
= print_apollo_ide_config(p
, bmide_dev
);
285 p
+= sprintf(p
, "--------------drive0------drive1-------drive0------drive1----\n");
286 p
= print_apollo_chipset_control3(p
, bmide_dev
, 1);
287 p
= print_apollo_drive_config(p
, bmide_dev
);
289 return p
-buffer
; /* hoping it is less than 4K... */
292 #endif /* defined(DISPLAY_VIA_TIMINGS) && defined(CONFIG_PROC_FS) */
295 * Used to set Fifo configuration via kernel command line:
299 static byte newfifo
= 0;
301 /* Used to just intialize once Fifo configuration */
302 static short int done
= 0;
305 * Set VIA Chipset Timings for (U)DMA modes enabled.
307 * VIA Apollo chipset has complete support for
308 * setting up the timing parameters.
310 static void set_via_timings (ide_hwif_t
*hwif
)
312 struct pci_dev
*dev
= hwif
->pci_dev
;
313 byte post
= hwif
->channel
? 0x30 : 0xc0;
314 byte flush
= hwif
->channel
? 0x50 : 0xa0;
315 int mask
= hwif
->channel
? ((newfifo
& 0x60) ? 0 : 1) :
316 (((newfifo
& 0x60) == 0x60) ? 1 : 0);
318 int rc
= 0, errors
= 0;
320 printk("%s: VIA Bus-Master ", hwif
->name
);
323 * setting IDE read prefetch buffer and IDE post write buffer.
324 * (This feature allows prefetched reads and post writes).
326 if ((rc
= pci_read_config_byte(dev
, 0x41, &via_config
)))
330 if ((rc
= pci_write_config_byte(dev
, 0x41, via_config
& ~post
)))
333 if ((rc
= pci_write_config_byte(dev
, 0x41, via_config
| post
)))
338 * setting Channel read and End-of-sector FIFO flush.
339 * (This feature ensures that FIFO flush is enabled:
340 * - for read DMA when interrupt asserts the given channel.
341 * - at the end of each sector for the given channel.)
343 if ((rc
= pci_read_config_byte(dev
, 0x46, &via_config
)))
347 if ((rc
= pci_write_config_byte(dev
, 0x46, via_config
& ~flush
)))
350 if ((rc
= pci_write_config_byte(dev
, 0x46, via_config
| flush
)))
355 printk("Config %s. No DMA Enabled\n",
356 errors
? "ERROR":"Success");
358 printk("(U)DMA Timing Config %s\n",
359 errors
? "ERROR" : "Success");
363 * Sets VIA 82c586 FIFO configuration:
364 * This chipsets gets a splitable fifo. This can be driven either by command
365 * line option (eg "splitfifo=2,2,3" which asks this driver to switch all the
366 * 16 fifo levels to the second drive, and give it a threshold of 3 for (u)dma
370 static int via_set_fifoconfig(ide_hwif_t
*hwif
)
373 unsigned int timings
;
374 struct pci_dev
*dev
= hwif
->pci_dev
;
376 /* read port configuration */
377 if (pci_read_config_dword(dev
, 0x40, &timings
))
380 /* first read actual fifo config: */
381 if (pci_read_config_byte(dev
, 0x43, &fifo
))
384 /* keep 4 and 7 bit as they seem to differ between chipsets flavors... */
385 newfifo
= fifo
& 0x90;
388 /* we received a config request from kernel command line: */
389 newfifo
|= fifoconfig
& 0x6f;
391 /* If ever just one channel is unused, allocate all fifo levels to it
392 * and give it a 3/4 threshold for (u)dma transfers.
393 * Otherwise, share it evenly between channels:
395 if ((timings
& 3) == 2) {
396 /* only primary channel is enabled
397 * 16 buf. to prim. chan. thresh=3/4
400 } else if ((timings
& 3) == 1) {
401 /* only secondary channel is enabled!
402 * 16 buffers to sec. ch. thresh=3/4
406 /* fifo evenly distributed: */
411 /* write resulting configuration to chipset: */
412 if (pci_write_config_byte(dev
, 0x43, newfifo
))
415 /* and then reread it to get the actual one */
416 if (pci_read_config_byte(dev
, 0x43, &newfifo
))
419 /* print a kernel report: */
420 printk("Split FIFO Configuration: %s Primary buffers, threshold = %s\n",
421 ((newfifo
& 0x60) == 0x60) ? " 0" :
422 ((newfifo
& 0x60) ? " 8" : "16"),
423 !(newfifo
& 0x0c) ? "1" :
424 (!(newfifo
& 0x08) ? "3/4" :
425 (newfifo
& 0x04) ? "1/4" : "1/2"));
427 printk(" %s Second. buffers, threshold = %s\n",
428 ((newfifo
& 0x60) == 0x60) ? "16" :
429 ((newfifo
& 0x60) ? " 8" : " 0"),
430 !(newfifo
& 0x03) ? "1" :
431 (!(newfifo
& 0x02) ? "3/4" :
432 (newfifo
& 0x01) ? "1/4" : "1/2"));
434 #if defined(DISPLAY_VIA_TIMINGS) && defined(CONFIG_PROC_FS)
435 bmide_dev
= hwif
->pci_dev
;
436 via_display_info
= &via_get_info
;
437 #endif /* DISPLAY_VIA_TIMINGS && CONFIG_PROC_FS*/
442 * ide_dmacapable_via82c568(ide_hwif_t *, unsigned long)
443 * checks if channel "channel" of if hwif is dma
444 * capable or not, according to kernel command line,
445 * and the new fifo settings.
446 * It calls "ide_setup_dma" on capable mainboards, and
447 * bypasses the setup if not capable.
450 void ide_dmacapable_via82c586 (ide_hwif_t
*hwif
, unsigned long dmabase
)
453 via_set_fifoconfig(hwif
);
458 * check if any fifo is available for requested port:
460 if (((hwif
->channel
== 0) && ((newfifo
& 0x60) == 0x60)) ||
461 ((hwif
->channel
== 1) && ((newfifo
& 0x60) == 0x00))) {
462 printk(" %s: VP_IDE Bus-Master DMA disabled (FIFO setting)\n", hwif
->name
);
464 ide_setup_dma(hwif
, dmabase
, 8);
468 __initfunc(void ide_init_via82c586 (ide_hwif_t
*hwif
))
470 set_via_timings(hwif
);