enable HiP04 SoC
Subsystems (10)
v10 cover enable HiP04 SoC
Changelog:
v10:
* Move snoop filter code to be executed on secondary cores. And change it to assembly code since MMU isn't enabled at that time.
* Rebase irq gic patch on latest gic patch.
* Use global variable in irq gic patch.
* Use global variable in vgic patch.
* Drop debug uart patch since it's in another patch set.
* Remove some ARCHs from multi_v7_lpae_defconfig.
v9:
* Remove delay workaround in mcpm implementation.
* Clean in gic.
* Rename vgic_cpu_nr_lr to vgic_cpu_hw_cfg in vgic driver.
* Always use high word of vgic_cpu_hw_cfg for GICH_APR offset. So the implementation of arm64 is also updated.
* Drop "irq: gic: use mask field in GICC_IAR" patch since it's merged.
v7:
* Remove hip04_smp_init_ops().
* Remove CONFIG_ARCH_HIP04 in hisilicn.c since hip04_smp_init_ops() is removed.
v6:
* Split HiP04 enabling patch into patches on document, mcpm & hiP04.
* Move reset operation in HiP04 MCPM implementation.
* Remove ARCH_MULTI_V7_NONLPAE & ARCH_MULTI_V7_LPAE according to olof's comment.
v5:
* Add ARCH_MULTI_V7_NONLPAE to avoid change too much things in Kconfig.
* Use memreserve in DTS.
* Remove L2 reset operation in mcpm implementation.
* Re-use nr_lr field to cover HIP04 GICH_APR implementation.
* Add more comments.
v4:
* Add multi_v7_lpae_defconfig.
* Select CONFIG_ARCH_MULTI_V7_LPAE if CONFIG_ARCH_MULTI_V7 is selected.
* Only ARMADA_XP is ARCH_MULTI_V7_LPAE, other ARMADA chips are ARCH_MULTI_V7.
* Remove gich_lr0 variable since we can calculate offset of GICH_LR0 from GICH_APR.
* Cleanup GIC driver to support HiP04 GIC.
* Cleanup HiP04 mcpm implementation.
v3:
* Replace CONFIG_ARCH_MULTI_V7 by CONFIG_ARCH_MULTI_V7_LPAE in some SoC.
* Update MCPM code based on Dave's patch.
* Remove MCPM node in DTS file. Use sysctrl & fabric node instead.
* Move hardcoding on bootwrapper into DTS file.
* Append the CONFIG_MCPM_QUAD_CLUSTER for HiP04.
* Fix the return value from gic_get_cpumask() if it's used in standard gic.
* Add the vgic support on HiP04 GIC.
* Add virtualization support in HiP04 defconfig.
v2:
* Append ARCH_MULTI_V7_LPAE configuration. Define ARCH_MULTI_V7 to only support non-LPAE platform.
* Append document of DT supporting.
* Append ARCH_HISI in hi3xxx_defconfig.
* Enable errata 798181 for HiP04 SoC.
* Add PMU support.
Haojian Zhuang (10):
irq: gic: support hip04 gic
ARM: mcpm: support 4 clusters
ARM: hisi: enable MCPM implementation
ARM: hisi: enable HiP04
document: dt: add the binding on HiP04
document: dt: add the binding on HiP04 clock
ARM: dts: append hip04 dts
ARM: config: append lpae configuration
ARM: config: append hip04_defconfig
virt: arm: support hip04 gic
Kefeng Wang (1):
ARM: hisi: enable erratum 798181 of A15 on HiP04
Documentation/devicetree/bindings/arm/gic.txt | 1 + .../bindings/arm/hisilicon/hisilicon.txt | 21 ++ .../devicetree/bindings/clock/hip04-clock.txt | 20 ++ arch/arm/Kconfig | 9 + arch/arm/boot/dts/Makefile | 1 + arch/arm/boot/dts/hip04-d01.dts | 39 +++ arch/arm/boot/dts/hip04.dtsi | 267 ++++++++++++++++ arch/arm/configs/hip04_defconfig | 74 +++++ arch/arm/configs/multi_v7_lpae_defconfig | 343 +++++++++++++++++++++ arch/arm/include/asm/mcpm.h | 5 + arch/arm/kernel/asm-offsets.c | 2 +- arch/arm/kvm/interrupts_head.S | 29 +- arch/arm/mach-hisi/Kconfig | 9 + arch/arm/mach-hisi/Makefile | 1 + arch/arm/mach-hisi/hisilicon.c | 9 + arch/arm/mach-hisi/platmcpm.c | 330 ++++++++++++++++++++ arch/arm64/kernel/asm-offsets.c | 2 +- arch/arm64/kvm/hyp.S | 4 +- drivers/irqchip/irq-gic.c | 141 +++++++-- include/kvm/arm_vgic.h | 7 +- include/linux/irqchip/arm-gic.h | 6 + virt/kvm/arm/vgic.c | 37 ++- 22 files changed, 1300 insertions(+), 57 deletions(-) create mode 100644 Documentation/devicetree/bindings/clock/hip04-clock.txt create mode 100644 arch/arm/boot/dts/hip04-d01.dts create mode 100644 arch/arm/boot/dts/hip04.dtsi create mode 100644 arch/arm/configs/hip04_defconfig create mode 100644 arch/arm/configs/multi_v7_lpae_defconfig create mode 100644 arch/arm/mach-hisi/platmcpm.c
Signature · 1 line
1.9.1
PATCH v10 1/11 irq: gic: support hip04 gic
There's a little difference between ARM GIC and HiP04 GIC.
* HiP04 GIC could support 16 cores at most, and ARM GIC could support 8 cores at most. So the difination on GIC_DIST_TARGET registers are different since CPU interfaces are increased from 8-bit to 16-bit.
* HiP04 GIC could support 510 interrupts at most, and ARM GIC could support 1020 interrupts at most.
--- Documentation/devicetree/bindings/arm/gic.txt | 1 + drivers/irqchip/irq-gic.c | 141 +++++++++++++++++++------- 2 files changed, 108 insertions(+), 34 deletions(-)
Documentation/devicetree/bindings/arm/gic.txt +1 -0
@@ -16,6 +16,7 @@ Main node required properties: "arm,cortex-a9-gic" "arm,cortex-a7-gic" "arm,arm11mp-gic" + "hisilicon,hip04-gic" - interrupt-controller : Identifies the node as an interrupt controller - #interrupt-cells : Specifies the number of cells needed to encode an interrupt source. The type shall be a <u32> and the value shall be 3.
drivers/irqchip/irq-gic.c +107 -34
284 lines not on this page · raw message
Signature · 1 line
1.9.1
Mark Rutland
reviewerPATCH v10 1/11 irq: gic: support hip04 gic
Quoted 1 line · Haojian Zhuang
There's a little difference between ARM GIC and HiP04 GIC.
Given that we can't target interrupts correctly without this patch, and that the GIC in a HiP04 system can't claim compatibility with any other GIC, I'd call this a major difference.
Quoted 13 lines
* HiP04 GIC could support 16 cores at most, and ARM GIC could support 8 cores at most. So the difination on
GIC_DIST_TARGETregisters 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.
Signed-off-by Haojian Zhuang <[email protected]>--- Documentation/devicetree/bindings/arm/gic.txt | 1 + drivers/irqchip/irq-gic.c | 141 +++++++++++++++++++------- 2 files changed, 108 insertions(+), 34 deletions(-)
[...]
Quoted 4 lines
drivers/irqchip/irq-gic.c +4
-0+static bool gic_is_standard (struct gic_chip_data *gic_data) +{ +return (gic_data->nr_cpu_if ==8 ); +}
drivers/irqchip/irq-gic.c static int gic_retrigger(struct irq_data *d) · line 239
Quoted 10 lines
drivers/irqchip/irq-gic.c +10
-0+ +static u32 irqs_per_target_reg (struct gic_chip_data *gic_data) +{ +return (32 / gic_data->nr_cpu_if); +} + +static u32 irq_to_target_reg (struct gic_chip_data *gic_data,u32 irq) +{ +if (!gic_is_standard (gic_data)) + irq *=2 ;
If the function is called gic_is_standard, then the only thing we should know here is whether the GIC follows the GIC standard, not how it differs from the standard.
Please rename this function to something like gicd_has_16_bit_targets or anything else that clearly defines what you're ttrying to derive from it.
Thanks,
Mark.
PATCH v10 1/11 irq: gic: support hip04 gic
In reply to Haojian ZhuangHaojian,
Quoted 6 lines · Haojian Zhuang
There's a little difference between ARM GIC and HiP04 GIC.
* HiP04 GIC could support 16 cores at most, and ARM GIC could support 8 cores at most. So the difination on
GIC_DIST_TARGETregisters are different since CPU interfaces are increased from 8-bit to 16-bit.
Quoted 8 lines
* HiP04 GIC could support 510 interrupts at most, and ARM GIC could support 1020 interrupts at most.
Signed-off-by Haojian Zhuang <[email protected]>--- Documentation/devicetree/bindings/arm/gic.txt | 1 + drivers/irqchip/irq-gic.c | 141 +++++++++++++++++++------- 2 files changed, 108 insertions(+), 34 deletions(-)
I need to apologize. This is my first full cycle maintaining irqchip and I'm still coming up to speed. The tl;dr is, I'm just not comfortable with the approach in this patch.
If irq-gic.c was only used by one SoC, it'd be different, but in the scenario we have, I think it would be best if this were a separate driver, say irq-gic-hip04.c. You can link in irq-gic-common.o to get gic_dist_config(), and you'll be able to remove a lot of the static functions and conditionals.
I really think it's worth the extra maintenance overhead to do it this way.
thx,
Jason.
Mark Rutland
reviewerPATCH v10 1/11 irq: gic: support hip04 gic
Quoted 22 lines · Jason Cooper
Haojian,
Quoted 6 lines · Haojian Zhuang
There's a little difference between ARM GIC and HiP04 GIC.
* HiP04 GIC could support 16 cores at most, and ARM GIC could support 8 cores at most. So the difination on
GIC_DIST_TARGETregisters are different since CPU interfaces are increased from 8-bit to 16-bit.Quoted 8 lines
* HiP04 GIC could support 510 interrupts at most, and ARM GIC could support 1020 interrupts at most.
Signed-off-by Haojian Zhuang <[email protected]>--- Documentation/devicetree/bindings/arm/gic.txt | 1 + drivers/irqchip/irq-gic.c | 141 +++++++++++++++++++------- 2 files changed, 108 insertions(+), 34 deletions(-)I need to apologize. This is my first full cycle maintaining irqchip and I'm still coming up to speed. The tl;dr is, I'm just not comfortable with the approach in this patch.
Quoted 5 lines
If
irq-gic.cwas only used by one SoC, it'd be different, but in the scenario we have, I think it would be best if this were a separate driver, sayirq-gic-hip04.c. You can link in irq-gic-common.o to getgic_dist_config(), and you'll be able to remove a lot of the static functions and conditionals.
A better approach might be to have some function pointers with each compatible string, and then have associated with the HiP04 compatible string, and then have those call common (inline) function variants. The compiler can then deal with the different variants and we don't end up with multiple GIC drivers getting out-of-sync.
Thanks,
Mark.
PATCH v10 2/11 ARM: mcpm: support 4 clusters
In reply to Haojian ZhuangAdd the CONFIG_MCPM_QUAD_CLUSTER configuration to enlarge cluster number from 2 to 4.
--- arch/arm/Kconfig | 9 +++++++++ arch/arm/include/asm/mcpm.h | 5 +++++ 2 files changed, 14 insertions(+)
arch/arm/Kconfig +9 -0
@@ -1490,6 +1490,15 @@ config MCPM for (multi-)cluster based systems, such as big.LITTLE based systems. +config MCPM_QUAD_CLUSTER + bool + depends on MCPM + help + To avoid wasting resources unnecessarily, MCPM only supports up + to 2 clusters by default. + Platforms with 3 or 4 clusters that use MCPM must select this + option to allow the additional clusters to be managed. + config BIG_LITTLE bool "big.LITTLE support (Experimental)" depends on CPU_V7 && SMP
arch/arm/include/asm/mcpm.h +5 -0
@@ -20,7 +20,12 @@* to consider dynamic allocation. */ #define MAX_CPUS_PER_CLUSTER 4 + +#ifdef CONFIG_MCPM_QUAD_CLUSTER +#define MAX_NR_CLUSTERS 4 +#else #define MAX_NR_CLUSTERS 2 +#endif #ifndef __ASSEMBLY__
Signature · 1 line
1.9.1
PATCH v10 3/11 ARM: hisi: enable MCPM implementation
In reply to Haojian ZhuangMultiple CPU clusters are used in Hisilicon HiP04 SoC. Now use MCPM framework to manage power on HiP04 SoC.
--- arch/arm/mach-hisi/Makefile | 1 + arch/arm/mach-hisi/platmcpm.c | 331 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 332 insertions(+) create mode 100644 arch/arm/mach-hisi/platmcpm.c
arch/arm/mach-hisi/Makefile +1 -0
@@ -3,4 +3,5 @@ # obj-y += hisilicon.o +obj-$(CONFIG_MCPM) += platmcpm.o obj-$(CONFIG_SMP) += platsmp.o hotplug.o headsmp.o
arch/arm/mach-hisi/platmcpm.c new file +331 -0
331 lines not on this page · raw message
Signature · 1 line
1.9.1
PATCH v10 3/11 ARM: hisi: enable MCPM implementation
Quoted 165 lines · Haojian Zhuang
Multiple CPU clusters are used in Hisilicon HiP04 SoC. Now use MCPM framework to manage power on HiP04 SoC.
Signed-off-by Haojian Zhuang <[email protected]>--- arch/arm/mach-hisi/Makefile | 1 + arch/arm/mach-hisi/platmcpm.c | 331 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 332 insertions(+) create mode 100644 arch/arm/mach-hisi/platmcpm.carch/arm/mach-hisi/Makefile +1
-0@@ -3,4 +3,5 @@ # obj-y += hisilicon.o +obj-$(CONFIG_MCPM) += platmcpm.o obj-$(CONFIG_SMP) += platsmp.o hotplug.o headsmp.oarch/arm/mach-hisi/platmcpm.c new file +139
-0@@ -0,0 +1,331 @@ +/* +* Copyright (c) 2013-2014 Linaro Ltd. +* Copyright (c) 2013-2014 Hisilicon Limited. +* +* This program is free software; you can redistribute it and/or modify it +* under the terms and conditions of the GNU General Public License, +* version 2, as published by the Free Software Foundation. +*/ +#include <linux/delay.h> +#include <linux/io.h> +#include <linux/of_address.h> + +#include <asm/cputype.h> +#include <asm/cp15.h> +#include <asm/mcpm.h> + +#include "core.h" + +/* bits definition in SC_CPU_RESET_REQ[x]/SC_CPU_RESET_DREQ[x] +* 1 -- unreset; 0 -- reset +*/ +#define CORE_RESET_BIT (x) (1 << x) +#define NEON_RESET_BIT (x) (1 << (x + 4)) +#define CORE_DEBUG_RESET_BIT (x) (1 << (x + 9)) +#define CLUSTER_L2_RESET_BIT (1 << 8) +#define CLUSTER_DEBUG_RESET_BIT (1 << 13) + +/* +* bits definition in SC_CPU_RESET_STATUS[x] +* 1 -- reset status; 0 -- unreset status +*/ +#define CORE_RESET_STATUS (x) (1 << x) +#define NEON_RESET_STATUS (x) (1 << (x + 4)) +#define CORE_DEBUG_RESET_STATUS (x) (1 << (x + 9)) +#define CLUSTER_L2_RESET_STATUS (1 << 8) +#define CLUSTER_DEBUG_RESET_STATUS (1 << 13) +#define CORE_WFI_STATUS (x) (1 << (x + 16)) +#define CORE_WFE_STATUS (x) (1 << (x + 20)) +#define CORE_DEBUG_ACK (x) (1 << (x + 24)) + +#define SC_CPU_RESET_REQ (x) (0x520 + (x << 3))/* reset */ +#define SC_CPU_RESET_DREQ (x) (0x524 + (x << 3))/* unreset */ +#define SC_CPU_RESET_STATUS (x) (0x1520 + (x << 3)) + +#define FAB_SF_MODE 0x0c +#define FAB_SF_INVLD 0x10 + +/* bits definition in FB_SF_INVLD */ +#define FB_SF_INVLD_START (1 << 8) + +#define HIP04_MAX_CLUSTERS 4 +#define HIP04_MAX_CPUS_PER_CLUSTER 4 + +#define POLL_MSEC 10 +#define TIMEOUT_MSEC 1000 + +struct hip04_secondary_cpu_data { +u32 bootwrapper_phys; +u32 bootwrapper_size; +u32 bootwrapper_magic; +u32 relocation_entry; +u32 relocation_size; +}; + +static void __iomem *relocation, *sysctrl, *fabric; +static int hip04_cpu_table[HIP04_MAX_CLUSTERS ][HIP04_MAX_CPUS_PER_CLUSTER ]; +static DEFINE_SPINLOCK (boot_lock); +static struct hip04_secondary_cpu_data hip04_boot; +static u32 fabric_phys_addr; + +static bool hip04_cluster_down (unsigned int cluster) +{ +int i; + +for (i =0 ; i <HIP04_MAX_CPUS_PER_CLUSTER ; i++) +if (hip04_cpu_table[cluster][i]) +return false; +return true; +} + +static int hip04_mcpm_power_up (unsigned int cpu,unsigned int cluster) +{ +unsigned long data, mask; + +if (!relocation || !sysctrl) +return -ENODEV ; +if (cluster >=HIP04_MAX_CLUSTERS || cpu >=HIP04_MAX_CPUS_PER_CLUSTER ) +return -EINVAL ; + +spin_lock_irq (&boot_lock); + +if (hip04_cpu_table[cluster][cpu]) { + hip04_cpu_table[cluster][cpu]++; +spin_unlock_irq (&boot_lock); +return 0 ; + } + +writel_relaxed (hip04_boot.bootwrapper_phys, relocation); +writel_relaxed (hip04_boot.bootwrapper_magic, relocation +4 ); +writel_relaxed (virt_to_phys (mcpm_entry_point), relocation +8 ); +writel_relaxed (0 , relocation +12 ); + +if (hip04_cluster_down (cluster)) { + data =CLUSTER_DEBUG_RESET_BIT ; +writel_relaxed (data, sysctrl +SC_CPU_RESET_DREQ (cluster)); +do { + mask =CLUSTER_DEBUG_RESET_STATUS ; + data =readl_relaxed (sysctrl + \ +SC_CPU_RESET_STATUS (cluster)); + }while (data & mask); + } + + hip04_cpu_table[cluster][cpu]++; + + data =CORE_RESET_BIT (cpu) |NEON_RESET_BIT (cpu) | \ +CORE_DEBUG_RESET_BIT (cpu); +writel_relaxed (data, sysctrl +SC_CPU_RESET_DREQ (cluster)); +spin_unlock_irq (&boot_lock); +msleep (POLL_MSEC ); + +return 0 ; +} + +static void hip04_mcpm_power_down (void ) +{ +unsigned int mpidr, cpu, cluster, data =0 ; +bool skip_reset = false; + + mpidr =read_cpuid_mpidr (); + cpu =MPIDR_AFFINITY_LEVEL (mpidr,0 ); + cluster =MPIDR_AFFINITY_LEVEL (mpidr,1 ); + +__mcpm_cpu_going_down (cpu, cluster); + +spin_lock (&boot_lock); +BUG_ON (__mcpm_cluster_state (cluster) !=CLUSTER_UP ); + hip04_cpu_table[cluster][cpu]--; +if (hip04_cpu_table[cluster][cpu] ==1 ) { +/* A power_up request went ahead of us. */
arch/arm/mach-hisi/platmcpm.c line 149
Quoted 10 lines
arch/arm/mach-hisi/platmcpm.c new file +10
-0+ skip_reset = true; + }else if (hip04_cpu_table[cluster][cpu] >1 ) { +pr_err ("Cluster %d CPU%d boots multiple times\n" , cluster, cpu); +BUG (); + } +spin_unlock (&boot_lock); + +v7_exit_coherency_flush (louis); + +__mcpm_cpu_down (cpu, cluster);
What if there is a hip04_mcpm_power_up() being called on another CPU right here? There is a race that I illustrated in a previous email which is still unresolved.
Quoted 37 lines
arch/arm/mach-hisi/platmcpm.c new file +37
-0+ +if (!skip_reset) { + data =CORE_RESET_BIT (cpu) |NEON_RESET_BIT (cpu) | \ +CORE_DEBUG_RESET_BIT (cpu); +writel_relaxed (data, sysctrl +SC_CPU_RESET_REQ (cluster)); + } +} + +static int hip04_mcpm_wait_for_powerdown (unsigned int cpu,unsigned int cluster) +{ +unsigned int data, tries; + +BUG_ON (cluster >=HIP04_MAX_CLUSTERS || + cpu >=HIP04_MAX_CPUS_PER_CLUSTER ); + +for (tries =0 ; tries <TIMEOUT_MSEC /POLL_MSEC ; tries++) { + data =readl_relaxed (sysctrl +SC_CPU_RESET_STATUS (cluster)); +if (!(data &CORE_RESET_STATUS (cpu))) { +msleep (POLL_MSEC ); +continue ; + } +return 0 ; + } +return -ETIMEDOUT ; +} + +static void hip04_mcpm_powered_up (void ) +{ +if (!relocation) +return ; +spin_lock (&boot_lock); +writel_relaxed (0 , relocation); +writel_relaxed (0 , relocation +4 ); +writel_relaxed (0 , relocation +8 ); +writel_relaxed (0 , relocation +12 ); +spin_unlock (&boot_lock); +}
arch/arm/mach-hisi/platmcpm.c line 196
Quoted 10 lines
arch/arm/mach-hisi/platmcpm.c new file +10
-0+ +static void __naked hip04_mcpm_power_up_setup (unsigned int affinity_level) +{ + asmvolatile (" \n" +/* calculate fabric phys address */ +" adr r2, 2f \n" +" ldmia r2, {r1, r3} \n" +" sub r0, r2, r1 \n" +" add r2, r0, r3 \n" +" ldr r2, [r2] \n"
You may replace the above 2 instructions with "ldr r2, [r0, r3]".
arch/arm/mach-hisi/platmcpm.c line 200
Quoted 4 lines
arch/arm/mach-hisi/platmcpm.c new file +4
-0+/* get cluster id from MPIDR */ +" mrc p15, 0, r0, c0, c0, 5 \n" +" ubfx r1, r0, #8, #8 \n" +" and r1, r1, #0xf \n"
You don't need the "and" here. It is implicit in ubfx.
arch/arm/mach-hisi/platmcpm.c line 206
Quoted 6 lines
arch/arm/mach-hisi/platmcpm.c new file +6
-0+/* 1 << cluster id */ +" mov r0, #1 \n" +" mov r3, r0, lsl r1 \n" +" ldr r0, [r2, #"__stringify(FAB_SF_MODE)"] \n" +" tst r0, r3 \n" +" bxne lr \n"
Instead of running all this code all the time, you could simply test r0 at the very beginning and if it is not equal to 1 then return immediately. If it is 1 that means the CPU executing this code is the first one to run in the cluster, in which case you also don't have to test if the cluster snoop is already enabled here.
arch/arm/mach-hisi/platmcpm.c line 218
Quoted 12 lines
arch/arm/mach-hisi/platmcpm.c new file +12
-0+" orr r1, r0, r3 \n" +" str r1, [r2, #"__stringify(FAB_SF_MODE)"] \n" +"1: ldr r0, [r2, #"__stringify(FAB_SF_MODE)"] \n" +" tst r0, r3 \n" +" beq 1b \n" +" bx lr \n" + +" .align 2 \n" +"2: .word . \n" +" .word fabric_phys_addr \n" + ); +}
Of course you will also have to enable the snoops for the current cluster in hip04_cpu_table_init() as well.
Quoted 117 lines
arch/arm/mach-hisi/platmcpm.c new file +113
-0+ +static const struct mcpm_platform_ops hip04_mcpm_ops = { + .power_up = hip04_mcpm_power_up, + .power_down = hip04_mcpm_power_down, + .wait_for_powerdown = hip04_mcpm_wait_for_powerdown, + .powered_up = hip04_mcpm_powered_up, +}; + +static bool __init hip04_cpu_table_init (void ) +{ +unsigned int mpidr, cpu, cluster; + + mpidr =read_cpuid_mpidr (); + cpu =MPIDR_AFFINITY_LEVEL (mpidr,0 ); + cluster =MPIDR_AFFINITY_LEVEL (mpidr,1 ); + +if (cluster >=HIP04_MAX_CLUSTERS || + cpu >=HIP04_MAX_CPUS_PER_CLUSTER ) { +pr_err ("%s: boot CPU is out of bound!\n" , __func__); +return false; + } + hip04_cpu_table[cluster][cpu] =1 ; +return true; +} + +static int __init hip04_mcpm_init (void ) +{ +struct device_node *np, *np_fab; +struct resource fab_res; +int ret = -ENODEV ; + + np =of_find_compatible_node (NULL ,NULL ,"hisilicon,sysctrl" ); +if (!np) + goto err; + np_fab =of_find_compatible_node (NULL ,NULL ,"hisilicon,hip04-fabric" ); +if (!np_fab) + goto err; + +if (of_property_read_u32 (np,"bootwrapper-phys" , + &hip04_boot.bootwrapper_phys)) { +pr_err ("failed to get bootwrapper-phys\n" ); + ret = -EINVAL ; + goto err; + } +if (of_property_read_u32 (np,"bootwrapper-size" , + &hip04_boot.bootwrapper_size)) { +pr_err ("failed to get bootwrapper-size\n" ); + ret = -EINVAL ; + goto err; + } +if (of_property_read_u32 (np,"bootwrapper-magic" , + &hip04_boot.bootwrapper_magic)) { +pr_err ("failed to get bootwrapper-magic\n" ); + ret = -EINVAL ; + goto err; + } +if (of_property_read_u32 (np,"relocation-entry" , + &hip04_boot.relocation_entry)) { +pr_err ("failed to get relocation-entry\n" ); + ret = -EINVAL ; + goto err; + } +if (of_property_read_u32 (np,"relocation-size" , + &hip04_boot.relocation_size)) { +pr_err ("failed to get relocation-size\n" ); + ret = -EINVAL ; + goto err; + } + + relocation =ioremap (hip04_boot.relocation_entry, + hip04_boot.relocation_size); +if (!relocation) { +pr_err ("failed to map relocation space\n" ); + ret = -ENOMEM ; + goto err; + } + sysctrl =of_iomap (np,0 ); +if (!sysctrl) { +pr_err ("failed to get sysctrl base\n" ); + ret = -ENOMEM ; + goto err_sysctrl; + } + ret =of_address_to_resource (np_fab,0 , &fab_res); +if (ret) { +pr_err ("failed to get fabric base phys\n" ); + goto err_fabric; + } + fabric_phys_addr = fab_res.start; +sync_cache_w (&fabric_phys_addr); + fabric =of_iomap (np_fab,0 ); +if (!fabric) { +pr_err ("failed to get fabric base\n" ); + ret = -ENOMEM ; + goto err_fabric; + } + +if (!hip04_cpu_table_init ()) +return -EINVAL ; + ret =mcpm_platform_register (&hip04_mcpm_ops); +if (!ret) { +mcpm_sync_init (hip04_mcpm_power_up_setup); +pr_info ("HiP04 MCPM initialized\n" ); + } +mcpm_smp_set_ops (); +return ret; +err_fabric: +iounmap (sysctrl); +err_sysctrl: +iounmap (relocation); +err: +return ret; +} +early_initcall (hip04_mcpm_init);Signature · 1 line
1.9.1
PATCH v10 3/11 ARM: hisi: enable MCPM implementation
Quoted 37 lines · Nicolas Pitre
Quoted 35 lines · Haojian Zhuang
Multiple CPU clusters are used in Hisilicon HiP04 SoC. Now use MCPM framework to manage power on HiP04 SoC.
Signed-off-by Haojian Zhuang <[email protected]>--- arch/arm/mach-hisi/Makefile | 1 + arch/arm/mach-hisi/platmcpm.c | 331 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 332 insertions(+) create mode 100644 arch/arm/mach-hisi/platmcpm.carch/arm/mach-hisi/Makefile +23
-0+ +static void hip04_mcpm_power_down(void) +{ + unsigned int mpidr, cpu, cluster, data = 0; + bool skip_reset = false; + + mpidr = read_cpuid_mpidr(); + cpu = MPIDR_AFFINITY_LEVEL(mpidr, 0); + cluster = MPIDR_AFFINITY_LEVEL(mpidr, 1); + + __mcpm_cpu_going_down(cpu, cluster); + + spin_lock(&boot_lock); + BUG_ON(__mcpm_cluster_state(cluster) != CLUSTER_UP); + hip04_cpu_table[cluster][cpu]--; + if (hip04_cpu_table[cluster][cpu] == 1) { + /* A power_up request went ahead of us. */ + skip_reset = true; + } else if (hip04_cpu_table[cluster][cpu] > 1) { + pr_err("Cluster %d CPU%d boots multiple times\n", cluster, cpu); + BUG(); + } + spin_unlock(&boot_lock);
Quoted 9 lines
arch/arm/mach-hisi/Makefile
Quoted 4 lines
arch/arm/mach-hisi/Makefile +4
-0+ + v7_exit_coherency_flush(louis); + + __mcpm_cpu_down(cpu, cluster);What if there is a
hip04_mcpm_power_up()being called on another CPU right here? There is a race that I illustrated in a previous email which is still unresolved.
Thanks for your reminder again. I'll move it into the protection.
Quoted 41 lines
Quoted 41 lines
arch/arm/mach-hisi/Makefile +41
-0+ + if (!skip_reset) { + data = CORE_RESET_BIT(cpu) | NEON_RESET_BIT(cpu) | \ + CORE_DEBUG_RESET_BIT(cpu); + writel_relaxed(data, sysctrl + SC_CPU_RESET_REQ(cluster)); + } +} + +static int hip04_mcpm_wait_for_powerdown(unsigned int cpu, unsigned int cluster) +{ + unsigned int data, tries; + + BUG_ON(cluster >= HIP04_MAX_CLUSTERS || + cpu >= HIP04_MAX_CPUS_PER_CLUSTER); + + for (tries = 0; tries < TIMEOUT_MSEC / POLL_MSEC; tries++) { + data = readl_relaxed(sysctrl + SC_CPU_RESET_STATUS(cluster)); + if (!(data & CORE_RESET_STATUS(cpu))) { + msleep(POLL_MSEC); + continue; + } + return 0; + } + return -ETIMEDOUT; +} + +static void hip04_mcpm_powered_up(void) +{ + if (!relocation) + return; + spin_lock(&boot_lock); + writel_relaxed(0, relocation); + writel_relaxed(0, relocation + 4); + writel_relaxed(0, relocation + 8); + writel_relaxed(0, relocation + 12); + spin_unlock(&boot_lock); +} + +static void __naked hip04_mcpm_power_up_setup(unsigned int affinity_level) +{ + asm volatile (" \n"
Quoted 9 lines
Quoted 6 lines
+ /* calculate fabric phys address */ +" adr r2, 2f \n" +" ldmia r2, {r1, r3} \n" +" sub r0, r2, r1 \n" +" add r2, r0, r3 \n" +" ldr r2, [r2] \n"You may replace the above 2 instructions with "ldr r2, [r0, r3]".
OK.
Quoted 7 lines
Quoted 4 lines
+ /* get cluster id from MPIDR */ +" mrc p15, 0, r0, c0, c0, 5 \n" +" ubfx r1, r0, #8, #8 \n" +" and r1, r1, #0xf \n"You don't need the "and" here. It is implicit in ubfx.
OK.
Quoted 7 lines
Quoted 6 lines
+ /* 1 << cluster id */ +" mov r0, #1 \n" +" mov r3, r0, lsl r1 \n" +" ldr r0, [r2, #"__stringify(FAB_SF_MODE)"] \n" +" tst r0, r3 \n" +" bxne lr \n"
Quoted 6 lines
Instead of running all this code all the time, you could simply test r0 at the very beginning and if it is not equal to 1 then return immediately. If it is 1 that means the CPU executing this code is the first one to run in the cluster, in which case you also don't have to test if the cluster snoop is already enabled here.
Since I need to enable the cluster snoop for cluster 0. At this time, it's not enabled although core0 is running.
Quoted 7 lines
Quoted 7 lines
+" orr r1, r0, r3 \n" +" str r1, [r2, #"__stringify(FAB_SF_MODE)"] \n" +"1: ldr r0, [r2, #"__stringify(FAB_SF_MODE)"] \n" +" tst r0, r3 \n" +" beq 1b \n" +" bx lr \n"+
Quoted 8 lines
arch/arm/mach-hisi/Makefile
Quoted 5 lines
+" .align 2 \n" +"2: .word . \n" +" .word fabric_phys_addr \n"arch/arm/mach-hisi/Makefile +2
-0+ ); +}Of course you will also have to enable the snoops for the current cluster in
hip04_cpu_table_init()as well.
It means that I need to reserve the copy to enable the snoop in c code for cluster 0. Is it right?
Quoted 119 lines
Quoted 119 lines
arch/arm/mach-hisi/Makefile +113
-1+ +static const struct mcpm_platform_ops hip04_mcpm_ops = { + .power_up = hip04_mcpm_power_up, + .power_down = hip04_mcpm_power_down, + .wait_for_powerdown = hip04_mcpm_wait_for_powerdown, + .powered_up = hip04_mcpm_powered_up, +}; + +static bool __init hip04_cpu_table_init(void) +{ + unsigned int mpidr, cpu, cluster; + + mpidr = read_cpuid_mpidr(); + cpu = MPIDR_AFFINITY_LEVEL(mpidr, 0); + cluster = MPIDR_AFFINITY_LEVEL(mpidr, 1); + + if (cluster >= HIP04_MAX_CLUSTERS || + cpu >= HIP04_MAX_CPUS_PER_CLUSTER) { + pr_err("%s: boot CPU is out of bound!\n", __func__); + return false; + } + hip04_cpu_table[cluster][cpu] = 1; + return true; +} + +static int __init hip04_mcpm_init(void) +{ + struct device_node *np, *np_fab; + struct resource fab_res; + int ret = -ENODEV; + + np = of_find_compatible_node(NULL, NULL, "hisilicon,sysctrl"); + if (!np) + goto err; + np_fab = of_find_compatible_node(NULL, NULL, "hisilicon,hip04-fabric"); + if (!np_fab) + goto err; + + if (of_property_read_u32(np, "bootwrapper-phys", + &hip04_boot.bootwrapper_phys)) { + pr_err("failed to get bootwrapper-phys\n"); + ret = -EINVAL; + goto err; + } + if (of_property_read_u32(np, "bootwrapper-size", + &hip04_boot.bootwrapper_size)) { + pr_err("failed to get bootwrapper-size\n"); + ret = -EINVAL; + goto err; + } + if (of_property_read_u32(np, "bootwrapper-magic", + &hip04_boot.bootwrapper_magic)) { + pr_err("failed to get bootwrapper-magic\n"); + ret = -EINVAL; + goto err; + } + if (of_property_read_u32(np, "relocation-entry", + &hip04_boot.relocation_entry)) { + pr_err("failed to get relocation-entry\n"); + ret = -EINVAL; + goto err; + } + if (of_property_read_u32(np, "relocation-size", + &hip04_boot.relocation_size)) { + pr_err("failed to get relocation-size\n"); + ret = -EINVAL; + goto err; + } + + relocation = ioremap(hip04_boot.relocation_entry, + hip04_boot.relocation_size); + if (!relocation) { + pr_err("failed to map relocation space\n"); + ret = -ENOMEM; + goto err; + } + sysctrl = of_iomap(np, 0); + if (!sysctrl) { + pr_err("failed to get sysctrl base\n"); + ret = -ENOMEM; + goto err_sysctrl; + } + ret = of_address_to_resource(np_fab, 0, &fab_res); + if (ret) { + pr_err("failed to get fabric base phys\n"); + goto err_fabric; + } + fabric_phys_addr = fab_res.start; + sync_cache_w(&fabric_phys_addr); + fabric = of_iomap(np_fab, 0); + if (!fabric) { + pr_err("failed to get fabric base\n"); + ret = -ENOMEM; + goto err_fabric; + } + + if (!hip04_cpu_table_init()) + return -EINVAL; + ret = mcpm_platform_register(&hip04_mcpm_ops); + if (!ret) { + mcpm_sync_init(hip04_mcpm_power_up_setup); + pr_info("HiP04 MCPM initialized\n"); + } + mcpm_smp_set_ops(); + return ret; +err_fabric: + iounmap(sysctrl); +err_sysctrl: + iounmap(relocation); +err: + return ret; +} +early_initcall(hip04_mcpm_init); --1.9.1
PATCH v10 3/11 ARM: hisi: enable MCPM implementation
Quoted 40 lines · Haojian Zhuang
Quoted 14 lines · Nicolas Pitre
arch/arm/mach-hisi/platmcpm.c line 196
Quoted 9 lines · Haojian Zhuang
arch/arm/mach-hisi/platmcpm.c new file +9
-0+static void __naked hip04_mcpm_power_up_setup (unsigned int affinity_level) +{ + asmvolatile (" \n" +/* calculate fabric phys address */ +" adr r2, 2f \n" +" ldmia r2, {r1, r3} \n" +" sub r0, r2, r1 \n" +" add r2, r0, r3 \n" +" ldr r2, [r2] \n"You may replace the above 2 instructions with "ldr r2, [r0, r3]".
OK.
Quoted 7 lines
Quoted 4 lines
+ /* get cluster id from MPIDR */ +" mrc p15, 0, r0, c0, c0, 5 \n" +" ubfx r1, r0, #8, #8 \n" +" and r1, r1, #0xf \n"You don't need the "and" here. It is implicit in ubfx.
OK.
Quoted 7 lines
Quoted 6 lines
+ /* 1 << cluster id */ +" mov r0, #1 \n" +" mov r3, r0, lsl r1 \n" +" ldr r0, [r2, #"__stringify(FAB_SF_MODE)"] \n" +" tst r0, r3 \n" +" bxne lr \n"Quoted 6 lines
Instead of running all this code all the time, you could simply test r0 at the very beginning and if it is not equal to 1 then return immediately. If it is 1 that means the CPU executing this code is the first one to run in the cluster, in which case you also don't have to test if the cluster snoop is already enabled here.
Quoted 2 lines
Since I need to enable the cluster snoop for cluster 0. At this time, it's not enabled although core0 is running.
Yes, hence my next comment.
Quoted 16 lines
Quoted 7 lines
Quoted 7 lines
+" orr r1, r0, r3 \n" +" str r1, [r2, #"__stringify(FAB_SF_MODE)"] \n" +"1: ldr r0, [r2, #"__stringify(FAB_SF_MODE)"] \n" +" tst r0, r3 \n" +" beq 1b \n" +" bx lr \n"+
Quoted 8 lines
Review
Quoted 5 lines
+" .align 2 \n" +"2: .word . \n" +" .word fabric_phys_addr \n"(quoted diff) +2
-0+ ); +}Of course you will also have to enable the snoops for the current cluster in
hip04_cpu_table_init()as well.
Quoted 2 lines
It means that I need to reserve the copy to enable the snoop in c code for cluster 0. Is it right?
Yes. And it can be __init just like hip04_cpu_table_init().
Nicolas
PATCH v10 4/11 ARM: hisi: enable HiP04
In reply to Haojian ZhuangSupport HiP04 SoC what supports 16 cores. And it relies on MCPM framework.
--- arch/arm/mach-hisi/Kconfig | 8 ++++++++ arch/arm/mach-hisi/hisilicon.c | 9 +++++++++ arch/arm/mach-hisi/platmcpm.c | 1 - 3 files changed, 17 insertions(+), 1 deletion(-)
arch/arm/mach-hisi/Kconfig +8 -0
@@ -19,6 +19,14 @@ config ARCH_HI3xxx help Support for Hisilicon Hi36xx SoC family +config ARCH_HIP04 + bool "Hisilicon HiP04 Cortex A15 family" if ARCH_MULTI_V7 + select HAVE_ARM_ARCH_TIMER + select MCPM if SMP + select MCPM_QUAD_CLUSTER if SMP + help + Support for Hisilicon HiP04 SoC family + config ARCH_HIX5HD2 bool "Hisilicon X5HD2 family" if ARCH_MULTI_V7 select CACHE_L2X0
arch/arm/mach-hisi/hisilicon.c +9 -0
@@ -114,3 +114,12 @@ DT_MACHINE_START(HIX5HD2_DT, "Hisilicon HIX5HD2 (Flattened Device Tree)") .smp = smp_ops(hix5hd2_smp_ops), .restart = hi3xxx_restart, MACHINE_END + +static const char *hip04_compat[] __initconst = { +"hisilicon,hip04-d01" , +NULL , +}; + +DT_MACHINE_START (HIP04 ,"Hisilicon HiP04 (Flattened Device Tree)" ) + .dt_compat = hip04_compat, +MACHINE_END
arch/arm/mach-hisi/platmcpm.c +0 -1
@@ -116,7 +116,6 @@ static int hip04_mcpm_power_up(unsigned int cpu, unsigned int cluster)CORE_DEBUG_RESET_BIT (cpu);writel_relaxed (data, sysctrl +SC_CPU_RESET_DREQ (cluster));spin_unlock_irq (&boot_lock); -msleep (POLL_MSEC );return 0 ; }
Signature · 1 line
1.9.1
Arnd Bergmann
maintainerPATCH v10 4/11 ARM: hisi: enable HiP04
arch/arm/mach-hisi/platmcpm.c static int hip04_mcpm_power_up(unsigned int cpu, unsigned int cluster) · line 121
Quoted 10 lines · Haojian Zhuang
arch/arm/mach-hisi/platmcpm.c +0
-1@@ -116,7 +116,6 @@ static int hip04_mcpm_power_up(unsigned int cpu, unsigned int cluster)CORE_DEBUG_RESET_BIT (cpu);writel_relaxed (data, sysctrl +SC_CPU_RESET_DREQ (cluster));spin_unlock_irq (&boot_lock); -msleep (POLL_MSEC );return 0 ; }
Is this change intentional? It seems like it should belong into the earlier patch that introduces this file.
Arnd
PATCH v10 4/11 ARM: hisi: enable HiP04
Quoted 9 lines · Arnd Bergmann
Quoted 8 lines · Haojian Zhuang
arch/arm/mach-hisi/platmcpm.c +0
-1@@ -116,7 +116,6 @@ static int hip04_mcpm_power_up(unsigned int cpu, unsigned int cluster)CORE_DEBUG_RESET_BIT (cpu);writel_relaxed (data, sysctrl +SC_CPU_RESET_DREQ (cluster));spin_unlock_irq (&boot_lock); -msleep (POLL_MSEC );
Quoted 7 lines
arch/arm/mach-hisi/platmcpm.c static int hip04_mcpm_power_up(unsigned int cpu, unsigned int cluster) · line 121
Quoted 2 lines
arch/arm/mach-hisi/platmcpm.c +0
-0return 0 ; }Is this change intentional? It seems like it should belong into the earlier patch that introduces this file.
Arnd
Yes, it should belong to the earlier patch. And it's fixed in v12 or v13.
Regards
Haojian
PATCH v10 5/11 document: dt: add the binding on HiP04
In reply to Haojian ZhuangAdd bootwrapper-phys, bootwrapper-size, bootwrapper-magic properties for Hisilicon HiP04 SoC.
--- .../devicetree/bindings/arm/hisilicon/hisilicon.txt | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+)
Documentation/devicetree/bindings/arm/hisilicon/hisilicon.txt +21 -0
@@ -4,6 +4,10 @@ Hisilicon Platforms Device Tree Bindings Hi4511 Board Required root node properties: - compatible = "hisilicon,hi3620-hi4511"; +HiP04 D01 Board +Required root node properties: + - compatible = "hisilicon,hip04-d01"; + Hisilicon system controller
@@ -19,6 +23,15 @@ Optional properties: If reg value is not zero, cpun exit wfi and go - resume-offset : offset in sysctrl for notifying cpu0 when resume - reboot-offset : offset in sysctrl for system reboot +- relocation-entry : relocation address of secondary cpu boot code +- relocation-size : relocation size of secondary cpu boot code +- bootwrapper-phys : physical address of boot wrapper +- bootwrapper-size : size of boot wrapper +- bootwrapper-magic : magic number for secondary cpu in boot wrapper +The memory area of [bootwrapper-phys : bootwrapper-phys+bootwrapper-size] +should be reserved. This should be set in /memreserve/ node in DTS file. +bootwrapper-phys, bootwrapper-size, bootwrapper-magic is used in HiP04 +DTS file. Example:
@@ -31,6 +44,7 @@ Example: reboot-offset = <0x4>; }; + PCTRL: Peripheral misc control register Required Properties:
@@ -44,3 +58,10 @@ Example: compatible = "hisilicon,pctrl"; reg = <0xfca09000 0x1000>; }; + + +Fabric: + +Required Properties: +- compatible: "hisilicon,hip04-fabric"; +- reg: Address and size of Fabric
Signature · 1 line
1.9.1
PATCH v10 6/11 document: dt: add the binding on HiP04 clock
In reply to Haojian ZhuangThe DT binding for Hisilicon HiP04 clock driver.
--- .../devicetree/bindings/clock/hip04-clock.txt | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 Documentation/devicetree/bindings/clock/hip04-clock.txt
Documentation/devicetree/bindings/clock/hip04-clock.txt new file +20 -0
@@ -0,0 +1,20 @@ +* Hisilicon HiP04 Clock Controller + +The HiP04 clock controller generates and supplies clock to various +controllers within the HiP04 SoC. + +Required Properties: + +- compatible: should be one of the following. + - "hisilicon,hip04-clock" - controller compatible with HiP04 SoC. + +- reg: physical base address of the controller and length of memory mapped + region. + +- #clock-cells: should be 1. + + +Each clock is assigned an identifier and client nodes use this identifier +to specify the clock which they consume. + +All these identifier could be found in <dt-bindings/clock/hip04-clock.h>.
Signature · 1 line
1.9.1
PATCH v10 7/11 ARM: dts: append hip04 dts
In reply to Haojian ZhuangAdd hip04-d01.dts & hip04.dtsi for hip04 SoC platform.
--- arch/arm/boot/dts/Makefile | 1 + arch/arm/boot/dts/hip04-d01.dts | 39 ++++++ arch/arm/boot/dts/hip04.dtsi | 267 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 307 insertions(+) create mode 100644 arch/arm/boot/dts/hip04-d01.dts create mode 100644 arch/arm/boot/dts/hip04.dtsi
arch/arm/boot/dts/Makefile +1 -0
@@ -86,6 +86,7 @@ dtb-$(CONFIG_ARCH_HI3xxx) += hi3620-hi4511.dtb dtb-$(CONFIG_ARCH_HIX5HD2) += hix5hd2-dkb.dtb dtb-$(CONFIG_ARCH_HIGHBANK) += highbank.dtb \ ecx-2000.dtb +dtb-$(CONFIG_ARCH_HIP04) += hip04-d01.dtb dtb-$(CONFIG_ARCH_INTEGRATOR) += integratorap.dtb \ integratorcp.dtb dtb-$(CONFIG_ARCH_KEYSTONE) += k2hk-evm.dtb \
arch/arm/boot/dts/hip04-d01.dts new file +39 -0
@@ -0,0 +1,39 @@ +/* + * Copyright (C) 2013-2014 Linaro Ltd. + * Author: Haojian Zhuang <[email protected]> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * publishhed by the Free Software Foundation. + */ + +/dts-v1/; + +/* For bootwrapper */ +/memreserve/ 0x10c00000 0x00010000; + +#include "hip04.dtsi" + +/ { + /* memory bus is 64-bit */ + #address-cells = <2>; + #size-cells = <2>; + model = "Hisilicon D01 Development Board"; + compatible = "hisilicon,hip04-d01"; + + memory at 00000000,10000000 { + device_type = "memory"; + reg = <0x00000000 0x10000000 0x00000000 0xc0000000>; + }; + + memory at 00000004,c0000000 { + device_type = "memory"; + reg = <0x00000004 0xc0000000 0x00000003 0x40000000>; + }; + + soc { + uart0: uart at 4007000 { + status = "ok"; + }; + }; +};
arch/arm/boot/dts/hip04.dtsi new file +267 -0
267 lines not on this page · raw message
Signature · 1 line
1.9.1
PATCH v10 8/11 ARM: config: append lpae configuration
In reply to Haojian ZhuangAppend multi_v7_lpae_config. In this default configuration, CONFIG_ARCH_MULTI_V6 is disabled. CONFIG_ARM_LPAE is enabled.
--- arch/arm/configs/multi_v7_lpae_defconfig | 343 +++++++++++++++++++++++++++++++ 1 file changed, 343 insertions(+) create mode 100644 arch/arm/configs/multi_v7_lpae_defconfig
arch/arm/configs/multi_v7_lpae_defconfig new file +343 -0
@@ -0,0 +1,343 @@ +CONFIG_SYSVIPC=y +CONFIG_FHANDLE=y +CONFIG_IRQ_DOMAIN_DEBUG=y +CONFIG_NO_HZ=y +CONFIG_HIGH_RES_TIMERS=y +CONFIG_BLK_DEV_INITRD=y +CONFIG_EMBEDDED=y +CONFIG_MODULES=y +CONFIG_MODULE_UNLOAD=y +CONFIG_PARTITION_ADVANCED=y +# CONFIG_ARCH_MULTI_V6 is not set +CONFIG_ARCH_MULTI_V7=y +CONFIG_ARM_LPAE=y +CONFIG_ARCH_MVEBU=y +CONFIG_MACH_ARMADA_XP=y +CONFIG_ARCH_BCM=y +CONFIG_ARCH_BCM_5301X=y +CONFIG_ARCH_BCM_MOBILE=y +CONFIG_GPIO_PCA953X=y +CONFIG_ARCH_HIGHBANK=y +CONFIG_ARCH_HISI=y +CONFIG_ARCH_HIP04=y +CONFIG_ARCH_KEYSTONE=y +CONFIG_ARCH_MXC=y +CONFIG_MACH_IMX51_DT=y +CONFIG_SOC_IMX53=y +CONFIG_SOC_IMX6Q=y +CONFIG_SOC_IMX6SL=y +CONFIG_SOC_VF610=y +CONFIG_ARCH_OMAP3=y +CONFIG_ARCH_OMAP4=y +CONFIG_SOC_OMAP5=y +CONFIG_SOC_AM33XX=y +CONFIG_SOC_DRA7XX=y +CONFIG_SOC_AM43XX=y +CONFIG_ARCH_QCOM=y +CONFIG_ARCH_MSM8X60=y +CONFIG_ARCH_MSM8960=y +CONFIG_ARCH_MSM8974=y +CONFIG_ARCH_ROCKCHIP=y +CONFIG_ARCH_SOCFPGA=y +CONFIG_PLAT_SPEAR=y +CONFIG_ARCH_SPEAR13XX=y +CONFIG_MACH_SPEAR1310=y +CONFIG_MACH_SPEAR1340=y +CONFIG_ARCH_STI=y +CONFIG_ARCH_SUNXI=y +CONFIG_ARCH_SIRF=y +CONFIG_ARCH_TEGRA=y +CONFIG_ARCH_TEGRA_2x_SOC=y +CONFIG_ARCH_TEGRA_3x_SOC=y +CONFIG_ARCH_TEGRA_114_SOC=y +CONFIG_ARCH_TEGRA_124_SOC=y +CONFIG_TEGRA_EMC_SCALING_ENABLE=y +CONFIG_ARCH_U8500=y +CONFIG_MACH_HREFV60=y +CONFIG_MACH_SNOWBALL=y +CONFIG_MACH_UX500_DT=y +CONFIG_ARCH_VEXPRESS=y +CONFIG_ARCH_VEXPRESS_CA9X4=y +CONFIG_ARCH_VIRT=y +CONFIG_ARCH_WM8850=y +CONFIG_ARCH_ZYNQ=y +CONFIG_NEON=y +CONFIG_TRUSTED_FOUNDATIONS=y +CONFIG_PCI=y +CONFIG_PCI_MSI=y +CONFIG_PCI_MVEBU=y +CONFIG_PCI_TEGRA=y +CONFIG_SMP=y +CONFIG_HIGHMEM=y +CONFIG_HIGHPTE=y +CONFIG_CMA=y +CONFIG_ARM_APPENDED_DTB=y +CONFIG_ARM_ATAG_DTB_COMPAT=y +CONFIG_KEXEC=y +CONFIG_CPU_FREQ=y +CONFIG_CPU_FREQ_STAT_DETAILS=y +CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y +CONFIG_CPU_IDLE=y +CONFIG_NET=y +CONFIG_PACKET=y +CONFIG_UNIX=y +CONFIG_INET=y +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +CONFIG_IP_PNP_BOOTP=y +CONFIG_IP_PNP_RARP=y +CONFIG_IPV6_ROUTER_PREF=y +CONFIG_IPV6_OPTIMISTIC_DAD=y +CONFIG_INET6_AH=m +CONFIG_INET6_ESP=m +CONFIG_INET6_IPCOMP=m +CONFIG_IPV6_MIP6=m +CONFIG_IPV6_TUNNEL=m +CONFIG_IPV6_MULTIPLE_TABLES=y +CONFIG_CFG80211=m +CONFIG_MAC80211=m +CONFIG_RFKILL=y +CONFIG_RFKILL_INPUT=y +CONFIG_RFKILL_GPIO=y +CONFIG_DEVTMPFS=y +CONFIG_DEVTMPFS_MOUNT=y +CONFIG_DMA_CMA=y +CONFIG_CMA_SIZE_MBYTES=64 +CONFIG_OMAP_OCP2SCP=y +CONFIG_MTD=y +CONFIG_MTD_M25P80=y +CONFIG_BLK_DEV_LOOP=y +CONFIG_ICS932S401=y +CONFIG_APDS9802ALS=y +CONFIG_ISL29003=y +CONFIG_BLK_DEV_SD=y +CONFIG_BLK_DEV_SR=y +CONFIG_SCSI_MULTI_LUN=y +CONFIG_ATA=y +CONFIG_SATA_AHCI_PLATFORM=y +CONFIG_SATA_HIGHBANK=y +CONFIG_SATA_MV=y +CONFIG_NETDEVICES=y +CONFIG_SUN4I_EMAC=y +CONFIG_NET_CALXEDA_XGMAC=y +CONFIG_MV643XX_ETH=y +CONFIG_MVNETA=y +CONFIG_KS8851=y +CONFIG_R8169=y +CONFIG_SMSC911X=y +CONFIG_STMMAC_ETH=y +CONFIG_TI_CPSW=y +CONFIG_AT803X_PHY=y +CONFIG_MARVELL_PHY=y +CONFIG_ICPLUS_PHY=y +CONFIG_USB_PEGASUS=y +CONFIG_USB_USBNET=y +CONFIG_USB_NET_SMSC75XX=y +CONFIG_USB_NET_SMSC95XX=y +CONFIG_BRCMFMAC=m +CONFIG_RT2X00=m +CONFIG_RT2800USB=m +CONFIG_INPUT_EVDEV=y +CONFIG_KEYBOARD_GPIO=y +CONFIG_KEYBOARD_TEGRA=y +CONFIG_KEYBOARD_SPEAR=y +CONFIG_KEYBOARD_CROS_EC=y +CONFIG_MOUSE_PS2_ELANTECH=y +CONFIG_INPUT_MISC=y +CONFIG_INPUT_MPU3050=y +CONFIG_SERIO_AMBAKMI=y +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_SERIAL_8250_DW=y +CONFIG_SERIAL_AMBA_PL011=y +CONFIG_SERIAL_AMBA_PL011_CONSOLE=y +CONFIG_SERIAL_SIRFSOC=y +CONFIG_SERIAL_SIRFSOC_CONSOLE=y +CONFIG_SERIAL_TEGRA=y +CONFIG_SERIAL_IMX=y +CONFIG_SERIAL_IMX_CONSOLE=y +CONFIG_SERIAL_MSM=y +CONFIG_SERIAL_MSM_CONSOLE=y +CONFIG_SERIAL_VT8500=y +CONFIG_SERIAL_VT8500_CONSOLE=y +CONFIG_SERIAL_OF_PLATFORM=y +CONFIG_SERIAL_OMAP=y +CONFIG_SERIAL_OMAP_CONSOLE=y +CONFIG_SERIAL_XILINX_PS_UART=y +CONFIG_SERIAL_XILINX_PS_UART_CONSOLE=y +CONFIG_SERIAL_FSL_LPUART=y +CONFIG_SERIAL_FSL_LPUART_CONSOLE=y +CONFIG_SERIAL_ST_ASC=y +CONFIG_SERIAL_ST_ASC_CONSOLE=y +CONFIG_I2C_CHARDEV=y +CONFIG_I2C_MUX=y +CONFIG_I2C_MUX_PCA954x=y +CONFIG_I2C_MUX_PINCTRL=y +CONFIG_I2C_DESIGNWARE_PLATFORM=y +CONFIG_I2C_MV64XXX=y +CONFIG_I2C_SIRF=y +CONFIG_I2C_TEGRA=y +CONFIG_SPI=y +CONFIG_SPI_OMAP24XX=y +CONFIG_SPI_ORION=y +CONFIG_SPI_PL022=y +CONFIG_SPI_SIRF=y +CONFIG_SPI_TEGRA114=y +CONFIG_SPI_TEGRA20_SFLASH=y +CONFIG_SPI_TEGRA20_SLINK=y +CONFIG_PINCTRL_AS3722=y +CONFIG_PINCTRL_PALMAS=y +CONFIG_GPIO_SYSFS=y +CONFIG_GPIO_GENERIC_PLATFORM=y +CONFIG_GPIO_PCA953X_IRQ=y +CONFIG_GPIO_TWL4030=y +CONFIG_GPIO_PALMAS=y +CONFIG_GPIO_TPS6586X=y +CONFIG_GPIO_TPS65910=y +CONFIG_BATTERY_SBS=y +CONFIG_CHARGER_TPS65090=y +CONFIG_POWER_RESET_AS3722=y +CONFIG_POWER_RESET_GPIO=y +CONFIG_SENSORS_LM90=y +CONFIG_THERMAL=y +CONFIG_DOVE_THERMAL=y +CONFIG_ARMADA_THERMAL=y +CONFIG_WATCHDOG=y +CONFIG_ORION_WATCHDOG=y +CONFIG_MFD_AS3722=y +CONFIG_MFD_CROS_EC=y +CONFIG_MFD_CROS_EC_SPI=y +CONFIG_MFD_MAX8907=y +CONFIG_MFD_PALMAS=y +CONFIG_MFD_TPS65090=y +CONFIG_MFD_TPS6586X=y +CONFIG_MFD_TPS65910=y +CONFIG_REGULATOR_VIRTUAL_CONSUMER=y +CONFIG_REGULATOR_AB8500=y +CONFIG_REGULATOR_AS3722=y +CONFIG_REGULATOR_GPIO=y +CONFIG_REGULATOR_MAX8907=y +CONFIG_REGULATOR_PALMAS=y +CONFIG_REGULATOR_TPS51632=y +CONFIG_REGULATOR_TPS62360=y +CONFIG_REGULATOR_TPS65090=y +CONFIG_REGULATOR_TPS6586X=y +CONFIG_REGULATOR_TPS65910=y +CONFIG_REGULATOR_TWL4030=y +CONFIG_REGULATOR_VEXPRESS=y +CONFIG_MEDIA_SUPPORT=y +CONFIG_MEDIA_CAMERA_SUPPORT=y +CONFIG_MEDIA_USB_SUPPORT=y +CONFIG_USB_VIDEO_CLASS=y +CONFIG_USB_GSPCA=y +CONFIG_DRM=y +CONFIG_DRM_TEGRA=y +CONFIG_DRM_PANEL_SIMPLE=y +CONFIG_FB_ARMCLCD=y +CONFIG_FB_WM8505=y +CONFIG_FB_SIMPLE=y +CONFIG_BACKLIGHT_LCD_SUPPORT=y +CONFIG_BACKLIGHT_CLASS_DEVICE=y +CONFIG_BACKLIGHT_PWM=y +CONFIG_FRAMEBUFFER_CONSOLE=y +CONFIG_SOUND=y +CONFIG_SND=y +CONFIG_SND_SOC=y +CONFIG_SND_SOC_TEGRA=y +CONFIG_SND_SOC_TEGRA_RT5640=y +CONFIG_SND_SOC_TEGRA_WM8753=y +CONFIG_SND_SOC_TEGRA_WM8903=y +CONFIG_SND_SOC_TEGRA_TRIMSLICE=y +CONFIG_SND_SOC_TEGRA_ALC5632=y +CONFIG_SND_SOC_TEGRA_MAX98090=y +CONFIG_USB=y +CONFIG_USB_XHCI_HCD=y +CONFIG_USB_EHCI_HCD=y +CONFIG_USB_EHCI_TEGRA=y +CONFIG_USB_EHCI_HCD_PLATFORM=y +CONFIG_USB_ISP1760_HCD=y +CONFIG_USB_STORAGE=y +CONFIG_USB_CHIPIDEA=y +CONFIG_USB_CHIPIDEA_HOST=y +CONFIG_AB8500_USB=y +CONFIG_OMAP_USB3=y +CONFIG_SAMSUNG_USB2PHY=y +CONFIG_SAMSUNG_USB3PHY=y +CONFIG_USB_GPIO_VBUS=y +CONFIG_USB_ISP1301=y +CONFIG_USB_MXS_PHY=y +CONFIG_MMC=y +CONFIG_MMC_BLOCK_MINORS=16 +CONFIG_MMC_ARMMMCI=y +CONFIG_MMC_SDHCI=y +CONFIG_MMC_SDHCI_ESDHC_IMX=y +CONFIG_MMC_SDHCI_TEGRA=y +CONFIG_MMC_SDHCI_DOVE=y +CONFIG_MMC_SDHCI_SPEAR=y +CONFIG_MMC_SDHCI_BCM_KONA=y +CONFIG_MMC_OMAP=y +CONFIG_MMC_OMAP_HS=y +CONFIG_MMC_MVSDIO=y +CONFIG_EDAC=y +CONFIG_EDAC_MM_EDAC=y +CONFIG_EDAC_HIGHBANK_MC=y +CONFIG_EDAC_HIGHBANK_L2=y +CONFIG_RTC_CLASS=y +CONFIG_RTC_DRV_AS3722=y +CONFIG_RTC_DRV_MAX8907=y +CONFIG_RTC_DRV_PALMAS=y +CONFIG_RTC_DRV_TWL4030=y +CONFIG_RTC_DRV_TPS6586X=y +CONFIG_RTC_DRV_TPS65910=y +CONFIG_RTC_DRV_EM3027=y +CONFIG_RTC_DRV_PL031=y +CONFIG_RTC_DRV_VT8500=y +CONFIG_RTC_DRV_MV=y +CONFIG_RTC_DRV_TEGRA=y +CONFIG_DMADEVICES=y +CONFIG_DW_DMAC=y +CONFIG_MV_XOR=y +CONFIG_TEGRA20_APB_DMA=y +CONFIG_STE_DMA40=y +CONFIG_SIRF_DMA=y +CONFIG_TI_EDMA=y +CONFIG_PL330_DMA=y +CONFIG_IMX_SDMA=y +CONFIG_IMX_DMA=y +CONFIG_MXS_DMA=y +CONFIG_DMA_OMAP=y +CONFIG_STAGING=y +CONFIG_SENSORS_ISL29018=y +CONFIG_SENSORS_ISL29028=y +CONFIG_MFD_NVEC=y +CONFIG_KEYBOARD_NVEC=y +CONFIG_SERIO_NVEC_PS2=y +CONFIG_NVEC_POWER=y +CONFIG_COMMON_CLK_QCOM=y +CONFIG_MSM_GCC_8660=y +CONFIG_MSM_MMCC_8960=y +CONFIG_MSM_MMCC_8974=y +CONFIG_TEGRA_IOMMU_GART=y +CONFIG_TEGRA_IOMMU_SMMU=y +CONFIG_MEMORY=y +CONFIG_IIO=y +CONFIG_AK8975=y +CONFIG_PWM=y +CONFIG_PWM_TEGRA=y +CONFIG_PWM_VT8500=y +CONFIG_OMAP_USB2=y +CONFIG_EXT4_FS=y +CONFIG_VFAT_FS=y +CONFIG_TMPFS=y +CONFIG_SQUASHFS=y +CONFIG_SQUASHFS_LZO=y +CONFIG_SQUASHFS_XZ=y +CONFIG_NFS_FS=y +CONFIG_NFS_V3_ACL=y +CONFIG_NFS_V4=y +CONFIG_ROOT_NFS=y +CONFIG_PRINTK_TIME=y +CONFIG_DEBUG_FS=y +CONFIG_MAGIC_SYSRQ=y +CONFIG_LOCKUP_DETECTOR=y +CONFIG_CRYPTO_DEV_TEGRA_AES=y
Signature · 1 line
1.9.1
PATCH v10 9/11 ARM: config: append hip04_defconfig
In reply to Haojian ZhuangSelect HiP04 SoC configuration by hip04_defconfig.
--- arch/arm/configs/hip04_defconfig | 74 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 74 insertions(+) create mode 100644 arch/arm/configs/hip04_defconfig
arch/arm/configs/hip04_defconfig new file +74 -0
@@ -0,0 +1,74 @@ +CONFIG_SYSVIPC=y +CONFIG_POSIX_MQUEUE=y +CONFIG_IRQ_DOMAIN_DEBUG=y +CONFIG_NO_HZ=y +CONFIG_HIGH_RES_TIMERS=y +CONFIG_BSD_PROCESS_ACCT=y +CONFIG_BLK_DEV_INITRD=y +CONFIG_RD_GZIP=y +# CONFIG_ARCH_MULTI_V6 is not set +CONFIG_ARCH_MULTI_V7=y +CONFIG_ARCH_HISI=y +CONFIG_ARCH_HIP04=y +CONFIG_ARM_LPAE=y +CONFIG_SMP=y +CONFIG_NR_CPUS=16 +CONFIG_MCPM=y +CONFIG_MCPM_QUAD_CLUSTER=y +CONFIG_PREEMPT=y +CONFIG_AEABI=y +CONFIG_ARM_APPENDED_DTB=y +CONFIG_ARM_ATAG_DTB_COMPAT=y +CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_FROM_BOOTLOADER=y +CONFIG_HIGHMEM=y +CONFIG_VFP=y +CONFIG_NEON=y +CONFIG_NET=y +CONFIG_UNIX=y +CONFIG_INET=y +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +CONFIG_DEVTMPFS=y +CONFIG_DEVTMPFS_MOUNT=y +CONFIG_BLK_DEV=y +CONFIG_BLK_DEV_LOOP=y +CONFIG_BLK_DEV_LOOP_MIN_COUNT=8 +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_BLK_DEV_RAM_SIZE=4096 +CONFIG_BLK_DEV_SD=y +CONFIG_ATA=y +CONFIG_SATA_AHCI_PLATFORM=y +CONFIG_NETDEVICES=y +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_SERIAL_8250_NR_UARTS=2 +CONFIG_SERIAL_8250_RUNTIME_UARTS=2 +CONFIG_SERIAL_8250_DW=y +CONFIG_SERIAL_OF_PLATFORM=y +CONFIG_I2C_DESIGNWARE_PLATFORM=y +CONFIG_PINCTRL_SINGLE=y +CONFIG_GPIO_GENERIC_PLATFORM=y +CONFIG_REGULATOR_GPIO=y +CONFIG_DRM=y +CONFIG_FB_SIMPLE=y +CONFIG_RTC_CLASS=y +CONFIG_EXT4_FS=y +CONFIG_TMPFS=y +CONFIG_NFS_FS=y +CONFIG_NFS_V3_ACL=y +CONFIG_NFS_V4=y +CONFIG_ROOT_NFS=y +CONFIG_PRINTK_TIME=y +CONFIG_DEBUG_FS=y +CONFIG_DEBUG_KERNEL=y +CONFIG_DEBUG_LL=y +CONFIG_DEBUG_UART_8250=y +CONFIG_EARLY_PRINTK=y +CONFIG_LOCKUP_DETECTOR=y +CONFIG_DEBUG_USER=y +CONFIG_VIRTUALIZATION=y +CONFIG_KVM=y +CONFIG_KVM_ARM_HOST=y +CONFIG_KVM_ARM_MAX_VCPUS=4 +CONFIG_KVM_ARM_VGIC=y
Signature · 1 line
1.9.1
PATCH v10 10/11 ARM: hisi: enable erratum 798181 of A15 on HiP04
In reply to Haojian ZhuangFrom: Kefeng Wang <[email protected]>
The commit 93dc688 (ARM: 7684/1: errata: Workaround for Cortex-A15 erratum 798181 (TLBI/DSB operations)) introduced a workaround for Cortex-A15 erratum 798181. Enable it for HIP04(Cortex-a15 r3p2).
--- arch/arm/mach-hisi/Kconfig | 1 + 1 file changed, 1 insertion(+)
arch/arm/mach-hisi/Kconfig +1 -0
@@ -21,6 +21,7 @@ config ARCH_HI3xxx config ARCH_HIP04 bool "Hisilicon HiP04 Cortex A15 family" if ARCH_MULTI_V7 + select ARM_ERRATA_798181 if SMP select HAVE_ARM_ARCH_TIMER select MCPM if SMP select MCPM_QUAD_CLUSTER if SMP
Signature · 1 line
1.9.1
PATCH v10 11/11 virt: arm: support hip04 gic
In reply to Haojian ZhuangIn ARM standard GIC, GICH_APR offset is 0xf0 & GICH_LR0 offset is 0x100. In HiP04 GIC, GICH_APR offset is 0x70 & GICH_LR0 offset is 0x80.
Now reuse the nr_lr field in struct vgic_cpu. Bit[31:16] is used to store GICH_APR offset in HiP04, and bit[15:0] is used to store real nr_lr variable. In ARM standard GIC, don't set bit[31:16]. So we could avoid to change the VGIC implementation in arm64.
--- arch/arm/kernel/asm-offsets.c | 2 +- arch/arm/kvm/interrupts_head.S | 29 +++++++++++++++++++++++------ arch/arm64/kernel/asm-offsets.c | 2 +- arch/arm64/kvm/hyp.S | 4 ++-- include/kvm/arm_vgic.h | 7 +++++-- include/linux/irqchip/arm-gic.h | 6 ++++++ virt/kvm/arm/vgic.c | 37 ++++++++++++++++++++++++++----------- 7 files changed, 64 insertions(+), 23 deletions(-)
arch/arm/kernel/asm-offsets.c +1 -1
@@ -189,7 +189,7 @@ int main(void)DEFINE (VGIC_CPU_ELRSR , offsetof(struct vgic_cpu , vgic_elrsr));DEFINE (VGIC_CPU_APR , offsetof(struct vgic_cpu , vgic_apr));DEFINE (VGIC_CPU_LR , offsetof(struct vgic_cpu , vgic_lr)); -DEFINE (VGIC_CPU_NR_LR , offsetof(struct vgic_cpu , nr_lr)); +DEFINE (VGIC_CPU_HW_CFG , offsetof(struct vgic_cpu , hw_cfg));#ifdef CONFIG_KVM_ARM_TIMER DEFINE(VCPU_TIMER_CNTV_CTL, offsetof(struct kvm_vcpu, arch.timer_cpu.cntv_ctl)); DEFINE(VCPU_TIMER_CNTV_CVAL, offsetof(struct kvm_vcpu, arch.timer_cpu.cntv_cval));
arch/arm/kvm/interrupts_head.S +23 -6
@@ -419,7 +419,9 @@ vcpu .req r0 @ vcpu pointer always in r0 ldr r7, [r2, #GICH_EISR1] ldr r8, [r2, #GICH_ELRSR0] ldr r9, [r2, #GICH_ELRSR1] - ldr r10, [r2, #GICH_APR] + ldr r10, [r11, #VGIC_CPU_HW_CFG] + mov r10, r10, lsr #HWCFG_APR_SHIFT + ldr r10, [r2, r10] str r3, [r11, #VGIC_CPU_HCR] str r4, [r11, #VGIC_CPU_VMCR]
@@ -435,9 +437,15 @@ vcpu .req r0 @ vcpu pointer always in r0 str r5, [r2, #GICH_HCR] /* Save list registers */ - add r2, r2, #GICH_LR0 + ldr r4, [r11, #VGIC_CPU_HW_CFG] + mov r10, r4, lsr #HWCFG_APR_SHIFT + /* the offset between GICH_APR & GICH_LR0 is 0x10 */ + add r10, r10, #0x10 + add r2, r2, r10 add r3, r11, #VGIC_CPU_LR - ldr r4, [r11, #VGIC_CPU_NR_LR] + /* Get NR_LR from VGIC_CPU_HW_CFG */ + ldr r6, =HWCFG_NR_LR_MASK + and r4, r4, r6 1: ldr r6, [r2], #4 str r6, [r3], #4 subs r4, r4, #1
@@ -469,12 +477,21 @@ vcpu .req r0 @ vcpu pointer always in r0 str r3, [r2, #GICH_HCR] str r4, [r2, #GICH_VMCR] - str r8, [r2, #GICH_APR] + ldr r6, [r11, #VGIC_CPU_HW_CFG] + mov r6, r6, lsr #HWCFG_APR_SHIFT + str r8, [r2, r6] /* Restore list registers */ - add r2, r2, #GICH_LR0 + ldr r4, [r11, #VGIC_CPU_HW_CFG] + mov r6, r4, lsr #HWCFG_APR_SHIFT + /* the offset between GICH_APR & GICH_LR0 is 0x10 */ + add r6, r6, #0x10 + /* get offset of GICH_LR0 */ + add r2, r2, r6 + /* Get NR_LR from VGIC_CPU_HW_CFG */ add r3, r11, #VGIC_CPU_LR - ldr r4, [r11, #VGIC_CPU_NR_LR] + ldr r6, =HWCFG_NR_LR_MASK + and r4, r4, r6 1: ldr r6, [r3], #4 str r6, [r2], #4 subs r4, r4, #1
arch/arm64/kernel/asm-offsets.c +1 -1
@@ -136,7 +136,7 @@ int main(void)DEFINE (VGIC_CPU_ELRSR , offsetof(struct vgic_cpu , vgic_elrsr));DEFINE (VGIC_CPU_APR , offsetof(struct vgic_cpu , vgic_apr));DEFINE (VGIC_CPU_LR , offsetof(struct vgic_cpu , vgic_lr)); -DEFINE (VGIC_CPU_NR_LR , offsetof(struct vgic_cpu , nr_lr)); +DEFINE (VGIC_CPU_HW_CFG , offsetof(struct vgic_cpu , hw_cfg)); DEFINE(KVM_VTTBR, offsetof(struct kvm, arch.vttbr)); DEFINE(KVM_VGIC_VCTRL, offsetof(struct kvm, arch.vgic.vctrl_base));#endif
arch/arm64/kvm/hyp.S +2 -2
@@ -426,7 +426,7 @@ CPU_BE( rev w11, w11 ) /* Save list registers */ add x2, x2, #GICH_LR0 - ldr w4, [x3, #VGIC_CPU_NR_LR] + ldr w4, [x3, #VGIC_CPU_HW_CFG] add x3, x3, #VGIC_CPU_LR 1: ldr w5, [x2], #4 CPU_BE( rev w5, w5 )
@@ -465,7 +465,7 @@ CPU_BE( rev w6, w6 ) /* Restore list registers */ add x2, x2, #GICH_LR0 - ldr w4, [x3, #VGIC_CPU_NR_LR] + ldr w4, [x3, #VGIC_CPU_HW_CFG] add x3, x3, #VGIC_CPU_LR 1: ldr w5, [x3], #4 CPU_BE( rev w5, w5 )
include/kvm/arm_vgic.h +5 -2
@@ -122,8 +122,11 @@ struct vgic_cpu {/* Bitmap of used/free list registers */ DECLARE_BITMAP ( lr_used,VGIC_MAX_LRS ); -/* Number of list registers on this CPU */ -int nr_lr; +/* +* bit[31:16]: GICH_APR offset +* bit[15:0]: Number of list registers on this CPU +*/ +u32 hw_cfg;/* CPU vif control registers for world switch */ u32 vgic_hcr;
include/linux/irqchip/arm-gic.h +6 -0
@@ -49,6 +49,8 @@#define GICH_ELRSR1 0x34#define GICH_APR 0xf0#define GICH_LR0 0x100 +#define HIP04_GICH_APR 0x70 +/* GICH_LR0 offset in HiP04 is 0x80 */ #define GICH_HCR_EN (1 << 0)#define GICH_HCR_UIE (1 << 1)
@@ -73,6 +75,10 @@#define GICH_MISR_EOI (1 << 0)#define GICH_MISR_U (1 << 1) +#define HWCFG_NR_LR_MASK 0xffff +#define HWCFG_APR_SHIFT 16 +#define HWCFG_APR_MASK (0xffff << HWCFG_APR_SHIFT) +#ifndef __ASSEMBLY__struct device_node ;
virt/kvm/arm/vgic.c +26 -11
@@ -97,7 +97,7 @@ static void vgic_retire_disabled_irqs(struct kvm_vcpu *vcpu);static void vgic_update_state (struct kvm *kvm);static void vgic_kick_vcpus (struct kvm *kvm);static void vgic_dispatch_sgi (struct kvm_vcpu *vcpu,u32 reg); -static u32 vgic_nr_lr; +static u32 vgic_hw_cfg, vgic_nr_lr;static unsigned int vgic_maint_irq;
@@ -625,7 +625,7 @@ static void vgic_unqueue_irqs(struct kvm_vcpu *vcpu)int i, irq, source_cpu;u32 *lr; -for_each_set_bit (i, vgic_cpu->lr_used, vgic_cpu->nr_lr) { +for_each_set_bit (i, vgic_cpu->lr_used, vgic_nr_lr) { lr = &vgic_cpu->vgic_lr[i]; irq =LR_IRQID (*lr); source_cpu =LR_CPUID (*lr);
@@ -1006,7 +1006,7 @@ static void vgic_retire_disabled_irqs(struct kvm_vcpu *vcpu)struct vgic_cpu *vgic_cpu = &vcpu->arch.vgic_cpu;int lr; -for_each_set_bit (lr, vgic_cpu->lr_used, vgic_cpu->nr_lr) { +for_each_set_bit (lr, vgic_cpu->lr_used, vgic_nr_lr) {int irq = vgic_cpu->vgic_lr[lr] &GICH_LR_VIRTUALID ;if (!vgic_irq_is_enabled (vcpu, irq)) {
@@ -1047,8 +1047,8 @@ static bool vgic_queue_irq(struct kvm_vcpu *vcpu, u8 sgi_source_id, int irq)/* Try to use another LR for this interrupt */ lr =find_first_zero_bit ((unsigned long *)vgic_cpu->lr_used, - vgic_cpu->nr_lr); -if (lr >= vgic_cpu->nr_lr) + vgic_nr_lr); +if (lr >= vgic_nr_lr)return false;kvm_debug ("LR%d allocated for IRQ%d %x\n" , lr, irq, sgi_source_id);
@@ -1183,7 +1183,7 @@ static bool vgic_process_maintenance(struct kvm_vcpu *vcpu)int lr, irq;for_each_set_bit (lr, (unsigned long *)vgic_cpu->vgic_eisr, - vgic_cpu->nr_lr) { + vgic_nr_lr) { irq = vgic_cpu->vgic_lr[lr] &GICH_LR_VIRTUALID ;vgic_irq_clear_active (vcpu, irq);
@@ -1227,7 +1227,7 @@ static void __kvm_vgic_sync_hwstate(struct kvm_vcpu *vcpu)/* Clear mappings for empty LRs */ for_each_set_bit (lr, (unsigned long *)vgic_cpu->vgic_elrsr, - vgic_cpu->nr_lr) { + vgic_nr_lr) {int irq;if (!test_and_clear_bit (lr, vgic_cpu->lr_used))
@@ -1241,8 +1241,8 @@ static void __kvm_vgic_sync_hwstate(struct kvm_vcpu *vcpu)/* Check if we still have something up our sleeve... */ pending =find_first_zero_bit ((unsigned long *)vgic_cpu->vgic_elrsr, - vgic_cpu->nr_lr); -if (level_pending || pending < vgic_cpu->nr_lr) + vgic_nr_lr); +if (level_pending || pending < vgic_nr_lr)set_bit (vcpu->vcpu_id, &dist->irq_pending_on_cpu); }
@@ -1438,7 +1438,7 @@ int kvm_vgic_vcpu_init(struct kvm_vcpu *vcpu)*/ vgic_cpu->vgic_vmcr =0 ; - vgic_cpu->nr_lr = vgic_nr_lr; + vgic_cpu->hw_cfg = vgic_hw_cfg; vgic_cpu->vgic_hcr =GICH_HCR_EN ;/* Get the show on the road... */ return 0 ;
@@ -1470,17 +1470,31 @@ static struct notifier_block vgic_cpu_nb = { .notifier_call = vgic_cpu_notify, }; +static const struct of_device_id of_vgic_ids[] = { + { + .compatible ="arm,cortex-a15-gic" , + .data = (void *)GICH_APR , + }, { + .compatible ="hisilicon,hip04-gic" , + .data = (void *)HIP04_GICH_APR , + }, { + }, +}; +int kvm_vgic_hyp_init (void ) {int ret;struct resource vctrl_res;struct resource vcpu_res; +const struct of_device_id *match; - vgic_node =of_find_compatible_node (NULL ,NULL ,"arm,cortex-a15-gic" ); + vgic_node =of_find_matching_node_and_match (NULL , of_vgic_ids, &match);if (!vgic_node) {kvm_err ("error: no compatible vgic node in DT\n" );return -ENODEV ; } +/* High word of vgic_hw_cfg is the offset of GICH_APR. */ + vgic_hw_cfg = (unsigned long )match->data <<HWCFG_APR_SHIFT ; vgic_maint_irq =irq_of_parse_and_map (vgic_node,0 );if (!vgic_maint_irq) {
@@ -1517,6 +1531,7 @@ int kvm_vgic_hyp_init(void) vgic_nr_lr =readl_relaxed (vgic_vctrl_base +GICH_VTR ); vgic_nr_lr = (vgic_nr_lr &0x3f ) +1 ; + vgic_hw_cfg |= vgic_nr_lr; ret = create_hyp_io_mappings(vgic_vctrl_base, vgic_vctrl_base + resource_size(&vctrl_res),
Signature · 1 line
1.9.1