summaryrefslogtreecommitdiffstats
path: root/arm64-socionext-96b-enablement.patch
diff options
context:
space:
mode:
Diffstat (limited to 'arm64-socionext-96b-enablement.patch')
-rw-r--r--arm64-socionext-96b-enablement.patch420
1 files changed, 0 insertions, 420 deletions
diff --git a/arm64-socionext-96b-enablement.patch b/arm64-socionext-96b-enablement.patch
index 0a7df3a19..d5d6cda86 100644
--- a/arm64-socionext-96b-enablement.patch
+++ b/arm64-socionext-96b-enablement.patch
@@ -1,423 +1,3 @@
-From 58be18a7bbf9dca67f4260ac172a44baa59d0ee9 Mon Sep 17 00:00:00 2001
-From: Ard Biesheuvel <ard.biesheuvel@linaro.org>
-Date: Mon, 21 Aug 2017 10:47:48 +0100
-Subject: arm64: acpi/gtdt: validate CNTFRQ after having enabled the frame
-
-The ACPI GTDT code validates the CNTFRQ field of each MMIO timer
-frame against the CNTFRQ system register of the current CPU, to
-ensure that they are equal, which is mandated by the architecture.
-
-However, reading the CNTFRQ field of a frame is not possible until
-the RFRQ bit in the frame's CNTACRn register is set, and doing so
-before that willl produce the following error:
-
- arch_timer: [Firmware Bug]: CNTFRQ mismatch: frame @ 0x00000000e0be0000: (0x00000000), CPU: (0x0ee6b280)
- arch_timer: Disabling MMIO timers due to CNTFRQ mismatch
- arch_timer: Failed to initialize memory-mapped timer.
-
-The reason is that the CNTFRQ field is RES0 if access is not enabled.
-
-So move the validation of CNTFRQ into the loop that iterates over the
-timers to find the best frame, but defer it until after we have selected
-the best frame, which should also have enabled the RFRQ bit.
-
-Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
----
- drivers/clocksource/arm_arch_timer.c | 38 ++++++++++++++++++++----------------
- 1 file changed, 21 insertions(+), 17 deletions(-)
-
-diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c
-index fd4b7f6..14e2419 100644
---- a/drivers/clocksource/arm_arch_timer.c
-+++ b/drivers/clocksource/arm_arch_timer.c
-@@ -1268,10 +1268,6 @@ arch_timer_mem_find_best_frame(struct arch_timer_mem *timer_mem)
-
- iounmap(cntctlbase);
-
-- if (!best_frame)
-- pr_err("Unable to find a suitable frame in timer @ %pa\n",
-- &timer_mem->cntctlbase);
--
- return best_frame;
- }
-
-@@ -1372,6 +1368,8 @@ static int __init arch_timer_mem_of_init(struct device_node *np)
-
- frame = arch_timer_mem_find_best_frame(timer_mem);
- if (!frame) {
-+ pr_err("Unable to find a suitable frame in timer @ %pa\n",
-+ &timer_mem->cntctlbase);
- ret = -EINVAL;
- goto out;
- }
-@@ -1420,7 +1418,7 @@ arch_timer_mem_verify_cntfrq(struct arch_timer_mem *timer_mem)
- static int __init arch_timer_mem_acpi_init(int platform_timer_count)
- {
- struct arch_timer_mem *timers, *timer;
-- struct arch_timer_mem_frame *frame;
-+ struct arch_timer_mem_frame *frame, *best_frame = NULL;
- int timer_count, i, ret = 0;
-
- timers = kcalloc(platform_timer_count, sizeof(*timers),
-@@ -1432,14 +1430,6 @@ static int __init arch_timer_mem_acpi_init(int platform_timer_count)
- if (ret || !timer_count)
- goto out;
-
-- for (i = 0; i < timer_count; i++) {
-- ret = arch_timer_mem_verify_cntfrq(&timers[i]);
-- if (ret) {
-- pr_err("Disabling MMIO timers due to CNTFRQ mismatch\n");
-- goto out;
-- }
-- }
--
- /*
- * While unlikely, it's theoretically possible that none of the frames
- * in a timer expose the combination of feature we want.
-@@ -1448,12 +1438,26 @@ static int __init arch_timer_mem_acpi_init(int platform_timer_count)
- timer = &timers[i];
-
- frame = arch_timer_mem_find_best_frame(timer);
-- if (frame)
-- break;
-+ if (!best_frame)
-+ best_frame = frame;
-+
-+ ret = arch_timer_mem_verify_cntfrq(timer);
-+ if (ret) {
-+ pr_err("Disabling MMIO timers due to CNTFRQ mismatch\n");
-+ goto out;
-+ }
-+
-+ if (!best_frame) /* implies !frame */
-+ /*
-+ * Only complain about missing suitable frames if we
-+ * haven't already found one in a previous iteration.
-+ */
-+ pr_err("Unable to find a suitable frame in timer @ %pa\n",
-+ &timer->cntctlbase);
- }
-
-- if (frame)
-- ret = arch_timer_mem_frame_register(frame);
-+ if (best_frame)
-+ ret = arch_timer_mem_frame_register(best_frame);
- out:
- kfree(timers);
- return ret;
---
-cgit v1.1
-
-From 33d983b5bb2929ae242606925e708092b1dfdd8f Mon Sep 17 00:00:00 2001
-From: Ard Biesheuvel <ard.biesheuvel@linaro.org>
-Date: Sat, 2 Sep 2017 11:01:22 +0100
-Subject: drivers/irqchip: gicv3: add workaround for Synquacer pre-ITS
-
-In their infinite wisdom, the Socionext engineers have decided
-that ITS device IDs should not be hardwired, but it should be
-left up to the software to assign them, by allowing it to
-redirect MSI doorbell writes via a separate hardware block
-that issues the doorbell write with a device ID that is
-derived from the memory address. This completely breaks any
-kind of isolation, or virtualization in general, for that
-matter, but add support for it nonetheless.
-
-Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
----
- arch/arm64/Kconfig | 8 +++++++
- drivers/irqchip/irq-gic-v3-its.c | 48 +++++++++++++++++++++++++++++++++++-----
- 2 files changed, 51 insertions(+), 5 deletions(-)
-
-diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
-index 0df64a6..c4361df 100644
---- a/arch/arm64/Kconfig
-+++ b/arch/arm64/Kconfig
-@@ -539,6 +539,14 @@ config QCOM_QDF2400_ERRATUM_0065
-
- If unsure, say Y.
-
-+config SOCIONEXT_SYNQUACER_PREITS
-+ bool "Socionext Synquacer: Workaround for GICv3 pre-ITS"
-+ default y
-+ help
-+ Socionext Synquacer SoCs implement a separate h/w block to generate
-+ MSI doorbell writes with non-zero values for the device ID.
-+
-+ If unsure, say Y.
- endmenu
-
-
-diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c
-index e8d8934..0d372f1 100644
---- a/drivers/irqchip/irq-gic-v3-its.c
-+++ b/drivers/irqchip/irq-gic-v3-its.c
-@@ -46,6 +46,7 @@
- #define ITS_FLAGS_CMDQ_NEEDS_FLUSHING (1ULL << 0)
- #define ITS_FLAGS_WORKAROUND_CAVIUM_22375 (1ULL << 1)
- #define ITS_FLAGS_WORKAROUND_CAVIUM_23144 (1ULL << 2)
-+#define ITS_FLAGS_WORKAROUND_SOCIONEXT_PREITS (1ULL << 3)
-
- #define RDIST_FLAGS_PROPBASE_NEEDS_FLUSHING (1 << 0)
-
-@@ -99,6 +100,10 @@ struct its_node {
- struct its_collection *collections;
- struct list_head its_device_list;
- u64 flags;
-+#ifdef CONFIG_SOCIONEXT_SYNQUACER_PREITS
-+ u64 pre_its_base;
-+ u64 pre_its_size;
-+#endif
- u32 ite_size;
- u32 device_ids;
- int numa_node;
-@@ -1102,13 +1107,29 @@ static void its_irq_compose_msi_msg(struct irq_data *d, struct msi_msg *msg)
- u64 addr;
-
- its = its_dev->its;
-- addr = its->phys_base + GITS_TRANSLATER;
-+
-+#ifdef CONFIG_SOCIONEXT_SYNQUACER_PREITS
-+ if (its->flags & ITS_FLAGS_WORKAROUND_SOCIONEXT_PREITS)
-+
-+ /*
-+ * The Socionext Synquacer SoC has a so-called 'pre-ITS',
-+ * which maps 32-bit writes into a separate window of size
-+ * '4 << device_id_bits' onto writes to GITS_TRANSLATER with
-+ * device ID taken from bits [device_id_bits + 1:2] of the
-+ * window offset.
-+ */
-+ addr = its->pre_its_base + (its_dev->device_id << 2);
-+ else
-+#endif
-+ addr = its->phys_base + GITS_TRANSLATER;
-
- msg->address_lo = lower_32_bits(addr);
- msg->address_hi = upper_32_bits(addr);
- msg->data = its_get_event_id(d);
-
-- iommu_dma_map_msi_msg(d->irq, msg);
-+ if (!IS_ENABLED(CONFIG_SOCIONEXT_SYNQUACER_PREITS) ||
-+ !(its->flags & ITS_FLAGS_WORKAROUND_SOCIONEXT_PREITS))
-+ iommu_dma_map_msi_msg(d->irq, msg);
- }
-
- static int its_irq_set_irqchip_state(struct irq_data *d,
-@@ -1666,6 +1687,11 @@ static int its_alloc_tables(struct its_node *its)
- ids = 0x14; /* 20 bits, 8MB */
- }
-
-+#ifdef CONFIG_SOCIONEXT_SYNQUACER_PREITS
-+ if (its->flags & ITS_FLAGS_WORKAROUND_SOCIONEXT_PREITS)
-+ ids = ilog2(its->pre_its_size) - 2;
-+#endif
-+
- its->device_ids = ids;
-
- for (i = 0; i < GITS_BASER_NR_REGS; i++) {
-@@ -2788,11 +2814,21 @@ static const struct gic_quirk its_quirks[] = {
- }
- };
-
--static void its_enable_quirks(struct its_node *its)
-+static void its_enable_quirks(struct its_node *its,
-+ struct fwnode_handle *handle)
- {
- u32 iidr = readl_relaxed(its->base + GITS_IIDR);
-
- gic_enable_quirks(iidr, its_quirks, its);
-+
-+#ifdef CONFIG_SOCIONEXT_SYNQUACER_PREITS
-+ if (!fwnode_property_read_u64_array(handle,
-+ "socionext,synquacer-pre-its",
-+ &its->pre_its_base, 2)) {
-+ its->flags |= ITS_FLAGS_WORKAROUND_SOCIONEXT_PREITS;
-+ pr_info("ITS: enabling workaround for Socionext Synquacer pre-ITS\n");
-+ }
-+#endif
- }
-
- static int its_init_domain(struct fwnode_handle *handle, struct its_node *its)
-@@ -2812,7 +2848,9 @@ static int its_init_domain(struct fwnode_handle *handle, struct its_node *its)
-
- inner_domain->parent = its_parent;
- irq_domain_update_bus_token(inner_domain, DOMAIN_BUS_NEXUS);
-- inner_domain->flags |= IRQ_DOMAIN_FLAG_MSI_REMAP;
-+
-+ if (!(its->flags & ITS_FLAGS_WORKAROUND_SOCIONEXT_PREITS))
-+ inner_domain->flags |= IRQ_DOMAIN_FLAG_MSI_REMAP;
- info->ops = &its_msi_domain_ops;
- info->data = its;
- inner_domain->host_data = info;
-@@ -2966,7 +3004,7 @@ static int __init its_probe_one(struct resource *res,
- }
- its->cmd_write = its->cmd_base;
-
-- its_enable_quirks(its);
-+ its_enable_quirks(its, handle);
-
- err = its_alloc_tables(its);
- if (err)
---
-cgit v1.1
-
-From 26e7bb47b0fb03a01be1e391a08c7375b45335a2 Mon Sep 17 00:00:00 2001
-From: Ard Biesheuvel <ard.biesheuvel@linaro.org>
-Date: Mon, 21 Aug 2017 20:29:05 +0100
-Subject: pci: designware: add driver for DWC controller in ECAM shift mode
-
-Some implementations of the Synopsys Designware PCIe controller implement
-a so-called ECAM shift mode, which allows a static memory window to be
-configured that covers the configuration space of the entire bus range.
-
-If the firmware performs all the low level configuration that is required
-to expose this controller in a fully ECAM compatible manner, we can
-simply describe it as "pci-host-ecam-generic" and be done with it.
-However, it appears that in some cases (one of which is the Armada 80x0),
-the IP is synthesized with an ATU window size that does not allow the
-first bus to be mapped in a way that prevents the device on the
-downstream port from appearing more than once.
-
-So implement a driver that relies on the firmware to perform all low
-level initialization, and drives the controller in ECAM mode, but
-overrides the config space accessors to take the above quirk into
-account.
-
-Note that, unlike most drivers for this IP, this driver does not expose
-a fake bridge device at B/D/F 00:00.0. There is no point in doing so,
-given that this is not a true bridge, and does not require any windows
-to be configured in order for the downstream device to operate correctly.
-Omitting it also prevents the PCI resource allocation routines from
-handing out BAR space to it unnecessarily.
-
-Cc: Bjorn Helgaas <bhelgaas@google.com>
-Cc: Jingoo Han <jingoohan1@gmail.com>
-Cc: Joao Pinto <Joao.Pinto@synopsys.com>
-Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
----
- drivers/pci/dwc/Kconfig | 11 +++++
- drivers/pci/dwc/Makefile | 1 +
- drivers/pci/dwc/pcie-designware-ecam.c | 77 ++++++++++++++++++++++++++++++++++
- 3 files changed, 89 insertions(+)
- create mode 100644 drivers/pci/dwc/pcie-designware-ecam.c
-
-diff --git a/drivers/pci/dwc/Kconfig b/drivers/pci/dwc/Kconfig
-index 22ec82f..19856b1 100644
---- a/drivers/pci/dwc/Kconfig
-+++ b/drivers/pci/dwc/Kconfig
-@@ -169,4 +169,15 @@ config PCIE_KIRIN
- Say Y here if you want PCIe controller support
- on HiSilicon Kirin series SoCs.
-
-+config PCIE_DW_HOST_ECAM
-+ bool "Synopsys DesignWare PCIe controller in ECAM mode"
-+ depends on OF && PCI
-+ select PCI_HOST_COMMON
-+ select IRQ_DOMAIN
-+ help
-+ Add support for Synopsys DesignWare PCIe controllers configured
-+ by the firmware into ECAM shift mode. In some cases, these are
-+ fully ECAM compliant, in which case the pci-host-generic driver
-+ may be used instead.
-+
- endmenu
-diff --git a/drivers/pci/dwc/Makefile b/drivers/pci/dwc/Makefile
-index c61be97..7d5a23e 100644
---- a/drivers/pci/dwc/Makefile
-+++ b/drivers/pci/dwc/Makefile
-@@ -1,5 +1,6 @@
- # SPDX-License-Identifier: GPL-2.0
- obj-$(CONFIG_PCIE_DW) += pcie-designware.o
- obj-$(CONFIG_PCIE_DW_HOST) += pcie-designware-host.o
-+obj-$(CONFIG_PCIE_DW_HOST_ECAM) += pcie-designware-ecam.o
- obj-$(CONFIG_PCIE_DW_EP) += pcie-designware-ep.o
- obj-$(CONFIG_PCIE_DW_PLAT) += pcie-designware-plat.o
- ifneq ($(filter y,$(CONFIG_PCI_DRA7XX_HOST) $(CONFIG_PCI_DRA7XX_EP)),)
-diff --git a/drivers/pci/dwc/pcie-designware-ecam.c b/drivers/pci/dwc/pcie-designware-ecam.c
-new file mode 100644
-index 0000000..ede627d
---- /dev/null
-+++ b/drivers/pci/dwc/pcie-designware-ecam.c
-@@ -0,0 +1,77 @@
-+/*
-+ * Driver for mostly ECAM compatible Synopsys dw PCIe controllers
-+ * configured by the firmware into RC mode
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation.
-+ *
-+ * Copyright (C) 2014 ARM Limited
-+ * Copyright (C) 2017 Linaro Limited
-+ *
-+ * Authors: Will Deacon <will.deacon@arm.com>
-+ * Ard Biesheuvel <ard.biesheuvel@linaro.org>
-+ */
-+
-+#include <linux/kernel.h>
-+#include <linux/init.h>
-+#include <linux/of_address.h>
-+#include <linux/of_pci.h>
-+#include <linux/pci-ecam.h>
-+#include <linux/platform_device.h>
-+
-+static int pci_dw_ecam_config_read(struct pci_bus *bus, u32 devfn, int where,
-+ int size, u32 *val)
-+{
-+ struct pci_config_window *cfg = bus->sysdata;
-+
-+ /*
-+ * The Synopsys dw PCIe controller in RC mode will not filter type 0
-+ * config TLPs sent to devices 1 and up on its downstream port,
-+ * resulting in devices appearing multiple times on bus 0 unless we
-+ * filter them here.
-+ */
-+ if (bus->number == cfg->busr.start && PCI_SLOT(devfn) > 0) {
-+ *val = 0xffffffff;
-+ return PCIBIOS_DEVICE_NOT_FOUND;
-+ }
-+ return pci_generic_config_read(bus, devfn, where, size, val);
-+}
-+
-+static int pci_dw_ecam_config_write(struct pci_bus *bus, u32 devfn, int where,
-+ int size, u32 val)
-+{
-+ struct pci_config_window *cfg = bus->sysdata;
-+
-+ if (bus->number == cfg->busr.start && PCI_SLOT(devfn) > 0)
-+ return PCIBIOS_DEVICE_NOT_FOUND;
-+
-+ return pci_generic_config_write(bus, devfn, where, size, val);
-+}
-+
-+static struct pci_ecam_ops pci_dw_ecam_bus_ops = {
-+ .pci_ops.map_bus = pci_ecam_map_bus,
-+ .pci_ops.read = pci_dw_ecam_config_read,
-+ .pci_ops.write = pci_dw_ecam_config_write,
-+ .bus_shift = 20,
-+};
-+
-+static const struct of_device_id pci_dw_ecam_of_match[] = {
-+ { .compatible = "marvell,armada8k-pcie-ecam" },
-+ { .compatible = "socionext,synquacer-pcie-ecam" },
-+ { .compatible = "snps,dw-pcie-ecam" },
-+ { },
-+};
-+
-+static int pci_dw_ecam_probe(struct platform_device *pdev)
-+{
-+ return pci_host_common_probe(pdev, &pci_dw_ecam_bus_ops);
-+}
-+
-+static struct platform_driver pci_dw_ecam_driver = {
-+ .driver.name = "pcie-designware-ecam",
-+ .driver.of_match_table = pci_dw_ecam_of_match,
-+ .driver.suppress_bind_attrs = true,
-+ .probe = pci_dw_ecam_probe,
-+};
-+builtin_platform_driver(pci_dw_ecam_driver);
---
-cgit v1.1
-
From e3dff048a10f16aa0fd32438442ce39558bbdbef Mon Sep 17 00:00:00 2001
From: Jassi Brar <jaswinder.singh@linaro.org>
Date: Tue, 29 Aug 2017 22:45:59 +0530