All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v15 00/12] enable Hisilicon HiP04
@ 2014-07-28 13:57 Haojian Zhuang
  2014-07-28 13:57 ` [PATCH v15 01/12] irq: gic: support hip04 gic Haojian Zhuang
                   ` (12 more replies)
  0 siblings, 13 replies; 55+ messages in thread
From: Haojian Zhuang @ 2014-07-28 13:57 UTC (permalink / raw)
  To: linux-arm-kernel

Changelog:
v15:
  * Add p04 debug uart back.
  * Refresh since hix5hd2 code updated.

v14:
  * Mount function pointers to different implementation on standard
    GICv2 and Hisilicon HiP04 GIC.

v13:
  * Restore power down operation in MCPM.
  * Fix disabling snoop filter issue in MCPM.

v12:
  * Use wfi as power down state in MCPM.
  * Remove wait_for_powerdown() in MCPM because wfi is used now.

v11:
  * Fix the protection issue on mcpm power down.
  * Clean assembly code in mcpm power up.

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 (11):
  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
  ARM: debug: add HiP04 debug uart

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/Kconfig.debug                             |  10 +
 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                      | 366 +++++++++++++++++
 arch/arm64/kernel/asm-offsets.c                    |   2 +-
 arch/arm64/kvm/hyp.S                               |   4 +-
 drivers/irqchip/irq-gic.c                          | 436 +++++++++++++++++----
 include/kvm/arm_vgic.h                             |   7 +-
 include/linux/irqchip/arm-gic.h                    |   6 +
 virt/kvm/arm/vgic.c                                |  37 +-
 23 files changed, 1588 insertions(+), 110 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

-- 
1.9.1

^ permalink raw reply	[flat|nested] 55+ messages in thread

* [PATCH v15 01/12] irq: gic: support hip04 gic
  2014-07-28 13:57 [PATCH v15 00/12] enable Hisilicon HiP04 Haojian Zhuang
@ 2014-07-28 13:57 ` Haojian Zhuang
  2014-07-28 17:38   ` Marc Zyngier
  2014-07-28 13:57 ` [PATCH v15 02/12] ARM: mcpm: support 4 clusters Haojian Zhuang
                   ` (11 subsequent siblings)
  12 siblings, 1 reply; 55+ messages in thread
From: Haojian Zhuang @ 2014-07-28 13:57 UTC (permalink / raw)
  To: linux-arm-kernel

There's some difference between ARM GICv2 and HiP04 GIC.

* HiP04 GIC could support 16 cores at most, and ARM GIC could support
8 cores at most. So the defination 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.

Changelog:
v14:
  * Mount function pointers to different implementation on standard
    GICv2 and Hisilicon HiP04 GIC.

Signed-off-by: Haojian Zhuang <haojian.zhuang@linaro.org>
---
 Documentation/devicetree/bindings/arm/gic.txt |   1 +
 drivers/irqchip/irq-gic.c                     | 436 +++++++++++++++++++++-----
 2 files changed, 350 insertions(+), 87 deletions(-)

diff --git a/Documentation/devicetree/bindings/arm/gic.txt b/Documentation/devicetree/bindings/arm/gic.txt
index 5573c08..150f7d6 100644
--- a/Documentation/devicetree/bindings/arm/gic.txt
+++ b/Documentation/devicetree/bindings/arm/gic.txt
@@ -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.
diff --git a/drivers/irqchip/irq-gic.c b/drivers/irqchip/irq-gic.c
index 508b815..b47243f 100644
--- a/drivers/irqchip/irq-gic.c
+++ b/drivers/irqchip/irq-gic.c
@@ -69,19 +69,23 @@ struct gic_chip_data {
 #ifdef CONFIG_GIC_NON_BANKED
 	void __iomem *(*get_base)(union gic_base *);
 #endif
+	void (*init_cpu_map)(void);
+	u32 (*get_cpu_map)(u32);
+	void (*set_cpu_map)(u32, u32);
+	bool (*cpu_invalid)(u32);
+	u32 (*get_cpumask)(struct gic_chip_data *);
+	void (*set_dist_target)(struct gic_chip_data *, u32, u32);
+	void (*set_dist_softint)(struct gic_chip_data *, u32, u32);
+	void (*dist_init)(struct gic_chip_data *);
+	void (*dist_save)(unsigned int);
+	void (*dist_restore)(unsigned int);
+	u32 nr_cpu_if;
+	u32 max_nr_irq;
 };
 
 static DEFINE_RAW_SPINLOCK(irq_controller_lock);
 
 /*
- * The GIC mapping of CPU interfaces does not necessarily match
- * the logical CPU numbering.  Let's use a mapping as returned
- * by the GIC itself.
- */
-#define NR_GIC_CPU_IF 8
-static u8 gic_cpu_map[NR_GIC_CPU_IF] __read_mostly;
-
-/*
  * Supported arch specific GIC irq extension.
  * Default make them NULL.
  */
@@ -222,23 +226,21 @@ static int gic_retrigger(struct irq_data *d)
 static int gic_set_affinity(struct irq_data *d, const struct cpumask *mask_val,
 			    bool force)
 {
-	void __iomem *reg = gic_dist_base(d) + GIC_DIST_TARGET + (gic_irq(d) & ~3);
-	unsigned int cpu, shift = (gic_irq(d) % 4) * 8;
-	u32 val, mask, bit;
+	struct gic_chip_data *gic_data = irq_data_get_irq_chip_data(d);
+	unsigned int cpu;
+	u32 bit;
 
 	if (!force)
 		cpu = cpumask_any_and(mask_val, cpu_online_mask);
 	else
 		cpu = cpumask_first(mask_val);
 
-	if (cpu >= NR_GIC_CPU_IF || cpu >= nr_cpu_ids)
+	if (gic_data->cpu_invalid(cpu) || cpu >= nr_cpu_ids)
 		return -EINVAL;
 
 	raw_spin_lock(&irq_controller_lock);
-	mask = 0xff << shift;
-	bit = gic_cpu_map[cpu] << shift;
-	val = readl_relaxed(reg) & ~mask;
-	writel_relaxed(val | bit, reg);
+	bit = gic_data->get_cpu_map(cpu);
+	gic_data->set_dist_target(gic_data, gic_irq(d), bit);
 	raw_spin_unlock(&irq_controller_lock);
 
 	return IRQ_SET_MASK_OK;
@@ -304,7 +306,7 @@ static void gic_handle_cascade_irq(unsigned int irq, struct irq_desc *desc)
 		goto out;
 
 	cascade_irq = irq_find_mapping(chip_data->domain, gic_irq);
-	if (unlikely(gic_irq < 32 || gic_irq > 1020))
+	if (unlikely(gic_irq < 32 || gic_irq > chip_data->max_nr_irq))
 		handle_bad_irq(cascade_irq, desc);
 	else
 		generic_handle_irq(cascade_irq);
@@ -335,69 +337,31 @@ void __init gic_cascade_irq(unsigned int gic_nr, unsigned int irq)
 	irq_set_chained_handler(irq, gic_handle_cascade_irq);
 }
 
-static u8 gic_get_cpumask(struct gic_chip_data *gic)
-{
-	void __iomem *base = gic_data_dist_base(gic);
-	u32 mask, i;
-
-	for (i = mask = 0; i < 32; i += 4) {
-		mask = readl_relaxed(base + GIC_DIST_TARGET + i);
-		mask |= mask >> 16;
-		mask |= mask >> 8;
-		if (mask)
-			break;
-	}
-
-	if (!mask)
-		pr_crit("GIC CPU mask not found - kernel will fail to boot.\n");
-
-	return mask;
-}
-
-static void __init gic_dist_init(struct gic_chip_data *gic)
-{
-	unsigned int i;
-	u32 cpumask;
-	unsigned int gic_irqs = gic->gic_irqs;
-	void __iomem *base = gic_data_dist_base(gic);
-
-	writel_relaxed(0, base + GIC_DIST_CTRL);
-
-	/*
-	 * Set all global interrupts to this CPU only.
-	 */
-	cpumask = gic_get_cpumask(gic);
-	cpumask |= cpumask << 8;
-	cpumask |= cpumask << 16;
-	for (i = 32; i < gic_irqs; i += 4)
-		writel_relaxed(cpumask, base + GIC_DIST_TARGET + i * 4 / 4);
-
-	gic_dist_config(base, gic_irqs, NULL);
-
-	writel_relaxed(1, base + GIC_DIST_CTRL);
-}
-
 static void gic_cpu_init(struct gic_chip_data *gic)
 {
 	void __iomem *dist_base = gic_data_dist_base(gic);
 	void __iomem *base = gic_data_cpu_base(gic);
 	unsigned int cpu_mask, cpu = smp_processor_id();
 	int i;
+	u32 data;
 
 	/*
 	 * Get what the GIC says our CPU mask is.
 	 */
-	BUG_ON(cpu >= NR_GIC_CPU_IF);
-	cpu_mask = gic_get_cpumask(gic);
-	gic_cpu_map[cpu] = cpu_mask;
+	BUG_ON(gic->cpu_invalid(cpu));
+	cpu_mask = gic->get_cpumask(gic);
+	gic->set_cpu_map(cpu, cpu_mask);
 
 	/*
 	 * Clear our mask from the other map entries in case they're
 	 * still undefined.
 	 */
-	for (i = 0; i < NR_GIC_CPU_IF; i++)
-		if (i != cpu)
-			gic_cpu_map[i] &= ~cpu_mask;
+	for (i = 0; i < gic->nr_cpu_if; i++) {
+		if (i != cpu) {
+			data = gic->get_cpu_map(i);
+			gic->set_cpu_map(i, data & ~cpu_mask);
+		}
+	}
 
 	gic_cpu_config(dist_base, NULL);
 
@@ -489,6 +453,70 @@ static void gic_dist_restore(unsigned int gic_nr)
 	writel_relaxed(1, dist_base + GIC_DIST_CTRL);
 }
 
+static void hip04_dist_save(unsigned int gic_nr)
+{
+	unsigned int gic_irqs;
+	void __iomem *dist_base;
+	int i;
+
+	if (gic_nr >= MAX_GIC_NR)
+		BUG();
+
+	gic_irqs = gic_data[gic_nr].gic_irqs;
+	dist_base = gic_data_dist_base(&gic_data[gic_nr]);
+
+	if (!dist_base)
+		return;
+
+	for (i = 0; i < DIV_ROUND_UP(gic_irqs, 16); i++)
+		gic_data[gic_nr].saved_spi_conf[i] =
+			readl_relaxed(dist_base + GIC_DIST_CONFIG + i * 4);
+
+	for (i = 0; i < DIV_ROUND_UP(gic_irqs, 2); i++)
+		gic_data[gic_nr].saved_spi_target[i] =
+			readl_relaxed(dist_base + GIC_DIST_TARGET + i * 2);
+
+	for (i = 0; i < DIV_ROUND_UP(gic_irqs, 32); i++)
+		gic_data[gic_nr].saved_spi_enable[i] =
+			readl_relaxed(dist_base + GIC_DIST_ENABLE_SET + i * 4);
+}
+
+static void hip04_dist_restore(unsigned int gic_nr)
+{
+	unsigned int gic_irqs;
+	unsigned int i;
+	void __iomem *dist_base;
+
+	if (gic_nr >= MAX_GIC_NR)
+		BUG();
+
+	gic_irqs = gic_data[gic_nr].gic_irqs;
+	dist_base = gic_data_dist_base(&gic_data[gic_nr]);
+
+	if (!dist_base)
+		return;
+
+	writel_relaxed(0, dist_base + GIC_DIST_CTRL);
+
+	for (i = 0; i < DIV_ROUND_UP(gic_irqs, 16); i++)
+		writel_relaxed(gic_data[gic_nr].saved_spi_conf[i],
+			dist_base + GIC_DIST_CONFIG + i * 4);
+
+	for (i = 0; i < DIV_ROUND_UP(gic_irqs, 4); i++)
+		writel_relaxed(0xa0a0a0a0,
+			dist_base + GIC_DIST_PRI + i * 4);
+
+	for (i = 0; i < DIV_ROUND_UP(gic_irqs, 2); i++)
+		writel_relaxed(gic_data[gic_nr].saved_spi_target[i],
+			dist_base + GIC_DIST_TARGET + i * 2);
+
+	for (i = 0; i < DIV_ROUND_UP(gic_irqs, 32); i++)
+		writel_relaxed(gic_data[gic_nr].saved_spi_enable[i],
+			dist_base + GIC_DIST_ENABLE_SET + i * 4);
+
+	writel_relaxed(1, dist_base + GIC_DIST_CTRL);
+}
+
 static void gic_cpu_save(unsigned int gic_nr)
 {
 	int i;
@@ -565,11 +593,11 @@ static int gic_notifier(struct notifier_block *self, unsigned long cmd,	void *v)
 			gic_cpu_restore(i);
 			break;
 		case CPU_CLUSTER_PM_ENTER:
-			gic_dist_save(i);
+			gic_data[i].dist_save(i);
 			break;
 		case CPU_CLUSTER_PM_ENTER_FAILED:
 		case CPU_CLUSTER_PM_EXIT:
-			gic_dist_restore(i);
+			gic_data[i].dist_restore(i);
 			break;
 		}
 	}
@@ -610,7 +638,7 @@ static void gic_raise_softirq(const struct cpumask *mask, unsigned int irq)
 
 	/* Convert our logical CPU mask into a physical one. */
 	for_each_cpu(cpu, mask)
-		map |= gic_cpu_map[cpu];
+		map |= gic_data[0].get_cpu_map(cpu);
 
 	/*
 	 * Ensure that stores to Normal memory are visible to the
@@ -619,7 +647,7 @@ static void gic_raise_softirq(const struct cpumask *mask, unsigned int irq)
 	dmb(ishst);
 
 	/* this always happens on GIC0 */
-	writel_relaxed(map << 16 | irq, gic_data_dist_base(&gic_data[0]) + GIC_DIST_SOFTINT);
+	gic_data[0].set_dist_softint(&gic_data[0], irq, map);
 
 	raw_spin_unlock_irqrestore(&irq_controller_lock, flags);
 }
@@ -634,10 +662,9 @@ static void gic_raise_softirq(const struct cpumask *mask, unsigned int irq)
  */
 void gic_send_sgi(unsigned int cpu_id, unsigned int irq)
 {
-	BUG_ON(cpu_id >= NR_GIC_CPU_IF);
-	cpu_id = 1 << cpu_id;
+	BUG_ON(gic_data[0].cpu_invalid(cpu_id));
 	/* this always happens on GIC0 */
-	writel_relaxed((cpu_id << 16) | irq, gic_data_dist_base(&gic_data[0]) + GIC_DIST_SOFTINT);
+	gic_data[0].set_dist_softint(&gic_data[0], irq, 1 << cpu_id);
 }
 
 /*
@@ -653,9 +680,9 @@ int gic_get_cpu_id(unsigned int cpu)
 {
 	unsigned int cpu_bit;
 
-	if (cpu >= NR_GIC_CPU_IF)
+	if (gic_data[0].cpu_invalid(cpu))
 		return -1;
-	cpu_bit = gic_cpu_map[cpu];
+	cpu_bit = gic_data[0].get_cpu_map(cpu);
 	if (cpu_bit & (cpu_bit - 1))
 		return -1;
 	return __ffs(cpu_bit);
@@ -673,6 +700,7 @@ int gic_get_cpu_id(unsigned int cpu)
  */
 void gic_migrate_target(unsigned int new_cpu_id)
 {
+	struct gic_chip_data *gic = &gic_data[gic_nr];
 	unsigned int cur_cpu_id, gic_irqs, gic_nr = 0;
 	void __iomem *dist_base;
 	int i, ror_val, cpu = smp_processor_id();
@@ -681,19 +709,19 @@ void gic_migrate_target(unsigned int new_cpu_id)
 	if (gic_nr >= MAX_GIC_NR)
 		BUG();
 
-	dist_base = gic_data_dist_base(&gic_data[gic_nr]);
+	dist_base = gic_data_dist_base(gic);
 	if (!dist_base)
 		return;
-	gic_irqs = gic_data[gic_nr].gic_irqs;
+	gic_irqs = gic->gic_irqs;
 
-	cur_cpu_id = __ffs(gic_cpu_map[cpu]);
+	cur_cpu_id = __ffs(gic->get_cpu_map(cpu));
 	cur_target_mask = 0x01010101 << cur_cpu_id;
 	ror_val = (cur_cpu_id - new_cpu_id) & 31;
 
 	raw_spin_lock(&irq_controller_lock);
 
 	/* Update the target interface for this logical CPU */
-	gic_cpu_map[cpu] = 1 << new_cpu_id;
+	gic_data->set_cpu_map(cpu, 1 << new_cpu_id);
 
 	/*
 	 * Find all the peripheral interrupts targetting the current
@@ -730,8 +758,7 @@ void gic_migrate_target(unsigned int new_cpu_id)
 		writel_relaxed(val, dist_base + GIC_DIST_SGI_PENDING_CLEAR + i);
 		for (j = i; j < i + 4; j++) {
 			if (val & 0xff)
-				writel_relaxed((1 << (new_cpu_id + 16)) | j,
-						dist_base + GIC_DIST_SOFTINT);
+				gic->set_dist_softint(gic, j, 1 << new_cpu_id);
 			val >>= 8;
 		}
 	}
@@ -883,7 +910,7 @@ void __init gic_init_bases(unsigned int gic_nr, int irq_start,
 {
 	irq_hw_number_t hwirq_base;
 	struct gic_chip_data *gic;
-	int gic_irqs, irq_base, i;
+	int gic_irqs, irq_base;
 	int nr_routable_irqs;
 
 	BUG_ON(gic_nr >= MAX_GIC_NR);
@@ -924,8 +951,7 @@ void __init gic_init_bases(unsigned int gic_nr, int irq_start,
 	 * Initialize the CPU interface map to all CPUs.
 	 * It will be refined as each CPU probes its ID.
 	 */
-	for (i = 0; i < NR_GIC_CPU_IF; i++)
-		gic_cpu_map[i] = 0xff;
+	gic->init_cpu_map();
 
 	/*
 	 * For primary GICs, skip over SGIs.
@@ -941,12 +967,13 @@ void __init gic_init_bases(unsigned int gic_nr, int irq_start,
 
 	/*
 	 * Find out how many interrupts are supported.
-	 * The GIC only supports up to 1020 interrupt sources.
+	 * The ARM/Qualcomm GIC only supports up to 1020 interrupt sources.
+	 * The HiP04 GIC only supports up to 510 interrupt sources.
 	 */
 	gic_irqs = readl_relaxed(gic_data_dist_base(gic) + GIC_DIST_CTR) & 0x1f;
 	gic_irqs = (gic_irqs + 1) * 32;
-	if (gic_irqs > 1020)
-		gic_irqs = 1020;
+	if (gic_irqs > gic->max_nr_irq)
+		gic_irqs = gic->max_nr_irq;
 	gic->gic_irqs = gic_irqs;
 
 	gic_irqs -= hwirq_base; /* calculate # of irqs to allocate */
@@ -981,7 +1008,7 @@ void __init gic_init_bases(unsigned int gic_nr, int irq_start,
 	}
 
 	gic_chip.flags |= gic_arch_extn.flags;
-	gic_dist_init(gic);
+	gic->dist_init(gic);
 	gic_cpu_init(gic);
 	gic_pm_init(gic);
 }
@@ -989,6 +1016,98 @@ void __init gic_init_bases(unsigned int gic_nr, int irq_start,
 #ifdef CONFIG_OF
 static int gic_cnt __initdata;
 
+/*
+ * The GIC mapping of CPU interfaces does not necessarily match
+ * the logical CPU numbering.  Let's use a mapping as returned
+ * by the GIC itself.
+ */
+#define NR_GIC_CPU_IF 8
+static u8 gic_cpu_map[NR_GIC_CPU_IF] __read_mostly;
+
+static void gic_init_cpu_map(void)
+{
+	int i;
+	for (i = 0; i < NR_GIC_CPU_IF; i++)
+		gic_cpu_map[i] = 0xff;
+}
+
+static u32 gic_get_cpu_map(u32 i)
+{
+	return gic_cpu_map[i];
+}
+
+static void gic_set_cpu_map(u32 i, u32 data)
+{
+	gic_cpu_map[i] = data & 0xff;
+}
+
+static bool gic_cpu_invalid(u32 cpu)
+{
+	return cpu >= NR_GIC_CPU_IF;
+}
+
+static u32 gic_get_cpumask(struct gic_chip_data *gic)
+{
+	void __iomem *base = gic_data_dist_base(gic);
+	u32 mask, i;
+
+	for (i = mask = 0; i < 32; i += 4) {
+		mask = readl_relaxed(base + GIC_DIST_TARGET + i);
+		mask |= mask >> 16;
+		mask |= mask >> 8;
+		if (mask)
+			break;
+	}
+
+	if (!mask)
+		pr_crit("GIC CPU mask not found - kernel will fail to boot.\n");
+
+	return mask & 0xff;
+}
+
+static void gic_set_dist_target(struct gic_chip_data *gic, u32 irq, u32 data)
+{
+	void __iomem *base = gic_data_dist_base(gic);
+	u32 val, mask, offset, shift = (irq % 4) * 8;
+
+	mask = 0xff << shift;
+	offset = irq & ~3U;
+	val = readl_relaxed(base + GIC_DIST_TARGET + offset) & ~mask;
+	val |= data << shift;
+	writel_relaxed(val, base + GIC_DIST_TARGET + offset);
+}
+
+static void gic_set_dist_softint(struct gic_chip_data *gic, u32 irq, u32 data)
+{
+	void __iomem *base = gic_data_dist_base(gic);
+
+	data = data << 16;
+	writel_relaxed(data | irq, base + GIC_DIST_SOFTINT);
+}
+
+static void gic_dist_init(struct gic_chip_data *gic)
+{
+	unsigned int i;
+	u32 cpumask;
+	unsigned int gic_irqs = gic->gic_irqs;
+	void __iomem *base = gic_data_dist_base(gic);
+
+	writel_relaxed(0, base + GIC_DIST_CTRL);
+
+	/*
+	 * Set all global interrupts to this CPU only.
+	 */
+	cpumask = gic_get_cpumask(gic);
+	cpumask |= cpumask << 8;
+	cpumask |= cpumask << 16;
+	for (i = 32; i < gic_irqs; i += 4)
+		writel_relaxed(cpumask, base + GIC_DIST_TARGET + i * 4 / 4);
+
+	gic_dist_config(base, gic_irqs, NULL);
+
+	writel_relaxed(1, base + GIC_DIST_CTRL);
+}
+
 static int __init
 gic_of_init(struct device_node *node, struct device_node *parent)
 {
@@ -1009,6 +1128,148 @@ gic_of_init(struct device_node *node, struct device_node *parent)
 	if (of_property_read_u32(node, "cpu-offset", &percpu_offset))
 		percpu_offset = 0;
 
+	gic_data[gic_cnt].nr_cpu_if = 8;
+	gic_data[gic_cnt].init_cpu_map = gic_init_cpu_map;
+	gic_data[gic_cnt].get_cpu_map = gic_get_cpu_map;
+	gic_data[gic_cnt].set_cpu_map = gic_set_cpu_map;
+	gic_data[gic_cnt].cpu_invalid = gic_cpu_invalid;
+	gic_data[gic_cnt].get_cpumask = gic_get_cpumask;
+	gic_data[gic_cnt].dist_init = gic_dist_init;
+	gic_data[gic_cnt].dist_save = gic_dist_save;
+	gic_data[gic_cnt].dist_restore = gic_dist_restore;
+	gic_data[gic_cnt].set_dist_target = gic_set_dist_target;
+	gic_data[gic_cnt].set_dist_softint = gic_set_dist_softint;
+	gic_data[gic_cnt].max_nr_irq = 1020;
+	gic_init_bases(gic_cnt, -1, dist_base, cpu_base, percpu_offset, node);
+	if (!gic_cnt)
+		gic_init_physaddr(node);
+
+	if (parent) {
+		irq = irq_of_parse_and_map(node, 0);
+		gic_cascade_irq(gic_cnt, irq);
+	}
+	gic_cnt++;
+	return 0;
+}
+
+/* HiP04 extends the number of CPU interface from 8 to 16 */
+#define NR_HIP04_CPU_IF	16
+static u16 hip04_cpu_map[NR_HIP04_CPU_IF] __read_mostly;
+
+static void hip04_init_cpu_map(void)
+{
+	int i;
+	for (i = 0; i < NR_HIP04_CPU_IF; i++)
+		hip04_cpu_map[i] = 0xffff;
+}
+
+static u32 hip04_get_cpu_map(u32 i)
+{
+	return hip04_cpu_map[i];
+}
+
+static void hip04_set_cpu_map(u32 i, u32 data)
+{
+	hip04_cpu_map[i] = data & 0xffff;
+}
+
+static bool hip04_cpu_invalid(u32 cpu)
+{
+	return cpu >= NR_HIP04_CPU_IF;
+}
+
+static u32 hip04_get_cpumask(struct gic_chip_data *gic)
+{
+	void __iomem *base = gic_data_dist_base(gic);
+	u32 mask, i;
+
+	for (i = mask = 0; i < 32; i += 2) {
+		mask = readl_relaxed(base + GIC_DIST_TARGET + i * 2);
+		mask |= mask >> 16;
+		if (mask)
+			break;
+	}
+
+	if (!mask)
+		pr_crit("GIC CPU mask not found - kernel will fail to boot.\n");
+
+	return mask & 0xffff;
+}
+
+static void hip04_set_dist_target(struct gic_chip_data *gic, u32 irq, u32 data)
+{
+	void __iomem *base = gic_data_dist_base(gic);
+	u32 val, mask, offset, shift = (irq % 2) * 16;
+
+	mask = 0xffff << shift;
+	offset = (irq * 2) & ~3U;
+	val = readl_relaxed(base + GIC_DIST_TARGET + offset) & ~mask;
+	val |= data << shift;
+	writel_relaxed(val, base + GIC_DIST_TARGET + offset);
+}
+
+static void hip04_set_dist_softint(struct gic_chip_data *gic, u32 irq, u32 data)
+{
+	void __iomem *base = gic_data_dist_base(gic);
+
+	data = data << 8;
+	writel_relaxed(data | irq, base + GIC_DIST_SOFTINT);
+}
+
+static void hip04_dist_init(struct gic_chip_data *gic)
+{
+	unsigned int i;
+	u32 cpumask;
+	unsigned int gic_irqs = gic->gic_irqs;
+	void __iomem *base = gic_data_dist_base(gic);
+
+	writel_relaxed(0, base + GIC_DIST_CTRL);
+
+	/*
+	 * Set all global interrupts to this CPU only.
+	 */
+	cpumask = hip04_get_cpumask(gic);
+	cpumask |= cpumask << 16;
+	for (i = 32; i < gic_irqs; i += 2)
+		writel_relaxed(cpumask, base + GIC_DIST_TARGET + i * 2);
+
+	gic_dist_config(base, gic_irqs, NULL);
+
+	writel_relaxed(1, base + GIC_DIST_CTRL);
+}
+
+static int __init
+hip04_of_init(struct device_node *node, struct device_node *parent)
+{
+	void __iomem *cpu_base;
+	void __iomem *dist_base;
+	u32 percpu_offset;
+	int irq;
+
+	if (WARN_ON(!node))
+		return -ENODEV;
+
+	dist_base = of_iomap(node, 0);
+	WARN(!dist_base, "unable to map gic dist registers\n");
+
+	cpu_base = of_iomap(node, 1);
+	WARN(!cpu_base, "unable to map gic cpu registers\n");
+
+	if (of_property_read_u32(node, "cpu-offset", &percpu_offset))
+		percpu_offset = 0;
+
+	gic_data[gic_cnt].nr_cpu_if = 16;
+	gic_data[gic_cnt].init_cpu_map = hip04_init_cpu_map;
+	gic_data[gic_cnt].get_cpu_map = hip04_get_cpu_map;
+	gic_data[gic_cnt].set_cpu_map = hip04_set_cpu_map;
+	gic_data[gic_cnt].cpu_invalid = hip04_cpu_invalid;
+	gic_data[gic_cnt].get_cpumask = hip04_get_cpumask;
+	gic_data[gic_cnt].dist_init = hip04_dist_init;
+	gic_data[gic_cnt].dist_save = hip04_dist_save;
+	gic_data[gic_cnt].dist_restore = hip04_dist_restore;
+	gic_data[gic_cnt].set_dist_target = hip04_set_dist_target;
+	gic_data[gic_cnt].set_dist_softint = hip04_set_dist_softint;
+	gic_data[gic_cnt].max_nr_irq = 510;
 	gic_init_bases(gic_cnt, -1, dist_base, cpu_base, percpu_offset, node);
 	if (!gic_cnt)
 		gic_init_physaddr(node);
@@ -1022,6 +1283,7 @@ gic_of_init(struct device_node *node, struct device_node *parent)
 }
 IRQCHIP_DECLARE(cortex_a15_gic, "arm,cortex-a15-gic", gic_of_init);
 IRQCHIP_DECLARE(cortex_a9_gic, "arm,cortex-a9-gic", gic_of_init);
+IRQCHIP_DECLARE(hip04_gic, "hisilicon,hip04-gic", hip04_of_init);
 IRQCHIP_DECLARE(msm_8660_qgic, "qcom,msm-8660-qgic", gic_of_init);
 IRQCHIP_DECLARE(msm_qgic2, "qcom,msm-qgic2", gic_of_init);
 
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 55+ messages in thread

* [PATCH v15 02/12] ARM: mcpm: support 4 clusters
  2014-07-28 13:57 [PATCH v15 00/12] enable Hisilicon HiP04 Haojian Zhuang
  2014-07-28 13:57 ` [PATCH v15 01/12] irq: gic: support hip04 gic Haojian Zhuang
@ 2014-07-28 13:57 ` Haojian Zhuang
  2014-07-28 13:57 ` [PATCH v15 03/12] ARM: hisi: enable MCPM implementation Haojian Zhuang
                   ` (10 subsequent siblings)
  12 siblings, 0 replies; 55+ messages in thread
From: Haojian Zhuang @ 2014-07-28 13:57 UTC (permalink / raw)
  To: linux-arm-kernel

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

Signed-off-by: Haojian Zhuang <haojian.zhuang@linaro.org>
Reviewed-by: Nicolas Pitre <nico@linaro.org>
---
 arch/arm/Kconfig            | 9 +++++++++
 arch/arm/include/asm/mcpm.h | 5 +++++
 2 files changed, 14 insertions(+)

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 87b63fd..10cc6ec 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -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
diff --git a/arch/arm/include/asm/mcpm.h b/arch/arm/include/asm/mcpm.h
index d9702eb..a4fbacc 100644
--- a/arch/arm/include/asm/mcpm.h
+++ b/arch/arm/include/asm/mcpm.h
@@ -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__
 
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 55+ messages in thread

* [PATCH v15 03/12] ARM: hisi: enable MCPM implementation
  2014-07-28 13:57 [PATCH v15 00/12] enable Hisilicon HiP04 Haojian Zhuang
  2014-07-28 13:57 ` [PATCH v15 01/12] irq: gic: support hip04 gic Haojian Zhuang
  2014-07-28 13:57 ` [PATCH v15 02/12] ARM: mcpm: support 4 clusters Haojian Zhuang
@ 2014-07-28 13:57 ` Haojian Zhuang
  2014-07-28 13:57 ` [PATCH v15 04/12] ARM: hisi: enable HiP04 Haojian Zhuang
                   ` (9 subsequent siblings)
  12 siblings, 0 replies; 55+ messages in thread
From: Haojian Zhuang @ 2014-07-28 13:57 UTC (permalink / raw)
  To: linux-arm-kernel

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

Changelog:
v13:
  * Restore power down operation in MCPM.
  * Fix disabling snoop filter issue in MCPM.
v12:
  * Use wfi as power down state in MCPM.
  * Remove wait_for_powerdown() in MCPM because wfi is used now.

Signed-off-by: Haojian Zhuang <haojian.zhuang@linaro.org>
---
 arch/arm/mach-hisi/Makefile   |   1 +
 arch/arm/mach-hisi/platmcpm.c | 366 ++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 367 insertions(+)
 create mode 100644 arch/arm/mach-hisi/platmcpm.c

diff --git a/arch/arm/mach-hisi/Makefile b/arch/arm/mach-hisi/Makefile
index ee2506b..d64831e 100644
--- a/arch/arm/mach-hisi/Makefile
+++ b/arch/arm/mach-hisi/Makefile
@@ -3,4 +3,5 @@
 #
 
 obj-y	+= hisilicon.o
+obj-$(CONFIG_MCPM)		+= platmcpm.o
 obj-$(CONFIG_SMP)		+= platsmp.o hotplug.o headsmp.o
diff --git a/arch/arm/mach-hisi/platmcpm.c b/arch/arm/mach-hisi/platmcpm.c
new file mode 100644
index 0000000..9538ba3
--- /dev/null
+++ b/arch/arm/mach-hisi/platmcpm.c
@@ -0,0 +1,366 @@
+/*
+ * 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 void hip04_set_snoop_filter(unsigned int cluster, unsigned int on)
+{
+	unsigned long data;
+
+	if (!fabric)
+		BUG();
+	data = readl_relaxed(fabric + FAB_SF_MODE);
+	if (on)
+		data |= 1 << cluster;
+	else
+		data &= ~(1 << cluster);
+	writel_relaxed(data, fabric + FAB_SF_MODE);
+	while (1) {
+		if (data == readl_relaxed(fabric + FAB_SF_MODE))
+			break;
+	}
+	return;
+}
+
+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])
+		goto out;
+
+	/* Make secondary core out of reset. */
+	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);
+	}
+
+	data = CORE_RESET_BIT(cpu) | NEON_RESET_BIT(cpu) | \
+	       CORE_DEBUG_RESET_BIT(cpu);
+	writel_relaxed(data, sysctrl + SC_CPU_RESET_DREQ(cluster));
+out:
+	hip04_cpu_table[cluster][cpu]++;
+	spin_unlock_irq(&boot_lock);
+
+	return 0;
+}
+
+static void hip04_mcpm_power_down(void)
+{
+	unsigned int mpidr, cpu, cluster;
+	bool skip_wfi = 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_wfi = 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);
+
+	if (!skip_wfi)
+		wfi();
+}
+
+static int hip04_mcpm_wait_for_powerdown(unsigned int cpu, unsigned int cluster)
+{
+	unsigned int data, tries, count;
+
+	BUG_ON(cluster >= HIP04_MAX_CLUSTERS ||
+	       cpu >= HIP04_MAX_CPUS_PER_CLUSTER);
+
+	count = TIMEOUT_MSEC / POLL_MSEC;
+	spin_lock(&boot_lock);
+	for (tries = 0; tries < count; tries++) {
+		data = readl_relaxed(sysctrl + SC_CPU_RESET_STATUS(cluster));
+		if (!(data & CORE_WFI_STATUS(cpu))) {
+			msleep(POLL_MSEC);
+			continue;
+		}
+	}
+	if (tries >= count)
+		goto err;
+	data = CORE_RESET_BIT(cpu) | NEON_RESET_BIT(cpu) | \
+	       CORE_DEBUG_RESET_BIT(cpu);
+	writel_relaxed(data, sysctrl + SC_CPU_RESET_REQ(cluster));
+	for (tries = 0; tries < count; tries++) {
+		data = readl_relaxed(sysctrl + SC_CPU_RESET_STATUS(cluster));
+		if (!(data & CORE_RESET_STATUS(cpu))) {
+			msleep(POLL_MSEC);
+			continue;
+		}
+	}
+	if (tries >= count)
+		goto err;
+	if (hip04_cluster_down(cluster))
+		hip04_set_snoop_filter(cluster, 0);
+	spin_unlock(&boot_lock);
+	return 0;
+err:
+	spin_unlock(&boot_lock);
+	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"
+"	cmp	r0, #0			\n"
+"	bxeq	lr			\n"
+	/* calculate fabric phys address */
+"	adr	r2, 2f			\n"
+"	ldmia	r2, {r1, r3}		\n"
+"	sub	r0, r2, r1		\n"
+"	ldr	r2, [r0, r3]		\n"
+	/* get cluster id from MPIDR */
+"	mrc	p15, 0, r0, c0, c0, 5	\n"
+"	ubfx	r1, r0, #8, #8		\n"
+	/* 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"
+"	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"
+	);
+}
+
+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_set_snoop_filter(0, 1);
+	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

^ permalink raw reply related	[flat|nested] 55+ messages in thread

* [PATCH v15 04/12] ARM: hisi: enable HiP04
  2014-07-28 13:57 [PATCH v15 00/12] enable Hisilicon HiP04 Haojian Zhuang
                   ` (2 preceding siblings ...)
  2014-07-28 13:57 ` [PATCH v15 03/12] ARM: hisi: enable MCPM implementation Haojian Zhuang
@ 2014-07-28 13:57 ` Haojian Zhuang
  2014-07-28 14:38   ` Arnd Bergmann
  2014-07-28 13:57 ` [PATCH v15 05/12] document: dt: add the binding on HiP04 Haojian Zhuang
                   ` (8 subsequent siblings)
  12 siblings, 1 reply; 55+ messages in thread
From: Haojian Zhuang @ 2014-07-28 13:57 UTC (permalink / raw)
  To: linux-arm-kernel

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

Signed-off-by: Haojian Zhuang <haojian.zhuang@linaro.org>
---
 arch/arm/mach-hisi/Kconfig     | 8 ++++++++
 arch/arm/mach-hisi/hisilicon.c | 9 +++++++++
 2 files changed, 17 insertions(+)

diff --git a/arch/arm/mach-hisi/Kconfig b/arch/arm/mach-hisi/Kconfig
index 9848829..2a36fb7 100644
--- a/arch/arm/mach-hisi/Kconfig
+++ b/arch/arm/mach-hisi/Kconfig
@@ -22,6 +22,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
diff --git a/arch/arm/mach-hisi/hisilicon.c b/arch/arm/mach-hisi/hisilicon.c
index f37fb65..5b8c11f 100644
--- a/arch/arm/mach-hisi/hisilicon.c
+++ b/arch/arm/mach-hisi/hisilicon.c
@@ -65,3 +65,12 @@ static const char *hix5hd2_compat[] __initconst = {
 DT_MACHINE_START(HIX5HD2_DT, "Hisilicon HIX5HD2 (Flattened Device Tree)")
 	.dt_compat	= hix5hd2_compat,
 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
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 55+ messages in thread

* [PATCH v15 05/12] document: dt: add the binding on HiP04
  2014-07-28 13:57 [PATCH v15 00/12] enable Hisilicon HiP04 Haojian Zhuang
                   ` (3 preceding siblings ...)
  2014-07-28 13:57 ` [PATCH v15 04/12] ARM: hisi: enable HiP04 Haojian Zhuang
@ 2014-07-28 13:57 ` Haojian Zhuang
  2014-07-28 14:41   ` Arnd Bergmann
  2014-07-28 13:57 ` [PATCH v15 06/12] document: dt: add the binding on HiP04 clock Haojian Zhuang
                   ` (7 subsequent siblings)
  12 siblings, 1 reply; 55+ messages in thread
From: Haojian Zhuang @ 2014-07-28 13:57 UTC (permalink / raw)
  To: linux-arm-kernel

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

Signed-off-by: Haojian Zhuang <haojian.zhuang@linaro.org>
---
 .../devicetree/bindings/arm/hisilicon/hisilicon.txt | 21 +++++++++++++++++++++
 1 file changed, 21 insertions(+)

diff --git a/Documentation/devicetree/bindings/arm/hisilicon/hisilicon.txt b/Documentation/devicetree/bindings/arm/hisilicon/hisilicon.txt
index 934f000..eca605a 100644
--- a/Documentation/devicetree/bindings/arm/hisilicon/hisilicon.txt
+++ b/Documentation/devicetree/bindings/arm/hisilicon/hisilicon.txt
@@ -5,6 +5,11 @@ Hi4511 Board
 Required root node properties:
 	- compatible = "hisilicon,hi3620-hi4511";
 
+HiP04 D01 Board
+Required root node properties:
+	- compatible = "hisilicon,hip04-d01";
+
+
 Hisilicon system controller
 
 Required properties:
@@ -19,6 +24,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:
 
@@ -55,3 +69,10 @@ Example:
 		compatible = "hisilicon,pctrl";
 		reg = <0xfca09000 0x1000>;
 	};
+
+-----------------------------------------------------------------------
+Fabric:
+
+Required Properties:
+- compatible: "hisilicon,hip04-fabric";
+- reg: Address and size of Fabric
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 55+ messages in thread

* [PATCH v15 06/12] document: dt: add the binding on HiP04 clock
  2014-07-28 13:57 [PATCH v15 00/12] enable Hisilicon HiP04 Haojian Zhuang
                   ` (4 preceding siblings ...)
  2014-07-28 13:57 ` [PATCH v15 05/12] document: dt: add the binding on HiP04 Haojian Zhuang
@ 2014-07-28 13:57 ` Haojian Zhuang
  2014-07-28 17:54   ` Mark Rutland
  2014-07-28 13:57 ` [PATCH v15 07/12] ARM: dts: append hip04 dts Haojian Zhuang
                   ` (6 subsequent siblings)
  12 siblings, 1 reply; 55+ messages in thread
From: Haojian Zhuang @ 2014-07-28 13:57 UTC (permalink / raw)
  To: linux-arm-kernel

The DT binding for Hisilicon HiP04 clock driver.

Signed-off-by: Haojian Zhuang <haojian.zhuang@linaro.org>
---
 .../devicetree/bindings/clock/hip04-clock.txt        | 20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/clock/hip04-clock.txt

diff --git a/Documentation/devicetree/bindings/clock/hip04-clock.txt b/Documentation/devicetree/bindings/clock/hip04-clock.txt
new file mode 100644
index 0000000..4d31ae3
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/hip04-clock.txt
@@ -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>.
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 55+ messages in thread

* [PATCH v15 07/12] ARM: dts: append hip04 dts
  2014-07-28 13:57 [PATCH v15 00/12] enable Hisilicon HiP04 Haojian Zhuang
                   ` (5 preceding siblings ...)
  2014-07-28 13:57 ` [PATCH v15 06/12] document: dt: add the binding on HiP04 clock Haojian Zhuang
@ 2014-07-28 13:57 ` Haojian Zhuang
  2014-07-28 18:06   ` Mark Rutland
  2014-07-28 13:57 ` [PATCH v15 08/12] ARM: config: append lpae configuration Haojian Zhuang
                   ` (5 subsequent siblings)
  12 siblings, 1 reply; 55+ messages in thread
From: Haojian Zhuang @ 2014-07-28 13:57 UTC (permalink / raw)
  To: linux-arm-kernel

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

Signed-off-by: Haojian Zhuang <haojian.zhuang@linaro.org>
---
 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

diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
index 721525e..6587bbf 100644
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
@@ -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 \
diff --git a/arch/arm/boot/dts/hip04-d01.dts b/arch/arm/boot/dts/hip04-d01.dts
new file mode 100644
index 0000000..661c8e5
--- /dev/null
+++ b/arch/arm/boot/dts/hip04-d01.dts
@@ -0,0 +1,39 @@
+/*
+ *  Copyright (C) 2013-2014 Linaro Ltd.
+ *  Author: Haojian Zhuang <haojian.zhuang@linaro.org>
+ *
+ *  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";
+		};
+	};
+};
diff --git a/arch/arm/boot/dts/hip04.dtsi b/arch/arm/boot/dts/hip04.dtsi
new file mode 100644
index 0000000..30942be
--- /dev/null
+++ b/arch/arm/boot/dts/hip04.dtsi
@@ -0,0 +1,267 @@
+/*
+ * Hisilicon Ltd. HiP04 SoC
+ *
+ * Copyright (C) 2013-2014 Hisilicon Ltd.
+ * Copyright (C) 2013-2014 Linaro Ltd.
+ *
+ * Author: Haojian Zhuang <haojian.zhuang@linaro.org>
+ *
+ * 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.
+ */
+
+#include <dt-bindings/clock/hip04-clock.h>
+
+/ {
+	/* memory bus is 64-bit */
+	#address-cells = <2>;
+	#size-cells = <2>;
+
+	aliases {
+		serial0 = &uart0;
+	};
+
+	cpus {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		cpu-map {
+			cluster0 {
+				core0 {
+					cpu = <&CPU0>;
+				};
+				core1 {
+					cpu = <&CPU1>;
+				};
+				core2 {
+					cpu = <&CPU2>;
+				};
+				core3 {
+					cpu = <&CPU3>;
+				};
+			};
+			cluster1 {
+				core0 {
+					cpu = <&CPU4>;
+				};
+				core1 {
+					cpu = <&CPU5>;
+				};
+				core2 {
+					cpu = <&CPU6>;
+				};
+				core3 {
+					cpu = <&CPU7>;
+				};
+			};
+			cluster2 {
+				core0 {
+					cpu = <&CPU8>;
+				};
+				core1 {
+					cpu = <&CPU9>;
+				};
+				core2 {
+					cpu = <&CPU10>;
+				};
+				core3 {
+					cpu = <&CPU11>;
+				};
+			};
+			cluster3 {
+				core0 {
+					cpu = <&CPU12>;
+				};
+				core1 {
+					cpu = <&CPU13>;
+				};
+				core2 {
+					cpu = <&CPU14>;
+				};
+				core3 {
+					cpu = <&CPU15>;
+				};
+			};
+		};
+		CPU0: cpu at 0 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a15";
+			reg = <0>;
+		};
+		CPU1: cpu at 1 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a15";
+			reg = <1>;
+		};
+		CPU2: cpu at 2 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a15";
+			reg = <2>;
+		};
+		CPU3: cpu at 3 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a15";
+			reg = <3>;
+		};
+		CPU4: cpu at 100 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a15";
+			reg = <0x100>;
+		};
+		CPU5: cpu at 101 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a15";
+			reg = <0x101>;
+		};
+		CPU6: cpu at 102 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a15";
+			reg = <0x102>;
+		};
+		CPU7: cpu at 103 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a15";
+			reg = <0x103>;
+		};
+		CPU8: cpu at 200 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a15";
+			reg = <0x200>;
+		};
+		CPU9: cpu at 201 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a15";
+			reg = <0x201>;
+		};
+		CPU10: cpu at 202 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a15";
+			reg = <0x202>;
+		};
+		CPU11: cpu at 203 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a15";
+			reg = <0x203>;
+		};
+		CPU12: cpu at 300 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a15";
+			reg = <0x300>;
+		};
+		CPU13: cpu at 301 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a15";
+			reg = <0x301>;
+		};
+		CPU14: cpu at 302 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a15";
+			reg = <0x302>;
+		};
+		CPU15: cpu at 303 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a15";
+			reg = <0x303>;
+		};
+	};
+
+	clock: clock {
+		compatible = "hisilicon,hip04-clock";
+		/* dummy register.
+		 * Don't need to access clock registers since they're
+		 * configured in firmware already.
+		 */
+		reg = <0 0 0 0x1000>;
+		#clock-cells = <1>;
+	};
+
+	timer {
+		compatible = "arm,armv7-timer";
+		interrupt-parent = <&gic>;
+		interrupts = <1 13 0xf08>,
+			     <1 14 0xf08>,
+			     <1 11 0xf08>,
+			     <1 10 0xf08>;
+	};
+
+	soc {
+		/* It's a 32-bit SoC. */
+		#address-cells = <1>;
+		#size-cells = <1>;
+		compatible = "simple-bus";
+		interrupt-parent = <&gic>;
+		ranges = <0 0 0xe0000000 0x10000000>;
+
+		gic: interrupt-controller at c01000 {
+			compatible = "hisilicon,hip04-gic";
+			#interrupt-cells = <3>;
+			#address-cells = <0>;
+			interrupt-controller;
+			interrupts = <1 9 0xf04>;
+
+			reg = <0xc01000 0x1000>, <0xc02000 0x1000>,
+			      <0xc04000 0x2000>, <0xc06000 0x2000>;
+		};
+
+		sysctrl: sysctrl {
+			compatible = "hisilicon,sysctrl";
+			reg = <0x3e00000 0x00100000>;
+			relocation-entry = <0xe0000100>;
+			relocation-size = <0x1000>;
+			bootwrapper-phys = <0x10c00000>;
+			bootwrapper-size = <0x10000>;
+			bootwrapper-magic = <0xa5a5a5a5>;
+		};
+
+		fabric: fabric {
+			compatible = "hisilicon,hip04-fabric";
+			reg = <0x302a000 0x1000>;
+		};
+
+		dual_timer0: dual_timer at 3000000 {
+			compatible = "arm,sp804", "arm,primecell";
+			reg = <0x3000000 0x1000>;
+			interrupts = <0 224 4>;
+			clocks = <&clock HIP04_CLK_50M>;
+			clock-names = "apb_pclk";
+		};
+
+		arm-pmu {
+			compatible = "arm,cortex-a15-pmu";
+			interrupts = <0 64 4>,
+				     <0 65 4>,
+				     <0 66 4>,
+				     <0 67 4>,
+				     <0 68 4>,
+				     <0 69 4>,
+				     <0 70 4>,
+				     <0 71 4>,
+				     <0 72 4>,
+				     <0 73 4>,
+				     <0 74 4>,
+				     <0 75 4>,
+				     <0 76 4>,
+				     <0 77 4>,
+				     <0 78 4>,
+				     <0 79 4>;
+		};
+
+		uart0: uart at 4007000 {
+			compatible = "snps,dw-apb-uart";
+			reg = <0x4007000 0x1000>;
+			interrupts = <0 381 4>;
+			clocks = <&clock HIP04_CLK_168M>;
+			clock-names = "uartclk";
+			reg-shift = <2>;
+			status = "disabled";
+		};
+
+		sata0: sata at a000000 {
+			compatible = "hisilicon,hisi-ahci";
+			reg = <0xa000000 0x1000000>;
+			interrupts = <0 372 4>;
+		};
+
+	};
+};
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 55+ messages in thread

* [PATCH v15 08/12] ARM: config: append lpae configuration
  2014-07-28 13:57 [PATCH v15 00/12] enable Hisilicon HiP04 Haojian Zhuang
                   ` (6 preceding siblings ...)
  2014-07-28 13:57 ` [PATCH v15 07/12] ARM: dts: append hip04 dts Haojian Zhuang
@ 2014-07-28 13:57 ` Haojian Zhuang
  2014-07-29  4:05   ` Olof Johansson
  2014-07-28 13:57 ` [PATCH v15 09/12] ARM: config: append hip04_defconfig Haojian Zhuang
                   ` (4 subsequent siblings)
  12 siblings, 1 reply; 55+ messages in thread
From: Haojian Zhuang @ 2014-07-28 13:57 UTC (permalink / raw)
  To: linux-arm-kernel

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

Signed-off-by: Haojian Zhuang <haojian.zhuang@linaro.org>
---
 arch/arm/configs/multi_v7_lpae_defconfig | 343 +++++++++++++++++++++++++++++++
 1 file changed, 343 insertions(+)
 create mode 100644 arch/arm/configs/multi_v7_lpae_defconfig

diff --git a/arch/arm/configs/multi_v7_lpae_defconfig b/arch/arm/configs/multi_v7_lpae_defconfig
new file mode 100644
index 0000000..891937b
--- /dev/null
+++ b/arch/arm/configs/multi_v7_lpae_defconfig
@@ -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
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 55+ messages in thread

* [PATCH v15 09/12] ARM: config: append hip04_defconfig
  2014-07-28 13:57 [PATCH v15 00/12] enable Hisilicon HiP04 Haojian Zhuang
                   ` (7 preceding siblings ...)
  2014-07-28 13:57 ` [PATCH v15 08/12] ARM: config: append lpae configuration Haojian Zhuang
@ 2014-07-28 13:57 ` Haojian Zhuang
  2014-07-29  4:07   ` Olof Johansson
  2014-07-28 13:57 ` [PATCH v15 10/12] ARM: hisi: enable erratum 798181 of A15 on HiP04 Haojian Zhuang
                   ` (3 subsequent siblings)
  12 siblings, 1 reply; 55+ messages in thread
From: Haojian Zhuang @ 2014-07-28 13:57 UTC (permalink / raw)
  To: linux-arm-kernel

Select HiP04 SoC configuration by hip04_defconfig.

Signed-off-by: Haojian Zhuang <haojian.zhuang@linaro.org>
---
 arch/arm/configs/hip04_defconfig | 74 ++++++++++++++++++++++++++++++++++++++++
 1 file changed, 74 insertions(+)
 create mode 100644 arch/arm/configs/hip04_defconfig

diff --git a/arch/arm/configs/hip04_defconfig b/arch/arm/configs/hip04_defconfig
new file mode 100644
index 0000000..5c471b2
--- /dev/null
+++ b/arch/arm/configs/hip04_defconfig
@@ -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
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 55+ messages in thread

* [PATCH v15 10/12] ARM: hisi: enable erratum 798181 of A15 on HiP04
  2014-07-28 13:57 [PATCH v15 00/12] enable Hisilicon HiP04 Haojian Zhuang
                   ` (8 preceding siblings ...)
  2014-07-28 13:57 ` [PATCH v15 09/12] ARM: config: append hip04_defconfig Haojian Zhuang
@ 2014-07-28 13:57 ` Haojian Zhuang
  2014-07-29  4:08   ` Olof Johansson
  2014-07-28 13:57 ` [PATCH v15 11/12] virt: arm: support hip04 gic Haojian Zhuang
                   ` (2 subsequent siblings)
  12 siblings, 1 reply; 55+ messages in thread
From: Haojian Zhuang @ 2014-07-28 13:57 UTC (permalink / raw)
  To: linux-arm-kernel

From: Kefeng Wang <kefeng.wang@linaro.org>

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).

Signed-off-by: Kefeng Wang <kefeng.wang@linaro.org>
Singed-off-by: Haojian Zhuang <haojian.zhuang@linaro.org>
---
 arch/arm/mach-hisi/Kconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm/mach-hisi/Kconfig b/arch/arm/mach-hisi/Kconfig
index 2a36fb7..075772b 100644
--- a/arch/arm/mach-hisi/Kconfig
+++ b/arch/arm/mach-hisi/Kconfig
@@ -24,6 +24,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
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 55+ messages in thread

* [PATCH v15 11/12] virt: arm: support hip04 gic
  2014-07-28 13:57 [PATCH v15 00/12] enable Hisilicon HiP04 Haojian Zhuang
                   ` (9 preceding siblings ...)
  2014-07-28 13:57 ` [PATCH v15 10/12] ARM: hisi: enable erratum 798181 of A15 on HiP04 Haojian Zhuang
@ 2014-07-28 13:57 ` Haojian Zhuang
  2014-07-28 18:00   ` Marc Zyngier
  2014-07-28 13:57 ` [PATCH v15 12/12] ARM: debug: add HiP04 debug uart Haojian Zhuang
  2014-07-28 14:43 ` [PATCH v15 00/12] enable Hisilicon HiP04 Arnd Bergmann
  12 siblings, 1 reply; 55+ messages in thread
From: Haojian Zhuang @ 2014-07-28 13:57 UTC (permalink / raw)
  To: linux-arm-kernel

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.

Signed-off-by: Haojian Zhuang <haojian.zhuang@linaro.org>
---
 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(-)

diff --git a/arch/arm/kernel/asm-offsets.c b/arch/arm/kernel/asm-offsets.c
index 85598b5..166cc98 100644
--- a/arch/arm/kernel/asm-offsets.c
+++ b/arch/arm/kernel/asm-offsets.c
@@ -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));
diff --git a/arch/arm/kvm/interrupts_head.S b/arch/arm/kvm/interrupts_head.S
index 76af9302..9fbbf99 100644
--- a/arch/arm/kvm/interrupts_head.S
+++ b/arch/arm/kvm/interrupts_head.S
@@ -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
diff --git a/arch/arm64/kernel/asm-offsets.c b/arch/arm64/kernel/asm-offsets.c
index 646f888..2422358 100644
--- a/arch/arm64/kernel/asm-offsets.c
+++ b/arch/arm64/kernel/asm-offsets.c
@@ -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
diff --git a/arch/arm64/kvm/hyp.S b/arch/arm64/kvm/hyp.S
index b0d1512..2dbe337 100644
--- a/arch/arm64/kvm/hyp.S
+++ b/arch/arm64/kvm/hyp.S
@@ -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 )
diff --git a/include/kvm/arm_vgic.h b/include/kvm/arm_vgic.h
index f27000f..eba4b51 100644
--- a/include/kvm/arm_vgic.h
+++ b/include/kvm/arm_vgic.h
@@ -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;
diff --git a/include/linux/irqchip/arm-gic.h b/include/linux/irqchip/arm-gic.h
index 45e2d8c..b055f92 100644
--- a/include/linux/irqchip/arm-gic.h
+++ b/include/linux/irqchip/arm-gic.h
@@ -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;
diff --git a/virt/kvm/arm/vgic.c b/virt/kvm/arm/vgic.c
index 56ff9be..6c0ee89 100644
--- a/virt/kvm/arm/vgic.c
+++ b/virt/kvm/arm/vgic.c
@@ -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),
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 55+ messages in thread

* [PATCH v15 12/12] ARM: debug: add HiP04 debug uart
  2014-07-28 13:57 [PATCH v15 00/12] enable Hisilicon HiP04 Haojian Zhuang
                   ` (10 preceding siblings ...)
  2014-07-28 13:57 ` [PATCH v15 11/12] virt: arm: support hip04 gic Haojian Zhuang
@ 2014-07-28 13:57 ` Haojian Zhuang
  2014-07-28 14:43 ` [PATCH v15 00/12] enable Hisilicon HiP04 Arnd Bergmann
  12 siblings, 0 replies; 55+ messages in thread
From: Haojian Zhuang @ 2014-07-28 13:57 UTC (permalink / raw)
  To: linux-arm-kernel

Add the support of Hisilicon HiP04 debug uart.

Signed-off-by: Haojian Zhuang <haojian.zhuang@linaro.org>
---
 arch/arm/Kconfig.debug | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/arch/arm/Kconfig.debug b/arch/arm/Kconfig.debug
index d061de0..c6499cc 100644
--- a/arch/arm/Kconfig.debug
+++ b/arch/arm/Kconfig.debug
@@ -231,6 +231,14 @@ choice
 		  Say Y here if you want kernel low-level debugging support
 		  on Hix5hd2 UART.
 
+	config DEBUG_HIP04_UART
+		bool "Hisilicon HiP04 Debug UART"
+		depends on ARCH_HIP04
+		select DEBUG_UART_8250
+		help
+		  Say Y here if you want kernel low-level debugging support
+		  on HIP04 UART.
+
 	config DEBUG_HIGHBANK_UART
 		bool "Kernel low-level debugging messages via Highbank UART"
 		depends on ARCH_HIGHBANK
@@ -1095,6 +1103,7 @@ config DEBUG_UART_PHYS
 	default 0xd4017000 if DEBUG_MMP_UART2
 	default 0xd4018000 if DEBUG_MMP_UART3
 	default 0xe0000000 if ARCH_SPEAR13XX
+	default 0xe4007000 if DEBUG_HIP04_UART
 	default 0xf0000be0 if ARCH_EBSA110
 	default 0xf1012000 if DEBUG_MVEBU_UART_ALTERNATE
 	default 0xf1012000 if ARCH_DOVE || ARCH_KIRKWOOD || ARCH_MV78XX0 || \
@@ -1136,6 +1145,7 @@ config DEBUG_UART_VIRT
 	default 0xf7008000 if DEBUG_S3C24XX_UART && (DEBUG_S3C_UART2 || \
 				DEBUG_S3C2410_UART2)
 	default 0xf7fc9000 if DEBUG_BERLIN_UART
+	default 0xf8007000 if DEBUG_HIP04_UART
 	default 0xf8009000 if DEBUG_VEXPRESS_UART0_CA9
 	default 0xf8090000 if DEBUG_VEXPRESS_UART0_RS1
 	default 0xfa71e000 if DEBUG_QCOM_UARTDM
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 55+ messages in thread

* [PATCH v15 04/12] ARM: hisi: enable HiP04
  2014-07-28 13:57 ` [PATCH v15 04/12] ARM: hisi: enable HiP04 Haojian Zhuang
@ 2014-07-28 14:38   ` Arnd Bergmann
  0 siblings, 0 replies; 55+ messages in thread
From: Arnd Bergmann @ 2014-07-28 14:38 UTC (permalink / raw)
  To: linux-arm-kernel

On Monday 28 July 2014 21:57:48 Haojian Zhuang wrote:
> +
> +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
> 

One last-minute comment: you match the ID of a particular board (d01)
but the string lists the name of the SoC family.
I'd just changen the match table to list "hisilicon,hip04" directly
rather than the board.
In the dts file, the root node should already be compatible with both.

	Arnd

^ permalink raw reply	[flat|nested] 55+ messages in thread

* [PATCH v15 05/12] document: dt: add the binding on HiP04
  2014-07-28 13:57 ` [PATCH v15 05/12] document: dt: add the binding on HiP04 Haojian Zhuang
@ 2014-07-28 14:41   ` Arnd Bergmann
  0 siblings, 0 replies; 55+ messages in thread
From: Arnd Bergmann @ 2014-07-28 14:41 UTC (permalink / raw)
  To: linux-arm-kernel

On Monday 28 July 2014 21:57:49 Haojian Zhuang wrote:
> 
> +HiP04 D01 Board
> +Required root node properties:
> +       - compatible = "hisilicon,hip04-d01";
> +

As mentioned in my patch 04 comment, I think it's better
to refer to the SoC here rather than the board. Even if you
know that there is only one board with this particular SoC,
we don't normally document each board as there are so many of
them.

	Arnd

^ permalink raw reply	[flat|nested] 55+ messages in thread

* [PATCH v15 00/12] enable Hisilicon HiP04
  2014-07-28 13:57 [PATCH v15 00/12] enable Hisilicon HiP04 Haojian Zhuang
                   ` (11 preceding siblings ...)
  2014-07-28 13:57 ` [PATCH v15 12/12] ARM: debug: add HiP04 debug uart Haojian Zhuang
@ 2014-07-28 14:43 ` Arnd Bergmann
  12 siblings, 0 replies; 55+ messages in thread
From: Arnd Bergmann @ 2014-07-28 14:43 UTC (permalink / raw)
  To: linux-arm-kernel

On Monday 28 July 2014 21:57:44 Haojian Zhuang wrote:
> Changelog:
> v15:
>   * Add p04 debug uart back.
>   * Refresh since hix5hd2 code updated.
> 

Looks fine to me overall. One small comment from my side, otherwise
please send a pull request once the GIC driver changes have sufficent
Acks. I'll be on vacation starting on Wednesday, so it will likely be
up to Olof to decide whether to merge this for 3.17 or 3.18 depending
on the timing.

	Arnd

^ permalink raw reply	[flat|nested] 55+ messages in thread

* [PATCH v15 01/12] irq: gic: support hip04 gic
  2014-07-28 13:57 ` [PATCH v15 01/12] irq: gic: support hip04 gic Haojian Zhuang
@ 2014-07-28 17:38   ` Marc Zyngier
  2014-07-29 13:05     ` Arnd Bergmann
  0 siblings, 1 reply; 55+ messages in thread
From: Marc Zyngier @ 2014-07-28 17:38 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Haojian,

On Mon, Jul 28 2014 at  2:57:45 pm BST, Haojian Zhuang <haojian.zhuang@linaro.org> wrote:
> There's some difference between ARM GICv2 and HiP04 GIC.
>
> * HiP04 GIC could support 16 cores at most, and ARM GIC could support
> 8 cores at most. So the defination 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.
>
> Changelog:
> v14:
>   * Mount function pointers to different implementation on standard
>     GICv2 and Hisilicon HiP04 GIC.
>
> Signed-off-by: Haojian Zhuang <haojian.zhuang@linaro.org>
> ---
>  Documentation/devicetree/bindings/arm/gic.txt |   1 +
>  drivers/irqchip/irq-gic.c                     | 436 +++++++++++++++++++++-----
>  2 files changed, 350 insertions(+), 87 deletions(-)
>
> diff --git a/Documentation/devicetree/bindings/arm/gic.txt b/Documentation/devicetree/bindings/arm/gic.txt
> index 5573c08..150f7d6 100644
> --- a/Documentation/devicetree/bindings/arm/gic.txt
> +++ b/Documentation/devicetree/bindings/arm/gic.txt
> @@ -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.
> diff --git a/drivers/irqchip/irq-gic.c b/drivers/irqchip/irq-gic.c
> index 508b815..b47243f 100644
> --- a/drivers/irqchip/irq-gic.c
> +++ b/drivers/irqchip/irq-gic.c
> @@ -69,19 +69,23 @@ struct gic_chip_data {
>  #ifdef CONFIG_GIC_NON_BANKED
>         void __iomem *(*get_base)(union gic_base *);
>  #endif
> +       void (*init_cpu_map)(void);
> +       u32 (*get_cpu_map)(u32);
> +       void (*set_cpu_map)(u32, u32);
> +       bool (*cpu_invalid)(u32);

Nit: It would make more sense to me to have a "cpu_valid" hook, instead
of the negative version.

> +       u32 (*get_cpumask)(struct gic_chip_data *);
> +       void (*set_dist_target)(struct gic_chip_data *, u32, u32);
> +       void (*set_dist_softint)(struct gic_chip_data *, u32, u32);
> +       void (*dist_init)(struct gic_chip_data *);
> +       void (*dist_save)(unsigned int);
> +       void (*dist_restore)(unsigned int);
> +       u32 nr_cpu_if;
> +       u32 max_nr_irq;
>  };
>
>  static DEFINE_RAW_SPINLOCK(irq_controller_lock);
>
>  /*
> - * The GIC mapping of CPU interfaces does not necessarily match
> - * the logical CPU numbering.  Let's use a mapping as returned
> - * by the GIC itself.
> - */
> -#define NR_GIC_CPU_IF 8
> -static u8 gic_cpu_map[NR_GIC_CPU_IF] __read_mostly;
> -
> -/*
>   * Supported arch specific GIC irq extension.
>   * Default make them NULL.
>   */
> @@ -222,23 +226,21 @@ static int gic_retrigger(struct irq_data *d)
>  static int gic_set_affinity(struct irq_data *d, const struct cpumask *mask_val,
>                             bool force)
>  {
> -       void __iomem *reg = gic_dist_base(d) + GIC_DIST_TARGET + (gic_irq(d) & ~3);
> -       unsigned int cpu, shift = (gic_irq(d) % 4) * 8;
> -       u32 val, mask, bit;
> +       struct gic_chip_data *gic_data = irq_data_get_irq_chip_data(d);
> +       unsigned int cpu;
> +       u32 bit;
>
>         if (!force)
>                 cpu = cpumask_any_and(mask_val, cpu_online_mask);
>         else
>                 cpu = cpumask_first(mask_val);
>
> -       if (cpu >= NR_GIC_CPU_IF || cpu >= nr_cpu_ids)
> +       if (gic_data->cpu_invalid(cpu) || cpu >= nr_cpu_ids)
>                 return -EINVAL;
>
>         raw_spin_lock(&irq_controller_lock);
> -       mask = 0xff << shift;
> -       bit = gic_cpu_map[cpu] << shift;
> -       val = readl_relaxed(reg) & ~mask;
> -       writel_relaxed(val | bit, reg);
> +       bit = gic_data->get_cpu_map(cpu);
> +       gic_data->set_dist_target(gic_data, gic_irq(d), bit);
>         raw_spin_unlock(&irq_controller_lock);
>
>         return IRQ_SET_MASK_OK;
> @@ -304,7 +306,7 @@ static void gic_handle_cascade_irq(unsigned int irq, struct irq_desc *desc)
>                 goto out;
>
>         cascade_irq = irq_find_mapping(chip_data->domain, gic_irq);
> -       if (unlikely(gic_irq < 32 || gic_irq > 1020))
> +       if (unlikely(gic_irq < 32 || gic_irq > chip_data->max_nr_irq))
>                 handle_bad_irq(cascade_irq, desc);
>         else
>                 generic_handle_irq(cascade_irq);
> @@ -335,69 +337,31 @@ void __init gic_cascade_irq(unsigned int gic_nr, unsigned int irq)
>         irq_set_chained_handler(irq, gic_handle_cascade_irq);
>  }
>
> -static u8 gic_get_cpumask(struct gic_chip_data *gic)
> -{
> -       void __iomem *base = gic_data_dist_base(gic);
> -       u32 mask, i;
> -
> -       for (i = mask = 0; i < 32; i += 4) {
> -               mask = readl_relaxed(base + GIC_DIST_TARGET + i);
> -               mask |= mask >> 16;
> -               mask |= mask >> 8;
> -               if (mask)
> -                       break;
> -       }
> -
> -       if (!mask)
> -               pr_crit("GIC CPU mask not found - kernel will fail to boot.\n");
> -
> -       return mask;
> -}
> -
> -static void __init gic_dist_init(struct gic_chip_data *gic)
> -{
> -       unsigned int i;
> -       u32 cpumask;
> -       unsigned int gic_irqs = gic->gic_irqs;
> -       void __iomem *base = gic_data_dist_base(gic);
> -
> -       writel_relaxed(0, base + GIC_DIST_CTRL);
> -
> -       /*
> -        * Set all global interrupts to this CPU only.
> -        */
> -       cpumask = gic_get_cpumask(gic);
> -       cpumask |= cpumask << 8;
> -       cpumask |= cpumask << 16;
> -       for (i = 32; i < gic_irqs; i += 4)
> -               writel_relaxed(cpumask, base + GIC_DIST_TARGET + i * 4 / 4);
> -
> -       gic_dist_config(base, gic_irqs, NULL);
> -
> -       writel_relaxed(1, base + GIC_DIST_CTRL);
> -}
> -
>  static void gic_cpu_init(struct gic_chip_data *gic)
>  {
>         void __iomem *dist_base = gic_data_dist_base(gic);
>         void __iomem *base = gic_data_cpu_base(gic);
>         unsigned int cpu_mask, cpu = smp_processor_id();
>         int i;
> +       u32 data;
>
>         /*
>          * Get what the GIC says our CPU mask is.
>          */
> -       BUG_ON(cpu >= NR_GIC_CPU_IF);
> -       cpu_mask = gic_get_cpumask(gic);
> -       gic_cpu_map[cpu] = cpu_mask;
> +       BUG_ON(gic->cpu_invalid(cpu));
> +       cpu_mask = gic->get_cpumask(gic);
> +       gic->set_cpu_map(cpu, cpu_mask);
>
>         /*
>          * Clear our mask from the other map entries in case they're
>          * still undefined.
>          */
> -       for (i = 0; i < NR_GIC_CPU_IF; i++)
> -               if (i != cpu)
> -                       gic_cpu_map[i] &= ~cpu_mask;
> +       for (i = 0; i < gic->nr_cpu_if; i++) {
> +               if (i != cpu) {
> +                       data = gic->get_cpu_map(i);
> +                       gic->set_cpu_map(i, data & ~cpu_mask);
> +               }
> +       }
>
>         gic_cpu_config(dist_base, NULL);
>
> @@ -489,6 +453,70 @@ static void gic_dist_restore(unsigned int gic_nr)
>         writel_relaxed(1, dist_base + GIC_DIST_CTRL);
>  }
>
> +static void hip04_dist_save(unsigned int gic_nr)
> +{
> +       unsigned int gic_irqs;
> +       void __iomem *dist_base;
> +       int i;
> +
> +       if (gic_nr >= MAX_GIC_NR)
> +               BUG();
> +
> +       gic_irqs = gic_data[gic_nr].gic_irqs;
> +       dist_base = gic_data_dist_base(&gic_data[gic_nr]);
> +
> +       if (!dist_base)
> +               return;
> +
> +       for (i = 0; i < DIV_ROUND_UP(gic_irqs, 16); i++)
> +               gic_data[gic_nr].saved_spi_conf[i] =
> +                       readl_relaxed(dist_base + GIC_DIST_CONFIG + i * 4);
> +
> +       for (i = 0; i < DIV_ROUND_UP(gic_irqs, 2); i++)
> +               gic_data[gic_nr].saved_spi_target[i] =
> +                       readl_relaxed(dist_base + GIC_DIST_TARGET + i * 2);
> +
> +       for (i = 0; i < DIV_ROUND_UP(gic_irqs, 32); i++)
> +               gic_data[gic_nr].saved_spi_enable[i] =
> +                       readl_relaxed(dist_base + GIC_DIST_ENABLE_SET + i * 4);
> +}
> +
> +static void hip04_dist_restore(unsigned int gic_nr)
> +{
> +       unsigned int gic_irqs;
> +       unsigned int i;
> +       void __iomem *dist_base;
> +
> +       if (gic_nr >= MAX_GIC_NR)
> +               BUG();
> +
> +       gic_irqs = gic_data[gic_nr].gic_irqs;
> +       dist_base = gic_data_dist_base(&gic_data[gic_nr]);
> +
> +       if (!dist_base)
> +               return;
> +
> +       writel_relaxed(0, dist_base + GIC_DIST_CTRL);
> +
> +       for (i = 0; i < DIV_ROUND_UP(gic_irqs, 16); i++)
> +               writel_relaxed(gic_data[gic_nr].saved_spi_conf[i],
> +                       dist_base + GIC_DIST_CONFIG + i * 4);
> +
> +       for (i = 0; i < DIV_ROUND_UP(gic_irqs, 4); i++)
> +               writel_relaxed(0xa0a0a0a0,
> +                       dist_base + GIC_DIST_PRI + i * 4);
> +
> +       for (i = 0; i < DIV_ROUND_UP(gic_irqs, 2); i++)
> +               writel_relaxed(gic_data[gic_nr].saved_spi_target[i],
> +                       dist_base + GIC_DIST_TARGET + i * 2);
> +
> +       for (i = 0; i < DIV_ROUND_UP(gic_irqs, 32); i++)
> +               writel_relaxed(gic_data[gic_nr].saved_spi_enable[i],
> +                       dist_base + GIC_DIST_ENABLE_SET + i * 4);
> +
> +       writel_relaxed(1, dist_base + GIC_DIST_CTRL);
> +}
> +
>  static void gic_cpu_save(unsigned int gic_nr)
>  {
>         int i;
> @@ -565,11 +593,11 @@ static int gic_notifier(struct notifier_block *self, unsigned long cmd,   void *v)
>                         gic_cpu_restore(i);
>                         break;
>                 case CPU_CLUSTER_PM_ENTER:
> -                       gic_dist_save(i);
> +                       gic_data[i].dist_save(i);
>                         break;
>                 case CPU_CLUSTER_PM_ENTER_FAILED:
>                 case CPU_CLUSTER_PM_EXIT:
> -                       gic_dist_restore(i);
> +                       gic_data[i].dist_restore(i);
>                         break;
>                 }
>         }
> @@ -610,7 +638,7 @@ static void gic_raise_softirq(const struct cpumask *mask, unsigned int irq)
>
>         /* Convert our logical CPU mask into a physical one. */
>         for_each_cpu(cpu, mask)
> -               map |= gic_cpu_map[cpu];
> +               map |= gic_data[0].get_cpu_map(cpu);
>
>         /*
>          * Ensure that stores to Normal memory are visible to the
> @@ -619,7 +647,7 @@ static void gic_raise_softirq(const struct cpumask *mask, unsigned int irq)
>         dmb(ishst);
>
>         /* this always happens on GIC0 */
> -       writel_relaxed(map << 16 | irq, gic_data_dist_base(&gic_data[0]) + GIC_DIST_SOFTINT);
> +       gic_data[0].set_dist_softint(&gic_data[0], irq, map);
>
>         raw_spin_unlock_irqrestore(&irq_controller_lock, flags);
>  }
> @@ -634,10 +662,9 @@ static void gic_raise_softirq(const struct cpumask *mask, unsigned int irq)
>   */
>  void gic_send_sgi(unsigned int cpu_id, unsigned int irq)
>  {
> -       BUG_ON(cpu_id >= NR_GIC_CPU_IF);
> -       cpu_id = 1 << cpu_id;
> +       BUG_ON(gic_data[0].cpu_invalid(cpu_id));
>         /* this always happens on GIC0 */
> -       writel_relaxed((cpu_id << 16) | irq, gic_data_dist_base(&gic_data[0]) + GIC_DIST_SOFTINT);
> +       gic_data[0].set_dist_softint(&gic_data[0], irq, 1 << cpu_id);
>  }
>
>  /*
> @@ -653,9 +680,9 @@ int gic_get_cpu_id(unsigned int cpu)
>  {
>         unsigned int cpu_bit;
>
> -       if (cpu >= NR_GIC_CPU_IF)
> +       if (gic_data[0].cpu_invalid(cpu))
>                 return -1;
> -       cpu_bit = gic_cpu_map[cpu];
> +       cpu_bit = gic_data[0].get_cpu_map(cpu);
>         if (cpu_bit & (cpu_bit - 1))
>                 return -1;
>         return __ffs(cpu_bit);
> @@ -673,6 +700,7 @@ int gic_get_cpu_id(unsigned int cpu)
>   */
>  void gic_migrate_target(unsigned int new_cpu_id)
>  {
> +       struct gic_chip_data *gic = &gic_data[gic_nr];
>         unsigned int cur_cpu_id, gic_irqs, gic_nr = 0;
>         void __iomem *dist_base;
>         int i, ror_val, cpu = smp_processor_id();
> @@ -681,19 +709,19 @@ void gic_migrate_target(unsigned int new_cpu_id)
>         if (gic_nr >= MAX_GIC_NR)
>                 BUG();
>
> -       dist_base = gic_data_dist_base(&gic_data[gic_nr]);
> +       dist_base = gic_data_dist_base(gic);
>         if (!dist_base)
>                 return;
> -       gic_irqs = gic_data[gic_nr].gic_irqs;
> +       gic_irqs = gic->gic_irqs;
>
> -       cur_cpu_id = __ffs(gic_cpu_map[cpu]);
> +       cur_cpu_id = __ffs(gic->get_cpu_map(cpu));
>         cur_target_mask = 0x01010101 << cur_cpu_id;
>         ror_val = (cur_cpu_id - new_cpu_id) & 31;
>
>         raw_spin_lock(&irq_controller_lock);
>
>         /* Update the target interface for this logical CPU */
> -       gic_cpu_map[cpu] = 1 << new_cpu_id;
> +       gic_data->set_cpu_map(cpu, 1 << new_cpu_id);
>
>         /*
>          * Find all the peripheral interrupts targetting the current
> @@ -730,8 +758,7 @@ void gic_migrate_target(unsigned int new_cpu_id)
>                 writel_relaxed(val, dist_base + GIC_DIST_SGI_PENDING_CLEAR + i);
>                 for (j = i; j < i + 4; j++) {
>                         if (val & 0xff)
> -                               writel_relaxed((1 << (new_cpu_id + 16)) | j,
> -                                               dist_base + GIC_DIST_SOFTINT);
> +                               gic->set_dist_softint(gic, j, 1 << new_cpu_id);
>                         val >>= 8;
>                 }
>         }
> @@ -883,7 +910,7 @@ void __init gic_init_bases(unsigned int gic_nr, int irq_start,
>  {
>         irq_hw_number_t hwirq_base;
>         struct gic_chip_data *gic;
> -       int gic_irqs, irq_base, i;
> +       int gic_irqs, irq_base;
>         int nr_routable_irqs;
>
>         BUG_ON(gic_nr >= MAX_GIC_NR);
> @@ -924,8 +951,7 @@ void __init gic_init_bases(unsigned int gic_nr, int irq_start,
>          * Initialize the CPU interface map to all CPUs.
>          * It will be refined as each CPU probes its ID.
>          */
> -       for (i = 0; i < NR_GIC_CPU_IF; i++)
> -               gic_cpu_map[i] = 0xff;
> +       gic->init_cpu_map();
>
>         /*
>          * For primary GICs, skip over SGIs.
> @@ -941,12 +967,13 @@ void __init gic_init_bases(unsigned int gic_nr, int irq_start,
>
>         /*
>          * Find out how many interrupts are supported.
> -        * The GIC only supports up to 1020 interrupt sources.
> +        * The ARM/Qualcomm GIC only supports up to 1020 interrupt sources.
> +        * The HiP04 GIC only supports up to 510 interrupt sources.
>          */
>         gic_irqs = readl_relaxed(gic_data_dist_base(gic) + GIC_DIST_CTR) & 0x1f;
>         gic_irqs = (gic_irqs + 1) * 32;
> -       if (gic_irqs > 1020)
> -               gic_irqs = 1020;
> +       if (gic_irqs > gic->max_nr_irq)
> +               gic_irqs = gic->max_nr_irq;
>         gic->gic_irqs = gic_irqs;
>
>         gic_irqs -= hwirq_base; /* calculate # of irqs to allocate */
> @@ -981,7 +1008,7 @@ void __init gic_init_bases(unsigned int gic_nr, int irq_start,
>         }
>
>         gic_chip.flags |= gic_arch_extn.flags;
> -       gic_dist_init(gic);
> +       gic->dist_init(gic);
>         gic_cpu_init(gic);
>         gic_pm_init(gic);
>  }
> @@ -989,6 +1016,98 @@ void __init gic_init_bases(unsigned int gic_nr, int irq_start,
>  #ifdef CONFIG_OF
>  static int gic_cnt __initdata;

I think you just broke all the non-DT platforms in one single go.

> +/*
> + * The GIC mapping of CPU interfaces does not necessarily match
> + * the logical CPU numbering.  Let's use a mapping as returned
> + * by the GIC itself.
> + */
> +#define NR_GIC_CPU_IF 8
> +static u8 gic_cpu_map[NR_GIC_CPU_IF] __read_mostly;
> +
> +static void gic_init_cpu_map(void)
> +{
> +       int i;
> +       for (i = 0; i < NR_GIC_CPU_IF; i++)
> +               gic_cpu_map[i] = 0xff;
> +}
> +
> +static u32 gic_get_cpu_map(u32 i)
> +{
> +       return gic_cpu_map[i];
> +}
> +
> +static void gic_set_cpu_map(u32 i, u32 data)
> +{
> +       gic_cpu_map[i] = data & 0xff;
> +}
> +
> +static bool gic_cpu_invalid(u32 cpu)
> +{
> +       return cpu >= NR_GIC_CPU_IF;
> +}
> +
> +static u32 gic_get_cpumask(struct gic_chip_data *gic)
> +{
> +       void __iomem *base = gic_data_dist_base(gic);
> +       u32 mask, i;
> +
> +       for (i = mask = 0; i < 32; i += 4) {
> +               mask = readl_relaxed(base + GIC_DIST_TARGET + i);
> +               mask |= mask >> 16;
> +               mask |= mask >> 8;
> +               if (mask)
> +                       break;
> +       }
> +
> +       if (!mask)
> +               pr_crit("GIC CPU mask not found - kernel will fail to boot.\n");
> +
> +       return mask & 0xff;
> +}
> +
> +static void gic_set_dist_target(struct gic_chip_data *gic, u32 irq, u32 data)
> +{
> +       void __iomem *base = gic_data_dist_base(gic);
> +       u32 val, mask, offset, shift = (irq % 4) * 8;
> +
> +       mask = 0xff << shift;
> +       offset = irq & ~3U;
> +       val = readl_relaxed(base + GIC_DIST_TARGET + offset) & ~mask;
> +       val |= data << shift;
> +       writel_relaxed(val, base + GIC_DIST_TARGET + offset);
> +}
> +
> +static void gic_set_dist_softint(struct gic_chip_data *gic, u32 irq, u32 data)
> +{
> +       void __iomem *base = gic_data_dist_base(gic);
> +
> +       data = data << 16;
> +       writel_relaxed(data | irq, base + GIC_DIST_SOFTINT);
> +}
> +
> +static void gic_dist_init(struct gic_chip_data *gic)
> +{
> +       unsigned int i;
> +       u32 cpumask;
> +       unsigned int gic_irqs = gic->gic_irqs;
> +       void __iomem *base = gic_data_dist_base(gic);
> +
> +       writel_relaxed(0, base + GIC_DIST_CTRL);
> +
> +       /*
> +        * Set all global interrupts to this CPU only.
> +        */
> +       cpumask = gic_get_cpumask(gic);
> +       cpumask |= cpumask << 8;
> +       cpumask |= cpumask << 16;
> +       for (i = 32; i < gic_irqs; i += 4)
> +               writel_relaxed(cpumask, base + GIC_DIST_TARGET + i * 4 / 4);
> +
> +       gic_dist_config(base, gic_irqs, NULL);
> +
> +       writel_relaxed(1, base + GIC_DIST_CTRL);
> +}
> +
>  static int __init
>  gic_of_init(struct device_node *node, struct device_node *parent)
>  {
> @@ -1009,6 +1128,148 @@ gic_of_init(struct device_node *node, struct device_node *parent)
>         if (of_property_read_u32(node, "cpu-offset", &percpu_offset))
>                 percpu_offset = 0;
>
> +       gic_data[gic_cnt].nr_cpu_if = 8;
> +       gic_data[gic_cnt].init_cpu_map = gic_init_cpu_map;
> +       gic_data[gic_cnt].get_cpu_map = gic_get_cpu_map;
> +       gic_data[gic_cnt].set_cpu_map = gic_set_cpu_map;
> +       gic_data[gic_cnt].cpu_invalid = gic_cpu_invalid;
> +       gic_data[gic_cnt].get_cpumask = gic_get_cpumask;
> +       gic_data[gic_cnt].dist_init = gic_dist_init;
> +       gic_data[gic_cnt].dist_save = gic_dist_save;
> +       gic_data[gic_cnt].dist_restore = gic_dist_restore;
> +       gic_data[gic_cnt].set_dist_target = gic_set_dist_target;
> +       gic_data[gic_cnt].set_dist_softint = gic_set_dist_softint;
> +       gic_data[gic_cnt].max_nr_irq = 1020;
> +       gic_init_bases(gic_cnt, -1, dist_base, cpu_base, percpu_offset, node);
> +       if (!gic_cnt)
> +               gic_init_physaddr(node);
> +
> +       if (parent) {
> +               irq = irq_of_parse_and_map(node, 0);
> +               gic_cascade_irq(gic_cnt, irq);
> +       }
> +       gic_cnt++;
> +       return 0;
> +}
> +
> +/* HiP04 extends the number of CPU interface from 8 to 16 */
> +#define NR_HIP04_CPU_IF        16
> +static u16 hip04_cpu_map[NR_HIP04_CPU_IF] __read_mostly;
> +
> +static void hip04_init_cpu_map(void)
> +{
> +       int i;
> +       for (i = 0; i < NR_HIP04_CPU_IF; i++)
> +               hip04_cpu_map[i] = 0xffff;
> +}
> +
> +static u32 hip04_get_cpu_map(u32 i)
> +{
> +       return hip04_cpu_map[i];
> +}
> +
> +static void hip04_set_cpu_map(u32 i, u32 data)
> +{
> +       hip04_cpu_map[i] = data & 0xffff;
> +}
> +
> +static bool hip04_cpu_invalid(u32 cpu)
> +{
> +       return cpu >= NR_HIP04_CPU_IF;
> +}
> +
> +static u32 hip04_get_cpumask(struct gic_chip_data *gic)
> +{
> +       void __iomem *base = gic_data_dist_base(gic);
> +       u32 mask, i;
> +
> +       for (i = mask = 0; i < 32; i += 2) {
> +               mask = readl_relaxed(base + GIC_DIST_TARGET + i * 2);
> +               mask |= mask >> 16;
> +               if (mask)
> +                       break;
> +       }
> +
> +       if (!mask)
> +               pr_crit("GIC CPU mask not found - kernel will fail to
> boot.\n");

Certainly we don't need this message twice. It should be placed wherever
necessary.

> +
> +       return mask & 0xffff;
> +}
> +
> +static void hip04_set_dist_target(struct gic_chip_data *gic, u32 irq, u32 data)
> +{
> +       void __iomem *base = gic_data_dist_base(gic);
> +       u32 val, mask, offset, shift = (irq % 2) * 16;
> +
> +       mask = 0xffff << shift;
> +       offset = (irq * 2) & ~3U;
> +       val = readl_relaxed(base + GIC_DIST_TARGET + offset) & ~mask;
> +       val |= data << shift;
> +       writel_relaxed(val, base + GIC_DIST_TARGET + offset);
> +}
> +
> +static void hip04_set_dist_softint(struct gic_chip_data *gic, u32 irq, u32 data)
> +{
> +       void __iomem *base = gic_data_dist_base(gic);
> +
> +       data = data << 8;
> +       writel_relaxed(data | irq, base + GIC_DIST_SOFTINT);
> +}
> +
> +static void hip04_dist_init(struct gic_chip_data *gic)
> +{
> +       unsigned int i;
> +       u32 cpumask;
> +       unsigned int gic_irqs = gic->gic_irqs;
> +       void __iomem *base = gic_data_dist_base(gic);
> +
> +       writel_relaxed(0, base + GIC_DIST_CTRL);
> +
> +       /*
> +        * Set all global interrupts to this CPU only.
> +        */
> +       cpumask = hip04_get_cpumask(gic);
> +       cpumask |= cpumask << 16;
> +       for (i = 32; i < gic_irqs; i += 2)
> +               writel_relaxed(cpumask, base + GIC_DIST_TARGET + i * 2);
> +
> +       gic_dist_config(base, gic_irqs, NULL);
> +
> +       writel_relaxed(1, base + GIC_DIST_CTRL);
> +}
> +
> +static int __init
> +hip04_of_init(struct device_node *node, struct device_node *parent)
> +{
> +       void __iomem *cpu_base;
> +       void __iomem *dist_base;
> +       u32 percpu_offset;
> +       int irq;
> +
> +       if (WARN_ON(!node))
> +               return -ENODEV;
> +
> +       dist_base = of_iomap(node, 0);
> +       WARN(!dist_base, "unable to map gic dist registers\n");
> +
> +       cpu_base = of_iomap(node, 1);
> +       WARN(!cpu_base, "unable to map gic cpu registers\n");
> +
> +       if (of_property_read_u32(node, "cpu-offset", &percpu_offset))
> +               percpu_offset = 0;
> +
> +       gic_data[gic_cnt].nr_cpu_if = 16;
> +       gic_data[gic_cnt].init_cpu_map = hip04_init_cpu_map;
> +       gic_data[gic_cnt].get_cpu_map = hip04_get_cpu_map;
> +       gic_data[gic_cnt].set_cpu_map = hip04_set_cpu_map;
> +       gic_data[gic_cnt].cpu_invalid = hip04_cpu_invalid;
> +       gic_data[gic_cnt].get_cpumask = hip04_get_cpumask;
> +       gic_data[gic_cnt].dist_init = hip04_dist_init;
> +       gic_data[gic_cnt].dist_save = hip04_dist_save;
> +       gic_data[gic_cnt].dist_restore = hip04_dist_restore;
> +       gic_data[gic_cnt].set_dist_target = hip04_set_dist_target;
> +       gic_data[gic_cnt].set_dist_softint = hip04_set_dist_softint;
> +       gic_data[gic_cnt].max_nr_irq = 510;
>         gic_init_bases(gic_cnt, -1, dist_base, cpu_base, percpu_offset, node);
>         if (!gic_cnt)
>                 gic_init_physaddr(node);
> @@ -1022,6 +1283,7 @@ gic_of_init(struct device_node *node, struct device_node *parent)
>  }
>  IRQCHIP_DECLARE(cortex_a15_gic, "arm,cortex-a15-gic", gic_of_init);
>  IRQCHIP_DECLARE(cortex_a9_gic, "arm,cortex-a9-gic", gic_of_init);
> +IRQCHIP_DECLARE(hip04_gic, "hisilicon,hip04-gic", hip04_of_init);
>  IRQCHIP_DECLARE(msm_8660_qgic, "qcom,msm-8660-qgic", gic_of_init);
>  IRQCHIP_DECLARE(msm_qgic2, "qcom,msm-qgic2", gic_of_init);

Overall, this code should be able to sitting within a #ifdef/#endif
block, only selected if this platform is enabled, and possibly find a
way not to impact all the other platforms when this is not selected.

Finally, I'd like to outline how much I dislike the way the GIC
architecture has been abused here. Yes, this solves a particular
problem, at a given point in time, but this also feels extremely short
sighted from whoever has put this thing together. This really feels like
a short-term HW hack that is already addressed by GICv3. Merging support
for non architecture compliant HW is never the best solution.

Thanks,

	M.
-- 
Jazz is not dead. It just smells funny.

^ permalink raw reply	[flat|nested] 55+ messages in thread

* [PATCH v15 06/12] document: dt: add the binding on HiP04 clock
  2014-07-28 13:57 ` [PATCH v15 06/12] document: dt: add the binding on HiP04 clock Haojian Zhuang
@ 2014-07-28 17:54   ` Mark Rutland
  2014-07-29  2:25     ` Haojian Zhuang
  0 siblings, 1 reply; 55+ messages in thread
From: Mark Rutland @ 2014-07-28 17:54 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Jul 28, 2014 at 02:57:50PM +0100, Haojian Zhuang wrote:
> The DT binding for Hisilicon HiP04 clock driver.
> 
> Signed-off-by: Haojian Zhuang <haojian.zhuang@linaro.org>
> ---
>  .../devicetree/bindings/clock/hip04-clock.txt        | 20 ++++++++++++++++++++
>  1 file changed, 20 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/clock/hip04-clock.txt
> 
> diff --git a/Documentation/devicetree/bindings/clock/hip04-clock.txt b/Documentation/devicetree/bindings/clock/hip04-clock.txt
> new file mode 100644
> index 0000000..4d31ae3
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/clock/hip04-clock.txt
> @@ -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.

There's only one clock controller on-board and it's custom for HiP04?

> +
> +- 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>.

This must come in the same patch.

Mark.

^ permalink raw reply	[flat|nested] 55+ messages in thread

* [PATCH v15 11/12] virt: arm: support hip04 gic
  2014-07-28 13:57 ` [PATCH v15 11/12] virt: arm: support hip04 gic Haojian Zhuang
@ 2014-07-28 18:00   ` Marc Zyngier
  2014-07-29  2:31     ` Haojian Zhuang
  0 siblings, 1 reply; 55+ messages in thread
From: Marc Zyngier @ 2014-07-28 18:00 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Jul 28 2014 at  2:57:55 pm BST, Haojian Zhuang <haojian.zhuang@linaro.org> wrote:
> 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.
>
> Signed-off-by: Haojian Zhuang <haojian.zhuang@linaro.org>
> ---
>  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(-)
>
> diff --git a/arch/arm/kernel/asm-offsets.c b/arch/arm/kernel/asm-offsets.c
> index 85598b5..166cc98 100644
> --- a/arch/arm/kernel/asm-offsets.c
> +++ b/arch/arm/kernel/asm-offsets.c
> @@ -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));
> diff --git a/arch/arm/kvm/interrupts_head.S b/arch/arm/kvm/interrupts_head.S
> index 76af9302..9fbbf99 100644
> --- a/arch/arm/kvm/interrupts_head.S
> +++ b/arch/arm/kvm/interrupts_head.S
> @@ -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

Use "ubfx r4, r4, #0, #16" instead (with the proper symbolic constants,
of course). It will save loading this mask from the constant pool. For
consistency, you can also replace the above mov+lsr with the same
mechanism.

>  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

Same here.

>  1:	ldr	r6, [r3], #4
>  	str	r6, [r2], #4
>  	subs	r4, r4, #1
> diff --git a/arch/arm64/kernel/asm-offsets.c b/arch/arm64/kernel/asm-offsets.c
> index 646f888..2422358 100644
> --- a/arch/arm64/kernel/asm-offsets.c
> +++ b/arch/arm64/kernel/asm-offsets.c
> @@ -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
> diff --git a/arch/arm64/kvm/hyp.S b/arch/arm64/kvm/hyp.S
> index b0d1512..2dbe337 100644
> --- a/arch/arm64/kvm/hyp.S
> +++ b/arch/arm64/kvm/hyp.S
> @@ -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]

Have you tested this? It looks to me that you're not dropping the top
bits, so you're going to end-up with 0x1000004 list registers instead of
the expected 4 with GIC-400...

>  	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]

Same here.

>  	add	x3, x3, #VGIC_CPU_LR
>  1:	ldr	w5, [x3], #4
>  CPU_BE(	rev	w5, w5 )
> diff --git a/include/kvm/arm_vgic.h b/include/kvm/arm_vgic.h
> index f27000f..eba4b51 100644
> --- a/include/kvm/arm_vgic.h
> +++ b/include/kvm/arm_vgic.h
> @@ -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;
> diff --git a/include/linux/irqchip/arm-gic.h b/include/linux/irqchip/arm-gic.h
> index 45e2d8c..b055f92 100644
> --- a/include/linux/irqchip/arm-gic.h
> +++ b/include/linux/irqchip/arm-gic.h
> @@ -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;
> diff --git a/virt/kvm/arm/vgic.c b/virt/kvm/arm/vgic.c
> index 56ff9be..6c0ee89 100644
> --- a/virt/kvm/arm/vgic.c
> +++ b/virt/kvm/arm/vgic.c
> @@ -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),

Most of this is going to conflict very badly with the rest of the GICv3
patch series which is already queued for 3.17. You'll have to rebase it
on top of the current kvmarm/queue branch.

Thanks,

	M.
-- 
Jazz is not dead. It just smells funny.

^ permalink raw reply	[flat|nested] 55+ messages in thread

* [PATCH v15 07/12] ARM: dts: append hip04 dts
  2014-07-28 13:57 ` [PATCH v15 07/12] ARM: dts: append hip04 dts Haojian Zhuang
@ 2014-07-28 18:06   ` Mark Rutland
  2014-07-29  2:44     ` Haojian Zhuang
  0 siblings, 1 reply; 55+ messages in thread
From: Mark Rutland @ 2014-07-28 18:06 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Jul 28, 2014 at 02:57:51PM +0100, Haojian Zhuang wrote:
> Add hip04-d01.dts & hip04.dtsi for hip04 SoC platform.
> 
> Signed-off-by: Haojian Zhuang <haojian.zhuang@linaro.org>
> ---
>  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
> 
> diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
> index 721525e..6587bbf 100644
> --- a/arch/arm/boot/dts/Makefile
> +++ b/arch/arm/boot/dts/Makefile
> @@ -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 \
> diff --git a/arch/arm/boot/dts/hip04-d01.dts b/arch/arm/boot/dts/hip04-d01.dts
> new file mode 100644
> index 0000000..661c8e5
> --- /dev/null
> +++ b/arch/arm/boot/dts/hip04-d01.dts
> @@ -0,0 +1,39 @@
> +/*
> + *  Copyright (C) 2013-2014 Linaro Ltd.
> + *  Author: Haojian Zhuang <haojian.zhuang@linaro.org>
> + *
> + *  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;

How exactly is this bootwrapper used? Is the kernel compiled into it?

It might make more sense for the wrapper build system to inject
bootwrapper-related properties. Then the DTB is less likely to
amalgamate hacks to workaround differences between versions, and can be
used on systems without a wrapper without throwing away some memory.

> +
> +#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>;
> +       };

You can fold these into a single node.

> +
> +       soc {
> +               uart0: uart at 4007000 {
> +                       status = "ok";
> +               };
> +       };
> +};
> diff --git a/arch/arm/boot/dts/hip04.dtsi b/arch/arm/boot/dts/hip04.dtsi
> new file mode 100644
> index 0000000..30942be
> --- /dev/null
> +++ b/arch/arm/boot/dts/hip04.dtsi
> @@ -0,0 +1,267 @@
> +/*
> + * Hisilicon Ltd. HiP04 SoC
> + *
> + * Copyright (C) 2013-2014 Hisilicon Ltd.
> + * Copyright (C) 2013-2014 Linaro Ltd.
> + *
> + * Author: Haojian Zhuang <haojian.zhuang@linaro.org>
> + *
> + * 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.

s/hh/h/

[...]

> +       clock: clock {
> +               compatible = "hisilicon,hip04-clock";
> +               /* dummy register.
> +                * Don't need to access clock registers since they're
> +                * configured in firmware already.
> +                */
> +               reg = <0 0 0 0x1000>;

Huh? Whether or not you need to access the registers should be up to the
kernel, not the DT.

Why can the kernel not access these? This sounds like a hack.

> +               #clock-cells = <1>;
> +       };
> +
> +       timer {
> +               compatible = "arm,armv7-timer";
> +               interrupt-parent = <&gic>;
> +               interrupts = <1 13 0xf08>,
> +                            <1 14 0xf08>,
> +                            <1 11 0xf08>,
> +                            <1 10 0xf08>;
> +       };
> +
> +       soc {
> +               /* It's a 32-bit SoC. */
> +               #address-cells = <1>;
> +               #size-cells = <1>;
> +               compatible = "simple-bus";
> +               interrupt-parent = <&gic>;
> +               ranges = <0 0 0xe0000000 0x10000000>;
> +
> +               gic: interrupt-controller at c01000 {
> +                       compatible = "hisilicon,hip04-gic";
> +                       #interrupt-cells = <3>;
> +                       #address-cells = <0>;
> +                       interrupt-controller;
> +                       interrupts = <1 9 0xf04>;
> +
> +                       reg = <0xc01000 0x1000>, <0xc02000 0x1000>,
> +                             <0xc04000 0x2000>, <0xc06000 0x2000>;

Please place these on separate lines. It's easier to read and will match
what you've done for every other node.

> +               };
> +
> +               sysctrl: sysctrl {
> +                       compatible = "hisilicon,sysctrl";
> +                       reg = <0x3e00000 0x00100000>;
> +                       relocation-entry = <0xe0000100>;
> +                       relocation-size = <0x1000>;
> +                       bootwrapper-phys = <0x10c00000>;
> +                       bootwrapper-size = <0x10000>;
> +                       bootwrapper-magic = <0xa5a5a5a5>;

Are these absolute addresses, or translated per ranges above?

Why are they related to the system controller?

> +               };
> +
> +               fabric: fabric {
> +                       compatible = "hisilicon,hip04-fabric";
> +                       reg = <0x302a000 0x1000>;

How is this going to be used?

> +               };
> +
> +               dual_timer0: dual_timer at 3000000 {
> +                       compatible = "arm,sp804", "arm,primecell";
> +                       reg = <0x3000000 0x1000>;
> +                       interrupts = <0 224 4>;
> +                       clocks = <&clock HIP04_CLK_50M>;
> +                       clock-names = "apb_pclk";
> +               };

I thought sp804 had two clocks (one for AMBA and one for the actual
timer). What's going on here?

Cheers,
Mark.

^ permalink raw reply	[flat|nested] 55+ messages in thread

* [PATCH v15 06/12] document: dt: add the binding on HiP04 clock
  2014-07-28 17:54   ` Mark Rutland
@ 2014-07-29  2:25     ` Haojian Zhuang
  2014-07-29  9:55       ` Arnd Bergmann
  2014-07-29 12:38       ` Mark Rutland
  0 siblings, 2 replies; 55+ messages in thread
From: Haojian Zhuang @ 2014-07-29  2:25 UTC (permalink / raw)
  To: linux-arm-kernel

On 29 July 2014 01:54, Mark Rutland <mark.rutland@arm.com> wrote:
> On Mon, Jul 28, 2014 at 02:57:50PM +0100, Haojian Zhuang wrote:
>> The DT binding for Hisilicon HiP04 clock driver.
>>
>> Signed-off-by: Haojian Zhuang <haojian.zhuang@linaro.org>
>> ---
>>  .../devicetree/bindings/clock/hip04-clock.txt        | 20 ++++++++++++++++++++
>>  1 file changed, 20 insertions(+)
>>  create mode 100644 Documentation/devicetree/bindings/clock/hip04-clock.txt
>>
>> diff --git a/Documentation/devicetree/bindings/clock/hip04-clock.txt b/Documentation/devicetree/bindings/clock/hip04-clock.txt
>> new file mode 100644
>> index 0000000..4d31ae3
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/clock/hip04-clock.txt
>> @@ -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.
>
> There's only one clock controller on-board and it's custom for HiP04?
>

Since all those PLL settings are configured in bootloader, kernel
don't need to configure it again.

By the way, I don't have the manual to configure those PLLs. All the clocks
are defined as fixed in kernel side.

>> +
>> +- 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>.
>
> This must come in the same patch.
>
> Mark.

HiP04 clock driver is already merged into mainline.

Regards
Haojian

^ permalink raw reply	[flat|nested] 55+ messages in thread

* [PATCH v15 11/12] virt: arm: support hip04 gic
  2014-07-28 18:00   ` Marc Zyngier
@ 2014-07-29  2:31     ` Haojian Zhuang
  2014-07-29  8:47       ` Marc Zyngier
  0 siblings, 1 reply; 55+ messages in thread
From: Haojian Zhuang @ 2014-07-29  2:31 UTC (permalink / raw)
  To: linux-arm-kernel

On 29 July 2014 02:00, Marc Zyngier <marc.zyngier@arm.com> wrote:
> On Mon, Jul 28 2014 at  2:57:55 pm BST, Haojian Zhuang <haojian.zhuang@linaro.org> wrote:
>> 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.
>>
>> Signed-off-by: Haojian Zhuang <haojian.zhuang@linaro.org>
>> ---
>>  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(-)
>>
>> diff --git a/arch/arm/kernel/asm-offsets.c b/arch/arm/kernel/asm-offsets.c
>> index 85598b5..166cc98 100644
>> --- a/arch/arm/kernel/asm-offsets.c
>> +++ b/arch/arm/kernel/asm-offsets.c
>> @@ -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));
>> diff --git a/arch/arm/kvm/interrupts_head.S b/arch/arm/kvm/interrupts_head.S
>> index 76af9302..9fbbf99 100644
>> --- a/arch/arm/kvm/interrupts_head.S
>> +++ b/arch/arm/kvm/interrupts_head.S
>> @@ -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
>
> Use "ubfx r4, r4, #0, #16" instead (with the proper symbolic constants,
> of course). It will save loading this mask from the constant pool. For
> consistency, you can also replace the above mov+lsr with the same
> mechanism.
>
OK

>>  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
>
> Same here.
>

OK
>>  1:   ldr     r6, [r3], #4
>>       str     r6, [r2], #4
>>       subs    r4, r4, #1
>> diff --git a/arch/arm64/kernel/asm-offsets.c b/arch/arm64/kernel/asm-offsets.c
>> index 646f888..2422358 100644
>> --- a/arch/arm64/kernel/asm-offsets.c
>> +++ b/arch/arm64/kernel/asm-offsets.c
>> @@ -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
>> diff --git a/arch/arm64/kvm/hyp.S b/arch/arm64/kvm/hyp.S
>> index b0d1512..2dbe337 100644
>> --- a/arch/arm64/kvm/hyp.S
>> +++ b/arch/arm64/kvm/hyp.S
>> @@ -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]
>
> Have you tested this? It looks to me that you're not dropping the top
> bits, so you're going to end-up with 0x1000004 list registers instead of
> the expected 4 with GIC-400...
>

As you mentioned, GICv2 isn't used in arm64. And the HIP04 GIC isn't
used in arm64 also. I renamed to VGIC_CPU_NR_LR to VGIC_CPU_HW_CFG. It
seems that I needn't drop it as APR offset isn't recorded in
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]
>
> Same here.
>
>>       add     x3, x3, #VGIC_CPU_LR
>>  1:   ldr     w5, [x3], #4
>>  CPU_BE(      rev     w5, w5 )
>> diff --git a/include/kvm/arm_vgic.h b/include/kvm/arm_vgic.h
>> index f27000f..eba4b51 100644
>> --- a/include/kvm/arm_vgic.h
>> +++ b/include/kvm/arm_vgic.h
>> @@ -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;
>> diff --git a/include/linux/irqchip/arm-gic.h b/include/linux/irqchip/arm-gic.h
>> index 45e2d8c..b055f92 100644
>> --- a/include/linux/irqchip/arm-gic.h
>> +++ b/include/linux/irqchip/arm-gic.h
>> @@ -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;
>> diff --git a/virt/kvm/arm/vgic.c b/virt/kvm/arm/vgic.c
>> index 56ff9be..6c0ee89 100644
>> --- a/virt/kvm/arm/vgic.c
>> +++ b/virt/kvm/arm/vgic.c
>> @@ -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),
>
> Most of this is going to conflict very badly with the rest of the GICv3
> patch series which is already queued for 3.17. You'll have to rebase it
> on top of the current kvmarm/queue branch.
>

OK

^ permalink raw reply	[flat|nested] 55+ messages in thread

* [PATCH v15 07/12] ARM: dts: append hip04 dts
  2014-07-28 18:06   ` Mark Rutland
@ 2014-07-29  2:44     ` Haojian Zhuang
  2014-07-29  3:53       ` Olof Johansson
  2014-07-29 12:32       ` Mark Rutland
  0 siblings, 2 replies; 55+ messages in thread
From: Haojian Zhuang @ 2014-07-29  2:44 UTC (permalink / raw)
  To: linux-arm-kernel

On 29 July 2014 02:06, Mark Rutland <mark.rutland@arm.com> wrote:
> On Mon, Jul 28, 2014 at 02:57:51PM +0100, Haojian Zhuang wrote:
>> Add hip04-d01.dts & hip04.dtsi for hip04 SoC platform.
>>
>> Signed-off-by: Haojian Zhuang <haojian.zhuang@linaro.org>
>> ---
>>  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
>>
>> diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
>> index 721525e..6587bbf 100644
>> --- a/arch/arm/boot/dts/Makefile
>> +++ b/arch/arm/boot/dts/Makefile
>> @@ -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 \
>> diff --git a/arch/arm/boot/dts/hip04-d01.dts b/arch/arm/boot/dts/hip04-d01.dts
>> new file mode 100644
>> index 0000000..661c8e5
>> --- /dev/null
>> +++ b/arch/arm/boot/dts/hip04-d01.dts
>> @@ -0,0 +1,39 @@
>> +/*
>> + *  Copyright (C) 2013-2014 Linaro Ltd.
>> + *  Author: Haojian Zhuang <haojian.zhuang@linaro.org>
>> + *
>> + *  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;
>
> How exactly is this bootwrapper used? Is the kernel compiled into it?
>
> It might make more sense for the wrapper build system to inject
> bootwrapper-related properties. Then the DTB is less likely to
> amalgamate hacks to workaround differences between versions, and can be
> used on systems without a wrapper without throwing away some memory.
>

In this platform, we relied on the bootwrapper. If I discard this,
I'll fail to bring up all secondary cores.

>> +
>> +#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>;
>> +       };
>
> You can fold these into a single node.
>

The address spaces of these two memory node are different.
I can't fold them into a single node.

>> +
>> +       soc {
>> +               uart0: uart at 4007000 {
>> +                       status = "ok";
>> +               };
>> +       };
>> +};
>> diff --git a/arch/arm/boot/dts/hip04.dtsi b/arch/arm/boot/dts/hip04.dtsi
>> new file mode 100644
>> index 0000000..30942be
>> --- /dev/null
>> +++ b/arch/arm/boot/dts/hip04.dtsi
>> @@ -0,0 +1,267 @@
>> +/*
>> + * Hisilicon Ltd. HiP04 SoC
>> + *
>> + * Copyright (C) 2013-2014 Hisilicon Ltd.
>> + * Copyright (C) 2013-2014 Linaro Ltd.
>> + *
>> + * Author: Haojian Zhuang <haojian.zhuang@linaro.org>
>> + *
>> + * 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.
>
> s/hh/h/
>

Thanks. I'll fix it.

> [...]
>
>> +       clock: clock {
>> +               compatible = "hisilicon,hip04-clock";
>> +               /* dummy register.
>> +                * Don't need to access clock registers since they're
>> +                * configured in firmware already.
>> +                */
>> +               reg = <0 0 0 0x1000>;
>
> Huh? Whether or not you need to access the registers should be up to the
> kernel, not the DT.
>
> Why can the kernel not access these? This sounds like a hack.
>

Because I didn't get these materials yet. All clocks are enabled in bootloader.

>> +               #clock-cells = <1>;
>> +       };
>> +
>> +       timer {
>> +               compatible = "arm,armv7-timer";
>> +               interrupt-parent = <&gic>;
>> +               interrupts = <1 13 0xf08>,
>> +                            <1 14 0xf08>,
>> +                            <1 11 0xf08>,
>> +                            <1 10 0xf08>;
>> +       };
>> +
>> +       soc {
>> +               /* It's a 32-bit SoC. */
>> +               #address-cells = <1>;
>> +               #size-cells = <1>;
>> +               compatible = "simple-bus";
>> +               interrupt-parent = <&gic>;
>> +               ranges = <0 0 0xe0000000 0x10000000>;
>> +
>> +               gic: interrupt-controller at c01000 {
>> +                       compatible = "hisilicon,hip04-gic";
>> +                       #interrupt-cells = <3>;
>> +                       #address-cells = <0>;
>> +                       interrupt-controller;
>> +                       interrupts = <1 9 0xf04>;
>> +
>> +                       reg = <0xc01000 0x1000>, <0xc02000 0x1000>,
>> +                             <0xc04000 0x2000>, <0xc06000 0x2000>;
>
> Please place these on separate lines. It's easier to read and will match
> what you've done for every other node.
>

OK

>> +               };
>> +
>> +               sysctrl: sysctrl {
>> +                       compatible = "hisilicon,sysctrl";
>> +                       reg = <0x3e00000 0x00100000>;
>> +                       relocation-entry = <0xe0000100>;
>> +                       relocation-size = <0x1000>;
>> +                       bootwrapper-phys = <0x10c00000>;
>> +                       bootwrapper-size = <0x10000>;
>> +                       bootwrapper-magic = <0xa5a5a5a5>;
>
> Are these absolute addresses, or translated per ranges above?
>
> Why are they related to the system controller?
>

I need these parameters. But I can't find a better place.

>> +               };
>> +
>> +               fabric: fabric {
>> +                       compatible = "hisilicon,hip04-fabric";
>> +                       reg = <0x302a000 0x1000>;
>
> How is this going to be used?
>

Fabric could configure snoop filter of multiple cluster. I don't have
the manual. I only know this.

>> +               };
>> +
>> +               dual_timer0: dual_timer at 3000000 {
>> +                       compatible = "arm,sp804", "arm,primecell";
>> +                       reg = <0x3000000 0x1000>;
>> +                       interrupts = <0 224 4>;
>> +                       clocks = <&clock HIP04_CLK_50M>;
>> +                       clock-names = "apb_pclk";
>> +               };
>
> I thought sp804 had two clocks (one for AMBA and one for the actual
> timer). What's going on here?
>

If only one clock is configured at here, sp804 driver believes that
clk2 is same as clk1.

Regards
Haojian

^ permalink raw reply	[flat|nested] 55+ messages in thread

* [PATCH v15 07/12] ARM: dts: append hip04 dts
  2014-07-29  2:44     ` Haojian Zhuang
@ 2014-07-29  3:53       ` Olof Johansson
  2014-07-29  4:00         ` Olof Johansson
                           ` (2 more replies)
  2014-07-29 12:32       ` Mark Rutland
  1 sibling, 3 replies; 55+ messages in thread
From: Olof Johansson @ 2014-07-29  3:53 UTC (permalink / raw)
  To: linux-arm-kernel

Hi,


On Tue, Jul 29, 2014 at 10:44:40AM +0800, Haojian Zhuang wrote:
> On 29 July 2014 02:06, Mark Rutland <mark.rutland@arm.com> wrote:
> > On Mon, Jul 28, 2014 at 02:57:51PM +0100, Haojian Zhuang wrote:
> >> +/*
> >> + *  Copyright (C) 2013-2014 Linaro Ltd.
> >> + *  Author: Haojian Zhuang <haojian.zhuang@linaro.org>
> >> + *
> >> + *  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;
> >
> > How exactly is this bootwrapper used? Is the kernel compiled into it?
> >
> > It might make more sense for the wrapper build system to inject
> > bootwrapper-related properties. Then the DTB is less likely to
> > amalgamate hacks to workaround differences between versions, and can be
> > used on systems without a wrapper without throwing away some memory.
> >
> 
> In this platform, we relied on the bootwrapper. If I discard this,
> I'll fail to bring up all secondary cores.

What is this memory used for? Is this where the cores are parked on the spin
table, or something else? Does your platform have runtime firmware?

> >> +
> >> +#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>;
> >> +       };
> >
> > You can fold these into a single node.
> >
> 
> The address spaces of these two memory node are different.
> I can't fold them into a single node.

There's no functional difference today between having two memory nodes or one
node with two ranges. It would be:
	memory at 0 {
		device_type = "memory";
		reg = <0x00000000 0x10000000 0x00000000 0xc0000000>,
		      <0x00000004 0xc0000000 0x00000003 0x40000000>;

> >> +
> >> +       soc {
> >> +               uart0: uart at 4007000 {
> >> +                       status = "ok";
> >> +               };
> >> +       };
> >> +};
> >> diff --git a/arch/arm/boot/dts/hip04.dtsi b/arch/arm/boot/dts/hip04.dtsi
> >> new file mode 100644
> >> index 0000000..30942be
> >> --- /dev/null
> >> +++ b/arch/arm/boot/dts/hip04.dtsi
> >> @@ -0,0 +1,267 @@
> >> +/*
> >> + * Hisilicon Ltd. HiP04 SoC
> >> + *
> >> + * Copyright (C) 2013-2014 Hisilicon Ltd.
> >> + * Copyright (C) 2013-2014 Linaro Ltd.
> >> + *
> >> + * Author: Haojian Zhuang <haojian.zhuang@linaro.org>
> >> + *
> >> + * 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.
> >
> > s/hh/h/
> >
> 
> Thanks. I'll fix it.
> 
> > [...]
> >
> >> +       clock: clock {
> >> +               compatible = "hisilicon,hip04-clock";
> >> +               /* dummy register.
> >> +                * Don't need to access clock registers since they're
> >> +                * configured in firmware already.
> >> +                */
> >> +               reg = <0 0 0 0x1000>;
> >
> > Huh? Whether or not you need to access the registers should be up to the
> > kernel, not the DT.
> >
> > Why can the kernel not access these? This sounds like a hack.
> >
> 
> Because I didn't get these materials yet. All clocks are enabled in bootloader.

What materials? Technical documentation for the CPU you're upstreaming?

It seems like a very bad idea to upstream a DT for a CPU that you don't
have documentation for. It seems appropriate to wait until you have
documentation so you can make sure that the hardware you're describing
is actually what is there, and not something made-up or misdescribed.

> >> +               };
> >> +
> >> +               sysctrl: sysctrl {
> >> +                       compatible = "hisilicon,sysctrl";
> >> +                       reg = <0x3e00000 0x00100000>;
> >> +                       relocation-entry = <0xe0000100>;
> >> +                       relocation-size = <0x1000>;
> >> +                       bootwrapper-phys = <0x10c00000>;
> >> +                       bootwrapper-size = <0x10000>;
> >> +                       bootwrapper-magic = <0xa5a5a5a5>;
> >
> > Are these absolute addresses, or translated per ranges above?
> >
> > Why are they related to the system controller?
> >
> 
> I need these parameters. But I can't find a better place.

Again, what is the boot wrapper in this case? And what do you need them for?

> >> +               };
> >> +
> >> +               fabric: fabric {
> >> +                       compatible = "hisilicon,hip04-fabric";
> >> +                       reg = <0x302a000 0x1000>;
> >
> > How is this going to be used?
> >
> 
> Fabric could configure snoop filter of multiple cluster. I don't have
> the manual. I only know this.

What driver is going to bind against this? It probably makes sense to leave
this out until the consumer is also upstreamed, to have something to have as
a base for discussion.


-Olof

^ permalink raw reply	[flat|nested] 55+ messages in thread

* [PATCH v15 07/12] ARM: dts: append hip04 dts
  2014-07-29  3:53       ` Olof Johansson
@ 2014-07-29  4:00         ` Olof Johansson
  2014-08-01 12:02           ` Haojian Zhuang
  2014-07-29 10:58         ` Haojian Zhuang
  2014-07-29 11:12         ` Will Deacon
  2 siblings, 1 reply; 55+ messages in thread
From: Olof Johansson @ 2014-07-29  4:00 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Jul 28, 2014 at 8:53 PM, Olof Johansson <olof@lixom.net> wrote:
> Hi,
>
>
> On Tue, Jul 29, 2014 at 10:44:40AM +0800, Haojian Zhuang wrote:
>> On 29 July 2014 02:06, Mark Rutland <mark.rutland@arm.com> wrote:
>> > On Mon, Jul 28, 2014 at 02:57:51PM +0100, Haojian Zhuang wrote:
>> >> +/*
>> >> + *  Copyright (C) 2013-2014 Linaro Ltd.
>> >> + *  Author: Haojian Zhuang <haojian.zhuang@linaro.org>
>> >> + *
>> >> + *  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;
>> >
>> > How exactly is this bootwrapper used? Is the kernel compiled into it?
>> >
>> > It might make more sense for the wrapper build system to inject
>> > bootwrapper-related properties. Then the DTB is less likely to
>> > amalgamate hacks to workaround differences between versions, and can be
>> > used on systems without a wrapper without throwing away some memory.
>> >
>>
>> In this platform, we relied on the bootwrapper. If I discard this,
>> I'll fail to bring up all secondary cores.
>
> What is this memory used for? Is this where the cores are parked on the spin
> table, or something else? Does your platform have runtime firmware?
>
>> >> +
>> >> +#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>;
>> >> +       };
>> >
>> > You can fold these into a single node.
>> >
>>
>> The address spaces of these two memory node are different.
>> I can't fold them into a single node.
>
> There's no functional difference today between having two memory nodes or one
> node with two ranges. It would be:
>         memory at 0 {
>                 device_type = "memory";
>                 reg = <0x00000000 0x10000000 0x00000000 0xc0000000>,
>                       <0x00000004 0xc0000000 0x00000003 0x40000000>;
>
>> >> +
>> >> +       soc {
>> >> +               uart0: uart at 4007000 {
>> >> +                       status = "ok";
>> >> +               };
>> >> +       };
>> >> +};
>> >> diff --git a/arch/arm/boot/dts/hip04.dtsi b/arch/arm/boot/dts/hip04.dtsi
>> >> new file mode 100644
>> >> index 0000000..30942be
>> >> --- /dev/null
>> >> +++ b/arch/arm/boot/dts/hip04.dtsi
>> >> @@ -0,0 +1,267 @@
>> >> +/*
>> >> + * Hisilicon Ltd. HiP04 SoC
>> >> + *
>> >> + * Copyright (C) 2013-2014 Hisilicon Ltd.
>> >> + * Copyright (C) 2013-2014 Linaro Ltd.
>> >> + *
>> >> + * Author: Haojian Zhuang <haojian.zhuang@linaro.org>
>> >> + *
>> >> + * 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.
>> >
>> > s/hh/h/
>> >
>>
>> Thanks. I'll fix it.
>>
>> > [...]
>> >
>> >> +       clock: clock {
>> >> +               compatible = "hisilicon,hip04-clock";
>> >> +               /* dummy register.
>> >> +                * Don't need to access clock registers since they're
>> >> +                * configured in firmware already.
>> >> +                */
>> >> +               reg = <0 0 0 0x1000>;
>> >
>> > Huh? Whether or not you need to access the registers should be up to the
>> > kernel, not the DT.
>> >
>> > Why can the kernel not access these? This sounds like a hack.
>> >
>>
>> Because I didn't get these materials yet. All clocks are enabled in bootloader.
>
> What materials? Technical documentation for the CPU you're upstreaming?
>
> It seems like a very bad idea to upstream a DT for a CPU that you don't
> have documentation for. It seems appropriate to wait until you have
> documentation so you can make sure that the hardware you're describing
> is actually what is there, and not something made-up or misdescribed.
>
>> >> +               };
>> >> +
>> >> +               sysctrl: sysctrl {
>> >> +                       compatible = "hisilicon,sysctrl";

I think you already got the comment somewhere else that this property
is much to generic, but if not: It needs to be more specific than
this.

>> >> +                       reg = <0x3e00000 0x00100000>;
>> >> +                       relocation-entry = <0xe0000100>;
>> >> +                       relocation-size = <0x1000>;
>> >> +                       bootwrapper-phys = <0x10c00000>;
>> >> +                       bootwrapper-size = <0x10000>;
>> >> +                       bootwrapper-magic = <0xa5a5a5a5>;
>> >
>> > Are these absolute addresses, or translated per ranges above?
>> >
>> > Why are they related to the system controller?
>> >
>>
>> I need these parameters. But I can't find a better place.
>
> Again, what is the boot wrapper in this case? And what do you need them for?

Ok, looking at patch 3/12, it seems that the "bootwrapper" base
address is used to specify where the CPU goes when released by the
system controller.

Isn't there an address that can be written in the system controller
that specifies this base address, such that you can just handle this
dynamically at runtime? It seems really, really odd that the platform
will expect this one page in the middle of ram to just be untouched
otherwise.



-Olof

^ permalink raw reply	[flat|nested] 55+ messages in thread

* [PATCH v15 08/12] ARM: config: append lpae configuration
  2014-07-28 13:57 ` [PATCH v15 08/12] ARM: config: append lpae configuration Haojian Zhuang
@ 2014-07-29  4:05   ` Olof Johansson
  2014-07-29 10:43     ` Haojian Zhuang
  0 siblings, 1 reply; 55+ messages in thread
From: Olof Johansson @ 2014-07-29  4:05 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Jul 28, 2014 at 09:57:52PM +0800, Haojian Zhuang wrote:
> Append multi_v7_lpae_config. In this default configuration,
> CONFIG_ARCH_MULTI_V6 is disabled. CONFIG_ARM_LPAE is enabled.

NACK. This is the nth time I have had to nack this patch.

You are enabling platforms here that don't have LPAE. Don't do that.

It's trivial to create a LPAE version of multi_v7 defconfig locally.


-Olof

^ permalink raw reply	[flat|nested] 55+ messages in thread

* [PATCH v15 09/12] ARM: config: append hip04_defconfig
  2014-07-28 13:57 ` [PATCH v15 09/12] ARM: config: append hip04_defconfig Haojian Zhuang
@ 2014-07-29  4:07   ` Olof Johansson
  0 siblings, 0 replies; 55+ messages in thread
From: Olof Johansson @ 2014-07-29  4:07 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Jul 28, 2014 at 09:57:53PM +0800, Haojian Zhuang wrote:
> Select HiP04 SoC configuration by hip04_defconfig.

Your subject says "append hip04_defconfig", but this adds it.

Also, the one-sentence description doesn't quite make sense.

We normally keep one defconfig per vendors these days. For server platforms,
having per-vendor configs doesn't make sense in the same way as embedded
platforms, since enabling a few extra platforms and drivers isn't nearly as big
a deal with you have 12.5GB RAM.

So, please just enable your drivers in multi_v7 and don't add a
hip04_defconfig.


-Olof

^ permalink raw reply	[flat|nested] 55+ messages in thread

* [PATCH v15 10/12] ARM: hisi: enable erratum 798181 of A15 on HiP04
  2014-07-28 13:57 ` [PATCH v15 10/12] ARM: hisi: enable erratum 798181 of A15 on HiP04 Haojian Zhuang
@ 2014-07-29  4:08   ` Olof Johansson
  2014-07-29 10:41     ` Haojian Zhuang
  0 siblings, 1 reply; 55+ messages in thread
From: Olof Johansson @ 2014-07-29  4:08 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Jul 28, 2014 at 09:57:54PM +0800, Haojian Zhuang wrote:
> From: Kefeng Wang <kefeng.wang@linaro.org>
> 
> 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).
> 
> Signed-off-by: Kefeng Wang <kefeng.wang@linaro.org>
> Singed-off-by: Haojian Zhuang <haojian.zhuang@linaro.org>

There's no need to do this as a separate patch if you just added this entry in
a different patch in the same series -- just fold this in with that.


-Olof

^ permalink raw reply	[flat|nested] 55+ messages in thread

* [PATCH v15 11/12] virt: arm: support hip04 gic
  2014-07-29  2:31     ` Haojian Zhuang
@ 2014-07-29  8:47       ` Marc Zyngier
  0 siblings, 0 replies; 55+ messages in thread
From: Marc Zyngier @ 2014-07-29  8:47 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Jul 29 2014 at  3:31:52 am BST, Haojian Zhuang <haojian.zhuang@linaro.org> wrote:
> On 29 July 2014 02:00, Marc Zyngier <marc.zyngier@arm.com> wrote:
>> On Mon, Jul 28 2014 at 2:57:55 pm BST, Haojian Zhuang
>> <haojian.zhuang@linaro.org> wrote:
>>> 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.
>>>
>>> Signed-off-by: Haojian Zhuang <haojian.zhuang@linaro.org>
>>> ---
>>>  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(-)
>>>
>>> diff --git a/arch/arm/kernel/asm-offsets.c b/arch/arm/kernel/asm-offsets.c
>>> index 85598b5..166cc98 100644
>>> --- a/arch/arm/kernel/asm-offsets.c
>>> +++ b/arch/arm/kernel/asm-offsets.c
>>> @@ -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));
>>> diff --git a/arch/arm/kvm/interrupts_head.S b/arch/arm/kvm/interrupts_head.S
>>> index 76af9302..9fbbf99 100644
>>> --- a/arch/arm/kvm/interrupts_head.S
>>> +++ b/arch/arm/kvm/interrupts_head.S
>>> @@ -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
>>
>> Use "ubfx r4, r4, #0, #16" instead (with the proper symbolic constants,
>> of course). It will save loading this mask from the constant pool. For
>> consistency, you can also replace the above mov+lsr with the same
>> mechanism.
>>
> OK
>
>>>  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
>>
>> Same here.
>>
>
> OK
>>>  1:   ldr     r6, [r3], #4
>>>       str     r6, [r2], #4
>>>       subs    r4, r4, #1
>>> diff --git a/arch/arm64/kernel/asm-offsets.c b/arch/arm64/kernel/asm-offsets.c
>>> index 646f888..2422358 100644
>>> --- a/arch/arm64/kernel/asm-offsets.c
>>> +++ b/arch/arm64/kernel/asm-offsets.c
>>> @@ -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
>>> diff --git a/arch/arm64/kvm/hyp.S b/arch/arm64/kvm/hyp.S
>>> index b0d1512..2dbe337 100644
>>> --- a/arch/arm64/kvm/hyp.S
>>> +++ b/arch/arm64/kvm/hyp.S
>>> @@ -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]
>>
>> Have you tested this? It looks to me that you're not dropping the top
>> bits, so you're going to end-up with 0x1000004 list registers instead of
>> the expected 4 with GIC-400...
>>
>
> As you mentioned, GICv2 isn't used in arm64. And the HIP04 GIC isn't
> used in arm64 also. I renamed to VGIC_CPU_NR_LR to VGIC_CPU_HW_CFG. It
> seems that I needn't drop it as APR offset isn't recorded in
> VGIC_CPU_HW_CFG.

If you understood that arm64 didn't use GICv2, I must have expressed
myself extremely badly. What do you think this code does? The only
saving grace is that the is no FrankenGIC involved here, and we just
have to trim the offset.

Thanks,

	M.
-- 
Jazz is not dead. It just smells funny.

^ permalink raw reply	[flat|nested] 55+ messages in thread

* [PATCH v15 06/12] document: dt: add the binding on HiP04 clock
  2014-07-29  2:25     ` Haojian Zhuang
@ 2014-07-29  9:55       ` Arnd Bergmann
  2014-07-29 10:40         ` Haojian Zhuang
  2014-07-29 12:38       ` Mark Rutland
  1 sibling, 1 reply; 55+ messages in thread
From: Arnd Bergmann @ 2014-07-29  9:55 UTC (permalink / raw)
  To: linux-arm-kernel

On Tuesday 29 July 2014 10:25:49 Haojian Zhuang wrote:
> On 29 July 2014 01:54, Mark Rutland <mark.rutland@arm.com> wrote:
> > On Mon, Jul 28, 2014 at 02:57:50PM +0100, Haojian Zhuang wrote:
> >> The DT binding for Hisilicon HiP04 clock driver.
> >>
> >> Signed-off-by: Haojian Zhuang <haojian.zhuang@linaro.org>
> >> ---
> >>  .../devicetree/bindings/clock/hip04-clock.txt        | 20 ++++++++++++++++++++
> >>  1 file changed, 20 insertions(+)
> >>  create mode 100644 Documentation/devicetree/bindings/clock/hip04-clock.txt
> >>
> >> diff --git a/Documentation/devicetree/bindings/clock/hip04-clock.txt b/Documentation/devicetree/bindings/clock/hip04-clock.txt
> >> new file mode 100644
> >> index 0000000..4d31ae3
> >> --- /dev/null
> >> +++ b/Documentation/devicetree/bindings/clock/hip04-clock.txt
> >> @@ -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.
> >
> > There's only one clock controller on-board and it's custom for HiP04?
> >
> 
> Since all those PLL settings are configured in bootloader, kernel
> don't need to configure it again.
> 
> By the way, I don't have the manual to configure those PLLs. All the clocks
> are defined as fixed in kernel side.
> 

If all the clocks are fixed-rate, you don't actually need a driver
for them, just use the regular fixed-rate clock and define one
node per clock.

	Arnd

^ permalink raw reply	[flat|nested] 55+ messages in thread

* [PATCH v15 06/12] document: dt: add the binding on HiP04 clock
  2014-07-29  9:55       ` Arnd Bergmann
@ 2014-07-29 10:40         ` Haojian Zhuang
  0 siblings, 0 replies; 55+ messages in thread
From: Haojian Zhuang @ 2014-07-29 10:40 UTC (permalink / raw)
  To: linux-arm-kernel

On 29 July 2014 17:55, Arnd Bergmann <arnd@arndb.de> wrote:
> On Tuesday 29 July 2014 10:25:49 Haojian Zhuang wrote:
>> On 29 July 2014 01:54, Mark Rutland <mark.rutland@arm.com> wrote:
>> > On Mon, Jul 28, 2014 at 02:57:50PM +0100, Haojian Zhuang wrote:
>> >> The DT binding for Hisilicon HiP04 clock driver.
>> >>
>> >> Signed-off-by: Haojian Zhuang <haojian.zhuang@linaro.org>
>> >> ---
>> >>  .../devicetree/bindings/clock/hip04-clock.txt        | 20 ++++++++++++++++++++
>> >>  1 file changed, 20 insertions(+)
>> >>  create mode 100644 Documentation/devicetree/bindings/clock/hip04-clock.txt
>> >>
>> >> diff --git a/Documentation/devicetree/bindings/clock/hip04-clock.txt b/Documentation/devicetree/bindings/clock/hip04-clock.txt
>> >> new file mode 100644
>> >> index 0000000..4d31ae3
>> >> --- /dev/null
>> >> +++ b/Documentation/devicetree/bindings/clock/hip04-clock.txt
>> >> @@ -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.
>> >
>> > There's only one clock controller on-board and it's custom for HiP04?
>> >
>>
>> Since all those PLL settings are configured in bootloader, kernel
>> don't need to configure it again.
>>
>> By the way, I don't have the manual to configure those PLLs. All the clocks
>> are defined as fixed in kernel side.
>>
>
> If all the clocks are fixed-rate, you don't actually need a driver
> for them, just use the regular fixed-rate clock and define one
> node per clock.
>
>         Arnd

OK. I'll update it.

Regards
Haojian

^ permalink raw reply	[flat|nested] 55+ messages in thread

* [PATCH v15 10/12] ARM: hisi: enable erratum 798181 of A15 on HiP04
  2014-07-29  4:08   ` Olof Johansson
@ 2014-07-29 10:41     ` Haojian Zhuang
  0 siblings, 0 replies; 55+ messages in thread
From: Haojian Zhuang @ 2014-07-29 10:41 UTC (permalink / raw)
  To: linux-arm-kernel

On 29 July 2014 12:08, Olof Johansson <olof@lixom.net> wrote:
> On Mon, Jul 28, 2014 at 09:57:54PM +0800, Haojian Zhuang wrote:
>> From: Kefeng Wang <kefeng.wang@linaro.org>
>>
>> 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).
>>
>> Signed-off-by: Kefeng Wang <kefeng.wang@linaro.org>
>> Singed-off-by: Haojian Zhuang <haojian.zhuang@linaro.org>
>
> There's no need to do this as a separate patch if you just added this entry in
> a different patch in the same series -- just fold this in with that.
>
>
> -Olof

OK

Regards
Haojian

^ permalink raw reply	[flat|nested] 55+ messages in thread

* [PATCH v15 08/12] ARM: config: append lpae configuration
  2014-07-29  4:05   ` Olof Johansson
@ 2014-07-29 10:43     ` Haojian Zhuang
  2014-07-31  1:01       ` Olof Johansson
  0 siblings, 1 reply; 55+ messages in thread
From: Haojian Zhuang @ 2014-07-29 10:43 UTC (permalink / raw)
  To: linux-arm-kernel

On 29 July 2014 12:05, Olof Johansson <olof@lixom.net> wrote:
> On Mon, Jul 28, 2014 at 09:57:52PM +0800, Haojian Zhuang wrote:
>> Append multi_v7_lpae_config. In this default configuration,
>> CONFIG_ARCH_MULTI_V6 is disabled. CONFIG_ARM_LPAE is enabled.
>
> NACK. This is the nth time I have had to nack this patch.
>
> You are enabling platforms here that don't have LPAE. Don't do that.
>
> It's trivial to create a LPAE version of multi_v7 defconfig locally.
>
>
> -Olof

I tried to remove those SoCs that can't support LPAE. But I don't know
every platform in details.

How about that I only enable HIP04 in multi_v7_lpae_defconfig. If you
think any platform could be added, please help to list it. Then I
could append them into the multi_v7_lpae_defconfig.

Regards
Haojian

^ permalink raw reply	[flat|nested] 55+ messages in thread

* [PATCH v15 07/12] ARM: dts: append hip04 dts
  2014-07-29  3:53       ` Olof Johansson
  2014-07-29  4:00         ` Olof Johansson
@ 2014-07-29 10:58         ` Haojian Zhuang
  2014-07-29 16:56           ` Olof Johansson
  2014-07-29 11:12         ` Will Deacon
  2 siblings, 1 reply; 55+ messages in thread
From: Haojian Zhuang @ 2014-07-29 10:58 UTC (permalink / raw)
  To: linux-arm-kernel

On 29 July 2014 11:53, Olof Johansson <olof@lixom.net> wrote:
> Hi,
>
>
> On Tue, Jul 29, 2014 at 10:44:40AM +0800, Haojian Zhuang wrote:
>> On 29 July 2014 02:06, Mark Rutland <mark.rutland@arm.com> wrote:
>> > On Mon, Jul 28, 2014 at 02:57:51PM +0100, Haojian Zhuang wrote:
>> >> +/*
>> >> + *  Copyright (C) 2013-2014 Linaro Ltd.
>> >> + *  Author: Haojian Zhuang <haojian.zhuang@linaro.org>
>> >> + *
>> >> + *  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;
>> >
>> > How exactly is this bootwrapper used? Is the kernel compiled into it?
>> >
>> > It might make more sense for the wrapper build system to inject
>> > bootwrapper-related properties. Then the DTB is less likely to
>> > amalgamate hacks to workaround differences between versions, and can be
>> > used on systems without a wrapper without throwing away some memory.
>> >
>>
>> In this platform, we relied on the bootwrapper. If I discard this,
>> I'll fail to bring up all secondary cores.
>
> What is this memory used for? Is this where the cores are parked on the spin
> table, or something else? Does your platform have runtime firmware?
>

This memory stores the instructions that secondary cores will execute initially.

They will switch cores into non-secure & hyp mode.

There's no runtime firmware in this platform. And there's no schedule
to support it.

>> >> +
>> >> +#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>;
>> >> +       };
>> >
>> > You can fold these into a single node.
>> >
>>
>> The address spaces of these two memory node are different.
>> I can't fold them into a single node.
>
> There's no functional difference today between having two memory nodes or one
> node with two ranges. It would be:
>         memory at 0 {
>                 device_type = "memory";
>                 reg = <0x00000000 0x10000000 0x00000000 0xc0000000>,
>                       <0x00000004 0xc0000000 0x00000003 0x40000000>;
>

OK.

>> >> +
>> >> +       soc {
>> >> +               uart0: uart at 4007000 {
>> >> +                       status = "ok";
>> >> +               };
>> >> +       };
>> >> +};
>> >> diff --git a/arch/arm/boot/dts/hip04.dtsi b/arch/arm/boot/dts/hip04.dtsi
>> >> new file mode 100644
>> >> index 0000000..30942be
>> >> --- /dev/null
>> >> +++ b/arch/arm/boot/dts/hip04.dtsi
>> >> @@ -0,0 +1,267 @@
>> >> +/*
>> >> + * Hisilicon Ltd. HiP04 SoC
>> >> + *
>> >> + * Copyright (C) 2013-2014 Hisilicon Ltd.
>> >> + * Copyright (C) 2013-2014 Linaro Ltd.
>> >> + *
>> >> + * Author: Haojian Zhuang <haojian.zhuang@linaro.org>
>> >> + *
>> >> + * 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.
>> >
>> > s/hh/h/
>> >
>>
>> Thanks. I'll fix it.
>>
>> > [...]
>> >
>> >> +       clock: clock {
>> >> +               compatible = "hisilicon,hip04-clock";
>> >> +               /* dummy register.
>> >> +                * Don't need to access clock registers since they're
>> >> +                * configured in firmware already.
>> >> +                */
>> >> +               reg = <0 0 0 0x1000>;
>> >
>> > Huh? Whether or not you need to access the registers should be up to the
>> > kernel, not the DT.
>> >
>> > Why can the kernel not access these? This sounds like a hack.
>> >
>>
>> Because I didn't get these materials yet. All clocks are enabled in bootloader.
>
> What materials? Technical documentation for the CPU you're upstreaming?
>
> It seems like a very bad idea to upstream a DT for a CPU that you don't
> have documentation for. It seems appropriate to wait until you have
> documentation so you can make sure that the hardware you're describing
> is actually what is there, and not something made-up or misdescribed.
>
>> >> +               };
>> >> +
>> >> +               sysctrl: sysctrl {
>> >> +                       compatible = "hisilicon,sysctrl";
>> >> +                       reg = <0x3e00000 0x00100000>;
>> >> +                       relocation-entry = <0xe0000100>;
>> >> +                       relocation-size = <0x1000>;
>> >> +                       bootwrapper-phys = <0x10c00000>;
>> >> +                       bootwrapper-size = <0x10000>;
>> >> +                       bootwrapper-magic = <0xa5a5a5a5>;
>> >
>> > Are these absolute addresses, or translated per ranges above?
>> >
>> > Why are they related to the system controller?
>> >
>>
>> I need these parameters. But I can't find a better place.
>
> Again, what is the boot wrapper in this case? And what do you need them for?
>

Now UEFI didn't switch secondary cores to non-secure & hyp mode. The
bootwrapper is used to handle this job. Then bootwrapper will jump to
kernel to continue boot SMP. So the relocation area is used to store
the SMP entrance.

SMP feature will fail without bootwrapper in this platform.

>> >> +               };
>> >> +
>> >> +               fabric: fabric {
>> >> +                       compatible = "hisilicon,hip04-fabric";
>> >> +                       reg = <0x302a000 0x1000>;
>> >
>> > How is this going to be used?
>> >
>>
>> Fabric could configure snoop filter of multiple cluster. I don't have
>> the manual. I only know this.
>
> What driver is going to bind against this? It probably makes sense to leave
> this out until the consumer is also upstreamed, to have something to have as
> a base for discussion.

Only one register is configured in the fabric by kernel. Do we need a driver?

This register is only used when we power up/down the cluster. MCPM
framework could help to call the function to configure this register.

Regards
Haojian

^ permalink raw reply	[flat|nested] 55+ messages in thread

* [PATCH v15 07/12] ARM: dts: append hip04 dts
  2014-07-29  3:53       ` Olof Johansson
  2014-07-29  4:00         ` Olof Johansson
  2014-07-29 10:58         ` Haojian Zhuang
@ 2014-07-29 11:12         ` Will Deacon
  2014-07-29 11:32           ` Haojian Zhuang
  2 siblings, 1 reply; 55+ messages in thread
From: Will Deacon @ 2014-07-29 11:12 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Jul 29, 2014 at 04:53:21AM +0100, Olof Johansson wrote:
> On Tue, Jul 29, 2014 at 10:44:40AM +0800, Haojian Zhuang wrote:
> > Because I didn't get these materials yet. All clocks are enabled in bootloader.
> 
> What materials? Technical documentation for the CPU you're upstreaming?
> 
> It seems like a very bad idea to upstream a DT for a CPU that you don't
> have documentation for. It seems appropriate to wait until you have
> documentation so you can make sure that the hardware you're describing
> is actually what is there, and not something made-up or misdescribed.

I completely agree. Furthermore, given that this SoC implements a dodgy
custom GIC, I don't think it's unreasonable for us to ask for documentation
describing that too, otherwise it's going to make maintaining a complicated
irqchip driver that much worse.

Will

^ permalink raw reply	[flat|nested] 55+ messages in thread

* [PATCH v15 07/12] ARM: dts: append hip04 dts
  2014-07-29 11:12         ` Will Deacon
@ 2014-07-29 11:32           ` Haojian Zhuang
  2014-07-29 12:13             ` Will Deacon
  0 siblings, 1 reply; 55+ messages in thread
From: Haojian Zhuang @ 2014-07-29 11:32 UTC (permalink / raw)
  To: linux-arm-kernel

On 29 July 2014 19:12, Will Deacon <will.deacon@arm.com> wrote:
> On Tue, Jul 29, 2014 at 04:53:21AM +0100, Olof Johansson wrote:
>> On Tue, Jul 29, 2014 at 10:44:40AM +0800, Haojian Zhuang wrote:
>> > Because I didn't get these materials yet. All clocks are enabled in bootloader.
>>
>> What materials? Technical documentation for the CPU you're upstreaming?
>>
>> It seems like a very bad idea to upstream a DT for a CPU that you don't
>> have documentation for. It seems appropriate to wait until you have
>> documentation so you can make sure that the hardware you're describing
>> is actually what is there, and not something made-up or misdescribed.
>
> I completely agree. Furthermore, given that this SoC implements a dodgy
> custom GIC, I don't think it's unreasonable for us to ask for documentation
> describing that too, otherwise it's going to make maintaining a complicated
> irqchip driver that much worse.
>
> Will

I don't have enough documents on clocks. And all clocks are already
enabled in UEFI. There're also no requirement on change the clock
frequency & disable them. So I set all these clocks as fixed rate.

It's different from GIC. If I don't have documents on GIC, I can't
write code for HIP04 GIC. HiP04 GIC supports 16-cores. ARM GICv2
supports 8-cores. So some registers offsets and bit fields are
different from GICv2.

Regards
Haojian

^ permalink raw reply	[flat|nested] 55+ messages in thread

* [PATCH v15 07/12] ARM: dts: append hip04 dts
  2014-07-29 11:32           ` Haojian Zhuang
@ 2014-07-29 12:13             ` Will Deacon
  2014-07-29 12:15               ` Haojian Zhuang
  0 siblings, 1 reply; 55+ messages in thread
From: Will Deacon @ 2014-07-29 12:13 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Jul 29, 2014 at 12:32:09PM +0100, Haojian Zhuang wrote:
> On 29 July 2014 19:12, Will Deacon <will.deacon@arm.com> wrote:
> > On Tue, Jul 29, 2014 at 04:53:21AM +0100, Olof Johansson wrote:
> >> On Tue, Jul 29, 2014 at 10:44:40AM +0800, Haojian Zhuang wrote:
> >> > Because I didn't get these materials yet. All clocks are enabled in bootloader.
> >>
> >> What materials? Technical documentation for the CPU you're upstreaming?
> >>
> >> It seems like a very bad idea to upstream a DT for a CPU that you don't
> >> have documentation for. It seems appropriate to wait until you have
> >> documentation so you can make sure that the hardware you're describing
> >> is actually what is there, and not something made-up or misdescribed.
> >
> > I completely agree. Furthermore, given that this SoC implements a dodgy
> > custom GIC, I don't think it's unreasonable for us to ask for documentation
> > describing that too, otherwise it's going to make maintaining a complicated
> > irqchip driver that much worse.
> >
> I don't have enough documents on clocks. And all clocks are already
> enabled in UEFI. There're also no requirement on change the clock
> frequency & disable them. So I set all these clocks as fixed rate.
> 
> It's different from GIC. If I don't have documents on GIC, I can't
> write code for HIP04 GIC. HiP04 GIC supports 16-cores. ARM GICv2
> supports 8-cores. So some registers offsets and bit fields are
> different from GICv2.

Sure, and I'm asking for those documents to be made publicly available
somewhere so that we can refer to them if we need to change this code in
future.

Will

^ permalink raw reply	[flat|nested] 55+ messages in thread

* [PATCH v15 07/12] ARM: dts: append hip04 dts
  2014-07-29 12:13             ` Will Deacon
@ 2014-07-29 12:15               ` Haojian Zhuang
  2014-07-29 12:22                 ` Will Deacon
  0 siblings, 1 reply; 55+ messages in thread
From: Haojian Zhuang @ 2014-07-29 12:15 UTC (permalink / raw)
  To: linux-arm-kernel

On 29 July 2014 20:13, Will Deacon <will.deacon@arm.com> wrote:
> On Tue, Jul 29, 2014 at 12:32:09PM +0100, Haojian Zhuang wrote:
>> On 29 July 2014 19:12, Will Deacon <will.deacon@arm.com> wrote:
>> > On Tue, Jul 29, 2014 at 04:53:21AM +0100, Olof Johansson wrote:
>> >> On Tue, Jul 29, 2014 at 10:44:40AM +0800, Haojian Zhuang wrote:
>> >> > Because I didn't get these materials yet. All clocks are enabled in bootloader.
>> >>
>> >> What materials? Technical documentation for the CPU you're upstreaming?
>> >>
>> >> It seems like a very bad idea to upstream a DT for a CPU that you don't
>> >> have documentation for. It seems appropriate to wait until you have
>> >> documentation so you can make sure that the hardware you're describing
>> >> is actually what is there, and not something made-up or misdescribed.
>> >
>> > I completely agree. Furthermore, given that this SoC implements a dodgy
>> > custom GIC, I don't think it's unreasonable for us to ask for documentation
>> > describing that too, otherwise it's going to make maintaining a complicated
>> > irqchip driver that much worse.
>> >
>> I don't have enough documents on clocks. And all clocks are already
>> enabled in UEFI. There're also no requirement on change the clock
>> frequency & disable them. So I set all these clocks as fixed rate.
>>
>> It's different from GIC. If I don't have documents on GIC, I can't
>> write code for HIP04 GIC. HiP04 GIC supports 16-cores. ARM GICv2
>> supports 8-cores. So some registers offsets and bit fields are
>> different from GICv2.
>
> Sure, and I'm asking for those documents to be made publicly available
> somewhere so that we can refer to them if we need to change this code in
> future.
>
> Will

I can send the copy to you since it's already public. But the main
issue is that this document is written in Chinese. I hope it could be
written in English.

Regards
Haojian

^ permalink raw reply	[flat|nested] 55+ messages in thread

* [PATCH v15 07/12] ARM: dts: append hip04 dts
  2014-07-29 12:15               ` Haojian Zhuang
@ 2014-07-29 12:22                 ` Will Deacon
  0 siblings, 0 replies; 55+ messages in thread
From: Will Deacon @ 2014-07-29 12:22 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Jul 29, 2014 at 01:15:45PM +0100, Haojian Zhuang wrote:
> On 29 July 2014 20:13, Will Deacon <will.deacon@arm.com> wrote:
> > On Tue, Jul 29, 2014 at 12:32:09PM +0100, Haojian Zhuang wrote:
> >> On 29 July 2014 19:12, Will Deacon <will.deacon@arm.com> wrote:
> >> > On Tue, Jul 29, 2014 at 04:53:21AM +0100, Olof Johansson wrote:
> >> >> On Tue, Jul 29, 2014 at 10:44:40AM +0800, Haojian Zhuang wrote:
> >> >> > Because I didn't get these materials yet. All clocks are enabled in bootloader.
> >> >>
> >> >> What materials? Technical documentation for the CPU you're upstreaming?
> >> >>
> >> >> It seems like a very bad idea to upstream a DT for a CPU that you don't
> >> >> have documentation for. It seems appropriate to wait until you have
> >> >> documentation so you can make sure that the hardware you're describing
> >> >> is actually what is there, and not something made-up or misdescribed.
> >> >
> >> > I completely agree. Furthermore, given that this SoC implements a dodgy
> >> > custom GIC, I don't think it's unreasonable for us to ask for documentation
> >> > describing that too, otherwise it's going to make maintaining a complicated
> >> > irqchip driver that much worse.
> >> >
> >> I don't have enough documents on clocks. And all clocks are already
> >> enabled in UEFI. There're also no requirement on change the clock
> >> frequency & disable them. So I set all these clocks as fixed rate.
> >>
> >> It's different from GIC. If I don't have documents on GIC, I can't
> >> write code for HIP04 GIC. HiP04 GIC supports 16-cores. ARM GICv2
> >> supports 8-cores. So some registers offsets and bit fields are
> >> different from GICv2.
> >
> > Sure, and I'm asking for those documents to be made publicly available
> > somewhere so that we can refer to them if we need to change this code in
> > future.
> >
> I can send the copy to you since it's already public. But the main
> issue is that this document is written in Chinese. I hope it could be
> written in English.

Any chance of a translation, please? The ARM GIC spec is available in
English, which is largely the language in which the kernel is developed.

Will

^ permalink raw reply	[flat|nested] 55+ messages in thread

* [PATCH v15 07/12] ARM: dts: append hip04 dts
  2014-07-29  2:44     ` Haojian Zhuang
  2014-07-29  3:53       ` Olof Johansson
@ 2014-07-29 12:32       ` Mark Rutland
  2014-07-29 17:01         ` Olof Johansson
  1 sibling, 1 reply; 55+ messages in thread
From: Mark Rutland @ 2014-07-29 12:32 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Jul 29, 2014 at 03:44:40AM +0100, Haojian Zhuang wrote:
> On 29 July 2014 02:06, Mark Rutland <mark.rutland@arm.com> wrote:
> > On Mon, Jul 28, 2014 at 02:57:51PM +0100, Haojian Zhuang wrote:
> >> Add hip04-d01.dts & hip04.dtsi for hip04 SoC platform.
> >>
> >> Signed-off-by: Haojian Zhuang <haojian.zhuang@linaro.org>
> >> ---
> >>  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
> >>
> >> diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
> >> index 721525e..6587bbf 100644
> >> --- a/arch/arm/boot/dts/Makefile
> >> +++ b/arch/arm/boot/dts/Makefile
> >> @@ -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 \
> >> diff --git a/arch/arm/boot/dts/hip04-d01.dts b/arch/arm/boot/dts/hip04-d01.dts
> >> new file mode 100644
> >> index 0000000..661c8e5
> >> --- /dev/null
> >> +++ b/arch/arm/boot/dts/hip04-d01.dts
> >> @@ -0,0 +1,39 @@
> >> +/*
> >> + *  Copyright (C) 2013-2014 Linaro Ltd.
> >> + *  Author: Haojian Zhuang <haojian.zhuang@linaro.org>
> >> + *
> >> + *  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;
> >
> > How exactly is this bootwrapper used? Is the kernel compiled into it?
> >
> > It might make more sense for the wrapper build system to inject
> > bootwrapper-related properties. Then the DTB is less likely to
> > amalgamate hacks to workaround differences between versions, and can be
> > used on systems without a wrapper without throwing away some memory.
> >
> 
> In this platform, we relied on the bootwrapper. If I discard this,
> I'll fail to bring up all secondary cores.

What loads the boot wrapper into memory, and from where?

In another reply you mentioned you're using UEFI. Is this wrapper
considered part of your UEFI implementation? If so it should be reserved
in the UEFI memory map, and there should be no need of memory nodes or
memreserves -- all that should come from UEFI.

What exactly is the boot wrapper in charge of?

What is the split in responsiblity between the wrapper and the kernel?

[...]

> >> +               };
> >> +
> >> +               fabric: fabric {
> >> +                       compatible = "hisilicon,hip04-fabric";
> >> +                       reg = <0x302a000 0x1000>;
> >
> > How is this going to be used?
> >
> 
> Fabric could configure snoop filter of multiple cluster. I don't have
> the manual. I only know this.

Is this accessible to the non-secure side?

If the firmware is currently programming things correctly then we
shouldn't need this for now.

> >> +               };
> >> +
> >> +               dual_timer0: dual_timer at 3000000 {
> >> +                       compatible = "arm,sp804", "arm,primecell";
> >> +                       reg = <0x3000000 0x1000>;
> >> +                       interrupts = <0 224 4>;
> >> +                       clocks = <&clock HIP04_CLK_50M>;
> >> +                       clock-names = "apb_pclk";
> >> +               };
> >
> > I thought sp804 had two clocks (one for AMBA and one for the actual
> > timer). What's going on here?
> >
> 
> If only one clock is configured at here, sp804 driver believes that
> clk2 is same as clk1.

I'm not keen on relying on that. It's arguably a bug in the driver.

Thanks,
Mark.

^ permalink raw reply	[flat|nested] 55+ messages in thread

* [PATCH v15 06/12] document: dt: add the binding on HiP04 clock
  2014-07-29  2:25     ` Haojian Zhuang
  2014-07-29  9:55       ` Arnd Bergmann
@ 2014-07-29 12:38       ` Mark Rutland
  1 sibling, 0 replies; 55+ messages in thread
From: Mark Rutland @ 2014-07-29 12:38 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Jul 29, 2014 at 03:25:49AM +0100, Haojian Zhuang wrote:
> On 29 July 2014 01:54, Mark Rutland <mark.rutland@arm.com> wrote:
> > On Mon, Jul 28, 2014 at 02:57:50PM +0100, Haojian Zhuang wrote:
> >> The DT binding for Hisilicon HiP04 clock driver.
> >>
> >> Signed-off-by: Haojian Zhuang <haojian.zhuang@linaro.org>
> >> ---
> >>  .../devicetree/bindings/clock/hip04-clock.txt        | 20 ++++++++++++++++++++
> >>  1 file changed, 20 insertions(+)
> >>  create mode 100644 Documentation/devicetree/bindings/clock/hip04-clock.txt
> >>
> >> diff --git a/Documentation/devicetree/bindings/clock/hip04-clock.txt b/Documentation/devicetree/bindings/clock/hip04-clock.txt
> >> new file mode 100644
> >> index 0000000..4d31ae3
> >> --- /dev/null
> >> +++ b/Documentation/devicetree/bindings/clock/hip04-clock.txt
> >> @@ -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.
> >
> > There's only one clock controller on-board and it's custom for HiP04?
> >
> 
> Since all those PLL settings are configured in bootloader, kernel
> don't need to configure it again.
> 
> By the way, I don't have the manual to configure those PLLs. All the clocks
> are defined as fixed in kernel side.

Given that, per Arnd's suggestion these should probably just be
fixed-clock nodes, and we don't need the driver at all until we know how
to handle these PLLs and their parents.

> >> +
> >> +- 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>.
> >
> > This must come in the same patch.
> >
> > Mark.
> 
> HiP04 clock driver is already merged into mainline.

I see. This was not obvious from the commit message.

Mark.

^ permalink raw reply	[flat|nested] 55+ messages in thread

* [PATCH v15 01/12] irq: gic: support hip04 gic
  2014-07-28 17:38   ` Marc Zyngier
@ 2014-07-29 13:05     ` Arnd Bergmann
  2014-07-29 13:19       ` Will Deacon
  2014-07-29 13:41       ` Marc Zyngier
  0 siblings, 2 replies; 55+ messages in thread
From: Arnd Bergmann @ 2014-07-29 13:05 UTC (permalink / raw)
  To: linux-arm-kernel

On Monday 28 July 2014 18:38:58 Marc Zyngier wrote:
> Overall, this code should be able to sitting within a #ifdef/#endif
> block, only selected if this platform is enabled, and possibly find a
> way not to impact all the other platforms when this is not selected.
> 
> Finally, I'd like to outline how much I dislike the way the GIC
> architecture has been abused here. Yes, this solves a particular
> problem, at a given point in time, but this also feels extremely short
> sighted from whoever has put this thing together. This really feels like
> a short-term HW hack that is already addressed by GICv3. Merging support
> for non architecture compliant HW is never the best solution.

Not merging support for shipping hardware is also not a solution,
and we already support any number of irqchip drivers and have all
the logic we need to sort that out at runtime.

My feeling is that the original approach taken in the early version
of the patch set was actually better, given all the problems with
integrating this nicely into the gic driver.

Would you be happier with that? The downside of that would be
that some driver bugs would get fixed in one driver but not the
other one, which is why we normally try to avoid it. On the other
hand, it means that the normal GIC driver does not get polluted
with hacks that are only needed for the hip04 version and there
is an obvious way to disable the driver at compile time when you
build for other platforms.

	Arnd

^ permalink raw reply	[flat|nested] 55+ messages in thread

* [PATCH v15 01/12] irq: gic: support hip04 gic
  2014-07-29 13:05     ` Arnd Bergmann
@ 2014-07-29 13:19       ` Will Deacon
  2014-07-29 13:41       ` Marc Zyngier
  1 sibling, 0 replies; 55+ messages in thread
From: Will Deacon @ 2014-07-29 13:19 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Jul 29, 2014 at 02:05:06PM +0100, Arnd Bergmann wrote:
> On Monday 28 July 2014 18:38:58 Marc Zyngier wrote:
> > Overall, this code should be able to sitting within a #ifdef/#endif
> > block, only selected if this platform is enabled, and possibly find a
> > way not to impact all the other platforms when this is not selected.
> > 
> > Finally, I'd like to outline how much I dislike the way the GIC
> > architecture has been abused here. Yes, this solves a particular
> > problem, at a given point in time, but this also feels extremely short
> > sighted from whoever has put this thing together. This really feels like
> > a short-term HW hack that is already addressed by GICv3. Merging support
> > for non architecture compliant HW is never the best solution.
> 
> Not merging support for shipping hardware is also not a solution,
> and we already support any number of irqchip drivers and have all
> the logic we need to sort that out at runtime.
> 
> My feeling is that the original approach taken in the early version
> of the patch set was actually better, given all the problems with
> integrating this nicely into the gic driver.
> 
> Would you be happier with that? The downside of that would be
> that some driver bugs would get fixed in one driver but not the
> other one, which is why we normally try to avoid it. On the other
> hand, it means that the normal GIC driver does not get polluted
> with hacks that are only needed for the hip04 version and there
> is an obvious way to disable the driver at compile time when you
> build for other platforms.

Yeah, I think after all this, you're right and keeping the two drivers
strictly separate is probably the best thing after all. That also allows
the vgic and gicv3 work to continue regardless of the hip04 driver,
especially since we don't have any useful documentation for the hardware
itself.

As for the KVM side, I think we should treat this as something totally
separate to the GIC and *not* instantiate a vgic in response to
KVM_CREATE_IRQCHIP on systems with this hardware.

Will

^ permalink raw reply	[flat|nested] 55+ messages in thread

* [PATCH v15 01/12] irq: gic: support hip04 gic
  2014-07-29 13:05     ` Arnd Bergmann
  2014-07-29 13:19       ` Will Deacon
@ 2014-07-29 13:41       ` Marc Zyngier
  1 sibling, 0 replies; 55+ messages in thread
From: Marc Zyngier @ 2014-07-29 13:41 UTC (permalink / raw)
  To: linux-arm-kernel

On 29/07/14 14:05, Arnd Bergmann wrote:
> On Monday 28 July 2014 18:38:58 Marc Zyngier wrote:
>> Overall, this code should be able to sitting within a #ifdef/#endif
>> block, only selected if this platform is enabled, and possibly find a
>> way not to impact all the other platforms when this is not selected.
>>
>> Finally, I'd like to outline how much I dislike the way the GIC
>> architecture has been abused here. Yes, this solves a particular
>> problem, at a given point in time, but this also feels extremely short
>> sighted from whoever has put this thing together. This really feels like
>> a short-term HW hack that is already addressed by GICv3. Merging support
>> for non architecture compliant HW is never the best solution.
> 
> Not merging support for shipping hardware is also not a solution,
> and we already support any number of irqchip drivers and have all
> the logic we need to sort that out at runtime.

I don't dispute this, and maybe I'm just tired of seeing pointlessly
divergent HW being pushed around.

> My feeling is that the original approach taken in the early version
> of the patch set was actually better, given all the problems with
> integrating this nicely into the gic driver.
> 
> Would you be happier with that? The downside of that would be
> that some driver bugs would get fixed in one driver but not the
> other one, which is why we normally try to avoid it. On the other
> hand, it means that the normal GIC driver does not get polluted
> with hacks that are only needed for the hip04 version and there
> is an obvious way to disable the driver at compile time when you
> build for other platforms.

Indeed. I think I'd be much happier with a completely separate driver.
There will even be some benefits to the hip04 driver, as it won't have
to deal with the non-DT stuff and the crazy gic_arch_extn.

Thanks,

	M.
-- 
Jazz is not dead. It just smells funny...

^ permalink raw reply	[flat|nested] 55+ messages in thread

* [PATCH v15 07/12] ARM: dts: append hip04 dts
  2014-07-29 10:58         ` Haojian Zhuang
@ 2014-07-29 16:56           ` Olof Johansson
  0 siblings, 0 replies; 55+ messages in thread
From: Olof Johansson @ 2014-07-29 16:56 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Jul 29, 2014 at 3:58 AM, Haojian Zhuang
<haojian.zhuang@linaro.org> wrote:
> On 29 July 2014 11:53, Olof Johansson <olof@lixom.net> wrote:
>> Hi,
>>
>>
>> On Tue, Jul 29, 2014 at 10:44:40AM +0800, Haojian Zhuang wrote:
>>> On 29 July 2014 02:06, Mark Rutland <mark.rutland@arm.com> wrote:
>>> > On Mon, Jul 28, 2014 at 02:57:51PM +0100, Haojian Zhuang wrote:
>>> >> +/*
>>> >> + *  Copyright (C) 2013-2014 Linaro Ltd.
>>> >> + *  Author: Haojian Zhuang <haojian.zhuang@linaro.org>
>>> >> + *
>>> >> + *  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;
>>> >
>>> > How exactly is this bootwrapper used? Is the kernel compiled into it?
>>> >
>>> > It might make more sense for the wrapper build system to inject
>>> > bootwrapper-related properties. Then the DTB is less likely to
>>> > amalgamate hacks to workaround differences between versions, and can be
>>> > used on systems without a wrapper without throwing away some memory.
>>> >
>>>
>>> In this platform, we relied on the bootwrapper. If I discard this,
>>> I'll fail to bring up all secondary cores.
>>
>> What is this memory used for? Is this where the cores are parked on the spin
>> table, or something else? Does your platform have runtime firmware?
>>
>
> This memory stores the instructions that secondary cores will execute initially.
>
> They will switch cores into non-secure & hyp mode.

Lots of SoCs do this, but when it's managed like this, they normally
will either provide the code snippet in a piece of SRAM on-chip, or
the kernel will provide it and set up the trampolines accordingly.

> There's no runtime firmware in this platform. And there's no schedule
> to support it.

Ok.

>
>>> >> +
>>> >> +#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>;
>>> >> +       };
>>> >
>>> > You can fold these into a single node.
>>> >
>>>
>>> The address spaces of these two memory node are different.
>>> I can't fold them into a single node.
>>
>> There's no functional difference today between having two memory nodes or one
>> node with two ranges. It would be:
>>         memory at 0 {
>>                 device_type = "memory";
>>                 reg = <0x00000000 0x10000000 0x00000000 0xc0000000>,
>>                       <0x00000004 0xc0000000 0x00000003 0x40000000>;
>>
>
> OK.
>
>>> >> +
>>> >> +       soc {
>>> >> +               uart0: uart at 4007000 {
>>> >> +                       status = "ok";
>>> >> +               };
>>> >> +       };
>>> >> +};
>>> >> diff --git a/arch/arm/boot/dts/hip04.dtsi b/arch/arm/boot/dts/hip04.dtsi
>>> >> new file mode 100644
>>> >> index 0000000..30942be
>>> >> --- /dev/null
>>> >> +++ b/arch/arm/boot/dts/hip04.dtsi
>>> >> @@ -0,0 +1,267 @@
>>> >> +/*
>>> >> + * Hisilicon Ltd. HiP04 SoC
>>> >> + *
>>> >> + * Copyright (C) 2013-2014 Hisilicon Ltd.
>>> >> + * Copyright (C) 2013-2014 Linaro Ltd.
>>> >> + *
>>> >> + * Author: Haojian Zhuang <haojian.zhuang@linaro.org>
>>> >> + *
>>> >> + * 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.
>>> >
>>> > s/hh/h/
>>> >
>>>
>>> Thanks. I'll fix it.
>>>
>>> > [...]
>>> >
>>> >> +       clock: clock {
>>> >> +               compatible = "hisilicon,hip04-clock";
>>> >> +               /* dummy register.
>>> >> +                * Don't need to access clock registers since they're
>>> >> +                * configured in firmware already.
>>> >> +                */
>>> >> +               reg = <0 0 0 0x1000>;
>>> >
>>> > Huh? Whether or not you need to access the registers should be up to the
>>> > kernel, not the DT.
>>> >
>>> > Why can the kernel not access these? This sounds like a hack.
>>> >
>>>
>>> Because I didn't get these materials yet. All clocks are enabled in bootloader.
>>
>> What materials? Technical documentation for the CPU you're upstreaming?
>>
>> It seems like a very bad idea to upstream a DT for a CPU that you don't
>> have documentation for. It seems appropriate to wait until you have
>> documentation so you can make sure that the hardware you're describing
>> is actually what is there, and not something made-up or misdescribed.
>>
>>> >> +               };
>>> >> +
>>> >> +               sysctrl: sysctrl {
>>> >> +                       compatible = "hisilicon,sysctrl";
>>> >> +                       reg = <0x3e00000 0x00100000>;
>>> >> +                       relocation-entry = <0xe0000100>;
>>> >> +                       relocation-size = <0x1000>;
>>> >> +                       bootwrapper-phys = <0x10c00000>;
>>> >> +                       bootwrapper-size = <0x10000>;
>>> >> +                       bootwrapper-magic = <0xa5a5a5a5>;
>>> >
>>> > Are these absolute addresses, or translated per ranges above?
>>> >
>>> > Why are they related to the system controller?
>>> >
>>>
>>> I need these parameters. But I can't find a better place.
>>
>> Again, what is the boot wrapper in this case? And what do you need them for?
>>
>
> Now UEFI didn't switch secondary cores to non-secure & hyp mode. The
> bootwrapper is used to handle this job. Then bootwrapper will jump to
> kernel to continue boot SMP. So the relocation area is used to store
> the SMP entrance.
>
> SMP feature will fail without bootwrapper in this platform.

What you call bootwrapper seems to just be the trampoline code used to
launch an onlined processor? Why does that have to live in just that
piece of memory, can't the kernel configure it?

>>> >> +               };
>>> >> +
>>> >> +               fabric: fabric {
>>> >> +                       compatible = "hisilicon,hip04-fabric";
>>> >> +                       reg = <0x302a000 0x1000>;
>>> >
>>> > How is this going to be used?
>>> >
>>>
>>> Fabric could configure snoop filter of multiple cluster. I don't have
>>> the manual. I only know this.
>>
>> What driver is going to bind against this? It probably makes sense to leave
>> this out until the consumer is also upstreamed, to have something to have as
>> a base for discussion.
>
> Only one register is configured in the fabric by kernel. Do we need a driver?

Ah, I see. My main worry is that you're trying to describe in DT a
piece of hardware that you only have some code snippets for, not
documentation. Is the register window on this IP block really 4K in
size? You only touch the first 20 bytes of it in the MCPM code, for
example.


-Olof

^ permalink raw reply	[flat|nested] 55+ messages in thread

* [PATCH v15 07/12] ARM: dts: append hip04 dts
  2014-07-29 12:32       ` Mark Rutland
@ 2014-07-29 17:01         ` Olof Johansson
  2014-07-29 17:33           ` Mark Rutland
  2014-07-30 11:26           ` Leif Lindholm
  0 siblings, 2 replies; 55+ messages in thread
From: Olof Johansson @ 2014-07-29 17:01 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Jul 29, 2014 at 5:32 AM, Mark Rutland <mark.rutland@arm.com> wrote:
> On Tue, Jul 29, 2014 at 03:44:40AM +0100, Haojian Zhuang wrote:
>> On 29 July 2014 02:06, Mark Rutland <mark.rutland@arm.com> wrote:
>> > On Mon, Jul 28, 2014 at 02:57:51PM +0100, Haojian Zhuang wrote:
>> >> Add hip04-d01.dts & hip04.dtsi for hip04 SoC platform.
>> >>
>> >> Signed-off-by: Haojian Zhuang <haojian.zhuang@linaro.org>
>> >> ---
>> >>  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
>> >>
>> >> diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
>> >> index 721525e..6587bbf 100644
>> >> --- a/arch/arm/boot/dts/Makefile
>> >> +++ b/arch/arm/boot/dts/Makefile
>> >> @@ -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 \
>> >> diff --git a/arch/arm/boot/dts/hip04-d01.dts b/arch/arm/boot/dts/hip04-d01.dts
>> >> new file mode 100644
>> >> index 0000000..661c8e5
>> >> --- /dev/null
>> >> +++ b/arch/arm/boot/dts/hip04-d01.dts
>> >> @@ -0,0 +1,39 @@
>> >> +/*
>> >> + *  Copyright (C) 2013-2014 Linaro Ltd.
>> >> + *  Author: Haojian Zhuang <haojian.zhuang@linaro.org>
>> >> + *
>> >> + *  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;
>> >
>> > How exactly is this bootwrapper used? Is the kernel compiled into it?
>> >
>> > It might make more sense for the wrapper build system to inject
>> > bootwrapper-related properties. Then the DTB is less likely to
>> > amalgamate hacks to workaround differences between versions, and can be
>> > used on systems without a wrapper without throwing away some memory.
>> >
>>
>> In this platform, we relied on the bootwrapper. If I discard this,
>> I'll fail to bring up all secondary cores.
>
> What loads the boot wrapper into memory, and from where?
>
> In another reply you mentioned you're using UEFI. Is this wrapper
> considered part of your UEFI implementation? If so it should be reserved
> in the UEFI memory map, and there should be no need of memory nodes or
> memreserves -- all that should come from UEFI.

There's no UEFI memory map parsing on 32-bit, is there?

> What exactly is the boot wrapper in charge of?
>
> What is the split in responsiblity between the wrapper and the kernel?

Sounds like it's just the trampoline code that's executed at CPU
spin-up time. I wouldn't be surprised if there's a register somewhere
on the same controller that you poke the cpu to life that you can
write what address for it to start executing at, or at least some
other location where it can be redirected somewhere else. It's very
unlikely a wired-in address in hardware. Or so I hope. :-)

>> >> +               };
>> >> +
>> >> +               fabric: fabric {
>> >> +                       compatible = "hisilicon,hip04-fabric";
>> >> +                       reg = <0x302a000 0x1000>;
>> >
>> > How is this going to be used?
>> >
>>
>> Fabric could configure snoop filter of multiple cluster. I don't have
>> the manual. I only know this.
>
> Is this accessible to the non-secure side?
>
> If the firmware is currently programming things correctly then we
> shouldn't need this for now.

with MCPM clusters get powered up and down, it's not uncommon to have
to take them out of coherence domains.

>> >> +               };
>> >> +
>> >> +               dual_timer0: dual_timer at 3000000 {
>> >> +                       compatible = "arm,sp804", "arm,primecell";
>> >> +                       reg = <0x3000000 0x1000>;
>> >> +                       interrupts = <0 224 4>;
>> >> +                       clocks = <&clock HIP04_CLK_50M>;
>> >> +                       clock-names = "apb_pclk";
>> >> +               };
>> >
>> > I thought sp804 had two clocks (one for AMBA and one for the actual
>> > timer). What's going on here?
>> >
>>
>> If only one clock is configured at here, sp804 driver believes that
>> clk2 is same as clk1.
>
> I'm not keen on relying on that. It's arguably a bug in the driver.

The driver should warn, but we can't make it fail on it now. :(


-Olof

^ permalink raw reply	[flat|nested] 55+ messages in thread

* [PATCH v15 07/12] ARM: dts: append hip04 dts
  2014-07-29 17:01         ` Olof Johansson
@ 2014-07-29 17:33           ` Mark Rutland
  2014-07-30 11:26           ` Leif Lindholm
  1 sibling, 0 replies; 55+ messages in thread
From: Mark Rutland @ 2014-07-29 17:33 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Jul 29, 2014 at 06:01:48PM +0100, Olof Johansson wrote:
> On Tue, Jul 29, 2014 at 5:32 AM, Mark Rutland <mark.rutland@arm.com> wrote:
> > On Tue, Jul 29, 2014 at 03:44:40AM +0100, Haojian Zhuang wrote:
> >> On 29 July 2014 02:06, Mark Rutland <mark.rutland@arm.com> wrote:
> >> > On Mon, Jul 28, 2014 at 02:57:51PM +0100, Haojian Zhuang wrote:
> >> >> Add hip04-d01.dts & hip04.dtsi for hip04 SoC platform.
> >> >>
> >> >> Signed-off-by: Haojian Zhuang <haojian.zhuang@linaro.org>
> >> >> ---
> >> >>  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
> >> >>
> >> >> diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
> >> >> index 721525e..6587bbf 100644
> >> >> --- a/arch/arm/boot/dts/Makefile
> >> >> +++ b/arch/arm/boot/dts/Makefile
> >> >> @@ -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 \
> >> >> diff --git a/arch/arm/boot/dts/hip04-d01.dts b/arch/arm/boot/dts/hip04-d01.dts
> >> >> new file mode 100644
> >> >> index 0000000..661c8e5
> >> >> --- /dev/null
> >> >> +++ b/arch/arm/boot/dts/hip04-d01.dts
> >> >> @@ -0,0 +1,39 @@
> >> >> +/*
> >> >> + *  Copyright (C) 2013-2014 Linaro Ltd.
> >> >> + *  Author: Haojian Zhuang <haojian.zhuang@linaro.org>
> >> >> + *
> >> >> + *  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;
> >> >
> >> > How exactly is this bootwrapper used? Is the kernel compiled into it?
> >> >
> >> > It might make more sense for the wrapper build system to inject
> >> > bootwrapper-related properties. Then the DTB is less likely to
> >> > amalgamate hacks to workaround differences between versions, and can be
> >> > used on systems without a wrapper without throwing away some memory.
> >> >
> >>
> >> In this platform, we relied on the bootwrapper. If I discard this,
> >> I'll fail to bring up all secondary cores.
> >
> > What loads the boot wrapper into memory, and from where?
> >
> > In another reply you mentioned you're using UEFI. Is this wrapper
> > considered part of your UEFI implementation? If so it should be reserved
> > in the UEFI memory map, and there should be no need of memory nodes or
> > memreserves -- all that should come from UEFI.
> 
> There's no UEFI memory map parsing on 32-bit, is there?

Apparently not, so this can be ignored. Sorry for the noise.

That said I'm slightly confused by the decision to use UEFI given that
we can't use the standard EFI boot mechanism and services on 32-bit.

> > What exactly is the boot wrapper in charge of?
> >
> > What is the split in responsiblity between the wrapper and the kernel?
> 
> Sounds like it's just the trampoline code that's executed at CPU
> spin-up time. I wouldn't be surprised if there's a register somewhere
> on the same controller that you poke the cpu to life that you can
> write what address for it to start executing at, or at least some
> other location where it can be redirected somewhere else. It's very
> unlikely a wired-in address in hardware. Or so I hope. :-)

Me too.

> >> >> +               };
> >> >> +
> >> >> +               fabric: fabric {
> >> >> +                       compatible = "hisilicon,hip04-fabric";
> >> >> +                       reg = <0x302a000 0x1000>;
> >> >
> >> > How is this going to be used?
> >> >
> >>
> >> Fabric could configure snoop filter of multiple cluster. I don't have
> >> the manual. I only know this.
> >
> > Is this accessible to the non-secure side?
> >
> > If the firmware is currently programming things correctly then we
> > shouldn't need this for now.
> 
> with MCPM clusters get powered up and down, it's not uncommon to have
> to take them out of coherence domains.

Sure, but that won't be possible if those registers are secure-only
given the comments that secondaries are demoted to hyp by the wrapper.
That might be possible to work around, but we might be in for further
pain given the primary is already in a non-secure mode.

It might be that this is useful for performance monitoring on the
non-secure side anyway, but without a user it might make more sense to
just drop the node for now.

> >> >> +               };
> >> >> +
> >> >> +               dual_timer0: dual_timer at 3000000 {
> >> >> +                       compatible = "arm,sp804", "arm,primecell";
> >> >> +                       reg = <0x3000000 0x1000>;
> >> >> +                       interrupts = <0 224 4>;
> >> >> +                       clocks = <&clock HIP04_CLK_50M>;
> >> >> +                       clock-names = "apb_pclk";
> >> >> +               };
> >> >
> >> > I thought sp804 had two clocks (one for AMBA and one for the actual
> >> > timer). What's going on here?
> >> >
> >>
> >> If only one clock is configured at here, sp804 driver believes that
> >> clk2 is same as clk1.
> >
> > I'm not keen on relying on that. It's arguably a bug in the driver.
> 
> The driver should warn, but we can't make it fail on it now. :(

Yeah. I should revive my series for that. So far everyone seems to be
happy with just hacking around it :(

Thanks,
Mark.

^ permalink raw reply	[flat|nested] 55+ messages in thread

* [PATCH v15 07/12] ARM: dts: append hip04 dts
  2014-07-29 17:01         ` Olof Johansson
  2014-07-29 17:33           ` Mark Rutland
@ 2014-07-30 11:26           ` Leif Lindholm
  1 sibling, 0 replies; 55+ messages in thread
From: Leif Lindholm @ 2014-07-30 11:26 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Jul 29, 2014 at 10:01:48AM -0700, Olof Johansson wrote:
> >> In this platform, we relied on the bootwrapper. If I discard this,
> >> I'll fail to bring up all secondary cores.
> >
> > What loads the boot wrapper into memory, and from where?
> >
> > In another reply you mentioned you're using UEFI. Is this wrapper
> > considered part of your UEFI implementation? If so it should be reserved
> > in the UEFI memory map, and there should be no need of memory nodes or
> > memreserves -- all that should come from UEFI.
> 
> There's no UEFI memory map parsing on 32-bit, is there?

There is in my patch set, but that is still dependent on the
early_ioremap support, which needs someone to comment on the "use
generic fixmap on ARM" bit.
 
/
    Leif

^ permalink raw reply	[flat|nested] 55+ messages in thread

* [PATCH v15 08/12] ARM: config: append lpae configuration
  2014-07-29 10:43     ` Haojian Zhuang
@ 2014-07-31  1:01       ` Olof Johansson
  2014-07-31  2:24         ` Haojian Zhuang
  0 siblings, 1 reply; 55+ messages in thread
From: Olof Johansson @ 2014-07-31  1:01 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Jul 29, 2014 at 3:43 AM, Haojian Zhuang
<haojian.zhuang@linaro.org> wrote:
> On 29 July 2014 12:05, Olof Johansson <olof@lixom.net> wrote:
>> On Mon, Jul 28, 2014 at 09:57:52PM +0800, Haojian Zhuang wrote:
>>> Append multi_v7_lpae_config. In this default configuration,
>>> CONFIG_ARCH_MULTI_V6 is disabled. CONFIG_ARM_LPAE is enabled.
>>
>> NACK. This is the nth time I have had to nack this patch.
>>
>> You are enabling platforms here that don't have LPAE. Don't do that.
>>
>> It's trivial to create a LPAE version of multi_v7 defconfig locally.
>>
>>
>> -Olof
>
> I tried to remove those SoCs that can't support LPAE. But I don't know
> every platform in details.
>
> How about that I only enable HIP04 in multi_v7_lpae_defconfig. If you
> think any platform could be added, please help to list it. Then I
> could append them into the multi_v7_lpae_defconfig.

I really don't like having to repeat this over and over: Just add LPAE
to a multi_v7_defconfig build when you need to turn it on.

The alternative is to do this right from the beginning, and move
multi_v7 over to be a v6_v7 defconfig, and also have an lpae+kvm
defconfig for A7/12/15/17 (and mvebu/krait) platforms. But there's
been no need for that yet since all platforms to date can boot without
LPAE just fine -- in fact most of them don't actually need it since
nearly all of them have less memory and for the few of them that do
you just turn on LPAE manually like I suggested.


-Olof

^ permalink raw reply	[flat|nested] 55+ messages in thread

* [PATCH v15 08/12] ARM: config: append lpae configuration
  2014-07-31  1:01       ` Olof Johansson
@ 2014-07-31  2:24         ` Haojian Zhuang
  2014-07-31  3:55           ` Olof Johansson
  0 siblings, 1 reply; 55+ messages in thread
From: Haojian Zhuang @ 2014-07-31  2:24 UTC (permalink / raw)
  To: linux-arm-kernel

On 31 July 2014 09:01, Olof Johansson <olof@lixom.net> wrote:
> On Tue, Jul 29, 2014 at 3:43 AM, Haojian Zhuang
> <haojian.zhuang@linaro.org> wrote:
>> On 29 July 2014 12:05, Olof Johansson <olof@lixom.net> wrote:
>>> On Mon, Jul 28, 2014 at 09:57:52PM +0800, Haojian Zhuang wrote:
>>>> Append multi_v7_lpae_config. In this default configuration,
>>>> CONFIG_ARCH_MULTI_V6 is disabled. CONFIG_ARM_LPAE is enabled.
>>>
>>> NACK. This is the nth time I have had to nack this patch.
>>>
>>> You are enabling platforms here that don't have LPAE. Don't do that.
>>>
>>> It's trivial to create a LPAE version of multi_v7 defconfig locally.
>>>
>>>
>>> -Olof
>>
>> I tried to remove those SoCs that can't support LPAE. But I don't know
>> every platform in details.
>>
>> How about that I only enable HIP04 in multi_v7_lpae_defconfig. If you
>> think any platform could be added, please help to list it. Then I
>> could append them into the multi_v7_lpae_defconfig.
>
> I really don't like having to repeat this over and over: Just add LPAE
> to a multi_v7_defconfig build when you need to turn it on.
>
> The alternative is to do this right from the beginning, and move
> multi_v7 over to be a v6_v7 defconfig, and also have an lpae+kvm
> defconfig for A7/12/15/17 (and mvebu/krait) platforms. But there's
> been no need for that yet since all platforms to date can boot without
> LPAE just fine -- in fact most of them don't actually need it since
> nearly all of them have less memory and for the few of them that do
> you just turn on LPAE manually like I suggested.
>
>
> -Olof

I can drop both hip04_defconfig & multi_v7_lpae_defconfig. But the
problem is that 16GB memory is used in hip04 platform. 64bit memory
address is also used in hip04 dts file. So I can't boot kernel without
LPAE configuration.

If I integrate ARCH_HIP04 & LPAE into hi3xxx_defconfig, both
ARCH_HI3XXX & ARCH_X5HD2 don't support LPAE.

Regards
Haojian

^ permalink raw reply	[flat|nested] 55+ messages in thread

* [PATCH v15 08/12] ARM: config: append lpae configuration
  2014-07-31  2:24         ` Haojian Zhuang
@ 2014-07-31  3:55           ` Olof Johansson
  2014-07-31  5:30             ` Haojian Zhuang
  0 siblings, 1 reply; 55+ messages in thread
From: Olof Johansson @ 2014-07-31  3:55 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Jul 30, 2014 at 7:24 PM, Haojian Zhuang
<haojian.zhuang@linaro.org> wrote:
> On 31 July 2014 09:01, Olof Johansson <olof@lixom.net> wrote:
>> On Tue, Jul 29, 2014 at 3:43 AM, Haojian Zhuang
>> <haojian.zhuang@linaro.org> wrote:
>>> On 29 July 2014 12:05, Olof Johansson <olof@lixom.net> wrote:
>>>> On Mon, Jul 28, 2014 at 09:57:52PM +0800, Haojian Zhuang wrote:
>>>>> Append multi_v7_lpae_config. In this default configuration,
>>>>> CONFIG_ARCH_MULTI_V6 is disabled. CONFIG_ARM_LPAE is enabled.
>>>>
>>>> NACK. This is the nth time I have had to nack this patch.
>>>>
>>>> You are enabling platforms here that don't have LPAE. Don't do that.
>>>>
>>>> It's trivial to create a LPAE version of multi_v7 defconfig locally.
>>>>
>>>>
>>>> -Olof
>>>
>>> I tried to remove those SoCs that can't support LPAE. But I don't know
>>> every platform in details.
>>>
>>> How about that I only enable HIP04 in multi_v7_lpae_defconfig. If you
>>> think any platform could be added, please help to list it. Then I
>>> could append them into the multi_v7_lpae_defconfig.
>>
>> I really don't like having to repeat this over and over: Just add LPAE
>> to a multi_v7_defconfig build when you need to turn it on.
>>
>> The alternative is to do this right from the beginning, and move
>> multi_v7 over to be a v6_v7 defconfig, and also have an lpae+kvm
>> defconfig for A7/12/15/17 (and mvebu/krait) platforms. But there's
>> been no need for that yet since all platforms to date can boot without
>> LPAE just fine -- in fact most of them don't actually need it since
>> nearly all of them have less memory and for the few of them that do
>> you just turn on LPAE manually like I suggested.
>>
>>
>> -Olof
>
> I can drop both hip04_defconfig & multi_v7_lpae_defconfig. But the
> problem is that 16GB memory is used in hip04 platform. 64bit memory
> address is also used in hip04 dts file. So I can't boot kernel without
> LPAE configuration.
>
> If I integrate ARCH_HIP04 & LPAE into hi3xxx_defconfig, both
> ARCH_HI3XXX & ARCH_X5HD2 don't support LPAE.

There is memory at 0x10000000-0xd0000000 and all I/O is below 4GB. You
should be able to boot just fine without LPAE, but you won't see all
memory available.


-Olof

^ permalink raw reply	[flat|nested] 55+ messages in thread

* [PATCH v15 08/12] ARM: config: append lpae configuration
  2014-07-31  3:55           ` Olof Johansson
@ 2014-07-31  5:30             ` Haojian Zhuang
  2014-07-31 14:41               ` Arnd Bergmann
  0 siblings, 1 reply; 55+ messages in thread
From: Haojian Zhuang @ 2014-07-31  5:30 UTC (permalink / raw)
  To: linux-arm-kernel

On 31 July 2014 11:55, Olof Johansson <olof@lixom.net> wrote:
> On Wed, Jul 30, 2014 at 7:24 PM, Haojian Zhuang
> <haojian.zhuang@linaro.org> wrote:
>> On 31 July 2014 09:01, Olof Johansson <olof@lixom.net> wrote:
>>> On Tue, Jul 29, 2014 at 3:43 AM, Haojian Zhuang
>>> <haojian.zhuang@linaro.org> wrote:
>>>> On 29 July 2014 12:05, Olof Johansson <olof@lixom.net> wrote:
>>>>> On Mon, Jul 28, 2014 at 09:57:52PM +0800, Haojian Zhuang wrote:
>>>>>> Append multi_v7_lpae_config. In this default configuration,
>>>>>> CONFIG_ARCH_MULTI_V6 is disabled. CONFIG_ARM_LPAE is enabled.
>>>>>
>>>>> NACK. This is the nth time I have had to nack this patch.
>>>>>
>>>>> You are enabling platforms here that don't have LPAE. Don't do that.
>>>>>
>>>>> It's trivial to create a LPAE version of multi_v7 defconfig locally.
>>>>>
>>>>>
>>>>> -Olof
>>>>
>>>> I tried to remove those SoCs that can't support LPAE. But I don't know
>>>> every platform in details.
>>>>
>>>> How about that I only enable HIP04 in multi_v7_lpae_defconfig. If you
>>>> think any platform could be added, please help to list it. Then I
>>>> could append them into the multi_v7_lpae_defconfig.
>>>
>>> I really don't like having to repeat this over and over: Just add LPAE
>>> to a multi_v7_defconfig build when you need to turn it on.
>>>
>>> The alternative is to do this right from the beginning, and move
>>> multi_v7 over to be a v6_v7 defconfig, and also have an lpae+kvm
>>> defconfig for A7/12/15/17 (and mvebu/krait) platforms. But there's
>>> been no need for that yet since all platforms to date can boot without
>>> LPAE just fine -- in fact most of them don't actually need it since
>>> nearly all of them have less memory and for the few of them that do
>>> you just turn on LPAE manually like I suggested.
>>>
>>>
>>> -Olof
>>
>> I can drop both hip04_defconfig & multi_v7_lpae_defconfig. But the
>> problem is that 16GB memory is used in hip04 platform. 64bit memory
>> address is also used in hip04 dts file. So I can't boot kernel without
>> LPAE configuration.
>>
>> If I integrate ARCH_HIP04 & LPAE into hi3xxx_defconfig, both
>> ARCH_HI3XXX & ARCH_X5HD2 don't support LPAE.
>
> There is memory at 0x10000000-0xd0000000 and all I/O is below 4GB. You
> should be able to boot just fine without LPAE, but you won't see all
> memory available.
>

Maybe I didn't express this well. Let's check the memory layout in hip04.

<0x00000000-10000000, 0x00000000-c0000000> & <0x00000004-0xc0000000,
0x00000003-40000000> are two memory regions.

These memory address is 64-bit. When ARM_LPAE is disabled,
memblock_add() parses memory base address & size with 32-bit. Since
ARCH_PHYS_ADDR_T_64BIT is highly depend on ARM_LPAE.

Then these two memory regions become <0x10000000, 0xc0000000> &
<0xc0000000, 0xffffffff>. Lots of IO space are in <0xe0000000,
0xefffffff>. So memory space conflicts when ARM_LPAE is disabled.
Kernel panic will come since it believes IO space is memory.

Only two solutions are available in below.
1. Use hip04_defconfig to declare ARM_LPAE.
2. Use hi3xxx_defconfig, and only declare 2.9GB memory in DTS file
without ARM_LPAE.

I think solution #1 is better. What's your opinion?

Best Regards
Haojian

^ permalink raw reply	[flat|nested] 55+ messages in thread

* [PATCH v15 08/12] ARM: config: append lpae configuration
  2014-07-31  5:30             ` Haojian Zhuang
@ 2014-07-31 14:41               ` Arnd Bergmann
  2014-08-01 12:16                 ` Haojian Zhuang
  0 siblings, 1 reply; 55+ messages in thread
From: Arnd Bergmann @ 2014-07-31 14:41 UTC (permalink / raw)
  To: linux-arm-kernel

On Thursday 31 July 2014, Haojian Zhuang wrote:
> Maybe I didn't express this well. Let's check the memory layout in hip04.
> 
> <0x00000000-10000000, 0x00000000-c0000000> & <0x00000004-0xc0000000,
> 0x00000003-40000000> are two memory regions.
> 
> These memory address is 64-bit. When ARM_LPAE is disabled,
> memblock_add() parses memory base address & size with 32-bit. Since
> ARCH_PHYS_ADDR_T_64BIT is highly depend on ARM_LPAE.
> 
> Then these two memory regions become <0x10000000, 0xc0000000> &
> <0xc0000000, 0xffffffff>. Lots of IO space are in <0xe0000000,
> 0xefffffff>. So memory space conflicts when ARM_LPAE is disabled.
> Kernel panic will come since it believes IO space is memory.
> 
> Only two solutions are available in below.
> 1. Use hip04_defconfig to declare ARM_LPAE.
> 2. Use hi3xxx_defconfig, and only declare 2.9GB memory in DTS file
> without ARM_LPAE.
> 
> I think solution #1 is better. What's your opinion?
> 

I think it's a bug in the DT parsing code if incorrect memory
regions get added. It's supposed to parse the memory nodes using
"long enough" (u64 or arbitrary-length) data types and then
skip every range that doesn't fit into phys_addr_t.

	Arnd

^ permalink raw reply	[flat|nested] 55+ messages in thread

* [PATCH v15 07/12] ARM: dts: append hip04 dts
  2014-07-29  4:00         ` Olof Johansson
@ 2014-08-01 12:02           ` Haojian Zhuang
  0 siblings, 0 replies; 55+ messages in thread
From: Haojian Zhuang @ 2014-08-01 12:02 UTC (permalink / raw)
  To: linux-arm-kernel

On 29 July 2014 12:00, Olof Johansson <olof@lixom.net> wrote:
>>> >> +                       reg = <0x3e00000 0x00100000>;
>>> >> +                       relocation-entry = <0xe0000100>;
>>> >> +                       relocation-size = <0x1000>;
>>> >> +                       bootwrapper-phys = <0x10c00000>;
>>> >> +                       bootwrapper-size = <0x10000>;
>>> >> +                       bootwrapper-magic = <0xa5a5a5a5>;
>>> >
>>> > Are these absolute addresses, or translated per ranges above?
>>> >
>>> > Why are they related to the system controller?
>>> >
>>>
>>> I need these parameters. But I can't find a better place.
>>
>> Again, what is the boot wrapper in this case? And what do you need them for?
>
> Ok, looking at patch 3/12, it seems that the "bootwrapper" base
> address is used to specify where the CPU goes when released by the
> system controller.
>
> Isn't there an address that can be written in the system controller
> that specifies this base address, such that you can just handle this
> dynamically at runtime? It seems really, really odd that the platform
> will expect this one page in the middle of ram to just be untouched
> otherwise.
>

I'll move these parameters from DTS file to command line. Then I can
reserve these memory when I parse the command line.

Regards
Haojian

^ permalink raw reply	[flat|nested] 55+ messages in thread

* [PATCH v15 08/12] ARM: config: append lpae configuration
  2014-07-31 14:41               ` Arnd Bergmann
@ 2014-08-01 12:16                 ` Haojian Zhuang
  0 siblings, 0 replies; 55+ messages in thread
From: Haojian Zhuang @ 2014-08-01 12:16 UTC (permalink / raw)
  To: linux-arm-kernel

On 31 July 2014 22:41, Arnd Bergmann <arnd@arndb.de> wrote:
> On Thursday 31 July 2014, Haojian Zhuang wrote:
>> Maybe I didn't express this well. Let's check the memory layout in hip04.
>>
>> <0x00000000-10000000, 0x00000000-c0000000> & <0x00000004-0xc0000000,
>> 0x00000003-40000000> are two memory regions.
>>
>> These memory address is 64-bit. When ARM_LPAE is disabled,
>> memblock_add() parses memory base address & size with 32-bit. Since
>> ARCH_PHYS_ADDR_T_64BIT is highly depend on ARM_LPAE.
>>
>> Then these two memory regions become <0x10000000, 0xc0000000> &
>> <0xc0000000, 0xffffffff>. Lots of IO space are in <0xe0000000,
>> 0xefffffff>. So memory space conflicts when ARM_LPAE is disabled.
>> Kernel panic will come since it believes IO space is memory.
>>
>> Only two solutions are available in below.
>> 1. Use hip04_defconfig to declare ARM_LPAE.
>> 2. Use hi3xxx_defconfig, and only declare 2.9GB memory in DTS file
>> without ARM_LPAE.
>>
>> I think solution #1 is better. What's your opinion?
>>
>
> I think it's a bug in the DT parsing code if incorrect memory
> regions get added. It's supposed to parse the memory nodes using
> "long enough" (u64 or arbitrary-length) data types and then
> skip every range that doesn't fit into phys_addr_t.
>
>         Arnd

OK. I'll check them before invoking memblock_add().

Regards
Haojian

^ permalink raw reply	[flat|nested] 55+ messages in thread

end of thread, other threads:[~2014-08-01 12:16 UTC | newest]

Thread overview: 55+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-07-28 13:57 [PATCH v15 00/12] enable Hisilicon HiP04 Haojian Zhuang
2014-07-28 13:57 ` [PATCH v15 01/12] irq: gic: support hip04 gic Haojian Zhuang
2014-07-28 17:38   ` Marc Zyngier
2014-07-29 13:05     ` Arnd Bergmann
2014-07-29 13:19       ` Will Deacon
2014-07-29 13:41       ` Marc Zyngier
2014-07-28 13:57 ` [PATCH v15 02/12] ARM: mcpm: support 4 clusters Haojian Zhuang
2014-07-28 13:57 ` [PATCH v15 03/12] ARM: hisi: enable MCPM implementation Haojian Zhuang
2014-07-28 13:57 ` [PATCH v15 04/12] ARM: hisi: enable HiP04 Haojian Zhuang
2014-07-28 14:38   ` Arnd Bergmann
2014-07-28 13:57 ` [PATCH v15 05/12] document: dt: add the binding on HiP04 Haojian Zhuang
2014-07-28 14:41   ` Arnd Bergmann
2014-07-28 13:57 ` [PATCH v15 06/12] document: dt: add the binding on HiP04 clock Haojian Zhuang
2014-07-28 17:54   ` Mark Rutland
2014-07-29  2:25     ` Haojian Zhuang
2014-07-29  9:55       ` Arnd Bergmann
2014-07-29 10:40         ` Haojian Zhuang
2014-07-29 12:38       ` Mark Rutland
2014-07-28 13:57 ` [PATCH v15 07/12] ARM: dts: append hip04 dts Haojian Zhuang
2014-07-28 18:06   ` Mark Rutland
2014-07-29  2:44     ` Haojian Zhuang
2014-07-29  3:53       ` Olof Johansson
2014-07-29  4:00         ` Olof Johansson
2014-08-01 12:02           ` Haojian Zhuang
2014-07-29 10:58         ` Haojian Zhuang
2014-07-29 16:56           ` Olof Johansson
2014-07-29 11:12         ` Will Deacon
2014-07-29 11:32           ` Haojian Zhuang
2014-07-29 12:13             ` Will Deacon
2014-07-29 12:15               ` Haojian Zhuang
2014-07-29 12:22                 ` Will Deacon
2014-07-29 12:32       ` Mark Rutland
2014-07-29 17:01         ` Olof Johansson
2014-07-29 17:33           ` Mark Rutland
2014-07-30 11:26           ` Leif Lindholm
2014-07-28 13:57 ` [PATCH v15 08/12] ARM: config: append lpae configuration Haojian Zhuang
2014-07-29  4:05   ` Olof Johansson
2014-07-29 10:43     ` Haojian Zhuang
2014-07-31  1:01       ` Olof Johansson
2014-07-31  2:24         ` Haojian Zhuang
2014-07-31  3:55           ` Olof Johansson
2014-07-31  5:30             ` Haojian Zhuang
2014-07-31 14:41               ` Arnd Bergmann
2014-08-01 12:16                 ` Haojian Zhuang
2014-07-28 13:57 ` [PATCH v15 09/12] ARM: config: append hip04_defconfig Haojian Zhuang
2014-07-29  4:07   ` Olof Johansson
2014-07-28 13:57 ` [PATCH v15 10/12] ARM: hisi: enable erratum 798181 of A15 on HiP04 Haojian Zhuang
2014-07-29  4:08   ` Olof Johansson
2014-07-29 10:41     ` Haojian Zhuang
2014-07-28 13:57 ` [PATCH v15 11/12] virt: arm: support hip04 gic Haojian Zhuang
2014-07-28 18:00   ` Marc Zyngier
2014-07-29  2:31     ` Haojian Zhuang
2014-07-29  8:47       ` Marc Zyngier
2014-07-28 13:57 ` [PATCH v15 12/12] ARM: debug: add HiP04 debug uart Haojian Zhuang
2014-07-28 14:43 ` [PATCH v15 00/12] enable Hisilicon HiP04 Arnd Bergmann

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.