2 * linux/drivers/block/sis5513.c Version 0.09 Feb. 10, 2000
4 * Copyright (C) 1999-2000 Andre Hedrick (andre@suse.com)
5 * May be copied or modified under the terms of the GNU General Public License
7 * Thanks to SIS Taiwan for direct support and hardware.
8 * Tested and designed on the SiS620/5513 chipset.
11 #include <linux/config.h>
12 #include <linux/types.h>
13 #include <linux/kernel.h>
14 #include <linux/delay.h>
15 #include <linux/timer.h>
17 #include <linux/ioport.h>
18 #include <linux/blkdev.h>
19 #include <linux/hdreg.h>
21 #include <linux/interrupt.h>
22 #include <linux/pci.h>
23 #include <linux/init.h>
24 #include <linux/ide.h>
29 #include "ide_modes.h"
31 #define DISPLAY_SIS_TIMINGS
32 #define SIS5513_DEBUG_DRIVE_INFO 0
34 static struct pci_dev
*host_dev
= NULL
;
36 #define arraysize(x) (sizeof(x)/sizeof(*(x)))
38 #define SIS5513_FLAG_ATA_00 0x00000000
39 #define SIS5513_FLAG_ATA_16 0x00000001
40 #define SIS5513_FLAG_ATA_33 0x00000002
41 #define SIS5513_FLAG_ATA_66 0x00000004
42 #define SIS5513_FLAG_LATENCY 0x00000010
46 unsigned short host_id
;
48 } SiSHostChipInfo
[] = {
49 { "SiS530", PCI_DEVICE_ID_SI_530
, SIS5513_FLAG_ATA_66
, },
50 { "SiS540", PCI_DEVICE_ID_SI_540
, SIS5513_FLAG_ATA_66
, },
51 { "SiS620", PCI_DEVICE_ID_SI_620
, SIS5513_FLAG_ATA_66
|SIS5513_FLAG_LATENCY
, },
52 { "SiS630", PCI_DEVICE_ID_SI_630
, SIS5513_FLAG_ATA_66
|SIS5513_FLAG_LATENCY
, },
53 { "SiS5591", PCI_DEVICE_ID_SI_5591
, SIS5513_FLAG_ATA_33
, },
54 { "SiS5597", PCI_DEVICE_ID_SI_5597
, SIS5513_FLAG_ATA_33
, },
55 { "SiS5600", PCI_DEVICE_ID_SI_5600
, SIS5513_FLAG_ATA_33
, },
56 { "SiS5511", PCI_DEVICE_ID_SI_5511
, SIS5513_FLAG_ATA_16
, },
61 static struct _pio_mode_mapping
{
65 } pio_mode_mapping
[] = {
73 static struct _dma_mode_mapping
{
77 } dma_mode_mapping
[] = {
83 static struct _udma_mode_mapping
{
86 } udma_mode_mapping
[] = {
95 static __inline__
char * find_udma_mode (byte cycle_time
)
99 for (n
= 0; n
<= 4; n
++)
100 if (udma_mode_mapping
[n
].cycle_time
<= cycle_time
)
101 return udma_mode_mapping
[n
].udma_mode
;
102 return udma_mode_mapping
[4].udma_mode
;
106 #if defined(DISPLAY_SIS_TIMINGS) && defined(CONFIG_PROC_FS)
107 #include <linux/stat.h>
108 #include <linux/proc_fs.h>
110 static int sis_get_info(char *, char **, off_t
, int);
111 extern int (*sis_display_info
)(char *, char **, off_t
, int); /* ide-proc.c */
112 struct pci_dev
*bmide_dev
;
114 static char *cable_type
[] = {
119 static char *recovery_time
[] ={
120 "12 PCICLK", "1 PCICLK",
121 "2 PCICLK", "3 PCICLK",
122 "4 PCICLK", "5 PCICLCK",
123 "6 PCICLK", "7 PCICLCK",
124 "8 PCICLK", "9 PCICLCK",
125 "10 PCICLK", "11 PCICLK",
126 "13 PCICLK", "14 PCICLK",
127 "15 PCICLK", "15 PCICLK"
130 static char *cycle_time
[] = {
131 "Undefined", "2 CLCK",
137 static char *active_time
[] = {
138 "8 PCICLK", "1 PCICLCK",
139 "2 PCICLK", "2 PCICLK",
140 "4 PCICLK", "5 PCICLK",
141 "6 PCICLK", "12 PCICLK"
144 static int sis_get_info (char *buffer
, char **addr
, off_t offset
, int count
)
151 p
+= sprintf(p
, "--------------- Primary Channel ---------------- Secondary Channel -------------\n");
152 rc
= pci_read_config_byte(bmide_dev
, 0x4a, ®
);
153 p
+= sprintf(p
, "Channel Status: %s \t \t \t \t %s \n",
154 (reg
& 0x02) ? "On" : "Off",
155 (reg
& 0x04) ? "On" : "Off");
157 rc
= pci_read_config_byte(bmide_dev
, 0x09, ®
);
158 p
+= sprintf(p
, "Operation Mode: %s \t \t \t %s \n",
159 (reg
& 0x01) ? "Native" : "Compatible",
160 (reg
& 0x04) ? "Native" : "Compatible");
162 rc
= pci_read_config_byte(bmide_dev
, 0x48, ®
);
163 p
+= sprintf(p
, "Cable Type: %s \t \t \t %s\n",
164 (reg
& 0x10) ? cable_type
[1] : cable_type
[0],
165 (reg
& 0x20) ? cable_type
[1] : cable_type
[0]);
167 rc
= pci_read_config_word(bmide_dev
, 0x4c, ®2
);
168 rc
= pci_read_config_word(bmide_dev
, 0x4e, ®3
);
169 p
+= sprintf(p
, "Prefetch Count: %d \t \t \t \t %d\n",
172 rc
= pci_read_config_byte(bmide_dev
, 0x4b, ®
);
173 p
+= sprintf(p
, "Drvie 0: Postwrite %s \t \t Postwrite %s\n",
174 (reg
& 0x10) ? "Enabled" : "Disabled",
175 (reg
& 0x40) ? "Enabled" : "Disabled");
176 p
+= sprintf(p
, " Prefetch %s \t \t Prefetch %s\n",
177 (reg
& 0x01) ? "Enabled" : "Disabled",
178 (reg
& 0x04) ? "Enabled" : "Disabled");
180 rc
= pci_read_config_byte(bmide_dev
, 0x41, ®
);
181 rc
= pci_read_config_byte(bmide_dev
, 0x45, ®1
);
182 p
+= sprintf(p
, " UDMA %s \t \t \t UDMA %s\n",
183 (reg
& 0x80) ? "Enabled" : "Disabled",
184 (reg1
& 0x80) ? "Enabled" : "Disabled");
185 p
+= sprintf(p
, " UDMA Cycle Time %s \t UDMA Cycle Time %s\n",
186 cycle_time
[(reg
& 0x70) >> 4], cycle_time
[(reg1
& 0x70) >> 4]);
187 p
+= sprintf(p
, " Data Active Time %s \t Data Active Time %s\n",
188 active_time
[(reg
& 0x07)], active_time
[(reg
&0x07)] );
190 rc
= pci_read_config_byte(bmide_dev
, 0x40, ®
);
191 rc
= pci_read_config_byte(bmide_dev
, 0x44, ®1
);
192 p
+= sprintf(p
, " Data Recovery Time %s \t Data Recovery Time %s\n",
193 recovery_time
[(reg
& 0x0f)], recovery_time
[(reg1
& 0x0f)]);
196 rc
= pci_read_config_byte(bmide_dev
, 0x4b, ®
);
197 p
+= sprintf(p
, "Drvie 1: Postwrite %s \t \t Postwrite %s\n",
198 (reg
& 0x20) ? "Enabled" : "Disabled",
199 (reg
& 0x80) ? "Enabled" : "Disabled");
200 p
+= sprintf(p
, " Prefetch %s \t \t Prefetch %s\n",
201 (reg
& 0x02) ? "Enabled" : "Disabled",
202 (reg
& 0x08) ? "Enabled" : "Disabled");
204 rc
= pci_read_config_byte(bmide_dev
, 0x43, ®
);
205 rc
= pci_read_config_byte(bmide_dev
, 0x47, ®1
);
206 p
+= sprintf(p
, " UDMA %s \t \t \t UDMA %s\n",
207 (reg
& 0x80) ? "Enabled" : "Disabled",
208 (reg1
& 0x80) ? "Enabled" : "Disabled");
209 p
+= sprintf(p
, " UDMA Cycle Time %s \t UDMA Cycle Time %s\n",
210 cycle_time
[(reg
& 0x70) >> 4], cycle_time
[(reg1
& 0x70) >> 4]);
211 p
+= sprintf(p
, " Data Active Time %s \t Data Active Time %s\n",
212 active_time
[(reg
& 0x07)], active_time
[(reg
&0x07)] );
214 rc
= pci_read_config_byte(bmide_dev
, 0x42, ®
);
215 rc
= pci_read_config_byte(bmide_dev
, 0x46, ®1
);
216 p
+= sprintf(p
, " Data Recovery Time %s \t Data Recovery Time %s\n",
217 recovery_time
[(reg
& 0x0f)], recovery_time
[(reg1
& 0x0f)]);
220 #endif /* defined(DISPLAY_SIS_TIMINGS) && defined(CONFIG_PROC_FS) */
223 extern char *ide_xfer_verbose (byte xfer_rate
);
226 * ((id->hw_config & 0x2000) && (HWIF(drive)->udma_four))
228 static int config_chipset_for_dma (ide_drive_t
*drive
, byte ultra
)
230 struct hd_driveid
*id
= drive
->id
;
231 ide_hwif_t
*hwif
= HWIF(drive
);
232 struct pci_dev
*dev
= hwif
->pci_dev
;
234 byte drive_pci
, test1
, test2
, mask
;
237 unsigned long dma_base
= hwif
->dma_base
;
238 byte unit
= (drive
->select
.b
.unit
& 0x01);
239 byte speed
= 0x00, unmask
= 0xE0, four_two
= 0x00;
240 int drive_number
= ((hwif
->channel
? 2 : 0) + unit
);
241 byte udma_66
= ((id
->hw_config
& 0x2000) && (hwif
->udma_four
)) ? 1 : 0;
244 switch(host_dev
->device
) {
245 case PCI_DEVICE_ID_SI_530
:
246 case PCI_DEVICE_ID_SI_540
:
247 case PCI_DEVICE_ID_SI_620
:
248 case PCI_DEVICE_ID_SI_630
:
256 switch(drive_number
) {
257 case 0: drive_pci
= 0x40;break;
258 case 1: drive_pci
= 0x42;break;
259 case 2: drive_pci
= 0x44;break;
260 case 3: drive_pci
= 0x46;break;
261 default: return ide_dma_off
;
264 pci_read_config_byte(dev
, drive_pci
, &test1
);
265 pci_read_config_byte(dev
, drive_pci
|0x01, &test2
);
267 if ((!ultra
) && (test2
& 0x80)) {
268 pci_write_config_byte(dev
, drive_pci
|0x01, test2
& ~0x80);
269 pci_read_config_byte(dev
, drive_pci
|0x01, &test2
);
272 if ((id
->dma_ultra
& 0x0010) && (ultra
) && (udma_66
) && (four_two
)) {
273 if (!(test2
& 0x90)) {
274 pci_write_config_byte(dev
, drive_pci
|0x01, test2
& ~unmask
);
275 pci_write_config_byte(dev
, drive_pci
|0x01, test2
|0x90);
278 } else if ((id
->dma_ultra
& 0x0008) && (ultra
) && (udma_66
) && (four_two
)) {
279 if (!(test2
& 0xA0)) {
280 pci_write_config_byte(dev
, drive_pci
|0x01, test2
& ~unmask
);
281 pci_write_config_byte(dev
, drive_pci
|0x01, test2
|0xA0);
284 } else if ((id
->dma_ultra
& 0x0004) && (ultra
)) {
285 mask
= (four_two
) ? 0xB0 : 0xA0;
286 if (!(test2
& mask
)) {
287 pci_write_config_byte(dev
, drive_pci
|0x01, test2
& ~unmask
);
288 pci_write_config_byte(dev
, drive_pci
|0x01, test2
|mask
);
291 } else if ((id
->dma_ultra
& 0x0002) && (ultra
)) {
292 mask
= (four_two
) ? 0xD0 : 0xC0;
293 if (!(test2
& mask
)) {
294 pci_write_config_byte(dev
, drive_pci
|0x01, test2
& ~unmask
);
295 pci_write_config_byte(dev
, drive_pci
|0x01, test2
|mask
);
298 } else if ((id
->dma_ultra
& 0x0001) && (ultra
)) {
299 if (!(test2
& unmask
)) {
300 pci_write_config_byte(dev
, drive_pci
|0x01, test2
& ~unmask
);
301 pci_write_config_byte(dev
, drive_pci
|0x01, test2
|unmask
);
304 } else if (id
->dma_mword
& 0x0004) {
305 speed
= XFER_MW_DMA_2
;
306 } else if (id
->dma_mword
& 0x0002) {
307 speed
= XFER_MW_DMA_1
;
308 } else if (id
->dma_mword
& 0x0001) {
309 speed
= XFER_MW_DMA_0
;
310 } else if (id
->dma_1word
& 0x0004) {
311 speed
= XFER_SW_DMA_2
;
312 } else if (id
->dma_1word
& 0x0002) {
313 speed
= XFER_SW_DMA_1
;
314 } else if (id
->dma_1word
& 0x0001) {
315 speed
= XFER_SW_DMA_0
;
317 return ((int) ide_dma_off_quietly
);
320 outb(inb(dma_base
+2)|(1<<(5+unit
)), dma_base
+2);
321 err
= ide_config_drive_speed(drive
, speed
);
323 #if SIS5513_DEBUG_DRIVE_INFO
324 printk("%s: %s drive%d\n", drive
->name
, ide_xfer_verbose(speed
), drive_number
);
325 #endif /* SIS5513_DEBUG_DRIVE_INFO */
327 return ((int) ((id
->dma_ultra
>> 11) & 3) ? ide_dma_on
:
328 ((id
->dma_ultra
>> 8) & 7) ? ide_dma_on
:
329 ((id
->dma_mword
>> 8) & 7) ? ide_dma_on
:
330 ((id
->dma_1word
>> 8) & 7) ? ide_dma_on
:
331 ide_dma_off_quietly
);
334 static void config_drive_art_rwp (ide_drive_t
*drive
)
336 ide_hwif_t
*hwif
= HWIF(drive
);
337 struct pci_dev
*dev
= hwif
->pci_dev
;
339 byte timing
, pio
, drive_pci
, test1
, test2
;
341 unsigned short eide_pio_timing
[6] = {600, 390, 240, 180, 120, 90};
342 unsigned short xfer_pio
= drive
->id
->eide_pio_modes
;
343 int drive_number
= ((hwif
->channel
? 2 : 0) + (drive
->select
.b
.unit
& 0x01));
345 if (drive
->media
== ide_disk
) {
346 struct pci_dev
*dev
= hwif
->pci_dev
;
348 byte rw_prefetch
= (0x11 << drive_number
);
350 pci_read_config_byte(dev
, 0x4b, ®4bh
);
351 if ((reg4bh
& rw_prefetch
) != rw_prefetch
)
352 pci_write_config_byte(dev
, 0x4b, reg4bh
|rw_prefetch
);
355 pio
= ide_get_best_pio_mode(drive
, 255, 5, NULL
);
360 if (drive
->id
->eide_pio_iordy
> 0) {
363 drive
->id
->eide_pio_iordy
>eide_pio_timing
[xfer_pio
];
366 xfer_pio
= (drive
->id
->eide_pio_modes
& 4) ? 0x05 :
367 (drive
->id
->eide_pio_modes
& 2) ? 0x04 :
368 (drive
->id
->eide_pio_modes
& 1) ? 0x03 : xfer_pio
;
371 timing
= (xfer_pio
>= pio
) ? xfer_pio
: pio
;
374 * Mode 0 Mode 1 Mode 2 Mode 3 Mode 4
375 * Active time 8T (240ns) 6T (180ns) 4T (120ns) 3T (90ns) 3T (90ns)
376 * 0x41 2:0 bits 000 110 100 011 011
377 * Recovery time 12T (360ns) 7T (210ns) 4T (120ns) 3T (90ns) 1T (30ns)
378 * 0x40 3:0 bits 0000 0111 0100 0011 0001
379 * Cycle time 20T (600ns) 13T (390ns) 8T (240ns) 6T (180ns) 4T (120ns)
382 switch(drive_number
) {
383 case 0: drive_pci
= 0x40;break;
384 case 1: drive_pci
= 0x42;break;
385 case 2: drive_pci
= 0x44;break;
386 case 3: drive_pci
= 0x46;break;
390 pci_read_config_byte(dev
, drive_pci
, &test1
);
391 pci_read_config_byte(dev
, drive_pci
|0x01, &test2
);
394 * Do a blanket clear of active and recovery timings.
401 case 4: test1
|= 0x01;test2
|= 0x03;break;
402 case 3: test1
|= 0x03;test2
|= 0x03;break;
403 case 2: test1
|= 0x04;test2
|= 0x04;break;
404 case 1: test1
|= 0x07;test2
|= 0x06;break;
408 pci_write_config_byte(dev
, drive_pci
, test1
);
409 pci_write_config_byte(dev
, drive_pci
|0x01, test2
);
412 static int config_drive_xfer_rate (ide_drive_t
*drive
)
414 struct hd_driveid
*id
= drive
->id
;
415 ide_dma_action_t dma_func
= ide_dma_off_quietly
;
417 if (id
&& (id
->capability
& 1) && HWIF(drive
)->autodma
) {
418 /* Consult the list of known "bad" drives */
419 if (ide_dmaproc(ide_dma_bad_drive
, drive
)) {
420 return HWIF(drive
)->dmaproc(ide_dma_off
, drive
);
423 if (id
->field_valid
& 4) {
424 if (id
->dma_ultra
& 0x001F) {
425 /* Force if Capable UltraDMA */
426 dma_func
= config_chipset_for_dma(drive
, 1);
427 if ((id
->field_valid
& 2) &&
428 (dma_func
!= ide_dma_on
))
431 } else if (id
->field_valid
& 2) {
433 if ((id
->dma_mword
& 0x0007) ||
434 (id
->dma_1word
& 0x0007)) {
435 /* Force if Capable regular DMA modes */
436 dma_func
= config_chipset_for_dma(drive
, 0);
438 } else if ((ide_dmaproc(ide_dma_good_drive
, drive
)) &&
439 (id
->eide_dma_time
> 150)) {
440 /* Consult the list of known "good" drives */
441 dma_func
= config_chipset_for_dma(drive
, 0);
444 return HWIF(drive
)->dmaproc(dma_func
, drive
);
448 * sis5513_dmaproc() initiates/aborts (U)DMA read/write operations on a drive.
450 int sis5513_dmaproc (ide_dma_action_t func
, ide_drive_t
*drive
)
454 config_drive_art_rwp(drive
);
455 return config_drive_xfer_rate(drive
);
459 return ide_dmaproc(func
, drive
); /* use standard DMA stuff */
462 unsigned int __init
pci_init_sis5513 (struct pci_dev
*dev
, const char *name
)
464 struct pci_dev
*host
;
468 pci_read_config_byte(dev
, PCI_LATENCY_TIMER
, &latency
);
470 for (i
= 0; i
< arraysize (SiSHostChipInfo
) && !host_dev
; i
++) {
471 host
= pci_find_device (PCI_VENDOR_ID_SI
,
472 SiSHostChipInfo
[i
].host_id
,
478 printk(SiSHostChipInfo
[i
].name
);
480 if (SiSHostChipInfo
[i
].flags
& SIS5513_FLAG_LATENCY
) {
482 pci_write_config_byte(dev
, PCI_LATENCY_TIMER
, 0x10);
489 pci_read_config_byte(dev
, 0x52, ®52h
);
490 if (!(reg52h
& 0x04)) {
491 /* set IDE controller to operate in Compabitility mode obly */
492 pci_write_config_byte(dev
, 0x52, reg52h
|0x04);
494 #if defined(DISPLAY_SIS_TIMINGS) && defined(CONFIG_PROC_FS)
497 sis_display_info
= &sis_get_info
;
498 #endif /* defined(DISPLAY_SIS_TIMINGS) && defined(CONFIG_PROC_FS) */
503 unsigned int __init
ata66_sis5513 (ide_hwif_t
*hwif
)
505 byte reg48h
= 0, ata66
= 0;
506 byte mask
= hwif
->channel
? 0x20 : 0x10;
507 pci_read_config_byte(hwif
->pci_dev
, 0x48, ®48h
);
510 switch(host_dev
->device
) {
511 case PCI_DEVICE_ID_SI_530
:
512 case PCI_DEVICE_ID_SI_540
:
513 case PCI_DEVICE_ID_SI_620
:
514 case PCI_DEVICE_ID_SI_630
:
515 ata66
= (reg48h
& mask
) ? 0 : 1;
523 void __init
ide_init_sis5513 (ide_hwif_t
*hwif
)
526 hwif
->irq
= hwif
->channel
? 15 : 14;
528 if (!(hwif
->dma_base
))
532 switch(host_dev
->device
) {
533 case PCI_DEVICE_ID_SI_530
:
534 case PCI_DEVICE_ID_SI_540
:
535 case PCI_DEVICE_ID_SI_620
:
536 case PCI_DEVICE_ID_SI_630
:
537 case PCI_DEVICE_ID_SI_5600
:
538 case PCI_DEVICE_ID_SI_5597
:
539 case PCI_DEVICE_ID_SI_5591
:
541 hwif
->dmaproc
= &sis5513_dmaproc
;