* [PATCH 2/5] nvme: rename "pci" operations to "mmio"
From: Dan Williams @ 2016-10-22 0:25 UTC (permalink / raw)
To: tj; +Cc: keith.busch, linux-ide, hch, linux-nvme
In-Reply-To: <147709592108.3733.7194541797066785254.stgit@dwillia2-desk3.amr.corp.intel.com>
In preparation for adding a platform_device nvme host, rename to a more
generic "mmio" prefix.
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
---
drivers/nvme/host/pci.c | 30 +++++++++++++++---------------
1 file changed, 15 insertions(+), 15 deletions(-)
diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c
index 0fc99f0f2571..8c4330b95be8 100644
--- a/drivers/nvme/host/pci.c
+++ b/drivers/nvme/host/pci.c
@@ -771,7 +771,7 @@ static int nvme_poll(struct blk_mq_hw_ctx *hctx, unsigned int tag)
return 0;
}
-static void nvme_pci_submit_async_event(struct nvme_ctrl *ctrl, int aer_idx)
+static void nvme_mmio_submit_async_event(struct nvme_ctrl *ctrl, int aer_idx)
{
struct nvme_dev *dev = to_nvme_dev(ctrl);
struct nvme_queue *nvmeq = dev->queues[0];
@@ -1704,7 +1704,7 @@ static void nvme_release_prp_pools(struct nvme_dev *dev)
dma_pool_destroy(dev->prp_small_pool);
}
-static void nvme_pci_free_ctrl(struct nvme_ctrl *ctrl)
+static void nvme_mmio_free_ctrl(struct nvme_ctrl *ctrl)
{
struct nvme_dev *dev = to_nvme_dev(ctrl);
@@ -1826,38 +1826,38 @@ static int nvme_reset(struct nvme_dev *dev)
return 0;
}
-static int nvme_pci_reg_read32(struct nvme_ctrl *ctrl, u32 off, u32 *val)
+static int nvme_mmio_reg_read32(struct nvme_ctrl *ctrl, u32 off, u32 *val)
{
*val = readl(to_nvme_dev(ctrl)->bar + off);
return 0;
}
-static int nvme_pci_reg_write32(struct nvme_ctrl *ctrl, u32 off, u32 val)
+static int nvme_mmio_reg_write32(struct nvme_ctrl *ctrl, u32 off, u32 val)
{
writel(val, to_nvme_dev(ctrl)->bar + off);
return 0;
}
-static int nvme_pci_reg_read64(struct nvme_ctrl *ctrl, u32 off, u64 *val)
+static int nvme_mmio_reg_read64(struct nvme_ctrl *ctrl, u32 off, u64 *val)
{
*val = readq(to_nvme_dev(ctrl)->bar + off);
return 0;
}
-static int nvme_pci_reset_ctrl(struct nvme_ctrl *ctrl)
+static int nvme_mmio_reset_ctrl(struct nvme_ctrl *ctrl)
{
return nvme_reset(to_nvme_dev(ctrl));
}
-static const struct nvme_ctrl_ops nvme_pci_ctrl_ops = {
- .name = "pcie",
+static const struct nvme_ctrl_ops nvme_mmio_ctrl_ops = {
+ .name = "mmio",
.module = THIS_MODULE,
- .reg_read32 = nvme_pci_reg_read32,
- .reg_write32 = nvme_pci_reg_write32,
- .reg_read64 = nvme_pci_reg_read64,
- .reset_ctrl = nvme_pci_reset_ctrl,
- .free_ctrl = nvme_pci_free_ctrl,
- .submit_async_event = nvme_pci_submit_async_event,
+ .reg_read32 = nvme_mmio_reg_read32,
+ .reg_write32 = nvme_mmio_reg_write32,
+ .reg_read64 = nvme_mmio_reg_read64,
+ .reset_ctrl = nvme_mmio_reset_ctrl,
+ .free_ctrl = nvme_mmio_free_ctrl,
+ .submit_async_event = nvme_mmio_submit_async_event,
};
static int nvme_dev_map(struct nvme_dev *dev)
@@ -1912,7 +1912,7 @@ static int nvme_probe(struct pci_dev *pdev, const struct pci_device_id *id)
if (result)
goto put_pci;
- result = nvme_init_ctrl(&dev->ctrl, &pdev->dev, &nvme_pci_ctrl_ops,
+ result = nvme_init_ctrl(&dev->ctrl, &pdev->dev, &nvme_mmio_ctrl_ops,
id->driver_data);
if (result)
goto release_pools;
^ permalink raw reply related
* [PATCH 1/5] ahci: nvme remap support
From: Dan Williams @ 2016-10-22 0:25 UTC (permalink / raw)
To: tj; +Cc: keith.busch, linux-ide, hch, linux-nvme
In-Reply-To: <147709592108.3733.7194541797066785254.stgit@dwillia2-desk3.amr.corp.intel.com>
Some Intel ahci implementations have the capability to expose another
pci-express device's memory resources through an ahci memory bar. Add
the enabling to detect these configurations and register the resources
for the nvme driver to consume. Otherwise, the nvme device is
effectively hidden from the kernel for this configuration.
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
---
drivers/ata/Kconfig | 10 +++
drivers/ata/ahci.c | 165 +++++++++++++++++++++++++++++++++++++++++++++++++++
drivers/ata/ahci.h | 14 ++++
3 files changed, 188 insertions(+), 1 deletion(-)
diff --git a/drivers/ata/Kconfig b/drivers/ata/Kconfig
index 2c8be74f401d..b9e46f2c69c1 100644
--- a/drivers/ata/Kconfig
+++ b/drivers/ata/Kconfig
@@ -90,6 +90,16 @@ config SATA_AHCI
If unsure, say N.
+config SATA_AHCI_NVME
+ tristate "AHCI: Remapped NVMe support"
+ depends on SATA_AHCI
+ depends on BLK_DEV_NVME
+ help
+ Support discovering remapped NVMe devices that appear in AHCI
+ PCI memory space.
+
+ If unsure, say N.
+
config SATA_AHCI_PLATFORM
tristate "Platform AHCI SATA support"
help
diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c
index ba5f11cebee2..cc2c81ae497a 100644
--- a/drivers/ata/ahci.c
+++ b/drivers/ata/ahci.c
@@ -39,6 +39,7 @@
#include <linux/delay.h>
#include <linux/interrupt.h>
#include <linux/dma-mapping.h>
+#include <linux/platform_device.h>
#include <linux/device.h>
#include <linux/dmi.h>
#include <linux/gfp.h>
@@ -46,6 +47,7 @@
#include <scsi/scsi_host.h>
#include <scsi/scsi_cmnd.h>
#include <linux/libata.h>
+#include <linux/io-64-nonatomic-lo-hi.h>
#include "ahci.h"
#define DRV_NAME "ahci"
@@ -1400,6 +1402,81 @@ static irqreturn_t ahci_thunderx_irq_handler(int irq, void *dev_instance)
}
#endif
+enum {
+ AHCI_VSCAP = 0xa4,
+ AHCI_REMAP_CAP = 0x800,
+ PCI_CLASS_STORAGE_EXPRESS = 0x10802,
+ /* device class code */
+ AHCI_REMAP_N_DCC = 0x880,
+ /* remap-device base relative to ahci-bar */
+ AHCI_REMAP_N_OFFSET = SZ_16K,
+ AHCI_REMAP_N_SIZE = SZ_16K,
+};
+
+static unsigned int ahci_remap_dcc(int i)
+{
+ return AHCI_REMAP_N_DCC + i * 0x80;
+}
+
+static unsigned int ahci_remap_base(int i)
+{
+ return AHCI_REMAP_N_OFFSET + i * AHCI_REMAP_N_SIZE;
+}
+
+static int ahci_remap_init(struct pci_dev *pdev, int bar,
+ struct ahci_host_priv *hpriv)
+{
+ int i, count = 0;
+ u32 cap;
+
+ /*
+ * Check if remapped nvme devices might be present and if so
+ * register platform resources.
+ */
+ if (IS_ENABLED(CONFIG_SATA_AHCI_NVME)
+ && pdev->vendor == PCI_VENDOR_ID_INTEL
+ && pci_resource_len(pdev, bar) == SZ_512K
+ && bar == AHCI_PCI_BAR_STANDARD
+ && (readl(hpriv->mmio + AHCI_VSCAP) & 1))
+ /* pass */;
+ else
+ return -ENODEV;
+
+ cap = readq(hpriv->mmio + AHCI_REMAP_CAP);
+ for (i = 0; i < AHCI_MAX_REMAP; i++) {
+ struct ahci_remap *rdev;
+
+ if ((cap & (1 << i)) == 0)
+ continue;
+ if (readl(hpriv->mmio + ahci_remap_dcc(i))
+ != PCI_CLASS_STORAGE_EXPRESS)
+ continue;
+
+ rdev = devm_kzalloc(&pdev->dev, sizeof(*rdev), GFP_KERNEL);
+ if (!rdev)
+ return -ENOMEM;
+
+ rdev->id = i;
+ rdev->mem.start = pci_resource_start(pdev, bar)
+ + ahci_remap_base(i);
+ rdev->mem.end = rdev->mem.start + AHCI_REMAP_N_SIZE - 1;
+ rdev->mem.flags = IORESOURCE_MEM;
+
+ /*
+ * This will be translated to kernel irq vector after
+ * ahci irq initialization.
+ */
+ rdev->irq.start = 0;
+ rdev->irq.end = 0;
+ rdev->irq.flags = IORESOURCE_IRQ;
+
+ hpriv->remap[i] = rdev;
+ count++;
+ }
+
+ return count > 0 ? 0 : -ENODEV;
+}
+
static int ahci_get_irq_vector(struct ata_host *host, int port)
{
return pci_irq_vector(to_pci_dev(host->dev), port);
@@ -1410,7 +1487,7 @@ static int ahci_init_msi(struct pci_dev *pdev, unsigned int n_ports,
{
int nvec;
- if (hpriv->flags & AHCI_HFLAG_NO_MSI)
+ if (hpriv->flags & (AHCI_HFLAG_NO_MSI | AHCI_HFLAG_REMAP))
return -ENODEV;
/*
@@ -1452,6 +1529,58 @@ static int ahci_init_msi(struct pci_dev *pdev, unsigned int n_ports,
return pci_alloc_irq_vectors(pdev, 1, 1, PCI_IRQ_MSIX);
}
+static void ahci_remap_restore(void *data)
+{
+ struct pci_dev *pdev = data;
+ int bar = AHCI_PCI_BAR_STANDARD;
+
+ pci_resource_end(pdev, bar) = pci_resource_start(pdev, bar) + SZ_512K - 1;
+}
+
+static void ahci_remap_unregister(void *data)
+{
+ struct platform_device *pdev = data;
+
+ platform_device_del(pdev);
+ put_device(&pdev->dev);
+}
+
+static void ahci_remap_register_devices(struct device *dev,
+ struct ahci_host_priv *hpriv)
+{
+ struct platform_device *pdev;
+ int i;
+
+ if ((hpriv->flags & AHCI_HFLAG_REMAP) == 0)
+ return;
+
+ for (i = 0; i < AHCI_MAX_REMAP; i++) {
+ struct ahci_remap *rdev = hpriv->remap[i];
+
+ if (!rdev)
+ continue;
+ pdev = platform_device_alloc("ahci_nvme", rdev->id);
+ if (!pdev)
+ continue;
+ if (platform_device_add_resources(pdev, &rdev->mem, 2) != 0) {
+ put_device(&pdev->dev);
+ continue;
+ }
+
+ pdev->dev.parent = dev;
+ if (platform_device_add(pdev) != 0) {
+ put_device(&pdev->dev);
+ continue;
+ }
+
+ if (devm_add_action_or_reset(dev, ahci_remap_unregister,
+ pdev) != 0)
+ continue;
+ dev_info(dev, "remap: %s %pR %pR\n", dev_name(&pdev->dev),
+ &rdev->mem, &rdev->irq);
+ }
+}
+
static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
{
unsigned int board_id = ent->driver_data;
@@ -1545,6 +1674,23 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
hpriv->mmio = pcim_iomap_table(pdev)[ahci_pci_bar];
+ /* detect remapped nvme devices */
+ if (ahci_remap_init(pdev, ahci_pci_bar, hpriv) == 0) {
+ pcim_iounmap_regions(pdev, 1 << ahci_pci_bar);
+ pci_resource_end(pdev, ahci_pci_bar)
+ = pci_resource_start(pdev, ahci_pci_bar) + SZ_16K - 1;
+ rc = devm_add_action_or_reset(dev, ahci_remap_restore, pdev);
+ if (rc)
+ return rc;
+ rc = pcim_iomap_regions(pdev, 1 << ahci_pci_bar, DRV_NAME);
+ if (rc == -EBUSY)
+ pcim_pin_device(pdev);
+ if (rc)
+ return rc;
+ hpriv->mmio = pcim_iomap_table(pdev)[ahci_pci_bar];
+ hpriv->flags |= AHCI_HFLAG_REMAP;
+ }
+
/* must set flag prior to save config in order to take effect */
if (ahci_broken_devslp(pdev))
hpriv->flags |= AHCI_HFLAG_NO_DEVSLP;
@@ -1616,6 +1762,21 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
if (ahci_init_msi(pdev, n_ports, hpriv) < 0) {
/* legacy intx interrupts */
pci_intx(pdev, 1);
+
+ /*
+ * Don't rely on the msi-x capability in the remap case,
+ * share the legacy interrupt across ahci and remapped
+ * devices.
+ */
+ if (hpriv->flags & AHCI_HFLAG_REMAP)
+ for (i = 0; i < AHCI_MAX_REMAP; i++) {
+ struct ahci_remap *rdev = hpriv->remap[i];
+
+ if (!rdev || resource_size(&rdev->irq) < 1)
+ continue;
+ rdev->irq.start = pdev->irq;
+ rdev->irq.end = rdev->irq.start;
+ }
}
hpriv->irq = pdev->irq;
@@ -1668,6 +1829,8 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
if (rc)
return rc;
+ ahci_remap_register_devices(&pdev->dev, hpriv);
+
pm_runtime_put_noidle(&pdev->dev);
return 0;
}
diff --git a/drivers/ata/ahci.h b/drivers/ata/ahci.h
index 0cc08f892fea..859d08979497 100644
--- a/drivers/ata/ahci.h
+++ b/drivers/ata/ahci.h
@@ -248,6 +248,8 @@ enum {
AHCI_HFLAG_MULTI_MSI = 0,
#endif
AHCI_HFLAG_WAKE_BEFORE_STOP = (1 << 22), /* wake before DMA stop */
+ AHCI_HFLAG_REMAP = (1 << 23),
+ AHCI_MAX_REMAP = 3,
/* ap->flags bits */
@@ -324,6 +326,17 @@ struct ahci_port_priv {
char *irq_desc; /* desc in /proc/interrupts */
};
+struct ahci_remap {
+ int id;
+ /*
+ * @mem and @irq must be consecutive for
+ * platform_device_add_resources() in
+ * ahci_remap_register_devices()
+ */
+ struct resource mem;
+ struct resource irq;
+};
+
struct ahci_host_priv {
/* Input fields */
unsigned int flags; /* AHCI_HFLAG_* */
@@ -352,6 +365,7 @@ struct ahci_host_priv {
unsigned nports; /* Number of ports */
void *plat_data; /* Other platform data */
unsigned int irq; /* interrupt line */
+ struct ahci_remap *remap[AHCI_MAX_REMAP]; /* remapped devices */
/*
* Optional ahci_start_engine override, if not set this gets set to the
* default ahci_start_engine during ahci_save_initial_config, this can
^ permalink raw reply related
* [PATCH 0/5] ahci: nvme remap support
From: Dan Williams @ 2016-10-22 0:25 UTC (permalink / raw)
To: tj; +Cc: keith.busch, linux-ide, hch, linux-nvme
Some Intel ahci implementations have the capability to expose another
pci-express device's memory resources through an ahci memory bar. Add
the enabling to detect these configurations and register the resources
for the nvme driver to consume. Otherwise, the nvme device is
effectively hidden from the kernel for this configuration.
---
Dan Williams (5):
ahci: nvme remap support
nvme: rename "pci" operations to "mmio"
nvme: introduce nvme_dev_ops
nvme: move common definitions to pci.h
nvme: ahci remap support
drivers/ata/Kconfig | 11 +
drivers/ata/ahci.c | 165 +++++++++++++++++++++
drivers/ata/ahci.h | 14 ++
drivers/nvme/host/Makefile | 2
drivers/nvme/host/ahci.c | 198 +++++++++++++++++++++++++
drivers/nvme/host/pci.c | 344 +++++++++++++++++++++++---------------------
drivers/nvme/host/pci.h | 98 +++++++++++++
7 files changed, 664 insertions(+), 168 deletions(-)
create mode 100644 drivers/nvme/host/ahci.c
create mode 100644 drivers/nvme/host/pci.h
^ permalink raw reply
* Re: Regression with 0b9e2988ab22 ("ahci: use pci_alloc_irq_vectors")
From: Jarkko Nikula @ 2016-10-21 14:05 UTC (permalink / raw)
To: Christoph Hellwig; +Cc: linux-ide, linux-kernel
In-Reply-To: <20161021132709.GA18825@lst.de>
On 10/21/2016 04:27 PM, Christoph Hellwig wrote:
> Hi Jarkko,
>
> please try the two fixes queue up in the libata tree for this:
>
> https://git.kernel.org/cgit/linux/kernel/git/tj/libata.git/log/?h=for-4.9-fixes
>
Great! Commit 17a51f12cfbd ("ahci: only try to use multi-MSI mode if
there is more than 1 port") fixed the non-working SATA on a machine with
single port and it continues using MSI.
Another machine with more ports still uses IO-APIC (was using MSI before
0b9e2988ab22 ("ahci: use pci_alloc_irq_vectors")). Then I applied
a478b097474c ("ahci: fix nvec check") but didn't see changes.
--
Jarkko
^ permalink raw reply
* Re: [PATCH] ahci: use pci_alloc_irq_vectors
From: Robert Richter @ 2016-10-21 14:01 UTC (permalink / raw)
To: Christoph Hellwig
Cc: Robert Richter, Auger Eric, Marc Zyngier, linux-ide,
dan.j.williamps, Tejun Heo, linux-arm-kernel
In-Reply-To: <20161021125918.GA18082@lst.de>
Christoph,
On 21.10.16 14:59:18, Christoph Hellwig wrote:
> can you try the latest fixed in the libata tree:
>
> https://git.kernel.org/cgit/linux/kernel/git/tj/libata.git/log/?h=for-4.9-fixes
I see now this warning:
WARNING: CPU: 0 PID: 1601 at drivers/ata/libata-core.c:6426 ata_host_activate+0x138/0x150
... and it still fails:
[ 21.765921] ata1.00: qc timeout (cmd 0xec)
[ 21.770031] ata1.00: failed to IDENTIFY (I/O error, err_mask=0x4)
[ 22.249869] ata1: SATA link up 6.0 Gbps (SStatus 133 SControl 300)
[ 22.533896] ata4.00: qc timeout (cmd 0xec)
[ 22.537996] ata4.00: failed to IDENTIFY (I/O error, err_mask=0x4)
[ 23.017874] ata4: SATA link up 6.0 Gbps (SStatus 133 SControl 300)
[ 32.261874] ata1.00: qc timeout (cmd 0xec)
[ 32.265972] ata1.00: failed to IDENTIFY (I/O error, err_mask=0x4)
[ 32.272059] ata1: limiting SATA link speed to 3.0 Gbps
[ 32.753873] ata1: SATA link up 3.0 Gbps (SStatus 123 SControl 320)
[ 33.029878] ata4.00: qc timeout (cmd 0xec)
[ 33.033978] ata4.00: failed to IDENTIFY (I/O error, err_mask=0x4)
[ 33.040066] ata4: limiting SATA link speed to 3.0 Gbps
[ 33.521884] ata4: SATA link up 3.0 Gbps (SStatus 123 SControl 320)
[ 63.493874] ata1.00: qc timeout (cmd 0xec)
[ 63.497973] ata1.00: failed to IDENTIFY (I/O error, err_mask=0x4)
[ 63.977867] ata1: SATA link up 3.0 Gbps (SStatus 123 SControl 320)
[ 65.541890] ata4.00: qc timeout (cmd 0xec)
[ 65.545987] ata4.00: failed to IDENTIFY (I/O error, err_mask=0x4)
[ 66.025873] ata4: SATA link up 3.0 Gbps (SStatus 123 SControl 320)
[ 66.032337] VFS: Cannot open root device "sda2" or unknown-block(0,0): error -6
[ 66.039682] Please append a correct "root=" boot option; here are the available partitions:
[ 66.048047] Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(0,0)
Full log below.
(Note that I tested a backported version based on 4.8 with all your 3
patches applied.)
-Robert
[ 15.740362] ahci 0001:00:08.0: version 3.0
[ 15.744577] ahci 0001:00:08.0: AHCI 0001.0300 32 slots 1 ports 6 Gbps 0x1 impl SATA mode
[ 15.752670] ahci 0001:00:08.0: flags: 64bit ncq sntf ilck pm led clo only pmp fbs pio slum part ccc apst
[ 15.762239] ahci 0001:00:08.0: port 0 is not capable of FBS
[ 15.767996] ------------[ cut here ]------------
[ 15.772610] WARNING: CPU: 0 PID: 1601 at drivers/ata/libata-core.c:6426 ata_host_activate+0x138/0x150
[ 15.781815]
[ 15.783298] CPU: 0 PID: 1601 Comm: kworker/0:1 Tainted: G W 4.8.1-00004-gf0dadca853a2 #171
[ 15.792677] Hardware name: www.cavium.com ThunderX CRB-2S/ThunderX CRB-2S, BIOS 0.3 Sep 13 2016
[ 15.801365] Workqueue: events work_for_cpu_fn
[ 15.805714] task: ffff800fcb5e4e00 task.stack: ffff800fcb618000
[ 15.811622] PC is at ata_host_activate+0x138/0x150
[ 15.816401] LR is at ata_host_activate+0x5c/0x150
[ 15.821094] pc : [<ffff0000087b7868>] lr : [<ffff0000087b778c>] pstate: 60000045
[ 15.828476] sp : ffff800fcb61bbb0
[ 15.831780] x29: ffff800fcb61bbb0 x28: 0000000000000001
[ 15.837085] x27: ffff000009245408 x26: ffff000009245bf0
[ 15.842391] x25: ffff800fca8e40a0 x24: ffff800fcb451118
[ 15.847695] x23: 0000000000000080 x22: ffff000009245bf0
[ 15.853000] x21: 0000000000000000 x20: ffff0000087cddc8
[ 15.858305] x19: ffff800fcb451218 x18: ffff0000892f7d77
[ 15.863610] x17: ffff7fe003f2e820 x16: ffffffffffffff98
[ 15.868915] x15: 0000000000000006 x14: ffff0000092f7d85
[ 15.874220] x13: ffff00000979ffff x12: 0000000000000008
[ 15.879525] x11: 0088000000000000 x10: 0140000000000040
[ 15.884829] x9 : 0000000000000000 x8 : ffff000009796500
[ 15.890135] x7 : 0000000000000006 x6 : ffff800fcb618000
[ 15.895439] x5 : ffff800fcb901b00 x4 : 0000000000000000
[ 15.900744] x3 : ffff00001b000104 x2 : ffff800fcb451118
[ 15.906049] x1 : 0000000000000040 x0 : 0000000000000000
[ 15.911354]
[ 15.912835] ---[ end trace 2c145cc81872d49e ]---
[ 15.917440] Call trace:
[ 15.919876] Exception stack(0xffff800fcb61b9e0 to 0xffff800fcb61bb10)
[ 15.926306] b9e0: ffff800fcb451218 0001000000000000 ffff800fcb61bbb0 ffff0000087b7868
[ 15.934124] ba00: ffff000009780000 0000000000020000 0000000000000008 00e800000000070f
[ 15.941942] ba20: 0000000000000000 ffff7fe000300100 ffff800fcb61bab0 ffff000008776250
[ 15.949760] ba40: ffff800fca8e40a0 ffff800fca8e4150 0000000000000004 0000000000000040
[ 15.957578] ba60: 0000000000016500 ffff800fcb451118 ffff800fcb61bab0 ffff0000087d10e8
[ 15.965396] ba80: 0000000000000000 0000000000000040 ffff800fcb451118 ffff00001b000104
[ 15.973214] baa0: 0000000000000000 ffff800fcb901b00 ffff800fcb618000 0000000000000006
[ 15.981032] bac0: ffff000009796500 0000000000000000 0140000000000040 0088000000000000
[ 15.988849] bae0: 0000000000000008 ffff00000979ffff ffff0000092f7d85 0000000000000006
[ 15.996667] bb00: ffffffffffffff98 ffff7fe003f2e820
[ 16.001533] [<ffff0000087b7868>] ata_host_activate+0x138/0x150
[ 16.007356] [<ffff0000087d2950>] ahci_host_activate+0x138/0x170
[ 16.013264] [<ffff0000087ced84>] ahci_init_one+0x8d4/0xd50
[ 16.018740] [<ffff00000850f394>] local_pci_probe+0x3c/0xb8
[ 16.024214] [<ffff0000080cc458>] work_for_cpu_fn+0x18/0x28
[ 16.029689] [<ffff0000080ce710>] process_one_work+0x118/0x378
[ 16.035424] [<ffff0000080cebd8>] worker_thread+0x268/0x4b0
[ 16.040900] [<ffff0000080d4c10>] kthread+0xd0/0xe8
[ 16.045680] [<ffff000008082e90>] ret_from_fork+0x10/0x40
[ 16.051483] scsi host0: ahci
[ 16.054531] ata1: SATA max UDMA/133 abar m2097152@0x814000000000 port 0x814000000100
[ 16.062464] ahci 0001:00:09.0: AHCI 0001.0300 32 slots 1 ports 6 Gbps 0x1 impl SATA mode
[ 16.070558] ahci 0001:00:09.0: flags: 64bit ncq sntf ilck pm led clo only pmp fbs pio slum part ccc apst
[ 16.080121] ahci 0001:00:09.0: port 0 is not capable of FBS
[ 16.085790] ------------[ cut here ]------------
[ 16.090400] WARNING: CPU: 0 PID: 1601 at drivers/ata/libata-core.c:6426 ata_host_activate+0x138/0x150
[ 16.099604]
[ 16.101086] CPU: 0 PID: 1601 Comm: kworker/0:1 Tainted: G W 4.8.1-00004-gf0dadca853a2 #171
[ 16.110464] Hardware name: www.cavium.com ThunderX CRB-2S/ThunderX CRB-2S, BIOS 0.3 Sep 13 2016
[ 16.119150] Workqueue: events work_for_cpu_fn
[ 16.123498] task: ffff800fcb5e4e00 task.stack: ffff800fcb618000
[ 16.129406] PC is at ata_host_activate+0x138/0x150
[ 16.134186] LR is at ata_host_activate+0x5c/0x150
[ 16.138878] pc : [<ffff0000087b7868>] lr : [<ffff0000087b778c>] pstate: 60000045
[ 16.146260] sp : ffff800fcb61bbb0
[ 16.149563] x29: ffff800fcb61bbb0 x28: 0000000000000001
[ 16.154868] x27: ffff000009245408 x26: ffff000009245bf0
[ 16.160172] x25: ffff800fca8e60a0 x24: ffff800fcb45ff18
[ 16.165477] x23: 0000000000000080 x22: ffff000009245bf0
[ 16.170781] x21: 0000000000000000 x20: ffff0000087cddc8
[ 16.176086] x19: ffff800fcb45fe18 x18: ffff0000892f7d77
[ 16.181390] x17: ffff7fe040029e60 x16: ffffffffffffff98
[ 16.186695] x15: 0000000000000006 x14: ffff0000092f7d85
[ 16.192000] x13: ffff000009f3ffff x12: 0000000000000008
[ 16.197304] x11: 0088000000000000 x10: 0140000000000040
[ 16.202608] x9 : 0000000000000000 x8 : ffff000009f36500
[ 16.207913] x7 : 0000000000000006 x6 : ffff800fcb618000
[ 16.213218] x5 : ffff800fcb903900 x4 : 0000000000000000
[ 16.218522] x3 : ffff00001b400104 x2 : ffff800fcb45ff18
[ 16.223827] x1 : 0000000000000040 x0 : 0000000000000000
[ 16.229131]
[ 16.230612] ---[ end trace 2c145cc81872d49f ]---
[ 16.235216] Call trace:
[ 16.237652] Exception stack(0xffff800fcb61b9e0 to 0xffff800fcb61bb10)
[ 16.244081] b9e0: ffff800fcb45fe18 0001000000000000 ffff800fcb61bbb0 ffff0000087b7868
[ 16.251899] ba00: ffff000009f20000 0000000000020000 0000000000000008 00e800000000070f
[ 16.259717] ba20: 0000000000000000 ffff7fe000300180 ffff800fcb61bab0 ffff000008776250
[ 16.267535] ba40: ffff800fca8e60a0 ffff800fca8e6150 0000000000000004 0000000000000040
[ 16.275353] ba60: 0000000000016500 ffff800fcb45ff18 ffff800fcb61bab0 ffff0000087d10e8
[ 16.283170] ba80: 0000000000000000 0000000000000040 ffff800fcb45ff18 ffff00001b400104
[ 16.290988] baa0: 0000000000000000 ffff800fcb903900 ffff800fcb618000 0000000000000006
[ 16.298806] bac0: ffff000009f36500 0000000000000000 0140000000000040 0088000000000000
[ 16.306623] bae0: 0000000000000008 ffff000009f3ffff ffff0000092f7d85 0000000000000006
[ 16.314440] bb00: ffffffffffffff98 ffff7fe040029e60
[ 16.319307] [<ffff0000087b7868>] ata_host_activate+0x138/0x150
[ 16.325128] [<ffff0000087d2950>] ahci_host_activate+0x138/0x170
[ 16.331036] [<ffff0000087ced84>] ahci_init_one+0x8d4/0xd50
[ 16.336510] [<ffff00000850f394>] local_pci_probe+0x3c/0xb8
[ 16.341985] [<ffff0000080cc458>] work_for_cpu_fn+0x18/0x28
[ 16.347458] [<ffff0000080ce710>] process_one_work+0x118/0x378
[ 16.353192] [<ffff0000080cebd8>] worker_thread+0x268/0x4b0
[ 16.358667] [<ffff0000080d4c10>] kthread+0xd0/0xe8
[ 16.363447] [<ffff000008082e90>] ret_from_fork+0x10/0x40
[ 16.369153] scsi host1: ahci
[ 16.372172] ata2: SATA max UDMA/133 abar m2097152@0x815000000000 port 0x815000000100
[ 16.380095] ahci 0001:00:0a.0: AHCI 0001.0300 32 slots 1 ports 6 Gbps 0x1 impl SATA mode
[ 16.388189] ahci 0001:00:0a.0: flags: 64bit ncq sntf ilck pm led clo only pmp fbs pio slum part ccc apst
[ 16.397752] ahci 0001:00:0a.0: port 0 is not capable of FBS
[ 16.403423] ------------[ cut here ]------------
[ 16.408033] WARNING: CPU: 0 PID: 1601 at drivers/ata/libata-core.c:6426 ata_host_activate+0x138/0x150
[ 16.417238]
[ 16.418719] CPU: 0 PID: 1601 Comm: kworker/0:1 Tainted: G W 4.8.1-00004-gf0dadca853a2 #171
[ 16.428098] Hardware name: www.cavium.com ThunderX CRB-2S/ThunderX CRB-2S, BIOS 0.3 Sep 13 2016
[ 16.436784] Workqueue: events work_for_cpu_fn
[ 16.441131] task: ffff800fcb5e4e00 task.stack: ffff800fcb618000
[ 16.447039] PC is at ata_host_activate+0x138/0x150
[ 16.451818] LR is at ata_host_activate+0x5c/0x150
[ 16.456511] pc : [<ffff0000087b7868>] lr : [<ffff0000087b778c>] pstate: 60000045
[ 16.463893] sp : ffff800fcb61bbb0
[ 16.467196] x29: ffff800fcb61bbb0 x28: 0000000000000001
[ 16.472501] x27: ffff000009245408 x26: ffff000009245bf0
[ 16.477806] x25: ffff800fca8e80a0 x24: ffff800fcb451b18
[ 16.483111] x23: 0000000000000080 x22: ffff000009245bf0
[ 16.488415] x21: 0000000000000000 x20: ffff0000087cddc8
[ 16.493720] x19: ffff800fcb451c18 x18: ffff0000892f7d77
[ 16.499025] x17: ffff7fe003f2e6a0 x16: ffffffffffffff98
[ 16.504330] x15: 0000000000000006 x14: ffff0000092f7d85
[ 16.509634] x13: ffff000009f6ffff x12: 0000000000000008
[ 16.514939] x11: 0088000000000000 x10: 0140000000000040
[ 16.520244] x9 : 0000000000000000 x8 : ffff000009f66500
[ 16.525548] x7 : 0000000000000006 x6 : ffff800fcb618000
[ 16.530853] x5 : ffff800fcb905780 x4 : 0000000000000000
[ 16.536158] x3 : ffff00001b800104 [ 16.537881] ata1: SATA link up 6.0 Gbps (SStatus 133 SControl 300)
[ 16.545541] x2 : ffff800fcb451b18
[ 16.549110] x1 : 0000000000000040 x0 : 0000000000000000
[ 16.554414]
[ 16.555893] ---[ end trace 2c145cc81872d4a0 ]---
[ 16.560499] Call trace:
[ 16.562934] Exception stack(0xffff800fcb61b9e0 to 0xffff800fcb61bb10)
[ 16.569363] b9e0: ffff800fcb451c18 0001000000000000 ffff800fcb61bbb0 ffff0000087b7868
[ 16.577181] ba00: ffff000009f50000 0000000000020000 0000000000000008 00e800000000070f
[ 16.584999] ba20: 0000000000000000 ffff7fe000300200 ffff800fcb61bab0 ffff000008776250
[ 16.592817] ba40: ffff800fca8e80a0 ffff800fca8e8150 0000000000000004 0000000000000040
[ 16.600634] ba60: 0000000000016500 ffff800fcb451b18 ffff800fcb61bab0 ffff0000087d10e8
[ 16.608452] ba80: 0000000000000000 0000000000000040 ffff800fcb451b18 ffff00001b800104
[ 16.616270] baa0: 0000000000000000 ffff800fcb905780 ffff800fcb618000 0000000000000006
[ 16.624088] bac0: ffff000009f66500 0000000000000000 0140000000000040 0088000000000000
[ 16.631905] bae0: 0000000000000008 ffff000009f6ffff ffff0000092f7d85 0000000000000006
[ 16.639723] bb00: ffffffffffffff98 ffff7fe003f2e6a0
[ 16.644589] [<ffff0000087b7868>] ata_host_activate+0x138/0x150
[ 16.650411] [<ffff0000087d2950>] ahci_host_activate+0x138/0x170
[ 16.656318] [<ffff0000087ced84>] ahci_init_one+0x8d4/0xd50
[ 16.661793] [<ffff00000850f394>] local_pci_probe+0x3c/0xb8
[ 16.667266] [<ffff0000080cc458>] work_for_cpu_fn+0x18/0x28
[ 16.672741] [<ffff0000080ce710>] process_one_work+0x118/0x378
[ 16.678475] [<ffff0000080cebd8>] worker_thread+0x268/0x4b0
[ 16.683949] [<ffff0000080d4c10>] kthread+0xd0/0xe8
[ 16.688728] [<ffff000008082e90>] ret_from_fork+0x10/0x40
[ 16.692073] ata2: SATA link down (SStatus 0 SControl 300)
[ 16.699826] scsi host2: ahci
[ 16.702835] ata3: SATA max UDMA/133 abar m2097152@0x816000000000 port 0x816000000100
[ 16.710759] ahci 0001:00:0b.0: AHCI 0001.0300 32 slots 1 ports 6 Gbps 0x1 impl SATA mode
[ 16.718852] ahci 0001:00:0b.0: flags: 64bit ncq sntf ilck pm led clo only pmp fbs pio slum part ccc apst
[ 16.728416] ahci 0001:00:0b.0: port 0 is not capable of FBS
[ 16.734084] ------------[ cut here ]------------
[ 16.738693] WARNING: CPU: 0 PID: 1601 at drivers/ata/libata-core.c:6426 ata_host_activate+0x138/0x150
[ 16.747898]
[ 16.749379] CPU: 0 PID: 1601 Comm: kworker/0:1 Tainted: G W 4.8.1-00004-gf0dadca853a2 #171
[ 16.758758] Hardware name: www.cavium.com ThunderX CRB-2S/ThunderX CRB-2S, BIOS 0.3 Sep 13 2016
[ 16.767444] Workqueue: events work_for_cpu_fn
[ 16.771792] task: ffff800fcb5e4e00 task.stack: ffff800fcb618000
[ 16.777699] PC is at ata_host_activate+0x138/0x150
[ 16.782479] LR is at ata_host_activate+0x5c/0x150
[ 16.787171] pc : [<ffff0000087b7868>] lr : [<ffff0000087b778c>] pstate: 60000045
[ 16.794553] sp : ffff800fcb61bbb0
[ 16.797856] x29: ffff800fcb61bbb0 x28: 0000000000000001
[ 16.803161] x27: ffff000009245408 x26: ffff000009245bf0
[ 16.808466] x25: ffff800fca8ea0a0 x24: ffff800fcb45f518
[ 16.813770] x23: 0000000000000080 x22: ffff000009245bf0
[ 16.819075] x21: 0000000000000000 x20: ffff0000087cddc8
[ 16.824380] x19: ffff800fcb45f418 x18: ffff0000892f7d77
[ 16.829685] x17: ffff7fe003f2e6a0 x16: ffffffffffffff98
[ 16.834989] x15: 0000000000000006 x14: ffff0000092f7d85
[ 16.840294] x13: ffff000009fbffff x12: 0000000000000008
[ 16.845599] x11: 0088000000000000 x10: 0140000000000040
[ 16.850903] x9 : 0000000000000000 x8 : ffff000009fb6500
[ 16.856208] x7 : 0000000000000006 x6 : ffff800fcb618000
[ 16.861512] x5 : ffff800fcb907500 x4 : 0000000000000000
[ 16.866817] x3 : ffff00001bc00104 x2 : ffff800fcb45f518
[ 16.872122] x1 : 0000000000000040 x0 : 0000000000000000
[ 16.877426]
[ 16.878906] ---[ end trace 2c145cc81872d4a1 ]---
[ 16.883511] Call trace:
[ 16.885946] Exception stack(0xffff800fcb61b9e0 to 0xffff800fcb61bb10)
[ 16.892376] b9e0: ffff800fcb45f418 0001000000000000 ffff800fcb61bbb0 ffff0000087b7868
[ 16.900194] ba00: ffff000009fa0000 0000000000020000 0000000000000008 00e800000000070f
[ 16.908011] ba20: 0000000000000000 ffff7fe000300280 ffff800fcb61bab0 ffff000008776250
[ 16.915829] ba40: ffff800fca8ea0a0 ffff800fca8ea150 0000000000000004 0000000000000040
[ 16.923647] ba60: 0000000000016500 ffff800fcb45f518 ffff800fcb61bab0 ffff0000087d10e8
[ 16.931465] ba80: 0000000000000000 0000000000000040 ffff800fcb45f518 ffff00001bc00104
[ 16.939283] baa0: 0000000000000000 ffff800fcb907500 ffff800fcb618000 0000000000000006
[ 16.947101] bac0: ffff000009fb6500 0000000000000000 0140000000000040 0088000000000000
[ 16.954918] bae0: 0000000000000008 ffff000009fbffff ffff0000092f7d85 0000000000000006
[ 16.962735] bb00: ffffffffffffff98 ffff7fe003f2e6a0
[ 16.967602] [<ffff0000087b7868>] ata_host_activate+0x138/0x150
[ 16.973424] [<ffff0000087d2950>] ahci_host_activate+0x138/0x170
[ 16.979332] [<ffff0000087ced84>] ahci_init_one+0x8d4/0xd50
[ 16.984805] [<ffff00000850f394>] local_pci_probe+0x3c/0xb8
[ 16.990280] [<ffff0000080cc458>] work_for_cpu_fn+0x18/0x28
[ 16.995753] [<ffff0000080ce710>] process_one_work+0x118/0x378
[ 17.001488] [<ffff0000080cebd8>] worker_thread+0x268/0x4b0
[ 17.006963] [<ffff0000080d4c10>] kthread+0xd0/0xe8
[ 17.011742] [<ffff000008082e90>] ret_from_fork+0x10/0x40
[ 17.017465] scsi host3: ahci
[ 17.020476] ata4: SATA max UDMA/133 abar m2097152@0x817000000000 port 0x817000000100
[ 17.024054] ata3: SATA link down (SStatus 0 SControl 300)
[ 17.033978] ahci 0005:00:08.0: AHCI 0001.0300 32 slots 1 ports 6 Gbps 0x1 impl SATA mode
[ 17.042077] ahci 0005:00:08.0: flags: 64bit ncq sntf ilck pm led clo only pmp fbs pio slum part ccc apst
[ 17.051650] ahci 0005:00:08.0: port 0 is not capable of FBS
[ 17.057638] ------------[ cut here ]------------
[ 17.062263] WARNING: CPU: 49 PID: 1 at drivers/ata/libata-core.c:6426 ata_host_activate+0x138/0x150
[ 17.071295]
[ 17.072781] CPU: 49 PID: 1 Comm: swapper/0 Tainted: G W 4.8.1-00004-gf0dadca853a2 #171
[ 17.081814] Hardware name: www.cavium.com ThunderX CRB-2S/ThunderX CRB-2S, BIOS 0.3 Sep 13 2016
[ 17.090500] task: ffff800fc8340000 task.stack: ffff810000484000
[ 17.096409] PC is at ata_host_activate+0x138/0x150
[ 17.101190] LR is at ata_host_activate+0x5c/0x150
[ 17.105883] pc : [<ffff0000087b7868>] lr : [<ffff0000087b778c>] pstate: 60000045
[ 17.113266] sp : ffff810000487a90
[ 17.116570] x29: ffff810000487a90 x28: 0000000000000001
[ 17.121879] x27: ffff000009245408 x26: ffff000009245bf0
[ 17.127187] x25: ffff8100084810a0 x24: ffff81000a705018
[ 17.132495] x23: 0000000000000080 x22: ffff000009245bf0
[ 17.137803] x21: 0000000000000000 x20: ffff0000087cddc8
[ 17.143110] x19: ffff81000a705118 x18: ffff0000892f7d77
[ 17.148418] x17: ffff7fe003f2e620 x16: 0000000000000002
[ 17.153726] x15: 0000000000000006 x14: ffff0000092f7d85
[ 17.159033] x13: ffff00000a62ffff x12: 0000000000000008
[ 17.164341] x11: 0088000000000000 x10: 0140000000000040
[ 17.169649] x9 : 0000000000000000 x8 : ffff00000a626500
[ 17.174956] x7 : 0000000000000006 x6 : ffff810000484000
[ 17.180264] x5 : ffff81000a71f480 x4 : 0000000000000000
[ 17.185571] x3 : ffff00001e400104 x2 : ffff81000a705018
[ 17.190879] x1 : 0000000000000040 x0 : 0000000000000000
[ 17.196186]
[ 17.197667] ---[ end trace 2c145cc81872d4a2 ]---
[ 17.202274] Call trace:
[ 17.204712] Exception stack(0xffff8100004878c0 to 0xffff8100004879f0)
[ 17.211143] 78c0: ffff81000a705118 0001000000000000 ffff810000487a90 ffff0000087b7868
[ 17.218961] 78e0: ffff00000a610000 0000000000020000 0000000000000008 00e800000000070f
[ 17.226780] 7900: 0000000000000000 ffff7fe000300300 ffff810000487990 ffff000008776250
[ 17.234598] 7920: ffff8100084810a0 ffff810008481150 0000000000000004 0000000000000040
[ 17.242417] 7940: 0000000000016500 ffff81000a705018 ffff810000487990 ffff0000087d10e8
[ 17.250235] 7960: 0000000000000000 0000000000000040 ffff81000a705018 ffff00001e400104
[ 17.258054] 7980: 0000000000000000 ffff81000a71f480 ffff810000484000 0000000000000006
[ 17.265872] 79a0: ffff00000a626500 0000000000000000 0140000000000040 0088000000000000
[ 17.273691] 79c0: 0000000000000008 ffff00000a62ffff ffff0000092f7d85 0000000000000006
[ 17.281508] 79e0: 0000000000000002 ffff7fe003f2e620
[ 17.286376] [<ffff0000087b7868>] ata_host_activate+0x138/0x150
[ 17.292201] [<ffff0000087d2950>] ahci_host_activate+0x138/0x170
[ 17.298111] [<ffff0000087ced84>] ahci_init_one+0x8d4/0xd50
[ 17.303590] [<ffff00000850f394>] local_pci_probe+0x3c/0xb8
[ 17.309065] [<ffff000008510330>] pci_device_probe+0x110/0x148
[ 17.314808] [<ffff00000876ac54>] driver_probe_device+0x204/0x2b0
[ 17.320803] [<ffff00000876adac>] __driver_attach+0xac/0xb0
[ 17.326279] [<ffff000008768d24>] bus_for_each_dev+0x5c/0xa0
[ 17.331840] [<ffff00000876aee8>] driver_attach+0x20/0x28
[ 17.337141] [<ffff0000087697d0>] bus_add_driver+0x1c8/0x230
[ 17.342703] [<ffff00000876b620>] driver_register+0x60/0xf8
[ 17.348178] [<ffff0000085103a0>] __pci_register_driver+0x38/0x40
[ 17.354183] [<ffff0000090b2fec>] ahci_pci_driver_init+0x20/0x28
[ 17.360100] [<ffff000009080c88>] do_one_initcall+0x84/0x114
[ 17.365662] [<ffff000009080ed0>] kernel_init_freeable+0x1b8/0x25c
[ 17.371754] [<ffff000008c20f30>] kernel_init+0x10/0x108
[ 17.376972] [<ffff000008082e90>] ret_from_fork+0x10/0x40
[ 17.382862] scsi host4: ahci
[ 17.385910] ata5: SATA max UDMA/133 abar m2097152@0x914000000000 port 0x914000000100
[ 17.393763] ahci 0005:00:09.0: AHCI 0001.0300 32 slots 1 ports 6 Gbps 0x1 impl SATA mode
[ 17.401864] ahci 0005:00:09.0: flags: 64bit ncq sntf ilck pm led clo only pmp fbs pio slum part ccc apst
[ 17.411425] ahci 0005:00:09.0: port 0 is not capable of FBS
[ 17.417096] ------------[ cut here ]------------
[ 17.421707] WARNING: CPU: 49 PID: 1 at drivers/ata/libata-core.c:6426 ata_host_activate+0x138/0x150
[ 17.430739]
[ 17.432221] CPU: 49 PID: 1 Comm: swapper/0 Tainted: G W 4.8.1-00004-gf0dadca853a2 #171
[ 17.441253] Hardware name: www.cavium.com ThunderX CRB-2S/ThunderX CRB-2S, BIOS 0.3 Sep 13 2016
[ 17.449939] task: ffff800fc8340000 task.stack: ffff810000484000
[ 17.455847] PC is at ata_host_activate+0x138/0x150
[ 17.460627] LR is at ata_host_activate+0x5c/0x150
[ 17.465320] pc : [<ffff0000087b7868>] lr : [<ffff0000087b778c>] pstate: 60000045
[ 17.472703] sp : ffff810000487a90
[ 17.476007] x29: ffff810000487a90 x28: 0000000000000001
[ 17.481314] x27: ffff000009245408 x26: ffff000009245bf0
[ 17.486621] x25: ffff8100084830a0 x24: ffff81000a70fa18
[ 17.491929] x23: 0000000000000080 x22: ffff000009245bf0
[ 17.497236] x21: 0000000000000000 x20: ffff0000087cddc8
[ 17.502544] x19: ffff81000a70f918 x18: ffff0000892f7d77
[ 17.507851] x17: ffff7fe040029ea0 [ 17.509883] ata4: SATA link up 6.0 Gbps (SStatus 133 SControl 300)
[ 17.517234] x16: ffffffffffffff98
[ 17.520804] x15: 0000000000000006 x14: ffff0000092f7d85
[ 17.526112] x13: ffff00000a67ffff x12: 0000000000000008
[ 17.531420] x11: 0088000000000000 x10: 0140000000000040
[ 17.536727] x9 : 0000000000000000 x8 : ffff00000a676500
[ 17.542035] x7 : 0000000000000006 x6 : ffff810000484000
[ 17.547342] x5 : ffff81000a71d680 x4 : 0000000000000000
[ 17.552650] x3 : ffff00001e800104 x2 : ffff81000a70fa18
[ 17.557957] x1 : 0000000000000040 x0 : 0000000000000000
[ 17.563264]
[ 17.564745] ---[ end trace 2c145cc81872d4a3 ]---
[ 17.569351] Call trace:
[ 17.571788] Exception stack(0xffff8100004878c0 to 0xffff8100004879f0)
[ 17.578218] 78c0: ffff81000a70f918 0001000000000000 ffff810000487a90 ffff0000087b7868
[ 17.586036] 78e0: ffff00000a660000 0000000000020000 0000000000000008 00e800000000070f
[ 17.593855] 7900: 0000000000000000 ffff7fe000300380 ffff810000487990 ffff000008776250
[ 17.601673] 7920: ffff8100084830a0 ffff810008483150 0000000000000004 0000000000000040
[ 17.609492] 7940: 0000000000016500 ffff81000a70fa18 ffff810000487990 ffff0000087d10e8
[ 17.617310] 7960: 0000000000000000 0000000000000040 ffff81000a70fa18 ffff00001e800104
[ 17.625129] 7980: 0000000000000000 ffff81000a71d680 ffff810000484000 0000000000000006
[ 17.632947] 79a0: ffff00000a676500 0000000000000000 0140000000000040 0088000000000000
[ 17.640765] 79c0: 0000000000000008 ffff00000a67ffff ffff0000092f7d85 0000000000000006
[ 17.648583] 79e0: ffffffffffffff98 ffff7fe040029ea0
[ 17.653451] [<ffff0000087b7868>] ata_host_activate+0x138/0x150
[ 17.659273] [<ffff0000087d2950>] ahci_host_activate+0x138/0x170
[ 17.665182] [<ffff0000087ced84>] ahci_init_one+0x8d4/0xd50
[ 17.670657] [<ffff00000850f394>] local_pci_probe+0x3c/0xb8
[ 17.676131] [<ffff000008510330>] pci_device_probe+0x110/0x148
[ 17.681867] [<ffff00000876ac54>] driver_probe_device+0x204/0x2b0
[ 17.687863] [<ffff00000876adac>] __driver_attach+0xac/0xb0
[ 17.693337] [<ffff000008768d24>] bus_for_each_dev+0x5c/0xa0
[ 17.698899] [<ffff00000876aee8>] driver_attach+0x20/0x28
[ 17.704200] [<ffff0000087697d0>] bus_add_driver+0x1c8/0x230
[ 17.708031] ata5: SATA link down (SStatus 0 SControl 300)
[ 17.715147] [<ffff00000876b620>] driver_register+0x60/0xf8
[ 17.720621] [<ffff0000085103a0>] __pci_register_driver+0x38/0x40
[ 17.726617] [<ffff0000090b2fec>] ahci_pci_driver_init+0x20/0x28
[ 17.732527] [<ffff000009080c88>] do_one_initcall+0x84/0x114
[ 17.738089] [<ffff000009080ed0>] kernel_init_freeable+0x1b8/0x25c
[ 17.744172] [<ffff000008c20f30>] kernel_init+0x10/0x108
[ 17.749386] [<ffff000008082e90>] ret_from_fork+0x10/0x40
[ 17.755136] scsi host5: ahci
[ 17.758152] ata6: SATA max UDMA/133 abar m2097152@0x915000000000 port 0x915000000100
[ 17.766004] ahci 0005:00:0a.0: AHCI 0001.0300 32 slots 1 ports 6 Gbps 0x1 impl SATA mode
[ 17.774095] ahci 0005:00:0a.0: flags: 64bit ncq sntf ilck pm led clo only pmp fbs pio slum part ccc apst
[ 17.783660] ahci 0005:00:0a.0: port 0 is not capable of FBS
[ 17.789335] ------------[ cut here ]------------
[ 17.793946] WARNING: CPU: 49 PID: 1 at drivers/ata/libata-core.c:6426 ata_host_activate+0x138/0x150
[ 17.802977]
[ 17.804460] CPU: 49 PID: 1 Comm: swapper/0 Tainted: G W 4.8.1-00004-gf0dadca853a2 #171
[ 17.813491] Hardware name: www.cavium.com ThunderX CRB-2S/ThunderX CRB-2S, BIOS 0.3 Sep 13 2016
[ 17.822177] task: ffff800fc8340000 task.stack: ffff810000484000
[ 17.828085] PC is at ata_host_activate+0x138/0x150
[ 17.832866] LR is at ata_host_activate+0x5c/0x150
[ 17.837559] pc : [<ffff0000087b7868>] lr : [<ffff0000087b778c>] pstate: 60000045
[ 17.844942] sp : ffff810000487a90
[ 17.848246] x29: ffff810000487a90 x28: 0000000000000001
[ 17.853553] x27: ffff000009245408 x26: ffff000009245bf0
[ 17.858861] x25: ffff8100084850a0 x24: ffff81000a705e18
[ 17.864169] x23: 0000000000000080 x22: ffff000009245bf0
[ 17.869477] x21: 0000000000000000 x20: ffff0000087cddc8
[ 17.874784] x19: ffff81000a705f18 x18: ffff0000892f7d77
[ 17.880092] x17: ffff7fe040029ea0 x16: ffffffffffffff98
[ 17.885399] x15: 0000000000000006 x14: ffff0000092f7d85
[ 17.890707] x13: ffff00000a6dffff x12: 0000000000000008
[ 17.896014] x11: 0088000000000000 x10: 0140000000000040
[ 17.901321] x9 : 0000000000000000 x8 : ffff00000a6d6500
[ 17.906628] x7 : 0000000000000006 x6 : ffff810000484000
[ 17.911936] x5 : ffff81000a71b880 x4 : 0000000000000000
[ 17.917244] x3 : ffff00001ec00104 x2 : ffff81000a705e18
[ 17.922551] x1 : 0000000000000040 x0 : 0000000000000000
[ 17.927858]
[ 17.929339] ---[ end trace 2c145cc81872d4a4 ]---
[ 17.933945] Call trace:
[ 17.936381] Exception stack(0xffff8100004878c0 to 0xffff8100004879f0)
[ 17.942811] 78c0: ffff81000a705f18 0001000000000000 ffff810000487a90 ffff0000087b7868
[ 17.950630] 78e0: ffff00000a6c0000 0000000000020000 0000000000000008 00e800000000070f
[ 17.958449] 7900: 0000000000000000 ffff7fe000300400 ffff810000487990 ffff000008776250
[ 17.966267] 7920: ffff8100084850a0 ffff810008485150 0000000000000004 0000000000000040
[ 17.974085] 7940: 0000000000016500 ffff81000a705e18 ffff810000487990 ffff0000087d10e8
[ 17.981904] 7960: 0000000000000000 0000000000000040 ffff81000a705e18 ffff00001ec00104
[ 17.989722] 7980: 0000000000000000 ffff81000a71b880 ffff810000484000 0000000000000006
[ 17.997541] 79a0: ffff00000a6d6500 0000000000000000 0140000000000040 0088000000000000
[ 18.005359] 79c0: 0000000000000008 ffff00000a6dffff ffff0000092f7d85 0000000000000006
[ 18.013177] 79e0: ffffffffffffff98 ffff7fe040029ea0
[ 18.018044] [<ffff0000087b7868>] ata_host_activate+0x138/0x150
[ 18.023867] [<ffff0000087d2950>] ahci_host_activate+0x138/0x170
[ 18.029775] [<ffff0000087ced84>] ahci_init_one+0x8d4/0xd50
[ 18.035250] [<ffff00000850f394>] local_pci_probe+0x3c/0xb8
[ 18.040725] [<ffff000008510330>] pci_device_probe+0x110/0x148
[ 18.046460] [<ffff00000876ac54>] driver_probe_device+0x204/0x2b0
[ 18.052456] [<ffff00000876adac>] __driver_attach+0xac/0xb0
[ 18.057931] [<ffff000008768d24>] bus_for_each_dev+0x5c/0xa0
[ 18.063492] [<ffff00000876aee8>] driver_attach+0x20/0x28
[ 18.068793] [<ffff0000087697d0>] bus_add_driver+0x1c8/0x230
[ 18.074355] [<ffff00000876b620>] driver_register+0x60/0xf8
[ 18.079829] [<ffff0000085103a0>] __pci_register_driver+0x38/0x40
[ 18.080051] ata6: SATA link down (SStatus 0 SControl 300)
[ 18.091210] [<ffff0000090b2fec>] ahci_pci_driver_init+0x20/0x28
[ 18.097120] [<ffff000009080c88>] do_one_initcall+0x84/0x114
[ 18.102682] [<ffff000009080ed0>] kernel_init_freeable+0x1b8/0x25c
[ 18.108765] [<ffff000008c20f30>] kernel_init+0x10/0x108
[ 18.113979] [<ffff000008082e90>] ret_from_fork+0x10/0x40
[ 18.119725] scsi host6: ahci
[ 18.122747] ata7: SATA max UDMA/133 abar m2097152@0x916000000000 port 0x916000000100
[ 18.130601] ahci 0005:00:0b.0: AHCI 0001.0300 32 slots 1 ports 6 Gbps 0x1 impl SATA mode
[ 18.138693] ahci 0005:00:0b.0: flags: 64bit ncq sntf ilck pm led clo only pmp fbs pio slum part ccc apst
[ 18.148258] ahci 0005:00:0b.0: port 0 is not capable of FBS
[ 18.153931] ------------[ cut here ]------------
[ 18.158542] WARNING: CPU: 49 PID: 1 at drivers/ata/libata-core.c:6426 ata_host_activate+0x138/0x150
[ 18.167574]
[ 18.169057] CPU: 49 PID: 1 Comm: swapper/0 Tainted: G W 4.8.1-00004-gf0dadca853a2 #171
[ 18.178089] Hardware name: www.cavium.com ThunderX CRB-2S/ThunderX CRB-2S, BIOS 0.3 Sep 13 2016
[ 18.186774] task: ffff800fc8340000 task.stack: ffff810000484000
[ 18.192683] PC is at ata_host_activate+0x138/0x150
[ 18.197463] LR is at ata_host_activate+0x5c/0x150
[ 18.202156] pc : [<ffff0000087b7868>] lr : [<ffff0000087b778c>] pstate: 60000045
[ 18.209539] sp : ffff810000487a90
[ 18.212843] x29: ffff810000487a90 x28: 0000000000000001
[ 18.218150] x27: ffff000009245408 x26: ffff000009245bf0
[ 18.223458] x25: ffff8100084870a0 x24: ffff81000a70ec18
[ 18.228765] x23: 0000000000000080 x22: ffff000009245bf0
[ 18.234073] x21: 0000000000000000 x20: ffff0000087cddc8
[ 18.239380] x19: ffff81000a70eb18 x18: ffff0000892f7d77
[ 18.244688] x17: ffff7fe040029ee0 x16: ffffffffffffff98
[ 18.249995] x15: 0000000000000006 x14: ffff0000092f7d85
[ 18.255303] x13: ffff00000a73ffff x12: 0000000000000008
[ 18.260611] x11: 0088000000000000 x10: 0140000000000040
[ 18.265918] x9 : 0000000000000000 x8 : ffff00000a736500
[ 18.271225] x7 : 0000000000000006 x6 : ffff810000484000
[ 18.276533] x5 : ffff81000a719a80 x4 : 0000000000000000
[ 18.281840] x3 : ffff00001f000104 x2 : ffff81000a70ec18
[ 18.287148] x1 : 0000000000000040 x0 : 0000000000000000
[ 18.292455]
[ 18.293936] ---[ end trace 2c145cc81872d4a5 ]---
[ 18.298542] Call trace:
[ 18.300979] Exception stack(0xffff8100004878c0 to 0xffff8100004879f0)
[ 18.307409] 78c0: ffff81000a70eb18 0001000000000000 ffff810000487a90 ffff0000087b7868
[ 18.315228] 78e0: ffff00000a720000 0000000000020000 0000000000000008 00e800000000070f
[ 18.323046] 7900: 0000000000000000 ffff7fe000300480 ffff810000487990 ffff000008776250
[ 18.330865] 7920: ffff8100084870a0 ffff810008487150 0000000000000004 0000000000000040
[ 18.338683] 7940: 0000000000016500 ffff81000a70ec18 ffff810000487990 ffff0000087d10e8
[ 18.346502] 7960: 0000000000000000 0000000000000040 ffff81000a70ec18 ffff00001f000104
[ 18.354320] 7980: 0000000000000000 ffff81000a719a80 ffff810000484000 0000000000000006
[ 18.362139] 79a0: ffff00000a736500 0000000000000000 0140000000000040 0088000000000000
[ 18.369957] 79c0: 0000000000000008 ffff00000a73ffff ffff0000092f7d85 0000000000000006
[ 18.377775] 79e0: ffffffffffffff98 ffff7fe040029ee0
[ 18.382643] [<ffff0000087b7868>] ata_host_activate+0x138/0x150
[ 18.388465] [<ffff0000087d2950>] ahci_host_activate+0x138/0x170
[ 18.394373] [<ffff0000087ced84>] ahci_init_one+0x8d4/0xd50
[ 18.399848] [<ffff00000850f394>] local_pci_probe+0x3c/0xb8
[ 18.405323] [<ffff000008510330>] pci_device_probe+0x110/0x148
[ 18.411059] [<ffff00000876ac54>] driver_probe_device+0x204/0x2b0
[ 18.417055] [<ffff00000876adac>] __driver_attach+0xac/0xb0
[ 18.422529] [<ffff000008768d24>] bus_for_each_dev+0x5c/0xa0
[ 18.428091] [<ffff00000876aee8>] driver_attach+0x20/0x28
[ 18.433392] [<ffff0000087697d0>] bus_add_driver+0x1c8/0x230
[ 18.438954] [<ffff00000876b620>] driver_register+0x60/0xf8
[ 18.444010] ata7: SATA link down (SStatus 0 SControl 300)
[ 18.449813] [<ffff0000085103a0>] __pci_register_driver+0x38/0x40
[ 18.455809] [<ffff0000090b2fec>] ahci_pci_driver_init+0x20/0x28
[ 18.461719] [<ffff000009080c88>] do_one_initcall+0x84/0x114
[ 18.467281] [<ffff000009080ed0>] kernel_init_freeable+0x1b8/0x25c
[ 18.473364] [<ffff000008c20f30>] kernel_init+0x10/0x108
[ 18.478578] [<ffff000008082e90>] ret_from_fork+0x10/0x40
[ 18.484409] scsi host7: ahci
[ 18.487425] ata8: SATA max UDMA/133 abar m2097152@0x917000000000 port 0x917000000100
...
[ 18.808074] ata8: SATA link down (SStatus 0 SControl 300)
...
[ 21.765921] ata1.00: qc timeout (cmd 0xec)
[ 21.770031] ata1.00: failed to IDENTIFY (I/O error, err_mask=0x4)
[ 22.249869] ata1: SATA link up 6.0 Gbps (SStatus 133 SControl 300)
[ 22.533896] ata4.00: qc timeout (cmd 0xec)
[ 22.537996] ata4.00: failed to IDENTIFY (I/O error, err_mask=0x4)
[ 23.017874] ata4: SATA link up 6.0 Gbps (SStatus 133 SControl 300)
[ 32.261874] ata1.00: qc timeout (cmd 0xec)
[ 32.265972] ata1.00: failed to IDENTIFY (I/O error, err_mask=0x4)
[ 32.272059] ata1: limiting SATA link speed to 3.0 Gbps
[ 32.753873] ata1: SATA link up 3.0 Gbps (SStatus 123 SControl 320)
[ 33.029878] ata4.00: qc timeout (cmd 0xec)
[ 33.033978] ata4.00: failed to IDENTIFY (I/O error, err_mask=0x4)
[ 33.040066] ata4: limiting SATA link speed to 3.0 Gbps
[ 33.521884] ata4: SATA link up 3.0 Gbps (SStatus 123 SControl 320)
[ 63.493874] ata1.00: qc timeout (cmd 0xec)
[ 63.497973] ata1.00: failed to IDENTIFY (I/O error, err_mask=0x4)
[ 63.977867] ata1: SATA link up 3.0 Gbps (SStatus 123 SControl 320)
[ 65.541890] ata4.00: qc timeout (cmd 0xec)
[ 65.545987] ata4.00: failed to IDENTIFY (I/O error, err_mask=0x4)
[ 66.025873] ata4: SATA link up 3.0 Gbps (SStatus 123 SControl 320)
[ 66.032337] VFS: Cannot open root device "sda2" or unknown-block(0,0): error -6
[ 66.039682] Please append a correct "root=" boot option; here are the available partitions:
[ 66.048047] Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(0,0)
[ 66.056304] CPU: 55 PID: 1 Comm: swapper/0 Tainted: G W 4.8.1-00004-gf0dadca853a2 #171
[ 66.065337] Hardware name: www.cavium.com ThunderX CRB-2S/ThunderX CRB-2S, BIOS 0.3 Sep 13 2016
[ 66.074023] Call trace:
[ 66.076474] [<ffff0000080883c8>] dump_backtrace+0x0/0x1a0
[ 66.081863] [<ffff00000808857c>] show_stack+0x14/0x20
[ 66.086908] [<ffff00000849adf4>] dump_stack+0x94/0xb8
[ 66.091956] [<ffff00000815df94>] panic+0x10c/0x26c
[ 66.096744] [<ffff000009081318>] mount_block_root+0x18c/0x264
[ 66.102480] [<ffff00000908150c>] mount_root+0x11c/0x134
[ 66.107695] [<ffff000009081660>] prepare_namespace+0x13c/0x184
[ 66.113517] [<ffff000009080f50>] kernel_init_freeable+0x238/0x25c
[ 66.119607] [<ffff000008c20f30>] kernel_init+0x10/0x108
[ 66.124822] [<ffff000008082e90>] ret_from_fork+0x10/0x40
[ 66.130125] SMP: stopping secondary CPUs
^ permalink raw reply
* Re: Regression with 0b9e2988ab22 ("ahci: use pci_alloc_irq_vectors")
From: Christoph Hellwig @ 2016-10-21 13:27 UTC (permalink / raw)
To: Jarkko Nikula; +Cc: Christoph Hellwig, linux-ide, linux-kernel
In-Reply-To: <9d293889-3215-403b-bdf9-c24b684f18f0@linux.intel.com>
Hi Jarkko,
please try the two fixes queue up in the libata tree for this:
https://git.kernel.org/cgit/linux/kernel/git/tj/libata.git/log/?h=for-4.9-fixes
^ permalink raw reply
* Regression with 0b9e2988ab22 ("ahci: use pci_alloc_irq_vectors")
From: Jarkko Nikula @ 2016-10-21 13:09 UTC (permalink / raw)
To: Christoph Hellwig; +Cc: linux-ide, linux-kernel
Hi
SATA stopped working on Intel SoCs that have single SATA port after
v4.9-rc1:
[ 8.705008] ata1.00: qc timeout (cmd 0x27)
[ 8.709164] ata1.00: failed to read native max address (err_mask=0x4)
[ 8.715557] ata1.00: HPA support seems broken, skipping HPA handling
[ 9.029754] ata1: SATA link up 6.0 Gbps (SStatus 133 SControl 300)
[ 14.337028] ata1.00: qc timeout (cmd 0xef)
[ 14.341185] ata1.00: failed to enable AA (error_mask=0x4)
[ 14.346557] ata1: limiting SATA link speed to 3.0 Gbps
[ 14.666922] ata1: SATA link up 3.0 Gbps (SStatus 123 SControl 320)
[ 14.684359] ata1.00: ATA-9: INTEL SSDSC2BW240A4, DC32, max UDMA/133
[ 14.690650] ata1.00: 468862128 sectors, multi 16: LBA48 NCQ (depth 31/32)
[ 19.969116] ata1.00: qc timeout (cmd 0x47)
[ 19.973307] ata1.00: READ LOG DMA EXT failed, trying unqueued
[ 19.979026] ata1.00: failed to set xfermode (err_mask=0x40)
[ 19.984559] ata1.00: disabled
[ 19.987527] ata1: hard resetting link
[ 20.306943] ata1: SATA link up 3.0 Gbps (SStatus 123 SControl 320)
[ 20.313163] ata1: EH complete
I bisected this into commit 0b9e2988ab22 ("ahci: use
pci_alloc_irq_vectors").
I did some debugging on a few machines (Skylake, Broxton, Kaby Lake and
Bay Trail based) in our lab.
Before 0b9e2988ab22:
- All of those machines are using MSI for AHCI
- Number of SATA ports 1-4
- pci_msi_vec_count() returns 1 for all machines
After 0b9e2988ab22:
- SATA stopped working on machines with single port:
* pci_alloc_irq_vectors() returns 1
* Allocates the same MSI irq number as before but handler name
is (null)
- With >1 ports AHCI defaults now to IO-APIC but continues working
* pci_alloc_irq_vectors() returns -EINVAL from
__pci_enable_msi_range() due if (nvec < minvec) test.
--
Jarkko
^ permalink raw reply
* Re: [PATCH] ahci: use pci_alloc_irq_vectors
From: Christoph Hellwig @ 2016-10-21 12:59 UTC (permalink / raw)
To: Robert Richter
Cc: Tejun Heo, Christoph Hellwig, dan.j.williamps, linux-ide,
linux-arm-kernel, Marc Zyngier, Auger Eric
In-Reply-To: <20161020154722.GH22012@rric.localdomain>
Hi Robert,
can you try the latest fixed in the libata tree:
https://git.kernel.org/cgit/linux/kernel/git/tj/libata.git/log/?h=for-4.9-fixes
^ permalink raw reply
* Re: [PATCH v2 1/1] ahci: imx: Add imx53 SATA temperature sensor support
From: Bartlomiej Zolnierkiewicz @ 2016-10-21 10:56 UTC (permalink / raw)
To: Fabien Lahoudere
Cc: tj, linux-ide, linux-kernel, rui.zhang, edubezval, Csaba Kertesz
In-Reply-To: <1477034768-11721-1-git-send-email-fabien.lahoudere@collabora.co.uk>
Hi,
On Friday, October 21, 2016 09:26:08 AM Fabien Lahoudere wrote:
> From: Csaba Kertesz <csaba.kertesz@vincit.fi>
>
> Add a hwmon entry to get the temperature from the die of imx53
> SATA.
>
> The original patch was made by Richard Zhu for kernel 2.6.x:
> ENGR00134041-MX53-Add-the-SATA-AHCI-temperature-monitor.patch
>
> Signed-off-by: Fabien Lahoudere <fabien.lahoudere@collabora.co.uk>
> ---
> drivers/ata/ahci_imx.c | 225 +++++++++++++++++++++++++++++++++++++++++++++++++
> 1 file changed, 225 insertions(+)
>
> diff --git a/drivers/ata/ahci_imx.c b/drivers/ata/ahci_imx.c
> index 3f3a7db..a2a8c63 100644
> --- a/drivers/ata/ahci_imx.c
> +++ b/drivers/ata/ahci_imx.c
> @@ -26,6 +26,9 @@
> #include <linux/mfd/syscon.h>
> #include <linux/mfd/syscon/imx6q-iomuxc-gpr.h>
> #include <linux/libata.h>
> +#include <linux/hwmon.h>
> +#include <linux/hwmon-sysfs.h>
> +#include <linux/thermal.h>
> #include "ahci.h"
>
> #define DRV_NAME "ahci-imx"
> @@ -214,6 +217,210 @@ static int imx_sata_phy_reset(struct ahci_host_priv *hpriv)
> return timeout ? 0 : -ETIMEDOUT;
> }
>
> +enum {
> + /* SATA PHY Register */
> + SATA_PHY_CR_CLOCK_CRCMP_LT_LIMIT = 0x0001,
> + SATA_PHY_CR_CLOCK_DAC_CTL = 0x0008,
> + SATA_PHY_CR_CLOCK_RTUNE_CTL = 0x0009,
> + SATA_PHY_CR_CLOCK_ADC_OUT = 0x000A,
> + SATA_PHY_CR_CLOCK_MPLL_TST = 0x0017,
> +};
> +
> +/* SATA AHCI temperature monitor */
> +static int sata_ahci_read_temperature(void *dev, int *temp)
> +{
> + u16 mpll_test_reg, rtune_ctl_reg, dac_ctl_reg, adc_out_reg, read_sum;
> + u32 str1, str2, str3, str4, index, read_attempt;
> + const u32 attempt_limit = 100;
> + int m1, m2, a;
> + struct ahci_host_priv *hpriv = dev_get_drvdata(dev);
> + void __iomem *mmio = hpriv->mmio;
> +
> + /* check rd-wr to reg */
> + read_sum = 0;
> + imx_phy_reg_addressing(SATA_PHY_CR_CLOCK_CRCMP_LT_LIMIT, mmio);
> + imx_phy_reg_write(read_sum, mmio);
> + imx_phy_reg_read(&read_sum, mmio);
> + if ((read_sum & 0xffff) != 0)
> + dev_err(dev, "Read/Write REG error, 0x%x!\n", read_sum);
> +
> + imx_phy_reg_write(0x5A5A, mmio);
> + imx_phy_reg_read(&read_sum, mmio);
> + if ((read_sum & 0xffff) != 0x5A5A)
> + dev_err(dev, "Read/Write REG error, 0x%x!\n", read_sum);
> +
> + imx_phy_reg_write(0x1234, mmio);
> + imx_phy_reg_read(&read_sum, mmio);
> + if ((read_sum & 0xffff) != 0x1234)
> + dev_err(dev, "Read/Write REG error, 0x%x!\n", read_sum);
> +
> + /* start temperature test */
> + imx_phy_reg_addressing(SATA_PHY_CR_CLOCK_MPLL_TST, mmio);
> + imx_phy_reg_read(&mpll_test_reg, mmio);
> + imx_phy_reg_addressing(SATA_PHY_CR_CLOCK_RTUNE_CTL, mmio);
> + imx_phy_reg_read(&rtune_ctl_reg, mmio);
> + imx_phy_reg_addressing(SATA_PHY_CR_CLOCK_DAC_CTL, mmio);
> + imx_phy_reg_read(&dac_ctl_reg, mmio);
> +
> + /* mpll_tst.meas_iv ([12:2]) */
> + str1 = (mpll_test_reg >> 2) & 0x7FF;
> + /* rtune_ctl.mode ([1:0]) */
> + str2 = (rtune_ctl_reg) & 0x3;
> + /* dac_ctl.dac_mode ([14:12]) */
> + str3 = (dac_ctl_reg >> 12) & 0x7;
> + /* rtune_ctl.sel_atbp ([4]) */
> + str4 = (rtune_ctl_reg >> 4);
> +
> + /* Calculate the m1 */
> + /* mpll_tst.meas_iv */
> + mpll_test_reg = (mpll_test_reg & 0xE03) | (512) << 2;
> + /* rtune_ctl.mode */
> + rtune_ctl_reg = (rtune_ctl_reg & 0xFFC) | (1);
> + /* dac_ctl.dac_mode */
> + dac_ctl_reg = (dac_ctl_reg & 0x8FF) | (4) << 12;
> + /* rtune_ctl.sel_atbp */
> + rtune_ctl_reg = (rtune_ctl_reg & 0xFEF) | (0) << 4;
> +
> + imx_phy_reg_addressing(SATA_PHY_CR_CLOCK_MPLL_TST, mmio);
> + imx_phy_reg_write(mpll_test_reg, mmio);
> + imx_phy_reg_addressing(SATA_PHY_CR_CLOCK_DAC_CTL, mmio);
> + imx_phy_reg_write(dac_ctl_reg, mmio);
The code below is duplicated later for obtaining m2.
It should be moved to a common helper function.
> + imx_phy_reg_addressing(SATA_PHY_CR_CLOCK_RTUNE_CTL, mmio);
> + imx_phy_reg_write(rtune_ctl_reg, mmio);
> +
> + /* two dummy read */
> + index = 0;
> + read_attempt = 0;
> + adc_out_reg = 0;
> + imx_phy_reg_addressing(SATA_PHY_CR_CLOCK_ADC_OUT, mmio);
> + while (index < 2) {
> + imx_phy_reg_read(&adc_out_reg, mmio);
> + /* check if valid */
> + if (adc_out_reg & 0x400)
> + index++;
> +
> + read_attempt++;
> + if (read_attempt > attempt_limit) {
> + dev_err(dev, "Read REG more than %d times!\n",
> + attempt_limit);
> + break;
> + }
> + }
> +
> + index = 0;
> + read_attempt = 0;
> + read_sum = 0;
> + while (index < 80) {
> + imx_phy_reg_read(&adc_out_reg, mmio);
> + if (adc_out_reg & 0x400) {
> + read_sum = read_sum + (adc_out_reg & 0x3FF);
> + index++;
> + }
> + read_attempt++;
> + if (read_attempt > attempt_limit) {
> + dev_err(dev, "Read REG more than %d times!\n",
> + attempt_limit);
> + break;
> + }
> + }
(end of duplicated code)
> + /* Use the U32 to make 1000 precision */
> + m1 = (read_sum * 1000) / 80;
> +
> + /* Calculate the m2 */
> + /* rtune_ctl.sel_atbp */
> + rtune_ctl_reg = (rtune_ctl_reg & 0xFEF) | (1) << 4;
> + imx_phy_reg_addressing(SATA_PHY_CR_CLOCK_RTUNE_CTL, mmio);
> + imx_phy_reg_write(rtune_ctl_reg, mmio);
> +
> + /* two dummy read */
> + index = 0;
> + read_attempt = 0;
adc_out_reg zeroing is missing here
> + imx_phy_reg_addressing(SATA_PHY_CR_CLOCK_ADC_OUT, mmio);
> + while (index < 2) {
> + imx_phy_reg_read(&adc_out_reg, mmio);
> + /* check if valid */
> + if (adc_out_reg & 0x400)
> + index++;
> +
> + read_attempt++;
> + if (read_attempt > attempt_limit) {
> + dev_err(dev, "Read REG more than %d times!\n",
> + attempt_limit);
> + break;
> + }
> + }
> +
> + index = 0;
> + read_attempt = 0;
> + read_sum = 0;
> + while (index < 80) {
> + imx_phy_reg_read(&adc_out_reg, mmio);
> + if (adc_out_reg & 0x400) {
> + read_sum = read_sum + (adc_out_reg & 0x3FF);
> + index++;
> + }
> + read_attempt++;
> + if (read_attempt > attempt_limit) {
> + dev_err(dev, "Read REG more than %d times!\n",
> + attempt_limit);
> + break;
> + }
> + }
> + /* Use the U32 to make 1000 precision */
> + m2 = (read_sum * 1000) / 80;
The rest looks fine to me.
Best regards,
--
Bartlomiej Zolnierkiewicz
Samsung R&D Institute Poland
Samsung Electronics
^ permalink raw reply
* [PATCH v2 1/1] ahci: imx: Add imx53 SATA temperature sensor support
From: Fabien Lahoudere @ 2016-10-21 7:26 UTC (permalink / raw)
To: tj
Cc: linux-ide, linux-kernel, rui.zhang, edubezval, Csaba Kertesz,
Fabien Lahoudere
In-Reply-To: <20161019173137.GE18532@htj.duckdns.org>
From: Csaba Kertesz <csaba.kertesz@vincit.fi>
Add a hwmon entry to get the temperature from the die of imx53
SATA.
The original patch was made by Richard Zhu for kernel 2.6.x:
ENGR00134041-MX53-Add-the-SATA-AHCI-temperature-monitor.patch
Signed-off-by: Fabien Lahoudere <fabien.lahoudere@collabora.co.uk>
---
drivers/ata/ahci_imx.c | 225 +++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 225 insertions(+)
diff --git a/drivers/ata/ahci_imx.c b/drivers/ata/ahci_imx.c
index 3f3a7db..a2a8c63 100644
--- a/drivers/ata/ahci_imx.c
+++ b/drivers/ata/ahci_imx.c
@@ -26,6 +26,9 @@
#include <linux/mfd/syscon.h>
#include <linux/mfd/syscon/imx6q-iomuxc-gpr.h>
#include <linux/libata.h>
+#include <linux/hwmon.h>
+#include <linux/hwmon-sysfs.h>
+#include <linux/thermal.h>
#include "ahci.h"
#define DRV_NAME "ahci-imx"
@@ -214,6 +217,210 @@ static int imx_sata_phy_reset(struct ahci_host_priv *hpriv)
return timeout ? 0 : -ETIMEDOUT;
}
+enum {
+ /* SATA PHY Register */
+ SATA_PHY_CR_CLOCK_CRCMP_LT_LIMIT = 0x0001,
+ SATA_PHY_CR_CLOCK_DAC_CTL = 0x0008,
+ SATA_PHY_CR_CLOCK_RTUNE_CTL = 0x0009,
+ SATA_PHY_CR_CLOCK_ADC_OUT = 0x000A,
+ SATA_PHY_CR_CLOCK_MPLL_TST = 0x0017,
+};
+
+/* SATA AHCI temperature monitor */
+static int sata_ahci_read_temperature(void *dev, int *temp)
+{
+ u16 mpll_test_reg, rtune_ctl_reg, dac_ctl_reg, adc_out_reg, read_sum;
+ u32 str1, str2, str3, str4, index, read_attempt;
+ const u32 attempt_limit = 100;
+ int m1, m2, a;
+ struct ahci_host_priv *hpriv = dev_get_drvdata(dev);
+ void __iomem *mmio = hpriv->mmio;
+
+ /* check rd-wr to reg */
+ read_sum = 0;
+ imx_phy_reg_addressing(SATA_PHY_CR_CLOCK_CRCMP_LT_LIMIT, mmio);
+ imx_phy_reg_write(read_sum, mmio);
+ imx_phy_reg_read(&read_sum, mmio);
+ if ((read_sum & 0xffff) != 0)
+ dev_err(dev, "Read/Write REG error, 0x%x!\n", read_sum);
+
+ imx_phy_reg_write(0x5A5A, mmio);
+ imx_phy_reg_read(&read_sum, mmio);
+ if ((read_sum & 0xffff) != 0x5A5A)
+ dev_err(dev, "Read/Write REG error, 0x%x!\n", read_sum);
+
+ imx_phy_reg_write(0x1234, mmio);
+ imx_phy_reg_read(&read_sum, mmio);
+ if ((read_sum & 0xffff) != 0x1234)
+ dev_err(dev, "Read/Write REG error, 0x%x!\n", read_sum);
+
+ /* start temperature test */
+ imx_phy_reg_addressing(SATA_PHY_CR_CLOCK_MPLL_TST, mmio);
+ imx_phy_reg_read(&mpll_test_reg, mmio);
+ imx_phy_reg_addressing(SATA_PHY_CR_CLOCK_RTUNE_CTL, mmio);
+ imx_phy_reg_read(&rtune_ctl_reg, mmio);
+ imx_phy_reg_addressing(SATA_PHY_CR_CLOCK_DAC_CTL, mmio);
+ imx_phy_reg_read(&dac_ctl_reg, mmio);
+
+ /* mpll_tst.meas_iv ([12:2]) */
+ str1 = (mpll_test_reg >> 2) & 0x7FF;
+ /* rtune_ctl.mode ([1:0]) */
+ str2 = (rtune_ctl_reg) & 0x3;
+ /* dac_ctl.dac_mode ([14:12]) */
+ str3 = (dac_ctl_reg >> 12) & 0x7;
+ /* rtune_ctl.sel_atbp ([4]) */
+ str4 = (rtune_ctl_reg >> 4);
+
+ /* Calculate the m1 */
+ /* mpll_tst.meas_iv */
+ mpll_test_reg = (mpll_test_reg & 0xE03) | (512) << 2;
+ /* rtune_ctl.mode */
+ rtune_ctl_reg = (rtune_ctl_reg & 0xFFC) | (1);
+ /* dac_ctl.dac_mode */
+ dac_ctl_reg = (dac_ctl_reg & 0x8FF) | (4) << 12;
+ /* rtune_ctl.sel_atbp */
+ rtune_ctl_reg = (rtune_ctl_reg & 0xFEF) | (0) << 4;
+
+ imx_phy_reg_addressing(SATA_PHY_CR_CLOCK_MPLL_TST, mmio);
+ imx_phy_reg_write(mpll_test_reg, mmio);
+ imx_phy_reg_addressing(SATA_PHY_CR_CLOCK_DAC_CTL, mmio);
+ imx_phy_reg_write(dac_ctl_reg, mmio);
+ imx_phy_reg_addressing(SATA_PHY_CR_CLOCK_RTUNE_CTL, mmio);
+ imx_phy_reg_write(rtune_ctl_reg, mmio);
+
+ /* two dummy read */
+ index = 0;
+ read_attempt = 0;
+ adc_out_reg = 0;
+ imx_phy_reg_addressing(SATA_PHY_CR_CLOCK_ADC_OUT, mmio);
+ while (index < 2) {
+ imx_phy_reg_read(&adc_out_reg, mmio);
+ /* check if valid */
+ if (adc_out_reg & 0x400)
+ index++;
+
+ read_attempt++;
+ if (read_attempt > attempt_limit) {
+ dev_err(dev, "Read REG more than %d times!\n",
+ attempt_limit);
+ break;
+ }
+ }
+
+ index = 0;
+ read_attempt = 0;
+ read_sum = 0;
+ while (index < 80) {
+ imx_phy_reg_read(&adc_out_reg, mmio);
+ if (adc_out_reg & 0x400) {
+ read_sum = read_sum + (adc_out_reg & 0x3FF);
+ index++;
+ }
+ read_attempt++;
+ if (read_attempt > attempt_limit) {
+ dev_err(dev, "Read REG more than %d times!\n",
+ attempt_limit);
+ break;
+ }
+ }
+ /* Use the U32 to make 1000 precision */
+ m1 = (read_sum * 1000) / 80;
+
+ /* Calculate the m2 */
+ /* rtune_ctl.sel_atbp */
+ rtune_ctl_reg = (rtune_ctl_reg & 0xFEF) | (1) << 4;
+ imx_phy_reg_addressing(SATA_PHY_CR_CLOCK_RTUNE_CTL, mmio);
+ imx_phy_reg_write(rtune_ctl_reg, mmio);
+
+ /* two dummy read */
+ index = 0;
+ read_attempt = 0;
+ imx_phy_reg_addressing(SATA_PHY_CR_CLOCK_ADC_OUT, mmio);
+ while (index < 2) {
+ imx_phy_reg_read(&adc_out_reg, mmio);
+ /* check if valid */
+ if (adc_out_reg & 0x400)
+ index++;
+
+ read_attempt++;
+ if (read_attempt > attempt_limit) {
+ dev_err(dev, "Read REG more than %d times!\n",
+ attempt_limit);
+ break;
+ }
+ }
+
+ index = 0;
+ read_attempt = 0;
+ read_sum = 0;
+ while (index < 80) {
+ imx_phy_reg_read(&adc_out_reg, mmio);
+ if (adc_out_reg & 0x400) {
+ read_sum = read_sum + (adc_out_reg & 0x3FF);
+ index++;
+ }
+ read_attempt++;
+ if (read_attempt > attempt_limit) {
+ dev_err(dev, "Read REG more than %d times!\n",
+ attempt_limit);
+ break;
+ }
+ }
+ /* Use the U32 to make 1000 precision */
+ m2 = (read_sum * 1000) / 80;
+
+ /* restore the status */
+ /* mpll_tst.meas_iv */
+ mpll_test_reg = (mpll_test_reg & 0xE03) | (str1) << 2;
+ /* rtune_ctl.mode */
+ rtune_ctl_reg = (rtune_ctl_reg & 0xFFC) | (str2);
+ /* dac_ctl.dac_mode */
+ dac_ctl_reg = (dac_ctl_reg & 0x8FF) | (str3) << 12;
+ /* rtune_ctl.sel_atbp */
+ rtune_ctl_reg = (rtune_ctl_reg & 0xFEF) | (str4) << 4;
+
+ imx_phy_reg_addressing(SATA_PHY_CR_CLOCK_MPLL_TST, mmio);
+ imx_phy_reg_write(mpll_test_reg, mmio);
+ imx_phy_reg_addressing(SATA_PHY_CR_CLOCK_DAC_CTL, mmio);
+ imx_phy_reg_write(dac_ctl_reg, mmio);
+ imx_phy_reg_addressing(SATA_PHY_CR_CLOCK_RTUNE_CTL, mmio);
+ imx_phy_reg_write(rtune_ctl_reg, mmio);
+
+ /* Compute temperature */
+ if (!(m2 / 1000))
+ m2 = 1000;
+ a = (m2 - m1) / (m2/1000);
+ *temp = ((-559) * a * a) / 1000 + (1379) * a + (-458000);
+
+ return 0;
+}
+
+static ssize_t sata_ahci_show_temp(struct device *dev,
+ struct device_attribute *da,
+ char *buf)
+{
+ unsigned int temp = 0;
+ int err;
+
+ err = sata_ahci_read_temperature(dev, &temp);
+ if (err < 0)
+ return err;
+
+ return sprintf(buf, "%u\n", temp);
+}
+
+static const struct thermal_zone_of_device_ops fsl_sata_ahci_of_thermal_ops = {
+ .get_temp = sata_ahci_read_temperature,
+};
+
+static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, sata_ahci_show_temp, NULL, 0);
+
+static struct attribute *fsl_sata_ahci_attrs[] = {
+ &sensor_dev_attr_temp1_input.dev_attr.attr,
+ NULL
+};
+ATTRIBUTE_GROUPS(fsl_sata_ahci);
+
static int imx_sata_enable(struct ahci_host_priv *hpriv)
{
struct imx_ahci_priv *imxpriv = hpriv->plat_data;
@@ -597,6 +804,24 @@ static int imx_ahci_probe(struct platform_device *pdev)
if (ret)
return ret;
+ if (imxpriv->type == AHCI_IMX53) {
+ /* Add the temperature monitor */
+ struct device *hwmon_dev;
+
+ hwmon_dev =
+ devm_hwmon_device_register_with_groups(dev,
+ "sata_ahci",
+ hpriv,
+ fsl_sata_ahci_groups);
+ if (IS_ERR(hwmon_dev)) {
+ ret = PTR_ERR(hwmon_dev);
+ goto disable_clk;
+ }
+ devm_thermal_zone_of_sensor_register(hwmon_dev, 0, hwmon_dev,
+ &fsl_sata_ahci_of_thermal_ops);
+ dev_info(dev, "%s: sensor 'sata_ahci'\n", dev_name(hwmon_dev));
+ }
+
ret = imx_sata_enable(hpriv);
if (ret)
goto disable_clk;
--
2.1.4
^ permalink raw reply related
* Re: [PATCH] ahci: fix nvec check
From: Tejun Heo @ 2016-10-20 17:41 UTC (permalink / raw)
To: Christoph Hellwig; +Cc: colin.king, linux-ide
In-Reply-To: <1476976541-14501-1-git-send-email-hch@lst.de>
On Thu, Oct 20, 2016 at 05:15:41PM +0200, Christoph Hellwig wrote:
> commit 17a51f12 ("ahci: only try to use multi-MSI mode if there is more
> than 1 port") lead to a case where nvec isn't initialized before it's
> used. Fix this by moving the check into the n_ports conditional.
>
> Reported-by Colin Ian King <colin.king@canonical.com>
> Signed-off-by: Christoph Hellwig <hch@lst.de>
Applied to libata/for-4.9-fixes.
Thanks.
--
tejun
^ permalink raw reply
* Re: [PATCH] ahci: use pci_alloc_irq_vectors
From: Robert Richter @ 2016-10-20 15:47 UTC (permalink / raw)
To: Tejun Heo
Cc: Auger Eric, Marc Zyngier, linux-ide, dan.j.williamps,
Christoph Hellwig, linux-arm-kernel
In-Reply-To: <20160906163946.GB24268@htj.duckdns.org>
On 06.09.16 12:39:46, Tejun Heo wrote:
> On Mon, Sep 05, 2016 at 05:21:45PM +0200, Christoph Hellwig wrote:
> > Use the new pci_alloc_irq_vectors API to allocate MSI-X and MSI vectors.
> > The big advantage over the old code is that we can use the same API for
> > MSI and MSI-X, and that we don't need to store the MSI-X vector mapping
> > in driver-private data structures.
> >
> > This first conversion keeps the probe order as-is: MSI-X multi vector,
> > MSI multi vector, MSI single vector, MSI-X single vector and last a
> > single least legacy interrupt line. There is one small change of
> > behavior: we now check the "MSI Revert to Single Message" flag for
> > MSI-X in addition to MSI.
> >
> > Because the API to find the Linux IRQ number for a MSI/MSI-X vector
> > is PCI specific, but libahaci is bus-agnostic I had to a
> > get_irq_vector function pointer to struct ahci_host_priv. The
> > alternative would be to move the multi-vector case of ahci_host_activate
> > to ahci.c and just call ata_host_activate directly from the others
> > users of ahci_host_activate.
>
> Applied to libata/for-4.9 after pulling in the mainline.
Hm, this broke SATA on ThunderX. Log below.
I could not yet look into this closer but reverting this patch
helped:
0b9e2988ab22 ahci: use pci_alloc_irq_vectors
-Robert
[ 14.940982] ata1.00: qc timeout (cmd 0x27)
[ 14.941017] ata2.00: qc timeout (cmd 0x27)
[ 14.941021] ata2.00: failed to read native max address (err_mask=0x4)
[ 14.941023] ata2.00: HPA support seems broken, skipping HPA handling
[ 14.961969] ata1.00: failed to read native max address (err_mask=0x4)
[ 14.968401] ata1.00: HPA support seems broken, skipping HPA handling
[ 15.405004] ata2: SATA link up 6.0 Gbps (SStatus 133 SControl 300)
[ 15.437004] ata1: SATA link up 6.0 Gbps (SStatus 133 SControl 300)
[ 20.573007] ata2.00: qc timeout (cmd 0xef)
[ 20.573037] ata1.00: qc timeout (cmd 0xef)
[ 20.573041] ata1.00: failed to enable AA (error_mask=0x4)
[ 20.573044] ata1: limiting SATA link speed to 3.0 Gbps
[ 20.591691] ata2.00: failed to enable AA (error_mask=0x4)
[ 20.597083] ata2: limiting SATA link speed to 3.0 Gbps
[ 21.037003] ata1: SATA link up 3.0 Gbps (SStatus 123 SControl 320)
[ 21.043861] ata1.00: ATA-8: WDC WD5003ABYZ-011FA0, 01.01S03, max UDMA/133
[ 21.050647] ata1.00: 976773168 sectors, multi 0: LBA48 NCQ (depth 31/32)
[ 21.061007] ata2: SATA link up 3.0 Gbps (SStatus 123 SControl 320)
[ 21.067683] ata2.00: ATA-8: WDC WD5003ABYZ-011FA0, 01.01S03, max UDMA/133
[ 21.074468] ata2.00: 976773168 sectors, multi 0: LBA48 NCQ (depth 31/32)
[ 36.444979] ata1.00: qc timeout (cmd 0xef)
[ 36.445011] ata2.00: qc timeout (cmd 0xef)
[ 36.445014] ata2.00: failed to set xfermode (err_mask=0x4)
[ 36.445016] ata2.00: disabled
[ 36.445026] ata2: hard resetting link
[ 36.465268] ata1.00: failed to set xfermode (err_mask=0x4)
[ 36.470750] ata1.00: disabled
[ 36.473718] ata1: hard resetting link
[ 36.909003] ata2: SATA link up 3.0 Gbps (SStatus 123 SControl 320)
[ 36.915184] ata2: EH complete
[ 36.941013] ata1: SATA link up 3.0 Gbps (SStatus 123 SControl 320)
[ 36.947196] ata1: EH complete
[ 36.960294] Freeing unused kernel memory: 1024K (fffffe0001f70000 -
fffffe0002070000)
../..
[ 161.266664] dracut-initqueue[624]: Warning: dracut-initqueue timeout
- starting timeout scripts
[ 161.793311] dracut-initqueue[624]: Warning: dracut-initqueue timeout
- starting timeout scripts
[ 162.309073] dracut-initqueue[624]: Warning: dracut-initqueue timeout
- starting timeout scripts
^ permalink raw reply
* Re: [PATCH] ahci: fix nvec check
From: Colin Ian King @ 2016-10-20 15:32 UTC (permalink / raw)
To: Christoph Hellwig, tj; +Cc: linux-ide
In-Reply-To: <1476976541-14501-1-git-send-email-hch@lst.de>
On 20/10/16 16:15, Christoph Hellwig wrote:
> commit 17a51f12 ("ahci: only try to use multi-MSI mode if there is more
> than 1 port") lead to a case where nvec isn't initialized before it's
> used. Fix this by moving the check into the n_ports conditional.
>
> Reported-by Colin Ian King <colin.king@canonical.com>
> Signed-off-by: Christoph Hellwig <hch@lst.de>
> ---
> drivers/ata/ahci.c | 14 +++++++-------
> 1 file changed, 7 insertions(+), 7 deletions(-)
>
> diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c
> index ed311a0..60e42e2 100644
> --- a/drivers/ata/ahci.c
> +++ b/drivers/ata/ahci.c
> @@ -1436,14 +1436,14 @@ static int ahci_init_msi(struct pci_dev *pdev, unsigned int n_ports,
> "ahci: MRSM is on, fallback to single MSI\n");
> pci_free_irq_vectors(pdev);
> }
> - }
>
> - /*
> - * -ENOSPC indicated we don't have enough vectors. Don't bother trying
> - * a single vectors for any other error:
> - */
> - if (nvec < 0 && nvec != -ENOSPC)
> - return nvec;
> + /*
> + * -ENOSPC indicated we don't have enough vectors. Don't bother
> + * trying a single vectors for any other error:
> + */
> + if (nvec < 0 && nvec != -ENOSPC)
> + return nvec;
> + }
>
> /*
> * If the host is not capable of supporting per-port vectors, fall
>
That looks good to me. Thanks Christoph
Acked-by: Colin Ian King <colin.king@canonical.com>
^ permalink raw reply
* [PATCH] ahci: fix nvec check
From: Christoph Hellwig @ 2016-10-20 15:15 UTC (permalink / raw)
To: tj; +Cc: colin.king, linux-ide
commit 17a51f12 ("ahci: only try to use multi-MSI mode if there is more
than 1 port") lead to a case where nvec isn't initialized before it's
used. Fix this by moving the check into the n_ports conditional.
Reported-by Colin Ian King <colin.king@canonical.com>
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
drivers/ata/ahci.c | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c
index ed311a0..60e42e2 100644
--- a/drivers/ata/ahci.c
+++ b/drivers/ata/ahci.c
@@ -1436,14 +1436,14 @@ static int ahci_init_msi(struct pci_dev *pdev, unsigned int n_ports,
"ahci: MRSM is on, fallback to single MSI\n");
pci_free_irq_vectors(pdev);
}
- }
- /*
- * -ENOSPC indicated we don't have enough vectors. Don't bother trying
- * a single vectors for any other error:
- */
- if (nvec < 0 && nvec != -ENOSPC)
- return nvec;
+ /*
+ * -ENOSPC indicated we don't have enough vectors. Don't bother
+ * trying a single vectors for any other error:
+ */
+ if (nvec < 0 && nvec != -ENOSPC)
+ return nvec;
+ }
/*
* If the host is not capable of supporting per-port vectors, fall
--
2.1.4
^ permalink raw reply related
* Re: [PATCH] ata: set ncq_prio_enabled if device has support
From: Tejun Heo @ 2016-10-20 14:07 UTC (permalink / raw)
To: Adam Manzanares; +Cc: linux-ide, linux-kernel, Adam Manzanares
In-Reply-To: <1476934819-3084-1-git-send-email-adam.manzanares@hgst.com>
Hello, Adam.
Applied to libata/for-4.10 with minor edits.
Thanks!
------ 8< ------
>From 4e647d960c510e0d5cd700058fb8ddd529c390ee Mon Sep 17 00:00:00 2001
From: Adam Manzanares <adam.manzanares@hgst.com>
Date: Wed, 19 Oct 2016 20:40:19 -0700
Subject: [PATCH] ata: set ncq_prio_enabled iff device has support
We previously had a check to see if the device has support for
prioritized ncq commands and a check to see if a device flag
is set, through a sysfs variable, in order to send a prioritized
command.
This patch only allows the sysfs variable to be set if the device
supports prioritized commands enabling one check in ata_build_rw_tf
in order to determine whether or not to send a prioritized command.
This patch depends on ata: ATA Command Priority Disabled By Default
tj: Minor subject and formatting updates.
Signed-off-by: Adam Manzanares <adam.manzanares@wdc.com>
Signed-off-by: Tejun Heo <tj@kernel.org>
---
drivers/ata/libata-core.c | 3 +--
drivers/ata/libata-scsi.c | 10 ++++++++--
2 files changed, 9 insertions(+), 4 deletions(-)
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
index b294339..43842fd 100644
--- a/drivers/ata/libata-core.c
+++ b/drivers/ata/libata-core.c
@@ -787,8 +787,7 @@ int ata_build_rw_tf(struct ata_taskfile *tf, struct ata_device *dev,
if (tf->flags & ATA_TFLAG_FUA)
tf->device |= 1 << 7;
- if ((dev->flags & ATA_DFLAG_NCQ_PRIO) &&
- (dev->flags & ATA_DFLAG_NCQ_PRIO_ENABLE)) {
+ if (dev->flags & ATA_DFLAG_NCQ_PRIO_ENABLE) {
if (class == IOPRIO_CLASS_RT)
tf->hob_nsect |= ATA_PRIO_HIGH <<
ATA_SHIFT_PRIO;
diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c
index 87597a3..49c09d8 100644
--- a/drivers/ata/libata-scsi.c
+++ b/drivers/ata/libata-scsi.c
@@ -323,10 +323,16 @@ static ssize_t ata_ncq_prio_enable_store(struct device *device,
goto unlock;
}
- if (input)
+ if (input) {
+ if (!(dev->flags & ATA_DFLAG_NCQ_PRIO)) {
+ rc = -EOPNOTSUPP;
+ goto unlock;
+ }
+
dev->flags |= ATA_DFLAG_NCQ_PRIO_ENABLE;
- else
+ } else {
dev->flags &= ~ATA_DFLAG_NCQ_PRIO_ENABLE;
+ }
unlock:
spin_unlock_irqrestore(ap->lock, flags);
--
2.7.4
^ permalink raw reply related
* [PATCH] ata: xgene: Enable NCQ support for APM X-Gene SATA controller hardware v1.1
From: Rameshwar Prasad Sahu @ 2016-10-20 11:14 UTC (permalink / raw)
To: olof, tj, arnd
Cc: devicetree, mlangsdo, linux-scsi, jcm, Rameshwar Prasad Sahu,
patches, linux-ide, linux-arm-kernel
This patch enables NCQ support for APM X-Gene SATA controller
hardware v1.1 that was broken with hardware v1.0.
Signed-off-by: Rameshwar Prasad Sahu <rsahu@apm.com>
---
drivers/ata/ahci_xgene.c | 14 ++++++++------
1 files changed, 8 insertions(+), 6 deletions(-)
diff --git a/drivers/ata/ahci_xgene.c b/drivers/ata/ahci_xgene.c
index 73b19b2..8b88be9 100644
--- a/drivers/ata/ahci_xgene.c
+++ b/drivers/ata/ahci_xgene.c
@@ -87,6 +87,7 @@
enum xgene_ahci_version {
XGENE_AHCI_V1 = 1,
+ XGENE_AHCI_V1_1,
XGENE_AHCI_V2,
};
@@ -734,6 +735,7 @@ static struct scsi_host_template ahci_platform_sht = {
#ifdef CONFIG_ACPI
static const struct acpi_device_id xgene_ahci_acpi_match[] = {
{ "APMC0D0D", XGENE_AHCI_V1},
+ { "APMC0D67", XGENE_AHCI_V1_1},
{ "APMC0D32", XGENE_AHCI_V2},
{},
};
@@ -742,6 +744,7 @@ MODULE_DEVICE_TABLE(acpi, xgene_ahci_acpi_match);
static const struct of_device_id xgene_ahci_of_match[] = {
{.compatible = "apm,xgene-ahci", .data = (void *) XGENE_AHCI_V1},
+ {.compatible = "apm,xgene-ahci-v1-1", .data = (void *) XGENE_AHCI_V1_1},
{.compatible = "apm,xgene-ahci-v2", .data = (void *) XGENE_AHCI_V2},
{},
};
@@ -755,8 +758,7 @@ static int xgene_ahci_probe(struct platform_device *pdev)
struct resource *res;
const struct of_device_id *of_devid;
enum xgene_ahci_version version = XGENE_AHCI_V1;
- const struct ata_port_info *ppi[] = { &xgene_ahci_v1_port_info,
- &xgene_ahci_v2_port_info };
+ const struct ata_port_info *ppi;
int rc;
hpriv = ahci_platform_get_resources(pdev);
@@ -821,8 +823,6 @@ static int xgene_ahci_probe(struct platform_device *pdev)
dev_warn(&pdev->dev, "%s: Error reading device info. Assume version1\n",
__func__);
version = XGENE_AHCI_V1;
- } else if (info->valid & ACPI_VALID_CID) {
- version = XGENE_AHCI_V2;
}
}
}
@@ -858,18 +858,20 @@ skip_clk_phy:
switch (version) {
case XGENE_AHCI_V1:
+ ppi = &xgene_ahci_v1_port_info;
hpriv->flags = AHCI_HFLAG_NO_NCQ;
break;
case XGENE_AHCI_V2:
+ ppi = &xgene_ahci_v2_port_info;
hpriv->flags |= AHCI_HFLAG_YES_FBS;
hpriv->irq_handler = xgene_ahci_irq_intr;
break;
default:
+ ppi = &xgene_ahci_v1_port_info;
break;
}
- rc = ahci_platform_init_host(pdev, hpriv, ppi[version - 1],
- &ahci_platform_sht);
+ rc = ahci_platform_init_host(pdev, hpriv, ppi, &ahci_platform_sht);
if (rc)
goto disable_resources;
--
1.7.1
^ permalink raw reply related
* [PATCH] ata: set ncq_prio_enabled if device has support
From: Adam Manzanares @ 2016-10-20 3:40 UTC (permalink / raw)
To: tj; +Cc: linux-ide, linux-kernel, Adam Manzanares, Adam Manzanares
We previously had a check to see if the device has support for
prioritized ncq commands and a check to see if a device flag
is set, through a sysfs variable, in order to send a prioritized
command.
This patch only allows the sysfs variable to be set if the device
supports prioritized commands enabling one check in ata_build_rw_tf
in order to determine whether or not to send a prioritized command.
This patch depends on ata: ATA Command Priority Disabled By Default
Signed-off-by: Adam Manzanares <adam.manzanares@wdc.com>
---
drivers/ata/libata-core.c | 3 +--
drivers/ata/libata-scsi.c | 8 +++++++-
2 files changed, 8 insertions(+), 3 deletions(-)
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
index b294339..43842fd 100644
--- a/drivers/ata/libata-core.c
+++ b/drivers/ata/libata-core.c
@@ -787,8 +787,7 @@ int ata_build_rw_tf(struct ata_taskfile *tf, struct ata_device *dev,
if (tf->flags & ATA_TFLAG_FUA)
tf->device |= 1 << 7;
- if ((dev->flags & ATA_DFLAG_NCQ_PRIO) &&
- (dev->flags & ATA_DFLAG_NCQ_PRIO_ENABLE)) {
+ if (dev->flags & ATA_DFLAG_NCQ_PRIO_ENABLE) {
if (class == IOPRIO_CLASS_RT)
tf->hob_nsect |= ATA_PRIO_HIGH <<
ATA_SHIFT_PRIO;
diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c
index 87597a3..831beea 100644
--- a/drivers/ata/libata-scsi.c
+++ b/drivers/ata/libata-scsi.c
@@ -323,8 +323,14 @@ static ssize_t ata_ncq_prio_enable_store(struct device *device,
goto unlock;
}
- if (input)
+ if (input) {
+ if (!(dev->flags & ATA_DFLAG_NCQ_PRIO)) {
+ rc = -EOPNOTSUPP;
+ goto unlock;
+ }
+
dev->flags |= ATA_DFLAG_NCQ_PRIO_ENABLE;
+ }
else
dev->flags &= ~ATA_DFLAG_NCQ_PRIO_ENABLE;
--
2.1.4
^ permalink raw reply related
* Re: [PATCH v6 3/3] ata: ATA Command Priority Disabled By Default
From: Adam Manzanares @ 2016-10-19 20:02 UTC (permalink / raw)
To: Tejun Heo
Cc: Adam Manzanares, axboe, dan.j.williams, hare, martin.petersen,
mchristi, toshi.kani, ming.lei, sathya.prakash, chaitra.basappa,
suganath-prabu.subramani, linux-block, linux-ide, linux-kernel,
MPT-FusionLinux.pdl, linux-scsi
In-Reply-To: <20161019183829.GK18532@htj.duckdns.org>
The 10/19/2016 14:38, Tejun Heo wrote:
> Hello,
>
> Removed ata_ncq_prio_on() and renamed _on to _enable. If I messed up
> anything, please let me know.
>
Works as expected. Thanks for cleaning this up.
> Also, can you please send a follow-up patch to make the store function
> reject prio enabling if the device doesn't support it?
>
I'll send something out shortly.
Take care,
Adam
> Thanks.
>
> ------ 8< ------
> From 84f95243b5439a20c33837075b88926bfa00c4ec Mon Sep 17 00:00:00 2001
> From: Adam Manzanares <adam.manzanares@hgst.com>
> Date: Mon, 17 Oct 2016 11:27:30 -0700
> Subject: [PATCH 2/2] ata: ATA Command Priority Disabled By Default
>
> Add a sysfs entry to turn on priority information being passed
> to a ATA device. By default this feature is turned off.
>
> This patch depends on ata: Enabling ATA Command Priorities
>
> tj: Renamed ncq_prio_on to ncq_prio_enable and removed trivial
> ata_ncq_prio_on() and open-coded the test.
>
> Signed-off-by: Adam Manzanares <adam.manzanares@hgst.com>
> Signed-off-by: Tejun Heo <tj@kernel.org>
> ---
> drivers/ata/libahci.c | 1 +
> drivers/ata/libata-core.c | 3 ++-
> drivers/ata/libata-scsi.c | 68 +++++++++++++++++++++++++++++++++++++++++++++++
> include/linux/libata.h | 2 ++
> 4 files changed, 73 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/ata/libahci.c b/drivers/ata/libahci.c
> index 0d028ea..ee7db31 100644
> --- a/drivers/ata/libahci.c
> +++ b/drivers/ata/libahci.c
> @@ -140,6 +140,7 @@ EXPORT_SYMBOL_GPL(ahci_shost_attrs);
> struct device_attribute *ahci_sdev_attrs[] = {
> &dev_attr_sw_activity,
> &dev_attr_unload_heads,
> + &dev_attr_ncq_prio_enable,
> NULL
> };
> EXPORT_SYMBOL_GPL(ahci_sdev_attrs);
> diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
> index 8346faf..b294339 100644
> --- a/drivers/ata/libata-core.c
> +++ b/drivers/ata/libata-core.c
> @@ -787,7 +787,8 @@ int ata_build_rw_tf(struct ata_taskfile *tf, struct ata_device *dev,
> if (tf->flags & ATA_TFLAG_FUA)
> tf->device |= 1 << 7;
>
> - if (dev->flags & ATA_DFLAG_NCQ_PRIO) {
> + if ((dev->flags & ATA_DFLAG_NCQ_PRIO) &&
> + (dev->flags & ATA_DFLAG_NCQ_PRIO_ENABLE)) {
> if (class == IOPRIO_CLASS_RT)
> tf->hob_nsect |= ATA_PRIO_HIGH <<
> ATA_SHIFT_PRIO;
> diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c
> index 2bccc3c..87597a3 100644
> --- a/drivers/ata/libata-scsi.c
> +++ b/drivers/ata/libata-scsi.c
> @@ -271,6 +271,73 @@ DEVICE_ATTR(unload_heads, S_IRUGO | S_IWUSR,
> ata_scsi_park_show, ata_scsi_park_store);
> EXPORT_SYMBOL_GPL(dev_attr_unload_heads);
>
> +static ssize_t ata_ncq_prio_enable_show(struct device *device,
> + struct device_attribute *attr, char *buf)
> +{
> + struct scsi_device *sdev = to_scsi_device(device);
> + struct ata_port *ap;
> + struct ata_device *dev;
> + bool ncq_prio_enable;
> + int rc = 0;
> +
> + ap = ata_shost_to_port(sdev->host);
> +
> + spin_lock_irq(ap->lock);
> + dev = ata_scsi_find_dev(ap, sdev);
> + if (!dev) {
> + rc = -ENODEV;
> + goto unlock;
> + }
> +
> + ncq_prio_enable = dev->flags & ATA_DFLAG_NCQ_PRIO_ENABLE;
> +
> +unlock:
> + spin_unlock_irq(ap->lock);
> +
> + return rc ? rc : snprintf(buf, 20, "%u\n", ncq_prio_enable);
> +}
> +
> +static ssize_t ata_ncq_prio_enable_store(struct device *device,
> + struct device_attribute *attr,
> + const char *buf, size_t len)
> +{
> + struct scsi_device *sdev = to_scsi_device(device);
> + struct ata_port *ap;
> + struct ata_device *dev;
> + long int input;
> + unsigned long flags;
> + int rc;
> +
> + rc = kstrtol(buf, 10, &input);
> + if (rc)
> + return rc;
> + if ((input < 0) || (input > 1))
> + return -EINVAL;
> +
> + ap = ata_shost_to_port(sdev->host);
> +
> + spin_lock_irqsave(ap->lock, flags);
> + dev = ata_scsi_find_dev(ap, sdev);
> + if (unlikely(!dev)) {
> + rc = -ENODEV;
> + goto unlock;
> + }
> +
> + if (input)
> + dev->flags |= ATA_DFLAG_NCQ_PRIO_ENABLE;
> + else
> + dev->flags &= ~ATA_DFLAG_NCQ_PRIO_ENABLE;
> +
> +unlock:
> + spin_unlock_irqrestore(ap->lock, flags);
> +
> + return rc ? rc : len;
> +}
> +
> +DEVICE_ATTR(ncq_prio_enable, S_IRUGO | S_IWUSR,
> + ata_ncq_prio_enable_show, ata_ncq_prio_enable_store);
> +EXPORT_SYMBOL_GPL(dev_attr_ncq_prio_enable);
> +
> void ata_scsi_set_sense(struct ata_device *dev, struct scsi_cmnd *cmd,
> u8 sk, u8 asc, u8 ascq)
> {
> @@ -402,6 +469,7 @@ EXPORT_SYMBOL_GPL(dev_attr_sw_activity);
>
> struct device_attribute *ata_common_sdev_attrs[] = {
> &dev_attr_unload_heads,
> + &dev_attr_ncq_prio_enable,
> NULL
> };
> EXPORT_SYMBOL_GPL(ata_common_sdev_attrs);
> diff --git a/include/linux/libata.h b/include/linux/libata.h
> index 90b69a6..c170be5 100644
> --- a/include/linux/libata.h
> +++ b/include/linux/libata.h
> @@ -167,6 +167,7 @@ enum {
> ATA_DFLAG_UNLOCK_HPA = (1 << 18), /* unlock HPA */
> ATA_DFLAG_NCQ_SEND_RECV = (1 << 19), /* device supports NCQ SEND and RECV */
> ATA_DFLAG_NCQ_PRIO = (1 << 20), /* device supports NCQ priority */
> + ATA_DFLAG_NCQ_PRIO_ENABLE = (1 << 21), /* Priority cmds sent to dev */
> ATA_DFLAG_INIT_MASK = (1 << 24) - 1,
>
> ATA_DFLAG_DETACH = (1 << 24),
> @@ -545,6 +546,7 @@ typedef void (*ata_postreset_fn_t)(struct ata_link *link, unsigned int *classes)
>
> extern struct device_attribute dev_attr_link_power_management_policy;
> extern struct device_attribute dev_attr_unload_heads;
> +extern struct device_attribute dev_attr_ncq_prio_enable;
> extern struct device_attribute dev_attr_em_message_type;
> extern struct device_attribute dev_attr_em_message;
> extern struct device_attribute dev_attr_sw_activity;
> --
> 2.7.4
>
^ permalink raw reply
* Re: [PATCH 2/2] ata: ahci_tegra: add support for tegra210
From: Tejun Heo @ 2016-10-19 18:39 UTC (permalink / raw)
To: Preetham Chandru Ramchandra
Cc: swarren, thierry.reding, preetham260, ldewangan, linux-ide,
vbyravarasu, pkunapuli
In-Reply-To: <1476900956-23719-3-git-send-email-pchandru@nvidia.com>
On Wed, Oct 19, 2016 at 11:45:56PM +0530, Preetham Chandru Ramchandra wrote:
> From: Preetham Chandru R <pchandru@nvidia.com>
>
> Add AHCI support for tegra210.
> 1. Moved tegra124 specifics to tegra124_ahci_init.
> 2. Separated out the regulators needed for tegra124 and tegra210.
> 3. Set the LPM capabilities
> 4. Added support to disable features through DT
> 5. Created inline functions for read/write and modify to
> SATA, SATA Config and SATA Aux registers.
Can you please read Documentation/CodingStyle and reformat the patch?
Thanks.
--
tejun
^ permalink raw reply
* Re: [PATCH v6 0/3] Enabling ATA Command Priorities
From: Tejun Heo @ 2016-10-19 18:38 UTC (permalink / raw)
To: Adam Manzanares
Cc: axboe, dan.j.williams, hare, martin.petersen, mchristi,
toshi.kani, ming.lei, sathya.prakash, chaitra.basappa,
suganath-prabu.subramani, linux-block, linux-ide, linux-kernel,
MPT-FusionLinux.pdl, linux-scsi
In-Reply-To: <1476728850-2309-1-git-send-email-adam.manzanares@hgst.com>
On Mon, Oct 17, 2016 at 11:27:27AM -0700, Adam Manzanares wrote:
> This patch builds ATA commands with high priority if the iocontext of a process
> is set to real time. The goal of the patch is to improve tail latencies of
> workloads that use higher queue depths. This requires setting the iocontext
> ioprio on the request when it is initialized
>
> This patch has been tested with an Ultrastar HE8 HDD and cuts the
> the p99.99 tail latency of foreground IO from 2s down to 72ms when
> using the deadline scheduler. This patch works independently of the
> scheduler so it can be used with all of the currently available
> request based schedulers.
>
> Foreground IO, for the previously described results, is an async fio job
> submitting 4K read requests at a QD of 1 to the HDD. The foreground IO is set
> with the iopriority class of real time. The background workload is another fio
> job submitting read requests at a QD of 32 to the same HDD with default
> iopriority.
>
> This feature is enabled for ATA devices by setting the ata ncq_prio_on device
> attribute to 1. An ATA device is also checked to see if the device supports per
> command priority.
Applied 1-3 to libata/for-4.10 w/ some modifications.
Thanks.
--
tejun
^ permalink raw reply
* Re: [PATCH v6 3/3] ata: ATA Command Priority Disabled By Default
From: Tejun Heo @ 2016-10-19 18:38 UTC (permalink / raw)
To: Adam Manzanares
Cc: axboe, dan.j.williams, hare, martin.petersen, mchristi,
toshi.kani, ming.lei, sathya.prakash, chaitra.basappa,
suganath-prabu.subramani, linux-block, linux-ide, linux-kernel,
MPT-FusionLinux.pdl, linux-scsi
In-Reply-To: <1476728850-2309-4-git-send-email-adam.manzanares@hgst.com>
Hello,
Removed ata_ncq_prio_on() and renamed _on to _enable. If I messed up
anything, please let me know.
Also, can you please send a follow-up patch to make the store function
reject prio enabling if the device doesn't support it?
Thanks.
------ 8< ------
>From 84f95243b5439a20c33837075b88926bfa00c4ec Mon Sep 17 00:00:00 2001
From: Adam Manzanares <adam.manzanares@hgst.com>
Date: Mon, 17 Oct 2016 11:27:30 -0700
Subject: [PATCH 2/2] ata: ATA Command Priority Disabled By Default
Add a sysfs entry to turn on priority information being passed
to a ATA device. By default this feature is turned off.
This patch depends on ata: Enabling ATA Command Priorities
tj: Renamed ncq_prio_on to ncq_prio_enable and removed trivial
ata_ncq_prio_on() and open-coded the test.
Signed-off-by: Adam Manzanares <adam.manzanares@hgst.com>
Signed-off-by: Tejun Heo <tj@kernel.org>
---
drivers/ata/libahci.c | 1 +
drivers/ata/libata-core.c | 3 ++-
drivers/ata/libata-scsi.c | 68 +++++++++++++++++++++++++++++++++++++++++++++++
include/linux/libata.h | 2 ++
4 files changed, 73 insertions(+), 1 deletion(-)
diff --git a/drivers/ata/libahci.c b/drivers/ata/libahci.c
index 0d028ea..ee7db31 100644
--- a/drivers/ata/libahci.c
+++ b/drivers/ata/libahci.c
@@ -140,6 +140,7 @@ EXPORT_SYMBOL_GPL(ahci_shost_attrs);
struct device_attribute *ahci_sdev_attrs[] = {
&dev_attr_sw_activity,
&dev_attr_unload_heads,
+ &dev_attr_ncq_prio_enable,
NULL
};
EXPORT_SYMBOL_GPL(ahci_sdev_attrs);
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
index 8346faf..b294339 100644
--- a/drivers/ata/libata-core.c
+++ b/drivers/ata/libata-core.c
@@ -787,7 +787,8 @@ int ata_build_rw_tf(struct ata_taskfile *tf, struct ata_device *dev,
if (tf->flags & ATA_TFLAG_FUA)
tf->device |= 1 << 7;
- if (dev->flags & ATA_DFLAG_NCQ_PRIO) {
+ if ((dev->flags & ATA_DFLAG_NCQ_PRIO) &&
+ (dev->flags & ATA_DFLAG_NCQ_PRIO_ENABLE)) {
if (class == IOPRIO_CLASS_RT)
tf->hob_nsect |= ATA_PRIO_HIGH <<
ATA_SHIFT_PRIO;
diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c
index 2bccc3c..87597a3 100644
--- a/drivers/ata/libata-scsi.c
+++ b/drivers/ata/libata-scsi.c
@@ -271,6 +271,73 @@ DEVICE_ATTR(unload_heads, S_IRUGO | S_IWUSR,
ata_scsi_park_show, ata_scsi_park_store);
EXPORT_SYMBOL_GPL(dev_attr_unload_heads);
+static ssize_t ata_ncq_prio_enable_show(struct device *device,
+ struct device_attribute *attr, char *buf)
+{
+ struct scsi_device *sdev = to_scsi_device(device);
+ struct ata_port *ap;
+ struct ata_device *dev;
+ bool ncq_prio_enable;
+ int rc = 0;
+
+ ap = ata_shost_to_port(sdev->host);
+
+ spin_lock_irq(ap->lock);
+ dev = ata_scsi_find_dev(ap, sdev);
+ if (!dev) {
+ rc = -ENODEV;
+ goto unlock;
+ }
+
+ ncq_prio_enable = dev->flags & ATA_DFLAG_NCQ_PRIO_ENABLE;
+
+unlock:
+ spin_unlock_irq(ap->lock);
+
+ return rc ? rc : snprintf(buf, 20, "%u\n", ncq_prio_enable);
+}
+
+static ssize_t ata_ncq_prio_enable_store(struct device *device,
+ struct device_attribute *attr,
+ const char *buf, size_t len)
+{
+ struct scsi_device *sdev = to_scsi_device(device);
+ struct ata_port *ap;
+ struct ata_device *dev;
+ long int input;
+ unsigned long flags;
+ int rc;
+
+ rc = kstrtol(buf, 10, &input);
+ if (rc)
+ return rc;
+ if ((input < 0) || (input > 1))
+ return -EINVAL;
+
+ ap = ata_shost_to_port(sdev->host);
+
+ spin_lock_irqsave(ap->lock, flags);
+ dev = ata_scsi_find_dev(ap, sdev);
+ if (unlikely(!dev)) {
+ rc = -ENODEV;
+ goto unlock;
+ }
+
+ if (input)
+ dev->flags |= ATA_DFLAG_NCQ_PRIO_ENABLE;
+ else
+ dev->flags &= ~ATA_DFLAG_NCQ_PRIO_ENABLE;
+
+unlock:
+ spin_unlock_irqrestore(ap->lock, flags);
+
+ return rc ? rc : len;
+}
+
+DEVICE_ATTR(ncq_prio_enable, S_IRUGO | S_IWUSR,
+ ata_ncq_prio_enable_show, ata_ncq_prio_enable_store);
+EXPORT_SYMBOL_GPL(dev_attr_ncq_prio_enable);
+
void ata_scsi_set_sense(struct ata_device *dev, struct scsi_cmnd *cmd,
u8 sk, u8 asc, u8 ascq)
{
@@ -402,6 +469,7 @@ EXPORT_SYMBOL_GPL(dev_attr_sw_activity);
struct device_attribute *ata_common_sdev_attrs[] = {
&dev_attr_unload_heads,
+ &dev_attr_ncq_prio_enable,
NULL
};
EXPORT_SYMBOL_GPL(ata_common_sdev_attrs);
diff --git a/include/linux/libata.h b/include/linux/libata.h
index 90b69a6..c170be5 100644
--- a/include/linux/libata.h
+++ b/include/linux/libata.h
@@ -167,6 +167,7 @@ enum {
ATA_DFLAG_UNLOCK_HPA = (1 << 18), /* unlock HPA */
ATA_DFLAG_NCQ_SEND_RECV = (1 << 19), /* device supports NCQ SEND and RECV */
ATA_DFLAG_NCQ_PRIO = (1 << 20), /* device supports NCQ priority */
+ ATA_DFLAG_NCQ_PRIO_ENABLE = (1 << 21), /* Priority cmds sent to dev */
ATA_DFLAG_INIT_MASK = (1 << 24) - 1,
ATA_DFLAG_DETACH = (1 << 24),
@@ -545,6 +546,7 @@ typedef void (*ata_postreset_fn_t)(struct ata_link *link, unsigned int *classes)
extern struct device_attribute dev_attr_link_power_management_policy;
extern struct device_attribute dev_attr_unload_heads;
+extern struct device_attribute dev_attr_ncq_prio_enable;
extern struct device_attribute dev_attr_em_message_type;
extern struct device_attribute dev_attr_em_message;
extern struct device_attribute dev_attr_sw_activity;
--
2.7.4
^ permalink raw reply related
* Re: [PATCH v6 2/3] ata: Enabling ATA Command Priorities
From: Tejun Heo @ 2016-10-19 18:37 UTC (permalink / raw)
To: Adam Manzanares
Cc: axboe, dan.j.williams, hare, martin.petersen, mchristi,
toshi.kani, ming.lei, sathya.prakash, chaitra.basappa,
suganath-prabu.subramani, linux-block, linux-ide, linux-kernel,
MPT-FusionLinux.pdl, linux-scsi
In-Reply-To: <1476728850-2309-3-git-send-email-adam.manzanares@hgst.com>
Hello,
I removed ata_ncq_prio_enabled() as it was colliding with the sysfs
file rename and these trivial test functions tend to obscure more than
help anything.
Thanks.
------ 8< ------
>From 8e061784b51ec4a4efed0deaafb5bd9725bf5b06 Mon Sep 17 00:00:00 2001
From: Adam Manzanares <adam.manzanares@hgst.com>
Date: Mon, 17 Oct 2016 11:27:29 -0700
Subject: [PATCH 1/2] ata: Enabling ATA Command Priorities
This patch checks to see if an ATA device supports NCQ command priorities.
If so and the user has specified an iocontext that indicates
IO_PRIO_CLASS_RT then we build a tf with a high priority command.
This is done to improve the tail latency of commands that are high
priority by passing priority to the device.
tj: Removed trivial ata_ncq_prio_enabled() and open-coded the test.
Signed-off-by: Adam Manzanares <adam.manzanares@hgst.com>
Signed-off-by: Tejun Heo <tj@kernel.org>
---
drivers/ata/libata-core.c | 35 ++++++++++++++++++++++++++++++++++-
drivers/ata/libata-scsi.c | 6 +++++-
drivers/ata/libata.h | 2 +-
include/linux/ata.h | 6 ++++++
include/linux/libata.h | 3 +++
5 files changed, 49 insertions(+), 3 deletions(-)
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
index 223a770..8346faf 100644
--- a/drivers/ata/libata-core.c
+++ b/drivers/ata/libata-core.c
@@ -739,6 +739,7 @@ u64 ata_tf_read_block(const struct ata_taskfile *tf, struct ata_device *dev)
* @n_block: Number of blocks
* @tf_flags: RW/FUA etc...
* @tag: tag
+ * @class: IO priority class
*
* LOCKING:
* None.
@@ -753,7 +754,7 @@ u64 ata_tf_read_block(const struct ata_taskfile *tf, struct ata_device *dev)
*/
int ata_build_rw_tf(struct ata_taskfile *tf, struct ata_device *dev,
u64 block, u32 n_block, unsigned int tf_flags,
- unsigned int tag)
+ unsigned int tag, int class)
{
tf->flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE;
tf->flags |= tf_flags;
@@ -785,6 +786,12 @@ int ata_build_rw_tf(struct ata_taskfile *tf, struct ata_device *dev,
tf->device = ATA_LBA;
if (tf->flags & ATA_TFLAG_FUA)
tf->device |= 1 << 7;
+
+ if (dev->flags & ATA_DFLAG_NCQ_PRIO) {
+ if (class == IOPRIO_CLASS_RT)
+ tf->hob_nsect |= ATA_PRIO_HIGH <<
+ ATA_SHIFT_PRIO;
+ }
} else if (dev->flags & ATA_DFLAG_LBA) {
tf->flags |= ATA_TFLAG_LBA;
@@ -2156,6 +2163,30 @@ static void ata_dev_config_ncq_non_data(struct ata_device *dev)
}
}
+static void ata_dev_config_ncq_prio(struct ata_device *dev)
+{
+ struct ata_port *ap = dev->link->ap;
+ unsigned int err_mask;
+
+ err_mask = ata_read_log_page(dev,
+ ATA_LOG_SATA_ID_DEV_DATA,
+ ATA_LOG_SATA_SETTINGS,
+ ap->sector_buf,
+ 1);
+ if (err_mask) {
+ ata_dev_dbg(dev,
+ "failed to get Identify Device data, Emask 0x%x\n",
+ err_mask);
+ return;
+ }
+
+ if (ap->sector_buf[ATA_LOG_NCQ_PRIO_OFFSET] & BIT(3))
+ dev->flags |= ATA_DFLAG_NCQ_PRIO;
+ else
+ ata_dev_dbg(dev, "SATA page does not support priority\n");
+
+}
+
static int ata_dev_config_ncq(struct ata_device *dev,
char *desc, size_t desc_sz)
{
@@ -2205,6 +2236,8 @@ static int ata_dev_config_ncq(struct ata_device *dev,
ata_dev_config_ncq_send_recv(dev);
if (ata_id_has_ncq_non_data(dev->id))
ata_dev_config_ncq_non_data(dev);
+ if (ata_id_has_ncq_prio(dev->id))
+ ata_dev_config_ncq_prio(dev);
}
return 0;
diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c
index 9cceb4a..2bccc3c 100644
--- a/drivers/ata/libata-scsi.c
+++ b/drivers/ata/libata-scsi.c
@@ -50,6 +50,7 @@
#include <linux/uaccess.h>
#include <linux/suspend.h>
#include <asm/unaligned.h>
+#include <linux/ioprio.h>
#include "libata.h"
#include "libata-transport.h"
@@ -1755,6 +1756,8 @@ static unsigned int ata_scsi_rw_xlat(struct ata_queued_cmd *qc)
{
struct scsi_cmnd *scmd = qc->scsicmd;
const u8 *cdb = scmd->cmnd;
+ struct request *rq = scmd->request;
+ int class = IOPRIO_PRIO_CLASS(req_get_ioprio(rq));
unsigned int tf_flags = 0;
u64 block;
u32 n_block;
@@ -1821,7 +1824,8 @@ static unsigned int ata_scsi_rw_xlat(struct ata_queued_cmd *qc)
qc->nbytes = n_block * scmd->device->sector_size;
rc = ata_build_rw_tf(&qc->tf, qc->dev, block, n_block, tf_flags,
- qc->tag);
+ qc->tag, class);
+
if (likely(rc == 0))
return 0;
diff --git a/drivers/ata/libata.h b/drivers/ata/libata.h
index 3b301a4..8f3a559 100644
--- a/drivers/ata/libata.h
+++ b/drivers/ata/libata.h
@@ -66,7 +66,7 @@ extern u64 ata_tf_to_lba48(const struct ata_taskfile *tf);
extern struct ata_queued_cmd *ata_qc_new_init(struct ata_device *dev, int tag);
extern int ata_build_rw_tf(struct ata_taskfile *tf, struct ata_device *dev,
u64 block, u32 n_block, unsigned int tf_flags,
- unsigned int tag);
+ unsigned int tag, int class);
extern u64 ata_tf_read_block(const struct ata_taskfile *tf,
struct ata_device *dev);
extern unsigned ata_exec_internal(struct ata_device *dev,
diff --git a/include/linux/ata.h b/include/linux/ata.h
index fdb1803..af6859b 100644
--- a/include/linux/ata.h
+++ b/include/linux/ata.h
@@ -348,6 +348,7 @@ enum {
ATA_LOG_DEVSLP_DETO = 0x01,
ATA_LOG_DEVSLP_VALID = 0x07,
ATA_LOG_DEVSLP_VALID_MASK = 0x80,
+ ATA_LOG_NCQ_PRIO_OFFSET = 0x09,
/* NCQ send and receive log */
ATA_LOG_NCQ_SEND_RECV_SUBCMDS_OFFSET = 0x00,
@@ -940,6 +941,11 @@ static inline bool ata_id_has_ncq_non_data(const u16 *id)
return id[ATA_ID_SATA_CAPABILITY_2] & BIT(5);
}
+static inline bool ata_id_has_ncq_prio(const u16 *id)
+{
+ return id[ATA_ID_SATA_CAPABILITY] & BIT(12);
+}
+
static inline bool ata_id_has_trim(const u16 *id)
{
if (ata_id_major_version(id) >= 7 &&
diff --git a/include/linux/libata.h b/include/linux/libata.h
index 616eef4..90b69a6 100644
--- a/include/linux/libata.h
+++ b/include/linux/libata.h
@@ -166,6 +166,7 @@ enum {
ATA_DFLAG_NO_UNLOAD = (1 << 17), /* device doesn't support unload */
ATA_DFLAG_UNLOCK_HPA = (1 << 18), /* unlock HPA */
ATA_DFLAG_NCQ_SEND_RECV = (1 << 19), /* device supports NCQ SEND and RECV */
+ ATA_DFLAG_NCQ_PRIO = (1 << 20), /* device supports NCQ priority */
ATA_DFLAG_INIT_MASK = (1 << 24) - 1,
ATA_DFLAG_DETACH = (1 << 24),
@@ -342,7 +343,9 @@ enum {
ATA_SHIFT_PIO = 0,
ATA_SHIFT_MWDMA = ATA_SHIFT_PIO + ATA_NR_PIO_MODES,
ATA_SHIFT_UDMA = ATA_SHIFT_MWDMA + ATA_NR_MWDMA_MODES,
+ ATA_SHIFT_PRIO = 6,
+ ATA_PRIO_HIGH = 2,
/* size of buffer to pad xfers ending on unaligned boundaries */
ATA_DMA_PAD_SZ = 4,
--
2.7.4
^ permalink raw reply related
* [PATCH 2/2] ata: ahci_tegra: add support for tegra210
From: Preetham Chandru Ramchandra @ 2016-10-19 18:15 UTC (permalink / raw)
To: tj, swarren, thierry.reding, preetham260
Cc: ldewangan, linux-ide, vbyravarasu, pkunapuli, Preetham Chandru R
In-Reply-To: <1476900956-23719-1-git-send-email-pchandru@nvidia.com>
From: Preetham Chandru R <pchandru@nvidia.com>
Add AHCI support for tegra210.
1. Moved tegra124 specifics to tegra124_ahci_init.
2. Separated out the regulators needed for tegra124 and tegra210.
3. Set the LPM capabilities
4. Added support to disable features through DT
5. Created inline functions for read/write and modify to
SATA, SATA Config and SATA Aux registers.
Signed-off-by: Preetham Chandru R <pchandru@nvidia.com>
---
drivers/ata/ahci_tegra.c | 630 +++++++++++++++++++++++++++++++++++++----------
1 file changed, 500 insertions(+), 130 deletions(-)
diff --git a/drivers/ata/ahci_tegra.c b/drivers/ata/ahci_tegra.c
index 3a62eb2..fa88def 100644
--- a/drivers/ata/ahci_tegra.c
+++ b/drivers/ata/ahci_tegra.c
@@ -33,32 +33,74 @@
#define DRV_NAME "tegra-ahci"
+#define SATA_FPCI_BAR5_0 0x94
+#define FPCI_BAR5_START_MASK (0xFFFFFFF << 4)
+#define FPCI_BAR5_START (0x0040020 << 4)
+#define FPCI_BAR5_ACCESS_TYPE (0x1)
+
#define SATA_CONFIGURATION_0 0x180
-#define SATA_CONFIGURATION_EN_FPCI BIT(0)
+#define SATA_CONFIGURATION_0_EN_FPCI BIT(0)
+#define SATA_CONFIGURATION_CLK_OVERRIDE BIT(31)
+
+#define SATA_INTR_MASK_0 0x188
+#define IP_INT_MASK BIT(16)
#define SCFG_OFFSET 0x1000
-#define T_SATA0_CFG_1 0x04
-#define T_SATA0_CFG_1_IO_SPACE BIT(0)
-#define T_SATA0_CFG_1_MEMORY_SPACE BIT(1)
-#define T_SATA0_CFG_1_BUS_MASTER BIT(2)
-#define T_SATA0_CFG_1_SERR BIT(8)
+#define T_SATA_CFG_1 0x4
+#define T_SATA_CFG_1_IO_SPACE BIT(0)
+#define T_SATA_CFG_1_MEMORY_SPACE BIT(1)
+#define T_SATA_CFG_1_BUS_MASTER BIT(2)
+#define T_SATA_CFG_1_SERR BIT(8)
+
+#define T_SATA_CFG_9 0x24
+#define T_SATA_CFG_9_BASE_ADDRESS 0x40020000
-#define T_SATA0_CFG_9 0x24
-#define T_SATA0_CFG_9_BASE_ADDRESS_SHIFT 13
+#define T_SATA0_CFG_35 0x94
+#define T_SATA0_CFG_35_IDP_INDEX_MASK (0x7FF << 2)
+#define T_SATA0_CFG_35_IDP_INDEX (0x2A << 2)
-#define SATA_FPCI_BAR5 0x94
-#define SATA_FPCI_BAR5_START_SHIFT 4
+#define T_SATA0_AHCI_IDP1 0x98
+#define T_SATA0_AHCI_IDP1_DATA (0x400040)
-#define SATA_INTR_MASK 0x188
-#define SATA_INTR_MASK_IP_INT_MASK BIT(16)
+#define T_SATA0_CFG_PHY_1 0x12C
+#define T_SATA0_CFG_PHY_1_PADS_IDDQ_EN BIT(23)
+#define T_SATA0_CFG_PHY_1_PAD_PLL_IDDQ_EN BIT(22)
+
+#define T_SATA0_NVOOB 0x114
+#define T_SATA0_NVOOB_COMMA_CNT_MASK (0xff << 16)
+#define T_SATA0_NVOOB_COMMA_CNT (0x07 << 16)
+#define T_SATA0_NVOOB_SQUELCH_FILTER_MODE_MASK (0x3 << 24)
+#define T_SATA0_NVOOB_SQUELCH_FILTER_MODE (0x1 << 24)
+#define T_SATA0_NVOOB_SQUELCH_FILTER_LENGTH_MASK (0x3 << 26)
+#define T_SATA0_NVOOB_SQUELCH_FILTER_LENGTH (0x3 << 26)
+
+#define T_SATA_CFG_PHY_0 0x120
+#define T_SATA_CFG_PHY_0_USE_7BIT_ALIGN_DET_FOR_SPD BIT(11)
+#define T_SATA_CFG_PHY_0_MASK_SQUELCH BIT(24)
+
+#define FUSE_SATA_CALIB 0x124
+#define FUSE_SATA_CALIB_MASK 0x3
+
+#define T_SATA0_CFG2NVOOB_2 0x134
+#define T_SATA0_CFG2NVOOB_2_COMWAKE_IDLE_CNT_LOW_MASK (0x1ff << 18)
+#define T_SATA0_CFG2NVOOB_2_COMWAKE_IDLE_CNT_LOW (0xc << 18)
#define T_SATA0_AHCI_HBA_CAP_BKDR 0x300
+#define T_SATA0_AHCI_HBA_CAP_BKDR_PARTIAL_ST_CAP BIT(13)
+#define T_SATA0_AHCI_HBA_CAP_BKDR_SLUMBER_ST_CAP BIT(14)
+#define T_SATA0_AHCI_HBA_CAP_BKDR_SALP BIT(26)
+#define T_SATA0_AHCI_HBA_CAP_BKDR_SUPP_PM BIT(17)
+#define T_SATA0_AHCI_HBA_CAP_BKDR_SNCQ BIT(30)
-#define T_SATA0_BKDOOR_CC 0x4a4
+#define T_SATA_BKDOOR_CC 0x4A4
+#define T_SATA_BKDOOR_CC_CLASS_CODE_MASK (0xFFFF << 16)
+#define T_SATA_BKDOOR_CC_CLASS_CODE (0x0106 << 16)
+#define T_SATA_BKDOOR_CC_PROG_IF_MASK (0xFF << 8)
+#define T_SATA_BKDOOR_CC_PROG_IF (0x01 << 8)
-#define T_SATA0_CFG_SATA 0x54c
-#define T_SATA0_CFG_SATA_BACKDOOR_PROG_IF_EN BIT(12)
+#define T_SATA_CFG_SATA 0x54C
+#define T_SATA_CFG_SATA_BACKDOOR_PROG_IF_EN BIT(12)
#define T_SATA0_CFG_MISC 0x550
@@ -82,8 +124,27 @@
#define T_SATA0_CHX_PHY_CTRL11 0x6d0
#define T_SATA0_CHX_PHY_CTRL11_GEN2_RX_EQ (0x2800 << 16)
-#define FUSE_SATA_CALIB 0x124
-#define FUSE_SATA_CALIB_MASK 0x3
+/* Electrical settings for better link stability */
+#define T_SATA0_CHX_PHY_CTRL17_0 0x6e8
+#define T_SATA0_CHX_PHY_CTRL17_0_RX_EQ_CTRL_L_GEN1 0x55010000
+#define T_SATA0_CHX_PHY_CTRL18_0 0x6ec
+#define T_SATA0_CHX_PHY_CTRL18_0_RX_EQ_CTRL_L_GEN2 0x55010000
+#define T_SATA0_CHX_PHY_CTRL20_0 0x6f4
+#define T_SATA0_CHX_PHY_CTRL20_0_RX_EQ_CTRL_H_GEN1 0x1
+#define T_SATA0_CHX_PHY_CTRL21_0 0x6f8
+#define T_SATA0_CHX_PHY_CTRL21_0_RX_EQ_CTRL_H_GEN2 0x1
+
+/* AUX Registers */
+#define SATA_AUX_MISC_CNTL_1_0 0x8
+#define DEVSLP_OVERRIDE BIT(17)
+#define SDS_SUPPORT BIT(13)
+#define DESO_SUPPORT BIT(15)
+
+#define SATA_AUX_RX_STAT_INT_0 0xc
+#define SATA_DEVSLP BIT(7)
+
+#define SATA_AUX_SPARE_CFG0_0 0x18
+#define MDAT_TIMER_AFTER_PG_VALID BIT(14)
struct sata_pad_calibration {
u8 gen1_tx_amp;
@@ -99,15 +160,161 @@ static const struct sata_pad_calibration tegra124_pad_calibration[] = {
{0x14, 0x0e, 0x1a, 0x0e},
};
+struct tegra_ahci_ops {
+ int (*init)(struct ahci_host_priv *);
+};
+
+struct tegra_ahci_soc {
+ const char * const *supply_names;
+ unsigned int num_supplies;
+ struct tegra_ahci_ops ops;
+};
+
struct tegra_ahci_priv {
struct platform_device *pdev;
void __iomem *sata_regs;
+ void __iomem *sata_aux_regs;
struct reset_control *sata_rst;
struct reset_control *sata_oob_rst;
struct reset_control *sata_cold_rst;
/* Needs special handling, cannot use ahci_platform */
struct clk *sata_clk;
- struct regulator_bulk_data supplies[5];
+ struct regulator_bulk_data *supplies;
+ struct tegra_ahci_soc *soc_data;
+};
+
+static const char * const tegra124_supply_names[] = {
+ "avdd", "hvdd", "vddio", "target-5v", "target-12v"
+};
+
+static inline void tegra_ahci_sata_update(
+ struct tegra_ahci_priv *tegra,
+ u32 val, u32 mask, u32 offset
+
+ )
+{
+ u32 uval = 0;
+
+ uval = readl(tegra->sata_regs + offset);
+ uval = (uval & ~mask) | (val & mask);
+ writel(uval, tegra->sata_regs + offset);
+}
+
+static inline void tegra_ahci_scfg_writel(
+ struct tegra_ahci_priv *tegra, u32 val, u32 offset
+
+ )
+{
+ writel(val, tegra->sata_regs + SCFG_OFFSET + offset);
+}
+
+static inline void tegra_ahci_scfg_update(
+ struct tegra_ahci_priv *tegra, u32 val, u32 mask, u32 offset
+
+ )
+{
+ u32 uval = 0;
+
+ uval = readl(tegra->sata_regs + SCFG_OFFSET + offset);
+ uval = (uval & ~mask) | (val & mask);
+ writel(uval, tegra->sata_regs + SCFG_OFFSET + offset);
+}
+
+static inline u32 tegra_ahci_aux_readl(
+ struct tegra_ahci_priv *tegra, u32 offset
+
+ )
+{
+ u32 rval = 0;
+
+ rval = readl(tegra->sata_aux_regs + offset);
+ return rval;
+}
+
+static inline void tegra_ahci_aux_update(
+ struct tegra_ahci_priv *tegra, u32 val, u32 mask, u32 offset
+
+ )
+{
+ u32 uval = 0;
+
+ uval = readl(tegra->sata_aux_regs + offset);
+ uval = (uval & ~mask) | (val & mask);
+ writel(uval, tegra->sata_aux_regs + offset);
+}
+
+static int tegra124_ahci_init(struct ahci_host_priv *hpriv)
+{
+ struct tegra_ahci_priv *tegra = hpriv->plat_data;
+ struct sata_pad_calibration calib;
+ int ret;
+ u32 val;
+ u32 mask;
+
+ /* Pad calibration */
+
+ ret = tegra_fuse_readl(FUSE_SATA_CALIB, &val);
+ if (ret) {
+ dev_err(&tegra->pdev->dev,
+ "failed to read calibration fuse: %d\n", ret);
+ return ret;
+ }
+
+ calib = tegra124_pad_calibration[val & FUSE_SATA_CALIB_MASK];
+
+ tegra_ahci_scfg_writel(tegra, BIT(0), T_SATA0_INDEX);
+
+ mask = T_SATA0_CHX_PHY_CTRL1_GEN1_TX_AMP_MASK;
+ mask |= T_SATA0_CHX_PHY_CTRL1_GEN1_TX_PEAK_MASK;
+ val = calib.gen1_tx_amp <<
+ T_SATA0_CHX_PHY_CTRL1_GEN1_TX_AMP_SHIFT;
+ val |= calib.gen1_tx_peak <<
+ T_SATA0_CHX_PHY_CTRL1_GEN1_TX_PEAK_SHIFT;
+ tegra_ahci_scfg_update(tegra, val, mask, T_SATA0_CHX_PHY_CTRL1_GEN1);
+
+ mask = T_SATA0_CHX_PHY_CTRL1_GEN2_TX_AMP_MASK;
+ mask |= T_SATA0_CHX_PHY_CTRL1_GEN2_TX_PEAK_MASK;
+ val = calib.gen2_tx_amp <<
+ T_SATA0_CHX_PHY_CTRL1_GEN1_TX_AMP_SHIFT;
+ val |= calib.gen2_tx_peak <<
+ T_SATA0_CHX_PHY_CTRL1_GEN1_TX_PEAK_SHIFT;
+ tegra_ahci_scfg_update(tegra, val, mask, T_SATA0_CHX_PHY_CTRL1_GEN2);
+
+ tegra_ahci_scfg_writel(
+ tegra,
+ T_SATA0_CHX_PHY_CTRL11_GEN2_RX_EQ,
+ T_SATA0_CHX_PHY_CTRL11
+ );
+ tegra_ahci_scfg_writel(
+ tegra,
+ T_SATA0_CHX_PHY_CTRL2_CDR_CNTL_GEN1,
+ T_SATA0_CHX_PHY_CTRL2
+ );
+
+ tegra_ahci_scfg_writel(tegra, 0, T_SATA0_INDEX);
+
+ return 0;
+}
+
+static const char * const tegra210_supply_names[] = {
+ "dvdd-sata-pll",
+ "hvdd-sata",
+ "l0-hvddio-sata",
+ "l0-dvddio-sata",
+ "hvdd-pex-pll-e"
+};
+
+static const struct tegra_ahci_soc tegra124_ahci = {
+ .supply_names = tegra124_supply_names,
+ .num_supplies = ARRAY_SIZE(tegra124_supply_names),
+ .ops = {
+ .init = tegra124_ahci_init,
+ },
+};
+
+static const struct tegra_ahci_soc tegra210_ahci = {
+ .supply_names = tegra210_supply_names,
+ .num_supplies = ARRAY_SIZE(tegra210_supply_names),
};
static int tegra_ahci_power_on(struct ahci_host_priv *hpriv)
@@ -115,8 +322,10 @@ static int tegra_ahci_power_on(struct ahci_host_priv *hpriv)
struct tegra_ahci_priv *tegra = hpriv->plat_data;
int ret;
- ret = regulator_bulk_enable(ARRAY_SIZE(tegra->supplies),
- tegra->supplies);
+ ret = regulator_bulk_enable(
+ tegra->soc_data->num_supplies,
+ tegra->supplies
+ );
if (ret)
return ret;
@@ -144,8 +353,10 @@ static int tegra_ahci_power_on(struct ahci_host_priv *hpriv)
tegra_powergate_power_off(TEGRA_POWERGATE_SATA);
disable_regulators:
- regulator_bulk_disable(ARRAY_SIZE(tegra->supplies), tegra->supplies);
-
+ regulator_bulk_disable(
+ tegra->soc_data->num_supplies,
+ tegra->supplies
+ );
return ret;
}
@@ -162,131 +373,264 @@ static void tegra_ahci_power_off(struct ahci_host_priv *hpriv)
clk_disable_unprepare(tegra->sata_clk);
tegra_powergate_power_off(TEGRA_POWERGATE_SATA);
- regulator_bulk_disable(ARRAY_SIZE(tegra->supplies), tegra->supplies);
+ regulator_bulk_disable(
+ tegra->soc_data->num_supplies,
+ tegra->supplies
+ );
}
-static int tegra_ahci_controller_init(struct ahci_host_priv *hpriv)
+static void tegra_ahci_controller_deinit(struct ahci_host_priv *hpriv)
{
- struct tegra_ahci_priv *tegra = hpriv->plat_data;
- int ret;
- unsigned int val;
- struct sata_pad_calibration calib;
-
- ret = tegra_ahci_power_on(hpriv);
- if (ret) {
- dev_err(&tegra->pdev->dev,
- "failed to power on AHCI controller: %d\n", ret);
- return ret;
- }
-
- val = readl(tegra->sata_regs + SATA_CONFIGURATION_0);
- val |= SATA_CONFIGURATION_EN_FPCI;
- writel(val, tegra->sata_regs + SATA_CONFIGURATION_0);
-
- /* Pad calibration */
-
- ret = tegra_fuse_readl(FUSE_SATA_CALIB, &val);
- if (ret) {
- dev_err(&tegra->pdev->dev,
- "failed to read calibration fuse: %d\n", ret);
- return ret;
- }
-
- calib = tegra124_pad_calibration[val & FUSE_SATA_CALIB_MASK];
-
- writel(BIT(0), tegra->sata_regs + SCFG_OFFSET + T_SATA0_INDEX);
-
- val = readl(tegra->sata_regs +
- SCFG_OFFSET + T_SATA0_CHX_PHY_CTRL1_GEN1);
- val &= ~T_SATA0_CHX_PHY_CTRL1_GEN1_TX_AMP_MASK;
- val &= ~T_SATA0_CHX_PHY_CTRL1_GEN1_TX_PEAK_MASK;
- val |= calib.gen1_tx_amp <<
- T_SATA0_CHX_PHY_CTRL1_GEN1_TX_AMP_SHIFT;
- val |= calib.gen1_tx_peak <<
- T_SATA0_CHX_PHY_CTRL1_GEN1_TX_PEAK_SHIFT;
- writel(val, tegra->sata_regs + SCFG_OFFSET +
- T_SATA0_CHX_PHY_CTRL1_GEN1);
-
- val = readl(tegra->sata_regs +
- SCFG_OFFSET + T_SATA0_CHX_PHY_CTRL1_GEN2);
- val &= ~T_SATA0_CHX_PHY_CTRL1_GEN2_TX_AMP_MASK;
- val &= ~T_SATA0_CHX_PHY_CTRL1_GEN2_TX_PEAK_MASK;
- val |= calib.gen2_tx_amp <<
- T_SATA0_CHX_PHY_CTRL1_GEN1_TX_AMP_SHIFT;
- val |= calib.gen2_tx_peak <<
- T_SATA0_CHX_PHY_CTRL1_GEN1_TX_PEAK_SHIFT;
- writel(val, tegra->sata_regs + SCFG_OFFSET +
- T_SATA0_CHX_PHY_CTRL1_GEN2);
+ tegra_ahci_power_off(hpriv);
+}
- writel(T_SATA0_CHX_PHY_CTRL11_GEN2_RX_EQ,
- tegra->sata_regs + SCFG_OFFSET + T_SATA0_CHX_PHY_CTRL11);
- writel(T_SATA0_CHX_PHY_CTRL2_CDR_CNTL_GEN1,
- tegra->sata_regs + SCFG_OFFSET + T_SATA0_CHX_PHY_CTRL2);
+static void tegra_ahci_host_stop(struct ata_host *host)
+{
+ struct ahci_host_priv *hpriv = host->private_data;
- writel(0, tegra->sata_regs + SCFG_OFFSET + T_SATA0_INDEX);
+ tegra_ahci_controller_deinit(hpriv);
+}
- /* Program controller device ID */
+static struct ata_port_operations ahci_tegra_port_ops = {
+ .inherits = &ahci_ops,
+ .host_stop = tegra_ahci_host_stop,
+};
- val = readl(tegra->sata_regs + SCFG_OFFSET + T_SATA0_CFG_SATA);
- val |= T_SATA0_CFG_SATA_BACKDOOR_PROG_IF_EN;
- writel(val, tegra->sata_regs + SCFG_OFFSET + T_SATA0_CFG_SATA);
+static struct ata_port_info ahci_tegra_port_info = {
+ .flags = AHCI_FLAG_COMMON,
+ .pio_mask = ATA_PIO4,
+ .udma_mask = ATA_UDMA6,
+ .port_ops = &ahci_tegra_port_ops,
+};
- writel(0x01060100, tegra->sata_regs + SCFG_OFFSET + T_SATA0_BKDOOR_CC);
+static void tegra_ahci_disable_devslp(struct tegra_ahci_priv *tegra)
+{
+ u32 val = 0;
+ u32 mask = SDS_SUPPORT;
- val = readl(tegra->sata_regs + SCFG_OFFSET + T_SATA0_CFG_SATA);
- val &= ~T_SATA0_CFG_SATA_BACKDOOR_PROG_IF_EN;
- writel(val, tegra->sata_regs + SCFG_OFFSET + T_SATA0_CFG_SATA);
+ val = 0xFFFFFFFF & ~SDS_SUPPORT;
+ tegra_ahci_aux_update(tegra, val, mask, SATA_AUX_MISC_CNTL_1_0);
+}
- /* Enable IO & memory access, bus master mode */
+static void tegra_ahci_disable_hipm(struct tegra_ahci_priv *tegra)
+{
+ u32 val = 0;
+ u32 mask = T_SATA0_AHCI_HBA_CAP_BKDR_SALP;
- val = readl(tegra->sata_regs + SCFG_OFFSET + T_SATA0_CFG_1);
- val |= T_SATA0_CFG_1_IO_SPACE | T_SATA0_CFG_1_MEMORY_SPACE |
- T_SATA0_CFG_1_BUS_MASTER | T_SATA0_CFG_1_SERR;
- writel(val, tegra->sata_regs + SCFG_OFFSET + T_SATA0_CFG_1);
+ val = 0xFFFFFFFF & ~T_SATA0_AHCI_HBA_CAP_BKDR_SALP;
+ tegra_ahci_scfg_update(tegra, val, mask, T_SATA0_AHCI_HBA_CAP_BKDR);
+}
- /* Program SATA MMIO */
+static void tegra_ahci_disable_partial(struct tegra_ahci_priv *tegra)
+{
+ u32 val = 0;
+ u32 mask = T_SATA0_AHCI_HBA_CAP_BKDR_PARTIAL_ST_CAP;
- writel(0x10000 << SATA_FPCI_BAR5_START_SHIFT,
- tegra->sata_regs + SATA_FPCI_BAR5);
+ val = 0xFFFFFFFF & ~T_SATA0_AHCI_HBA_CAP_BKDR_PARTIAL_ST_CAP;
+ tegra_ahci_scfg_update(tegra, val, mask, T_SATA0_AHCI_HBA_CAP_BKDR);
+}
- writel(0x08000 << T_SATA0_CFG_9_BASE_ADDRESS_SHIFT,
- tegra->sata_regs + SCFG_OFFSET + T_SATA0_CFG_9);
+static void tegra_ahci_disable_slumber(struct tegra_ahci_priv *tegra)
+{
+ u32 val = 0;
+ u32 mask = T_SATA0_AHCI_HBA_CAP_BKDR_SLUMBER_ST_CAP;
- /* Unmask SATA interrupts */
+ val = 0xFFFFFFFF & ~T_SATA0_AHCI_HBA_CAP_BKDR_SLUMBER_ST_CAP;
+ tegra_ahci_scfg_update(tegra, val, mask, T_SATA0_AHCI_HBA_CAP_BKDR);
+}
- val = readl(tegra->sata_regs + SATA_INTR_MASK);
- val |= SATA_INTR_MASK_IP_INT_MASK;
- writel(val, tegra->sata_regs + SATA_INTR_MASK);
+static void tegra_ahci_disable_ncq(struct tegra_ahci_priv *tegra)
+{
+ u32 val = 0;
+ u32 mask = T_SATA0_AHCI_HBA_CAP_BKDR_SNCQ;
- return 0;
+ val = 0xFFFFFFFF & ~T_SATA0_AHCI_HBA_CAP_BKDR_SNCQ;
+ tegra_ahci_scfg_update(tegra, val, mask, T_SATA0_AHCI_HBA_CAP_BKDR);
}
-static void tegra_ahci_controller_deinit(struct ahci_host_priv *hpriv)
+static int tegra_ahci_disable_features(struct ahci_host_priv *hpriv)
{
- tegra_ahci_power_off(hpriv);
+ struct tegra_ahci_priv *tegra = hpriv->plat_data;
+ struct platform_device *pdev = tegra->pdev;
+ struct device *dev = &pdev->dev;
+ struct device_node *np = dev->of_node;
+ struct property *prop;
+ const char *feature;
+ int ret = 0;
+
+ if (of_property_count_strings(np, "nvidia,disable-features") <= 0)
+ return 0;
+
+ of_property_for_each_string(
+ np, "nvidia,disable-features", prop, feature
+ ) {
+ if (!strcmp(feature, "devslp"))
+ tegra_ahci_disable_devslp(tegra);
+ else if (!strcmp(feature, "hipm"))
+ tegra_ahci_disable_hipm(tegra);
+ else if (!strcmp(feature, "ncq"))
+ tegra_ahci_disable_ncq(tegra);
+ else if (!strcmp(feature, "dipm"))
+ ahci_tegra_port_info.flags |= ATA_FLAG_NO_DIPM;
+ else if (!strcmp(feature, "partial"))
+ tegra_ahci_disable_partial(tegra);
+ else if (!strcmp(feature, "slumber"))
+ tegra_ahci_disable_slumber(tegra);
+ }
+
+ return ret;
}
-static void tegra_ahci_host_stop(struct ata_host *host)
+static int tegra_ahci_controller_init(struct ahci_host_priv *hpriv)
{
- struct ahci_host_priv *hpriv = host->private_data;
+ struct tegra_ahci_priv *tegra = hpriv->plat_data;
+ int ret;
+ unsigned int val;
+ unsigned int mask;
- tegra_ahci_controller_deinit(hpriv);
-}
+ ret = tegra_ahci_power_on(hpriv);
+ if (ret) {
+ dev_err(&tegra->pdev->dev,
+ "failed to power on AHCI controller: %d\n", ret);
+ return ret;
+ }
-static struct ata_port_operations ahci_tegra_port_ops = {
- .inherits = &ahci_ops,
- .host_stop = tegra_ahci_host_stop,
-};
+ /* Program the following SATA IPFS registers
+ * to allow SW accesses to SATA's MMIO Register
+ */
+ mask = FPCI_BAR5_START_MASK | FPCI_BAR5_ACCESS_TYPE;
+ val = FPCI_BAR5_START | FPCI_BAR5_ACCESS_TYPE;
+ tegra_ahci_sata_update(tegra, val, mask, SATA_FPCI_BAR5_0);
+
+ /* Program the following SATA IPFS register to enable the SATA */
+ val = SATA_CONFIGURATION_0_EN_FPCI;
+ tegra_ahci_sata_update(tegra, val, val, SATA_CONFIGURATION_0);
+
+ /* Electrical settings for better link stability */
+ tegra_ahci_scfg_writel(
+ tegra,
+ T_SATA0_CHX_PHY_CTRL17_0_RX_EQ_CTRL_L_GEN1,
+ T_SATA0_CHX_PHY_CTRL17_0
+ );
+ tegra_ahci_scfg_writel(
+ tegra,
+ T_SATA0_CHX_PHY_CTRL18_0_RX_EQ_CTRL_L_GEN2,
+ T_SATA0_CHX_PHY_CTRL18_0);
+ tegra_ahci_scfg_writel(
+ tegra,
+ T_SATA0_CHX_PHY_CTRL20_0_RX_EQ_CTRL_H_GEN1,
+ T_SATA0_CHX_PHY_CTRL20_0
+ );
+ tegra_ahci_scfg_writel(
+ tegra,
+ T_SATA0_CHX_PHY_CTRL21_0_RX_EQ_CTRL_H_GEN2,
+ T_SATA0_CHX_PHY_CTRL21_0
+ );
+
+ /* For SQUELCH Filter & Gen3 drive getting detected as Gen1 drive */
+
+ mask = T_SATA_CFG_PHY_0_MASK_SQUELCH |
+ T_SATA_CFG_PHY_0_USE_7BIT_ALIGN_DET_FOR_SPD;
+ val = T_SATA_CFG_PHY_0_MASK_SQUELCH;
+ val &= ~T_SATA_CFG_PHY_0_USE_7BIT_ALIGN_DET_FOR_SPD;
+ tegra_ahci_scfg_update(tegra, val, mask, T_SATA_CFG_PHY_0);
+
+ mask = (
+ T_SATA0_NVOOB_COMMA_CNT_MASK |
+ T_SATA0_NVOOB_SQUELCH_FILTER_LENGTH_MASK |
+ T_SATA0_NVOOB_SQUELCH_FILTER_MODE_MASK
+ );
+ val = (
+ T_SATA0_NVOOB_COMMA_CNT |
+ T_SATA0_NVOOB_SQUELCH_FILTER_LENGTH |
+ T_SATA0_NVOOB_SQUELCH_FILTER_MODE
+ );
+ tegra_ahci_scfg_update(tegra, val, mask, T_SATA0_NVOOB);
+
+ /*
+ * Change CFG2NVOOB_2_COMWAKE_IDLE_CNT_LOW from 83.3 ns to 58.8ns
+ */
+ mask = T_SATA0_CFG2NVOOB_2_COMWAKE_IDLE_CNT_LOW_MASK;
+ val = T_SATA0_CFG2NVOOB_2_COMWAKE_IDLE_CNT_LOW;
+ tegra_ahci_scfg_update(tegra, val, mask, T_SATA0_CFG2NVOOB_2);
+
+ if (tegra->soc_data->ops.init)
+ tegra->soc_data->ops.init(hpriv);
+
+ /* Program the following SATA configuration registers
+ * to initialize SATA
+ */
+ val = (T_SATA_CFG_1_IO_SPACE | T_SATA_CFG_1_MEMORY_SPACE |
+ T_SATA_CFG_1_BUS_MASTER | T_SATA_CFG_1_SERR);
+ tegra_ahci_scfg_update(tegra, val, val, T_SATA_CFG_1);
+ tegra_ahci_scfg_writel(tegra, T_SATA_CFG_9_BASE_ADDRESS, T_SATA_CFG_9);
+
+ /* Program Class Code and Programming interface for SATA */
+ val = T_SATA_CFG_SATA_BACKDOOR_PROG_IF_EN;
+ tegra_ahci_scfg_update(tegra, val, val, T_SATA_CFG_SATA);
+
+ mask = T_SATA_BKDOOR_CC_CLASS_CODE_MASK | T_SATA_BKDOOR_CC_PROG_IF_MASK;
+ val = T_SATA_BKDOOR_CC_CLASS_CODE | T_SATA_BKDOOR_CC_PROG_IF;
+ tegra_ahci_scfg_update(tegra, val, mask, T_SATA_BKDOOR_CC);
+
+ mask = T_SATA_CFG_SATA_BACKDOOR_PROG_IF_EN;
+ val = (u32)~T_SATA_CFG_SATA_BACKDOOR_PROG_IF_EN;
+ tegra_ahci_scfg_update(tegra, val, mask, T_SATA_CFG_SATA);
+
+ /* Enabling LPM capabilities through Backdoor Programming */
+ val = (T_SATA0_AHCI_HBA_CAP_BKDR_PARTIAL_ST_CAP |
+ T_SATA0_AHCI_HBA_CAP_BKDR_SLUMBER_ST_CAP |
+ T_SATA0_AHCI_HBA_CAP_BKDR_SALP |
+ T_SATA0_AHCI_HBA_CAP_BKDR_SUPP_PM);
+ tegra_ahci_scfg_update(tegra, val, val, T_SATA0_AHCI_HBA_CAP_BKDR);
+
+ /* SATA Second Level Clock Gating configuration
+ * Enabling Gating of Tx/Rx clocks and driving Pad IDDQ and Lane
+ * IDDQ Signals
+ */
+ mask = T_SATA0_CFG_35_IDP_INDEX_MASK;
+ val = T_SATA0_CFG_35_IDP_INDEX;
+ tegra_ahci_scfg_update(tegra, val, mask, T_SATA0_CFG_35);
+ tegra_ahci_scfg_writel(
+ tegra, T_SATA0_AHCI_IDP1_DATA,
+ T_SATA0_AHCI_IDP1
+ );
+ val = (
+ T_SATA0_CFG_PHY_1_PADS_IDDQ_EN |
+ T_SATA0_CFG_PHY_1_PAD_PLL_IDDQ_EN
+ );
+ tegra_ahci_scfg_update(tegra, val, val, T_SATA0_CFG_PHY_1);
+
+ /*
+ * Indicate Sata only has the capability to enter DevSleep
+ * from slumber link.
+ */
+ tegra_ahci_aux_update(
+ tegra, DESO_SUPPORT, DESO_SUPPORT,
+ SATA_AUX_MISC_CNTL_1_0
+ );
+ /* Enabling IPFS Clock Gating */
+ mask = SATA_CONFIGURATION_CLK_OVERRIDE;
+ val = (u32)~SATA_CONFIGURATION_CLK_OVERRIDE;
+ tegra_ahci_sata_update(tegra, val, mask, SATA_CONFIGURATION_0);
+
+ tegra_ahci_disable_features(hpriv);
+
+ val = IP_INT_MASK;
+ tegra_ahci_sata_update(tegra, val, val, SATA_INTR_MASK_0);
-static const struct ata_port_info ahci_tegra_port_info = {
- .flags = AHCI_FLAG_COMMON,
- .pio_mask = ATA_PIO4,
- .udma_mask = ATA_UDMA6,
- .port_ops = &ahci_tegra_port_ops,
-};
+ return 0;
+}
static const struct of_device_id tegra_ahci_of_match[] = {
- { .compatible = "nvidia,tegra124-ahci" },
+ {
+ .compatible = "nvidia,tegra124-ahci",
+ .data = &tegra124_ahci
+ },
+ {
+ .compatible = "nvidia,tegra210-ahci",
+ .data = &tegra210_ahci
+ },
{}
};
MODULE_DEVICE_TABLE(of, tegra_ahci_of_match);
@@ -300,7 +644,9 @@ static int tegra_ahci_probe(struct platform_device *pdev)
struct ahci_host_priv *hpriv;
struct tegra_ahci_priv *tegra;
struct resource *res;
+ const struct of_device_id *match = NULL;
int ret;
+ unsigned int i;
hpriv = ahci_platform_get_resources(pdev);
if (IS_ERR(hpriv))
@@ -314,10 +660,23 @@ static int tegra_ahci_probe(struct platform_device *pdev)
tegra->pdev = pdev;
+ match = of_match_device(
+ of_match_ptr(tegra_ahci_of_match), &pdev->dev
+ );
+ if (!match)
+ return -ENODEV;
+
+ tegra->soc_data =
+ (struct tegra_ahci_soc *)of_device_get_match_data(&pdev->dev);
+
res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
tegra->sata_regs = devm_ioremap_resource(&pdev->dev, res);
if (IS_ERR(tegra->sata_regs))
return PTR_ERR(tegra->sata_regs);
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 2);
+ tegra->sata_aux_regs = devm_ioremap_resource(&pdev->dev, res);
+ if (IS_ERR(tegra->sata_aux_regs))
+ return PTR_ERR(tegra->sata_aux_regs);
tegra->sata_rst = devm_reset_control_get(&pdev->dev, "sata");
if (IS_ERR(tegra->sata_rst)) {
@@ -343,14 +702,23 @@ static int tegra_ahci_probe(struct platform_device *pdev)
return PTR_ERR(tegra->sata_clk);
}
- tegra->supplies[0].supply = "avdd";
- tegra->supplies[1].supply = "hvdd";
- tegra->supplies[2].supply = "vddio";
- tegra->supplies[3].supply = "target-5v";
- tegra->supplies[4].supply = "target-12v";
-
- ret = devm_regulator_bulk_get(&pdev->dev, ARRAY_SIZE(tegra->supplies),
- tegra->supplies);
+ tegra->supplies = devm_kcalloc(
+ &pdev->dev,
+ tegra->soc_data->num_supplies,
+ sizeof(*tegra->supplies),
+ GFP_KERNEL
+ );
+ if (IS_ERR(tegra->supplies))
+ return PTR_ERR(tegra->supplies);
+
+ for (i = 0; i < tegra->soc_data->num_supplies; i++)
+ tegra->supplies[i].supply = tegra->soc_data->supply_names[i];
+
+ ret = devm_regulator_bulk_get(
+ &pdev->dev,
+ tegra->soc_data->num_supplies,
+ tegra->supplies
+ );
if (ret) {
dev_err(&pdev->dev, "Failed to get regulators\n");
return ret;
@@ -360,8 +728,10 @@ static int tegra_ahci_probe(struct platform_device *pdev)
if (ret)
return ret;
- ret = ahci_platform_init_host(pdev, hpriv, &ahci_tegra_port_info,
- &ahci_platform_sht);
+ ret = ahci_platform_init_host(
+ pdev, hpriv, &ahci_tegra_port_info,
+ &ahci_platform_sht
+ );
if (ret)
goto deinit_controller;
@@ -385,5 +755,5 @@ static struct platform_driver tegra_ahci_driver = {
module_platform_driver(tegra_ahci_driver);
MODULE_AUTHOR("Mikko Perttunen <mperttunen@nvidia.com>");
-MODULE_DESCRIPTION("Tegra124 AHCI SATA driver");
+MODULE_DESCRIPTION("Tegra AHCI SATA driver");
MODULE_LICENSE("GPL v2");
--
2.1.4
^ permalink raw reply related
* [PATCH 1/2] dt-bindings: ata: ahci_tegra: Add tegra210 AHCI support
From: Preetham Chandru Ramchandra @ 2016-10-19 18:15 UTC (permalink / raw)
To: tj, swarren, thierry.reding, preetham260
Cc: ldewangan, linux-ide, vbyravarasu, pkunapuli, Preetham Chandru R
In-Reply-To: <1476900956-23719-1-git-send-email-pchandru@nvidia.com>
From: Preetham Chandru R <pchandru@nvidia.com>
Signed-off-by: Preetham Chandru R <pchandru@nvidia.com>
---
.../bindings/ata/nvidia,tegra124-ahci.txt | 48 ++++++++++++++++------
1 file changed, 36 insertions(+), 12 deletions(-)
diff --git a/Documentation/devicetree/bindings/ata/nvidia,tegra124-ahci.txt b/Documentation/devicetree/bindings/ata/nvidia,tegra124-ahci.txt
index 66c83c3..446214f 100644
--- a/Documentation/devicetree/bindings/ata/nvidia,tegra124-ahci.txt
+++ b/Documentation/devicetree/bindings/ata/nvidia,tegra124-ahci.txt
@@ -1,9 +1,9 @@
-Tegra124 SoC SATA AHCI controller
+Tegra SoC SATA AHCI controller
Required properties :
-- compatible : For Tegra124, must contain "nvidia,tegra124-ahci". Otherwise,
- must contain '"nvidia,<chip>-ahci", "nvidia,tegra124-ahci"', where <chip>
- is tegra132.
+- compatible : Must be one of:
+ - Tegra124 : "nvidia,tegra124-ahci"
+ - Tegra210 : "nvidia,tegra210-ahci"
- reg : Should contain 2 entries:
- AHCI register set (SATA BAR5)
- SATA register set
@@ -13,8 +13,6 @@ Required properties :
- clock-names : Must include the following entries:
- sata
- sata-oob
- - cml1
- - pll_e
- resets : Must contain an entry for each entry in reset-names.
See ../reset/reset.txt for details.
- reset-names : Must include the following entries:
@@ -24,9 +22,35 @@ Required properties :
- phys : Must contain an entry for each entry in phy-names.
See ../phy/phy-bindings.txt for details.
- phy-names : Must include the following entries:
- - sata-phy : XUSB PADCTL SATA PHY
-- hvdd-supply : Defines the SATA HVDD regulator
-- vddio-supply : Defines the SATA VDDIO regulator
-- avdd-supply : Defines the SATA AVDD regulator
-- target-5v-supply : Defines the SATA 5V power regulator
-- target-12v-supply : Defines the SATA 12V power regulator
+ - For T124:
+ - sata-phy : XUSB PADCTL SATA PHY
+ - For T210:
+ - sata-0
+- For T124:
+ - hvdd-supply : Defines the SATA HVDD regulator
+ - vddio-supply : Defines the SATA VDDIO regulator
+ - avdd-supply : Defines the SATA AVDD regulator
+ - target-5v-supply : Defines the SATA 5V power regulator
+- For T210:
+ - l0-hvddio-sata-supply : Defines the SATA HVDDIO regulator
+ - l0-dvddio-sata-supply : Defines the SATA DVDDIO regulator
+ - hvdd-pex-pll-e-supply : Defines the PEX PLL_E regulator
+ - dvdd-sata-pll-supply : Defines the SATA PLL regulator
+ - hvdd-sata-supply : Defines the SATA HVDD regulator
+- nvidia,disable-features : Must include the following entries:
+ - devslp
+ - dipm
+
+Optional properties:
+- clock-names :
+ - cml1 :
+ cml1 clock is required by phy so it is optional to define
+ here as phy driver will be enabling this clock.
+ - pll_e :
+ pll_e is the parent of cml1 clock so it is optional to define
+ here as phy driver will be enabling this clock.
+- nvidia,disable-features :
+ - hipm
+ - ncq
+ - partial
+ - slumber
--
2.1.4
^ permalink raw reply related
* [PATCH 0/2] ADD AHCI support for tegra210
From: Preetham Chandru Ramchandra @ 2016-10-19 18:15 UTC (permalink / raw)
To: tj, swarren, thierry.reding, preetham260
Cc: ldewangan, linux-ide, vbyravarasu, pkunapuli, Preetham Chandru R
From: Preetham Chandru R <pchandru@nvidia.com>
1. ADD AHCI support for tegra210
2. Extend the tegra AHCI controller device tree binding with tegra210
support
3. Add property node to enable/disable features like dipm, hipm, devslp,
partial, slumber, ncq.
Preetham Chandru R (2):
dt-bindings: ata: ahci_tegra: Add tegra210 AHCI support
ata: ahci_tegra: add support for tegra210
.../bindings/ata/nvidia,tegra124-ahci.txt | 48 +-
drivers/ata/ahci_tegra.c | 630 ++++++++++++++++-----
2 files changed, 536 insertions(+), 142 deletions(-)
--
2.1.4
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox