Skip to contentSkip to conversation

enable HiP04 SoC

PATCH Superseded Haojian Zhuang 5 participants 20 messages Jul 10, 2014 – Jul 28, 2014

Subsystems (10)

v10 of 17 Superseded Latest is v17 →

lore
Share & tools
lore
#0 lore raw

v10 cover enable HiP04 SoC

Changelog:
v10:
* Move snoop filter code to be executed on secondary cores. And change it to assembly code since MMU isn't enabled at that time.
* Rebase irq gic patch on latest gic patch.
* Use global variable in irq gic patch.
* Use global variable in vgic patch.
* Drop debug uart patch since it's in another patch set.
* Remove some ARCHs from multi_v7_lpae_defconfig.

v9:
* Remove delay workaround in mcpm implementation.
* Clean in gic.
* Rename vgic_cpu_nr_lr to vgic_cpu_hw_cfg in vgic driver.
* Always use high word of vgic_cpu_hw_cfg for GICH_APR offset. So the implementation of arm64 is also updated.
* Drop "irq: gic: use mask field in GICC_IAR" patch since it's merged.

v7:
* Remove hip04_smp_init_ops().
* Remove CONFIG_ARCH_HIP04 in hisilicn.c since hip04_smp_init_ops() is removed.

v6:
* Split HiP04 enabling patch into patches on document, mcpm & hiP04.
* Move reset operation in HiP04 MCPM implementation.
* Remove ARCH_MULTI_V7_NONLPAE & ARCH_MULTI_V7_LPAE according to olof's comment.

v5:
* Add ARCH_MULTI_V7_NONLPAE to avoid change too much things in Kconfig.
* Use memreserve in DTS.
* Remove L2 reset operation in mcpm implementation.
* Re-use nr_lr field to cover HIP04 GICH_APR implementation.
* Add more comments.

v4:
* Add multi_v7_lpae_defconfig.
* Select CONFIG_ARCH_MULTI_V7_LPAE if CONFIG_ARCH_MULTI_V7 is selected.
* Only ARMADA_XP is ARCH_MULTI_V7_LPAE, other ARMADA chips are ARCH_MULTI_V7.
* Remove gich_lr0 variable since we can calculate offset of GICH_LR0 from GICH_APR.
* Cleanup GIC driver to support HiP04 GIC.
* Cleanup HiP04 mcpm implementation.

v3:
* Replace CONFIG_ARCH_MULTI_V7 by CONFIG_ARCH_MULTI_V7_LPAE in some SoC.
* Update MCPM code based on Dave's patch.
* Remove MCPM node in DTS file. Use sysctrl & fabric node instead.
* Move hardcoding on bootwrapper into DTS file.
* Append the CONFIG_MCPM_QUAD_CLUSTER for HiP04.
* Fix the return value from gic_get_cpumask() if it's used in standard gic.
* Add the vgic support on HiP04 GIC.
* Add virtualization support in HiP04 defconfig.

v2:
* Append ARCH_MULTI_V7_LPAE configuration. Define ARCH_MULTI_V7 to only support non-LPAE platform.
* Append document of DT supporting.
* Append ARCH_HISI in hi3xxx_defconfig.
* Enable errata 798181 for HiP04 SoC.
* Add PMU support.

Haojian Zhuang (10):
irq: gic: support hip04 gic
ARM: mcpm: support 4 clusters
ARM: hisi: enable MCPM implementation
ARM: hisi: enable HiP04
document: dt: add the binding on HiP04
document: dt: add the binding on HiP04 clock
ARM: dts: append hip04 dts
ARM: config: append lpae configuration
ARM: config: append hip04_defconfig
virt: arm: support hip04 gic

Kefeng Wang (1):
ARM: hisi: enable erratum 798181 of A15 on HiP04

 Documentation/devicetree/bindings/arm/gic.txt      |   1 +
 .../bindings/arm/hisilicon/hisilicon.txt           |  21 ++
 .../devicetree/bindings/clock/hip04-clock.txt      |  20 ++
 arch/arm/Kconfig                                   |   9 +
 arch/arm/boot/dts/Makefile                         |   1 +
 arch/arm/boot/dts/hip04-d01.dts                    |  39 +++
 arch/arm/boot/dts/hip04.dtsi                       | 267 ++++++++++++++++
 arch/arm/configs/hip04_defconfig                   |  74 +++++
 arch/arm/configs/multi_v7_lpae_defconfig           | 343 +++++++++++++++++++++
 arch/arm/include/asm/mcpm.h                        |   5 +
 arch/arm/kernel/asm-offsets.c                      |   2 +-
 arch/arm/kvm/interrupts_head.S                     |  29 +-
 arch/arm/mach-hisi/Kconfig                         |   9 +
 arch/arm/mach-hisi/Makefile                        |   1 +
 arch/arm/mach-hisi/hisilicon.c                     |   9 +
 arch/arm/mach-hisi/platmcpm.c                      | 330 ++++++++++++++++++++
 arch/arm64/kernel/asm-offsets.c                    |   2 +-
 arch/arm64/kvm/hyp.S                               |   4 +-
 drivers/irqchip/irq-gic.c                          | 141 +++++++--
 include/kvm/arm_vgic.h                             |   7 +-
 include/linux/irqchip/arm-gic.h                    |   6 +
 virt/kvm/arm/vgic.c                                |  37 ++-
 22 files changed, 1300 insertions(+), 57 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/clock/hip04-clock.txt
 create mode 100644 arch/arm/boot/dts/hip04-d01.dts
 create mode 100644 arch/arm/boot/dts/hip04.dtsi
 create mode 100644 arch/arm/configs/hip04_defconfig
 create mode 100644 arch/arm/configs/multi_v7_lpae_defconfig
 create mode 100644 arch/arm/mach-hisi/platmcpm.c
Signature · 1 line
1.9.1
#1 lore raw

PATCH v10 1/11 irq: gic: support hip04 gic

There's a little difference between ARM GIC and HiP04 GIC.

* HiP04 GIC could support 16 cores at most, and ARM GIC could support 8 cores at most. So the difination on GIC_DIST_TARGET registers are different since CPU interfaces are increased from 8-bit to 16-bit.

* HiP04 GIC could support 510 interrupts at most, and ARM GIC could support 1020 interrupts at most.

---
 Documentation/devicetree/bindings/arm/gic.txt |   1 +
 drivers/irqchip/irq-gic.c                     | 141 +++++++++++++++++++-------
 2 files changed, 108 insertions(+), 34 deletions(-)
Documentation/devicetree/bindings/arm/gic.txt +1 -0
index 5573c08..150f7d6 100644
@@ -16,6 +16,7 @@ Main node required properties:
 	"arm,cortex-a9-gic"
 	"arm,cortex-a7-gic"
 	"arm,arm11mp-gic"
+	"hisilicon,hip04-gic"
 - interrupt-controller : Identifies the node as an interrupt controller
 - #interrupt-cells : Specifies the number of cells needed to encode an
   interrupt source.  The type shall be a <u32> and the value shall be 3.
drivers/irqchip/irq-gic.c +107 -34

284 lines not on this page · raw message

Signature · 1 line
1.9.1
reviewer
#2 lore raw

PATCH v10 1/11 irq: gic: support hip04 gic

Quoted 1 line · Haojian Zhuang

There's a little difference between ARM GIC and HiP04 GIC.

Given that we can't target interrupts correctly without this patch, and that the GIC in a HiP04 system can't claim compatibility with any other GIC, I'd call this a major difference.

Quoted 13 lines

* HiP04 GIC could support 16 cores at most, and ARM GIC could support 8 cores at most. So the difination on GIC_DIST_TARGET registers are different since CPU interfaces are increased from 8-bit to 16-bit.

* HiP04 GIC could support 510 interrupts at most, and ARM GIC could support 1020 interrupts at most.

---
 Documentation/devicetree/bindings/arm/gic.txt |   1 +
 drivers/irqchip/irq-gic.c                     | 141 +++++++++++++++++++-------
 2 files changed, 108 insertions(+), 34 deletions(-)

[...]

Quoted 4 lines
drivers/irqchip/irq-gic.c +4 -0
+static bool gic_is_standard(struct gic_chip_data *gic_data)
+{
+       return (gic_data->nr_cpu_if == 8);
+}

drivers/irqchip/irq-gic.c static int gic_retrigger(struct irq_data *d) · line 239

Quoted 10 lines
drivers/irqchip/irq-gic.c +10 -0
+
+static u32 irqs_per_target_reg(struct gic_chip_data *gic_data)
+{
+       return (32 / gic_data->nr_cpu_if);
+}
+
+static u32 irq_to_target_reg(struct gic_chip_data *gic_data, u32 irq)
+{
+       if (!gic_is_standard(gic_data))
+               irq *= 2;

If the function is called gic_is_standard, then the only thing we should know here is whether the GIC follows the GIC standard, not how it differs from the standard.

Please rename this function to something like gicd_has_16_bit_targets or anything else that clearly defines what you're ttrying to derive from it.

Thanks,
Mark.

#3 lore raw

PATCH v10 1/11 irq: gic: support hip04 gic

In reply to Haojian Zhuang

Haojian,

Quoted 6 lines · Haojian Zhuang

There's a little difference between ARM GIC and HiP04 GIC.

* HiP04 GIC could support 16 cores at most, and ARM GIC could support 8 cores at most. So the difination on GIC_DIST_TARGET registers are different since CPU interfaces are increased from 8-bit to 16-bit.

Quoted 8 lines

* HiP04 GIC could support 510 interrupts at most, and ARM GIC could support 1020 interrupts at most.

---
 Documentation/devicetree/bindings/arm/gic.txt |   1 +
 drivers/irqchip/irq-gic.c                     | 141 +++++++++++++++++++-------
 2 files changed, 108 insertions(+), 34 deletions(-)

I need to apologize. This is my first full cycle maintaining irqchip and I'm still coming up to speed. The tl;dr is, I'm just not comfortable with the approach in this patch.

If irq-gic.c was only used by one SoC, it'd be different, but in the scenario we have, I think it would be best if this were a separate driver, say irq-gic-hip04.c. You can link in irq-gic-common.o to get gic_dist_config(), and you'll be able to remove a lot of the static functions and conditionals.

I really think it's worth the extra maintenance overhead to do it this way.

thx,

Jason.

reviewer
#4 lore raw

PATCH v10 1/11 irq: gic: support hip04 gic

Quoted 22 lines · Jason Cooper

Haojian,

Quoted 6 lines · Haojian Zhuang

There's a little difference between ARM GIC and HiP04 GIC.

* HiP04 GIC could support 16 cores at most, and ARM GIC could support 8 cores at most. So the difination on GIC_DIST_TARGET registers are different since CPU interfaces are increased from 8-bit to 16-bit.

Quoted 8 lines

* HiP04 GIC could support 510 interrupts at most, and ARM GIC could support 1020 interrupts at most.

---
 Documentation/devicetree/bindings/arm/gic.txt |   1 +
 drivers/irqchip/irq-gic.c                     | 141 +++++++++++++++++++-------
 2 files changed, 108 insertions(+), 34 deletions(-)

I need to apologize. This is my first full cycle maintaining irqchip and I'm still coming up to speed. The tl;dr is, I'm just not comfortable with the approach in this patch.

Quoted 5 lines

If irq-gic.c was only used by one SoC, it'd be different, but in the scenario we have, I think it would be best if this were a separate driver, say irq-gic-hip04.c. You can link in irq-gic-common.o to get gic_dist_config(), and you'll be able to remove a lot of the static functions and conditionals.

A better approach might be to have some function pointers with each compatible string, and then have associated with the HiP04 compatible string, and then have those call common (inline) function variants. The compiler can then deal with the different variants and we don't end up with multiple GIC drivers getting out-of-sync.

Thanks,
Mark.

#5 lore raw

PATCH v10 2/11 ARM: mcpm: support 4 clusters

In reply to Haojian Zhuang

Add the CONFIG_MCPM_QUAD_CLUSTER configuration to enlarge cluster number from 2 to 4.

---
 arch/arm/Kconfig            | 9 +++++++++
 arch/arm/include/asm/mcpm.h | 5 +++++
 2 files changed, 14 insertions(+)
arch/arm/Kconfig +9 -0
index 87b63fd..10cc6ec 100644
@@ -1490,6 +1490,15 @@ config MCPM
 	  for (multi-)cluster based systems, such as big.LITTLE based
 	  systems.
 
+config MCPM_QUAD_CLUSTER
+	bool
+	depends on MCPM
+	help
+	  To avoid wasting resources unnecessarily, MCPM only supports up
+	  to 2 clusters by default.
+	  Platforms with 3 or 4 clusters that use MCPM must select this
+	  option to allow the additional clusters to be managed.
+
 config BIG_LITTLE
 	bool "big.LITTLE support (Experimental)"
 	depends on CPU_V7 && SMP
arch/arm/include/asm/mcpm.h +5 -0
index d9702eb..a4fbacc 100644
@@ -20,7 +20,12 @@
  * to consider dynamic allocation.
  */
 #define MAX_CPUS_PER_CLUSTER	4
+
+#ifdef CONFIG_MCPM_QUAD_CLUSTER
+#define MAX_NR_CLUSTERS		4
+#else
 #define MAX_NR_CLUSTERS		2
+#endif
 
 #ifndef __ASSEMBLY__
 
Signature · 1 line
1.9.1
#6 lore raw

PATCH v10 3/11 ARM: hisi: enable MCPM implementation

In reply to Haojian Zhuang

Multiple CPU clusters are used in Hisilicon HiP04 SoC. Now use MCPM framework to manage power on HiP04 SoC.

---
 arch/arm/mach-hisi/Makefile   |   1 +
 arch/arm/mach-hisi/platmcpm.c | 331 ++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 332 insertions(+)
 create mode 100644 arch/arm/mach-hisi/platmcpm.c
arch/arm/mach-hisi/Makefile +1 -0
index ee2506b..d64831e 100644
@@ -3,4 +3,5 @@
 #
 
 obj-y	+= hisilicon.o
+obj-$(CONFIG_MCPM)		+= platmcpm.o
 obj-$(CONFIG_SMP)		+= platsmp.o hotplug.o headsmp.o
arch/arm/mach-hisi/platmcpm.c new file +331 -0

331 lines not on this page · raw message

Signature · 1 line
1.9.1
#7 lore raw

PATCH v10 3/11 ARM: hisi: enable MCPM implementation

Quoted 165 lines · Haojian Zhuang

Multiple CPU clusters are used in Hisilicon HiP04 SoC. Now use MCPM framework to manage power on HiP04 SoC.

---
 arch/arm/mach-hisi/Makefile   |   1 +
 arch/arm/mach-hisi/platmcpm.c | 331 ++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 332 insertions(+)
 create mode 100644 arch/arm/mach-hisi/platmcpm.c
arch/arm/mach-hisi/Makefile +1 -0
index ee2506b..d64831e 100644
@@ -3,4 +3,5 @@
 #
 
 obj-y	+= hisilicon.o
+obj-$(CONFIG_MCPM)		+= platmcpm.o
 obj-$(CONFIG_SMP)		+= platsmp.o hotplug.o headsmp.o
arch/arm/mach-hisi/platmcpm.c new file +139 -0
new file mode 100644
index 0000000..3befcb3
@@ -0,0 +1,331 @@
+/*
+ * Copyright (c) 2013-2014 Linaro Ltd.
+ * Copyright (c) 2013-2014 Hisilicon Limited.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ */
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <linux/of_address.h>
+
+#include <asm/cputype.h>
+#include <asm/cp15.h>
+#include <asm/mcpm.h>
+
+#include "core.h"
+
+/* bits definition in SC_CPU_RESET_REQ[x]/SC_CPU_RESET_DREQ[x]
+ * 1 -- unreset; 0 -- reset
+ */
+#define CORE_RESET_BIT(x)		(1 << x)
+#define NEON_RESET_BIT(x)		(1 << (x + 4))
+#define CORE_DEBUG_RESET_BIT(x)		(1 << (x + 9))
+#define CLUSTER_L2_RESET_BIT		(1 << 8)
+#define CLUSTER_DEBUG_RESET_BIT		(1 << 13)
+
+/*
+ * bits definition in SC_CPU_RESET_STATUS[x]
+ * 1 -- reset status; 0 -- unreset status
+ */
+#define CORE_RESET_STATUS(x)		(1 << x)
+#define NEON_RESET_STATUS(x)		(1 << (x + 4))
+#define CORE_DEBUG_RESET_STATUS(x)	(1 << (x + 9))
+#define CLUSTER_L2_RESET_STATUS		(1 << 8)
+#define CLUSTER_DEBUG_RESET_STATUS	(1 << 13)
+#define CORE_WFI_STATUS(x)		(1 << (x + 16))
+#define CORE_WFE_STATUS(x)		(1 << (x + 20))
+#define CORE_DEBUG_ACK(x)		(1 << (x + 24))
+
+#define SC_CPU_RESET_REQ(x)		(0x520 + (x << 3))	/* reset */
+#define SC_CPU_RESET_DREQ(x)		(0x524 + (x << 3))	/* unreset */
+#define SC_CPU_RESET_STATUS(x)		(0x1520 + (x << 3))
+
+#define FAB_SF_MODE			0x0c
+#define FAB_SF_INVLD			0x10
+
+/* bits definition in FB_SF_INVLD */
+#define FB_SF_INVLD_START		(1 << 8)
+
+#define HIP04_MAX_CLUSTERS		4
+#define HIP04_MAX_CPUS_PER_CLUSTER	4
+
+#define POLL_MSEC	10
+#define TIMEOUT_MSEC	1000
+
+struct hip04_secondary_cpu_data {
+	u32	bootwrapper_phys;
+	u32	bootwrapper_size;
+	u32	bootwrapper_magic;
+	u32	relocation_entry;
+	u32	relocation_size;
+};
+
+static void __iomem *relocation, *sysctrl, *fabric;
+static int hip04_cpu_table[HIP04_MAX_CLUSTERS][HIP04_MAX_CPUS_PER_CLUSTER];
+static DEFINE_SPINLOCK(boot_lock);
+static struct hip04_secondary_cpu_data hip04_boot;
+static u32 fabric_phys_addr;
+
+static bool hip04_cluster_down(unsigned int cluster)
+{
+	int i;
+
+	for (i = 0; i < HIP04_MAX_CPUS_PER_CLUSTER; i++)
+		if (hip04_cpu_table[cluster][i])
+			return false;
+	return true;
+}
+
+static int hip04_mcpm_power_up(unsigned int cpu, unsigned int cluster)
+{
+	unsigned long data, mask;
+
+	if (!relocation || !sysctrl)
+		return -ENODEV;
+	if (cluster >= HIP04_MAX_CLUSTERS || cpu >= HIP04_MAX_CPUS_PER_CLUSTER)
+		return -EINVAL;
+
+	spin_lock_irq(&boot_lock);
+
+	if (hip04_cpu_table[cluster][cpu]) {
+		hip04_cpu_table[cluster][cpu]++;
+		spin_unlock_irq(&boot_lock);
+		return 0;
+	}
+
+	writel_relaxed(hip04_boot.bootwrapper_phys, relocation);
+	writel_relaxed(hip04_boot.bootwrapper_magic, relocation + 4);
+	writel_relaxed(virt_to_phys(mcpm_entry_point), relocation + 8);
+	writel_relaxed(0, relocation + 12);
+
+	if (hip04_cluster_down(cluster)) {
+		data = CLUSTER_DEBUG_RESET_BIT;
+		writel_relaxed(data, sysctrl + SC_CPU_RESET_DREQ(cluster));
+		do {
+			mask = CLUSTER_DEBUG_RESET_STATUS;
+			data = readl_relaxed(sysctrl + \
+					     SC_CPU_RESET_STATUS(cluster));
+		} while (data & mask);
+	}
+
+	hip04_cpu_table[cluster][cpu]++;
+
+	data = CORE_RESET_BIT(cpu) | NEON_RESET_BIT(cpu) | \
+	       CORE_DEBUG_RESET_BIT(cpu);
+	writel_relaxed(data, sysctrl + SC_CPU_RESET_DREQ(cluster));
+	spin_unlock_irq(&boot_lock);
+	msleep(POLL_MSEC);
+
+	return 0;
+}
+
+static void hip04_mcpm_power_down(void)
+{
+	unsigned int mpidr, cpu, cluster, data = 0;
+	bool skip_reset = false;
+
+	mpidr = read_cpuid_mpidr();
+	cpu = MPIDR_AFFINITY_LEVEL(mpidr, 0);
+	cluster = MPIDR_AFFINITY_LEVEL(mpidr, 1);
+
+	__mcpm_cpu_going_down(cpu, cluster);
+
+	spin_lock(&boot_lock);
+	BUG_ON(__mcpm_cluster_state(cluster) != CLUSTER_UP);
+	hip04_cpu_table[cluster][cpu]--;
+	if (hip04_cpu_table[cluster][cpu] == 1) {
+		/* A power_up request went ahead of us. */

arch/arm/mach-hisi/platmcpm.c line 149

Quoted 10 lines
arch/arm/mach-hisi/platmcpm.c new file +10 -0
+		skip_reset = true;
+	} else if (hip04_cpu_table[cluster][cpu] > 1) {
+		pr_err("Cluster %d CPU%d boots multiple times\n", cluster, cpu);
+		BUG();
+	}
+	spin_unlock(&boot_lock);
+
+	v7_exit_coherency_flush(louis);
+
+	__mcpm_cpu_down(cpu, cluster);

What if there is a hip04_mcpm_power_up() being called on another CPU right here? There is a race that I illustrated in a previous email which is still unresolved.

Quoted 37 lines
arch/arm/mach-hisi/platmcpm.c new file +37 -0
+
+	if (!skip_reset) {
+		data = CORE_RESET_BIT(cpu) | NEON_RESET_BIT(cpu) | \
+		       CORE_DEBUG_RESET_BIT(cpu);
+		writel_relaxed(data, sysctrl + SC_CPU_RESET_REQ(cluster));
+	}
+}
+
+static int hip04_mcpm_wait_for_powerdown(unsigned int cpu, unsigned int cluster)
+{
+	unsigned int data, tries;
+
+	BUG_ON(cluster >= HIP04_MAX_CLUSTERS ||
+	       cpu >= HIP04_MAX_CPUS_PER_CLUSTER);
+
+	for (tries = 0; tries < TIMEOUT_MSEC / POLL_MSEC; tries++) {
+		data = readl_relaxed(sysctrl + SC_CPU_RESET_STATUS(cluster));
+		if (!(data & CORE_RESET_STATUS(cpu))) {
+			msleep(POLL_MSEC);
+			continue;
+		}
+		return 0;
+	}
+	return -ETIMEDOUT;
+}
+
+static void hip04_mcpm_powered_up(void)
+{
+	if (!relocation)
+		return;
+	spin_lock(&boot_lock);
+	writel_relaxed(0, relocation);
+	writel_relaxed(0, relocation + 4);
+	writel_relaxed(0, relocation + 8);
+	writel_relaxed(0, relocation + 12);
+	spin_unlock(&boot_lock);
+}

arch/arm/mach-hisi/platmcpm.c line 196

Quoted 10 lines
arch/arm/mach-hisi/platmcpm.c new file +10 -0
+
+static void __naked hip04_mcpm_power_up_setup(unsigned int affinity_level)
+{
+	asm volatile ("			\n"
+	/* calculate fabric phys address */
+"	adr	r2, 2f			\n"
+"	ldmia	r2, {r1, r3}		\n"
+"	sub	r0, r2, r1		\n"
+"	add	r2, r0, r3		\n"
+"	ldr	r2, [r2]		\n"

You may replace the above 2 instructions with "ldr r2, [r0, r3]".

arch/arm/mach-hisi/platmcpm.c line 200

Quoted 4 lines
arch/arm/mach-hisi/platmcpm.c new file +4 -0
+	/* get cluster id from MPIDR */
+"	mrc	p15, 0, r0, c0, c0, 5	\n"
+"	ubfx	r1, r0, #8, #8		\n"
+"	and	r1, r1, #0xf		\n"

You don't need the "and" here. It is implicit in ubfx.

arch/arm/mach-hisi/platmcpm.c line 206

Quoted 6 lines
arch/arm/mach-hisi/platmcpm.c new file +6 -0
+	/* 1 << cluster id */
+"	mov	r0, #1			\n"
+"	mov	r3, r0, lsl r1		\n"
+"	ldr	r0, [r2, #"__stringify(FAB_SF_MODE)"]	\n"
+"	tst	r0, r3			\n"
+"	bxne	lr			\n"

Instead of running all this code all the time, you could simply test r0 at the very beginning and if it is not equal to 1 then return immediately. If it is 1 that means the CPU executing this code is the first one to run in the cluster, in which case you also don't have to test if the cluster snoop is already enabled here.

arch/arm/mach-hisi/platmcpm.c line 218

Quoted 12 lines
arch/arm/mach-hisi/platmcpm.c new file +12 -0
+"	orr	r1, r0, r3		\n"
+"	str	r1, [r2, #"__stringify(FAB_SF_MODE)"]	\n"
+"1:	ldr	r0, [r2, #"__stringify(FAB_SF_MODE)"]	\n"
+"	tst	r0, r3			\n"
+"	beq	1b			\n"
+"	bx	lr			\n"
+
+"	.align	2			\n"
+"2:	.word	.			\n"
+"	.word	fabric_phys_addr	\n"
+	);
+}

Of course you will also have to enable the snoops for the current cluster in hip04_cpu_table_init() as well.

Quoted 117 lines
arch/arm/mach-hisi/platmcpm.c new file +113 -0
+
+static const struct mcpm_platform_ops hip04_mcpm_ops = {
+	.power_up		= hip04_mcpm_power_up,
+	.power_down		= hip04_mcpm_power_down,
+	.wait_for_powerdown	= hip04_mcpm_wait_for_powerdown,
+	.powered_up		= hip04_mcpm_powered_up,
+};
+
+static bool __init hip04_cpu_table_init(void)
+{
+	unsigned int mpidr, cpu, cluster;
+
+	mpidr = read_cpuid_mpidr();
+	cpu = MPIDR_AFFINITY_LEVEL(mpidr, 0);
+	cluster = MPIDR_AFFINITY_LEVEL(mpidr, 1);
+
+	if (cluster >= HIP04_MAX_CLUSTERS ||
+	    cpu >= HIP04_MAX_CPUS_PER_CLUSTER) {
+		pr_err("%s: boot CPU is out of bound!\n", __func__);
+		return false;
+	}
+	hip04_cpu_table[cluster][cpu] = 1;
+	return true;
+}
+
+static int __init hip04_mcpm_init(void)
+{
+	struct device_node *np, *np_fab;
+	struct resource fab_res;
+	int ret = -ENODEV;
+
+	np = of_find_compatible_node(NULL, NULL, "hisilicon,sysctrl");
+	if (!np)
+		goto err;
+	np_fab = of_find_compatible_node(NULL, NULL, "hisilicon,hip04-fabric");
+	if (!np_fab)
+		goto err;
+
+	if (of_property_read_u32(np, "bootwrapper-phys",
+				 &hip04_boot.bootwrapper_phys)) {
+		pr_err("failed to get bootwrapper-phys\n");
+		ret = -EINVAL;
+		goto err;
+	}
+	if (of_property_read_u32(np, "bootwrapper-size",
+				 &hip04_boot.bootwrapper_size)) {
+		pr_err("failed to get bootwrapper-size\n");
+		ret = -EINVAL;
+		goto err;
+	}
+	if (of_property_read_u32(np, "bootwrapper-magic",
+				 &hip04_boot.bootwrapper_magic)) {
+		pr_err("failed to get bootwrapper-magic\n");
+		ret = -EINVAL;
+		goto err;
+	}
+	if (of_property_read_u32(np, "relocation-entry",
+				 &hip04_boot.relocation_entry)) {
+		pr_err("failed to get relocation-entry\n");
+		ret = -EINVAL;
+		goto err;
+	}
+	if (of_property_read_u32(np, "relocation-size",
+				 &hip04_boot.relocation_size)) {
+		pr_err("failed to get relocation-size\n");
+		ret = -EINVAL;
+		goto err;
+	}
+
+	relocation = ioremap(hip04_boot.relocation_entry,
+			     hip04_boot.relocation_size);
+	if (!relocation) {
+		pr_err("failed to map relocation space\n");
+		ret = -ENOMEM;
+		goto err;
+	}
+	sysctrl = of_iomap(np, 0);
+	if (!sysctrl) {
+		pr_err("failed to get sysctrl base\n");
+		ret = -ENOMEM;
+		goto err_sysctrl;
+	}
+	ret = of_address_to_resource(np_fab, 0, &fab_res);
+	if (ret) {
+		pr_err("failed to get fabric base phys\n");
+		goto err_fabric;
+	}
+	fabric_phys_addr = fab_res.start;
+	sync_cache_w(&fabric_phys_addr);
+	fabric = of_iomap(np_fab, 0);
+	if (!fabric) {
+		pr_err("failed to get fabric base\n");
+		ret = -ENOMEM;
+		goto err_fabric;
+	}
+
+	if (!hip04_cpu_table_init())
+		return -EINVAL;
+	ret = mcpm_platform_register(&hip04_mcpm_ops);
+	if (!ret) {
+		mcpm_sync_init(hip04_mcpm_power_up_setup);
+		pr_info("HiP04 MCPM initialized\n");
+	}
+	mcpm_smp_set_ops();
+	return ret;
+err_fabric:
+	iounmap(sysctrl);
+err_sysctrl:
+	iounmap(relocation);
+err:
+	return ret;
+}
+early_initcall(hip04_mcpm_init);
Signature · 1 line
1.9.1
#8 lore raw

PATCH v10 3/11 ARM: hisi: enable MCPM implementation

Quoted 37 lines · Nicolas Pitre
Quoted 35 lines · Haojian Zhuang

Multiple CPU clusters are used in Hisilicon HiP04 SoC. Now use MCPM framework to manage power on HiP04 SoC.

---
 arch/arm/mach-hisi/Makefile   |   1 +
 arch/arm/mach-hisi/platmcpm.c | 331 ++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 332 insertions(+)
 create mode 100644 arch/arm/mach-hisi/platmcpm.c
arch/arm/mach-hisi/Makefile +23 -0
index ee2506b..d64831e 100644
+
+static void hip04_mcpm_power_down(void)
+{
+     unsigned int mpidr, cpu, cluster, data = 0;
+     bool skip_reset = false;
+
+     mpidr = read_cpuid_mpidr();
+     cpu = MPIDR_AFFINITY_LEVEL(mpidr, 0);
+     cluster = MPIDR_AFFINITY_LEVEL(mpidr, 1);
+
+     __mcpm_cpu_going_down(cpu, cluster);
+
+     spin_lock(&boot_lock);
+     BUG_ON(__mcpm_cluster_state(cluster) != CLUSTER_UP);
+     hip04_cpu_table[cluster][cpu]--;
+     if (hip04_cpu_table[cluster][cpu] == 1) {
+             /* A power_up request went ahead of us. */
+             skip_reset = true;
+     } else if (hip04_cpu_table[cluster][cpu] > 1) {
+             pr_err("Cluster %d CPU%d boots multiple times\n", cluster, cpu);
+             BUG();
+     }
+     spin_unlock(&boot_lock);
Quoted 9 lines

arch/arm/mach-hisi/Makefile

Quoted 4 lines
arch/arm/mach-hisi/Makefile +4 -0
+
+     v7_exit_coherency_flush(louis);
+
+     __mcpm_cpu_down(cpu, cluster);

What if there is a hip04_mcpm_power_up() being called on another CPU right here? There is a race that I illustrated in a previous email which is still unresolved.

Thanks for your reminder again. I'll move it into the protection.

Quoted 41 lines
Quoted 41 lines
arch/arm/mach-hisi/Makefile +41 -0
+
+     if (!skip_reset) {
+             data = CORE_RESET_BIT(cpu) | NEON_RESET_BIT(cpu) | \
+                    CORE_DEBUG_RESET_BIT(cpu);
+             writel_relaxed(data, sysctrl + SC_CPU_RESET_REQ(cluster));
+     }
+}
+
+static int hip04_mcpm_wait_for_powerdown(unsigned int cpu, unsigned int cluster)
+{
+     unsigned int data, tries;
+
+     BUG_ON(cluster >= HIP04_MAX_CLUSTERS ||
+            cpu >= HIP04_MAX_CPUS_PER_CLUSTER);
+
+     for (tries = 0; tries < TIMEOUT_MSEC / POLL_MSEC; tries++) {
+             data = readl_relaxed(sysctrl + SC_CPU_RESET_STATUS(cluster));
+             if (!(data & CORE_RESET_STATUS(cpu))) {
+                     msleep(POLL_MSEC);
+                     continue;
+             }
+             return 0;
+     }
+     return -ETIMEDOUT;
+}
+
+static void hip04_mcpm_powered_up(void)
+{
+     if (!relocation)
+             return;
+     spin_lock(&boot_lock);
+     writel_relaxed(0, relocation);
+     writel_relaxed(0, relocation + 4);
+     writel_relaxed(0, relocation + 8);
+     writel_relaxed(0, relocation + 12);
+     spin_unlock(&boot_lock);
+}
+
+static void __naked hip04_mcpm_power_up_setup(unsigned int affinity_level)
+{
+     asm volatile ("                 \n"
Quoted 9 lines
Quoted 6 lines
+     /* calculate fabric phys address */
+"    adr     r2, 2f                  \n"
+"    ldmia   r2, {r1, r3}            \n"
+"    sub     r0, r2, r1              \n"
+"    add     r2, r0, r3              \n"
+"    ldr     r2, [r2]                \n"

You may replace the above 2 instructions with "ldr r2, [r0, r3]".

OK.

Quoted 7 lines
Quoted 4 lines
+     /* get cluster id from MPIDR */
+"    mrc     p15, 0, r0, c0, c0, 5   \n"
+"    ubfx    r1, r0, #8, #8          \n"
+"    and     r1, r1, #0xf            \n"

You don't need the "and" here. It is implicit in ubfx.

OK.

Quoted 7 lines
Quoted 6 lines
+     /* 1 << cluster id */
+"    mov     r0, #1                  \n"
+"    mov     r3, r0, lsl r1          \n"
+"    ldr     r0, [r2, #"__stringify(FAB_SF_MODE)"]   \n"
+"    tst     r0, r3                  \n"
+"    bxne    lr                      \n"
Quoted 6 lines

Instead of running all this code all the time, you could simply test r0 at the very beginning and if it is not equal to 1 then return immediately. If it is 1 that means the CPU executing this code is the first one to run in the cluster, in which case you also don't have to test if the cluster snoop is already enabled here.

Since I need to enable the cluster snoop for cluster 0. At this time, it's not enabled although core0 is running.

Quoted 7 lines
Quoted 7 lines
+"    orr     r1, r0, r3              \n"
+"    str     r1, [r2, #"__stringify(FAB_SF_MODE)"]   \n"
+"1:  ldr     r0, [r2, #"__stringify(FAB_SF_MODE)"]   \n"
+"    tst     r0, r3                  \n"
+"    beq     1b                      \n"
+"    bx      lr                      \n"

+

Quoted 8 lines

arch/arm/mach-hisi/Makefile

Quoted 5 lines
+"    .align  2                       \n"
+"2:  .word   .                       \n"
+"    .word   fabric_phys_addr        \n"
arch/arm/mach-hisi/Makefile +2 -0
+     );
+}

Of course you will also have to enable the snoops for the current cluster in hip04_cpu_table_init() as well.

It means that I need to reserve the copy to enable the snoop in c code for cluster 0. Is it right?

Quoted 119 lines
Quoted 119 lines
arch/arm/mach-hisi/Makefile +113 -1
+
+static const struct mcpm_platform_ops hip04_mcpm_ops = {
+     .power_up               = hip04_mcpm_power_up,
+     .power_down             = hip04_mcpm_power_down,
+     .wait_for_powerdown     = hip04_mcpm_wait_for_powerdown,
+     .powered_up             = hip04_mcpm_powered_up,
+};
+
+static bool __init hip04_cpu_table_init(void)
+{
+     unsigned int mpidr, cpu, cluster;
+
+     mpidr = read_cpuid_mpidr();
+     cpu = MPIDR_AFFINITY_LEVEL(mpidr, 0);
+     cluster = MPIDR_AFFINITY_LEVEL(mpidr, 1);
+
+     if (cluster >= HIP04_MAX_CLUSTERS ||
+         cpu >= HIP04_MAX_CPUS_PER_CLUSTER) {
+             pr_err("%s: boot CPU is out of bound!\n", __func__);
+             return false;
+     }
+     hip04_cpu_table[cluster][cpu] = 1;
+     return true;
+}
+
+static int __init hip04_mcpm_init(void)
+{
+     struct device_node *np, *np_fab;
+     struct resource fab_res;
+     int ret = -ENODEV;
+
+     np = of_find_compatible_node(NULL, NULL, "hisilicon,sysctrl");
+     if (!np)
+             goto err;
+     np_fab = of_find_compatible_node(NULL, NULL, "hisilicon,hip04-fabric");
+     if (!np_fab)
+             goto err;
+
+     if (of_property_read_u32(np, "bootwrapper-phys",
+                              &hip04_boot.bootwrapper_phys)) {
+             pr_err("failed to get bootwrapper-phys\n");
+             ret = -EINVAL;
+             goto err;
+     }
+     if (of_property_read_u32(np, "bootwrapper-size",
+                              &hip04_boot.bootwrapper_size)) {
+             pr_err("failed to get bootwrapper-size\n");
+             ret = -EINVAL;
+             goto err;
+     }
+     if (of_property_read_u32(np, "bootwrapper-magic",
+                              &hip04_boot.bootwrapper_magic)) {
+             pr_err("failed to get bootwrapper-magic\n");
+             ret = -EINVAL;
+             goto err;
+     }
+     if (of_property_read_u32(np, "relocation-entry",
+                              &hip04_boot.relocation_entry)) {
+             pr_err("failed to get relocation-entry\n");
+             ret = -EINVAL;
+             goto err;
+     }
+     if (of_property_read_u32(np, "relocation-size",
+                              &hip04_boot.relocation_size)) {
+             pr_err("failed to get relocation-size\n");
+             ret = -EINVAL;
+             goto err;
+     }
+
+     relocation = ioremap(hip04_boot.relocation_entry,
+                          hip04_boot.relocation_size);
+     if (!relocation) {
+             pr_err("failed to map relocation space\n");
+             ret = -ENOMEM;
+             goto err;
+     }
+     sysctrl = of_iomap(np, 0);
+     if (!sysctrl) {
+             pr_err("failed to get sysctrl base\n");
+             ret = -ENOMEM;
+             goto err_sysctrl;
+     }
+     ret = of_address_to_resource(np_fab, 0, &fab_res);
+     if (ret) {
+             pr_err("failed to get fabric base phys\n");
+             goto err_fabric;
+     }
+     fabric_phys_addr = fab_res.start;
+     sync_cache_w(&fabric_phys_addr);
+     fabric = of_iomap(np_fab, 0);
+     if (!fabric) {
+             pr_err("failed to get fabric base\n");
+             ret = -ENOMEM;
+             goto err_fabric;
+     }
+
+     if (!hip04_cpu_table_init())
+             return -EINVAL;
+     ret = mcpm_platform_register(&hip04_mcpm_ops);
+     if (!ret) {
+             mcpm_sync_init(hip04_mcpm_power_up_setup);
+             pr_info("HiP04 MCPM initialized\n");
+     }
+     mcpm_smp_set_ops();
+     return ret;
+err_fabric:
+     iounmap(sysctrl);
+err_sysctrl:
+     iounmap(relocation);
+err:
+     return ret;
+}
+early_initcall(hip04_mcpm_init);
--

1.9.1

#9 lore raw

PATCH v10 3/11 ARM: hisi: enable MCPM implementation

Quoted 40 lines · Haojian Zhuang
Quoted 14 lines · Nicolas Pitre

arch/arm/mach-hisi/platmcpm.c line 196

Quoted 9 lines · Haojian Zhuang
arch/arm/mach-hisi/platmcpm.c new file +9 -0
+static void __naked hip04_mcpm_power_up_setup(unsigned int affinity_level)
+{
+     asm volatile ("                 \n"
+     /* calculate fabric phys address */
+"    adr     r2, 2f                  \n"
+"    ldmia   r2, {r1, r3}            \n"
+"    sub     r0, r2, r1              \n"
+"    add     r2, r0, r3              \n"
+"    ldr     r2, [r2]                \n"

You may replace the above 2 instructions with "ldr r2, [r0, r3]".

OK.

Quoted 7 lines
Quoted 4 lines
+     /* get cluster id from MPIDR */
+"    mrc     p15, 0, r0, c0, c0, 5   \n"
+"    ubfx    r1, r0, #8, #8          \n"
+"    and     r1, r1, #0xf            \n"

You don't need the "and" here. It is implicit in ubfx.

OK.

Quoted 7 lines
Quoted 6 lines
+     /* 1 << cluster id */
+"    mov     r0, #1                  \n"
+"    mov     r3, r0, lsl r1          \n"
+"    ldr     r0, [r2, #"__stringify(FAB_SF_MODE)"]   \n"
+"    tst     r0, r3                  \n"
+"    bxne    lr                      \n"
Quoted 6 lines

Instead of running all this code all the time, you could simply test r0 at the very beginning and if it is not equal to 1 then return immediately. If it is 1 that means the CPU executing this code is the first one to run in the cluster, in which case you also don't have to test if the cluster snoop is already enabled here.

Quoted 2 lines

Since I need to enable the cluster snoop for cluster 0. At this time, it's not enabled although core0 is running.

Yes, hence my next comment.

Quoted 16 lines
Quoted 7 lines
Quoted 7 lines
+"    orr     r1, r0, r3              \n"
+"    str     r1, [r2, #"__stringify(FAB_SF_MODE)"]   \n"
+"1:  ldr     r0, [r2, #"__stringify(FAB_SF_MODE)"]   \n"
+"    tst     r0, r3                  \n"
+"    beq     1b                      \n"
+"    bx      lr                      \n"

+

Quoted 8 lines

Review

Quoted 5 lines
+"    .align  2                       \n"
+"2:  .word   .                       \n"
+"    .word   fabric_phys_addr        \n"
(quoted diff) +2 -0
+     );
+}

Of course you will also have to enable the snoops for the current cluster in hip04_cpu_table_init() as well.

Quoted 2 lines

It means that I need to reserve the copy to enable the snoop in c code for cluster 0. Is it right?

Yes. And it can be __init just like hip04_cpu_table_init().

Nicolas

#10 lore raw

PATCH v10 4/11 ARM: hisi: enable HiP04

In reply to Haojian Zhuang

Support HiP04 SoC what supports 16 cores. And it relies on MCPM framework.

---
 arch/arm/mach-hisi/Kconfig     | 8 ++++++++
 arch/arm/mach-hisi/hisilicon.c | 9 +++++++++
 arch/arm/mach-hisi/platmcpm.c  | 1 -
 3 files changed, 17 insertions(+), 1 deletion(-)
arch/arm/mach-hisi/Kconfig +8 -0
index 90fdbb4..a458f28 100644
@@ -19,6 +19,14 @@ config ARCH_HI3xxx
 	help
 	  Support for Hisilicon Hi36xx SoC family
 
+config ARCH_HIP04
+	bool "Hisilicon HiP04 Cortex A15 family" if ARCH_MULTI_V7
+	select HAVE_ARM_ARCH_TIMER
+	select MCPM if SMP
+	select MCPM_QUAD_CLUSTER if SMP
+	help
+	  Support for Hisilicon HiP04 SoC family
+
 config ARCH_HIX5HD2
 	bool "Hisilicon X5HD2 family" if ARCH_MULTI_V7
 	select CACHE_L2X0
arch/arm/mach-hisi/hisilicon.c +9 -0
index e842ca9..938cdba 100644
@@ -114,3 +114,12 @@ DT_MACHINE_START(HIX5HD2_DT, "Hisilicon HIX5HD2 (Flattened Device Tree)")
 	.smp		= smp_ops(hix5hd2_smp_ops),
 	.restart	= hi3xxx_restart,
 MACHINE_END
+
+static const char *hip04_compat[] __initconst = {
+	"hisilicon,hip04-d01",
+	NULL,
+};
+
+DT_MACHINE_START(HIP04, "Hisilicon HiP04 (Flattened Device Tree)")
+	.dt_compat	= hip04_compat,
+MACHINE_END
arch/arm/mach-hisi/platmcpm.c +0 -1
index 3befcb3..d903d75 100644
@@ -116,7 +116,6 @@ static int hip04_mcpm_power_up(unsigned int cpu, unsigned int cluster)
 	       CORE_DEBUG_RESET_BIT(cpu);
 	writel_relaxed(data, sysctrl + SC_CPU_RESET_DREQ(cluster));
 	spin_unlock_irq(&boot_lock);
-	msleep(POLL_MSEC);
 
 	return 0;
 }
Signature · 1 line
1.9.1
maintainer
#11 lore raw

PATCH v10 4/11 ARM: hisi: enable HiP04

arch/arm/mach-hisi/platmcpm.c static int hip04_mcpm_power_up(unsigned int cpu, unsigned int cluster) · line 121

Quoted 10 lines · Haojian Zhuang
arch/arm/mach-hisi/platmcpm.c +0 -1
@@ -116,7 +116,6 @@ static int hip04_mcpm_power_up(unsigned int cpu, unsigned int cluster)
               CORE_DEBUG_RESET_BIT(cpu);
        writel_relaxed(data, sysctrl + SC_CPU_RESET_DREQ(cluster));
        spin_unlock_irq(&boot_lock);
-       msleep(POLL_MSEC);
 
        return 0;
 }

Is this change intentional? It seems like it should belong into the earlier patch that introduces this file.

Arnd

#12 lore raw

PATCH v10 4/11 ARM: hisi: enable HiP04

Quoted 9 lines · Arnd Bergmann
Quoted 8 lines · Haojian Zhuang
arch/arm/mach-hisi/platmcpm.c +0 -1
@@ -116,7 +116,6 @@ static int hip04_mcpm_power_up(unsigned int cpu, unsigned int cluster)
               CORE_DEBUG_RESET_BIT(cpu);
        writel_relaxed(data, sysctrl + SC_CPU_RESET_DREQ(cluster));
        spin_unlock_irq(&boot_lock);
-       msleep(POLL_MSEC);
 
Quoted 7 lines

arch/arm/mach-hisi/platmcpm.c static int hip04_mcpm_power_up(unsigned int cpu, unsigned int cluster) · line 121

Quoted 2 lines
arch/arm/mach-hisi/platmcpm.c +0 -0
        return 0;
 }

Is this change intentional? It seems like it should belong into the earlier patch that introduces this file.

Arnd

Yes, it should belong to the earlier patch. And it's fixed in v12 or v13.

Regards
Haojian

#13 lore raw

PATCH v10 5/11 document: dt: add the binding on HiP04

In reply to Haojian Zhuang

Add bootwrapper-phys, bootwrapper-size, bootwrapper-magic properties for Hisilicon HiP04 SoC.

---
 .../devicetree/bindings/arm/hisilicon/hisilicon.txt | 21 +++++++++++++++++++++
 1 file changed, 21 insertions(+)
Documentation/devicetree/bindings/arm/hisilicon/hisilicon.txt +21 -0
index df0a452..5024992 100644
@@ -4,6 +4,10 @@ Hisilicon Platforms Device Tree Bindings
 Hi4511 Board
 Required root node properties:
 	- compatible = "hisilicon,hi3620-hi4511";
+HiP04 D01 Board
+Required root node properties:
+	- compatible = "hisilicon,hip04-d01";
+
 
 Hisilicon system controller
 
@@ -19,6 +23,15 @@ Optional properties:
 		If reg value is not zero, cpun exit wfi and go
 - resume-offset : offset in sysctrl for notifying cpu0 when resume
 - reboot-offset : offset in sysctrl for system reboot
+- relocation-entry : relocation address of secondary cpu boot code
+- relocation-size : relocation size of secondary cpu boot code
+- bootwrapper-phys : physical address of boot wrapper
+- bootwrapper-size : size of boot wrapper
+- bootwrapper-magic : magic number for secondary cpu in boot wrapper
+The memory area of [bootwrapper-phys : bootwrapper-phys+bootwrapper-size]
+should be reserved. This should be set in /memreserve/ node in DTS file.
+bootwrapper-phys, bootwrapper-size, bootwrapper-magic is used in HiP04
+DTS file.
 
 Example:
 
@@ -31,6 +44,7 @@ Example:
 		reboot-offset = <0x4>;
 	};
 
+
 PCTRL: Peripheral misc control register
 
 Required Properties:
@@ -44,3 +58,10 @@ Example:
 		compatible = "hisilicon,pctrl";
 		reg = <0xfca09000 0x1000>;
 	};
+
+
+Fabric:
+
+Required Properties:
+- compatible: "hisilicon,hip04-fabric";
+- reg: Address and size of Fabric
Signature · 1 line
1.9.1
#14 lore raw

PATCH v10 6/11 document: dt: add the binding on HiP04 clock

In reply to Haojian Zhuang

The DT binding for Hisilicon HiP04 clock driver.

---
 .../devicetree/bindings/clock/hip04-clock.txt        | 20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/clock/hip04-clock.txt
Documentation/devicetree/bindings/clock/hip04-clock.txt new file +20 -0
new file mode 100644
index 0000000..4d31ae3
@@ -0,0 +1,20 @@
+* Hisilicon HiP04 Clock Controller
+
+The HiP04 clock controller generates and supplies clock to various
+controllers within the HiP04 SoC.
+
+Required Properties:
+
+- compatible: should be one of the following.
+  - "hisilicon,hip04-clock" - controller compatible with HiP04 SoC.
+
+- reg: physical base address of the controller and length of memory mapped
+  region.
+
+- #clock-cells: should be 1.
+
+
+Each clock is assigned an identifier and client nodes use this identifier
+to specify the clock which they consume.
+
+All these identifier could be found in <dt-bindings/clock/hip04-clock.h>.
Signature · 1 line
1.9.1
#15 lore raw

PATCH v10 7/11 ARM: dts: append hip04 dts

In reply to Haojian Zhuang

Add hip04-d01.dts & hip04.dtsi for hip04 SoC platform.

---
 arch/arm/boot/dts/Makefile      |   1 +
 arch/arm/boot/dts/hip04-d01.dts |  39 ++++++
 arch/arm/boot/dts/hip04.dtsi    | 267 ++++++++++++++++++++++++++++++++++++++++
 3 files changed, 307 insertions(+)
 create mode 100644 arch/arm/boot/dts/hip04-d01.dts
 create mode 100644 arch/arm/boot/dts/hip04.dtsi
arch/arm/boot/dts/Makefile +1 -0
index 721525e..6587bbf 100644
@@ -86,6 +86,7 @@ dtb-$(CONFIG_ARCH_HI3xxx) += hi3620-hi4511.dtb
 dtb-$(CONFIG_ARCH_HIX5HD2) += hix5hd2-dkb.dtb
 dtb-$(CONFIG_ARCH_HIGHBANK) += highbank.dtb \
 	ecx-2000.dtb
+dtb-$(CONFIG_ARCH_HIP04) += hip04-d01.dtb
 dtb-$(CONFIG_ARCH_INTEGRATOR) += integratorap.dtb \
 	integratorcp.dtb
 dtb-$(CONFIG_ARCH_KEYSTONE) += k2hk-evm.dtb \
arch/arm/boot/dts/hip04-d01.dts new file +39 -0
new file mode 100644
index 0000000..661c8e5
@@ -0,0 +1,39 @@
+/*
+ *  Copyright (C) 2013-2014 Linaro Ltd.
+ *  Author: Haojian Zhuang <[email protected]>
+ *
+ *  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
+ *  publishhed by the Free Software Foundation.
+ */
+
+/dts-v1/;
+
+/* For bootwrapper */
+/memreserve/ 0x10c00000 0x00010000;
+
+#include "hip04.dtsi"
+
+/ {
+	/* memory bus is 64-bit */
+	#address-cells = <2>;
+	#size-cells = <2>;
+	model = "Hisilicon D01 Development Board";
+	compatible = "hisilicon,hip04-d01";
+
+	memory at 00000000,10000000 {
+		device_type = "memory";
+		reg = <0x00000000 0x10000000 0x00000000 0xc0000000>;
+	};
+
+	memory at 00000004,c0000000 {
+		device_type = "memory";
+		reg = <0x00000004 0xc0000000 0x00000003 0x40000000>;
+	};
+
+	soc {
+		uart0: uart at 4007000 {
+			status = "ok";
+		};
+	};
+};
arch/arm/boot/dts/hip04.dtsi new file +267 -0

267 lines not on this page · raw message

Signature · 1 line
1.9.1
#16 lore raw

PATCH v10 8/11 ARM: config: append lpae configuration

In reply to Haojian Zhuang

Append multi_v7_lpae_config. In this default configuration, CONFIG_ARCH_MULTI_V6 is disabled. CONFIG_ARM_LPAE is enabled.

---
 arch/arm/configs/multi_v7_lpae_defconfig | 343 +++++++++++++++++++++++++++++++
 1 file changed, 343 insertions(+)
 create mode 100644 arch/arm/configs/multi_v7_lpae_defconfig
arch/arm/configs/multi_v7_lpae_defconfig new file +343 -0
new file mode 100644
index 0000000..891937b
@@ -0,0 +1,343 @@
+CONFIG_SYSVIPC=y
+CONFIG_FHANDLE=y
+CONFIG_IRQ_DOMAIN_DEBUG=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_EMBEDDED=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_ARCH_MULTI_V6 is not set
+CONFIG_ARCH_MULTI_V7=y
+CONFIG_ARM_LPAE=y
+CONFIG_ARCH_MVEBU=y
+CONFIG_MACH_ARMADA_XP=y
+CONFIG_ARCH_BCM=y
+CONFIG_ARCH_BCM_5301X=y
+CONFIG_ARCH_BCM_MOBILE=y
+CONFIG_GPIO_PCA953X=y
+CONFIG_ARCH_HIGHBANK=y
+CONFIG_ARCH_HISI=y
+CONFIG_ARCH_HIP04=y
+CONFIG_ARCH_KEYSTONE=y
+CONFIG_ARCH_MXC=y
+CONFIG_MACH_IMX51_DT=y
+CONFIG_SOC_IMX53=y
+CONFIG_SOC_IMX6Q=y
+CONFIG_SOC_IMX6SL=y
+CONFIG_SOC_VF610=y
+CONFIG_ARCH_OMAP3=y
+CONFIG_ARCH_OMAP4=y
+CONFIG_SOC_OMAP5=y
+CONFIG_SOC_AM33XX=y
+CONFIG_SOC_DRA7XX=y
+CONFIG_SOC_AM43XX=y
+CONFIG_ARCH_QCOM=y
+CONFIG_ARCH_MSM8X60=y
+CONFIG_ARCH_MSM8960=y
+CONFIG_ARCH_MSM8974=y
+CONFIG_ARCH_ROCKCHIP=y
+CONFIG_ARCH_SOCFPGA=y
+CONFIG_PLAT_SPEAR=y
+CONFIG_ARCH_SPEAR13XX=y
+CONFIG_MACH_SPEAR1310=y
+CONFIG_MACH_SPEAR1340=y
+CONFIG_ARCH_STI=y
+CONFIG_ARCH_SUNXI=y
+CONFIG_ARCH_SIRF=y
+CONFIG_ARCH_TEGRA=y
+CONFIG_ARCH_TEGRA_2x_SOC=y
+CONFIG_ARCH_TEGRA_3x_SOC=y
+CONFIG_ARCH_TEGRA_114_SOC=y
+CONFIG_ARCH_TEGRA_124_SOC=y
+CONFIG_TEGRA_EMC_SCALING_ENABLE=y
+CONFIG_ARCH_U8500=y
+CONFIG_MACH_HREFV60=y
+CONFIG_MACH_SNOWBALL=y
+CONFIG_MACH_UX500_DT=y
+CONFIG_ARCH_VEXPRESS=y
+CONFIG_ARCH_VEXPRESS_CA9X4=y
+CONFIG_ARCH_VIRT=y
+CONFIG_ARCH_WM8850=y
+CONFIG_ARCH_ZYNQ=y
+CONFIG_NEON=y
+CONFIG_TRUSTED_FOUNDATIONS=y
+CONFIG_PCI=y
+CONFIG_PCI_MSI=y
+CONFIG_PCI_MVEBU=y
+CONFIG_PCI_TEGRA=y
+CONFIG_SMP=y
+CONFIG_HIGHMEM=y
+CONFIG_HIGHPTE=y
+CONFIG_CMA=y
+CONFIG_ARM_APPENDED_DTB=y
+CONFIG_ARM_ATAG_DTB_COMPAT=y
+CONFIG_KEXEC=y
+CONFIG_CPU_FREQ=y
+CONFIG_CPU_FREQ_STAT_DETAILS=y
+CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y
+CONFIG_CPU_IDLE=y
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+CONFIG_IP_PNP_RARP=y
+CONFIG_IPV6_ROUTER_PREF=y
+CONFIG_IPV6_OPTIMISTIC_DAD=y
+CONFIG_INET6_AH=m
+CONFIG_INET6_ESP=m
+CONFIG_INET6_IPCOMP=m
+CONFIG_IPV6_MIP6=m
+CONFIG_IPV6_TUNNEL=m
+CONFIG_IPV6_MULTIPLE_TABLES=y
+CONFIG_CFG80211=m
+CONFIG_MAC80211=m
+CONFIG_RFKILL=y
+CONFIG_RFKILL_INPUT=y
+CONFIG_RFKILL_GPIO=y
+CONFIG_DEVTMPFS=y
+CONFIG_DEVTMPFS_MOUNT=y
+CONFIG_DMA_CMA=y
+CONFIG_CMA_SIZE_MBYTES=64
+CONFIG_OMAP_OCP2SCP=y
+CONFIG_MTD=y
+CONFIG_MTD_M25P80=y
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_ICS932S401=y
+CONFIG_APDS9802ALS=y
+CONFIG_ISL29003=y
+CONFIG_BLK_DEV_SD=y
+CONFIG_BLK_DEV_SR=y
+CONFIG_SCSI_MULTI_LUN=y
+CONFIG_ATA=y
+CONFIG_SATA_AHCI_PLATFORM=y
+CONFIG_SATA_HIGHBANK=y
+CONFIG_SATA_MV=y
+CONFIG_NETDEVICES=y
+CONFIG_SUN4I_EMAC=y
+CONFIG_NET_CALXEDA_XGMAC=y
+CONFIG_MV643XX_ETH=y
+CONFIG_MVNETA=y
+CONFIG_KS8851=y
+CONFIG_R8169=y
+CONFIG_SMSC911X=y
+CONFIG_STMMAC_ETH=y
+CONFIG_TI_CPSW=y
+CONFIG_AT803X_PHY=y
+CONFIG_MARVELL_PHY=y
+CONFIG_ICPLUS_PHY=y
+CONFIG_USB_PEGASUS=y
+CONFIG_USB_USBNET=y
+CONFIG_USB_NET_SMSC75XX=y
+CONFIG_USB_NET_SMSC95XX=y
+CONFIG_BRCMFMAC=m
+CONFIG_RT2X00=m
+CONFIG_RT2800USB=m
+CONFIG_INPUT_EVDEV=y
+CONFIG_KEYBOARD_GPIO=y
+CONFIG_KEYBOARD_TEGRA=y
+CONFIG_KEYBOARD_SPEAR=y
+CONFIG_KEYBOARD_CROS_EC=y
+CONFIG_MOUSE_PS2_ELANTECH=y
+CONFIG_INPUT_MISC=y
+CONFIG_INPUT_MPU3050=y
+CONFIG_SERIO_AMBAKMI=y
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_DW=y
+CONFIG_SERIAL_AMBA_PL011=y
+CONFIG_SERIAL_AMBA_PL011_CONSOLE=y
+CONFIG_SERIAL_SIRFSOC=y
+CONFIG_SERIAL_SIRFSOC_CONSOLE=y
+CONFIG_SERIAL_TEGRA=y
+CONFIG_SERIAL_IMX=y
+CONFIG_SERIAL_IMX_CONSOLE=y
+CONFIG_SERIAL_MSM=y
+CONFIG_SERIAL_MSM_CONSOLE=y
+CONFIG_SERIAL_VT8500=y
+CONFIG_SERIAL_VT8500_CONSOLE=y
+CONFIG_SERIAL_OF_PLATFORM=y
+CONFIG_SERIAL_OMAP=y
+CONFIG_SERIAL_OMAP_CONSOLE=y
+CONFIG_SERIAL_XILINX_PS_UART=y
+CONFIG_SERIAL_XILINX_PS_UART_CONSOLE=y
+CONFIG_SERIAL_FSL_LPUART=y
+CONFIG_SERIAL_FSL_LPUART_CONSOLE=y
+CONFIG_SERIAL_ST_ASC=y
+CONFIG_SERIAL_ST_ASC_CONSOLE=y
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_MUX=y
+CONFIG_I2C_MUX_PCA954x=y
+CONFIG_I2C_MUX_PINCTRL=y
+CONFIG_I2C_DESIGNWARE_PLATFORM=y
+CONFIG_I2C_MV64XXX=y
+CONFIG_I2C_SIRF=y
+CONFIG_I2C_TEGRA=y
+CONFIG_SPI=y
+CONFIG_SPI_OMAP24XX=y
+CONFIG_SPI_ORION=y
+CONFIG_SPI_PL022=y
+CONFIG_SPI_SIRF=y
+CONFIG_SPI_TEGRA114=y
+CONFIG_SPI_TEGRA20_SFLASH=y
+CONFIG_SPI_TEGRA20_SLINK=y
+CONFIG_PINCTRL_AS3722=y
+CONFIG_PINCTRL_PALMAS=y
+CONFIG_GPIO_SYSFS=y
+CONFIG_GPIO_GENERIC_PLATFORM=y
+CONFIG_GPIO_PCA953X_IRQ=y
+CONFIG_GPIO_TWL4030=y
+CONFIG_GPIO_PALMAS=y
+CONFIG_GPIO_TPS6586X=y
+CONFIG_GPIO_TPS65910=y
+CONFIG_BATTERY_SBS=y
+CONFIG_CHARGER_TPS65090=y
+CONFIG_POWER_RESET_AS3722=y
+CONFIG_POWER_RESET_GPIO=y
+CONFIG_SENSORS_LM90=y
+CONFIG_THERMAL=y
+CONFIG_DOVE_THERMAL=y
+CONFIG_ARMADA_THERMAL=y
+CONFIG_WATCHDOG=y
+CONFIG_ORION_WATCHDOG=y
+CONFIG_MFD_AS3722=y
+CONFIG_MFD_CROS_EC=y
+CONFIG_MFD_CROS_EC_SPI=y
+CONFIG_MFD_MAX8907=y
+CONFIG_MFD_PALMAS=y
+CONFIG_MFD_TPS65090=y
+CONFIG_MFD_TPS6586X=y
+CONFIG_MFD_TPS65910=y
+CONFIG_REGULATOR_VIRTUAL_CONSUMER=y
+CONFIG_REGULATOR_AB8500=y
+CONFIG_REGULATOR_AS3722=y
+CONFIG_REGULATOR_GPIO=y
+CONFIG_REGULATOR_MAX8907=y
+CONFIG_REGULATOR_PALMAS=y
+CONFIG_REGULATOR_TPS51632=y
+CONFIG_REGULATOR_TPS62360=y
+CONFIG_REGULATOR_TPS65090=y
+CONFIG_REGULATOR_TPS6586X=y
+CONFIG_REGULATOR_TPS65910=y
+CONFIG_REGULATOR_TWL4030=y
+CONFIG_REGULATOR_VEXPRESS=y
+CONFIG_MEDIA_SUPPORT=y
+CONFIG_MEDIA_CAMERA_SUPPORT=y
+CONFIG_MEDIA_USB_SUPPORT=y
+CONFIG_USB_VIDEO_CLASS=y
+CONFIG_USB_GSPCA=y
+CONFIG_DRM=y
+CONFIG_DRM_TEGRA=y
+CONFIG_DRM_PANEL_SIMPLE=y
+CONFIG_FB_ARMCLCD=y
+CONFIG_FB_WM8505=y
+CONFIG_FB_SIMPLE=y
+CONFIG_BACKLIGHT_LCD_SUPPORT=y
+CONFIG_BACKLIGHT_CLASS_DEVICE=y
+CONFIG_BACKLIGHT_PWM=y
+CONFIG_FRAMEBUFFER_CONSOLE=y
+CONFIG_SOUND=y
+CONFIG_SND=y
+CONFIG_SND_SOC=y
+CONFIG_SND_SOC_TEGRA=y
+CONFIG_SND_SOC_TEGRA_RT5640=y
+CONFIG_SND_SOC_TEGRA_WM8753=y
+CONFIG_SND_SOC_TEGRA_WM8903=y
+CONFIG_SND_SOC_TEGRA_TRIMSLICE=y
+CONFIG_SND_SOC_TEGRA_ALC5632=y
+CONFIG_SND_SOC_TEGRA_MAX98090=y
+CONFIG_USB=y
+CONFIG_USB_XHCI_HCD=y
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_EHCI_TEGRA=y
+CONFIG_USB_EHCI_HCD_PLATFORM=y
+CONFIG_USB_ISP1760_HCD=y
+CONFIG_USB_STORAGE=y
+CONFIG_USB_CHIPIDEA=y
+CONFIG_USB_CHIPIDEA_HOST=y
+CONFIG_AB8500_USB=y
+CONFIG_OMAP_USB3=y
+CONFIG_SAMSUNG_USB2PHY=y
+CONFIG_SAMSUNG_USB3PHY=y
+CONFIG_USB_GPIO_VBUS=y
+CONFIG_USB_ISP1301=y
+CONFIG_USB_MXS_PHY=y
+CONFIG_MMC=y
+CONFIG_MMC_BLOCK_MINORS=16
+CONFIG_MMC_ARMMMCI=y
+CONFIG_MMC_SDHCI=y
+CONFIG_MMC_SDHCI_ESDHC_IMX=y
+CONFIG_MMC_SDHCI_TEGRA=y
+CONFIG_MMC_SDHCI_DOVE=y
+CONFIG_MMC_SDHCI_SPEAR=y
+CONFIG_MMC_SDHCI_BCM_KONA=y
+CONFIG_MMC_OMAP=y
+CONFIG_MMC_OMAP_HS=y
+CONFIG_MMC_MVSDIO=y
+CONFIG_EDAC=y
+CONFIG_EDAC_MM_EDAC=y
+CONFIG_EDAC_HIGHBANK_MC=y
+CONFIG_EDAC_HIGHBANK_L2=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_DRV_AS3722=y
+CONFIG_RTC_DRV_MAX8907=y
+CONFIG_RTC_DRV_PALMAS=y
+CONFIG_RTC_DRV_TWL4030=y
+CONFIG_RTC_DRV_TPS6586X=y
+CONFIG_RTC_DRV_TPS65910=y
+CONFIG_RTC_DRV_EM3027=y
+CONFIG_RTC_DRV_PL031=y
+CONFIG_RTC_DRV_VT8500=y
+CONFIG_RTC_DRV_MV=y
+CONFIG_RTC_DRV_TEGRA=y
+CONFIG_DMADEVICES=y
+CONFIG_DW_DMAC=y
+CONFIG_MV_XOR=y
+CONFIG_TEGRA20_APB_DMA=y
+CONFIG_STE_DMA40=y
+CONFIG_SIRF_DMA=y
+CONFIG_TI_EDMA=y
+CONFIG_PL330_DMA=y
+CONFIG_IMX_SDMA=y
+CONFIG_IMX_DMA=y
+CONFIG_MXS_DMA=y
+CONFIG_DMA_OMAP=y
+CONFIG_STAGING=y
+CONFIG_SENSORS_ISL29018=y
+CONFIG_SENSORS_ISL29028=y
+CONFIG_MFD_NVEC=y
+CONFIG_KEYBOARD_NVEC=y
+CONFIG_SERIO_NVEC_PS2=y
+CONFIG_NVEC_POWER=y
+CONFIG_COMMON_CLK_QCOM=y
+CONFIG_MSM_GCC_8660=y
+CONFIG_MSM_MMCC_8960=y
+CONFIG_MSM_MMCC_8974=y
+CONFIG_TEGRA_IOMMU_GART=y
+CONFIG_TEGRA_IOMMU_SMMU=y
+CONFIG_MEMORY=y
+CONFIG_IIO=y
+CONFIG_AK8975=y
+CONFIG_PWM=y
+CONFIG_PWM_TEGRA=y
+CONFIG_PWM_VT8500=y
+CONFIG_OMAP_USB2=y
+CONFIG_EXT4_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_TMPFS=y
+CONFIG_SQUASHFS=y
+CONFIG_SQUASHFS_LZO=y
+CONFIG_SQUASHFS_XZ=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3_ACL=y
+CONFIG_NFS_V4=y
+CONFIG_ROOT_NFS=y
+CONFIG_PRINTK_TIME=y
+CONFIG_DEBUG_FS=y
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_LOCKUP_DETECTOR=y
+CONFIG_CRYPTO_DEV_TEGRA_AES=y
Signature · 1 line
1.9.1
#17 lore raw

PATCH v10 9/11 ARM: config: append hip04_defconfig

In reply to Haojian Zhuang

Select HiP04 SoC configuration by hip04_defconfig.

---
 arch/arm/configs/hip04_defconfig | 74 ++++++++++++++++++++++++++++++++++++++++
 1 file changed, 74 insertions(+)
 create mode 100644 arch/arm/configs/hip04_defconfig
arch/arm/configs/hip04_defconfig new file +74 -0
new file mode 100644
index 0000000..5c471b2
@@ -0,0 +1,74 @@
+CONFIG_SYSVIPC=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_IRQ_DOMAIN_DEBUG=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_BSD_PROCESS_ACCT=y
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_RD_GZIP=y
+# CONFIG_ARCH_MULTI_V6 is not set
+CONFIG_ARCH_MULTI_V7=y
+CONFIG_ARCH_HISI=y
+CONFIG_ARCH_HIP04=y
+CONFIG_ARM_LPAE=y
+CONFIG_SMP=y
+CONFIG_NR_CPUS=16
+CONFIG_MCPM=y
+CONFIG_MCPM_QUAD_CLUSTER=y
+CONFIG_PREEMPT=y
+CONFIG_AEABI=y
+CONFIG_ARM_APPENDED_DTB=y
+CONFIG_ARM_ATAG_DTB_COMPAT=y
+CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_FROM_BOOTLOADER=y
+CONFIG_HIGHMEM=y
+CONFIG_VFP=y
+CONFIG_NEON=y
+CONFIG_NET=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_DEVTMPFS=y
+CONFIG_DEVTMPFS_MOUNT=y
+CONFIG_BLK_DEV=y
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_BLK_DEV_LOOP_MIN_COUNT=8
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=4096
+CONFIG_BLK_DEV_SD=y
+CONFIG_ATA=y
+CONFIG_SATA_AHCI_PLATFORM=y
+CONFIG_NETDEVICES=y
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_NR_UARTS=2
+CONFIG_SERIAL_8250_RUNTIME_UARTS=2
+CONFIG_SERIAL_8250_DW=y
+CONFIG_SERIAL_OF_PLATFORM=y
+CONFIG_I2C_DESIGNWARE_PLATFORM=y
+CONFIG_PINCTRL_SINGLE=y
+CONFIG_GPIO_GENERIC_PLATFORM=y
+CONFIG_REGULATOR_GPIO=y
+CONFIG_DRM=y
+CONFIG_FB_SIMPLE=y
+CONFIG_RTC_CLASS=y
+CONFIG_EXT4_FS=y
+CONFIG_TMPFS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3_ACL=y
+CONFIG_NFS_V4=y
+CONFIG_ROOT_NFS=y
+CONFIG_PRINTK_TIME=y
+CONFIG_DEBUG_FS=y
+CONFIG_DEBUG_KERNEL=y
+CONFIG_DEBUG_LL=y
+CONFIG_DEBUG_UART_8250=y
+CONFIG_EARLY_PRINTK=y
+CONFIG_LOCKUP_DETECTOR=y
+CONFIG_DEBUG_USER=y
+CONFIG_VIRTUALIZATION=y
+CONFIG_KVM=y
+CONFIG_KVM_ARM_HOST=y
+CONFIG_KVM_ARM_MAX_VCPUS=4
+CONFIG_KVM_ARM_VGIC=y
Signature · 1 line
1.9.1
#18 lore raw

PATCH v10 10/11 ARM: hisi: enable erratum 798181 of A15 on HiP04

In reply to Haojian Zhuang

From: Kefeng Wang <[email protected]>

The commit 93dc688 (ARM: 7684/1: errata: Workaround for Cortex-A15 erratum 798181 (TLBI/DSB operations)) introduced a workaround for Cortex-A15 erratum 798181. Enable it for HIP04(Cortex-a15 r3p2).

---
 arch/arm/mach-hisi/Kconfig | 1 +
 1 file changed, 1 insertion(+)
arch/arm/mach-hisi/Kconfig +1 -0
index a458f28..8d92e99 100644
@@ -21,6 +21,7 @@ config ARCH_HI3xxx
 
 config ARCH_HIP04
 	bool "Hisilicon HiP04 Cortex A15 family" if ARCH_MULTI_V7
+	select ARM_ERRATA_798181 if SMP
 	select HAVE_ARM_ARCH_TIMER
 	select MCPM if SMP
 	select MCPM_QUAD_CLUSTER if SMP
Signature · 1 line
1.9.1
#19 lore raw

PATCH v10 11/11 virt: arm: support hip04 gic

In reply to Haojian Zhuang

In ARM standard GIC, GICH_APR offset is 0xf0 & GICH_LR0 offset is 0x100. In HiP04 GIC, GICH_APR offset is 0x70 & GICH_LR0 offset is 0x80.

Now reuse the nr_lr field in struct vgic_cpu. Bit[31:16] is used to store GICH_APR offset in HiP04, and bit[15:0] is used to store real nr_lr variable. In ARM standard GIC, don't set bit[31:16]. So we could avoid to change the VGIC implementation in arm64.

---
 arch/arm/kernel/asm-offsets.c   |  2 +-
 arch/arm/kvm/interrupts_head.S  | 29 +++++++++++++++++++++++------
 arch/arm64/kernel/asm-offsets.c |  2 +-
 arch/arm64/kvm/hyp.S            |  4 ++--
 include/kvm/arm_vgic.h          |  7 +++++--
 include/linux/irqchip/arm-gic.h |  6 ++++++
 virt/kvm/arm/vgic.c             | 37 ++++++++++++++++++++++++++-----------
 7 files changed, 64 insertions(+), 23 deletions(-)
arch/arm/kernel/asm-offsets.c +1 -1
index 85598b5..166cc98 100644
@@ -189,7 +189,7 @@ int main(void)
   DEFINE(VGIC_CPU_ELRSR,	offsetof(struct vgic_cpu, vgic_elrsr));
   DEFINE(VGIC_CPU_APR,		offsetof(struct vgic_cpu, vgic_apr));
   DEFINE(VGIC_CPU_LR,		offsetof(struct vgic_cpu, vgic_lr));
-  DEFINE(VGIC_CPU_NR_LR,	offsetof(struct vgic_cpu, nr_lr));
+  DEFINE(VGIC_CPU_HW_CFG,	offsetof(struct vgic_cpu, hw_cfg));
 #ifdef CONFIG_KVM_ARM_TIMER
   DEFINE(VCPU_TIMER_CNTV_CTL,	offsetof(struct kvm_vcpu, arch.timer_cpu.cntv_ctl));
   DEFINE(VCPU_TIMER_CNTV_CVAL,	offsetof(struct kvm_vcpu, arch.timer_cpu.cntv_cval));
arch/arm/kvm/interrupts_head.S +23 -6
index 76af9302..9fbbf99 100644
@@ -419,7 +419,9 @@ vcpu	.req	r0		@ vcpu pointer always in r0
 	ldr	r7, [r2, #GICH_EISR1]
 	ldr	r8, [r2, #GICH_ELRSR0]
 	ldr	r9, [r2, #GICH_ELRSR1]
-	ldr	r10, [r2, #GICH_APR]
+	ldr	r10, [r11, #VGIC_CPU_HW_CFG]
+	mov	r10, r10, lsr #HWCFG_APR_SHIFT
+	ldr	r10, [r2, r10]
 
 	str	r3, [r11, #VGIC_CPU_HCR]
 	str	r4, [r11, #VGIC_CPU_VMCR]
@@ -435,9 +437,15 @@ vcpu	.req	r0		@ vcpu pointer always in r0
 	str	r5, [r2, #GICH_HCR]
 
 	/* Save list registers */
-	add	r2, r2, #GICH_LR0
+	ldr	r4, [r11, #VGIC_CPU_HW_CFG]
+	mov	r10, r4, lsr #HWCFG_APR_SHIFT
+	/* the offset between GICH_APR & GICH_LR0 is 0x10 */
+	add	r10, r10, #0x10
+	add	r2, r2, r10
 	add	r3, r11, #VGIC_CPU_LR
-	ldr	r4, [r11, #VGIC_CPU_NR_LR]
+	/* Get NR_LR from VGIC_CPU_HW_CFG */
+	ldr	r6, =HWCFG_NR_LR_MASK
+	and	r4, r4, r6
 1:	ldr	r6, [r2], #4
 	str	r6, [r3], #4
 	subs	r4, r4, #1
@@ -469,12 +477,21 @@ vcpu	.req	r0		@ vcpu pointer always in r0
 
 	str	r3, [r2, #GICH_HCR]
 	str	r4, [r2, #GICH_VMCR]
-	str	r8, [r2, #GICH_APR]
+	ldr	r6, [r11, #VGIC_CPU_HW_CFG]
+	mov	r6, r6, lsr #HWCFG_APR_SHIFT
+	str	r8, [r2, r6]
 
 	/* Restore list registers */
-	add	r2, r2, #GICH_LR0
+	ldr	r4, [r11, #VGIC_CPU_HW_CFG]
+	mov	r6, r4, lsr #HWCFG_APR_SHIFT
+	/* the offset between GICH_APR & GICH_LR0 is 0x10 */
+	add	r6, r6, #0x10
+	/* get offset of GICH_LR0 */
+	add	r2, r2, r6
+	/* Get NR_LR from VGIC_CPU_HW_CFG */
 	add	r3, r11, #VGIC_CPU_LR
-	ldr	r4, [r11, #VGIC_CPU_NR_LR]
+	ldr	r6, =HWCFG_NR_LR_MASK
+	and	r4, r4, r6
 1:	ldr	r6, [r3], #4
 	str	r6, [r2], #4
 	subs	r4, r4, #1
arch/arm64/kernel/asm-offsets.c +1 -1
index 646f888..2422358 100644
@@ -136,7 +136,7 @@ int main(void)
   DEFINE(VGIC_CPU_ELRSR,	offsetof(struct vgic_cpu, vgic_elrsr));
   DEFINE(VGIC_CPU_APR,		offsetof(struct vgic_cpu, vgic_apr));
   DEFINE(VGIC_CPU_LR,		offsetof(struct vgic_cpu, vgic_lr));
-  DEFINE(VGIC_CPU_NR_LR,	offsetof(struct vgic_cpu, nr_lr));
+  DEFINE(VGIC_CPU_HW_CFG,	offsetof(struct vgic_cpu, hw_cfg));
   DEFINE(KVM_VTTBR,		offsetof(struct kvm, arch.vttbr));
   DEFINE(KVM_VGIC_VCTRL,	offsetof(struct kvm, arch.vgic.vctrl_base));
 #endif
arch/arm64/kvm/hyp.S +2 -2
index b0d1512..2dbe337 100644
@@ -426,7 +426,7 @@ CPU_BE(	rev	w11, w11 )
 
 	/* Save list registers */
 	add	x2, x2, #GICH_LR0
-	ldr	w4, [x3, #VGIC_CPU_NR_LR]
+	ldr	w4, [x3, #VGIC_CPU_HW_CFG]
 	add	x3, x3, #VGIC_CPU_LR
 1:	ldr	w5, [x2], #4
 CPU_BE(	rev	w5, w5 )
@@ -465,7 +465,7 @@ CPU_BE(	rev	w6, w6 )
 
 	/* Restore list registers */
 	add	x2, x2, #GICH_LR0
-	ldr	w4, [x3, #VGIC_CPU_NR_LR]
+	ldr	w4, [x3, #VGIC_CPU_HW_CFG]
 	add	x3, x3, #VGIC_CPU_LR
 1:	ldr	w5, [x3], #4
 CPU_BE(	rev	w5, w5 )
include/kvm/arm_vgic.h +5 -2
index f27000f..eba4b51 100644
@@ -122,8 +122,11 @@ struct vgic_cpu {
 	/* Bitmap of used/free list registers */
 	DECLARE_BITMAP(	lr_used, VGIC_MAX_LRS);
 
-	/* Number of list registers on this CPU */
-	int		nr_lr;
+	/*
+	 * bit[31:16]: GICH_APR offset
+	 * bit[15:0]:  Number of list registers on this CPU
+	 */
+	u32		hw_cfg;
 
 	/* CPU vif control registers for world switch */
 	u32		vgic_hcr;
include/linux/irqchip/arm-gic.h +6 -0
index 45e2d8c..b055f92 100644
@@ -49,6 +49,8 @@
 #define GICH_ELRSR1 			0x34
 #define GICH_APR			0xf0
 #define GICH_LR0			0x100
+#define HIP04_GICH_APR			0x70
+/* GICH_LR0 offset in HiP04 is 0x80 */
 
 #define GICH_HCR_EN			(1 << 0)
 #define GICH_HCR_UIE			(1 << 1)
@@ -73,6 +75,10 @@
 #define GICH_MISR_EOI			(1 << 0)
 #define GICH_MISR_U			(1 << 1)
 
+#define HWCFG_NR_LR_MASK	0xffff
+#define HWCFG_APR_SHIFT		16
+#define HWCFG_APR_MASK		(0xffff << HWCFG_APR_SHIFT)
+
 #ifndef __ASSEMBLY__
 
 struct device_node;
virt/kvm/arm/vgic.c +26 -11
index 56ff9be..6c0ee89 100644
@@ -97,7 +97,7 @@ static void vgic_retire_disabled_irqs(struct kvm_vcpu *vcpu);
 static void vgic_update_state(struct kvm *kvm);
 static void vgic_kick_vcpus(struct kvm *kvm);
 static void vgic_dispatch_sgi(struct kvm_vcpu *vcpu, u32 reg);
-static u32 vgic_nr_lr;
+static u32 vgic_hw_cfg, vgic_nr_lr;
 
 static unsigned int vgic_maint_irq;
 
@@ -625,7 +625,7 @@ static void vgic_unqueue_irqs(struct kvm_vcpu *vcpu)
 	int i, irq, source_cpu;
 	u32 *lr;
 
-	for_each_set_bit(i, vgic_cpu->lr_used, vgic_cpu->nr_lr) {
+	for_each_set_bit(i, vgic_cpu->lr_used, vgic_nr_lr) {
 		lr = &vgic_cpu->vgic_lr[i];
 		irq = LR_IRQID(*lr);
 		source_cpu = LR_CPUID(*lr);
@@ -1006,7 +1006,7 @@ static void vgic_retire_disabled_irqs(struct kvm_vcpu *vcpu)
 	struct vgic_cpu *vgic_cpu = &vcpu->arch.vgic_cpu;
 	int lr;
 
-	for_each_set_bit(lr, vgic_cpu->lr_used, vgic_cpu->nr_lr) {
+	for_each_set_bit(lr, vgic_cpu->lr_used, vgic_nr_lr) {
 		int irq = vgic_cpu->vgic_lr[lr] & GICH_LR_VIRTUALID;
 
 		if (!vgic_irq_is_enabled(vcpu, irq)) {
@@ -1047,8 +1047,8 @@ static bool vgic_queue_irq(struct kvm_vcpu *vcpu, u8 sgi_source_id, int irq)
 
 	/* Try to use another LR for this interrupt */
 	lr = find_first_zero_bit((unsigned long *)vgic_cpu->lr_used,
-			       vgic_cpu->nr_lr);
-	if (lr >= vgic_cpu->nr_lr)
+				 vgic_nr_lr);
+	if (lr >= vgic_nr_lr)
 		return false;
 
 	kvm_debug("LR%d allocated for IRQ%d %x\n", lr, irq, sgi_source_id);
@@ -1183,7 +1183,7 @@ static bool vgic_process_maintenance(struct kvm_vcpu *vcpu)
 		int lr, irq;
 
 		for_each_set_bit(lr, (unsigned long *)vgic_cpu->vgic_eisr,
-				 vgic_cpu->nr_lr) {
+				 vgic_nr_lr) {
 			irq = vgic_cpu->vgic_lr[lr] & GICH_LR_VIRTUALID;
 
 			vgic_irq_clear_active(vcpu, irq);
@@ -1227,7 +1227,7 @@ static void __kvm_vgic_sync_hwstate(struct kvm_vcpu *vcpu)
 
 	/* Clear mappings for empty LRs */
 	for_each_set_bit(lr, (unsigned long *)vgic_cpu->vgic_elrsr,
-			 vgic_cpu->nr_lr) {
+			 vgic_nr_lr) {
 		int irq;
 
 		if (!test_and_clear_bit(lr, vgic_cpu->lr_used))
@@ -1241,8 +1241,8 @@ static void __kvm_vgic_sync_hwstate(struct kvm_vcpu *vcpu)
 
 	/* Check if we still have something up our sleeve... */
 	pending = find_first_zero_bit((unsigned long *)vgic_cpu->vgic_elrsr,
-				      vgic_cpu->nr_lr);
-	if (level_pending || pending < vgic_cpu->nr_lr)
+				      vgic_nr_lr);
+	if (level_pending || pending < vgic_nr_lr)
 		set_bit(vcpu->vcpu_id, &dist->irq_pending_on_cpu);
 }
 
@@ -1438,7 +1438,7 @@ int kvm_vgic_vcpu_init(struct kvm_vcpu *vcpu)
 	 */
 	vgic_cpu->vgic_vmcr = 0;
 
-	vgic_cpu->nr_lr = vgic_nr_lr;
+	vgic_cpu->hw_cfg = vgic_hw_cfg;
 	vgic_cpu->vgic_hcr = GICH_HCR_EN; /* Get the show on the road... */
 
 	return 0;
@@ -1470,17 +1470,31 @@ static struct notifier_block vgic_cpu_nb = {
 	.notifier_call = vgic_cpu_notify,
 };
 
+static const struct of_device_id of_vgic_ids[] = {
+	{
+		.compatible = "arm,cortex-a15-gic",
+		.data = (void *)GICH_APR,
+	}, {
+		.compatible = "hisilicon,hip04-gic",
+		.data = (void *)HIP04_GICH_APR,
+	}, {
+	},
+};
+
 int kvm_vgic_hyp_init(void)
 {
 	int ret;
 	struct resource vctrl_res;
 	struct resource vcpu_res;
+	const struct of_device_id *match;
 
-	vgic_node = of_find_compatible_node(NULL, NULL, "arm,cortex-a15-gic");
+	vgic_node = of_find_matching_node_and_match(NULL, of_vgic_ids, &match);
 	if (!vgic_node) {
 		kvm_err("error: no compatible vgic node in DT\n");
 		return -ENODEV;
 	}
+	/* High word of vgic_hw_cfg is the offset of GICH_APR. */
+	vgic_hw_cfg = (unsigned long)match->data << HWCFG_APR_SHIFT;
 
 	vgic_maint_irq = irq_of_parse_and_map(vgic_node, 0);
 	if (!vgic_maint_irq) {
@@ -1517,6 +1531,7 @@ int kvm_vgic_hyp_init(void)
 
 	vgic_nr_lr = readl_relaxed(vgic_vctrl_base + GICH_VTR);
 	vgic_nr_lr = (vgic_nr_lr & 0x3f) + 1;
+	vgic_hw_cfg |= vgic_nr_lr;
 
 	ret = create_hyp_io_mappings(vgic_vctrl_base,
 				     vgic_vctrl_base + resource_size(&vctrl_res),
Signature · 1 line
1.9.1