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.patch262
1 files changed, 0 insertions, 262 deletions
diff --git a/arm64-socionext-96b-enablement.patch b/arm64-socionext-96b-enablement.patch
index 0a7df3a19..fa93f0c8e 100644
--- a/arm64-socionext-96b-enablement.patch
+++ b/arm64-socionext-96b-enablement.patch
@@ -1,265 +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