aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi
diff options
context:
space:
mode:
authorJeff Garzik <jgarzik@pobox.com>2005-11-12 22:14:02 -0500
committerJeff Garzik <jgarzik@pobox.com>2005-11-12 22:14:02 -0500
commit522479fb98c6667f081e75f87e298e413c0b1db8 (patch)
tree2a2b52371dd840e054374f23ae607e4476db0ac0 /drivers/scsi
parent47c2b677daeed9c79ecb7167c211ff36876ea611 (diff)
[libata sata_mv] hardware initialization work
Implement flash reset and PCI reset on 50xx and 60xx. Implement LED enable on 50xx.
Diffstat (limited to 'drivers/scsi')
-rw-r--r--drivers/scsi/sata_mv.c117
1 files changed, 105 insertions, 12 deletions
diff --git a/drivers/scsi/sata_mv.c b/drivers/scsi/sata_mv.c
index 4ca4b35d0022..180baa532068 100644
--- a/drivers/scsi/sata_mv.c
+++ b/drivers/scsi/sata_mv.c
@@ -50,6 +50,7 @@ enum {
50 MV_PCI_REG_BASE = 0, 50 MV_PCI_REG_BASE = 0,
51 MV_IRQ_COAL_REG_BASE = 0x18000, /* 6xxx part only */ 51 MV_IRQ_COAL_REG_BASE = 0x18000, /* 6xxx part only */
52 MV_SATAHC0_REG_BASE = 0x20000, 52 MV_SATAHC0_REG_BASE = 0x20000,
53 MV_FLASH_CTL = 0x1046c,
53 MV_GPIO_PORT_CTL = 0x104f0, 54 MV_GPIO_PORT_CTL = 0x104f0,
54 MV_RESET_CFG = 0x180d8, 55 MV_RESET_CFG = 0x180d8,
55 56
@@ -87,12 +88,6 @@ enum {
87 ATA_FLAG_SATA_RESET | ATA_FLAG_MMIO), 88 ATA_FLAG_SATA_RESET | ATA_FLAG_MMIO),
88 MV_6XXX_FLAGS = MV_FLAG_IRQ_COALESCE, 89 MV_6XXX_FLAGS = MV_FLAG_IRQ_COALESCE,
89 90
90 chip_504x = 0,
91 chip_508x = 1,
92 chip_5080 = 2,
93 chip_604x = 3,
94 chip_608x = 4,
95
96 CRQB_FLAG_READ = (1 << 0), 91 CRQB_FLAG_READ = (1 << 0),
97 CRQB_TAG_SHIFT = 1, 92 CRQB_TAG_SHIFT = 1,
98 CRQB_CMD_ADDR_SHIFT = 8, 93 CRQB_CMD_ADDR_SHIFT = 8,
@@ -112,8 +107,19 @@ enum {
112 PCI_MASTER_EMPTY = (1 << 3), 107 PCI_MASTER_EMPTY = (1 << 3),
113 GLOB_SFT_RST = (1 << 4), 108 GLOB_SFT_RST = (1 << 4),
114 109
115 PCI_IRQ_CAUSE_OFS = 0x1d58, 110 MV_PCI_MODE = 0xd00,
116 PCI_IRQ_MASK_OFS = 0x1d5c, 111 MV_PCI_EXP_ROM_BAR_CTL = 0xd2c,
112 MV_PCI_DISC_TIMER = 0xd04,
113 MV_PCI_MSI_TRIGGER = 0xc38,
114 MV_PCI_SERR_MASK = 0xc28,
115 MV_PCI_XBAR_TMOUT = 0x1d04,
116 MV_PCI_ERR_LOW_ADDRESS = 0x1d40,
117 MV_PCI_ERR_HIGH_ADDRESS = 0x1d44,
118 MV_PCI_ERR_ATTRIBUTE = 0x1d48,
119 MV_PCI_ERR_COMMAND = 0x1d50,
120
121 PCI_IRQ_CAUSE_OFS = 0x1d58,
122 PCI_IRQ_MASK_OFS = 0x1d5c,
117 PCI_UNMASK_ALL_IRQS = 0x7fffff, /* bits 22-0 */ 123 PCI_UNMASK_ALL_IRQS = 0x7fffff, /* bits 22-0 */
118 124
119 HC_MAIN_IRQ_CAUSE_OFS = 0x1d60, 125 HC_MAIN_IRQ_CAUSE_OFS = 0x1d60,
@@ -236,6 +242,14 @@ enum {
236 EDMA_RSP_Q_BASE_LO_MASK = 0xffffff00U, 242 EDMA_RSP_Q_BASE_LO_MASK = 0xffffff00U,
237}; 243};
238 244
245enum chip_type {
246 chip_504x,
247 chip_508x,
248 chip_5080,
249 chip_604x,
250 chip_608x,
251};
252
239/* Command ReQuest Block: 32B */ 253/* Command ReQuest Block: 32B */
240struct mv_crqb { 254struct mv_crqb {
241 u32 sg_addr; 255 u32 sg_addr;
@@ -284,6 +298,8 @@ struct mv_hw_ops {
284 void (*read_preamp)(struct mv_host_priv *hpriv, int idx, 298 void (*read_preamp)(struct mv_host_priv *hpriv, int idx,
285 void __iomem *mmio); 299 void __iomem *mmio);
286 int (*reset_hc)(struct mv_host_priv *hpriv, void __iomem *mmio); 300 int (*reset_hc)(struct mv_host_priv *hpriv, void __iomem *mmio);
301 void (*reset_flash)(struct mv_host_priv *hpriv, void __iomem *mmio);
302 void (*reset_bus)(struct pci_dev *pdev, void __iomem *mmio);
287}; 303};
288 304
289struct mv_host_priv { 305struct mv_host_priv {
@@ -311,12 +327,16 @@ static void mv5_enable_leds(struct mv_host_priv *hpriv, void __iomem *mmio);
311static void mv5_read_preamp(struct mv_host_priv *hpriv, int idx, 327static void mv5_read_preamp(struct mv_host_priv *hpriv, int idx,
312 void __iomem *mmio); 328 void __iomem *mmio);
313static int mv5_reset_hc(struct mv_host_priv *hpriv, void __iomem *mmio); 329static int mv5_reset_hc(struct mv_host_priv *hpriv, void __iomem *mmio);
330static void mv5_reset_flash(struct mv_host_priv *hpriv, void __iomem *mmio);
331static void mv5_reset_bus(struct pci_dev *pdev, void __iomem *mmio);
314 332
315static void mv6_phy_errata(struct ata_port *ap); 333static void mv6_phy_errata(struct ata_port *ap);
316static void mv6_enable_leds(struct mv_host_priv *hpriv, void __iomem *mmio); 334static void mv6_enable_leds(struct mv_host_priv *hpriv, void __iomem *mmio);
317static void mv6_read_preamp(struct mv_host_priv *hpriv, int idx, 335static void mv6_read_preamp(struct mv_host_priv *hpriv, int idx,
318 void __iomem *mmio); 336 void __iomem *mmio);
319static int mv6_reset_hc(struct mv_host_priv *hpriv, void __iomem *mmio); 337static int mv6_reset_hc(struct mv_host_priv *hpriv, void __iomem *mmio);
338static void mv6_reset_flash(struct mv_host_priv *hpriv, void __iomem *mmio);
339static void mv_reset_pci_bus(struct pci_dev *pdev, void __iomem *mmio);
320 340
321static struct scsi_host_template mv_sht = { 341static struct scsi_host_template mv_sht = {
322 .module = THIS_MODULE, 342 .module = THIS_MODULE,
@@ -433,6 +453,8 @@ static const struct mv_hw_ops mv5xxx_ops = {
433 .enable_leds = mv5_enable_leds, 453 .enable_leds = mv5_enable_leds,
434 .read_preamp = mv5_read_preamp, 454 .read_preamp = mv5_read_preamp,
435 .reset_hc = mv5_reset_hc, 455 .reset_hc = mv5_reset_hc,
456 .reset_flash = mv5_reset_flash,
457 .reset_bus = mv5_reset_bus,
436}; 458};
437 459
438static const struct mv_hw_ops mv6xxx_ops = { 460static const struct mv_hw_ops mv6xxx_ops = {
@@ -440,6 +462,8 @@ static const struct mv_hw_ops mv6xxx_ops = {
440 .enable_leds = mv6_enable_leds, 462 .enable_leds = mv6_enable_leds,
441 .read_preamp = mv6_read_preamp, 463 .read_preamp = mv6_read_preamp,
442 .reset_hc = mv6_reset_hc, 464 .reset_hc = mv6_reset_hc,
465 .reset_flash = mv6_reset_flash,
466 .reset_bus = mv_reset_pci_bus,
443}; 467};
444 468
445/* 469/*
@@ -655,9 +679,45 @@ static void mv_scr_write(struct ata_port *ap, unsigned int sc_reg_in, u32 val)
655 } 679 }
656} 680}
657 681
682#undef ZERO
683#define ZERO(reg) writel(0, mmio + (reg))
684static void mv_reset_pci_bus(struct pci_dev *pdev, void __iomem *mmio)
685{
686 u32 tmp;
687
688 tmp = readl(mmio + MV_PCI_MODE);
689 tmp &= 0xff00ffff;
690 writel(tmp, mmio + MV_PCI_MODE);
691
692 ZERO(MV_PCI_DISC_TIMER);
693 ZERO(MV_PCI_MSI_TRIGGER);
694 writel(0x000100ff, mmio + MV_PCI_XBAR_TMOUT);
695 ZERO(HC_MAIN_IRQ_MASK_OFS);
696 ZERO(MV_PCI_SERR_MASK);
697 ZERO(PCI_IRQ_CAUSE_OFS);
698 ZERO(PCI_IRQ_MASK_OFS);
699 ZERO(MV_PCI_ERR_LOW_ADDRESS);
700 ZERO(MV_PCI_ERR_HIGH_ADDRESS);
701 ZERO(MV_PCI_ERR_ATTRIBUTE);
702 ZERO(MV_PCI_ERR_COMMAND);
703}
704#undef ZERO
705
706static void mv6_reset_flash(struct mv_host_priv *hpriv, void __iomem *mmio)
707{
708 u32 tmp;
709
710 mv5_reset_flash(hpriv, mmio);
711
712 tmp = readl(mmio + MV_GPIO_PORT_CTL);
713 tmp &= 0x3;
714 tmp |= (1 << 5) | (1 << 6);
715 writel(tmp, mmio + MV_GPIO_PORT_CTL);
716}
717
658/** 718/**
659 * mv_global_soft_reset - Perform the 6xxx global soft reset 719 * mv6_reset_hc - Perform the 6xxx global soft reset
660 * @mmio_base: base address of the HBA 720 * @mmio: base address of the HBA
661 * 721 *
662 * This routine only applies to 6xxx parts. 722 * This routine only applies to 6xxx parts.
663 * 723 *
@@ -1273,6 +1333,29 @@ static irqreturn_t mv_interrupt(int irq, void *dev_instance,
1273 return IRQ_RETVAL(handled); 1333 return IRQ_RETVAL(handled);
1274} 1334}
1275 1335
1336static void mv5_reset_bus(struct pci_dev *pdev, void __iomem *mmio)
1337{
1338 u8 rev_id;
1339 int early_5080;
1340
1341 pci_read_config_byte(pdev, PCI_REVISION_ID, &rev_id);
1342
1343 early_5080 = (pdev->device == 0x5080) && (rev_id == 0);
1344
1345 if (!early_5080) {
1346 u32 tmp = readl(mmio + MV_PCI_EXP_ROM_BAR_CTL);
1347 tmp |= (1 << 0);
1348 writel(tmp, mmio + MV_PCI_EXP_ROM_BAR_CTL);
1349 }
1350
1351 mv_reset_pci_bus(pdev, mmio);
1352}
1353
1354static void mv5_reset_flash(struct mv_host_priv *hpriv, void __iomem *mmio)
1355{
1356 writel(0x0fcfffff, mmio + MV_FLASH_CTL);
1357}
1358
1276static void mv5_read_preamp(struct mv_host_priv *hpriv, int idx, 1359static void mv5_read_preamp(struct mv_host_priv *hpriv, int idx,
1277 void __iomem *mmio) 1360 void __iomem *mmio)
1278{ 1361{
@@ -1281,7 +1364,15 @@ static void mv5_read_preamp(struct mv_host_priv *hpriv, int idx,
1281 1364
1282static void mv5_enable_leds(struct mv_host_priv *hpriv, void __iomem *mmio) 1365static void mv5_enable_leds(struct mv_host_priv *hpriv, void __iomem *mmio)
1283{ 1366{
1284 /* FIXME */ 1367 u32 tmp;
1368
1369 writel(0, mmio + MV_GPIO_PORT_CTL);
1370
1371 /* FIXME: handle MV_HP_ERRATA_50XXB2 errata */
1372
1373 tmp = readl(mmio + MV_PCI_EXP_ROM_BAR_CTL);
1374 tmp |= ~(1 << 0);
1375 writel(tmp, mmio + MV_PCI_EXP_ROM_BAR_CTL);
1285} 1376}
1286 1377
1287static void mv5_phy_errata(struct ata_port *ap) 1378static void mv5_phy_errata(struct ata_port *ap)
@@ -1564,7 +1655,7 @@ static void mv_port_init(struct ata_ioports *port, void __iomem *port_mmio)
1564} 1655}
1565 1656
1566static int mv_chip_id(struct pci_dev *pdev, struct mv_host_priv *hpriv, 1657static int mv_chip_id(struct pci_dev *pdev, struct mv_host_priv *hpriv,
1567 unsigned int board_idx) 1658 unsigned int board_idx)
1568{ 1659{
1569 u8 rev_id; 1660 u8 rev_id;
1570 u32 hp_flags = hpriv->hp_flags; 1661 u32 hp_flags = hpriv->hp_flags;
@@ -1676,6 +1767,8 @@ static int mv_init_host(struct pci_dev *pdev, struct ata_probe_ent *probe_ent,
1676 if (rc) 1767 if (rc)
1677 goto done; 1768 goto done;
1678 1769
1770 hpriv->ops->reset_flash(hpriv, mmio);
1771 hpriv->ops->reset_bus(pdev, mmio);
1679 hpriv->ops->enable_leds(hpriv, mmio); 1772 hpriv->ops->enable_leds(hpriv, mmio);
1680 1773
1681 for (port = 0; port < probe_ent->n_ports; port++) { 1774 for (port = 0; port < probe_ent->n_ports; port++) {