99 #define CMD640_PREFETCH_MASKS 1
103 #include <linux/types.h>
104 #include <linux/kernel.h>
108 #include <linux/module.h>
112 #define DRV_NAME "cmd640"
114 static bool cmd640_vlb;
123 #define PCMD_ENA 0x01
137 #define CFR_DEVREV 0x03
138 #define CFR_IDE01INTR 0x04
139 #define CFR_DEVID 0x18
140 #define CFR_AT_VESA_078h 0x20
141 #define CFR_DSA1 0x40
142 #define CFR_DSA0 0x80
145 #define CNTRL_DIS_RA0 0x40
146 #define CNTRL_DIS_RA1 0x80
147 #define CNTRL_ENA_2ND 0x08
154 #define ARTTIM23 0x57
155 #define ARTTIM23_DIS_RA2 0x04
156 #define ARTTIM23_DIS_RA3 0x08
157 #define ARTTIM23_IDE23INTR 0x10
158 #define DRWTIM23 0x58
167 #ifdef CONFIG_BLK_DEV_CMD640_ENHANCED
176 static u8 setup_counts[4] = {4, 4, 4, 4};
177 static u8 active_counts[4] = {16, 16, 16, 16};
178 static u8 recovery_counts[4] = {16, 16, 16, 16};
187 static unsigned int cmd640_key;
189 static u8 (*__get_cmd640_reg)(
u16 reg);
194 static unsigned int cmd640_chip_version;
206 outl_p((reg & 0xfc) | cmd640_key, 0xcf8);
207 outb_p(val, (reg & 3) | 0xcfc);
210 static u8 get_cmd640_reg_pci1(
u16 reg)
212 outl_p((reg & 0xfc) | cmd640_key, 0xcf8);
213 return inb_p((reg & 3) | 0xcfc);
218 static void put_cmd640_reg_pci2(
u16 reg,
u8 val)
221 outb_p(val, cmd640_key + reg);
225 static u8 get_cmd640_reg_pci2(
u16 reg)
230 b =
inb_p(cmd640_key + reg);
237 static void put_cmd640_reg_vlb(
u16 reg,
u8 val)
240 outb_p(val, cmd640_key + 4);
243 static u8 get_cmd640_reg_vlb(
u16 reg)
246 return inb_p(cmd640_key + 4);
249 static u8 get_cmd640_reg(
u16 reg)
255 b = __get_cmd640_reg(reg);
256 spin_unlock_irqrestore(&cmd640_lock, flags);
260 static void put_cmd640_reg(
u16 reg,
u8 val)
265 __put_cmd640_reg(reg, val);
266 spin_unlock_irqrestore(&cmd640_lock, flags);
269 static int __init match_pci_cmd640_device(
void)
271 const u8 ven_dev[4] = {0x95, 0x10, 0x40, 0x06};
273 for (i = 0; i < 4; i++) {
274 if (get_cmd640_reg(i) != ven_dev[i])
277 #ifdef STUPIDLY_TRUST_BROKEN_PCMD_ENA_BIT
279 printk(
"ide: cmd640 on PCI disabled by BIOS\n");
289 static int __init probe_for_cmd640_pci1(
void)
291 __get_cmd640_reg = get_cmd640_reg_pci1;
292 __put_cmd640_reg = put_cmd640_reg_pci1;
293 for (cmd640_key = 0x80000000;
294 cmd640_key <= 0x8000f800;
295 cmd640_key += 0x800) {
296 if (match_pci_cmd640_device())
305 static int __init probe_for_cmd640_pci2(
void)
307 __get_cmd640_reg = get_cmd640_reg_pci2;
308 __put_cmd640_reg = put_cmd640_reg_pci2;
309 for (cmd640_key = 0xc000; cmd640_key <= 0xcf00; cmd640_key += 0x100) {
310 if (match_pci_cmd640_device())
319 static int __init probe_for_cmd640_vlb(
void)
323 __get_cmd640_reg = get_cmd640_reg_vlb;
324 __put_cmd640_reg = put_cmd640_reg_vlb;
326 b = get_cmd640_reg(
CFR);
329 b = get_cmd640_reg(
CFR);
330 if (b == 0xff || b == 0x00 || !(b & CFR_AT_VESA_078h))
340 static int __init secondary_port_responding(
void)
348 if ((
inb_p(0x176) & 0x1f) != 0x0a) {
351 if ((
inb_p(0x176) & 0x1f) != 0x1a) {
352 spin_unlock_irqrestore(&cmd640_lock, flags);
356 spin_unlock_irqrestore(&cmd640_lock, flags);
360 #ifdef CMD640_DUMP_REGS
364 static void cmd640_dump_regs(
void)
366 unsigned int reg = cmd640_vlb ? 0x50 : 0x00;
369 printk(
"ide: cmd640 internal register dump:");
370 for (; reg <= 0x59; reg++) {
373 printk(
" %02x", get_cmd640_reg(reg));
382 #if CMD640_PREFETCH_MASKS
394 #ifndef CONFIG_BLK_DEV_CMD640_ENHANCED
401 u8 b = get_cmd640_reg(prefetch_regs[index]);
403 __set_prefetch_mode(drive, (b & prefetch_masks[index]) ? 0 : 1);
410 static void set_prefetch_mode(
ide_drive_t *drive,
unsigned int index,
int mode)
413 int reg = prefetch_regs[
index];
417 b = __get_cmd640_reg(reg);
418 __set_prefetch_mode(drive, mode);
420 b &= ~prefetch_masks[
index];
422 b |= prefetch_masks[
index];
423 __put_cmd640_reg(reg, b);
424 spin_unlock_irqrestore(&cmd640_lock, flags);
430 static void display_clocks(
unsigned int index)
432 u8 active_count, recovery_count;
434 active_count = active_counts[
index];
435 if (active_count == 1)
437 recovery_count = recovery_counts[
index];
438 if (active_count > 3 && recovery_count == 1)
440 if (cmd640_chip_version > 1)
442 printk(
", clocks=%d/%d/%d\n", setup_counts[index], active_count, recovery_count);
449 static inline u8 pack_nibbles(
u8 upper,
u8 lower)
451 return ((upper & 0x0f) << 4) | (lower & 0x0f);
458 static void program_drive_counts(
ide_drive_t *drive,
unsigned int index)
461 u8 setup_count = setup_counts[
index];
462 u8 active_count = active_counts[
index];
463 u8 recovery_count = recovery_counts[
index];
473 unsigned int mate = index ^ 1;
476 if (setup_count < setup_counts[mate])
477 setup_count = setup_counts[mate];
478 if (active_count < active_counts[mate])
479 active_count = active_counts[mate];
480 if (recovery_count < recovery_counts[mate])
481 recovery_count = recovery_counts[mate];
488 switch (setup_count) {
489 case 4: setup_count = 0x00;
break;
490 case 3: setup_count = 0x80;
break;
492 case 2: setup_count = 0x40;
break;
493 default: setup_count = 0xc0;
505 setup_count |= __get_cmd640_reg(arttim_regs[index]) & 0x3f;
506 __put_cmd640_reg(arttim_regs[index], setup_count);
507 __put_cmd640_reg(drwtim_regs[index], pack_nibbles(active_count, recovery_count));
508 spin_unlock_irqrestore(&cmd640_lock, flags);
514 static void cmd640_set_mode(
ide_drive_t *drive,
unsigned int index,
515 u8 pio_mode,
unsigned int cycle_time)
518 int setup_time, active_time, recovery_time, clock_time;
519 u8 setup_count, active_count, recovery_count, recovery_count2, cycle_count;
531 setup_time = t->
setup;
534 recovery_time = cycle_time - (setup_time + active_time);
535 clock_time = 1000 / bus_speed;
541 if (active_count < 2)
544 recovery_count =
DIV_ROUND_UP(recovery_time, clock_time);
545 recovery_count2 = cycle_count - (setup_count + active_count);
546 if (recovery_count2 > recovery_count)
547 recovery_count = recovery_count2;
548 if (recovery_count < 2)
550 if (recovery_count > 17) {
551 active_count += recovery_count - 17;
554 if (active_count > 16)
556 if (cmd640_chip_version > 1)
558 if (recovery_count > 16)
561 setup_counts[
index] = setup_count;
562 active_counts[
index] = active_count;
563 recovery_counts[
index] = recovery_count;
573 program_drive_counts(drive, index);
578 unsigned int index = 0, cycle_time;
585 b = get_cmd640_reg(
CNTRL) & ~0x27;
588 put_cmd640_reg(
CNTRL, b);
589 printk(
"%s: %sabled cmd640 fast host timing (devsel)\n",
590 drive->
name, (pio & 1) ?
"en" :
"dis");
594 set_prefetch_mode(drive, index, pio & 1);
595 printk(
"%s: %sabled cmd640 prefetch\n",
596 drive->
name, (pio & 1) ?
"en" :
"dis");
601 cmd640_set_mode(drive, index, pio, cycle_time);
603 printk(
"%s: selected cmd640 PIO mode%d (%dns)",
604 drive->
name, pio, cycle_time);
606 display_clocks(index);
612 unsigned int i = drive->
hwif->channel * 2 + (drive->
dn & 1);
614 #ifdef CONFIG_BLK_DEV_CMD640_ENHANCED
620 active_counts[
i] = 16;
621 recovery_counts[
i] = 16;
622 program_drive_counts(drive, i);
623 set_prefetch_mode(drive, i, 0);
629 check_prefetch(drive, i);
642 return (irq_stat & irq_mask) ? 1 : 0;
646 .init_dev = cmd640_init_dev,
647 #ifdef CONFIG_BLK_DEV_CMD640_ENHANCED
648 .set_pio_mode = cmd640_set_pio_mode,
650 .test_irq = cmd640_test_irq,
653 static int pci_conf1(
void)
661 outl(0x80000000, 0xCF8);
662 if (
inl(0xCF8) == 0x80000000) {
664 spin_unlock_irqrestore(&cmd640_lock, flags);
668 spin_unlock_irqrestore(&cmd640_lock, flags);
672 static int pci_conf2(
void)
680 if (
inb(0xCF8) == 0x00 &&
inb(0xCF8) == 0x00) {
681 spin_unlock_irqrestore(&cmd640_lock, flags);
684 spin_unlock_irqrestore(&cmd640_lock, flags);
694 .port_ops = &cmd640_port_ops,
698 static int cmd640x_init_one(
unsigned long base,
unsigned long ctl)
719 static int __init cmd640x_init(
void)
721 int second_port_cmd640 = 0,
rc;
726 if (cmd640_vlb && probe_for_cmd640_vlb()) {
732 if (pci_conf1() && probe_for_cmd640_pci1())
733 bus_type =
"PCI (type1)";
734 else if (pci_conf2() && probe_for_cmd640_pci2())
735 bus_type =
"PCI (type2)";
742 put_cmd640_reg(0x5b, 0xbd);
743 if (get_cmd640_reg(0x5b) != 0xbd) {
744 printk(
KERN_ERR "ide: cmd640 init failed: wrong value in reg 0x5b\n");
747 put_cmd640_reg(0x5b, 0);
749 #ifdef CMD640_DUMP_REGS
756 cfr = get_cmd640_reg(
CFR);
758 if (cmd640_chip_version == 0) {
759 printk(
"ide: bad cmd640 revision: %d\n", cmd640_chip_version);
763 rc = cmd640x_init_one(0x1f0, 0x3f6);
767 rc = cmd640x_init_one(0x170, 0x376);
776 ide_std_init_ports(&
hw[0], 0x1f0, 0x3f6);
779 ide_std_init_ports(&
hw[1], 0x170, 0x376);
782 printk(
KERN_INFO "cmd640: buggy cmd640%c interface on %s, config=0x%02x"
783 "\n",
'a' + cmd640_chip_version - 1, bus_type, cfr);
797 put_cmd640_reg(
CMDTIM, 0);
798 put_cmd640_reg(
BRST, 0x40);
800 b = get_cmd640_reg(
CNTRL);
805 if (secondary_port_responding()) {
807 second_port_cmd640 = 1;
809 }
else if (cmd640_vlb) {
810 second_port_cmd640 = 1;
813 port2 =
"not cmd640";
815 put_cmd640_reg(
CNTRL, b ^ CNTRL_ENA_2ND);
816 if (secondary_port_responding()) {
817 second_port_cmd640 = 1;
820 put_cmd640_reg(
CNTRL, b);
821 port2 =
"not responding";
828 if (second_port_cmd640)
832 second_port_cmd640 ?
"" :
"not ", port2);
834 #ifdef CMD640_DUMP_REGS
838 return ide_host_add(&cmd640_port_info, hws, second_port_cmd640 ? 2 : 1,