This source file includes following definitions.
- put_cmd640_reg_pci1
- get_cmd640_reg_pci1
- put_cmd640_reg_pci2
- get_cmd640_reg_pci2
- put_cmd640_reg_vlb
- get_cmd640_reg_vlb
- probe_for_cmd640_pci1
- probe_for_cmd640_pci2
- probe_for_cmd640_vlb
- cmd640_reset_controller
- secondary_port_responding
- ide_probe_for_cmd640x
- cmd640_off
- set_readahead_mode
- strmatch
- known_drive_readahead
- pack_arttim
- pack_counts
- max
- max4
- cmd640_set_timing
- cmd640_timings_to_clocks
- set_pio_mode
- cmd640_set_mode
- cmd640_tune_drive
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50 #undef REALLY_SLOW_IO
51
52 #include <linux/types.h>
53 #include <linux/kernel.h>
54 #include <linux/delay.h>
55 #include <linux/timer.h>
56 #include <linux/mm.h>
57 #include <linux/ioport.h>
58 #include <linux/blkdev.h>
59 #include <linux/hdreg.h>
60 #include <asm/io.h>
61 #include "ide.h"
62 #include "ide_modes.h"
63
64 int cmd640_vlb = 0;
65
66
67
68
69
70 #define VID 0x00
71 #define DID 0x02
72 #define PCMD 0x04
73 #define PSTTS 0x06
74 #define REVID 0x08
75 #define PROGIF 0x09
76 #define SUBCL 0x0a
77 #define BASCL 0x0b
78 #define BaseA0 0x10
79 #define BaseA1 0x14
80 #define BaseA2 0x18
81 #define BaseA3 0x1c
82 #define INTLINE 0x3c
83 #define INPINE 0x3d
84
85 #define CFR 0x50
86 #define CFR_DEVREV 0x03
87 #define CFR_IDE01INTR 0x04
88 #define CFR_DEVID 0x18
89 #define CFR_AT_VESA_078h 0x20
90 #define CFR_DSA1 0x40
91 #define CFR_DSA0 0x80
92
93 #define CNTRL 0x51
94 #define CNTRL_DIS_RA0 0x40
95 #define CNTRL_DIS_RA1 0x80
96 #define CNTRL_ENA_2ND 0x08
97
98 #define CMDTIM 0x52
99 #define ARTTIM0 0x53
100 #define DRWTIM0 0x54
101 #define ARTTIM1 0x55
102 #define DRWTIM1 0x56
103 #define ARTTIM23 0x57
104 #define DIS_RA2 0x04
105 #define DIS_RA3 0x08
106 #define DRWTIM23 0x58
107 #define BRST 0x59
108
109 static ide_tuneproc_t cmd640_tune_drive;
110
111
112 static void (*put_cmd640_reg)(int reg_no, int val);
113 byte (*get_cmd640_reg)(int reg_no);
114
115 enum { none, vlb, pci1, pci2 };
116 static int bus_type = none;
117 static int cmd640_chip_version;
118 static int cmd640_key;
119 static int bus_speed;
120
121
122
123
124
125
126
127
128 static void put_cmd640_reg_pci1(int reg_no, int val)
129 {
130 unsigned long flags;
131
132 save_flags(flags);
133 cli();
134 outl_p((reg_no & 0xfc) | cmd640_key, 0xcf8);
135 outb_p(val, (reg_no & 3) + 0xcfc);
136 restore_flags(flags);
137 }
138
139 static byte get_cmd640_reg_pci1(int reg_no)
140 {
141 byte b;
142 unsigned long flags;
143
144 save_flags(flags);
145 cli();
146 outl_p((reg_no & 0xfc) | cmd640_key, 0xcf8);
147 b = inb_p(0xcfc + (reg_no & 3));
148 restore_flags(flags);
149 return b;
150 }
151
152
153
154 static void put_cmd640_reg_pci2(int reg_no, int val)
155 {
156 unsigned long flags;
157
158 save_flags(flags);
159 cli();
160 outb_p(0x10, 0xcf8);
161 outb_p(val, cmd640_key + reg_no);
162 outb_p(0, 0xcf8);
163 restore_flags(flags);
164 }
165
166 static byte get_cmd640_reg_pci2(int reg_no)
167 {
168 byte b;
169 unsigned long flags;
170
171 save_flags(flags);
172 cli();
173 outb_p(0x10, 0xcf8);
174 b = inb_p(cmd640_key + reg_no);
175 outb_p(0, 0xcf8);
176 restore_flags(flags);
177 return b;
178 }
179
180
181
182 static void put_cmd640_reg_vlb(int reg_no, int val)
183 {
184 unsigned long flags;
185
186 save_flags(flags);
187 cli();
188 outb_p(reg_no, cmd640_key + 8);
189 outb_p(val, cmd640_key + 0xc);
190 restore_flags(flags);
191 }
192
193 static byte get_cmd640_reg_vlb(int reg_no)
194 {
195 byte b;
196 unsigned long flags;
197
198 save_flags(flags);
199 cli();
200 outb_p(reg_no, cmd640_key + 8);
201 b = inb_p(cmd640_key + 0xc);
202 restore_flags(flags);
203 return b;
204 }
205
206
207
208
209
210 static int probe_for_cmd640_pci1(void)
211 {
212 long id;
213 int k;
214
215 for (k = 0x80000000; k <= 0x8000f800; k += 0x800) {
216 outl(k, 0xcf8);
217 id = inl(0xcfc);
218 if (id != 0x06401095)
219 continue;
220 put_cmd640_reg = put_cmd640_reg_pci1;
221 get_cmd640_reg = get_cmd640_reg_pci1;
222 cmd640_key = k;
223 return 1;
224 }
225 return 0;
226 }
227
228
229
230
231
232 static int probe_for_cmd640_pci2(void)
233 {
234 int i;
235 int v_id;
236 int d_id;
237
238 for (i = 0xc000; i <= 0xcf00; i += 0x100) {
239 outb(0x10, 0xcf8);
240 v_id = inw(i);
241 d_id = inw(i + 2);
242 outb(0, 0xcf8);
243 if (v_id != 0x1095 || d_id != 0x640)
244 continue;
245 put_cmd640_reg = put_cmd640_reg_pci2;
246 get_cmd640_reg = get_cmd640_reg_pci2;
247 cmd640_key = i;
248 return 1;
249 }
250 return 0;
251 }
252
253
254
255
256
257 static int probe_for_cmd640_vlb(void) {
258 byte b;
259
260 outb(CFR, 0x178);
261 b = inb(0x17c);
262 if (b == 0xff || b == 0 || (b & CFR_AT_VESA_078h)) {
263 outb(CFR, 0x78);
264 b = inb(0x7c);
265 if (b == 0xff || b == 0 || !(b & CFR_AT_VESA_078h))
266 return 0;
267 cmd640_key = 0x70;
268 } else {
269 cmd640_key = 0x170;
270 }
271 put_cmd640_reg = put_cmd640_reg_vlb;
272 get_cmd640_reg = get_cmd640_reg_vlb;
273 return 1;
274 }
275
276 #if 0
277
278
279
280
281
282 static void cmd640_reset_controller(int iface_no)
283 {
284 int retry_count = 600;
285 int base_port = iface_no ? 0x170 : 0x1f0;
286
287 outb_p(4, base_port + 7);
288 udelay(5);
289 outb_p(0, base_port + 7);
290
291 do {
292 udelay(5);
293 retry_count -= 1;
294 } while ((inb_p(base_port + 7) & 0x80) && retry_count);
295
296 if (retry_count == 0)
297 printk("cmd640: failed to reset controller %d\n", iface_no);
298 }
299 #endif
300
301
302
303
304
305 int secondary_port_responding (void)
306 {
307
308
309
310
311 outb_p(0x0a,0x176);
312 udelay(1);
313 if (inb_p(0x176) == 0xff) {
314 outb_p(0x0b,0x176);
315 udelay(1);
316 if (inb_p(0x176) == 0xff)
317 return 0;
318 }
319 return 1;
320 }
321
322
323
324
325
326 int ide_probe_for_cmd640x(void)
327 {
328 int second_port_toggled = 0;
329 byte b;
330
331 if (probe_for_cmd640_pci1()) {
332 bus_type = pci1;
333 } else if (probe_for_cmd640_pci2()) {
334 bus_type = pci2;
335 } else if (cmd640_vlb && probe_for_cmd640_vlb()) {
336
337 bus_type = vlb;
338 } else {
339 return 0;
340 }
341
342 ide_hwifs[0].serialized = 1;
343 ide_hwifs[1].serialized = 1;
344
345 #if 0
346
347 for (b = 0; b != 0xff; b++) {
348 printk(" %2x%c", get_cmd640_reg(b),
349 ((b&0xf) == 0xf) ? '\n' : ',');
350 }
351 #endif
352
353
354
355
356
357 put_cmd640_reg(0x5b, 0xbd);
358 if (get_cmd640_reg(0x5b) != 0xbd) {
359 printk("ide: can't initialize cmd640 -- wrong value in 0x5b\n");
360 return 0;
361 }
362 put_cmd640_reg(0x5b, 0);
363
364
365
366
367
368 cmd640_chip_version = get_cmd640_reg(CFR) & CFR_DEVREV;
369 if (cmd640_chip_version == 0) {
370 printk ("ide: wrong CMD640 version -- 0\n");
371 return 0;
372 }
373
374
375
376
377 put_cmd640_reg(ARTTIM0, 0xc0);
378 put_cmd640_reg(ARTTIM1, 0xc0);
379 put_cmd640_reg(ARTTIM23, 0xcc);
380
381
382
383
384
385
386 bus_speed = (bus_type == vlb) ? 50 : 40;
387
388
389
390
391 b = get_cmd640_reg(CNTRL);
392
393 if (!secondary_port_responding()) {
394 b ^= CNTRL_ENA_2ND;
395 second_port_toggled = 1;
396 }
397
398
399
400
401 b |= (CNTRL_DIS_RA0 | CNTRL_DIS_RA1);
402
403 put_cmd640_reg(CNTRL, b);
404
405
406
407
408
409 ide_hwifs[0].chipset = ide_cmd640;
410 ide_hwifs[0].tuneproc = &cmd640_tune_drive;
411 if (ide_hwifs[0].drives[0].autotune == 0)
412 ide_hwifs[0].drives[0].autotune = 1;
413 if (ide_hwifs[0].drives[1].autotune == 0)
414 ide_hwifs[0].drives[1].autotune = 1;
415
416
417
418
419 if (secondary_port_responding()) {
420 ide_hwifs[1].chipset = ide_cmd640;
421 ide_hwifs[1].tuneproc = &cmd640_tune_drive;
422 if (ide_hwifs[1].drives[0].autotune == 0)
423 ide_hwifs[1].drives[0].autotune = 1;
424 if (ide_hwifs[1].drives[1].autotune == 0)
425 ide_hwifs[1].drives[1].autotune = 1;
426
427 put_cmd640_reg(ARTTIM23, (DIS_RA2 | DIS_RA3));
428
429 if (second_port_toggled) {
430
431 put_cmd640_reg(DRWTIM23, 0);
432 }
433 #if 0
434
435 cmd640_reset_controller(1);
436 #endif
437 }
438
439 printk("ide: buggy CMD640%c interface on ",
440 'A' - 1 + cmd640_chip_version);
441 switch (bus_type) {
442 case vlb :
443 printk("vlb (0x%x)", cmd640_key);
444 break;
445 case pci1:
446 printk("pci (0x%x)", cmd640_key);
447 break;
448 case pci2:
449 printk("pci (access method 2) (0x%x)", cmd640_key);
450 break;
451 }
452
453 #if 0
454
455 put_cmd640_reg(CMDTIM, 0);
456 #endif
457
458
459
460
461 printk("; serialized, secondary port %s\n", second_port_toggled ? "toggled" : "untouched");
462 return 1;
463 }
464
465 #if 0
466 int cmd640_off(void) {
467 static int a = 0;
468 byte b;
469
470 if (bus_type == none || a == 1)
471 return 0;
472 a = 1;
473 b = get_cmd640_reg(CNTRL);
474 b &= ~CNTRL_ENA_2ND;
475 put_cmd640_reg(CNTRL, b);
476 return 1;
477 }
478 #endif
479
480
481
482
483
484
485 static void set_readahead_mode(int mode, int if_num, int dr_num)
486 {
487 static int masks[2][2] =
488 {
489 {CNTRL_DIS_RA0, CNTRL_DIS_RA1},
490 {DIS_RA2, DIS_RA3}
491 };
492
493 int port = (if_num == 0) ? CNTRL : ARTTIM23;
494 int mask = masks[if_num][dr_num];
495 byte b;
496
497 b = get_cmd640_reg(port);
498 if (mode)
499 b &= ~mask;
500 else
501 b |= mask;
502 put_cmd640_reg(port, b);
503 }
504
505 static struct readahead_black_list {
506 const char* name;
507 int mode;
508 } drives_ra[] = {
509 { "QUANTUM LIGHTNING 540A", 0 },
510 { "ST3655A", 0 },
511 { "SAMSUNG", 0 },
512 { NULL, 0 }
513 };
514
515 static int strmatch(const char* pattern, const char* name) {
516 char c1, c2;
517
518 while (1) {
519 c1 = *pattern++;
520 c2 = *name++;
521 if (c1 == 0) {
522 return 0;
523 }
524 if (c1 != c2)
525 return 1;
526 }
527 }
528
529 static int known_drive_readahead(char* name) {
530 int i;
531
532 for (i = 0; drives_ra[i].name != NULL; i++) {
533 if (strmatch(drives_ra[i].name, name) == 0) {
534 return drives_ra[i].mode;
535 }
536 }
537 return -1;
538 }
539
540 static int arttim[4] = {2, 2, 2, 2};
541 static int a_count[4] = {1, 1, 1, 1};
542 static int r_count[4] = {1, 1, 1, 1};
543
544
545
546
547
548
549 inline static int pack_arttim(int clocks)
550 {
551 if (clocks <= 2) return 0x40;
552 else if (clocks == 3) return 0x80;
553 else if (clocks == 4) return 0x00;
554 else return 0xc0;
555 }
556
557
558
559
560
561
562 inline static int pack_counts(int act_count, int rec_count)
563 {
564 return ((act_count & 0x0f)<<4) | (rec_count & 0x0f);
565 }
566
567 inline int max(int a, int b) { return a > b ? a : b; }
568 inline int max4(int *p) { return max(p[0], max(p[1], max(p[2], p[3]))); }
569
570
571
572
573
574 static void cmd640_set_timing(int if_num, int dr_num)
575 {
576 int b_reg;
577 int ac, rc, at;
578
579
580
581
582
583
584
585
586 if (if_num == 0) {
587 b_reg = dr_num ? ARTTIM1 : ARTTIM0;
588 at = arttim[dr_num];
589 ac = a_count[dr_num];
590 rc = r_count[dr_num];
591 } else {
592 b_reg = ARTTIM23;
593 at = max(arttim[2], arttim[3]);
594 ac = max(a_count[2], a_count[3]);
595 rc = max(r_count[2], r_count[3]);
596 }
597
598 put_cmd640_reg(b_reg, pack_arttim(at));
599 put_cmd640_reg(b_reg + 1, pack_counts(ac, rc));
600
601
602
603
604
605 ac = max4(r_count);
606 rc = max4(a_count);
607 put_cmd640_reg(CMDTIM, pack_counts(ac, rc));
608 }
609
610
611
612
613
614 static struct pio_timing {
615 int mc_time;
616 int av_time;
617 int ds_time;
618 } pio_timings[6] = {
619 { 70, 165, 600 },
620 { 50, 125, 383 },
621 { 30, 100, 240 },
622 { 30, 80, 180 },
623 { 25, 70, 125 },
624 { 20, 50, 100 }
625 };
626
627 static void cmd640_timings_to_clocks(int mc_time, int av_time, int ds_time,
628 int clock_time, int drv_idx)
629 {
630 int a, b;
631
632 arttim[drv_idx] = (mc_time + clock_time - 1)/clock_time;
633
634 a = (av_time + clock_time - 1)/clock_time;
635 if (a < 2)
636 a = 2;
637 b = (ds_time + clock_time - 1)/clock_time - a;
638 if (b < 2)
639 b = 2;
640 if (b > 0x11) {
641 a += b - 0x11;
642 b = 0x11;
643 }
644 if (a > 0x10)
645 a = 0x10;
646 if (cmd640_chip_version > 1)
647 b -= 1;
648 if (b > 0x10)
649 b = 0x10;
650
651 a_count[drv_idx] = a;
652 r_count[drv_idx] = b;
653 }
654
655 static void set_pio_mode(int if_num, int drv_num, int mode_num) {
656 int p_base;
657 int i;
658
659 p_base = if_num ? 0x170 : 0x1f0;
660 outb_p(3, p_base + 1);
661 outb_p(mode_num | 8, p_base + 2);
662 outb_p((drv_num | 0xa) << 4, p_base + 6);
663 outb_p(0xef, p_base + 7);
664 for (i = 0; (i < 100) && (inb (p_base + 7) & 0x80); i++)
665 udelay(10000);
666 }
667
668
669
670
671
672 static void cmd640_set_mode(ide_drive_t* drive, int pio_mode) {
673 int interface_number;
674 int drive_number;
675 int clock_time;
676 int mc_time, av_time, ds_time;
677
678 interface_number = HWIF(drive)->index;
679 drive_number = drive->select.b.unit;
680 clock_time = 1000/bus_speed;
681
682 mc_time = pio_timings[pio_mode].mc_time;
683 av_time = pio_timings[pio_mode].av_time;
684 ds_time = pio_timings[pio_mode].ds_time;
685
686 cmd640_timings_to_clocks(mc_time, av_time, ds_time, clock_time,
687 interface_number*2 + drive_number);
688 set_pio_mode(interface_number, drive_number, pio_mode);
689 cmd640_set_timing(interface_number, drive_number);
690 }
691
692
693
694
695
696
697 static void cmd640_tune_drive(ide_drive_t *drive, byte pio_mode) {
698 int interface_number;
699 int drive_number;
700 int clock_time;
701 int max_pio;
702 int mc_time, av_time, ds_time;
703 struct hd_driveid* id;
704 int readahead;
705
706 if (pio_mode != 255) {
707 cmd640_set_mode(drive, pio_mode);
708 return;
709 }
710
711 interface_number = HWIF(drive)->index;
712 drive_number = drive->select.b.unit;
713 clock_time = 1000/bus_speed;
714 id = drive->id;
715 if ((max_pio = ide_scan_pio_blacklist(id->model)) != -1) {
716 ds_time = pio_timings[max_pio].ds_time;
717 } else {
718 max_pio = id->tPIO;
719 ds_time = pio_timings[max_pio].ds_time;
720 if (id->field_valid & 2) {
721 if ((id->capability & 8) && (id->eide_pio_modes & 7)) {
722 if (id->eide_pio_modes & 4) max_pio = 5;
723 else if (id->eide_pio_modes & 2) max_pio = 4;
724 else max_pio = 3;
725 ds_time = id->eide_pio_iordy;
726 } else {
727 ds_time = id->eide_pio;
728 }
729 if (ds_time == 0)
730 ds_time = pio_timings[max_pio].ds_time;
731 }
732
733
734
735
736 if (max_pio < 4 && max_pio != 0) {
737 max_pio -= 1;
738 ds_time = pio_timings[max_pio].ds_time;
739 }
740 }
741 mc_time = pio_timings[max_pio].mc_time;
742 av_time = pio_timings[max_pio].av_time;
743 cmd640_timings_to_clocks(mc_time, av_time, ds_time, clock_time,
744 interface_number*2 + drive_number);
745 set_pio_mode(interface_number, drive_number, max_pio);
746 cmd640_set_timing(interface_number, drive_number);
747
748
749
750
751
752 readahead = 0;
753 if (cmd640_chip_version > 1) {
754 readahead = known_drive_readahead(id->model);
755 if (readahead == -1)
756 readahead = 1;
757 set_readahead_mode(readahead, interface_number, drive_number);
758 }
759
760 printk ("Mode and Timing set to PIO%d, Readahead is %s\n",
761 max_pio, readahead ? "enabled" : "disabled");
762 }
763