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