aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/ide/cmd64x.c88
1 files changed, 29 insertions, 59 deletions
diff --git a/drivers/ide/cmd64x.c b/drivers/ide/cmd64x.c
index f2500c8826bb..5c5dd90d032b 100644
--- a/drivers/ide/cmd64x.c
+++ b/drivers/ide/cmd64x.c
@@ -7,6 +7,7 @@
7 * Copyright (C) 1998 David S. Miller (davem@redhat.com) 7 * Copyright (C) 1998 David S. Miller (davem@redhat.com)
8 * 8 *
9 * Copyright (C) 1999-2002 Andre Hedrick <andre@linux-ide.org> 9 * Copyright (C) 1999-2002 Andre Hedrick <andre@linux-ide.org>
10 * Copyright (C) 2007-2010 Bartlomiej Zolnierkiewicz
10 * Copyright (C) 2007,2009 MontaVista Software, Inc. <source@mvista.com> 11 * Copyright (C) 2007,2009 MontaVista Software, Inc. <source@mvista.com>
11 */ 12 */
12 13
@@ -50,72 +51,45 @@
50#define UDIDETCR1 0x7B 51#define UDIDETCR1 0x7B
51#define DTPR1 0x7C 52#define DTPR1 0x7C
52 53
53static u8 quantize_timing(int timing, int quant) 54static void cmd64x_program_timings(ide_drive_t *drive, u8 mode)
54{
55 return (timing + quant - 1) / quant;
56}
57
58/*
59 * This routine calculates active/recovery counts and then writes them into
60 * the chipset registers.
61 */
62static void program_cycle_times (ide_drive_t *drive, int cycle_time, int active_time)
63{ 55{
56 ide_hwif_t *hwif = drive->hwif;
64 struct pci_dev *dev = to_pci_dev(drive->hwif->dev); 57 struct pci_dev *dev = to_pci_dev(drive->hwif->dev);
65 int clock_time = 1000 / (ide_pci_clk ? ide_pci_clk : 33); 58 int bus_speed = ide_pci_clk ? ide_pci_clk : 33;
66 u8 cycle_count, active_count, recovery_count, drwtim; 59 const unsigned long T = 1000000 / bus_speed;
67 static const u8 recovery_values[] = 60 static const u8 recovery_values[] =
68 {15, 15, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 0}; 61 {15, 15, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 0};
62 static const u8 setup_values[] = {0x40, 0x40, 0x40, 0x80, 0, 0xc0};
63 static const u8 arttim_regs[4] = {ARTTIM0, ARTTIM1, ARTTIM23, ARTTIM23};
69 static const u8 drwtim_regs[4] = {DRWTIM0, DRWTIM1, DRWTIM2, DRWTIM3}; 64 static const u8 drwtim_regs[4] = {DRWTIM0, DRWTIM1, DRWTIM2, DRWTIM3};
65 struct ide_timing t;
66 u8 arttim = 0;
70 67
71 cycle_count = quantize_timing( cycle_time, clock_time); 68 ide_timing_compute(drive, mode, &t, T, 0);
72 active_count = quantize_timing(active_time, clock_time);
73 recovery_count = cycle_count - active_count;
74 69
75 /* 70 /*
76 * In case we've got too long recovery phase, try to lengthen 71 * In case we've got too long recovery phase, try to lengthen
77 * the active phase 72 * the active phase
78 */ 73 */
79 if (recovery_count > 16) { 74 if (t.recover > 16) {
80 active_count += recovery_count - 16; 75 t.active += t.recover - 16;
81 recovery_count = 16; 76 t.recover = 16;
82 } 77 }
83 if (active_count > 16) /* shouldn't actually happen... */ 78 if (t.active > 16) /* shouldn't actually happen... */
84 active_count = 16; 79 t.active = 16;
85 80
86 /* 81 /*
87 * Convert values to internal chipset representation 82 * Convert values to internal chipset representation
88 */ 83 */
89 recovery_count = recovery_values[recovery_count]; 84 t.recover = recovery_values[t.recover];
90 active_count &= 0x0f; 85 t.active &= 0x0f;
91 86
92 /* Program the active/recovery counts into the DRWTIM register */ 87 /* Program the active/recovery counts into the DRWTIM register */
93 drwtim = (active_count << 4) | recovery_count; 88 pci_write_config_byte(dev, drwtim_regs[drive->dn],
94 (void) pci_write_config_byte(dev, drwtim_regs[drive->dn], drwtim); 89 (t.active << 4) | t.recover);
95}
96 90
97/* 91 if (mode >= XFER_SW_DMA_0)
98 * This routine writes into the chipset registers 92 return;
99 * PIO setup/active/recovery timings.
100 */
101static void cmd64x_tune_pio(ide_drive_t *drive, const u8 pio)
102{
103 ide_hwif_t *hwif = drive->hwif;
104 struct pci_dev *dev = to_pci_dev(hwif->dev);
105 struct ide_timing *t = ide_timing_find_mode(XFER_PIO_0 + pio);
106 unsigned long setup_count;
107 unsigned int cycle_time;
108 u8 arttim = 0;
109
110 static const u8 setup_values[] = {0x40, 0x40, 0x40, 0x80, 0, 0xc0};
111 static const u8 arttim_regs[4] = {ARTTIM0, ARTTIM1, ARTTIM23, ARTTIM23};
112
113 cycle_time = ide_pio_cycle_time(drive, pio);
114
115 program_cycle_times(drive, cycle_time, t->active);
116
117 setup_count = quantize_timing(t->setup,
118 1000 / (ide_pci_clk ? ide_pci_clk : 33));
119 93
120 /* 94 /*
121 * The primary channel has individual address setup timing registers 95 * The primary channel has individual address setup timing registers
@@ -126,15 +100,15 @@ static void cmd64x_tune_pio(ide_drive_t *drive, const u8 pio)
126 if (hwif->channel) { 100 if (hwif->channel) {
127 ide_drive_t *pair = ide_get_pair_dev(drive); 101 ide_drive_t *pair = ide_get_pair_dev(drive);
128 102
129 ide_set_drivedata(drive, (void *)setup_count); 103 ide_set_drivedata(drive, (void *)(unsigned long)t.setup);
130 104
131 if (pair) 105 if (pair)
132 setup_count = max_t(u8, setup_count, 106 t.setup = max_t(u8, t.setup,
133 (unsigned long)ide_get_drivedata(pair)); 107 (unsigned long)ide_get_drivedata(pair));
134 } 108 }
135 109
136 if (setup_count > 5) /* shouldn't actually happen... */ 110 if (t.setup > 5) /* shouldn't actually happen... */
137 setup_count = 5; 111 t.setup = 5;
138 112
139 /* 113 /*
140 * Program the address setup clocks into the ARTTIM registers. 114 * Program the address setup clocks into the ARTTIM registers.
@@ -144,7 +118,7 @@ static void cmd64x_tune_pio(ide_drive_t *drive, const u8 pio)
144 if (hwif->channel) 118 if (hwif->channel)
145 arttim &= ~ARTTIM23_INTR_CH1; 119 arttim &= ~ARTTIM23_INTR_CH1;
146 arttim &= ~0xc0; 120 arttim &= ~0xc0;
147 arttim |= setup_values[setup_count]; 121 arttim |= setup_values[t.setup];
148 (void) pci_write_config_byte(dev, arttim_regs[drive->dn], arttim); 122 (void) pci_write_config_byte(dev, arttim_regs[drive->dn], arttim);
149} 123}
150 124
@@ -162,7 +136,7 @@ static void cmd64x_set_pio_mode(ide_drive_t *drive, const u8 pio)
162 if (pio == 8 || pio == 9) 136 if (pio == 8 || pio == 9)
163 return; 137 return;
164 138
165 cmd64x_tune_pio(drive, pio); 139 cmd64x_program_timings(drive, XFER_PIO_0 + pio);
166} 140}
167 141
168static void cmd64x_set_dma_mode(ide_drive_t *drive, const u8 speed) 142static void cmd64x_set_dma_mode(ide_drive_t *drive, const u8 speed)
@@ -197,13 +171,9 @@ static void cmd64x_set_dma_mode(ide_drive_t *drive, const u8 speed)
197 regU |= unit ? 0xC2 : 0x31; 171 regU |= unit ? 0xC2 : 0x31;
198 break; 172 break;
199 case XFER_MW_DMA_2: 173 case XFER_MW_DMA_2:
200 program_cycle_times(drive, 120, 70);
201 break;
202 case XFER_MW_DMA_1: 174 case XFER_MW_DMA_1:
203 program_cycle_times(drive, 150, 80);
204 break;
205 case XFER_MW_DMA_0: 175 case XFER_MW_DMA_0:
206 program_cycle_times(drive, 480, 215); 176 cmd64x_program_timings(drive, speed);
207 break; 177 break;
208 } 178 }
209 179
@@ -471,6 +441,6 @@ static void __exit cmd64x_ide_exit(void)
471module_init(cmd64x_ide_init); 441module_init(cmd64x_ide_init);
472module_exit(cmd64x_ide_exit); 442module_exit(cmd64x_ide_exit);
473 443
474MODULE_AUTHOR("Eddie Dost, David Miller, Andre Hedrick"); 444MODULE_AUTHOR("Eddie Dost, David Miller, Andre Hedrick, Bartlomiej Zolnierkiewicz");
475MODULE_DESCRIPTION("PCI driver module for CMD64x IDE"); 445MODULE_DESCRIPTION("PCI driver module for CMD64x IDE");
476MODULE_LICENSE("GPL"); 446MODULE_LICENSE("GPL");