Commit cfa7c641 authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'for-3.17-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/libata

Pull libata fixes from Tejun Heo:
 "Two patches are to add PCI IDs for ICH9 and all others are device
  specific fixes.  Nothing too interesting"

* 'for-3.17-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/libata:
  ahci_xgene: Fix the link down in first attempt for the APM X-Gene SoC AHCI SATA host controller driver.
  ahci_xgene: Skip the PHY and clock initialization if already configured by the firmware.
  ahci: add pcid for Marvel 0x9182 controller
  ata: Disabling the async PM for JMicron chip 363/361
  ata_piix: Add Device IDs for Intel 9 Series PCH
  ahci: Add Device IDs for Intel 9 Series PCH
  ata: ahci_tegra: Read calibration fuse
parents b531f5dd 0babe614
...@@ -305,6 +305,14 @@ static const struct pci_device_id ahci_pci_tbl[] = { ...@@ -305,6 +305,14 @@ static const struct pci_device_id ahci_pci_tbl[] = {
{ PCI_VDEVICE(INTEL, 0x9c85), board_ahci }, /* Wildcat Point-LP RAID */ { PCI_VDEVICE(INTEL, 0x9c85), board_ahci }, /* Wildcat Point-LP RAID */
{ PCI_VDEVICE(INTEL, 0x9c87), 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, 0x9c8f), board_ahci }, /* Wildcat Point-LP RAID */
{ PCI_VDEVICE(INTEL, 0x8c82), board_ahci }, /* 9 Series AHCI */
{ PCI_VDEVICE(INTEL, 0x8c83), board_ahci }, /* 9 Series AHCI */
{ PCI_VDEVICE(INTEL, 0x8c84), board_ahci }, /* 9 Series RAID */
{ PCI_VDEVICE(INTEL, 0x8c85), board_ahci }, /* 9 Series RAID */
{ PCI_VDEVICE(INTEL, 0x8c86), board_ahci }, /* 9 Series RAID */
{ PCI_VDEVICE(INTEL, 0x8c87), board_ahci }, /* 9 Series RAID */
{ PCI_VDEVICE(INTEL, 0x8c8e), board_ahci }, /* 9 Series RAID */
{ PCI_VDEVICE(INTEL, 0x8c8f), board_ahci }, /* 9 Series RAID */
/* JMicron 360/1/3/5/6, match class to avoid IDE function */ /* 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, { PCI_VENDOR_ID_JMICRON, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
...@@ -442,6 +450,8 @@ static const struct pci_device_id ahci_pci_tbl[] = { ...@@ -442,6 +450,8 @@ static const struct pci_device_id ahci_pci_tbl[] = {
{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL_EXT, 0x917a), { PCI_DEVICE(PCI_VENDOR_ID_MARVELL_EXT, 0x917a),
.driver_data = board_ahci_yes_fbs }, /* 88se9172 */ .driver_data = board_ahci_yes_fbs }, /* 88se9172 */
{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL_EXT, 0x9172), { PCI_DEVICE(PCI_VENDOR_ID_MARVELL_EXT, 0x9172),
.driver_data = board_ahci_yes_fbs }, /* 88se9182 */
{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL_EXT, 0x9182),
.driver_data = board_ahci_yes_fbs }, /* 88se9172 */ .driver_data = board_ahci_yes_fbs }, /* 88se9172 */
{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL_EXT, 0x9192), { PCI_DEVICE(PCI_VENDOR_ID_MARVELL_EXT, 0x9192),
.driver_data = board_ahci_yes_fbs }, /* 88se9172 on some Gigabyte */ .driver_data = board_ahci_yes_fbs }, /* 88se9172 on some Gigabyte */
...@@ -1329,6 +1339,18 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) ...@@ -1329,6 +1339,18 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
else if (pdev->vendor == 0x1c44 && pdev->device == 0x8000) else if (pdev->vendor == 0x1c44 && pdev->device == 0x8000)
ahci_pci_bar = AHCI_PCI_BAR_ENMOTUS; ahci_pci_bar = AHCI_PCI_BAR_ENMOTUS;
/*
* The JMicron chip 361/363 contains one SATA controller and one
* PATA controller,for powering on these both controllers, we must
* follow the sequence one by one, otherwise one of them can not be
* powered on successfully, so here we disable the async suspend
* method for these chips.
*/
if (pdev->vendor == PCI_VENDOR_ID_JMICRON &&
(pdev->device == PCI_DEVICE_ID_JMICRON_JMB363 ||
pdev->device == PCI_DEVICE_ID_JMICRON_JMB361))
device_disable_async_suspend(&pdev->dev);
/* acquire resources */ /* acquire resources */
rc = pcim_enable_device(pdev); rc = pcim_enable_device(pdev);
if (rc) if (rc)
......
...@@ -18,14 +18,17 @@ ...@@ -18,14 +18,17 @@
*/ */
#include <linux/ahci_platform.h> #include <linux/ahci_platform.h>
#include <linux/reset.h>
#include <linux/errno.h> #include <linux/errno.h>
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/of_device.h> #include <linux/of_device.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/regulator/consumer.h> #include <linux/regulator/consumer.h>
#include <linux/reset.h>
#include <soc/tegra/fuse.h>
#include <soc/tegra/pmc.h> #include <soc/tegra/pmc.h>
#include "ahci.h" #include "ahci.h"
#define SATA_CONFIGURATION_0 0x180 #define SATA_CONFIGURATION_0 0x180
...@@ -180,9 +183,12 @@ static int tegra_ahci_controller_init(struct ahci_host_priv *hpriv) ...@@ -180,9 +183,12 @@ static int tegra_ahci_controller_init(struct ahci_host_priv *hpriv)
/* Pad calibration */ /* Pad calibration */
/* FIXME Always use calibration 0. Change this to read the calibration ret = tegra_fuse_readl(FUSE_SATA_CALIB, &val);
* fuse once the fuse driver has landed. */ if (ret) {
val = 0; dev_err(&tegra->pdev->dev,
"failed to read calibration fuse: %d\n", ret);
return ret;
}
calib = tegra124_pad_calibration[val & FUSE_SATA_CALIB_MASK]; calib = tegra124_pad_calibration[val & FUSE_SATA_CALIB_MASK];
......
...@@ -78,6 +78,9 @@ ...@@ -78,6 +78,9 @@
#define CFG_MEM_RAM_SHUTDOWN 0x00000070 #define CFG_MEM_RAM_SHUTDOWN 0x00000070
#define BLOCK_MEM_RDY 0x00000074 #define BLOCK_MEM_RDY 0x00000074
/* Max retry for link down */
#define MAX_LINK_DOWN_RETRY 3
struct xgene_ahci_context { struct xgene_ahci_context {
struct ahci_host_priv *hpriv; struct ahci_host_priv *hpriv;
struct device *dev; struct device *dev;
...@@ -145,6 +148,14 @@ static unsigned int xgene_ahci_qc_issue(struct ata_queued_cmd *qc) ...@@ -145,6 +148,14 @@ static unsigned int xgene_ahci_qc_issue(struct ata_queued_cmd *qc)
return rc; return rc;
} }
static bool xgene_ahci_is_memram_inited(struct xgene_ahci_context *ctx)
{
void __iomem *diagcsr = ctx->csr_diag;
return (readl(diagcsr + CFG_MEM_RAM_SHUTDOWN) == 0 &&
readl(diagcsr + BLOCK_MEM_RDY) == 0xFFFFFFFF);
}
/** /**
* xgene_ahci_read_id - Read ID data from the specified device * xgene_ahci_read_id - Read ID data from the specified device
* @dev: device * @dev: device
...@@ -229,8 +240,11 @@ static void xgene_ahci_set_phy_cfg(struct xgene_ahci_context *ctx, int channel) ...@@ -229,8 +240,11 @@ static void xgene_ahci_set_phy_cfg(struct xgene_ahci_context *ctx, int channel)
* and Gen1 (1.5Gbps). Otherwise during long IO stress test, the PHY will * and Gen1 (1.5Gbps). Otherwise during long IO stress test, the PHY will
* report disparity error and etc. In addition, during COMRESET, there can * report disparity error and etc. In addition, during COMRESET, there can
* be error reported in the register PORT_SCR_ERR. For SERR_DISPARITY and * be error reported in the register PORT_SCR_ERR. For SERR_DISPARITY and
* SERR_10B_8B_ERR, the PHY receiver line must be reseted. The following * SERR_10B_8B_ERR, the PHY receiver line must be reseted. Also during long
* algorithm is followed to proper configure the hardware PHY during COMRESET: * reboot cycle regression, sometimes the PHY reports link down even if the
* device is present because of speed negotiation failure. so need to retry
* the COMRESET to get the link up. The following algorithm is followed to
* proper configure the hardware PHY during COMRESET:
* *
* Alg Part 1: * Alg Part 1:
* 1. Start the PHY at Gen3 speed (default setting) * 1. Start the PHY at Gen3 speed (default setting)
...@@ -246,9 +260,15 @@ static void xgene_ahci_set_phy_cfg(struct xgene_ahci_context *ctx, int channel) ...@@ -246,9 +260,15 @@ static void xgene_ahci_set_phy_cfg(struct xgene_ahci_context *ctx, int channel)
* Alg Part 2: * Alg Part 2:
* 1. On link up, if there are any SERR_DISPARITY and SERR_10B_8B_ERR error * 1. On link up, if there are any SERR_DISPARITY and SERR_10B_8B_ERR error
* reported in the register PORT_SCR_ERR, then reset the PHY receiver line * reported in the register PORT_SCR_ERR, then reset the PHY receiver line
* 2. Go to Alg Part 3 * 2. Go to Alg Part 4
* *
* Alg Part 3: * Alg Part 3:
* 1. Check the PORT_SCR_STAT to see whether device presence detected but PHY
* communication establishment failed and maximum link down attempts are
* less than Max attempts 3 then goto Alg Part 1.
* 2. Go to Alg Part 4.
*
* Alg Part 4:
* 1. Clear any pending from register PORT_SCR_ERR. * 1. Clear any pending from register PORT_SCR_ERR.
* *
* NOTE: For the initial version, we will NOT support Gen1/Gen2. In addition * NOTE: For the initial version, we will NOT support Gen1/Gen2. In addition
...@@ -267,19 +287,27 @@ static int xgene_ahci_do_hardreset(struct ata_link *link, ...@@ -267,19 +287,27 @@ static int xgene_ahci_do_hardreset(struct ata_link *link,
u8 *d2h_fis = pp->rx_fis + RX_FIS_D2H_REG; u8 *d2h_fis = pp->rx_fis + RX_FIS_D2H_REG;
void __iomem *port_mmio = ahci_port_base(ap); void __iomem *port_mmio = ahci_port_base(ap);
struct ata_taskfile tf; struct ata_taskfile tf;
int link_down_retry = 0;
int rc; int rc;
u32 val; u32 val, sstatus;
do {
/* clear D2H reception area to properly wait for D2H FIS */ /* clear D2H reception area to properly wait for D2H FIS */
ata_tf_init(link->device, &tf); ata_tf_init(link->device, &tf);
tf.command = ATA_BUSY; tf.command = ATA_BUSY;
ata_tf_to_fis(&tf, 0, 0, d2h_fis); ata_tf_to_fis(&tf, 0, 0, d2h_fis);
rc = sata_link_hardreset(link, timing, deadline, online, rc = sata_link_hardreset(link, timing, deadline, online,
ahci_check_ready); ahci_check_ready);
if (*online) {
val = readl(port_mmio + PORT_SCR_ERR); val = readl(port_mmio + PORT_SCR_ERR);
if (val & (SERR_DISPARITY | SERR_10B_8B_ERR)) if (val & (SERR_DISPARITY | SERR_10B_8B_ERR))
dev_warn(ctx->dev, "link has error\n"); dev_warn(ctx->dev, "link has error\n");
break;
}
sata_scr_read(link, SCR_STATUS, &sstatus);
} while (link_down_retry++ < MAX_LINK_DOWN_RETRY &&
(sstatus & 0xff) == 0x1);
/* clear all errors if any pending */ /* clear all errors if any pending */
val = readl(port_mmio + PORT_SCR_ERR); val = readl(port_mmio + PORT_SCR_ERR);
...@@ -467,6 +495,11 @@ static int xgene_ahci_probe(struct platform_device *pdev) ...@@ -467,6 +495,11 @@ static int xgene_ahci_probe(struct platform_device *pdev)
return -ENODEV; return -ENODEV;
} }
if (xgene_ahci_is_memram_inited(ctx)) {
dev_info(dev, "skip clock and PHY initialization\n");
goto skip_clk_phy;
}
/* Due to errata, HW requires full toggle transition */ /* Due to errata, HW requires full toggle transition */
rc = ahci_platform_enable_clks(hpriv); rc = ahci_platform_enable_clks(hpriv);
if (rc) if (rc)
...@@ -479,7 +512,7 @@ static int xgene_ahci_probe(struct platform_device *pdev) ...@@ -479,7 +512,7 @@ static int xgene_ahci_probe(struct platform_device *pdev)
/* Configure the host controller */ /* Configure the host controller */
xgene_ahci_hw_init(hpriv); xgene_ahci_hw_init(hpriv);
skip_clk_phy:
hpriv->flags = AHCI_HFLAG_NO_PMP | AHCI_HFLAG_NO_NCQ; hpriv->flags = AHCI_HFLAG_NO_PMP | AHCI_HFLAG_NO_NCQ;
rc = ahci_platform_init_host(pdev, hpriv, &xgene_ahci_port_info); rc = ahci_platform_init_host(pdev, hpriv, &xgene_ahci_port_info);
......
...@@ -340,6 +340,14 @@ static const struct pci_device_id piix_pci_tbl[] = { ...@@ -340,6 +340,14 @@ static const struct pci_device_id piix_pci_tbl[] = {
{ 0x8086, 0x0F21, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata_byt }, { 0x8086, 0x0F21, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata_byt },
/* SATA Controller IDE (Coleto Creek) */ /* SATA Controller IDE (Coleto Creek) */
{ 0x8086, 0x23a6, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata }, { 0x8086, 0x23a6, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata },
/* SATA Controller IDE (9 Series) */
{ 0x8086, 0x8c88, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata_snb },
/* SATA Controller IDE (9 Series) */
{ 0x8086, 0x8c89, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata_snb },
/* SATA Controller IDE (9 Series) */
{ 0x8086, 0x8c80, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata_snb },
/* SATA Controller IDE (9 Series) */
{ 0x8086, 0x8c81, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata_snb },
{ } /* terminate list */ { } /* terminate list */
}; };
......
...@@ -143,6 +143,18 @@ static int jmicron_init_one (struct pci_dev *pdev, const struct pci_device_id *i ...@@ -143,6 +143,18 @@ static int jmicron_init_one (struct pci_dev *pdev, const struct pci_device_id *i
}; };
const struct ata_port_info *ppi[] = { &info, NULL }; const struct ata_port_info *ppi[] = { &info, NULL };
/*
* The JMicron chip 361/363 contains one SATA controller and one
* PATA controller,for powering on these both controllers, we must
* follow the sequence one by one, otherwise one of them can not be
* powered on successfully, so here we disable the async suspend
* method for these chips.
*/
if (pdev->vendor == PCI_VENDOR_ID_JMICRON &&
(pdev->device == PCI_DEVICE_ID_JMICRON_JMB363 ||
pdev->device == PCI_DEVICE_ID_JMICRON_JMB361))
device_disable_async_suspend(&pdev->dev);
return ata_pci_bmdma_init_one(pdev, ppi, &jmicron_sht, NULL, 0); return ata_pci_bmdma_init_one(pdev, ppi, &jmicron_sht, NULL, 0);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment