diff options
author | Jeff Garzik <jgarzik@pobox.com> | 2005-11-12 21:13:17 -0500 |
---|---|---|
committer | Jeff Garzik <jgarzik@pobox.com> | 2005-11-12 21:13:17 -0500 |
commit | 47c2b677daeed9c79ecb7167c211ff36876ea611 (patch) | |
tree | 36bafb9418bde1aebb305560ca6c574ba49783b9 /drivers/scsi/sata_mv.c | |
parent | ba3fe8fb6a469390a14379519915f3c39a973d99 (diff) |
[libata sata_mv] mv_hw_ops for hardware families; new errata
- eliminate a bunch of redundant tests by creating a per-chip-family
set of hooks, mv_hw_ops
- implement more errata, from newer Marvell GPL'd driver
Diffstat (limited to 'drivers/scsi/sata_mv.c')
-rw-r--r-- | drivers/scsi/sata_mv.c | 296 |
1 files changed, 158 insertions, 138 deletions
diff --git a/drivers/scsi/sata_mv.c b/drivers/scsi/sata_mv.c index 9d116d00273d..4ca4b35d0022 100644 --- a/drivers/scsi/sata_mv.c +++ b/drivers/scsi/sata_mv.c | |||
@@ -83,16 +83,15 @@ enum { | |||
83 | /* Host Flags */ | 83 | /* Host Flags */ |
84 | MV_FLAG_DUAL_HC = (1 << 30), /* two SATA Host Controllers */ | 84 | MV_FLAG_DUAL_HC = (1 << 30), /* two SATA Host Controllers */ |
85 | MV_FLAG_IRQ_COALESCE = (1 << 29), /* IRQ coalescing capability */ | 85 | MV_FLAG_IRQ_COALESCE = (1 << 29), /* IRQ coalescing capability */ |
86 | MV_FLAG_GLBL_SFT_RST = (1 << 28), /* Global Soft Reset support */ | ||
87 | MV_COMMON_FLAGS = (ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | | 86 | MV_COMMON_FLAGS = (ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | |
88 | ATA_FLAG_SATA_RESET | ATA_FLAG_MMIO), | 87 | ATA_FLAG_SATA_RESET | ATA_FLAG_MMIO), |
89 | MV_6XXX_FLAGS = (MV_FLAG_IRQ_COALESCE | | 88 | MV_6XXX_FLAGS = MV_FLAG_IRQ_COALESCE, |
90 | MV_FLAG_GLBL_SFT_RST), | ||
91 | 89 | ||
92 | chip_504x = 0, | 90 | chip_504x = 0, |
93 | chip_508x = 1, | 91 | chip_508x = 1, |
94 | chip_604x = 2, | 92 | chip_5080 = 2, |
95 | chip_608x = 3, | 93 | chip_604x = 3, |
94 | chip_608x = 4, | ||
96 | 95 | ||
97 | CRQB_FLAG_READ = (1 << 0), | 96 | CRQB_FLAG_READ = (1 << 0), |
98 | CRQB_TAG_SHIFT = 1, | 97 | CRQB_TAG_SHIFT = 1, |
@@ -150,6 +149,7 @@ enum { | |||
150 | /* SATA registers */ | 149 | /* SATA registers */ |
151 | SATA_STATUS_OFS = 0x300, /* ctrl, err regs follow status */ | 150 | SATA_STATUS_OFS = 0x300, /* ctrl, err regs follow status */ |
152 | SATA_ACTIVE_OFS = 0x350, | 151 | SATA_ACTIVE_OFS = 0x350, |
152 | PHY_MODE3 = 0x310, | ||
153 | PHY_MODE4 = 0x314, | 153 | PHY_MODE4 = 0x314, |
154 | PHY_MODE2 = 0x330, | 154 | PHY_MODE2 = 0x330, |
155 | SATA_INTERFACE_CTL = 0x050, | 155 | SATA_INTERFACE_CTL = 0x050, |
@@ -209,23 +209,20 @@ enum { | |||
209 | ATA_RST = (1 << 2), | 209 | ATA_RST = (1 << 2), |
210 | 210 | ||
211 | EDMA_ARB_CFG = 0x38, | 211 | EDMA_ARB_CFG = 0x38, |
212 | EDMA_NO_SNOOP = (1 << 6), | ||
213 | 212 | ||
214 | /* Host private flags (hp_flags) */ | 213 | /* Host private flags (hp_flags) */ |
215 | MV_HP_FLAG_MSI = (1 << 0), | 214 | MV_HP_FLAG_MSI = (1 << 0), |
216 | MV_HP_ERRATA_60X1A1 = (1 << 1), | 215 | MV_HP_ERRATA_50XXB0 = (1 << 1), |
217 | MV_HP_ERRATA_60X1B0 = (1 << 2), | 216 | MV_HP_ERRATA_50XXB2 = (1 << 2), |
218 | MV_HP_ERRATA_50XXB0 = (1 << 3), | 217 | MV_HP_ERRATA_60X1B2 = (1 << 3), |
219 | MV_HP_ERRATA_50XXB1 = (1 << 4), | 218 | MV_HP_ERRATA_60X1C0 = (1 << 4), |
220 | MV_HP_ERRATA_50XXB2 = (1 << 5), | 219 | MV_HP_50XX = (1 << 5), |
221 | MV_HP_50XX = (1 << 6), | ||
222 | 220 | ||
223 | /* Port private flags (pp_flags) */ | 221 | /* Port private flags (pp_flags) */ |
224 | MV_PP_FLAG_EDMA_EN = (1 << 0), | 222 | MV_PP_FLAG_EDMA_EN = (1 << 0), |
225 | MV_PP_FLAG_EDMA_DS_ACT = (1 << 1), | 223 | MV_PP_FLAG_EDMA_DS_ACT = (1 << 1), |
226 | }; | 224 | }; |
227 | 225 | ||
228 | #define IS_50XX(hpriv) ((hpriv)->hp_flags & MV_HP_50XX) | ||
229 | #define IS_60XX(hpriv) (((hpriv)->hp_flags & MV_HP_50XX) == 0) | 226 | #define IS_60XX(hpriv) (((hpriv)->hp_flags & MV_HP_50XX) == 0) |
230 | 227 | ||
231 | enum { | 228 | enum { |
@@ -280,9 +277,19 @@ struct mv_port_signal { | |||
280 | u32 pre; | 277 | u32 pre; |
281 | }; | 278 | }; |
282 | 279 | ||
280 | struct mv_host_priv; | ||
281 | struct mv_hw_ops { | ||
282 | void (*phy_errata)(struct ata_port *ap); | ||
283 | void (*enable_leds)(struct mv_host_priv *hpriv, void __iomem *mmio); | ||
284 | void (*read_preamp)(struct mv_host_priv *hpriv, int idx, | ||
285 | void __iomem *mmio); | ||
286 | int (*reset_hc)(struct mv_host_priv *hpriv, void __iomem *mmio); | ||
287 | }; | ||
288 | |||
283 | struct mv_host_priv { | 289 | struct mv_host_priv { |
284 | u32 hp_flags; | 290 | u32 hp_flags; |
285 | struct mv_port_signal signal[8]; | 291 | struct mv_port_signal signal[8]; |
292 | const struct mv_hw_ops *ops; | ||
286 | }; | 293 | }; |
287 | 294 | ||
288 | static void mv_irq_clear(struct ata_port *ap); | 295 | static void mv_irq_clear(struct ata_port *ap); |
@@ -299,6 +306,18 @@ static irqreturn_t mv_interrupt(int irq, void *dev_instance, | |||
299 | static void mv_eng_timeout(struct ata_port *ap); | 306 | static void mv_eng_timeout(struct ata_port *ap); |
300 | static int mv_init_one(struct pci_dev *pdev, const struct pci_device_id *ent); | 307 | static int mv_init_one(struct pci_dev *pdev, const struct pci_device_id *ent); |
301 | 308 | ||
309 | static void mv5_phy_errata(struct ata_port *ap); | ||
310 | static void mv5_enable_leds(struct mv_host_priv *hpriv, void __iomem *mmio); | ||
311 | static void mv5_read_preamp(struct mv_host_priv *hpriv, int idx, | ||
312 | void __iomem *mmio); | ||
313 | static int mv5_reset_hc(struct mv_host_priv *hpriv, void __iomem *mmio); | ||
314 | |||
315 | static void mv6_phy_errata(struct ata_port *ap); | ||
316 | static void mv6_enable_leds(struct mv_host_priv *hpriv, void __iomem *mmio); | ||
317 | static void mv6_read_preamp(struct mv_host_priv *hpriv, int idx, | ||
318 | void __iomem *mmio); | ||
319 | static int mv6_reset_hc(struct mv_host_priv *hpriv, void __iomem *mmio); | ||
320 | |||
302 | static struct scsi_host_template mv_sht = { | 321 | static struct scsi_host_template mv_sht = { |
303 | .module = THIS_MODULE, | 322 | .module = THIS_MODULE, |
304 | .name = DRV_NAME, | 323 | .name = DRV_NAME, |
@@ -361,6 +380,13 @@ static struct ata_port_info mv_port_info[] = { | |||
361 | .udma_mask = 0, /* 0x7f (udma0-6 disabled for now) */ | 380 | .udma_mask = 0, /* 0x7f (udma0-6 disabled for now) */ |
362 | .port_ops = &mv_ops, | 381 | .port_ops = &mv_ops, |
363 | }, | 382 | }, |
383 | { /* chip_5080 */ | ||
384 | .sht = &mv_sht, | ||
385 | .host_flags = (MV_COMMON_FLAGS | MV_FLAG_DUAL_HC), | ||
386 | .pio_mask = 0x1f, /* pio0-4 */ | ||
387 | .udma_mask = 0, /* 0x7f (udma0-6 disabled for now) */ | ||
388 | .port_ops = &mv_ops, | ||
389 | }, | ||
364 | { /* chip_604x */ | 390 | { /* chip_604x */ |
365 | .sht = &mv_sht, | 391 | .sht = &mv_sht, |
366 | .host_flags = (MV_COMMON_FLAGS | MV_6XXX_FLAGS), | 392 | .host_flags = (MV_COMMON_FLAGS | MV_6XXX_FLAGS), |
@@ -382,7 +408,7 @@ static const struct pci_device_id mv_pci_tbl[] = { | |||
382 | #if 0 /* unusably broken right now */ | 408 | #if 0 /* unusably broken right now */ |
383 | {PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x5040), 0, 0, chip_504x}, | 409 | {PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x5040), 0, 0, chip_504x}, |
384 | {PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x5041), 0, 0, chip_504x}, | 410 | {PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x5041), 0, 0, chip_504x}, |
385 | {PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x5080), 0, 0, chip_508x}, | 411 | {PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x5080), 0, 0, chip_5080}, |
386 | {PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x5081), 0, 0, chip_508x}, | 412 | {PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x5081), 0, 0, chip_508x}, |
387 | #endif | 413 | #endif |
388 | 414 | ||
@@ -402,6 +428,20 @@ static struct pci_driver mv_pci_driver = { | |||
402 | .remove = ata_pci_remove_one, | 428 | .remove = ata_pci_remove_one, |
403 | }; | 429 | }; |
404 | 430 | ||
431 | static const struct mv_hw_ops mv5xxx_ops = { | ||
432 | .phy_errata = mv5_phy_errata, | ||
433 | .enable_leds = mv5_enable_leds, | ||
434 | .read_preamp = mv5_read_preamp, | ||
435 | .reset_hc = mv5_reset_hc, | ||
436 | }; | ||
437 | |||
438 | static const struct mv_hw_ops mv6xxx_ops = { | ||
439 | .phy_errata = mv6_phy_errata, | ||
440 | .enable_leds = mv6_enable_leds, | ||
441 | .read_preamp = mv6_read_preamp, | ||
442 | .reset_hc = mv6_reset_hc, | ||
443 | }; | ||
444 | |||
405 | /* | 445 | /* |
406 | * Functions | 446 | * Functions |
407 | */ | 447 | */ |
@@ -624,9 +664,9 @@ static void mv_scr_write(struct ata_port *ap, unsigned int sc_reg_in, u32 val) | |||
624 | * LOCKING: | 664 | * LOCKING: |
625 | * Inherited from caller. | 665 | * Inherited from caller. |
626 | */ | 666 | */ |
627 | static int mv_global_soft_reset(void __iomem *mmio_base) | 667 | static int mv6_reset_hc(struct mv_host_priv *hpriv, void __iomem *mmio) |
628 | { | 668 | { |
629 | void __iomem *reg = mmio_base + PCI_MAIN_CMD_STS_OFS; | 669 | void __iomem *reg = mmio + PCI_MAIN_CMD_STS_OFS; |
630 | int i, rc = 0; | 670 | int i, rc = 0; |
631 | u32 t; | 671 | u32 t; |
632 | 672 | ||
@@ -721,7 +761,6 @@ static inline void mv_priv_free(struct mv_port_priv *pp, struct device *dev) | |||
721 | static int mv_port_start(struct ata_port *ap) | 761 | static int mv_port_start(struct ata_port *ap) |
722 | { | 762 | { |
723 | struct device *dev = ap->host_set->dev; | 763 | struct device *dev = ap->host_set->dev; |
724 | struct mv_host_priv *hpriv = ap->host_set->private_data; | ||
725 | struct mv_port_priv *pp; | 764 | struct mv_port_priv *pp; |
726 | void __iomem *port_mmio = mv_ap_base(ap); | 765 | void __iomem *port_mmio = mv_ap_base(ap); |
727 | void *mem; | 766 | void *mem; |
@@ -779,15 +818,6 @@ static int mv_port_start(struct ata_port *ap) | |||
779 | writelfl(pp->crpb_dma & EDMA_RSP_Q_BASE_LO_MASK, | 818 | writelfl(pp->crpb_dma & EDMA_RSP_Q_BASE_LO_MASK, |
780 | port_mmio + EDMA_RSP_Q_OUT_PTR_OFS); | 819 | port_mmio + EDMA_RSP_Q_OUT_PTR_OFS); |
781 | 820 | ||
782 | if (hpriv->hp_flags & MV_HP_ERRATA_60X1A1) { | ||
783 | u32 new_tmp, tmp; | ||
784 | |||
785 | new_tmp = tmp = readl(port_mmio + EDMA_ARB_CFG); | ||
786 | new_tmp &= ~EDMA_NO_SNOOP; | ||
787 | if (new_tmp != tmp) | ||
788 | writel(new_tmp, port_mmio + EDMA_ARB_CFG); | ||
789 | } | ||
790 | |||
791 | pp->req_producer = pp->rsp_consumer = 0; | 821 | pp->req_producer = pp->rsp_consumer = 0; |
792 | 822 | ||
793 | /* Don't turn on EDMA here...do it before DMA commands only. Else | 823 | /* Don't turn on EDMA here...do it before DMA commands only. Else |
@@ -1243,39 +1273,37 @@ static irqreturn_t mv_interrupt(int irq, void *dev_instance, | |||
1243 | return IRQ_RETVAL(handled); | 1273 | return IRQ_RETVAL(handled); |
1244 | } | 1274 | } |
1245 | 1275 | ||
1246 | static void mv_cfg_signal5(struct mv_host_priv *hpriv, int idx, | 1276 | static void mv5_read_preamp(struct mv_host_priv *hpriv, int idx, |
1247 | void __iomem *mmio) | 1277 | void __iomem *mmio) |
1248 | { | 1278 | { |
1249 | /* FIXME */ | 1279 | /* FIXME */ |
1250 | } | 1280 | } |
1251 | 1281 | ||
1252 | static void mv_enable_leds5(struct mv_host_priv *hpriv, void __iomem *mmio) | 1282 | static void mv5_enable_leds(struct mv_host_priv *hpriv, void __iomem *mmio) |
1253 | { | 1283 | { |
1254 | /* FIXME */ | 1284 | /* FIXME */ |
1255 | } | 1285 | } |
1256 | 1286 | ||
1257 | static void mv_phy_errata5(struct ata_port *ap) | 1287 | static void mv5_phy_errata(struct ata_port *ap) |
1258 | { | 1288 | { |
1259 | /* FIXME */ | 1289 | /* FIXME */ |
1260 | } | 1290 | } |
1261 | 1291 | ||
1262 | static void mv_cfg_signal6(struct mv_host_priv *hpriv, int idx, | 1292 | static int mv5_reset_hc(struct mv_host_priv *hpriv, void __iomem *mmio) |
1293 | { | ||
1294 | /* FIXME */ | ||
1295 | return 1; | ||
1296 | } | ||
1297 | |||
1298 | static void mv6_read_preamp(struct mv_host_priv *hpriv, int idx, | ||
1263 | void __iomem *mmio) | 1299 | void __iomem *mmio) |
1264 | { | 1300 | { |
1265 | void __iomem *port_mmio; | 1301 | void __iomem *port_mmio; |
1266 | u32 tmp; | 1302 | u32 tmp; |
1267 | 1303 | ||
1268 | if (hpriv->hp_flags & MV_HP_ERRATA_60X1A1) { | ||
1269 | hpriv->signal[idx].amps = 0x5 << 8; | ||
1270 | hpriv->signal[idx].pre = 0x3 << 5; | ||
1271 | return; | ||
1272 | } | ||
1273 | |||
1274 | assert (hpriv->hp_flags & MV_HP_ERRATA_60X1B0); | ||
1275 | |||
1276 | tmp = readl(mmio + MV_RESET_CFG); | 1304 | tmp = readl(mmio + MV_RESET_CFG); |
1277 | if ((tmp & (1 << 0)) == 0) { | 1305 | if ((tmp & (1 << 0)) == 0) { |
1278 | hpriv->signal[idx].amps = 0x4 << 8; | 1306 | hpriv->signal[idx].amps = 0x7 << 8; |
1279 | hpriv->signal[idx].pre = 0x1 << 5; | 1307 | hpriv->signal[idx].pre = 0x1 << 5; |
1280 | return; | 1308 | return; |
1281 | } | 1309 | } |
@@ -1287,34 +1315,57 @@ static void mv_cfg_signal6(struct mv_host_priv *hpriv, int idx, | |||
1287 | hpriv->signal[idx].pre = tmp & 0xe0; /* bits 7:5 */ | 1315 | hpriv->signal[idx].pre = tmp & 0xe0; /* bits 7:5 */ |
1288 | } | 1316 | } |
1289 | 1317 | ||
1290 | static void mv_enable_leds6(struct mv_host_priv *hpriv, void __iomem *mmio) | 1318 | static void mv6_enable_leds(struct mv_host_priv *hpriv, void __iomem *mmio) |
1291 | { | 1319 | { |
1292 | if (hpriv->hp_flags & MV_HP_ERRATA_60X1A1) | 1320 | writel(0x00000060, mmio + MV_GPIO_PORT_CTL); |
1293 | writel(0x00020060, mmio + MV_GPIO_PORT_CTL); | ||
1294 | |||
1295 | else if (hpriv->hp_flags & MV_HP_ERRATA_60X1B0) | ||
1296 | writel(0x00000060, mmio + MV_GPIO_PORT_CTL); | ||
1297 | } | 1321 | } |
1298 | 1322 | ||
1299 | static void mv_phy_errata6(struct ata_port *ap) | 1323 | static void mv6_phy_errata(struct ata_port *ap) |
1300 | { | 1324 | { |
1301 | struct mv_host_priv *hpriv = ap->host_set->private_data; | 1325 | struct mv_host_priv *hpriv = ap->host_set->private_data; |
1302 | u32 hp_flags = hpriv->hp_flags; | 1326 | u32 hp_flags = hpriv->hp_flags; |
1303 | void __iomem *port_mmio = mv_ap_base(ap); | 1327 | void __iomem *port_mmio = mv_ap_base(ap); |
1328 | int fix_phy_mode2 = | ||
1329 | hp_flags & (MV_HP_ERRATA_60X1B2 | MV_HP_ERRATA_60X1C0); | ||
1304 | int fix_phy_mode4 = | 1330 | int fix_phy_mode4 = |
1305 | hp_flags & (MV_HP_ERRATA_60X1A1 | MV_HP_ERRATA_60X1B0); | 1331 | hp_flags & (MV_HP_ERRATA_60X1B2 | MV_HP_ERRATA_60X1C0); |
1306 | u32 m2; | 1332 | u32 m2, tmp; |
1333 | |||
1334 | if (fix_phy_mode2) { | ||
1335 | m2 = readl(port_mmio + PHY_MODE2); | ||
1336 | m2 &= ~(1 << 16); | ||
1337 | m2 |= (1 << 31); | ||
1338 | writel(m2, port_mmio + PHY_MODE2); | ||
1339 | |||
1340 | udelay(200); | ||
1341 | |||
1342 | m2 = readl(port_mmio + PHY_MODE2); | ||
1343 | m2 &= ~((1 << 16) | (1 << 31)); | ||
1344 | writel(m2, port_mmio + PHY_MODE2); | ||
1345 | |||
1346 | udelay(200); | ||
1347 | } | ||
1348 | |||
1349 | /* who knows what this magic does */ | ||
1350 | tmp = readl(port_mmio + PHY_MODE3); | ||
1351 | tmp &= ~0x7F800000; | ||
1352 | tmp |= 0x2A800000; | ||
1353 | writel(tmp, port_mmio + PHY_MODE3); | ||
1307 | 1354 | ||
1308 | if (fix_phy_mode4) { | 1355 | if (fix_phy_mode4) { |
1309 | u32 tmp, m4; | 1356 | u32 m4; |
1310 | 1357 | ||
1311 | m4 = readl(port_mmio + PHY_MODE4); | 1358 | m4 = readl(port_mmio + PHY_MODE4); |
1312 | tmp = readl(port_mmio + 0x310); | 1359 | |
1360 | if (hp_flags & MV_HP_ERRATA_60X1B2) | ||
1361 | tmp = readl(port_mmio + 0x310); | ||
1313 | 1362 | ||
1314 | m4 = (m4 & ~(1 << 1)) | (1 << 0); | 1363 | m4 = (m4 & ~(1 << 1)) | (1 << 0); |
1315 | 1364 | ||
1316 | writel(m4, port_mmio + PHY_MODE4); | 1365 | writel(m4, port_mmio + PHY_MODE4); |
1317 | writel(tmp, port_mmio + 0x310); | 1366 | |
1367 | if (hp_flags & MV_HP_ERRATA_60X1B2) | ||
1368 | writel(tmp, port_mmio + 0x310); | ||
1318 | } | 1369 | } |
1319 | 1370 | ||
1320 | /* Revert values of pre-emphasis and signal amps to the saved ones */ | 1371 | /* Revert values of pre-emphasis and signal amps to the saved ones */ |
@@ -1323,20 +1374,11 @@ static void mv_phy_errata6(struct ata_port *ap) | |||
1323 | m2 &= ~MV_M2_PREAMP_MASK; | 1374 | m2 &= ~MV_M2_PREAMP_MASK; |
1324 | m2 |= hpriv->signal[ap->port_no].amps; | 1375 | m2 |= hpriv->signal[ap->port_no].amps; |
1325 | m2 |= hpriv->signal[ap->port_no].pre; | 1376 | m2 |= hpriv->signal[ap->port_no].pre; |
1377 | m2 &= ~(1 << 16); | ||
1326 | 1378 | ||
1327 | writel(m2, port_mmio + PHY_MODE2); | 1379 | writel(m2, port_mmio + PHY_MODE2); |
1328 | } | 1380 | } |
1329 | 1381 | ||
1330 | static void mv_phy_errata(struct ata_port *ap) | ||
1331 | { | ||
1332 | struct mv_host_priv *hpriv = ap->host_set->private_data; | ||
1333 | |||
1334 | if (IS_50XX(hpriv)) | ||
1335 | mv_phy_errata5(ap); | ||
1336 | else | ||
1337 | mv_phy_errata6(ap); | ||
1338 | } | ||
1339 | |||
1340 | /** | 1382 | /** |
1341 | * mv_phy_reset - Perform eDMA reset followed by COMRESET | 1383 | * mv_phy_reset - Perform eDMA reset followed by COMRESET |
1342 | * @ap: ATA channel to manipulate | 1384 | * @ap: ATA channel to manipulate |
@@ -1376,7 +1418,7 @@ static void mv_phy_reset(struct ata_port *ap) | |||
1376 | */ | 1418 | */ |
1377 | writelfl(0, port_mmio + EDMA_CMD_OFS); | 1419 | writelfl(0, port_mmio + EDMA_CMD_OFS); |
1378 | 1420 | ||
1379 | mv_phy_errata(ap); | 1421 | hpriv->ops->phy_errata(ap); |
1380 | 1422 | ||
1381 | DPRINTK("S-regs after ATA_RST: SStat 0x%08x SErr 0x%08x " | 1423 | DPRINTK("S-regs after ATA_RST: SStat 0x%08x SErr 0x%08x " |
1382 | "SCtrl 0x%08x\n", mv_scr_read(ap, SCR_STATUS), | 1424 | "SCtrl 0x%08x\n", mv_scr_read(ap, SCR_STATUS), |
@@ -1521,15 +1563,7 @@ static void mv_port_init(struct ata_ioports *port, void __iomem *port_mmio) | |||
1521 | readl(port_mmio + EDMA_ERR_IRQ_MASK_OFS)); | 1563 | readl(port_mmio + EDMA_ERR_IRQ_MASK_OFS)); |
1522 | } | 1564 | } |
1523 | 1565 | ||
1524 | static void mv_enable_leds(struct mv_host_priv *hpriv, void __iomem *mmio) | 1566 | static int mv_chip_id(struct pci_dev *pdev, struct mv_host_priv *hpriv, |
1525 | { | ||
1526 | if (IS_50XX(hpriv)) | ||
1527 | mv_enable_leds5(hpriv, mmio); | ||
1528 | else | ||
1529 | mv_enable_leds6(hpriv, mmio); | ||
1530 | } | ||
1531 | |||
1532 | static int mv_cfg_errata(struct pci_dev *pdev, struct mv_host_priv *hpriv, | ||
1533 | unsigned int board_idx) | 1567 | unsigned int board_idx) |
1534 | { | 1568 | { |
1535 | u8 rev_id; | 1569 | u8 rev_id; |
@@ -1538,70 +1572,60 @@ static int mv_cfg_errata(struct pci_dev *pdev, struct mv_host_priv *hpriv, | |||
1538 | pci_read_config_byte(pdev, PCI_REVISION_ID, &rev_id); | 1572 | pci_read_config_byte(pdev, PCI_REVISION_ID, &rev_id); |
1539 | 1573 | ||
1540 | switch(board_idx) { | 1574 | switch(board_idx) { |
1575 | case chip_5080: | ||
1576 | hpriv->ops = &mv5xxx_ops; | ||
1577 | hp_flags |= MV_HP_50XX; | ||
1578 | |||
1579 | switch (rev_id) { | ||
1580 | case 0x1: | ||
1581 | hp_flags |= MV_HP_ERRATA_50XXB0; | ||
1582 | break; | ||
1583 | case 0x3: | ||
1584 | hp_flags |= MV_HP_ERRATA_50XXB2; | ||
1585 | break; | ||
1586 | default: | ||
1587 | dev_printk(KERN_WARNING, &pdev->dev, | ||
1588 | "Applying 50XXB2 workarounds to unknown rev\n"); | ||
1589 | hp_flags |= MV_HP_ERRATA_50XXB2; | ||
1590 | break; | ||
1591 | } | ||
1592 | break; | ||
1593 | |||
1541 | case chip_504x: | 1594 | case chip_504x: |
1542 | case chip_508x: | 1595 | case chip_508x: |
1596 | hpriv->ops = &mv5xxx_ops; | ||
1543 | hp_flags |= MV_HP_50XX; | 1597 | hp_flags |= MV_HP_50XX; |
1544 | 1598 | ||
1545 | if (pdev->device == 0x5080) { | 1599 | switch (rev_id) { |
1546 | switch (rev_id) { | 1600 | case 0x0: |
1547 | case 0x0: | 1601 | hp_flags |= MV_HP_ERRATA_50XXB0; |
1548 | dev_printk(KERN_WARNING, &pdev->dev, | 1602 | break; |
1549 | "Applying B0 workarounds to unknown rev 0\n"); | 1603 | case 0x3: |
1550 | /* fall through */ | 1604 | hp_flags |= MV_HP_ERRATA_50XXB2; |
1551 | case 0x1: | 1605 | break; |
1552 | hp_flags |= MV_HP_ERRATA_50XXB0; | 1606 | default: |
1553 | break; | 1607 | dev_printk(KERN_WARNING, &pdev->dev, |
1554 | case 0x2: | 1608 | "Applying B2 workarounds to unknown rev\n"); |
1555 | hp_flags |= MV_HP_ERRATA_50XXB1; | 1609 | hp_flags |= MV_HP_ERRATA_50XXB2; |
1556 | break; | 1610 | break; |
1557 | case 0x3: | ||
1558 | hp_flags |= MV_HP_ERRATA_50XXB2; | ||
1559 | break; | ||
1560 | default: | ||
1561 | dev_printk(KERN_WARNING, &pdev->dev, | ||
1562 | "Applying B2 workarounds to future rev\n"); | ||
1563 | hp_flags |= MV_HP_ERRATA_50XXB2; | ||
1564 | break; | ||
1565 | } | ||
1566 | } else { | ||
1567 | switch (rev_id) { | ||
1568 | case 0x0: | ||
1569 | hp_flags |= MV_HP_ERRATA_50XXB0; | ||
1570 | break; | ||
1571 | case 0x1: | ||
1572 | dev_printk(KERN_WARNING, &pdev->dev, | ||
1573 | "Applying B1 workarounds to unknown rev 1\n"); | ||
1574 | /* fall through */ | ||
1575 | case 0x2: | ||
1576 | hp_flags |= MV_HP_ERRATA_50XXB1; | ||
1577 | break; | ||
1578 | default: | ||
1579 | dev_printk(KERN_WARNING, &pdev->dev, | ||
1580 | "Applying B2 workarounds to future rev\n"); | ||
1581 | /* fall through */ | ||
1582 | case 0x3: | ||
1583 | hp_flags |= MV_HP_ERRATA_50XXB2; | ||
1584 | break; | ||
1585 | } | ||
1586 | } | 1611 | } |
1587 | break; | 1612 | break; |
1588 | 1613 | ||
1589 | case chip_604x: | 1614 | case chip_604x: |
1590 | case chip_608x: | 1615 | case chip_608x: |
1616 | hpriv->ops = &mv6xxx_ops; | ||
1617 | |||
1591 | switch (rev_id) { | 1618 | switch (rev_id) { |
1592 | case 0x0: | 1619 | case 0x7: |
1593 | dev_printk(KERN_WARNING, &pdev->dev, | 1620 | hp_flags |= MV_HP_ERRATA_60X1B2; |
1594 | "Applying A1 workarounds to unknown rev 0\n"); | 1621 | break; |
1595 | /* fall through */ | 1622 | case 0x9: |
1596 | case 0x1: | 1623 | hp_flags |= MV_HP_ERRATA_60X1C0; |
1597 | hp_flags |= MV_HP_ERRATA_60X1A1; | ||
1598 | break; | 1624 | break; |
1599 | default: | 1625 | default: |
1600 | dev_printk(KERN_WARNING, &pdev->dev, | 1626 | dev_printk(KERN_WARNING, &pdev->dev, |
1601 | "Applying B0 workarounds to future rev\n"); | 1627 | "Applying B2 workarounds to unknown rev\n"); |
1602 | /* fall through */ | 1628 | hp_flags |= MV_HP_ERRATA_60X1B2; |
1603 | case 0x2: | ||
1604 | hp_flags |= MV_HP_ERRATA_60X1B0; | ||
1605 | break; | 1629 | break; |
1606 | } | 1630 | } |
1607 | break; | 1631 | break; |
@@ -1617,7 +1641,7 @@ static int mv_cfg_errata(struct pci_dev *pdev, struct mv_host_priv *hpriv, | |||
1617 | } | 1641 | } |
1618 | 1642 | ||
1619 | /** | 1643 | /** |
1620 | * mv_host_init - Perform some early initialization of the host. | 1644 | * mv_init_host - Perform some early initialization of the host. |
1621 | * @pdev: host PCI device | 1645 | * @pdev: host PCI device |
1622 | * @probe_ent: early data struct representing the host | 1646 | * @probe_ent: early data struct representing the host |
1623 | * | 1647 | * |
@@ -1627,7 +1651,7 @@ static int mv_cfg_errata(struct pci_dev *pdev, struct mv_host_priv *hpriv, | |||
1627 | * LOCKING: | 1651 | * LOCKING: |
1628 | * Inherited from caller. | 1652 | * Inherited from caller. |
1629 | */ | 1653 | */ |
1630 | static int mv_host_init(struct pci_dev *pdev, struct ata_probe_ent *probe_ent, | 1654 | static int mv_init_host(struct pci_dev *pdev, struct ata_probe_ent *probe_ent, |
1631 | unsigned int board_idx) | 1655 | unsigned int board_idx) |
1632 | { | 1656 | { |
1633 | int rc = 0, n_hc, port, hc; | 1657 | int rc = 0, n_hc, port, hc; |
@@ -1635,28 +1659,24 @@ static int mv_host_init(struct pci_dev *pdev, struct ata_probe_ent *probe_ent, | |||
1635 | void __iomem *port_mmio; | 1659 | void __iomem *port_mmio; |
1636 | struct mv_host_priv *hpriv = probe_ent->private_data; | 1660 | struct mv_host_priv *hpriv = probe_ent->private_data; |
1637 | 1661 | ||
1638 | rc = mv_cfg_errata(pdev, hpriv, board_idx); | 1662 | /* global interrupt mask */ |
1663 | writel(0, mmio + HC_MAIN_IRQ_MASK_OFS); | ||
1664 | |||
1665 | rc = mv_chip_id(pdev, hpriv, board_idx); | ||
1639 | if (rc) | 1666 | if (rc) |
1640 | goto done; | 1667 | goto done; |
1641 | 1668 | ||
1642 | n_hc = mv_get_hc_count(probe_ent->host_flags); | 1669 | n_hc = mv_get_hc_count(probe_ent->host_flags); |
1643 | probe_ent->n_ports = MV_PORTS_PER_HC * n_hc; | 1670 | probe_ent->n_ports = MV_PORTS_PER_HC * n_hc; |
1644 | 1671 | ||
1645 | if (IS_50XX(hpriv)) { | 1672 | for (port = 0; port < probe_ent->n_ports; port++) |
1646 | for (port = 0; port < probe_ent->n_ports; port++) | 1673 | hpriv->ops->read_preamp(hpriv, port, mmio); |
1647 | mv_cfg_signal5(hpriv, port, mmio); | ||
1648 | } else { | ||
1649 | for (port = 0; port < probe_ent->n_ports; port++) | ||
1650 | mv_cfg_signal6(hpriv, port, mmio); | ||
1651 | } | ||
1652 | 1674 | ||
1653 | if ((MV_FLAG_GLBL_SFT_RST & probe_ent->host_flags) && | 1675 | rc = hpriv->ops->reset_hc(hpriv, mmio); |
1654 | mv_global_soft_reset(probe_ent->mmio_base)) { | 1676 | if (rc) |
1655 | rc = 1; | ||
1656 | goto done; | 1677 | goto done; |
1657 | } | ||
1658 | 1678 | ||
1659 | mv_enable_leds(hpriv, mmio); | 1679 | hpriv->ops->enable_leds(hpriv, mmio); |
1660 | 1680 | ||
1661 | for (port = 0; port < probe_ent->n_ports; port++) { | 1681 | for (port = 0; port < probe_ent->n_ports; port++) { |
1662 | port_mmio = mv_port_base(mmio, port); | 1682 | port_mmio = mv_port_base(mmio, port); |
@@ -1794,7 +1814,7 @@ static int mv_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
1794 | probe_ent->private_data = hpriv; | 1814 | probe_ent->private_data = hpriv; |
1795 | 1815 | ||
1796 | /* initialize adapter */ | 1816 | /* initialize adapter */ |
1797 | rc = mv_host_init(pdev, probe_ent, board_idx); | 1817 | rc = mv_init_host(pdev, probe_ent, board_idx); |
1798 | if (rc) { | 1818 | if (rc) { |
1799 | goto err_out_hpriv; | 1819 | goto err_out_hpriv; |
1800 | } | 1820 | } |