All of lore.kernel.org
 help / color / mirror / Atom feed
From: Marc Gonzalez <marc_gonzalez@sigmadesigns.com>
To: Bjorn Helgaas <helgaas@kernel.org>,
	Marc Zyngier <marc.zyngier@arm.com>,
	Thomas Gleixner <tglx@linutronix.de>
Cc: linux-pci <linux-pci@vger.kernel.org>,
	Linux ARM <linux-arm-kernel@lists.infradead.org>,
	LKML <linux-kernel@vger.kernel.org>, Mason <slash.tmp@free.fr>,
	Thibaud Cornic <thibaud_cornic@sigmadesigns.com>
Subject: [PATCH v9 2/3] PCI: Add tango PCIe host bridge support
Date: Tue, 20 Jun 2017 10:17:40 +0200	[thread overview]
Message-ID: <b32f9e1c-fdde-3064-f935-c817cf707534@sigmadesigns.com> (raw)
In-Reply-To: <987fac41-80dc-f1d0-ec0b-91ae57b91bfd@sigmadesigns.com>

This driver is required to work around several hardware bugs
in the PCIe controller.

NB: Revision 1 does not support legacy interrupts, or IO space.

Signed-off-by: Marc Gonzalez <marc_gonzalez@sigmadesigns.com>
---
 drivers/pci/host/Kconfig      |   8 +++
 drivers/pci/host/Makefile     |   1 +
 drivers/pci/host/pcie-tango.c | 164 ++++++++++++++++++++++++++++++++++++++++++
 include/linux/pci_ids.h       |   2 +
 4 files changed, 175 insertions(+)
 create mode 100644 drivers/pci/host/pcie-tango.c

diff --git a/drivers/pci/host/Kconfig b/drivers/pci/host/Kconfig
index d7e7c0a827c3..5183d9095c3a 100644
--- a/drivers/pci/host/Kconfig
+++ b/drivers/pci/host/Kconfig
@@ -285,6 +285,14 @@ config PCIE_ROCKCHIP
 	  There is 1 internal PCIe port available to support GEN2 with
 	  4 slots.
 
+config PCIE_TANGO
+	bool "Tango PCIe controller"
+	depends on ARCH_TANGO && PCI_MSI && OF
+	select PCI_HOST_COMMON
+	help
+	  Say Y here to enable PCIe controller support for Sigma Designs
+	  Tango systems, such as SMP8759 and later chips.
+
 config VMD
 	depends on PCI_MSI && X86_64
 	tristate "Intel Volume Management Device Driver"
diff --git a/drivers/pci/host/Makefile b/drivers/pci/host/Makefile
index 084cb4983645..fc7ea90196f3 100644
--- a/drivers/pci/host/Makefile
+++ b/drivers/pci/host/Makefile
@@ -32,4 +32,5 @@ obj-$(CONFIG_PCI_HOST_THUNDER_PEM) += pci-thunder-pem.o
 obj-$(CONFIG_PCIE_ARMADA_8K) += pcie-armada8k.o
 obj-$(CONFIG_PCIE_ARTPEC6) += pcie-artpec6.o
 obj-$(CONFIG_PCIE_ROCKCHIP) += pcie-rockchip.o
+obj-$(CONFIG_PCIE_TANGO) += pcie-tango.o
 obj-$(CONFIG_VMD) += vmd.o
diff --git a/drivers/pci/host/pcie-tango.c b/drivers/pci/host/pcie-tango.c
new file mode 100644
index 000000000000..67aaadcc1c5e
--- /dev/null
+++ b/drivers/pci/host/pcie-tango.c
@@ -0,0 +1,164 @@
+#include <linux/pci-ecam.h>
+#include <linux/delay.h>
+#include <linux/of.h>
+
+#define MSI_MAX 256
+
+#define SMP8759_MUX		0x48
+#define SMP8759_TEST_OUT	0x74
+
+struct tango_pcie {
+	void __iomem *mux;
+};
+
+/*** HOST BRIDGE SUPPORT ***/
+
+static int smp8759_config_read(struct pci_bus *bus,
+		unsigned int devfn, int where, int size, u32 *val)
+{
+	int ret;
+	struct pci_config_window *cfg = bus->sysdata;
+	struct tango_pcie *pcie = dev_get_drvdata(cfg->parent);
+
+	/*
+	 * QUIRK #1
+	 * Reads in configuration space outside devfn 0 return garbage.
+	 */
+	if (devfn != 0)
+		return PCIBIOS_FUNC_NOT_SUPPORTED;
+
+	/*
+	 * QUIRK #2
+	 * Unfortunately, config and mem spaces are muxed.
+	 * Linux does not support such a setting, since drivers are free
+	 * to access mem space directly, at any time.
+	 * Therefore, we can only PRAY that config and mem space accesses
+	 * NEVER occur concurrently.
+	 */
+	writel_relaxed(1, pcie->mux);
+	ret = pci_generic_config_read(bus, devfn, where, size, val);
+	writel_relaxed(0, pcie->mux);
+
+	return ret;
+}
+
+static int smp8759_config_write(struct pci_bus *bus,
+		unsigned int devfn, int where, int size, u32 val)
+{
+	int ret;
+	struct pci_config_window *cfg = bus->sysdata;
+	struct tango_pcie *pcie = dev_get_drvdata(cfg->parent);
+
+	writel_relaxed(1, pcie->mux);
+	ret = pci_generic_config_write(bus, devfn, where, size, val);
+	writel_relaxed(0, pcie->mux);
+
+	return ret;
+}
+
+static struct pci_ecam_ops smp8759_ecam_ops = {
+	.bus_shift	= 20,
+	.pci_ops	= {
+		.map_bus	= pci_ecam_map_bus,
+		.read		= smp8759_config_read,
+		.write		= smp8759_config_write,
+	}
+};
+
+static const struct of_device_id tango_pcie_ids[] = {
+	{ .compatible = "sigma,smp8759-pcie" },
+	{ /* sentinel */ },
+};
+
+static int tango_check_pcie_link(void __iomem *test_out)
+{
+	int i;
+
+	writel_relaxed(16, test_out);
+	for (i = 0; i < 10; ++i) {
+		u32 ltssm_state = readl_relaxed(test_out) >> 8;
+		if ((ltssm_state & 0x1f) == 0xf) /* L0 */
+			return 0;
+		usleep_range(3000, 4000);
+	}
+
+	return -ENODEV;
+}
+
+static int smp8759_init(struct tango_pcie *pcie, void __iomem *base)
+{
+	pcie->mux		= base + SMP8759_MUX;
+
+	return tango_check_pcie_link(base + SMP8759_TEST_OUT);
+}
+
+static int tango_pcie_probe(struct platform_device *pdev)
+{
+	int ret = -EINVAL;
+	void __iomem *base;
+	struct resource *res;
+	struct tango_pcie *pcie;
+	struct device *dev = &pdev->dev;
+
+	pr_err("MAJOR ISSUE: PCIe config and mem spaces are muxed\n");
+	pr_err("Tainting kernel... Use driver at your own risk\n");
+	add_taint(TAINT_FIRMWARE_WORKAROUND, LOCKDEP_STILL_OK);
+
+	pcie = devm_kzalloc(dev, sizeof(*pcie), GFP_KERNEL);
+	if (!pcie)
+		return -ENOMEM;
+
+	platform_set_drvdata(pdev, pcie);
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+	base = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(base))
+		return PTR_ERR(base);
+
+	if (of_device_is_compatible(dev->of_node, "sigma,smp8759-pcie"))
+		ret = smp8759_init(pcie, base);
+
+	if (ret)
+		return ret;
+
+	return pci_host_common_probe(pdev, &smp8759_ecam_ops);
+}
+
+static struct platform_driver tango_pcie_driver = {
+	.probe	= tango_pcie_probe,
+	.driver	= {
+		.name = KBUILD_MODNAME,
+		.of_match_table = tango_pcie_ids,
+	},
+};
+
+builtin_platform_driver(tango_pcie_driver);
+
+/*
+ * QUIRK #3
+ * The root complex advertizes the wrong device class.
+ * Header Type 1 is for PCI-to-PCI bridges.
+ */
+static void tango_fixup_class(struct pci_dev *dev)
+{
+	dev->class = PCI_CLASS_BRIDGE_PCI << 8;
+}
+DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_SIGMA, 0x24, tango_fixup_class);
+DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_SIGMA, 0x28, tango_fixup_class);
+
+/*
+ * QUIRK #4
+ * The root complex exposes a "fake" BAR, which is used to filter
+ * bus-to-system accesses. Only accesses within the range defined
+ * by this BAR are forwarded to the host, others are ignored.
+ *
+ * By default, the DMA framework expects an identity mapping,
+ * and DRAM0 is mapped at 0x80000000.
+ */
+static void tango_fixup_bar(struct pci_dev *dev)
+{
+	dev->non_compliant_bars = true;
+	pci_write_config_dword(dev, PCI_BASE_ADDRESS_0, 0x80000000);
+}
+DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_SIGMA, 0x24, tango_fixup_bar);
+DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_SIGMA, 0x28, tango_fixup_bar);
diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h
index f020ab4079d3..b577dbe46f8f 100644
--- a/include/linux/pci_ids.h
+++ b/include/linux/pci_ids.h
@@ -1369,6 +1369,8 @@
 #define PCI_DEVICE_ID_TTI_HPT374	0x0008
 #define PCI_DEVICE_ID_TTI_HPT372N	0x0009	/* apparently a 372N variant? */
 
+#define PCI_VENDOR_ID_SIGMA		0x1105
+
 #define PCI_VENDOR_ID_VIA		0x1106
 #define PCI_DEVICE_ID_VIA_8763_0	0x0198
 #define PCI_DEVICE_ID_VIA_8380_0	0x0204
-- 
2.11.0

WARNING: multiple messages have this Message-ID (diff)
From: Marc Gonzalez <marc_gonzalez@sigmadesigns.com>
To: Bjorn Helgaas <helgaas@kernel.org>,
	Marc Zyngier <marc.zyngier@arm.com>,
	Thomas Gleixner <tglx@linutronix.de>
Cc: linux-pci <linux-pci@vger.kernel.org>,
	Linux ARM <linux-arm-kernel@lists.infradead.org>,
	LKML <linux-kernel@vger.kernel.org>, Mason <slash.tmp@free.fr>,
	Thibaud Cornic <thibaud_cornic@sigmadesigns.com>
Subject: [PATCH v9 2/3] PCI: Add tango PCIe host bridge support
Date: Tue, 20 Jun 2017 10:17:40 +0200	[thread overview]
Message-ID: <b32f9e1c-fdde-3064-f935-c817cf707534@sigmadesigns.com> (raw)
In-Reply-To: <987fac41-80dc-f1d0-ec0b-91ae57b91bfd@sigmadesigns.com>

This driver is required to work around several hardware bugs
in the PCIe controller.

NB: Revision 1 does not support legacy interrupts, or IO space.

Signed-off-by: Marc Gonzalez <marc_gonzalez@sigmadesigns.com>
---
 drivers/pci/host/Kconfig      |   8 +++
 drivers/pci/host/Makefile     |   1 +
 drivers/pci/host/pcie-tango.c | 164 ++++++++++++++++++++++++++++++++++++++=
++++
 include/linux/pci_ids.h       |   2 +
 4 files changed, 175 insertions(+)
 create mode 100644 drivers/pci/host/pcie-tango.c

diff --git a/drivers/pci/host/Kconfig b/drivers/pci/host/Kconfig
index d7e7c0a827c3..5183d9095c3a 100644
--- a/drivers/pci/host/Kconfig
+++ b/drivers/pci/host/Kconfig
@@ -285,6 +285,14 @@ config PCIE_ROCKCHIP
 =09  There is 1 internal PCIe port available to support GEN2 with
 =09  4 slots.
=20
+config PCIE_TANGO
+=09bool "Tango PCIe controller"
+=09depends on ARCH_TANGO && PCI_MSI && OF
+=09select PCI_HOST_COMMON
+=09help
+=09  Say Y here to enable PCIe controller support for Sigma Designs
+=09  Tango systems, such as SMP8759 and later chips.
+
 config VMD
 =09depends on PCI_MSI && X86_64
 =09tristate "Intel Volume Management Device Driver"
diff --git a/drivers/pci/host/Makefile b/drivers/pci/host/Makefile
index 084cb4983645..fc7ea90196f3 100644
--- a/drivers/pci/host/Makefile
+++ b/drivers/pci/host/Makefile
@@ -32,4 +32,5 @@ obj-$(CONFIG_PCI_HOST_THUNDER_PEM) +=3D pci-thunder-pem.o
 obj-$(CONFIG_PCIE_ARMADA_8K) +=3D pcie-armada8k.o
 obj-$(CONFIG_PCIE_ARTPEC6) +=3D pcie-artpec6.o
 obj-$(CONFIG_PCIE_ROCKCHIP) +=3D pcie-rockchip.o
+obj-$(CONFIG_PCIE_TANGO) +=3D pcie-tango.o
 obj-$(CONFIG_VMD) +=3D vmd.o
diff --git a/drivers/pci/host/pcie-tango.c b/drivers/pci/host/pcie-tango.c
new file mode 100644
index 000000000000..67aaadcc1c5e
--- /dev/null
+++ b/drivers/pci/host/pcie-tango.c
@@ -0,0 +1,164 @@
+#include <linux/pci-ecam.h>
+#include <linux/delay.h>
+#include <linux/of.h>
+
+#define MSI_MAX 256
+
+#define SMP8759_MUX=09=090x48
+#define SMP8759_TEST_OUT=090x74
+
+struct tango_pcie {
+=09void __iomem *mux;
+};
+
+/*** HOST BRIDGE SUPPORT ***/
+
+static int smp8759_config_read(struct pci_bus *bus,
+=09=09unsigned int devfn, int where, int size, u32 *val)
+{
+=09int ret;
+=09struct pci_config_window *cfg =3D bus->sysdata;
+=09struct tango_pcie *pcie =3D dev_get_drvdata(cfg->parent);
+
+=09/*
+=09 * QUIRK #1
+=09 * Reads in configuration space outside devfn 0 return garbage.
+=09 */
+=09if (devfn !=3D 0)
+=09=09return PCIBIOS_FUNC_NOT_SUPPORTED;
+
+=09/*
+=09 * QUIRK #2
+=09 * Unfortunately, config and mem spaces are muxed.
+=09 * Linux does not support such a setting, since drivers are free
+=09 * to access mem space directly, at any time.
+=09 * Therefore, we can only PRAY that config and mem space accesses
+=09 * NEVER occur concurrently.
+=09 */
+=09writel_relaxed(1, pcie->mux);
+=09ret =3D pci_generic_config_read(bus, devfn, where, size, val);
+=09writel_relaxed(0, pcie->mux);
+
+=09return ret;
+}
+
+static int smp8759_config_write(struct pci_bus *bus,
+=09=09unsigned int devfn, int where, int size, u32 val)
+{
+=09int ret;
+=09struct pci_config_window *cfg =3D bus->sysdata;
+=09struct tango_pcie *pcie =3D dev_get_drvdata(cfg->parent);
+
+=09writel_relaxed(1, pcie->mux);
+=09ret =3D pci_generic_config_write(bus, devfn, where, size, val);
+=09writel_relaxed(0, pcie->mux);
+
+=09return ret;
+}
+
+static struct pci_ecam_ops smp8759_ecam_ops =3D {
+=09.bus_shift=09=3D 20,
+=09.pci_ops=09=3D {
+=09=09.map_bus=09=3D pci_ecam_map_bus,
+=09=09.read=09=09=3D smp8759_config_read,
+=09=09.write=09=09=3D smp8759_config_write,
+=09}
+};
+
+static const struct of_device_id tango_pcie_ids[] =3D {
+=09{ .compatible =3D "sigma,smp8759-pcie" },
+=09{ /* sentinel */ },
+};
+
+static int tango_check_pcie_link(void __iomem *test_out)
+{
+=09int i;
+
+=09writel_relaxed(16, test_out);
+=09for (i =3D 0; i < 10; ++i) {
+=09=09u32 ltssm_state =3D readl_relaxed(test_out) >> 8;
+=09=09if ((ltssm_state & 0x1f) =3D=3D 0xf) /* L0 */
+=09=09=09return 0;
+=09=09usleep_range(3000, 4000);
+=09}
+
+=09return -ENODEV;
+}
+
+static int smp8759_init(struct tango_pcie *pcie, void __iomem *base)
+{
+=09pcie->mux=09=09=3D base + SMP8759_MUX;
+
+=09return tango_check_pcie_link(base + SMP8759_TEST_OUT);
+}
+
+static int tango_pcie_probe(struct platform_device *pdev)
+{
+=09int ret =3D -EINVAL;
+=09void __iomem *base;
+=09struct resource *res;
+=09struct tango_pcie *pcie;
+=09struct device *dev =3D &pdev->dev;
+
+=09pr_err("MAJOR ISSUE: PCIe config and mem spaces are muxed\n");
+=09pr_err("Tainting kernel... Use driver at your own risk\n");
+=09add_taint(TAINT_FIRMWARE_WORKAROUND, LOCKDEP_STILL_OK);
+
+=09pcie =3D devm_kzalloc(dev, sizeof(*pcie), GFP_KERNEL);
+=09if (!pcie)
+=09=09return -ENOMEM;
+
+=09platform_set_drvdata(pdev, pcie);
+
+=09res =3D platform_get_resource(pdev, IORESOURCE_MEM, 1);
+=09base =3D devm_ioremap_resource(&pdev->dev, res);
+=09if (IS_ERR(base))
+=09=09return PTR_ERR(base);
+
+=09if (of_device_is_compatible(dev->of_node, "sigma,smp8759-pcie"))
+=09=09ret =3D smp8759_init(pcie, base);
+
+=09if (ret)
+=09=09return ret;
+
+=09return pci_host_common_probe(pdev, &smp8759_ecam_ops);
+}
+
+static struct platform_driver tango_pcie_driver =3D {
+=09.probe=09=3D tango_pcie_probe,
+=09.driver=09=3D {
+=09=09.name =3D KBUILD_MODNAME,
+=09=09.of_match_table =3D tango_pcie_ids,
+=09},
+};
+
+builtin_platform_driver(tango_pcie_driver);
+
+/*
+ * QUIRK #3
+ * The root complex advertizes the wrong device class.
+ * Header Type 1 is for PCI-to-PCI bridges.
+ */
+static void tango_fixup_class(struct pci_dev *dev)
+{
+=09dev->class =3D PCI_CLASS_BRIDGE_PCI << 8;
+}
+DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_SIGMA, 0x24, tango_fixup_class);
+DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_SIGMA, 0x28, tango_fixup_class);
+
+/*
+ * QUIRK #4
+ * The root complex exposes a "fake" BAR, which is used to filter
+ * bus-to-system accesses. Only accesses within the range defined
+ * by this BAR are forwarded to the host, others are ignored.
+ *
+ * By default, the DMA framework expects an identity mapping,
+ * and DRAM0 is mapped at 0x80000000.
+ */
+static void tango_fixup_bar(struct pci_dev *dev)
+{
+=09dev->non_compliant_bars =3D true;
+=09pci_write_config_dword(dev, PCI_BASE_ADDRESS_0, 0x80000000);
+}
+DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_SIGMA, 0x24, tango_fixup_bar);
+DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_SIGMA, 0x28, tango_fixup_bar);
diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h
index f020ab4079d3..b577dbe46f8f 100644
--- a/include/linux/pci_ids.h
+++ b/include/linux/pci_ids.h
@@ -1369,6 +1369,8 @@
 #define PCI_DEVICE_ID_TTI_HPT374=090x0008
 #define PCI_DEVICE_ID_TTI_HPT372N=090x0009=09/* apparently a 372N variant?=
 */
=20
+#define PCI_VENDOR_ID_SIGMA=09=090x1105
+
 #define PCI_VENDOR_ID_VIA=09=090x1106
 #define PCI_DEVICE_ID_VIA_8763_0=090x0198
 #define PCI_DEVICE_ID_VIA_8380_0=090x0204
--=20
2.11.0

WARNING: multiple messages have this Message-ID (diff)
From: marc_gonzalez@sigmadesigns.com (Marc Gonzalez)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH v9 2/3] PCI: Add tango PCIe host bridge support
Date: Tue, 20 Jun 2017 10:17:40 +0200	[thread overview]
Message-ID: <b32f9e1c-fdde-3064-f935-c817cf707534@sigmadesigns.com> (raw)
In-Reply-To: <987fac41-80dc-f1d0-ec0b-91ae57b91bfd@sigmadesigns.com>

This driver is required to work around several hardware bugs
in the PCIe controller.

NB: Revision 1 does not support legacy interrupts, or IO space.

Signed-off-by: Marc Gonzalez <marc_gonzalez@sigmadesigns.com>
---
 drivers/pci/host/Kconfig      |   8 +++
 drivers/pci/host/Makefile     |   1 +
 drivers/pci/host/pcie-tango.c | 164 ++++++++++++++++++++++++++++++++++++++++++
 include/linux/pci_ids.h       |   2 +
 4 files changed, 175 insertions(+)
 create mode 100644 drivers/pci/host/pcie-tango.c

diff --git a/drivers/pci/host/Kconfig b/drivers/pci/host/Kconfig
index d7e7c0a827c3..5183d9095c3a 100644
--- a/drivers/pci/host/Kconfig
+++ b/drivers/pci/host/Kconfig
@@ -285,6 +285,14 @@ config PCIE_ROCKCHIP
 	  There is 1 internal PCIe port available to support GEN2 with
 	  4 slots.
 
+config PCIE_TANGO
+	bool "Tango PCIe controller"
+	depends on ARCH_TANGO && PCI_MSI && OF
+	select PCI_HOST_COMMON
+	help
+	  Say Y here to enable PCIe controller support for Sigma Designs
+	  Tango systems, such as SMP8759 and later chips.
+
 config VMD
 	depends on PCI_MSI && X86_64
 	tristate "Intel Volume Management Device Driver"
diff --git a/drivers/pci/host/Makefile b/drivers/pci/host/Makefile
index 084cb4983645..fc7ea90196f3 100644
--- a/drivers/pci/host/Makefile
+++ b/drivers/pci/host/Makefile
@@ -32,4 +32,5 @@ obj-$(CONFIG_PCI_HOST_THUNDER_PEM) += pci-thunder-pem.o
 obj-$(CONFIG_PCIE_ARMADA_8K) += pcie-armada8k.o
 obj-$(CONFIG_PCIE_ARTPEC6) += pcie-artpec6.o
 obj-$(CONFIG_PCIE_ROCKCHIP) += pcie-rockchip.o
+obj-$(CONFIG_PCIE_TANGO) += pcie-tango.o
 obj-$(CONFIG_VMD) += vmd.o
diff --git a/drivers/pci/host/pcie-tango.c b/drivers/pci/host/pcie-tango.c
new file mode 100644
index 000000000000..67aaadcc1c5e
--- /dev/null
+++ b/drivers/pci/host/pcie-tango.c
@@ -0,0 +1,164 @@
+#include <linux/pci-ecam.h>
+#include <linux/delay.h>
+#include <linux/of.h>
+
+#define MSI_MAX 256
+
+#define SMP8759_MUX		0x48
+#define SMP8759_TEST_OUT	0x74
+
+struct tango_pcie {
+	void __iomem *mux;
+};
+
+/*** HOST BRIDGE SUPPORT ***/
+
+static int smp8759_config_read(struct pci_bus *bus,
+		unsigned int devfn, int where, int size, u32 *val)
+{
+	int ret;
+	struct pci_config_window *cfg = bus->sysdata;
+	struct tango_pcie *pcie = dev_get_drvdata(cfg->parent);
+
+	/*
+	 * QUIRK #1
+	 * Reads in configuration space outside devfn 0 return garbage.
+	 */
+	if (devfn != 0)
+		return PCIBIOS_FUNC_NOT_SUPPORTED;
+
+	/*
+	 * QUIRK #2
+	 * Unfortunately, config and mem spaces are muxed.
+	 * Linux does not support such a setting, since drivers are free
+	 * to access mem space directly, at any time.
+	 * Therefore, we can only PRAY that config and mem space accesses
+	 * NEVER occur concurrently.
+	 */
+	writel_relaxed(1, pcie->mux);
+	ret = pci_generic_config_read(bus, devfn, where, size, val);
+	writel_relaxed(0, pcie->mux);
+
+	return ret;
+}
+
+static int smp8759_config_write(struct pci_bus *bus,
+		unsigned int devfn, int where, int size, u32 val)
+{
+	int ret;
+	struct pci_config_window *cfg = bus->sysdata;
+	struct tango_pcie *pcie = dev_get_drvdata(cfg->parent);
+
+	writel_relaxed(1, pcie->mux);
+	ret = pci_generic_config_write(bus, devfn, where, size, val);
+	writel_relaxed(0, pcie->mux);
+
+	return ret;
+}
+
+static struct pci_ecam_ops smp8759_ecam_ops = {
+	.bus_shift	= 20,
+	.pci_ops	= {
+		.map_bus	= pci_ecam_map_bus,
+		.read		= smp8759_config_read,
+		.write		= smp8759_config_write,
+	}
+};
+
+static const struct of_device_id tango_pcie_ids[] = {
+	{ .compatible = "sigma,smp8759-pcie" },
+	{ /* sentinel */ },
+};
+
+static int tango_check_pcie_link(void __iomem *test_out)
+{
+	int i;
+
+	writel_relaxed(16, test_out);
+	for (i = 0; i < 10; ++i) {
+		u32 ltssm_state = readl_relaxed(test_out) >> 8;
+		if ((ltssm_state & 0x1f) == 0xf) /* L0 */
+			return 0;
+		usleep_range(3000, 4000);
+	}
+
+	return -ENODEV;
+}
+
+static int smp8759_init(struct tango_pcie *pcie, void __iomem *base)
+{
+	pcie->mux		= base + SMP8759_MUX;
+
+	return tango_check_pcie_link(base + SMP8759_TEST_OUT);
+}
+
+static int tango_pcie_probe(struct platform_device *pdev)
+{
+	int ret = -EINVAL;
+	void __iomem *base;
+	struct resource *res;
+	struct tango_pcie *pcie;
+	struct device *dev = &pdev->dev;
+
+	pr_err("MAJOR ISSUE: PCIe config and mem spaces are muxed\n");
+	pr_err("Tainting kernel... Use driver at your own risk\n");
+	add_taint(TAINT_FIRMWARE_WORKAROUND, LOCKDEP_STILL_OK);
+
+	pcie = devm_kzalloc(dev, sizeof(*pcie), GFP_KERNEL);
+	if (!pcie)
+		return -ENOMEM;
+
+	platform_set_drvdata(pdev, pcie);
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+	base = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(base))
+		return PTR_ERR(base);
+
+	if (of_device_is_compatible(dev->of_node, "sigma,smp8759-pcie"))
+		ret = smp8759_init(pcie, base);
+
+	if (ret)
+		return ret;
+
+	return pci_host_common_probe(pdev, &smp8759_ecam_ops);
+}
+
+static struct platform_driver tango_pcie_driver = {
+	.probe	= tango_pcie_probe,
+	.driver	= {
+		.name = KBUILD_MODNAME,
+		.of_match_table = tango_pcie_ids,
+	},
+};
+
+builtin_platform_driver(tango_pcie_driver);
+
+/*
+ * QUIRK #3
+ * The root complex advertizes the wrong device class.
+ * Header Type 1 is for PCI-to-PCI bridges.
+ */
+static void tango_fixup_class(struct pci_dev *dev)
+{
+	dev->class = PCI_CLASS_BRIDGE_PCI << 8;
+}
+DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_SIGMA, 0x24, tango_fixup_class);
+DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_SIGMA, 0x28, tango_fixup_class);
+
+/*
+ * QUIRK #4
+ * The root complex exposes a "fake" BAR, which is used to filter
+ * bus-to-system accesses. Only accesses within the range defined
+ * by this BAR are forwarded to the host, others are ignored.
+ *
+ * By default, the DMA framework expects an identity mapping,
+ * and DRAM0 is mapped@0x80000000.
+ */
+static void tango_fixup_bar(struct pci_dev *dev)
+{
+	dev->non_compliant_bars = true;
+	pci_write_config_dword(dev, PCI_BASE_ADDRESS_0, 0x80000000);
+}
+DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_SIGMA, 0x24, tango_fixup_bar);
+DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_SIGMA, 0x28, tango_fixup_bar);
diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h
index f020ab4079d3..b577dbe46f8f 100644
--- a/include/linux/pci_ids.h
+++ b/include/linux/pci_ids.h
@@ -1369,6 +1369,8 @@
 #define PCI_DEVICE_ID_TTI_HPT374	0x0008
 #define PCI_DEVICE_ID_TTI_HPT372N	0x0009	/* apparently a 372N variant? */
 
+#define PCI_VENDOR_ID_SIGMA		0x1105
+
 #define PCI_VENDOR_ID_VIA		0x1106
 #define PCI_DEVICE_ID_VIA_8763_0	0x0198
 #define PCI_DEVICE_ID_VIA_8380_0	0x0204
-- 
2.11.0

  parent reply	other threads:[~2017-06-20  8:21 UTC|newest]

Thread overview: 109+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-06-20  8:12 [PATCH v9 0/3] Tango PCIe controller support Marc Gonzalez
2017-06-20  8:12 ` Marc Gonzalez
2017-06-20  8:12 ` Marc Gonzalez
2017-06-20  8:14 ` [PATCH v9 1/3] PCI: Add DT binding for tango PCIe controller Marc Gonzalez
2017-06-20  8:14   ` Marc Gonzalez
2017-06-20  8:14   ` Marc Gonzalez
2017-06-20  8:17 ` Marc Gonzalez [this message]
2017-06-20  8:17   ` [PATCH v9 2/3] PCI: Add tango PCIe host bridge support Marc Gonzalez
2017-06-20  8:17   ` Marc Gonzalez
2017-07-02 23:18   ` Bjorn Helgaas
2017-07-02 23:18     ` Bjorn Helgaas
2017-07-02 23:18     ` Bjorn Helgaas
2017-07-03  9:35     ` Ard Biesheuvel
2017-07-03  9:35       ` Ard Biesheuvel
2017-07-03 13:27       ` Bjorn Helgaas
2017-07-03 13:27         ` Bjorn Helgaas
2017-07-03 13:27         ` Bjorn Helgaas
2017-07-04  6:58         ` Jisheng Zhang
2017-07-04  6:58           ` Jisheng Zhang
2017-07-04  6:58           ` Jisheng Zhang
2017-07-04  7:16           ` Jisheng Zhang
2017-07-04  7:16             ` Jisheng Zhang
2017-07-04  8:02           ` Ard Biesheuvel
2017-07-04  8:02             ` Ard Biesheuvel
2017-07-04  8:19             ` Jisheng Zhang
2017-07-04  8:19               ` Jisheng Zhang
2017-07-04  8:19               ` Jisheng Zhang
2017-07-04  9:38               ` Ard Biesheuvel
2017-07-04  9:38                 ` Ard Biesheuvel
2017-07-05 13:53                 ` Joao Pinto
2017-07-05 13:53                   ` Joao Pinto
2017-07-03  9:54     ` Marc Gonzalez
2017-07-03  9:54       ` Marc Gonzalez
2017-07-03  9:54       ` Marc Gonzalez
2017-07-03 13:13       ` Marc Gonzalez
2017-07-03 13:13         ` Marc Gonzalez
2017-07-03 15:30         ` Marc Gonzalez
2017-07-03 15:30           ` Marc Gonzalez
2017-07-03 15:30           ` Marc Gonzalez
2017-07-04  7:09           ` Peter Zijlstra
2017-07-04  7:09             ` Peter Zijlstra
2017-07-04 13:08             ` Mason
2017-07-04 13:08               ` Mason
2017-07-04 14:27               ` Peter Zijlstra
2017-07-04 14:27                 ` Peter Zijlstra
2017-07-04 15:18                 ` Mason
2017-07-04 15:18                   ` Mason
2017-07-03 13:40       ` Bjorn Helgaas
2017-07-03 13:40         ` Bjorn Helgaas
2017-07-03 13:40         ` Bjorn Helgaas
2017-07-03 14:34         ` Marc Gonzalez
2017-07-03 14:34           ` Marc Gonzalez
2017-07-03 14:34           ` Marc Gonzalez
2017-07-04 15:58           ` Bjorn Helgaas
2017-07-04 15:58             ` Bjorn Helgaas
2017-07-04 15:58             ` Bjorn Helgaas
2017-07-04 23:42             ` Mason
2017-07-04 23:42               ` Mason
2017-07-03 18:11         ` Russell King - ARM Linux
2017-07-03 18:11           ` Russell King - ARM Linux
2017-07-03 18:44           ` Ard Biesheuvel
2017-07-03 18:44             ` Ard Biesheuvel
2017-07-04 15:15           ` Bjorn Helgaas
2017-07-04 15:15             ` Bjorn Helgaas
2017-07-04 15:15             ` Bjorn Helgaas
2017-07-04 18:17             ` Russell King - ARM Linux
2017-07-04 18:17               ` Russell King - ARM Linux
2017-07-04 23:59           ` Mason
2017-07-04 23:59             ` Mason
2017-07-05  5:21             ` Greg Kroah-Hartman
2017-07-05  5:21               ` Greg Kroah-Hartman
2017-07-05 12:33             ` Mark Brown
2017-07-05 12:33               ` Mark Brown
2017-06-20  8:18 ` [PATCH v9 3/3] PCI: Add tango MSI controller support Marc Gonzalez
2017-06-20  8:18   ` Marc Gonzalez
2017-06-20  8:18   ` Marc Gonzalez
2017-07-04 20:24 ` [PATCH v9 0/3] Tango PCIe " Bjorn Helgaas
2017-07-04 20:24   ` Bjorn Helgaas
2017-07-04 20:24   ` Bjorn Helgaas
2017-07-04 22:55   ` Mason
2017-07-04 22:55     ` Mason
2017-07-04 22:55     ` Mason
2017-07-05 18:03     ` Bjorn Helgaas
2017-07-05 18:03       ` Bjorn Helgaas
2017-07-05 18:03       ` Bjorn Helgaas
2017-07-05 20:39       ` Mason
2017-07-05 20:39         ` Mason
2017-07-05 20:39         ` Mason
2017-07-05 21:34         ` Bjorn Helgaas
2017-07-05 21:34           ` Bjorn Helgaas
2017-07-05 21:34           ` Bjorn Helgaas
2017-07-05 21:34           ` Bjorn Helgaas
2017-07-05 21:59           ` Mason
2017-07-05 21:59             ` Mason
2017-07-05 21:59             ` Mason
2017-07-06  3:39             ` Bjorn Helgaas
2017-07-06  3:39               ` Bjorn Helgaas
2017-07-06  3:39               ` Bjorn Helgaas
2017-07-06  3:39               ` Bjorn Helgaas
2017-07-06 12:26               ` Mason
2017-07-06 12:26                 ` Mason
2017-07-06 12:40                 ` Marc Zyngier
2017-07-06 12:40                   ` Marc Zyngier
2017-07-06 12:40                   ` Marc Zyngier
2017-07-06 19:46                 ` Bjorn Helgaas
2017-07-06 19:46                   ` Bjorn Helgaas
2017-07-06 19:46                   ` Bjorn Helgaas
2017-07-07  9:55                   ` Marc Gonzalez
2017-07-07  9:55                     ` Marc Gonzalez

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=b32f9e1c-fdde-3064-f935-c817cf707534@sigmadesigns.com \
    --to=marc_gonzalez@sigmadesigns.com \
    --cc=helgaas@kernel.org \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-pci@vger.kernel.org \
    --cc=marc.zyngier@arm.com \
    --cc=slash.tmp@free.fr \
    --cc=tglx@linutronix.de \
    --cc=thibaud_cornic@sigmadesigns.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.