diff options
Diffstat (limited to 'drivers/ide')
-rw-r--r-- | drivers/ide/pci/pdc202xx_old.c | 178 |
1 files changed, 44 insertions, 134 deletions
diff --git a/drivers/ide/pci/pdc202xx_old.c b/drivers/ide/pci/pdc202xx_old.c index 7146fe3f6ba7..a6dd9c815342 100644 --- a/drivers/ide/pci/pdc202xx_old.c +++ b/drivers/ide/pci/pdc202xx_old.c | |||
@@ -1,8 +1,9 @@ | |||
1 | /* | 1 | /* |
2 | * linux/drivers/ide/pci/pdc202xx_old.c Version 0.36 Sept 11, 2002 | 2 | * linux/drivers/ide/pci/pdc202xx_old.c Version 0.50 Mar 3, 2007 |
3 | * | 3 | * |
4 | * Copyright (C) 1998-2002 Andre Hedrick <andre@linux-ide.org> | 4 | * Copyright (C) 1998-2002 Andre Hedrick <andre@linux-ide.org> |
5 | * Copyright (C) 2006-2007 MontaVista Software, Inc. | 5 | * Copyright (C) 2006-2007 MontaVista Software, Inc. |
6 | * Copyright (C) 2007 Bartlomiej Zolnierkiewicz | ||
6 | * | 7 | * |
7 | * Promise Ultra33 cards with BIOS v1.20 through 1.28 will need this | 8 | * Promise Ultra33 cards with BIOS v1.20 through 1.28 will need this |
8 | * compiled into the kernel if you have more than one card installed. | 9 | * compiled into the kernel if you have more than one card installed. |
@@ -60,45 +61,7 @@ static const char *pdc_quirk_drives[] = { | |||
60 | NULL | 61 | NULL |
61 | }; | 62 | }; |
62 | 63 | ||
63 | /* A Register */ | 64 | static void pdc_old_disable_66MHz_clock(ide_hwif_t *); |
64 | #define SYNC_ERRDY_EN 0xC0 | ||
65 | |||
66 | #define SYNC_IN 0x80 /* control bit, different for master vs. slave drives */ | ||
67 | #define ERRDY_EN 0x40 /* control bit, different for master vs. slave drives */ | ||
68 | #define IORDY_EN 0x20 /* PIO: IOREADY */ | ||
69 | #define PREFETCH_EN 0x10 /* PIO: PREFETCH */ | ||
70 | |||
71 | #define PA3 0x08 /* PIO"A" timing */ | ||
72 | #define PA2 0x04 /* PIO"A" timing */ | ||
73 | #define PA1 0x02 /* PIO"A" timing */ | ||
74 | #define PA0 0x01 /* PIO"A" timing */ | ||
75 | |||
76 | /* B Register */ | ||
77 | |||
78 | #define MB2 0x80 /* DMA"B" timing */ | ||
79 | #define MB1 0x40 /* DMA"B" timing */ | ||
80 | #define MB0 0x20 /* DMA"B" timing */ | ||
81 | |||
82 | #define PB4 0x10 /* PIO_FORCE 1:0 */ | ||
83 | |||
84 | #define PB3 0x08 /* PIO"B" timing */ /* PIO flow Control mode */ | ||
85 | #define PB2 0x04 /* PIO"B" timing */ /* PIO 4 */ | ||
86 | #define PB1 0x02 /* PIO"B" timing */ /* PIO 3 half */ | ||
87 | #define PB0 0x01 /* PIO"B" timing */ /* PIO 3 other half */ | ||
88 | |||
89 | /* C Register */ | ||
90 | #define IORDYp_NO_SPEED 0x4F | ||
91 | #define SPEED_DIS 0x0F | ||
92 | |||
93 | #define DMARQp 0x80 | ||
94 | #define IORDYp 0x40 | ||
95 | #define DMAR_EN 0x20 | ||
96 | #define DMAW_EN 0x10 | ||
97 | |||
98 | #define MC3 0x08 /* DMA"C" timing */ | ||
99 | #define MC2 0x04 /* DMA"C" timing */ | ||
100 | #define MC1 0x02 /* DMA"C" timing */ | ||
101 | #define MC0 0x01 /* DMA"C" timing */ | ||
102 | 65 | ||
103 | static int pdc202xx_tune_chipset (ide_drive_t *drive, u8 xferspeed) | 66 | static int pdc202xx_tune_chipset (ide_drive_t *drive, u8 xferspeed) |
104 | { | 67 | { |
@@ -107,52 +70,25 @@ static int pdc202xx_tune_chipset (ide_drive_t *drive, u8 xferspeed) | |||
107 | u8 drive_pci = 0x60 + (drive->dn << 2); | 70 | u8 drive_pci = 0x60 + (drive->dn << 2); |
108 | u8 speed = ide_rate_filter(drive, xferspeed); | 71 | u8 speed = ide_rate_filter(drive, xferspeed); |
109 | 72 | ||
110 | u32 drive_conf; | 73 | u8 AP = 0, BP = 0, CP = 0; |
111 | u8 AP, BP, CP, DP; | ||
112 | u8 TA = 0, TB = 0, TC = 0; | 74 | u8 TA = 0, TB = 0, TC = 0; |
113 | 75 | ||
114 | if (drive->media != ide_disk && | 76 | #if PDC202XX_DEBUG_DRIVE_INFO |
115 | drive->media != ide_cdrom && speed < XFER_SW_DMA_0) | 77 | u32 drive_conf = 0; |
116 | return -1; | ||
117 | |||
118 | pci_read_config_dword(dev, drive_pci, &drive_conf); | 78 | pci_read_config_dword(dev, drive_pci, &drive_conf); |
119 | pci_read_config_byte(dev, (drive_pci), &AP); | 79 | #endif |
120 | pci_read_config_byte(dev, (drive_pci)|0x01, &BP); | ||
121 | pci_read_config_byte(dev, (drive_pci)|0x02, &CP); | ||
122 | pci_read_config_byte(dev, (drive_pci)|0x03, &DP); | ||
123 | |||
124 | if (speed < XFER_SW_DMA_0) { | ||
125 | if ((AP & 0x0F) || (BP & 0x07)) { | ||
126 | /* clear PIO modes of lower 8421 bits of A Register */ | ||
127 | pci_write_config_byte(dev, (drive_pci), AP &~0x0F); | ||
128 | pci_read_config_byte(dev, (drive_pci), &AP); | ||
129 | 80 | ||
130 | /* clear PIO modes of lower 421 bits of B Register */ | 81 | /* |
131 | pci_write_config_byte(dev, (drive_pci)|0x01, BP &~0x07); | 82 | * TODO: do this once per channel |
132 | pci_read_config_byte(dev, (drive_pci)|0x01, &BP); | 83 | */ |
133 | 84 | if (dev->device != PCI_DEVICE_ID_PROMISE_20246) | |
134 | pci_read_config_byte(dev, (drive_pci), &AP); | 85 | pdc_old_disable_66MHz_clock(hwif); |
135 | pci_read_config_byte(dev, (drive_pci)|0x01, &BP); | ||
136 | } | ||
137 | } else { | ||
138 | if ((BP & 0xF0) && (CP & 0x0F)) { | ||
139 | /* clear DMA modes of upper 842 bits of B Register */ | ||
140 | /* clear PIO forced mode upper 1 bit of B Register */ | ||
141 | pci_write_config_byte(dev, (drive_pci)|0x01, BP &~0xF0); | ||
142 | pci_read_config_byte(dev, (drive_pci)|0x01, &BP); | ||
143 | |||
144 | /* clear DMA modes of lower 8421 bits of C Register */ | ||
145 | pci_write_config_byte(dev, (drive_pci)|0x02, CP &~0x0F); | ||
146 | pci_read_config_byte(dev, (drive_pci)|0x02, &CP); | ||
147 | } | ||
148 | } | ||
149 | 86 | ||
150 | pci_read_config_byte(dev, (drive_pci), &AP); | 87 | pci_read_config_byte(dev, drive_pci, &AP); |
151 | pci_read_config_byte(dev, (drive_pci)|0x01, &BP); | 88 | pci_read_config_byte(dev, drive_pci + 1, &BP); |
152 | pci_read_config_byte(dev, (drive_pci)|0x02, &CP); | 89 | pci_read_config_byte(dev, drive_pci + 2, &CP); |
153 | 90 | ||
154 | switch(speed) { | 91 | switch(speed) { |
155 | case XFER_UDMA_6: speed = XFER_UDMA_5; | ||
156 | case XFER_UDMA_5: | 92 | case XFER_UDMA_5: |
157 | case XFER_UDMA_4: TB = 0x20; TC = 0x01; break; | 93 | case XFER_UDMA_4: TB = 0x20; TC = 0x01; break; |
158 | case XFER_UDMA_2: TB = 0x20; TC = 0x01; break; | 94 | case XFER_UDMA_2: TB = 0x20; TC = 0x01; break; |
@@ -161,7 +97,7 @@ static int pdc202xx_tune_chipset (ide_drive_t *drive, u8 xferspeed) | |||
161 | case XFER_UDMA_0: | 97 | case XFER_UDMA_0: |
162 | case XFER_MW_DMA_2: TB = 0x60; TC = 0x03; break; | 98 | case XFER_MW_DMA_2: TB = 0x60; TC = 0x03; break; |
163 | case XFER_MW_DMA_1: TB = 0x60; TC = 0x04; break; | 99 | case XFER_MW_DMA_1: TB = 0x60; TC = 0x04; break; |
164 | case XFER_MW_DMA_0: | 100 | case XFER_MW_DMA_0: TB = 0xE0; TC = 0x0F; break; |
165 | case XFER_SW_DMA_2: TB = 0x60; TC = 0x05; break; | 101 | case XFER_SW_DMA_2: TB = 0x60; TC = 0x05; break; |
166 | case XFER_SW_DMA_1: TB = 0x80; TC = 0x06; break; | 102 | case XFER_SW_DMA_1: TB = 0x80; TC = 0x06; break; |
167 | case XFER_SW_DMA_0: TB = 0xC0; TC = 0x0B; break; | 103 | case XFER_SW_DMA_0: TB = 0xC0; TC = 0x0B; break; |
@@ -174,25 +110,39 @@ static int pdc202xx_tune_chipset (ide_drive_t *drive, u8 xferspeed) | |||
174 | } | 110 | } |
175 | 111 | ||
176 | if (speed < XFER_SW_DMA_0) { | 112 | if (speed < XFER_SW_DMA_0) { |
177 | pci_write_config_byte(dev, (drive_pci), AP|TA); | 113 | /* |
178 | pci_write_config_byte(dev, (drive_pci)|0x01, BP|TB); | 114 | * preserve SYNC_INT / ERDDY_EN bits while clearing |
115 | * Prefetch_EN / IORDY_EN / PA[3:0] bits of register A | ||
116 | */ | ||
117 | AP &= ~0x3f; | ||
118 | if (drive->id->capability & 4) | ||
119 | AP |= 0x20; /* set IORDY_EN bit */ | ||
120 | if (drive->media == ide_disk) | ||
121 | AP |= 0x10; /* set Prefetch_EN bit */ | ||
122 | /* clear PB[4:0] bits of register B */ | ||
123 | BP &= ~0x1f; | ||
124 | pci_write_config_byte(dev, drive_pci, AP | TA); | ||
125 | pci_write_config_byte(dev, drive_pci + 1, BP | TB); | ||
179 | } else { | 126 | } else { |
180 | pci_write_config_byte(dev, (drive_pci)|0x01, BP|TB); | 127 | /* clear MB[2:0] bits of register B */ |
181 | pci_write_config_byte(dev, (drive_pci)|0x02, CP|TC); | 128 | BP &= ~0xe0; |
129 | /* clear MC[3:0] bits of register C */ | ||
130 | CP &= ~0x0f; | ||
131 | pci_write_config_byte(dev, drive_pci + 1, BP | TB); | ||
132 | pci_write_config_byte(dev, drive_pci + 2, CP | TC); | ||
182 | } | 133 | } |
183 | 134 | ||
184 | #if PDC202XX_DEBUG_DRIVE_INFO | 135 | #if PDC202XX_DEBUG_DRIVE_INFO |
185 | printk(KERN_DEBUG "%s: %s drive%d 0x%08x ", | 136 | printk(KERN_DEBUG "%s: %s drive%d 0x%08x ", |
186 | drive->name, ide_xfer_verbose(speed), | 137 | drive->name, ide_xfer_verbose(speed), |
187 | drive->dn, drive_conf); | 138 | drive->dn, drive_conf); |
188 | pci_read_config_dword(dev, drive_pci, &drive_conf); | 139 | pci_read_config_dword(dev, drive_pci, &drive_conf); |
189 | printk("0x%08x\n", drive_conf); | 140 | printk("0x%08x\n", drive_conf); |
190 | #endif /* PDC202XX_DEBUG_DRIVE_INFO */ | 141 | #endif |
191 | 142 | ||
192 | return (ide_config_drive_speed(drive, speed)); | 143 | return ide_config_drive_speed(drive, speed); |
193 | } | 144 | } |
194 | 145 | ||
195 | |||
196 | static void pdc202xx_tune_drive(ide_drive_t *drive, u8 pio) | 146 | static void pdc202xx_tune_drive(ide_drive_t *drive, u8 pio) |
197 | { | 147 | { |
198 | pio = ide_get_best_pio_mode(drive, pio, 4, NULL); | 148 | pio = ide_get_best_pio_mode(drive, pio, 4, NULL); |
@@ -210,6 +160,8 @@ static u8 pdc202xx_old_cable_detect (ide_hwif_t *hwif) | |||
210 | * Set the control register to use the 66MHz system | 160 | * Set the control register to use the 66MHz system |
211 | * clock for UDMA 3/4/5 mode operation when necessary. | 161 | * clock for UDMA 3/4/5 mode operation when necessary. |
212 | * | 162 | * |
163 | * FIXME: this register is shared by both channels, some locking is needed | ||
164 | * | ||
213 | * It may also be possible to leave the 66MHz clock on | 165 | * It may also be possible to leave the 66MHz clock on |
214 | * and readjust the timing parameters. | 166 | * and readjust the timing parameters. |
215 | */ | 167 | */ |
@@ -231,55 +183,13 @@ static void pdc_old_disable_66MHz_clock(ide_hwif_t *hwif) | |||
231 | 183 | ||
232 | static int config_chipset_for_dma (ide_drive_t *drive) | 184 | static int config_chipset_for_dma (ide_drive_t *drive) |
233 | { | 185 | { |
234 | struct hd_driveid *id = drive->id; | 186 | u8 speed = ide_max_dma_mode(drive); |
235 | ide_hwif_t *hwif = HWIF(drive); | ||
236 | struct pci_dev *dev = hwif->pci_dev; | ||
237 | u32 drive_conf = 0; | ||
238 | u8 drive_pci = 0x60 + (drive->dn << 2); | ||
239 | u8 test1 = 0, test2 = 0, speed = -1; | ||
240 | u8 AP = 0; | ||
241 | |||
242 | if (dev->device != PCI_DEVICE_ID_PROMISE_20246) | ||
243 | pdc_old_disable_66MHz_clock(drive->hwif); | ||
244 | 187 | ||
245 | drive_pci = 0x60 + (drive->dn << 2); | 188 | if (!speed) |
246 | pci_read_config_dword(dev, drive_pci, &drive_conf); | ||
247 | if ((drive_conf != 0x004ff304) && (drive_conf != 0x004ff3c4)) | ||
248 | goto chipset_is_set; | ||
249 | |||
250 | pci_read_config_byte(dev, drive_pci, &test1); | ||
251 | if (!(test1 & SYNC_ERRDY_EN)) { | ||
252 | if (drive->select.b.unit & 0x01) { | ||
253 | pci_read_config_byte(dev, drive_pci - 4, &test2); | ||
254 | if ((test2 & SYNC_ERRDY_EN) && | ||
255 | !(test1 & SYNC_ERRDY_EN)) { | ||
256 | pci_write_config_byte(dev, drive_pci, | ||
257 | test1|SYNC_ERRDY_EN); | ||
258 | } | ||
259 | } else { | ||
260 | pci_write_config_byte(dev, drive_pci, | ||
261 | test1|SYNC_ERRDY_EN); | ||
262 | } | ||
263 | } | ||
264 | |||
265 | chipset_is_set: | ||
266 | |||
267 | pci_read_config_byte(dev, (drive_pci), &AP); | ||
268 | if (id->capability & 4) /* IORDY_EN */ | ||
269 | pci_write_config_byte(dev, (drive_pci), AP|IORDY_EN); | ||
270 | pci_read_config_byte(dev, (drive_pci), &AP); | ||
271 | if (drive->media == ide_disk) /* PREFETCH_EN */ | ||
272 | pci_write_config_byte(dev, (drive_pci), AP|PREFETCH_EN); | ||
273 | |||
274 | speed = ide_max_dma_mode(drive); | ||
275 | |||
276 | if (!(speed)) { | ||
277 | /* restore original pci-config space */ | ||
278 | pci_write_config_dword(dev, drive_pci, drive_conf); | ||
279 | return 0; | 189 | return 0; |
280 | } | ||
281 | 190 | ||
282 | (void) hwif->speedproc(drive, speed); | 191 | (void)pdc202xx_tune_chipset(drive, speed); |
192 | |||
283 | return ide_dma_enable(drive); | 193 | return ide_dma_enable(drive); |
284 | } | 194 | } |
285 | 195 | ||