|
|
1.1 root 1: /*
2: * linux/drivers/block/cmd640.c Version 0.07 Jan 27, 1996
3: *
4: * Copyright (C) 1995-1996 Linus Torvalds & author (see below)
5: */
6:
7: /*
8: * Principal Author/Maintainer: [email protected] (Igor Abramov)
9: *
10: * This file provides support for the advanced features and bugs
11: * of IDE interfaces using the CMD Technologies 0640 IDE interface chip.
12: *
13: * Version 0.01 Initial version, hacked out of ide.c,
14: * and #include'd rather than compiled separately.
15: * This will get cleaned up in a subsequent release.
16: *
17: * Version 0.02 Fixes for vlb initialization code, enable
18: * read-ahead for versions 'B' and 'C' of chip by
19: * default, some code cleanup.
20: *
21: * Version 0.03 Added reset of secondary interface,
22: * and black list for devices which are not compatible
23: * with read ahead mode. Separate function for setting
24: * readahead is added, possibly it will be called some
25: * day from ioctl processing code.
26: *
27: * Version 0.04 Now configs/compiles separate from ide.c -ml
28: *
29: * Version 0.05 Major rewrite of interface timing code.
30: * Added new function cmd640_set_mode to set PIO mode
31: * from ioctl call. New drives added to black list.
32: *
33: * Version 0.06 More code cleanup. Readahead is enabled only for
34: * detected hard drives, not included in readahed
35: * black list.
36: *
37: * Version 0.07 Changed to more conservative drive tuning policy.
38: * Unknown drives, which report PIO < 4 are set to
39: * (reported_PIO - 1) if it is supported, or to PIO0.
40: * List of known drives extended by info provided by
41: * CMD at their ftp site.
42: *
43: * Version 0.08 Added autotune/noautotune support. -ml
44: *
45: */
46:
47: #undef REALLY_SLOW_IO /* most systems can safely undef this */
48:
49: #include <linux/types.h>
50: #include <linux/kernel.h>
51: #include <linux/delay.h>
52: #include <linux/timer.h>
53: #include <linux/mm.h>
54: #include <linux/ioport.h>
55: #include <linux/blkdev.h>
56: #include <linux/hdreg.h>
57: #include <asm/io.h>
58: #include "ide.h"
59: #include "ide_modes.h"
60:
61: int cmd640_vlb = 0;
62:
63: /*
64: * CMD640 specific registers definition.
65: */
66:
67: #define VID 0x00
68: #define DID 0x02
69: #define PCMD 0x04
70: #define PSTTS 0x06
71: #define REVID 0x08
72: #define PROGIF 0x09
73: #define SUBCL 0x0a
74: #define BASCL 0x0b
75: #define BaseA0 0x10
76: #define BaseA1 0x14
77: #define BaseA2 0x18
78: #define BaseA3 0x1c
79: #define INTLINE 0x3c
80: #define INPINE 0x3d
81:
82: #define CFR 0x50
83: #define CFR_DEVREV 0x03
84: #define CFR_IDE01INTR 0x04
85: #define CFR_DEVID 0x18
86: #define CFR_AT_VESA_078h 0x20
87: #define CFR_DSA1 0x40
88: #define CFR_DSA0 0x80
89:
90: #define CNTRL 0x51
91: #define CNTRL_DIS_RA0 0x40
92: #define CNTRL_DIS_RA1 0x80
93: #define CNTRL_ENA_2ND 0x08
94:
95: #define CMDTIM 0x52
96: #define ARTTIM0 0x53
97: #define DRWTIM0 0x54
98: #define ARTTIM1 0x55
99: #define DRWTIM1 0x56
100: #define ARTTIM23 0x57
101: #define DIS_RA2 0x04
102: #define DIS_RA3 0x08
103: #define DRWTIM23 0x58
104: #define BRST 0x59
105:
106: static ide_tuneproc_t cmd640_tune_drive;
107:
108: /* Interface to access cmd640x registers */
109: static void (*put_cmd640_reg)(int reg_no, int val);
110: static byte (*get_cmd640_reg)(int reg_no);
111:
112: enum { none, vlb, pci1, pci2 };
113: static int bus_type = none;
114: static int cmd640_chip_version;
115: static int cmd640_key;
116: static int bus_speed; /* MHz */
117:
118: /*
119: * For some unknown reasons pcibios functions which read and write registers
120: * do not always work with cmd640. We use direct IO instead.
121: */
122:
123: /* PCI method 1 access */
124:
125: static void put_cmd640_reg_pci1(int reg_no, int val)
126: {
127: unsigned long flags;
128:
129: save_flags(flags);
130: cli();
131: outl_p((reg_no & 0xfc) | cmd640_key, 0xcf8);
132: outb_p(val, (reg_no & 3) + 0xcfc);
133: restore_flags(flags);
134: }
135:
136: static byte get_cmd640_reg_pci1(int reg_no)
137: {
138: byte b;
139: unsigned long flags;
140:
141: save_flags(flags);
142: cli();
143: outl_p((reg_no & 0xfc) | cmd640_key, 0xcf8);
144: b = inb_p(0xcfc + (reg_no & 3));
145: restore_flags(flags);
146: return b;
147: }
148:
149: /* PCI method 2 access (from CMD datasheet) */
150:
151: static void put_cmd640_reg_pci2(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, cmd640_key + reg_no);
159: outb_p(0, 0xcf8);
160: restore_flags(flags);
161: }
162:
163: static byte get_cmd640_reg_pci2(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(cmd640_key + reg_no);
172: outb_p(0, 0xcf8);
173: restore_flags(flags);
174: return b;
175: }
176:
177: /* VLB access */
178:
179: static void put_cmd640_reg_vlb(int reg_no, int val)
180: {
181: unsigned long flags;
182:
183: save_flags(flags);
184: cli();
185: outb_p(reg_no, cmd640_key + 8);
186: outb_p(val, cmd640_key + 0xc);
187: restore_flags(flags);
188: }
189:
190: static byte get_cmd640_reg_vlb(int reg_no)
191: {
192: byte b;
193: unsigned long flags;
194:
195: save_flags(flags);
196: cli();
197: outb_p(reg_no, cmd640_key + 8);
198: b = inb_p(cmd640_key + 0xc);
199: restore_flags(flags);
200: return b;
201: }
202:
203: /*
204: * Probe for CMD640x -- pci method 1
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: * Probe for CMD640x -- pci method 2
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: * Probe for CMD640x -- vlb
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: * Low level reset for controller, actually it has nothing specific for
275: * CMD640, but I don't know how to use standard reset routine before
276: * we recognized any drives.
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: * Probe for Cmd640x and initialize it if found
304: */
305:
306: int ide_probe_for_cmd640x(void)
307: {
308: int second_port;
309: byte b;
310:
311: if (probe_for_cmd640_pci1()) {
312: bus_type = pci1;
313: } else if (probe_for_cmd640_pci2()) {
314: bus_type = pci2;
315: } else if (cmd640_vlb && probe_for_cmd640_vlb()) {
316: /* May be remove cmd640_vlb at all, and probe in any case */
317: bus_type = vlb;
318: } else {
319: return 0;
320: }
321:
322: ide_hwifs[0].serialized = 1; /* ensure this *always* gets set */
323:
324: #if 0
325: /* Dump initial state of chip registers */
326: for (b = 0; b != 0xff; b++) {
327: printk(" %2x%c", get_cmd640_reg(b),
328: ((b&0xf) == 0xf) ? '\n' : ',');
329: }
330:
331: #endif
332:
333: /*
334: * Undocumented magic. (There is no 0x5b port in specs)
335: */
336:
337: put_cmd640_reg(0x5b, 0xbd);
338: if (get_cmd640_reg(0x5b) != 0xbd) {
339: printk("ide: can't initialize cmd640 -- wrong value in 0x5b\n");
340: return 0;
341: }
342: put_cmd640_reg(0x5b, 0);
343:
344: /*
345: * Documented magic.
346: */
347:
348: cmd640_chip_version = get_cmd640_reg(CFR) & CFR_DEVREV;
349: if (cmd640_chip_version == 0) {
350: printk ("ide: wrong CMD640 version -- 0\n");
351: return 0;
352: }
353:
354: /*
355: * Setup the most conservative timings for all drives,
356: */
357: put_cmd640_reg(ARTTIM0, 0xc0);
358: put_cmd640_reg(ARTTIM1, 0xc0);
359: put_cmd640_reg(ARTTIM23, 0xcc); /* 0xc0? */
360:
361: /*
362: * Do not initialize secondary controller for vlbus
363: */
364: second_port = (bus_type != vlb);
365:
366: /*
367: * Set the maximum allowed bus speed (it is safest until we
368: * find how to detect bus speed)
369: * Normally PCI bus runs at 33MHz, but often works overclocked to 40
370: */
371: bus_speed = (bus_type == vlb) ? 50 : 40;
372:
373: /*
374: * Setup Control Register
375: */
376: b = get_cmd640_reg(CNTRL);
377:
378: if (second_port)
379: b |= CNTRL_ENA_2ND;
380: else
381: b &= ~CNTRL_ENA_2ND;
382:
383: /*
384: * Disable readahead for drives at primary interface
385: */
386: b |= (CNTRL_DIS_RA0 | CNTRL_DIS_RA1);
387:
388: put_cmd640_reg(CNTRL, b);
389:
390: /*
391: * Note that we assume that the first interface is at 0x1f0,
392: * and that the second interface, if enabled, is at 0x170.
393: */
394: ide_hwifs[0].chipset = ide_cmd640;
395: ide_hwifs[0].tuneproc = &cmd640_tune_drive;
396: if (ide_hwifs[0].drives[0].autotune == 0)
397: ide_hwifs[0].drives[0].autotune = 1;
398: if (ide_hwifs[0].drives[1].autotune == 0)
399: ide_hwifs[0].drives[1].autotune = 1;
400:
401: /*
402: * Initialize 2nd IDE port, if required
403: */
404: if (second_port) {
405: ide_hwifs[1].chipset = ide_cmd640;
406: ide_hwifs[1].tuneproc = &cmd640_tune_drive;
407: if (ide_hwifs[1].drives[0].autotune == 0)
408: ide_hwifs[1].drives[0].autotune = 1;
409: if (ide_hwifs[1].drives[1].autotune == 0)
410: ide_hwifs[1].drives[1].autotune = 1;
411: /* We reset timings, and disable read-ahead */
412: put_cmd640_reg(ARTTIM23, (DIS_RA2 | DIS_RA3));
413: put_cmd640_reg(DRWTIM23, 0);
414:
415: cmd640_reset_controller(1);
416: }
417:
418: printk("ide: buggy CMD640%c interface at ",
419: 'A' - 1 + cmd640_chip_version);
420: switch (bus_type) {
421: case vlb :
422: printk("local bus, port 0x%x", cmd640_key);
423: break;
424: case pci1:
425: printk("pci, (0x%x)", cmd640_key);
426: break;
427: case pci2:
428: printk("pci,(access method 2) (0x%x)", cmd640_key);
429: break;
430: }
431:
432: /*
433: * Reset interface timings
434: */
435: put_cmd640_reg(CMDTIM, 0);
436:
437: printk("\n ... serialized, secondary interface %s\n",
438: second_port ? "enabled" : "disabled");
439:
440: return 1;
441: }
442:
443: int cmd640_off(void) {
444: static int a = 0;
445: byte b;
446:
447: if (bus_type == none || a == 1)
448: return 0;
449: a = 1;
450: b = get_cmd640_reg(CNTRL);
451: b &= ~CNTRL_ENA_2ND;
452: put_cmd640_reg(CNTRL, b);
453: return 1;
454: }
455:
456: /*
457: * Sets readahead mode for specific drive
458: * in the future it could be called from ioctl
459: */
460:
461: static void set_readahead_mode(int mode, int if_num, int dr_num)
462: {
463: static int masks[2][2] =
464: {
465: {CNTRL_DIS_RA0, CNTRL_DIS_RA1},
466: {DIS_RA2, DIS_RA3}
467: };
468:
469: int port = (if_num == 0) ? CNTRL : ARTTIM23;
470: int mask = masks[if_num][dr_num];
471: byte b;
472:
473: b = get_cmd640_reg(port);
474: if (mode)
475: b &= ~mask; /* Enable readahead for specific drive */
476: else
477: b |= mask; /* Disable readahed for specific drive */
478: put_cmd640_reg(port, b);
479: }
480:
481: static struct readahead_black_list {
482: const char* name;
483: int mode;
484: } drives_ra[] = {
485: { "ST3655A", 0 },
486: { "SAMSUNG", 0 }, /* Be conservative */
487: { NULL, 0 }
488: };
489:
490: static int strmatch(const char* pattern, const char* name) {
491: char c1, c2;
492:
493: while (1) {
494: c1 = *pattern++;
495: c2 = *name++;
496: if (c1 == 0) {
497: return 0;
498: }
499: if (c1 != c2)
500: return 1;
501: }
502: }
503:
504: static int known_drive_readahead(char* name) {
505: int i;
506:
507: for (i = 0; drives_ra[i].name != NULL; i++) {
508: if (strmatch(drives_ra[i].name, name) == 0) {
509: return drives_ra[i].mode;
510: }
511: }
512: return -1;
513: }
514:
515: static int arttim[4] = {2, 2, 2, 2}; /* Address setup count (in clocks) */
516: static int a_count[4] = {1, 1, 1, 1}; /* Active count (encoded) */
517: static int r_count[4] = {1, 1, 1, 1}; /* Recovery count (encoded) */
518:
519: /*
520: * Convert address setup count from number of clocks
521: * to representation used by controller
522: */
523:
524: inline static int pack_arttim(int clocks)
525: {
526: if (clocks <= 2) return 0x40;
527: else if (clocks == 3) return 0x80;
528: else if (clocks == 4) return 0x00;
529: else return 0xc0;
530: }
531:
532: /*
533: * Pack active and recovery counts into single byte representation
534: * used by controller
535: */
536:
537: inline static int pack_counts(int act_count, int rec_count)
538: {
539: return ((act_count & 0x0f)<<4) | (rec_count & 0x0f);
540: }
541:
542: inline int max(int a, int b) { return a > b ? a : b; }
543: inline int max4(int *p) { return max(p[0], max(p[1], max(p[2], p[3]))); }
544:
545: /*
546: * Set timing parameters
547: */
548:
549: static void cmd640_set_timing(int if_num, int dr_num)
550: {
551: int b_reg;
552: int ac, rc, at;
553:
554: /*
555: * Set address setup count and drive read/write timing registers.
556: * Primary interface has individual count/timing registers for
557: * each drive. Secondary interface has common set of registers, and
558: * we should set timings for the slowest drive.
559: */
560:
561: if (if_num == 0) {
562: b_reg = dr_num ? ARTTIM1 : ARTTIM0;
563: at = arttim[dr_num];
564: ac = a_count[dr_num];
565: rc = r_count[dr_num];
566: } else {
567: b_reg = ARTTIM23;
568: at = max(arttim[2], arttim[3]);
569: ac = max(a_count[2], a_count[3]);
570: rc = max(r_count[2], r_count[3]);
571: }
572:
573: put_cmd640_reg(b_reg, pack_arttim(at));
574: put_cmd640_reg(b_reg + 1, pack_counts(ac, rc));
575:
576: /*
577: * Update CMDTIM (IDE Command Block Timing Register)
578: */
579:
580: ac = max4(r_count);
581: rc = max4(a_count);
582: put_cmd640_reg(CMDTIM, pack_counts(ac, rc));
583: }
584:
585: /*
586: * Standard timings for PIO modes
587: */
588:
589: static struct pio_timing {
590: int mc_time; /* Minimal cycle time (ns) */
591: int av_time; /* Address valid to DIOR-/DIOW- setup (ns) */
592: int ds_time; /* DIOR data setup (ns) */
593: } pio_timings[6] = {
594: { 70, 165, 600 }, /* PIO Mode 0 */
595: { 50, 125, 383 }, /* PIO Mode 1 */
596: { 30, 100, 240 }, /* PIO Mode 2 */
597: { 30, 80, 180 }, /* PIO Mode 3 */
598: { 25, 70, 125 }, /* PIO Mode 4 -- should be 120, not 125 */
599: { 20, 50, 100 } /* PIO Mode ? (nonstandard) */
600: };
601:
602: static void cmd640_timings_to_clocks(int mc_time, int av_time, int ds_time,
603: int clock_time, int drv_idx)
604: {
605: int a, b;
606:
607: arttim[drv_idx] = (mc_time + clock_time - 1)/clock_time;
608:
609: a = (av_time + clock_time - 1)/clock_time;
610: if (a < 2)
611: a = 2;
612: b = (ds_time + clock_time - 1)/clock_time - a;
613: if (b < 2)
614: b = 2;
615: if (b > 0x11) {
616: a += b - 0x11;
617: b = 0x11;
618: }
619: if (a > 0x10)
620: a = 0x10;
621: if (cmd640_chip_version > 1)
622: b -= 1;
623: if (b > 0x10)
624: b = 0x10;
625:
626: a_count[drv_idx] = a;
627: r_count[drv_idx] = b;
628: }
629:
630: static void set_pio_mode(int if_num, int drv_num, int mode_num) {
631: int p_base;
632: int i;
633:
634: p_base = if_num ? 0x170 : 0x1f0;
635: outb_p(3, p_base + 1);
636: outb_p(mode_num | 8, p_base + 2);
637: outb_p((drv_num | 0xa) << 4, p_base + 6);
638: outb_p(0xef, p_base + 7);
639: for (i = 0; (i < 100) && (inb (p_base + 7) & 0x80); i++)
640: udelay(10000);
641: }
642:
643: /*
644: * Set a specific pio_mode for a drive
645: */
646:
647: static void cmd640_set_mode(ide_drive_t* drive, int pio_mode) {
648: int interface_number;
649: int drive_number;
650: int clock_time; /* ns */
651: int mc_time, av_time, ds_time;
652:
653: interface_number = HWIF(drive)->index;
654: drive_number = drive->select.b.unit;
655: clock_time = 1000/bus_speed;
656:
657: mc_time = pio_timings[pio_mode].mc_time;
658: av_time = pio_timings[pio_mode].av_time;
659: ds_time = pio_timings[pio_mode].ds_time;
660:
661: cmd640_timings_to_clocks(mc_time, av_time, ds_time, clock_time,
662: interface_number*2 + drive_number);
663: set_pio_mode(interface_number, drive_number, pio_mode);
664: cmd640_set_timing(interface_number, drive_number);
665: }
666:
667: /*
668: * Drive PIO mode "autoconfiguration".
669: * Ideally, this code should *always* call cmd640_set_mode(), but it doesn't.
670: */
671:
672: static void cmd640_tune_drive(ide_drive_t *drive, byte pio_mode) {
673: int interface_number;
674: int drive_number;
675: int clock_time; /* ns */
676: int max_pio;
677: int mc_time, av_time, ds_time;
678: struct hd_driveid* id;
679: int readahead; /* there is a global named read_ahead */
680:
681: if (pio_mode != 255) {
682: cmd640_set_mode(drive, pio_mode);
683: return;
684: }
685:
686: interface_number = HWIF(drive)->index;
687: drive_number = drive->select.b.unit;
688: clock_time = 1000/bus_speed;
689: id = drive->id;
690: if ((max_pio = ide_scan_pio_blacklist(id->model)) != -1) {
691: ds_time = pio_timings[max_pio].ds_time;
692: } else {
693: max_pio = id->tPIO;
694: ds_time = pio_timings[max_pio].ds_time;
695: if (id->field_valid & 2) {
696: if ((id->capability & 8) && (id->eide_pio_modes & 7)) {
697: if (id->eide_pio_modes & 4) max_pio = 5;
698: else if (id->eide_pio_modes & 2) max_pio = 4;
699: else max_pio = 3;
700: ds_time = id->eide_pio_iordy;
701: } else {
702: ds_time = id->eide_pio;
703: }
704: if (ds_time == 0)
705: ds_time = pio_timings[max_pio].ds_time;
706: }
707:
708: /*
709: * Conservative "downgrade"
710: */
711: if (max_pio < 4 && max_pio != 0) {
712: max_pio -= 1;
713: ds_time = pio_timings[max_pio].ds_time;
714: }
715: }
716: mc_time = pio_timings[max_pio].mc_time;
717: av_time = pio_timings[max_pio].av_time;
718: cmd640_timings_to_clocks(mc_time, av_time, ds_time, clock_time,
719: interface_number*2 + drive_number);
720: set_pio_mode(interface_number, drive_number, max_pio);
721: cmd640_set_timing(interface_number, drive_number);
722:
723: /*
724: * Disable (or set) readahead mode
725: */
726:
727: readahead = 0;
728: if (cmd640_chip_version > 1) { /* Mmmm.. probably should be > 2 ?? */
729: readahead = known_drive_readahead(id->model);
730: if (readahead == -1)
731: readahead = 1; /* Mmmm.. probably be 0 ?? */
732: set_readahead_mode(readahead, interface_number, drive_number);
733: }
734:
735: printk ("Mode and Timing set to PIO%d, Readahead is %s\n",
736: max_pio, readahead ? "enabled" : "disabled");
737: }
738:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.