diff options
author | Bartlomiej Zolnierkiewicz <bzolnier@gmail.com> | 2008-02-01 17:09:30 -0500 |
---|---|---|
committer | Bartlomiej Zolnierkiewicz <bzolnier@gmail.com> | 2008-02-01 17:09:30 -0500 |
commit | 993da8f9ea7e00d21af49d0e14a131183288bcf8 (patch) | |
tree | 74407441bf26d47bacdaa165439f0324a8629705 /drivers/ide/pci/amd74xx.c | |
parent | ecf32796395ed0e27667e7f735946d6dc60e1765 (diff) |
amd74xx: remove amd_ide_chips table
* Remove no longer needed assertion from amd74xx_probe().
* Factor out cable detection for AMD7409 to amd7409_cable_detect() and for
chipsets >= AMD7411 to amd7411_cable_detect().
* Use dev->vendor and dev->device instead of amd_config->udma_mask when
selecting cable detection method and checking for broken FIFO support in
init_chipset_amd74xx().
* Remove no longer needed AMD_BAD_FIFO define.
* Add 'swdma' parameter for setting .swdma_mask to DECLARE_AMD_DEV() macro.
* Add 'udma' parameter for setting .udma_mask to DECLARE_{AMD,NV}_DEV() macro.
* Keep a copy of a current amd74xx_chipsets[] entry in amd74xx_probe()
in order to fix ->swdma_mask on early AMD7409 revisions and ->udma_mask
on Serenade mainboards.
* Remove no longer needed fixups from init_chipset_amd74xx()
and AMD_CHECK_{SWDMA,SERENADE} defines.
* Move printing banner message from init_chipset_amd74xx() to amd74xx_probe(),
also remove incorrect comment while at it.
* Use hwif->ultra_mask instead of amd_config->udma_mask in amd_set_drive().
* Add 'udma_mask' argument to amd_set_speed() and pass UDMA mask from
amd_set_drive() instead of using amd_config->udma_mask.
* Move amd_config->base from AMD_* defines to users of these defines and add
0x40 the defined values. Then add amd_offset() inline helper for selecting
offset from 0x40 base (needed for nVidia controllers) and finally use it in
amd_set_speed(), amd7411_cable_detect() and init_chipset_amd74xx() instead
of amd_config->base.
* Remove no longer needed AMD_BAD_SWDMA define, ->{swdma,ultra}_mask setup
from init_hwif_amd74xx(), amd_{config,chipset} variables and amd_ide_chips
table.
* Fix init_chipset_amd74xx() comment.
* Bump driver version.
There should be no functionality changes caused by this patch.
Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
Diffstat (limited to 'drivers/ide/pci/amd74xx.c')
-rw-r--r-- | drivers/ide/pci/amd74xx.c | 275 |
1 files changed, 124 insertions, 151 deletions
diff --git a/drivers/ide/pci/amd74xx.c b/drivers/ide/pci/amd74xx.c index cee51fdafcf6..13c9f67969cd 100644 --- a/drivers/ide/pci/amd74xx.c +++ b/drivers/ide/pci/amd74xx.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Version 2.24 | 2 | * Version 2.25 |
3 | * | 3 | * |
4 | * AMD 755/756/766/8111 and nVidia nForce/2/2s/3/3s/CK804/MCP04 | 4 | * AMD 755/756/766/8111 and nVidia nForce/2/2s/3/3s/CK804/MCP04 |
5 | * IDE driver for Linux. | 5 | * IDE driver for Linux. |
@@ -28,81 +28,46 @@ | |||
28 | 28 | ||
29 | #include "ide-timing.h" | 29 | #include "ide-timing.h" |
30 | 30 | ||
31 | #define AMD_IDE_CONFIG (0x01 + amd_config->base) | 31 | enum { |
32 | #define AMD_CABLE_DETECT (0x02 + amd_config->base) | 32 | AMD_IDE_CONFIG = 0x41, |
33 | #define AMD_DRIVE_TIMING (0x08 + amd_config->base) | 33 | AMD_CABLE_DETECT = 0x42, |
34 | #define AMD_8BIT_TIMING (0x0e + amd_config->base) | 34 | AMD_DRIVE_TIMING = 0x48, |
35 | #define AMD_ADDRESS_SETUP (0x0c + amd_config->base) | 35 | AMD_8BIT_TIMING = 0x4e, |
36 | #define AMD_UDMA_TIMING (0x10 + amd_config->base) | 36 | AMD_ADDRESS_SETUP = 0x4c, |
37 | 37 | AMD_UDMA_TIMING = 0x50, | |
38 | #define AMD_CHECK_SWDMA 0x08 | ||
39 | #define AMD_BAD_SWDMA 0x10 | ||
40 | #define AMD_BAD_FIFO 0x20 | ||
41 | #define AMD_CHECK_SERENADE 0x40 | ||
42 | |||
43 | /* | ||
44 | * AMD SouthBridge chips. | ||
45 | */ | ||
46 | |||
47 | static struct amd_ide_chip { | ||
48 | unsigned short id; | ||
49 | u8 base; | ||
50 | u8 udma_mask; | ||
51 | u8 flags; | ||
52 | } amd_ide_chips[] = { | ||
53 | { PCI_DEVICE_ID_AMD_COBRA_7401, 0x40, ATA_UDMA2, AMD_BAD_SWDMA }, | ||
54 | { PCI_DEVICE_ID_AMD_VIPER_7409, 0x40, ATA_UDMA4, AMD_CHECK_SWDMA }, | ||
55 | { PCI_DEVICE_ID_AMD_VIPER_7411, 0x40, ATA_UDMA5, AMD_BAD_FIFO }, | ||
56 | { PCI_DEVICE_ID_AMD_OPUS_7441, 0x40, ATA_UDMA5, }, | ||
57 | { PCI_DEVICE_ID_AMD_8111_IDE, 0x40, ATA_UDMA6, AMD_CHECK_SERENADE }, | ||
58 | { PCI_DEVICE_ID_NVIDIA_NFORCE_IDE, 0x50, ATA_UDMA5, }, | ||
59 | { PCI_DEVICE_ID_NVIDIA_NFORCE2_IDE, 0x50, ATA_UDMA6, }, | ||
60 | { PCI_DEVICE_ID_NVIDIA_NFORCE2S_IDE, 0x50, ATA_UDMA6, }, | ||
61 | { PCI_DEVICE_ID_NVIDIA_NFORCE2S_SATA, 0x50, ATA_UDMA6, }, | ||
62 | { PCI_DEVICE_ID_NVIDIA_NFORCE3_IDE, 0x50, ATA_UDMA6, }, | ||
63 | { PCI_DEVICE_ID_NVIDIA_NFORCE3S_IDE, 0x50, ATA_UDMA6, }, | ||
64 | { PCI_DEVICE_ID_NVIDIA_NFORCE3S_SATA, 0x50, ATA_UDMA6, }, | ||
65 | { PCI_DEVICE_ID_NVIDIA_NFORCE3S_SATA2, 0x50, ATA_UDMA6, }, | ||
66 | { PCI_DEVICE_ID_NVIDIA_NFORCE_CK804_IDE, 0x50, ATA_UDMA6, }, | ||
67 | { PCI_DEVICE_ID_NVIDIA_NFORCE_MCP04_IDE, 0x50, ATA_UDMA6, }, | ||
68 | { PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_IDE, 0x50, ATA_UDMA6, }, | ||
69 | { PCI_DEVICE_ID_NVIDIA_NFORCE_MCP55_IDE, 0x50, ATA_UDMA6, }, | ||
70 | { PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_IDE, 0x50, ATA_UDMA6, }, | ||
71 | { PCI_DEVICE_ID_NVIDIA_NFORCE_MCP65_IDE, 0x50, ATA_UDMA6, }, | ||
72 | { PCI_DEVICE_ID_NVIDIA_NFORCE_MCP67_IDE, 0x50, ATA_UDMA6, }, | ||
73 | { PCI_DEVICE_ID_NVIDIA_NFORCE_MCP73_IDE, 0x50, ATA_UDMA6, }, | ||
74 | { PCI_DEVICE_ID_NVIDIA_NFORCE_MCP77_IDE, 0x50, ATA_UDMA6, }, | ||
75 | { PCI_DEVICE_ID_AMD_CS5536_IDE, 0x40, ATA_UDMA5, }, | ||
76 | { 0 } | ||
77 | }; | 38 | }; |
78 | 39 | ||
79 | static struct amd_ide_chip *amd_config; | ||
80 | static const struct ide_port_info *amd_chipset; | ||
81 | static unsigned int amd_80w; | 40 | static unsigned int amd_80w; |
82 | static unsigned int amd_clock; | 41 | static unsigned int amd_clock; |
83 | 42 | ||
84 | static char *amd_dma[] = { "16", "25", "33", "44", "66", "100", "133" }; | 43 | static char *amd_dma[] = { "16", "25", "33", "44", "66", "100", "133" }; |
85 | static unsigned char amd_cyc2udma[] = { 6, 6, 5, 4, 0, 1, 1, 2, 2, 3, 3, 3, 3, 3, 3, 7 }; | 44 | static unsigned char amd_cyc2udma[] = { 6, 6, 5, 4, 0, 1, 1, 2, 2, 3, 3, 3, 3, 3, 3, 7 }; |
86 | 45 | ||
46 | static inline u8 amd_offset(struct pci_dev *dev) | ||
47 | { | ||
48 | return (dev->vendor == PCI_VENDOR_ID_NVIDIA) ? 0x10 : 0; | ||
49 | } | ||
50 | |||
87 | /* | 51 | /* |
88 | * amd_set_speed() writes timing values to the chipset registers | 52 | * amd_set_speed() writes timing values to the chipset registers |
89 | */ | 53 | */ |
90 | 54 | ||
91 | static void amd_set_speed(struct pci_dev *dev, unsigned char dn, struct ide_timing *timing) | 55 | static void amd_set_speed(struct pci_dev *dev, u8 dn, u8 udma_mask, |
56 | struct ide_timing *timing) | ||
92 | { | 57 | { |
93 | unsigned char t; | 58 | u8 t = 0, offset = amd_offset(dev); |
94 | 59 | ||
95 | pci_read_config_byte(dev, AMD_ADDRESS_SETUP, &t); | 60 | pci_read_config_byte(dev, AMD_ADDRESS_SETUP + offset, &t); |
96 | t = (t & ~(3 << ((3 - dn) << 1))) | ((FIT(timing->setup, 1, 4) - 1) << ((3 - dn) << 1)); | 61 | t = (t & ~(3 << ((3 - dn) << 1))) | ((FIT(timing->setup, 1, 4) - 1) << ((3 - dn) << 1)); |
97 | pci_write_config_byte(dev, AMD_ADDRESS_SETUP, t); | 62 | pci_write_config_byte(dev, AMD_ADDRESS_SETUP + offset, t); |
98 | 63 | ||
99 | pci_write_config_byte(dev, AMD_8BIT_TIMING + (1 - (dn >> 1)), | 64 | pci_write_config_byte(dev, AMD_8BIT_TIMING + offset + (1 - (dn >> 1)), |
100 | ((FIT(timing->act8b, 1, 16) - 1) << 4) | (FIT(timing->rec8b, 1, 16) - 1)); | 65 | ((FIT(timing->act8b, 1, 16) - 1) << 4) | (FIT(timing->rec8b, 1, 16) - 1)); |
101 | 66 | ||
102 | pci_write_config_byte(dev, AMD_DRIVE_TIMING + (3 - dn), | 67 | pci_write_config_byte(dev, AMD_DRIVE_TIMING + offset + (3 - dn), |
103 | ((FIT(timing->active, 1, 16) - 1) << 4) | (FIT(timing->recover, 1, 16) - 1)); | 68 | ((FIT(timing->active, 1, 16) - 1) << 4) | (FIT(timing->recover, 1, 16) - 1)); |
104 | 69 | ||
105 | switch (amd_config->udma_mask) { | 70 | switch (udma_mask) { |
106 | case ATA_UDMA2: t = timing->udma ? (0xc0 | (FIT(timing->udma, 2, 5) - 2)) : 0x03; break; | 71 | case ATA_UDMA2: t = timing->udma ? (0xc0 | (FIT(timing->udma, 2, 5) - 2)) : 0x03; break; |
107 | case ATA_UDMA4: t = timing->udma ? (0xc0 | amd_cyc2udma[FIT(timing->udma, 2, 10)]) : 0x03; break; | 72 | case ATA_UDMA4: t = timing->udma ? (0xc0 | amd_cyc2udma[FIT(timing->udma, 2, 10)]) : 0x03; break; |
108 | case ATA_UDMA5: t = timing->udma ? (0xc0 | amd_cyc2udma[FIT(timing->udma, 1, 10)]) : 0x03; break; | 73 | case ATA_UDMA5: t = timing->udma ? (0xc0 | amd_cyc2udma[FIT(timing->udma, 1, 10)]) : 0x03; break; |
@@ -110,7 +75,7 @@ static void amd_set_speed(struct pci_dev *dev, unsigned char dn, struct ide_timi | |||
110 | default: return; | 75 | default: return; |
111 | } | 76 | } |
112 | 77 | ||
113 | pci_write_config_byte(dev, AMD_UDMA_TIMING + (3 - dn), t); | 78 | pci_write_config_byte(dev, AMD_UDMA_TIMING + offset + (3 - dn), t); |
114 | } | 79 | } |
115 | 80 | ||
116 | /* | 81 | /* |
@@ -120,12 +85,14 @@ static void amd_set_speed(struct pci_dev *dev, unsigned char dn, struct ide_timi | |||
120 | 85 | ||
121 | static void amd_set_drive(ide_drive_t *drive, const u8 speed) | 86 | static void amd_set_drive(ide_drive_t *drive, const u8 speed) |
122 | { | 87 | { |
123 | ide_drive_t *peer = HWIF(drive)->drives + (~drive->dn & 1); | 88 | ide_hwif_t *hwif = drive->hwif; |
89 | ide_drive_t *peer = hwif->drives + (~drive->dn & 1); | ||
124 | struct ide_timing t, p; | 90 | struct ide_timing t, p; |
125 | int T, UT; | 91 | int T, UT; |
92 | u8 udma_mask = hwif->ultra_mask; | ||
126 | 93 | ||
127 | T = 1000000000 / amd_clock; | 94 | T = 1000000000 / amd_clock; |
128 | UT = (amd_config->udma_mask == ATA_UDMA2) ? T : (T / 2); | 95 | UT = (udma_mask == ATA_UDMA2) ? T : (T / 2); |
129 | 96 | ||
130 | ide_timing_compute(drive, speed, &t, T, UT); | 97 | ide_timing_compute(drive, speed, &t, T, UT); |
131 | 98 | ||
@@ -137,7 +104,7 @@ static void amd_set_drive(ide_drive_t *drive, const u8 speed) | |||
137 | if (speed == XFER_UDMA_5 && amd_clock <= 33333) t.udma = 1; | 104 | if (speed == XFER_UDMA_5 && amd_clock <= 33333) t.udma = 1; |
138 | if (speed == XFER_UDMA_6 && amd_clock <= 33333) t.udma = 15; | 105 | if (speed == XFER_UDMA_6 && amd_clock <= 33333) t.udma = 15; |
139 | 106 | ||
140 | amd_set_speed(HWIF(drive)->pci_dev, drive->dn, &t); | 107 | amd_set_speed(hwif->pci_dev, drive->dn, udma_mask, &t); |
141 | } | 108 | } |
142 | 109 | ||
143 | /* | 110 | /* |
@@ -149,67 +116,68 @@ static void amd_set_pio_mode(ide_drive_t *drive, const u8 pio) | |||
149 | amd_set_drive(drive, XFER_PIO_0 + pio); | 116 | amd_set_drive(drive, XFER_PIO_0 + pio); |
150 | } | 117 | } |
151 | 118 | ||
152 | /* | 119 | static void __devinit amd7409_cable_detect(struct pci_dev *dev, |
153 | * The initialization callback. Here we determine the IDE chip type | 120 | const char *name) |
154 | * and initialize its drive independent registers. | 121 | { |
155 | */ | 122 | /* no host side cable detection */ |
123 | amd_80w = 0x03; | ||
124 | } | ||
156 | 125 | ||
157 | static unsigned int __devinit init_chipset_amd74xx(struct pci_dev *dev, const char *name) | 126 | static void __devinit amd7411_cable_detect(struct pci_dev *dev, |
127 | const char *name) | ||
158 | { | 128 | { |
159 | unsigned char t; | ||
160 | unsigned int u; | ||
161 | int i; | 129 | int i; |
130 | u32 u = 0; | ||
131 | u8 t = 0, offset = amd_offset(dev); | ||
132 | |||
133 | pci_read_config_byte(dev, AMD_CABLE_DETECT + offset, &t); | ||
134 | pci_read_config_dword(dev, AMD_UDMA_TIMING + offset, &u); | ||
135 | amd_80w = ((t & 0x3) ? 1 : 0) | ((t & 0xc) ? 2 : 0); | ||
136 | for (i = 24; i >= 0; i -= 8) | ||
137 | if (((u >> i) & 4) && !(amd_80w & (1 << (1 - (i >> 4))))) { | ||
138 | printk(KERN_WARNING "%s: BIOS didn't set cable bits " | ||
139 | "correctly. Enabling workaround.\n", | ||
140 | name); | ||
141 | amd_80w |= (1 << (1 - (i >> 4))); | ||
142 | } | ||
143 | } | ||
162 | 144 | ||
163 | /* | 145 | /* |
164 | * Check for bad SWDMA. | 146 | * The initialization callback. Initialize drive independent registers. |
165 | */ | 147 | */ |
166 | 148 | ||
167 | if (amd_config->flags & AMD_CHECK_SWDMA) { | 149 | static unsigned int __devinit init_chipset_amd74xx(struct pci_dev *dev, |
168 | if (dev->revision <= 7) | 150 | const char *name) |
169 | amd_config->flags |= AMD_BAD_SWDMA; | 151 | { |
170 | } | 152 | u8 t = 0, offset = amd_offset(dev); |
171 | 153 | ||
172 | /* | 154 | /* |
173 | * Check 80-wire cable presence. | 155 | * Check 80-wire cable presence. |
174 | */ | 156 | */ |
175 | 157 | ||
176 | switch (amd_config->udma_mask) { | 158 | if (dev->vendor == PCI_VENDOR_ID_AMD && |
177 | 159 | dev->device == PCI_DEVICE_ID_AMD_COBRA_7401) | |
178 | case ATA_UDMA6: | 160 | ; /* no UDMA > 2 */ |
179 | case ATA_UDMA5: | 161 | else if (dev->vendor == PCI_VENDOR_ID_AMD && |
180 | pci_read_config_byte(dev, AMD_CABLE_DETECT, &t); | 162 | dev->device == PCI_DEVICE_ID_AMD_VIPER_7409) |
181 | pci_read_config_dword(dev, AMD_UDMA_TIMING, &u); | 163 | amd7409_cable_detect(dev, name); |
182 | amd_80w = ((t & 0x3) ? 1 : 0) | ((t & 0xc) ? 2 : 0); | 164 | else |
183 | for (i = 24; i >= 0; i -= 8) | 165 | amd7411_cable_detect(dev, name); |
184 | if (((u >> i) & 4) && !(amd_80w & (1 << (1 - (i >> 4))))) { | ||
185 | printk(KERN_WARNING "%s: BIOS didn't set cable bits correctly. Enabling workaround.\n", | ||
186 | amd_chipset->name); | ||
187 | amd_80w |= (1 << (1 - (i >> 4))); | ||
188 | } | ||
189 | break; | ||
190 | |||
191 | case ATA_UDMA4: | ||
192 | /* no host side cable detection */ | ||
193 | amd_80w = 0x03; | ||
194 | break; | ||
195 | } | ||
196 | 166 | ||
197 | /* | 167 | /* |
198 | * Take care of prefetch & postwrite. | 168 | * Take care of prefetch & postwrite. |
199 | */ | 169 | */ |
200 | 170 | ||
201 | pci_read_config_byte(dev, AMD_IDE_CONFIG, &t); | 171 | pci_read_config_byte(dev, AMD_IDE_CONFIG + offset, &t); |
202 | pci_write_config_byte(dev, AMD_IDE_CONFIG, | 172 | /* |
203 | (amd_config->flags & AMD_BAD_FIFO) ? (t & 0x0f) : (t | 0xf0)); | 173 | * Check for broken FIFO support. |
204 | 174 | */ | |
205 | /* | 175 | if (dev->vendor == PCI_VENDOR_ID_AMD && |
206 | * Take care of incorrectly wired Serenade mainboards. | 176 | dev->vendor == PCI_DEVICE_ID_AMD_VIPER_7411) |
207 | */ | 177 | t &= 0x0f; |
208 | 178 | else | |
209 | if ((amd_config->flags & AMD_CHECK_SERENADE) && | 179 | t |= 0xf0; |
210 | dev->subsystem_vendor == PCI_VENDOR_ID_AMD && | 180 | pci_write_config_byte(dev, AMD_IDE_CONFIG + offset, t); |
211 | dev->subsystem_device == PCI_DEVICE_ID_AMD_SERENADE) | ||
212 | amd_config->udma_mask = ATA_UDMA5; | ||
213 | 181 | ||
214 | /* | 182 | /* |
215 | * Determine the system bus clock. | 183 | * Determine the system bus clock. |
@@ -225,18 +193,10 @@ static unsigned int __devinit init_chipset_amd74xx(struct pci_dev *dev, const ch | |||
225 | 193 | ||
226 | if (amd_clock < 20000 || amd_clock > 50000) { | 194 | if (amd_clock < 20000 || amd_clock > 50000) { |
227 | printk(KERN_WARNING "%s: User given PCI clock speed impossible (%d), using 33 MHz instead.\n", | 195 | printk(KERN_WARNING "%s: User given PCI clock speed impossible (%d), using 33 MHz instead.\n", |
228 | amd_chipset->name, amd_clock); | 196 | name, amd_clock); |
229 | amd_clock = 33333; | 197 | amd_clock = 33333; |
230 | } | 198 | } |
231 | 199 | ||
232 | /* | ||
233 | * Print the boot message. | ||
234 | */ | ||
235 | |||
236 | printk(KERN_INFO "%s: %s (rev %02x) UDMA%s controller\n", | ||
237 | amd_chipset->name, pci_name(dev), dev->revision, | ||
238 | amd_dma[fls(amd_config->udma_mask) - 1]); | ||
239 | |||
240 | return dev->irq; | 200 | return dev->irq; |
241 | } | 201 | } |
242 | 202 | ||
@@ -251,10 +211,6 @@ static void __devinit init_hwif_amd74xx(ide_hwif_t *hwif) | |||
251 | if (!hwif->dma_base) | 211 | if (!hwif->dma_base) |
252 | return; | 212 | return; |
253 | 213 | ||
254 | hwif->ultra_mask = amd_config->udma_mask; | ||
255 | if (amd_config->flags & AMD_BAD_SWDMA) | ||
256 | hwif->swdma_mask = 0x00; | ||
257 | |||
258 | if (hwif->cbl != ATA_CBL_PATA40_SHORT) { | 214 | if (hwif->cbl != ATA_CBL_PATA40_SHORT) { |
259 | if ((amd_80w >> hwif->channel) & 1) | 215 | if ((amd_80w >> hwif->channel) & 1) |
260 | hwif->cbl = ATA_CBL_PATA80; | 216 | hwif->cbl = ATA_CBL_PATA80; |
@@ -272,7 +228,7 @@ static void __devinit init_hwif_amd74xx(ide_hwif_t *hwif) | |||
272 | IDE_HFLAG_UNMASK_IRQS | \ | 228 | IDE_HFLAG_UNMASK_IRQS | \ |
273 | IDE_HFLAG_BOOTABLE) | 229 | IDE_HFLAG_BOOTABLE) |
274 | 230 | ||
275 | #define DECLARE_AMD_DEV(name_str) \ | 231 | #define DECLARE_AMD_DEV(name_str, swdma, udma) \ |
276 | { \ | 232 | { \ |
277 | .name = name_str, \ | 233 | .name = name_str, \ |
278 | .init_chipset = init_chipset_amd74xx, \ | 234 | .init_chipset = init_chipset_amd74xx, \ |
@@ -280,11 +236,12 @@ static void __devinit init_hwif_amd74xx(ide_hwif_t *hwif) | |||
280 | .enablebits = {{0x40,0x02,0x02}, {0x40,0x01,0x01}}, \ | 236 | .enablebits = {{0x40,0x02,0x02}, {0x40,0x01,0x01}}, \ |
281 | .host_flags = IDE_HFLAGS_AMD, \ | 237 | .host_flags = IDE_HFLAGS_AMD, \ |
282 | .pio_mask = ATA_PIO5, \ | 238 | .pio_mask = ATA_PIO5, \ |
283 | .swdma_mask = ATA_SWDMA2, \ | 239 | .swdma_mask = swdma, \ |
284 | .mwdma_mask = ATA_MWDMA2, \ | 240 | .mwdma_mask = ATA_MWDMA2, \ |
241 | .udma_mask = udma, \ | ||
285 | } | 242 | } |
286 | 243 | ||
287 | #define DECLARE_NV_DEV(name_str) \ | 244 | #define DECLARE_NV_DEV(name_str, udma) \ |
288 | { \ | 245 | { \ |
289 | .name = name_str, \ | 246 | .name = name_str, \ |
290 | .init_chipset = init_chipset_amd74xx, \ | 247 | .init_chipset = init_chipset_amd74xx, \ |
@@ -294,45 +251,61 @@ static void __devinit init_hwif_amd74xx(ide_hwif_t *hwif) | |||
294 | .pio_mask = ATA_PIO5, \ | 251 | .pio_mask = ATA_PIO5, \ |
295 | .swdma_mask = ATA_SWDMA2, \ | 252 | .swdma_mask = ATA_SWDMA2, \ |
296 | .mwdma_mask = ATA_MWDMA2, \ | 253 | .mwdma_mask = ATA_MWDMA2, \ |
254 | .udma_mask = udma, \ | ||
297 | } | 255 | } |
298 | 256 | ||
299 | static const struct ide_port_info amd74xx_chipsets[] __devinitdata = { | 257 | static const struct ide_port_info amd74xx_chipsets[] __devinitdata = { |
300 | /* 0 */ DECLARE_AMD_DEV("AMD7401"), | 258 | /* 0 */ DECLARE_AMD_DEV("AMD7401", 0x00, ATA_UDMA2), |
301 | /* 1 */ DECLARE_AMD_DEV("AMD7409"), | 259 | /* 1 */ DECLARE_AMD_DEV("AMD7409", ATA_SWDMA2, ATA_UDMA4), |
302 | /* 2 */ DECLARE_AMD_DEV("AMD7411"), | 260 | /* 2 */ DECLARE_AMD_DEV("AMD7411", ATA_SWDMA2, ATA_UDMA5), |
303 | /* 3 */ DECLARE_AMD_DEV("AMD7441"), | 261 | /* 3 */ DECLARE_AMD_DEV("AMD7441", ATA_SWDMA2, ATA_UDMA5), |
304 | /* 4 */ DECLARE_AMD_DEV("AMD8111"), | 262 | /* 4 */ DECLARE_AMD_DEV("AMD8111", ATA_SWDMA2, ATA_UDMA6), |
305 | 263 | ||
306 | /* 5 */ DECLARE_NV_DEV("NFORCE"), | 264 | /* 5 */ DECLARE_NV_DEV("NFORCE", ATA_UDMA5), |
307 | /* 6 */ DECLARE_NV_DEV("NFORCE2"), | 265 | /* 6 */ DECLARE_NV_DEV("NFORCE2", ATA_UDMA6), |
308 | /* 7 */ DECLARE_NV_DEV("NFORCE2-U400R"), | 266 | /* 7 */ DECLARE_NV_DEV("NFORCE2-U400R", ATA_UDMA6), |
309 | /* 8 */ DECLARE_NV_DEV("NFORCE2-U400R-SATA"), | 267 | /* 8 */ DECLARE_NV_DEV("NFORCE2-U400R-SATA", ATA_UDMA6), |
310 | /* 9 */ DECLARE_NV_DEV("NFORCE3-150"), | 268 | /* 9 */ DECLARE_NV_DEV("NFORCE3-150", ATA_UDMA6), |
311 | /* 10 */ DECLARE_NV_DEV("NFORCE3-250"), | 269 | /* 10 */ DECLARE_NV_DEV("NFORCE3-250", ATA_UDMA6), |
312 | /* 11 */ DECLARE_NV_DEV("NFORCE3-250-SATA"), | 270 | /* 11 */ DECLARE_NV_DEV("NFORCE3-250-SATA", ATA_UDMA6), |
313 | /* 12 */ DECLARE_NV_DEV("NFORCE3-250-SATA2"), | 271 | /* 12 */ DECLARE_NV_DEV("NFORCE3-250-SATA2", ATA_UDMA6), |
314 | /* 13 */ DECLARE_NV_DEV("NFORCE-CK804"), | 272 | /* 13 */ DECLARE_NV_DEV("NFORCE-CK804", ATA_UDMA6), |
315 | /* 14 */ DECLARE_NV_DEV("NFORCE-MCP04"), | 273 | /* 14 */ DECLARE_NV_DEV("NFORCE-MCP04", ATA_UDMA6), |
316 | /* 15 */ DECLARE_NV_DEV("NFORCE-MCP51"), | 274 | /* 15 */ DECLARE_NV_DEV("NFORCE-MCP51", ATA_UDMA6), |
317 | /* 16 */ DECLARE_NV_DEV("NFORCE-MCP55"), | 275 | /* 16 */ DECLARE_NV_DEV("NFORCE-MCP55", ATA_UDMA6), |
318 | /* 17 */ DECLARE_NV_DEV("NFORCE-MCP61"), | 276 | /* 17 */ DECLARE_NV_DEV("NFORCE-MCP61", ATA_UDMA6), |
319 | /* 18 */ DECLARE_NV_DEV("NFORCE-MCP65"), | 277 | /* 18 */ DECLARE_NV_DEV("NFORCE-MCP65", ATA_UDMA6), |
320 | /* 19 */ DECLARE_NV_DEV("NFORCE-MCP67"), | 278 | /* 19 */ DECLARE_NV_DEV("NFORCE-MCP67", ATA_UDMA6), |
321 | /* 20 */ DECLARE_NV_DEV("NFORCE-MCP73"), | 279 | /* 20 */ DECLARE_NV_DEV("NFORCE-MCP73", ATA_UDMA6), |
322 | /* 21 */ DECLARE_NV_DEV("NFORCE-MCP77"), | 280 | /* 21 */ DECLARE_NV_DEV("NFORCE-MCP77", ATA_UDMA6), |
323 | /* 22 */ DECLARE_AMD_DEV("AMD5536"), | 281 | |
282 | /* 22 */ DECLARE_AMD_DEV("AMD5536", ATA_SWDMA2, ATA_UDMA5), | ||
324 | }; | 283 | }; |
325 | 284 | ||
326 | static int __devinit amd74xx_probe(struct pci_dev *dev, const struct pci_device_id *id) | 285 | static int __devinit amd74xx_probe(struct pci_dev *dev, const struct pci_device_id *id) |
327 | { | 286 | { |
328 | amd_chipset = amd74xx_chipsets + id->driver_data; | 287 | struct ide_port_info d; |
329 | amd_config = amd_ide_chips + id->driver_data; | 288 | u8 idx = id->driver_data; |
330 | if (dev->device != amd_config->id) { | 289 | |
331 | printk(KERN_ERR "%s: assertion 0x%02x == 0x%02x failed !\n", | 290 | d = amd74xx_chipsets[idx]; |
332 | pci_name(dev), dev->device, amd_config->id); | 291 | |
333 | return -ENODEV; | 292 | /* |
293 | * Check for bad SWDMA and incorrectly wired Serenade mainboards. | ||
294 | */ | ||
295 | if (idx == 1) { | ||
296 | if (dev->revision <= 7) | ||
297 | d.swdma_mask = 0; | ||
298 | } else if (idx == 4) { | ||
299 | if (dev->subsystem_vendor == PCI_VENDOR_ID_AMD && | ||
300 | dev->subsystem_device == PCI_DEVICE_ID_AMD_SERENADE) | ||
301 | d.udma_mask = ATA_UDMA5; | ||
334 | } | 302 | } |
335 | return ide_setup_pci_device(dev, amd_chipset); | 303 | |
304 | printk(KERN_INFO "%s: %s (rev %02x) UDMA%s controller\n", | ||
305 | d.name, pci_name(dev), dev->revision, | ||
306 | amd_dma[fls(d.udma_mask) - 1]); | ||
307 | |||
308 | return ide_setup_pci_device(dev, &d); | ||
336 | } | 309 | } |
337 | 310 | ||
338 | static const struct pci_device_id amd74xx_pci_tbl[] = { | 311 | static const struct pci_device_id amd74xx_pci_tbl[] = { |