mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-08-27 19:29:37 +00:00
[libata sata_mv] hardware initialization work
Implement flash reset and PCI reset on 50xx and 60xx. Implement LED enable on 50xx.
This commit is contained in:
parent
47c2b677da
commit
522479fb98
1 changed files with 105 additions and 12 deletions
|
@ -50,6 +50,7 @@ enum {
|
|||
MV_PCI_REG_BASE = 0,
|
||||
MV_IRQ_COAL_REG_BASE = 0x18000, /* 6xxx part only */
|
||||
MV_SATAHC0_REG_BASE = 0x20000,
|
||||
MV_FLASH_CTL = 0x1046c,
|
||||
MV_GPIO_PORT_CTL = 0x104f0,
|
||||
MV_RESET_CFG = 0x180d8,
|
||||
|
||||
|
@ -87,12 +88,6 @@ enum {
|
|||
ATA_FLAG_SATA_RESET | ATA_FLAG_MMIO),
|
||||
MV_6XXX_FLAGS = MV_FLAG_IRQ_COALESCE,
|
||||
|
||||
chip_504x = 0,
|
||||
chip_508x = 1,
|
||||
chip_5080 = 2,
|
||||
chip_604x = 3,
|
||||
chip_608x = 4,
|
||||
|
||||
CRQB_FLAG_READ = (1 << 0),
|
||||
CRQB_TAG_SHIFT = 1,
|
||||
CRQB_CMD_ADDR_SHIFT = 8,
|
||||
|
@ -112,8 +107,19 @@ enum {
|
|||
PCI_MASTER_EMPTY = (1 << 3),
|
||||
GLOB_SFT_RST = (1 << 4),
|
||||
|
||||
PCI_IRQ_CAUSE_OFS = 0x1d58,
|
||||
PCI_IRQ_MASK_OFS = 0x1d5c,
|
||||
MV_PCI_MODE = 0xd00,
|
||||
MV_PCI_EXP_ROM_BAR_CTL = 0xd2c,
|
||||
MV_PCI_DISC_TIMER = 0xd04,
|
||||
MV_PCI_MSI_TRIGGER = 0xc38,
|
||||
MV_PCI_SERR_MASK = 0xc28,
|
||||
MV_PCI_XBAR_TMOUT = 0x1d04,
|
||||
MV_PCI_ERR_LOW_ADDRESS = 0x1d40,
|
||||
MV_PCI_ERR_HIGH_ADDRESS = 0x1d44,
|
||||
MV_PCI_ERR_ATTRIBUTE = 0x1d48,
|
||||
MV_PCI_ERR_COMMAND = 0x1d50,
|
||||
|
||||
PCI_IRQ_CAUSE_OFS = 0x1d58,
|
||||
PCI_IRQ_MASK_OFS = 0x1d5c,
|
||||
PCI_UNMASK_ALL_IRQS = 0x7fffff, /* bits 22-0 */
|
||||
|
||||
HC_MAIN_IRQ_CAUSE_OFS = 0x1d60,
|
||||
|
@ -236,6 +242,14 @@ enum {
|
|||
EDMA_RSP_Q_BASE_LO_MASK = 0xffffff00U,
|
||||
};
|
||||
|
||||
enum chip_type {
|
||||
chip_504x,
|
||||
chip_508x,
|
||||
chip_5080,
|
||||
chip_604x,
|
||||
chip_608x,
|
||||
};
|
||||
|
||||
/* Command ReQuest Block: 32B */
|
||||
struct mv_crqb {
|
||||
u32 sg_addr;
|
||||
|
@ -284,6 +298,8 @@ struct mv_hw_ops {
|
|||
void (*read_preamp)(struct mv_host_priv *hpriv, int idx,
|
||||
void __iomem *mmio);
|
||||
int (*reset_hc)(struct mv_host_priv *hpriv, void __iomem *mmio);
|
||||
void (*reset_flash)(struct mv_host_priv *hpriv, void __iomem *mmio);
|
||||
void (*reset_bus)(struct pci_dev *pdev, void __iomem *mmio);
|
||||
};
|
||||
|
||||
struct mv_host_priv {
|
||||
|
@ -311,12 +327,16 @@ static void mv5_enable_leds(struct mv_host_priv *hpriv, void __iomem *mmio);
|
|||
static void mv5_read_preamp(struct mv_host_priv *hpriv, int idx,
|
||||
void __iomem *mmio);
|
||||
static int mv5_reset_hc(struct mv_host_priv *hpriv, void __iomem *mmio);
|
||||
static void mv5_reset_flash(struct mv_host_priv *hpriv, void __iomem *mmio);
|
||||
static void mv5_reset_bus(struct pci_dev *pdev, void __iomem *mmio);
|
||||
|
||||
static void mv6_phy_errata(struct ata_port *ap);
|
||||
static void mv6_enable_leds(struct mv_host_priv *hpriv, void __iomem *mmio);
|
||||
static void mv6_read_preamp(struct mv_host_priv *hpriv, int idx,
|
||||
void __iomem *mmio);
|
||||
static int mv6_reset_hc(struct mv_host_priv *hpriv, void __iomem *mmio);
|
||||
static void mv6_reset_flash(struct mv_host_priv *hpriv, void __iomem *mmio);
|
||||
static void mv_reset_pci_bus(struct pci_dev *pdev, void __iomem *mmio);
|
||||
|
||||
static struct scsi_host_template mv_sht = {
|
||||
.module = THIS_MODULE,
|
||||
|
@ -433,6 +453,8 @@ static const struct mv_hw_ops mv5xxx_ops = {
|
|||
.enable_leds = mv5_enable_leds,
|
||||
.read_preamp = mv5_read_preamp,
|
||||
.reset_hc = mv5_reset_hc,
|
||||
.reset_flash = mv5_reset_flash,
|
||||
.reset_bus = mv5_reset_bus,
|
||||
};
|
||||
|
||||
static const struct mv_hw_ops mv6xxx_ops = {
|
||||
|
@ -440,6 +462,8 @@ static const struct mv_hw_ops mv6xxx_ops = {
|
|||
.enable_leds = mv6_enable_leds,
|
||||
.read_preamp = mv6_read_preamp,
|
||||
.reset_hc = mv6_reset_hc,
|
||||
.reset_flash = mv6_reset_flash,
|
||||
.reset_bus = mv_reset_pci_bus,
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -655,9 +679,45 @@ static void mv_scr_write(struct ata_port *ap, unsigned int sc_reg_in, u32 val)
|
|||
}
|
||||
}
|
||||
|
||||
#undef ZERO
|
||||
#define ZERO(reg) writel(0, mmio + (reg))
|
||||
static void mv_reset_pci_bus(struct pci_dev *pdev, void __iomem *mmio)
|
||||
{
|
||||
u32 tmp;
|
||||
|
||||
tmp = readl(mmio + MV_PCI_MODE);
|
||||
tmp &= 0xff00ffff;
|
||||
writel(tmp, mmio + MV_PCI_MODE);
|
||||
|
||||
ZERO(MV_PCI_DISC_TIMER);
|
||||
ZERO(MV_PCI_MSI_TRIGGER);
|
||||
writel(0x000100ff, mmio + MV_PCI_XBAR_TMOUT);
|
||||
ZERO(HC_MAIN_IRQ_MASK_OFS);
|
||||
ZERO(MV_PCI_SERR_MASK);
|
||||
ZERO(PCI_IRQ_CAUSE_OFS);
|
||||
ZERO(PCI_IRQ_MASK_OFS);
|
||||
ZERO(MV_PCI_ERR_LOW_ADDRESS);
|
||||
ZERO(MV_PCI_ERR_HIGH_ADDRESS);
|
||||
ZERO(MV_PCI_ERR_ATTRIBUTE);
|
||||
ZERO(MV_PCI_ERR_COMMAND);
|
||||
}
|
||||
#undef ZERO
|
||||
|
||||
static void mv6_reset_flash(struct mv_host_priv *hpriv, void __iomem *mmio)
|
||||
{
|
||||
u32 tmp;
|
||||
|
||||
mv5_reset_flash(hpriv, mmio);
|
||||
|
||||
tmp = readl(mmio + MV_GPIO_PORT_CTL);
|
||||
tmp &= 0x3;
|
||||
tmp |= (1 << 5) | (1 << 6);
|
||||
writel(tmp, mmio + MV_GPIO_PORT_CTL);
|
||||
}
|
||||
|
||||
/**
|
||||
* mv_global_soft_reset - Perform the 6xxx global soft reset
|
||||
* @mmio_base: base address of the HBA
|
||||
* mv6_reset_hc - Perform the 6xxx global soft reset
|
||||
* @mmio: base address of the HBA
|
||||
*
|
||||
* This routine only applies to 6xxx parts.
|
||||
*
|
||||
|
@ -1273,6 +1333,29 @@ static irqreturn_t mv_interrupt(int irq, void *dev_instance,
|
|||
return IRQ_RETVAL(handled);
|
||||
}
|
||||
|
||||
static void mv5_reset_bus(struct pci_dev *pdev, void __iomem *mmio)
|
||||
{
|
||||
u8 rev_id;
|
||||
int early_5080;
|
||||
|
||||
pci_read_config_byte(pdev, PCI_REVISION_ID, &rev_id);
|
||||
|
||||
early_5080 = (pdev->device == 0x5080) && (rev_id == 0);
|
||||
|
||||
if (!early_5080) {
|
||||
u32 tmp = readl(mmio + MV_PCI_EXP_ROM_BAR_CTL);
|
||||
tmp |= (1 << 0);
|
||||
writel(tmp, mmio + MV_PCI_EXP_ROM_BAR_CTL);
|
||||
}
|
||||
|
||||
mv_reset_pci_bus(pdev, mmio);
|
||||
}
|
||||
|
||||
static void mv5_reset_flash(struct mv_host_priv *hpriv, void __iomem *mmio)
|
||||
{
|
||||
writel(0x0fcfffff, mmio + MV_FLASH_CTL);
|
||||
}
|
||||
|
||||
static void mv5_read_preamp(struct mv_host_priv *hpriv, int idx,
|
||||
void __iomem *mmio)
|
||||
{
|
||||
|
@ -1281,7 +1364,15 @@ static void mv5_read_preamp(struct mv_host_priv *hpriv, int idx,
|
|||
|
||||
static void mv5_enable_leds(struct mv_host_priv *hpriv, void __iomem *mmio)
|
||||
{
|
||||
/* FIXME */
|
||||
u32 tmp;
|
||||
|
||||
writel(0, mmio + MV_GPIO_PORT_CTL);
|
||||
|
||||
/* FIXME: handle MV_HP_ERRATA_50XXB2 errata */
|
||||
|
||||
tmp = readl(mmio + MV_PCI_EXP_ROM_BAR_CTL);
|
||||
tmp |= ~(1 << 0);
|
||||
writel(tmp, mmio + MV_PCI_EXP_ROM_BAR_CTL);
|
||||
}
|
||||
|
||||
static 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)
|
|||
}
|
||||
|
||||
static int mv_chip_id(struct pci_dev *pdev, struct mv_host_priv *hpriv,
|
||||
unsigned int board_idx)
|
||||
unsigned int board_idx)
|
||||
{
|
||||
u8 rev_id;
|
||||
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,
|
|||
if (rc)
|
||||
goto done;
|
||||
|
||||
hpriv->ops->reset_flash(hpriv, mmio);
|
||||
hpriv->ops->reset_bus(pdev, mmio);
|
||||
hpriv->ops->enable_leds(hpriv, mmio);
|
||||
|
||||
for (port = 0; port < probe_ent->n_ports; port++) {
|
||||
|
|
Loading…
Reference in a new issue