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