aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ide/cmd64x.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/ide/cmd64x.c')
-rw-r--r--drivers/ide/cmd64x.c114
1 files changed, 43 insertions, 71 deletions
diff --git a/drivers/ide/cmd64x.c b/drivers/ide/cmd64x.c
index f2500c8826bb..5f80312e636b 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,42 @@
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
97/*
98 * This routine writes into the chipset registers
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 90
120 /* 91 /*
121 * The primary channel has individual address setup timing registers 92 * The primary channel has individual address setup timing registers
@@ -126,15 +97,21 @@ static void cmd64x_tune_pio(ide_drive_t *drive, const u8 pio)
126 if (hwif->channel) { 97 if (hwif->channel) {
127 ide_drive_t *pair = ide_get_pair_dev(drive); 98 ide_drive_t *pair = ide_get_pair_dev(drive);
128 99
129 ide_set_drivedata(drive, (void *)setup_count); 100 if (pair) {
101 struct ide_timing tp;
130 102
131 if (pair) 103 ide_timing_compute(pair, pair->pio_mode, &tp, T, 0);
132 setup_count = max_t(u8, setup_count, 104 ide_timing_merge(&t, &tp, &t, IDE_TIMING_SETUP);
133 (unsigned long)ide_get_drivedata(pair)); 105 if (pair->dma_mode) {
106 ide_timing_compute(pair, pair->dma_mode,
107 &tp, T, 0);
108 ide_timing_merge(&tp, &t, &t, IDE_TIMING_SETUP);
109 }
110 }
134 } 111 }
135 112
136 if (setup_count > 5) /* shouldn't actually happen... */ 113 if (t.setup > 5) /* shouldn't actually happen... */
137 setup_count = 5; 114 t.setup = 5;
138 115
139 /* 116 /*
140 * Program the address setup clocks into the ARTTIM registers. 117 * Program the address setup clocks into the ARTTIM registers.
@@ -144,7 +121,7 @@ static void cmd64x_tune_pio(ide_drive_t *drive, const u8 pio)
144 if (hwif->channel) 121 if (hwif->channel)
145 arttim &= ~ARTTIM23_INTR_CH1; 122 arttim &= ~ARTTIM23_INTR_CH1;
146 arttim &= ~0xc0; 123 arttim &= ~0xc0;
147 arttim |= setup_values[setup_count]; 124 arttim |= setup_values[t.setup];
148 (void) pci_write_config_byte(dev, arttim_regs[drive->dn], arttim); 125 (void) pci_write_config_byte(dev, arttim_regs[drive->dn], arttim);
149} 126}
150 127
@@ -153,8 +130,10 @@ static void cmd64x_tune_pio(ide_drive_t *drive, const u8 pio)
153 * Special cases are 8: prefetch off, 9: prefetch on (both never worked) 130 * Special cases are 8: prefetch off, 9: prefetch on (both never worked)
154 */ 131 */
155 132
156static void cmd64x_set_pio_mode(ide_drive_t *drive, const u8 pio) 133static void cmd64x_set_pio_mode(ide_hwif_t *hwif, ide_drive_t *drive)
157{ 134{
135 const u8 pio = drive->pio_mode - XFER_PIO_0;
136
158 /* 137 /*
159 * Filter out the prefetch control values 138 * Filter out the prefetch control values
160 * to prevent PIO5 from being programmed 139 * to prevent PIO5 from being programmed
@@ -162,20 +141,18 @@ static void cmd64x_set_pio_mode(ide_drive_t *drive, const u8 pio)
162 if (pio == 8 || pio == 9) 141 if (pio == 8 || pio == 9)
163 return; 142 return;
164 143
165 cmd64x_tune_pio(drive, pio); 144 cmd64x_program_timings(drive, XFER_PIO_0 + pio);
166} 145}
167 146
168static void cmd64x_set_dma_mode(ide_drive_t *drive, const u8 speed) 147static void cmd64x_set_dma_mode(ide_hwif_t *hwif, ide_drive_t *drive)
169{ 148{
170 ide_hwif_t *hwif = drive->hwif;
171 struct pci_dev *dev = to_pci_dev(hwif->dev); 149 struct pci_dev *dev = to_pci_dev(hwif->dev);
172 u8 unit = drive->dn & 0x01; 150 u8 unit = drive->dn & 0x01;
173 u8 regU = 0, pciU = hwif->channel ? UDIDETCR1 : UDIDETCR0; 151 u8 regU = 0, pciU = hwif->channel ? UDIDETCR1 : UDIDETCR0;
152 const u8 speed = drive->dma_mode;
174 153
175 if (speed >= XFER_SW_DMA_0) { 154 pci_read_config_byte(dev, pciU, &regU);
176 (void) pci_read_config_byte(dev, pciU, &regU); 155 regU &= ~(unit ? 0xCA : 0x35);
177 regU &= ~(unit ? 0xCA : 0x35);
178 }
179 156
180 switch(speed) { 157 switch(speed) {
181 case XFER_UDMA_5: 158 case XFER_UDMA_5:
@@ -197,18 +174,13 @@ static void cmd64x_set_dma_mode(ide_drive_t *drive, const u8 speed)
197 regU |= unit ? 0xC2 : 0x31; 174 regU |= unit ? 0xC2 : 0x31;
198 break; 175 break;
199 case XFER_MW_DMA_2: 176 case XFER_MW_DMA_2:
200 program_cycle_times(drive, 120, 70);
201 break;
202 case XFER_MW_DMA_1: 177 case XFER_MW_DMA_1:
203 program_cycle_times(drive, 150, 80);
204 break;
205 case XFER_MW_DMA_0: 178 case XFER_MW_DMA_0:
206 program_cycle_times(drive, 480, 215); 179 cmd64x_program_timings(drive, speed);
207 break; 180 break;
208 } 181 }
209 182
210 if (speed >= XFER_SW_DMA_0) 183 pci_write_config_byte(dev, pciU, regU);
211 (void) pci_write_config_byte(dev, pciU, regU);
212} 184}
213 185
214static void cmd648_clear_irq(ide_drive_t *drive) 186static void cmd648_clear_irq(ide_drive_t *drive)
@@ -471,6 +443,6 @@ static void __exit cmd64x_ide_exit(void)
471module_init(cmd64x_ide_init); 443module_init(cmd64x_ide_init);
472module_exit(cmd64x_ide_exit); 444module_exit(cmd64x_ide_exit);
473 445
474MODULE_AUTHOR("Eddie Dost, David Miller, Andre Hedrick"); 446MODULE_AUTHOR("Eddie Dost, David Miller, Andre Hedrick, Bartlomiej Zolnierkiewicz");
475MODULE_DESCRIPTION("PCI driver module for CMD64x IDE"); 447MODULE_DESCRIPTION("PCI driver module for CMD64x IDE");
476MODULE_LICENSE("GPL"); 448MODULE_LICENSE("GPL");