diff options
-rw-r--r-- | drivers/ata/Kconfig | 28 | ||||
-rw-r--r-- | drivers/ata/Makefile | 1 | ||||
-rw-r--r-- | drivers/ata/ahci.c | 94 | ||||
-rw-r--r-- | drivers/ata/ahci.h | 3 | ||||
-rw-r--r-- | drivers/ata/ahci_brcm.c | 120 | ||||
-rw-r--r-- | drivers/ata/ata_piix.c | 2 | ||||
-rw-r--r-- | drivers/ata/pata_at32.c | 400 | ||||
-rw-r--r-- | drivers/ata/pata_atiixp.c | 4 | ||||
-rw-r--r-- | drivers/ata/pata_it821x.c | 2 | ||||
-rw-r--r-- | drivers/ata/pata_pdc2027x.c | 4 | ||||
-rw-r--r-- | drivers/ata/sata_mv.c | 2 | ||||
-rw-r--r-- | drivers/phy/broadcom/phy-brcm-sata.c | 31 |
12 files changed, 221 insertions, 470 deletions
diff --git a/drivers/ata/Kconfig b/drivers/ata/Kconfig index cb5339166563..a7120d621154 100644 --- a/drivers/ata/Kconfig +++ b/drivers/ata/Kconfig @@ -92,6 +92,25 @@ config SATA_AHCI If unsure, say N. +config SATA_MOBILE_LPM_POLICY + int "Default SATA Link Power Management policy for mobile chipsets" + range 0 4 + default 0 + depends on SATA_AHCI + help + Select the Default SATA Link Power Management (LPM) policy to use + for mobile / laptop variants of chipsets / "South Bridges". + + The value set has the following meanings: + 0 => Keep firmware settings + 1 => Maximum performance + 2 => Medium power + 3 => Medium power with Device Initiated PM enabled + 4 => Minimum power + + Note "Minimum power" is known to cause issues, including disk + corruption, with some disks and should not be used. + config SATA_AHCI_PLATFORM tristate "Platform AHCI SATA support" help @@ -925,15 +944,6 @@ endif # ATA_BMDMA comment "PIO-only SFF controllers" -config PATA_AT32 - tristate "Atmel AVR32 PATA support (Experimental)" - depends on AVR32 && PLATFORM_AT32AP - help - This option enables support for the IDE devices on the - Atmel AT32AP platform. - - If unsure, say N. - config PATA_CMD640_PCI tristate "CMD640 PCI PATA support (Experimental)" depends on PCI diff --git a/drivers/ata/Makefile b/drivers/ata/Makefile index 8daec3e657f8..f1f5a3fbc777 100644 --- a/drivers/ata/Makefile +++ b/drivers/ata/Makefile @@ -96,7 +96,6 @@ obj-$(CONFIG_PATA_VIA) += pata_via.o obj-$(CONFIG_PATA_WINBOND) += pata_sl82c105.o # SFF PIO only -obj-$(CONFIG_PATA_AT32) += pata_at32.o obj-$(CONFIG_PATA_CMD640_PCI) += pata_cmd640.o obj-$(CONFIG_PATA_FALCON) += pata_falcon.o obj-$(CONFIG_PATA_ISAPNP) += pata_isapnp.o diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index 5443cb71d7ba..355a95a83a34 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c @@ -65,6 +65,7 @@ enum board_ids { /* board IDs by feature in alphabetical order */ board_ahci, board_ahci_ign_iferr, + board_ahci_mobile, board_ahci_nomsi, board_ahci_noncq, board_ahci_nosntf, @@ -140,6 +141,13 @@ static const struct ata_port_info ahci_port_info[] = { .udma_mask = ATA_UDMA6, .port_ops = &ahci_ops, }, + [board_ahci_mobile] = { + AHCI_HFLAGS (AHCI_HFLAG_IS_MOBILE), + .flags = AHCI_FLAG_COMMON, + .pio_mask = ATA_PIO4, + .udma_mask = ATA_UDMA6, + .port_ops = &ahci_ops, + }, [board_ahci_nomsi] = { AHCI_HFLAGS (AHCI_HFLAG_NO_MSI), .flags = AHCI_FLAG_COMMON, @@ -252,13 +260,13 @@ static const struct pci_device_id ahci_pci_tbl[] = { { PCI_VDEVICE(INTEL, 0x2924), board_ahci }, /* ICH9 */ { PCI_VDEVICE(INTEL, 0x2925), board_ahci }, /* ICH9 */ { PCI_VDEVICE(INTEL, 0x2927), board_ahci }, /* ICH9 */ - { PCI_VDEVICE(INTEL, 0x2929), board_ahci }, /* ICH9M */ - { PCI_VDEVICE(INTEL, 0x292a), board_ahci }, /* ICH9M */ - { PCI_VDEVICE(INTEL, 0x292b), board_ahci }, /* ICH9M */ - { PCI_VDEVICE(INTEL, 0x292c), board_ahci }, /* ICH9M */ - { PCI_VDEVICE(INTEL, 0x292f), board_ahci }, /* ICH9M */ + { PCI_VDEVICE(INTEL, 0x2929), board_ahci_mobile }, /* ICH9M */ + { PCI_VDEVICE(INTEL, 0x292a), board_ahci_mobile }, /* ICH9M */ + { PCI_VDEVICE(INTEL, 0x292b), board_ahci_mobile }, /* ICH9M */ + { PCI_VDEVICE(INTEL, 0x292c), board_ahci_mobile }, /* ICH9M */ + { PCI_VDEVICE(INTEL, 0x292f), board_ahci_mobile }, /* ICH9M */ { PCI_VDEVICE(INTEL, 0x294d), board_ahci }, /* ICH9 */ - { PCI_VDEVICE(INTEL, 0x294e), board_ahci }, /* ICH9M */ + { PCI_VDEVICE(INTEL, 0x294e), board_ahci_mobile }, /* ICH9M */ { PCI_VDEVICE(INTEL, 0x502a), board_ahci }, /* Tolapai */ { PCI_VDEVICE(INTEL, 0x502b), board_ahci }, /* Tolapai */ { PCI_VDEVICE(INTEL, 0x3a05), board_ahci }, /* ICH10 */ @@ -268,9 +276,9 @@ static const struct pci_device_id ahci_pci_tbl[] = { { PCI_VDEVICE(INTEL, 0x3b23), board_ahci }, /* PCH AHCI */ { PCI_VDEVICE(INTEL, 0x3b24), board_ahci }, /* PCH RAID */ { PCI_VDEVICE(INTEL, 0x3b25), board_ahci }, /* PCH RAID */ - { PCI_VDEVICE(INTEL, 0x3b29), board_ahci }, /* PCH AHCI */ + { PCI_VDEVICE(INTEL, 0x3b29), board_ahci_mobile }, /* PCH M AHCI */ { PCI_VDEVICE(INTEL, 0x3b2b), board_ahci }, /* PCH RAID */ - { PCI_VDEVICE(INTEL, 0x3b2c), board_ahci }, /* PCH RAID */ + { PCI_VDEVICE(INTEL, 0x3b2c), board_ahci_mobile }, /* PCH M RAID */ { PCI_VDEVICE(INTEL, 0x3b2f), board_ahci }, /* PCH AHCI */ { PCI_VDEVICE(INTEL, 0x19b0), board_ahci }, /* DNV AHCI */ { PCI_VDEVICE(INTEL, 0x19b1), board_ahci }, /* DNV AHCI */ @@ -293,9 +301,9 @@ static const struct pci_device_id ahci_pci_tbl[] = { { PCI_VDEVICE(INTEL, 0x19cE), board_ahci }, /* DNV AHCI */ { PCI_VDEVICE(INTEL, 0x19cF), board_ahci }, /* DNV AHCI */ { PCI_VDEVICE(INTEL, 0x1c02), board_ahci }, /* CPT AHCI */ - { PCI_VDEVICE(INTEL, 0x1c03), board_ahci }, /* CPT AHCI */ + { PCI_VDEVICE(INTEL, 0x1c03), board_ahci_mobile }, /* CPT M AHCI */ { PCI_VDEVICE(INTEL, 0x1c04), board_ahci }, /* CPT RAID */ - { PCI_VDEVICE(INTEL, 0x1c05), board_ahci }, /* CPT RAID */ + { PCI_VDEVICE(INTEL, 0x1c05), board_ahci_mobile }, /* CPT M RAID */ { PCI_VDEVICE(INTEL, 0x1c06), board_ahci }, /* CPT RAID */ { PCI_VDEVICE(INTEL, 0x1c07), board_ahci }, /* CPT RAID */ { PCI_VDEVICE(INTEL, 0x1d02), board_ahci }, /* PBG AHCI */ @@ -304,28 +312,28 @@ static const struct pci_device_id ahci_pci_tbl[] = { { PCI_VDEVICE(INTEL, 0x2826), board_ahci }, /* PBG RAID */ { PCI_VDEVICE(INTEL, 0x2323), board_ahci }, /* DH89xxCC AHCI */ { PCI_VDEVICE(INTEL, 0x1e02), board_ahci }, /* Panther Point AHCI */ - { PCI_VDEVICE(INTEL, 0x1e03), board_ahci }, /* Panther Point AHCI */ + { PCI_VDEVICE(INTEL, 0x1e03), board_ahci_mobile }, /* Panther M AHCI */ { PCI_VDEVICE(INTEL, 0x1e04), board_ahci }, /* Panther Point RAID */ { PCI_VDEVICE(INTEL, 0x1e05), board_ahci }, /* Panther Point RAID */ { PCI_VDEVICE(INTEL, 0x1e06), board_ahci }, /* Panther Point RAID */ - { PCI_VDEVICE(INTEL, 0x1e07), board_ahci }, /* Panther Point RAID */ + { PCI_VDEVICE(INTEL, 0x1e07), board_ahci_mobile }, /* Panther M RAID */ { PCI_VDEVICE(INTEL, 0x1e0e), board_ahci }, /* Panther Point RAID */ { PCI_VDEVICE(INTEL, 0x8c02), board_ahci }, /* Lynx Point AHCI */ - { PCI_VDEVICE(INTEL, 0x8c03), board_ahci }, /* Lynx Point AHCI */ + { PCI_VDEVICE(INTEL, 0x8c03), board_ahci_mobile }, /* Lynx M AHCI */ { PCI_VDEVICE(INTEL, 0x8c04), board_ahci }, /* Lynx Point RAID */ - { PCI_VDEVICE(INTEL, 0x8c05), board_ahci }, /* Lynx Point RAID */ + { PCI_VDEVICE(INTEL, 0x8c05), board_ahci_mobile }, /* Lynx M RAID */ { PCI_VDEVICE(INTEL, 0x8c06), board_ahci }, /* Lynx Point RAID */ - { PCI_VDEVICE(INTEL, 0x8c07), board_ahci }, /* Lynx Point RAID */ + { PCI_VDEVICE(INTEL, 0x8c07), board_ahci_mobile }, /* Lynx M RAID */ { PCI_VDEVICE(INTEL, 0x8c0e), board_ahci }, /* Lynx Point RAID */ - { PCI_VDEVICE(INTEL, 0x8c0f), board_ahci }, /* Lynx Point RAID */ - { PCI_VDEVICE(INTEL, 0x9c02), board_ahci }, /* Lynx Point-LP AHCI */ - { PCI_VDEVICE(INTEL, 0x9c03), board_ahci }, /* Lynx Point-LP AHCI */ - { PCI_VDEVICE(INTEL, 0x9c04), board_ahci }, /* Lynx Point-LP RAID */ - { PCI_VDEVICE(INTEL, 0x9c05), board_ahci }, /* Lynx Point-LP RAID */ - { PCI_VDEVICE(INTEL, 0x9c06), board_ahci }, /* Lynx Point-LP RAID */ - { PCI_VDEVICE(INTEL, 0x9c07), board_ahci }, /* Lynx Point-LP RAID */ - { PCI_VDEVICE(INTEL, 0x9c0e), board_ahci }, /* Lynx Point-LP RAID */ - { PCI_VDEVICE(INTEL, 0x9c0f), board_ahci }, /* Lynx Point-LP RAID */ + { PCI_VDEVICE(INTEL, 0x8c0f), board_ahci_mobile }, /* Lynx M RAID */ + { PCI_VDEVICE(INTEL, 0x9c02), board_ahci_mobile }, /* Lynx LP AHCI */ + { PCI_VDEVICE(INTEL, 0x9c03), board_ahci_mobile }, /* Lynx LP AHCI */ + { PCI_VDEVICE(INTEL, 0x9c04), board_ahci_mobile }, /* Lynx LP RAID */ + { PCI_VDEVICE(INTEL, 0x9c05), board_ahci_mobile }, /* Lynx LP RAID */ + { PCI_VDEVICE(INTEL, 0x9c06), board_ahci_mobile }, /* Lynx LP RAID */ + { PCI_VDEVICE(INTEL, 0x9c07), board_ahci_mobile }, /* Lynx LP RAID */ + { PCI_VDEVICE(INTEL, 0x9c0e), board_ahci_mobile }, /* Lynx LP RAID */ + { PCI_VDEVICE(INTEL, 0x9c0f), board_ahci_mobile }, /* Lynx LP RAID */ { PCI_VDEVICE(INTEL, 0x1f22), board_ahci }, /* Avoton AHCI */ { PCI_VDEVICE(INTEL, 0x1f23), board_ahci }, /* Avoton AHCI */ { PCI_VDEVICE(INTEL, 0x1f24), board_ahci }, /* Avoton RAID */ @@ -353,26 +361,26 @@ static const struct pci_device_id ahci_pci_tbl[] = { { PCI_VDEVICE(INTEL, 0x8d66), board_ahci }, /* Wellsburg RAID */ { PCI_VDEVICE(INTEL, 0x8d6e), board_ahci }, /* Wellsburg RAID */ { PCI_VDEVICE(INTEL, 0x23a3), board_ahci }, /* Coleto Creek AHCI */ - { PCI_VDEVICE(INTEL, 0x9c83), board_ahci }, /* Wildcat Point-LP AHCI */ - { PCI_VDEVICE(INTEL, 0x9c85), board_ahci }, /* Wildcat Point-LP RAID */ - { PCI_VDEVICE(INTEL, 0x9c87), board_ahci }, /* Wildcat Point-LP RAID */ - { PCI_VDEVICE(INTEL, 0x9c8f), board_ahci }, /* Wildcat Point-LP RAID */ + { PCI_VDEVICE(INTEL, 0x9c83), board_ahci_mobile }, /* Wildcat LP AHCI */ + { PCI_VDEVICE(INTEL, 0x9c85), board_ahci_mobile }, /* Wildcat LP RAID */ + { PCI_VDEVICE(INTEL, 0x9c87), board_ahci_mobile }, /* Wildcat LP RAID */ + { PCI_VDEVICE(INTEL, 0x9c8f), board_ahci_mobile }, /* Wildcat LP RAID */ { PCI_VDEVICE(INTEL, 0x8c82), board_ahci }, /* 9 Series AHCI */ - { PCI_VDEVICE(INTEL, 0x8c83), board_ahci }, /* 9 Series AHCI */ + { PCI_VDEVICE(INTEL, 0x8c83), board_ahci_mobile }, /* 9 Series M AHCI */ { PCI_VDEVICE(INTEL, 0x8c84), board_ahci }, /* 9 Series RAID */ - { PCI_VDEVICE(INTEL, 0x8c85), board_ahci }, /* 9 Series RAID */ + { PCI_VDEVICE(INTEL, 0x8c85), board_ahci_mobile }, /* 9 Series M RAID */ { PCI_VDEVICE(INTEL, 0x8c86), board_ahci }, /* 9 Series RAID */ - { PCI_VDEVICE(INTEL, 0x8c87), board_ahci }, /* 9 Series RAID */ + { PCI_VDEVICE(INTEL, 0x8c87), board_ahci_mobile }, /* 9 Series M RAID */ { PCI_VDEVICE(INTEL, 0x8c8e), board_ahci }, /* 9 Series RAID */ - { PCI_VDEVICE(INTEL, 0x8c8f), board_ahci }, /* 9 Series RAID */ - { PCI_VDEVICE(INTEL, 0x9d03), board_ahci }, /* Sunrise Point-LP AHCI */ - { PCI_VDEVICE(INTEL, 0x9d05), board_ahci }, /* Sunrise Point-LP RAID */ - { PCI_VDEVICE(INTEL, 0x9d07), board_ahci }, /* Sunrise Point-LP RAID */ + { PCI_VDEVICE(INTEL, 0x8c8f), board_ahci_mobile }, /* 9 Series M RAID */ + { PCI_VDEVICE(INTEL, 0x9d03), board_ahci_mobile }, /* Sunrise LP AHCI */ + { PCI_VDEVICE(INTEL, 0x9d05), board_ahci_mobile }, /* Sunrise LP RAID */ + { PCI_VDEVICE(INTEL, 0x9d07), board_ahci_mobile }, /* Sunrise LP RAID */ { PCI_VDEVICE(INTEL, 0xa102), board_ahci }, /* Sunrise Point-H AHCI */ - { PCI_VDEVICE(INTEL, 0xa103), board_ahci }, /* Sunrise Point-H AHCI */ + { PCI_VDEVICE(INTEL, 0xa103), board_ahci_mobile }, /* Sunrise M AHCI */ { PCI_VDEVICE(INTEL, 0xa105), board_ahci }, /* Sunrise Point-H RAID */ { PCI_VDEVICE(INTEL, 0xa106), board_ahci }, /* Sunrise Point-H RAID */ - { PCI_VDEVICE(INTEL, 0xa107), board_ahci }, /* Sunrise Point-H RAID */ + { PCI_VDEVICE(INTEL, 0xa107), board_ahci_mobile }, /* Sunrise M RAID */ { PCI_VDEVICE(INTEL, 0xa10f), board_ahci }, /* Sunrise Point-H RAID */ { PCI_VDEVICE(INTEL, 0x2822), board_ahci }, /* Lewisburg RAID*/ { PCI_VDEVICE(INTEL, 0x2823), board_ahci }, /* Lewisburg AHCI*/ @@ -386,6 +394,11 @@ static const struct pci_device_id ahci_pci_tbl[] = { { PCI_VDEVICE(INTEL, 0xa206), board_ahci }, /* Lewisburg RAID*/ { PCI_VDEVICE(INTEL, 0xa252), board_ahci }, /* Lewisburg RAID*/ { PCI_VDEVICE(INTEL, 0xa256), board_ahci }, /* Lewisburg RAID*/ + { PCI_VDEVICE(INTEL, 0xa356), board_ahci }, /* Cannon Lake PCH-H RAID */ + { PCI_VDEVICE(INTEL, 0x0f22), board_ahci_mobile }, /* Bay Trail AHCI */ + { PCI_VDEVICE(INTEL, 0x0f23), board_ahci_mobile }, /* Bay Trail AHCI */ + { PCI_VDEVICE(INTEL, 0x22a3), board_ahci_mobile }, /* Cherry Tr. AHCI */ + { PCI_VDEVICE(INTEL, 0x5ae3), board_ahci_mobile }, /* ApolloLake AHCI */ /* JMicron 360/1/3/5/6, match class to avoid IDE function */ { PCI_VENDOR_ID_JMICRON, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, @@ -593,6 +606,9 @@ static int marvell_enable = 1; module_param(marvell_enable, int, 0644); MODULE_PARM_DESC(marvell_enable, "Marvell SATA via AHCI (1 = enabled)"); +static int mobile_lpm_policy = CONFIG_SATA_MOBILE_LPM_POLICY; +module_param(mobile_lpm_policy, int, 0644); +MODULE_PARM_DESC(mobile_lpm_policy, "Default LPM policy for mobile chipsets"); static void ahci_pci_save_initial_config(struct pci_dev *pdev, struct ahci_host_priv *hpriv) @@ -1728,6 +1744,10 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) if (ap->flags & ATA_FLAG_EM) ap->em_message_type = hpriv->em_msg_type; + if ((hpriv->flags & AHCI_HFLAG_IS_MOBILE) && + mobile_lpm_policy >= ATA_LPM_UNKNOWN && + mobile_lpm_policy <= ATA_LPM_MIN_POWER) + ap->target_lpm_policy = mobile_lpm_policy; /* disabled/not-implemented port */ if (!(hpriv->port_map & (1 << i))) diff --git a/drivers/ata/ahci.h b/drivers/ata/ahci.h index 749fd94441b0..a9d996e17d75 100644 --- a/drivers/ata/ahci.h +++ b/drivers/ata/ahci.h @@ -251,6 +251,9 @@ enum { AHCI_HFLAG_YES_ALPM = (1 << 23), /* force ALPM cap on */ AHCI_HFLAG_NO_WRITE_TO_RO = (1 << 24), /* don't write to read only registers */ + AHCI_HFLAG_IS_MOBILE = (1 << 25), /* mobile chipset, use + SATA_MOBILE_LPM_POLICY + as default lpm_policy */ /* ap->flags bits */ diff --git a/drivers/ata/ahci_brcm.c b/drivers/ata/ahci_brcm.c index 5936d1679bf3..ea430819c80b 100644 --- a/drivers/ata/ahci_brcm.c +++ b/drivers/ata/ahci_brcm.c @@ -70,6 +70,13 @@ (DATA_ENDIAN << DMADESC_ENDIAN_SHIFT) | \ (MMIO_ENDIAN << MMIO_ENDIAN_SHIFT)) +#define BUS_CTRL_ENDIAN_NSP_CONF \ + (0x02 << DMADATA_ENDIAN_SHIFT | 0x02 << DMADESC_ENDIAN_SHIFT) + +#define BUS_CTRL_ENDIAN_CONF_MASK \ + (0x3 << MMIO_ENDIAN_SHIFT | 0x3 << DMADESC_ENDIAN_SHIFT | \ + 0x3 << DMADATA_ENDIAN_SHIFT | 0x3 << PIODATA_ENDIAN_SHIFT) + enum brcm_ahci_version { BRCM_SATA_BCM7425 = 1, BRCM_SATA_BCM7445, @@ -89,14 +96,6 @@ struct brcm_ahci_priv { enum brcm_ahci_version version; }; -static const struct ata_port_info ahci_brcm_port_info = { - .flags = AHCI_FLAG_COMMON | ATA_FLAG_NO_DIPM, - .link_flags = ATA_LFLAG_NO_DB_DELAY, - .pio_mask = ATA_PIO4, - .udma_mask = ATA_UDMA6, - .port_ops = &ahci_platform_ops, -}; - static inline u32 brcm_sata_readreg(void __iomem *addr) { /* @@ -250,20 +249,105 @@ static u32 brcm_ahci_get_portmask(struct platform_device *pdev, static void brcm_sata_init(struct brcm_ahci_priv *priv) { void __iomem *ctrl = priv->top_ctrl + SATA_TOP_CTRL_BUS_CTRL; + u32 data; /* Configure endianness */ - if (priv->version == BRCM_SATA_NSP) { - u32 data = brcm_sata_readreg(ctrl); - - data &= ~((0x03 << DMADATA_ENDIAN_SHIFT) | - (0x03 << DMADESC_ENDIAN_SHIFT)); - data |= (0x02 << DMADATA_ENDIAN_SHIFT) | - (0x02 << DMADESC_ENDIAN_SHIFT); - brcm_sata_writereg(data, ctrl); - } else - brcm_sata_writereg(BUS_CTRL_ENDIAN_CONF, ctrl); + data = brcm_sata_readreg(ctrl); + data &= ~BUS_CTRL_ENDIAN_CONF_MASK; + if (priv->version == BRCM_SATA_NSP) + data |= BUS_CTRL_ENDIAN_NSP_CONF; + else + data |= BUS_CTRL_ENDIAN_CONF; + brcm_sata_writereg(data, ctrl); +} + +static unsigned int brcm_ahci_read_id(struct ata_device *dev, + struct ata_taskfile *tf, u16 *id) +{ + struct ata_port *ap = dev->link->ap; + struct ata_host *host = ap->host; + struct ahci_host_priv *hpriv = host->private_data; + struct brcm_ahci_priv *priv = hpriv->plat_data; + void __iomem *mmio = hpriv->mmio; + unsigned int err_mask; + unsigned long flags; + int i, rc; + u32 ctl; + + /* Try to read the device ID and, if this fails, proceed with the + * recovery sequence below + */ + err_mask = ata_do_dev_read_id(dev, tf, id); + if (likely(!err_mask)) + return err_mask; + + /* Disable host interrupts */ + spin_lock_irqsave(&host->lock, flags); + ctl = readl(mmio + HOST_CTL); + ctl &= ~HOST_IRQ_EN; + writel(ctl, mmio + HOST_CTL); + readl(mmio + HOST_CTL); /* flush */ + spin_unlock_irqrestore(&host->lock, flags); + + /* Perform the SATA PHY reset sequence */ + brcm_sata_phy_disable(priv, ap->port_no); + + /* Bring the PHY back on */ + brcm_sata_phy_enable(priv, ap->port_no); + + /* Re-initialize and calibrate the PHY */ + for (i = 0; i < hpriv->nports; i++) { + rc = phy_init(hpriv->phys[i]); + if (rc) + goto disable_phys; + + rc = phy_calibrate(hpriv->phys[i]); + if (rc) { + phy_exit(hpriv->phys[i]); + goto disable_phys; + } + } + + /* Re-enable host interrupts */ + spin_lock_irqsave(&host->lock, flags); + ctl = readl(mmio + HOST_CTL); + ctl |= HOST_IRQ_EN; + writel(ctl, mmio + HOST_CTL); + readl(mmio + HOST_CTL); /* flush */ + spin_unlock_irqrestore(&host->lock, flags); + + return ata_do_dev_read_id(dev, tf, id); + +disable_phys: + while (--i >= 0) { + phy_power_off(hpriv->phys[i]); + phy_exit(hpriv->phys[i]); + } + + return AC_ERR_OTHER; +} + +static void brcm_ahci_host_stop(struct ata_host *host) +{ + struct ahci_host_priv *hpriv = host->private_data; + + ahci_platform_disable_resources(hpriv); } +static struct ata_port_operations ahci_brcm_platform_ops = { + .inherits = &ahci_ops, + .host_stop = brcm_ahci_host_stop, + .read_id = brcm_ahci_read_id, +}; + +static const struct ata_port_info ahci_brcm_port_info = { + .flags = AHCI_FLAG_COMMON | ATA_FLAG_NO_DIPM, + .link_flags = ATA_LFLAG_NO_DB_DELAY, + .pio_mask = ATA_PIO4, + .udma_mask = ATA_UDMA6, + .port_ops = &ahci_brcm_platform_ops, +}; + #ifdef CONFIG_PM_SLEEP static int brcm_ahci_suspend(struct device *dev) { diff --git a/drivers/ata/ata_piix.c b/drivers/ata/ata_piix.c index b702c20fbc2b..7ecb1322a514 100644 --- a/drivers/ata/ata_piix.c +++ b/drivers/ata/ata_piix.c @@ -458,7 +458,7 @@ static const struct piix_map_db *piix_map_db_table[] = { [ich8_2port_sata_byt] = &ich8_2port_map_db, }; -static struct pci_bits piix_enable_bits[] = { +static const struct pci_bits piix_enable_bits[] = { { 0x41U, 1U, 0x80UL, 0x80UL }, /* port 0 */ { 0x43U, 1U, 0x80UL, 0x80UL }, /* port 1 */ }; diff --git a/drivers/ata/pata_at32.c b/drivers/ata/pata_at32.c deleted file mode 100644 index 9aeb7a6dd4d4..000000000000 --- a/drivers/ata/pata_at32.c +++ /dev/null @@ -1,400 +0,0 @@ -/* - * AVR32 SMC/CFC PATA Driver - * - * Copyright (C) 2007 Atmel Norway - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License version - * 2 as published by the Free Software Foundation. - */ - -#define DEBUG - -#include <linux/kernel.h> -#include <linux/module.h> -#include <linux/init.h> -#include <linux/device.h> -#include <linux/platform_device.h> -#include <linux/delay.h> -#include <linux/interrupt.h> -#include <linux/irq.h> -#include <linux/slab.h> -#include <scsi/scsi_host.h> -#include <linux/ata.h> -#include <linux/libata.h> -#include <linux/err.h> -#include <linux/io.h> - -#include <mach/board.h> -#include <mach/smc.h> - -#define DRV_NAME "pata_at32" -#define DRV_VERSION "0.0.3" - -/* - * CompactFlash controller memory layout relative to the base address: - * - * Attribute memory: 0000 0000 -> 003f ffff - * Common memory: 0040 0000 -> 007f ffff - * I/O memory: 0080 0000 -> 00bf ffff - * True IDE Mode: 00c0 0000 -> 00df ffff - * Alt IDE Mode: 00e0 0000 -> 00ff ffff - * - * Only True IDE and Alt True IDE mode are needed for this driver. - * - * True IDE mode => CS0 = 0, CS1 = 1 (cmd, error, stat, etc) - * Alt True IDE mode => CS0 = 1, CS1 = 0 (ctl, alt_stat) - */ -#define CF_IDE_OFFSET 0x00c00000 -#define CF_ALT_IDE_OFFSET 0x00e00000 -#define CF_RES_SIZE 2048 - -/* - * Define DEBUG_BUS if you are doing debugging of your own EBI -> PATA - * adaptor with a logic analyzer or similar. - */ -#undef DEBUG_BUS - -/* - * ATA PIO modes - * - * Name | Mb/s | Min cycle time | Mask - * --------+-------+----------------+-------- - * Mode 0 | 3.3 | 600 ns | 0x01 - * Mode 1 | 5.2 | 383 ns | 0x03 - * Mode 2 | 8.3 | 240 ns | 0x07 - * Mode 3 | 11.1 | 180 ns | 0x0f - * Mode 4 | 16.7 | 120 ns | 0x1f - * - * Alter PIO_MASK below according to table to set maximal PIO mode. - */ -enum { - PIO_MASK = ATA_PIO4, -}; - -/* - * Struct containing private information about device. - */ -struct at32_ide_info { - unsigned int irq; - struct resource res_ide; - struct resource res_alt; - void __iomem *ide_addr; - void __iomem *alt_addr; - unsigned int cs; - struct smc_config smc; -}; - -/* - * Setup SMC for the given ATA timing. - */ -static int pata_at32_setup_timing(struct device *dev, - struct at32_ide_info *info, - const struct ata_timing *ata) -{ - struct smc_config *smc = &info->smc; - struct smc_timing timing; - - int active; - int recover; - - memset(&timing, 0, sizeof(struct smc_timing)); - - /* Total cycle time */ - timing.read_cycle = ata->cyc8b; - - /* DIOR <= CFIOR timings */ - timing.nrd_setup = ata->setup; - timing.nrd_pulse = ata->act8b; - timing.nrd_recover = ata->rec8b; - - /* Convert nanosecond timing to clock cycles */ - smc_set_timing(smc, &timing); - - /* Add one extra cycle setup due to signal ring */ - smc->nrd_setup = smc->nrd_setup + 1; - - active = smc->nrd_setup + smc->nrd_pulse; - recover = smc->read_cycle - active; - - /* Need at least two cycles recovery */ - if (recover < 2) - smc->read_cycle = active + 2; - - /* (CS0, CS1, DIR, OE) <= (CFCE1, CFCE2, CFRNW, NCSX) timings */ - smc->ncs_read_setup = 1; - smc->ncs_read_pulse = smc->read_cycle - 2; - - /* Write timings same as read timings */ - smc->write_cycle = smc->read_cycle; - smc->nwe_setup = smc->nrd_setup; - smc->nwe_pulse = smc->nrd_pulse; - smc->ncs_write_setup = smc->ncs_read_setup; - smc->ncs_write_pulse = smc->ncs_read_pulse; - - /* Do some debugging output of ATA and SMC timings */ - dev_dbg(dev, "ATA: C=%d S=%d P=%d R=%d\n", - ata->cyc8b, ata->setup, ata->act8b, ata->rec8b); - - dev_dbg(dev, "SMC: C=%d S=%d P=%d NS=%d NP=%d\n", - smc->read_cycle, smc->nrd_setup, smc->nrd_pulse, - smc->ncs_read_setup, smc->ncs_read_pulse); - - /* Finally, configure the SMC */ - return smc_set_configuration(info->cs, smc); -} - -/* - * Procedures for libATA. - */ -static void pata_at32_set_piomode(struct ata_port *ap, struct ata_device *adev) -{ - struct ata_timing timing; - struct at32_ide_info *info = ap->host->private_data; - - int ret; - - /* Compute ATA timing */ - ret = ata_timing_compute(adev, adev->pio_mode, &timing, 1000, 0); - if (ret) { - dev_warn(ap->dev, "Failed to compute ATA timing %d\n", ret); - return; - } - - /* Setup SMC to ATA timing */ - ret = pata_at32_setup_timing(ap->dev, info, &timing); - if (ret) { - dev_warn(ap->dev, "Failed to setup ATA timing %d\n", ret); - return; - } -} - -static struct scsi_host_template at32_sht = { - ATA_PIO_SHT(DRV_NAME), -}; - -static struct ata_port_operations at32_port_ops = { - .inherits = &ata_sff_port_ops, - .cable_detect = ata_cable_40wire, - .set_piomode = pata_at32_set_piomode, -}; - -static int __init pata_at32_init_one(struct device *dev, - struct at32_ide_info *info) -{ - struct ata_host *host; - struct ata_port *ap; - - host = ata_host_alloc(dev, 1); - if (!host) - return -ENOMEM; - - ap = host->ports[0]; - - /* Setup ATA bindings */ - ap->ops = &at32_port_ops; - ap->pio_mask = PIO_MASK; - ap->flags |= ATA_FLAG_SLAVE_POSS; - - /* - * Since all 8-bit taskfile transfers has to go on the lower - * byte of the data bus and there is a bug in the SMC that - * makes it impossible to alter the bus width during runtime, - * we need to hardwire the address signals as follows: - * - * A_IDE(2:0) <= A_EBI(3:1) - * - * This makes all addresses on the EBI even, thus all data - * will be on the lower byte of the data bus. All addresses - * used by libATA need to be altered according to this. - */ - ap->ioaddr.altstatus_addr = info->alt_addr + (0x06 << 1); - ap->ioaddr.ctl_addr = info->alt_addr + (0x06 << 1); - - ap->ioaddr.data_addr = info->ide_addr + (ATA_REG_DATA << 1); - ap->ioaddr.error_addr = info->ide_addr + (ATA_REG_ERR << 1); - ap->ioaddr.feature_addr = info->ide_addr + (ATA_REG_FEATURE << 1); - ap->ioaddr.nsect_addr = info->ide_addr + (ATA_REG_NSECT << 1); - ap->ioaddr.lbal_addr = info->ide_addr + (ATA_REG_LBAL << 1); - ap->ioaddr.lbam_addr = info->ide_addr + (ATA_REG_LBAM << 1); - ap->ioaddr.lbah_addr = info->ide_addr + (ATA_REG_LBAH << 1); - ap->ioaddr.device_addr = info->ide_addr + (ATA_REG_DEVICE << 1); - ap->ioaddr.status_addr = info->ide_addr + (ATA_REG_STATUS << 1); - ap->ioaddr.command_addr = info->ide_addr + (ATA_REG_CMD << 1); - - /* Set info as private data of ATA host */ - host->private_data = info; - - /* Register ATA device and return */ - return ata_host_activate(host, info->irq, ata_sff_interrupt, - IRQF_SHARED | IRQF_TRIGGER_RISING, - &at32_sht); -} - -/* - * This function may come in handy for people analyzing their own - * EBI -> PATA adaptors. - */ -#ifdef DEBUG_BUS - -static void __init pata_at32_debug_bus(struct device *dev, - struct at32_ide_info *info) -{ - const int d1 = 0xff; - const int d2 = 0x00; - - int i; - - /* Write 8-bit values (registers) */ - iowrite8(d1, info->alt_addr + (0x06 << 1)); - iowrite8(d2, info->alt_addr + (0x06 << 1)); - - for (i = 0; i < 8; i++) { - iowrite8(d1, info->ide_addr + (i << 1)); - iowrite8(d2, info->ide_addr + (i << 1)); - } - - /* Write 16 bit values (data) */ - iowrite16(d1, info->ide_addr); - iowrite16(d1 << 8, info->ide_addr); - - iowrite16(d1, info->ide_addr); - iowrite16(d1 << 8, info->ide_addr); -} - -#endif - -static int __init pata_at32_probe(struct platform_device *pdev) -{ - const struct ata_timing initial_timing = - {XFER_PIO_0, 70, 290, 240, 600, 165, 150, 600, 0}; - - struct device *dev = &pdev->dev; - struct at32_ide_info *info; - struct ide_platform_data *board = dev_get_platdata(&pdev->dev); - struct resource *res; - - int irq; - int ret; - - if (!board) - return -ENXIO; - - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!res) - return -ENXIO; - - /* Retrive IRQ */ - irq = platform_get_irq(pdev, 0); - if (irq < 0) - return irq; - - /* Setup struct containing private information */ - info = kzalloc(sizeof(struct at32_ide_info), GFP_KERNEL); - if (!info) - return -ENOMEM; - - info->irq = irq; - info->cs = board->cs; - - /* Request memory resources */ - info->res_ide.start = res->start + CF_IDE_OFFSET; - info->res_ide.end = info->res_ide.start + CF_RES_SIZE - 1; - info->res_ide.name = "ide"; - info->res_ide.flags = IORESOURCE_MEM; - - ret = request_resource(res, &info->res_ide); - if (ret) - goto err_req_res_ide; - - info->res_alt.start = res->start + CF_ALT_IDE_OFFSET; - info->res_alt.end = info->res_alt.start + CF_RES_SIZE - 1; - info->res_alt.name = "alt"; - info->res_alt.flags = IORESOURCE_MEM; - - ret = request_resource(res, &info->res_alt); - if (ret) - goto err_req_res_alt; - - /* Setup non-timing elements of SMC */ - info->smc.bus_width = 2; /* 16 bit data bus */ - info->smc.nrd_controlled = 1; /* Sample data on rising edge of NRD */ - info->smc.nwe_controlled = 0; /* Drive data on falling edge of NCS */ - info->smc.nwait_mode = 3; /* NWAIT is in READY mode */ - info->smc.byte_write = 0; /* Byte select access type */ - info->smc.tdf_mode = 0; /* TDF optimization disabled */ - info->smc.tdf_cycles = 0; /* No TDF wait cycles */ - - /* Setup SMC to ATA timing */ - ret = pata_at32_setup_timing(dev, info, &initial_timing); - if (ret) - goto err_setup_timing; - - /* Map ATA address space */ - ret = -ENOMEM; - info->ide_addr = devm_ioremap(dev, info->res_ide.start, 16); - info->alt_addr = devm_ioremap(dev, info->res_alt.start, 16); - if (!info->ide_addr || !info->alt_addr) - goto err_ioremap; - -#ifdef DEBUG_BUS - pata_at32_debug_bus(dev, info); -#endif - - /* Setup and register ATA device */ - ret = pata_at32_init_one(dev, info); - if (ret) - goto err_ata_device; - - return 0; - - err_ata_device: - err_ioremap: - err_setup_timing: - release_resource(&info->res_alt); - err_req_res_alt: - release_resource(&info->res_ide); - err_req_res_ide: - kfree(info); - - return ret; -} - -static int __exit pata_at32_remove(struct platform_device *pdev) -{ - struct ata_host *host = platform_get_drvdata(pdev); - struct at32_ide_info *info; - - if (!host) - return 0; - - info = host->private_data; - ata_host_detach(host); - - if (!info) - return 0; - - release_resource(&info->res_ide); - release_resource(&info->res_alt); - - kfree(info); - - return 0; -} - -/* work with hotplug and coldplug */ -MODULE_ALIAS("platform:at32_ide"); - -static struct platform_driver pata_at32_driver = { - .remove = __exit_p(pata_at32_remove), - .driver = { - .name = "at32_ide", - }, -}; - -module_platform_driver_probe(pata_at32_driver, pata_at32_probe); - -MODULE_LICENSE("GPL"); -MODULE_DESCRIPTION("AVR32 SMC/CFC PATA Driver"); -MODULE_AUTHOR("Kristoffer Nyborg Gregertsen <kngregertsen@norway.atmel.com>"); -MODULE_VERSION(DRV_VERSION); diff --git a/drivers/ata/pata_atiixp.c b/drivers/ata/pata_atiixp.c index 49d705c9f0f7..4d49fd3c927b 100644 --- a/drivers/ata/pata_atiixp.c +++ b/drivers/ata/pata_atiixp.c @@ -278,6 +278,10 @@ static int atiixp_init_one(struct pci_dev *pdev, const struct pci_device_id *id) }; const struct ata_port_info *ppi[] = { &info, &info }; + /* SB600 doesn't have secondary port wired */ + if((pdev->device == PCI_DEVICE_ID_ATI_IXP600_IDE)) + ppi[1] = &ata_dummy_port_info; + return ata_pci_bmdma_init_one(pdev, ppi, &atiixp_sht, NULL, ATA_HOST_PARALLEL_SCAN); } diff --git a/drivers/ata/pata_it821x.c b/drivers/ata/pata_it821x.c index 7a21edf89e72..8468b300193b 100644 --- a/drivers/ata/pata_it821x.c +++ b/drivers/ata/pata_it821x.c @@ -683,7 +683,7 @@ static u8 *it821x_firmware_command(struct ata_port *ap, u8 cmd, int len) ioread16_rep(ap->ioaddr.data_addr, buf, len/2); return (u8 *)buf; } - mdelay(1); + usleep_range(500, 1000); } kfree(buf); printk(KERN_ERR "it821x_firmware_command: timeout\n"); diff --git a/drivers/ata/pata_pdc2027x.c b/drivers/ata/pata_pdc2027x.c index 6db2e34bd52f..1a18e675ba9f 100644 --- a/drivers/ata/pata_pdc2027x.c +++ b/drivers/ata/pata_pdc2027x.c @@ -580,7 +580,7 @@ static void pdc_adjust_pll(struct ata_host *host, long pll_clock, unsigned int b ioread16(mmio_base + PDC_PLL_CTL); /* flush */ /* Wait the PLL circuit to be stable */ - mdelay(30); + msleep(30); #ifdef PDC_DEBUG /* @@ -620,7 +620,7 @@ static long pdc_detect_pll_input_clock(struct ata_host *host) start_time = ktime_get(); /* Let the counter run for 100 ms. */ - mdelay(100); + msleep(100); /* Read the counter values again */ end_count = pdc_read_counter(host); diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c index cc208b72b199..42d4589b43d4 100644 --- a/drivers/ata/sata_mv.c +++ b/drivers/ata/sata_mv.c @@ -3596,7 +3596,7 @@ static void mv_reset_channel(struct mv_host_priv *hpriv, void __iomem *mmio, hpriv->ops->phy_errata(hpriv, mmio, port_no); if (IS_GEN_I(hpriv)) - mdelay(1); + usleep_range(500, 1000); } static void mv_pmp_select(struct ata_port *ap, int pmp) diff --git a/drivers/phy/broadcom/phy-brcm-sata.c b/drivers/phy/broadcom/phy-brcm-sata.c index 3f953db70288..8708ea3b4d6d 100644 --- a/drivers/phy/broadcom/phy-brcm-sata.c +++ b/drivers/phy/broadcom/phy-brcm-sata.c @@ -150,6 +150,9 @@ enum sata_phy_regs { TXPMD_TX_FREQ_CTRL_CONTROL2_FMIN_MASK = 0x3ff, TXPMD_TX_FREQ_CTRL_CONTROL3 = 0x84, TXPMD_TX_FREQ_CTRL_CONTROL3_FMAX_MASK = 0x3ff, + + RXPMD_REG_BANK = 0x1c0, + RXPMD_RX_FREQ_MON_CONTROL1 = 0x87, }; enum sata_phy_ctrl_regs { @@ -505,8 +508,36 @@ static int brcm_sata_phy_init(struct phy *phy) return rc; } +static void brcm_stb_sata_calibrate(struct brcm_sata_port *port) +{ + void __iomem *base = brcm_sata_pcb_base(port); + u32 tmp = BIT(8); + + brcm_sata_phy_wr(base, RXPMD_REG_BANK, RXPMD_RX_FREQ_MON_CONTROL1, + ~tmp, tmp); +} + +static int brcm_sata_phy_calibrate(struct phy *phy) +{ + struct brcm_sata_port *port = phy_get_drvdata(phy); + int rc = -EOPNOTSUPP; + + switch (port->phy_priv->version) { + case BRCM_SATA_PHY_STB_28NM: + case BRCM_SATA_PHY_STB_40NM: + brcm_stb_sata_calibrate(port); + rc = 0; + break; + default: + break; + } + + return rc; +} + static const struct phy_ops phy_ops = { .init = brcm_sata_phy_init, + .calibrate = brcm_sata_phy_calibrate, .owner = THIS_MODULE, }; |