[U-Boot] [PATCH v4 1/2] armv8/ls1043a: fixup GIC offset according to SVR and SCFG_GIC400_ALIGN[GIC_ADDR_BIT]
Wenbin song
wenbin.song at nxp.com
Mon Oct 24 09:38:45 CEST 2016
The LS1043A rev1.1 silicon supports two types of GIC offset: 4K alignment
and 64K alignment. The bit SCFG_GIC400_ALIGN[GIC_ADDR_BIT] is used to choose
which offset will be used.
The LS1043A rev1.0 silicon only supports the CIG offset with 4K alignment.
If GIC_ADDR_BIT bit is set, 4K alignment is used, or else 64K alignment is used.
64K alignment is the default setting.
Overriding the weekly smp_kick_all_cpus, the new impletment is able to detect
GIC offset.
The default GIC offset in kernel device tree is using 64K alignment, it
need to be fixed if 4K alignment is detected.
Signed-off-by: Wenbin Song <wenbin.song at nxp.com>
Signed-off-by: Mingkai Hu <mingkai.hu at nxp.com>
---
Changes in v4:
Squash [patch 2/3 v3] with this patch.
Add comments on fix_gic_offest.
Add the descriptions of rev1.0 GIC offset.
Use macros to define the offset and size of GIC components.
Changes in v3:
Add descriptions about smp_kick_all_cpus on commit message.
Rename the macros on commit message to match with them used in the change.
Replace CONFIG_LS1043A with HAS_FEATURE_GIC4K_ALIGN.
Changes in v2:
None
---
arch/arm/cpu/armv8/fsl-layerscape/Kconfig | 4 ++
arch/arm/cpu/armv8/fsl-layerscape/fdt.c | 49 +++++++++++++++++++
arch/arm/cpu/armv8/fsl-layerscape/lowlevel.S | 55 ++++++++++++++++++++++
arch/arm/include/asm/arch-fsl-layerscape/config.h | 20 +++++++-
.../include/asm/arch-fsl-layerscape/immap_lsch2.h | 3 +-
5 files changed, 128 insertions(+), 3 deletions(-)
diff --git a/arch/arm/cpu/armv8/fsl-layerscape/Kconfig b/arch/arm/cpu/armv8/fsl-layerscape/Kconfig
index 94ec8d5..c66c497 100644
--- a/arch/arm/cpu/armv8/fsl-layerscape/Kconfig
+++ b/arch/arm/cpu/armv8/fsl-layerscape/Kconfig
@@ -12,6 +12,7 @@ config ARCH_LS1043A
select SYS_FSL_DDR_VER_50
select SYS_FSL_ERRATUM_A010315
select SYS_FSL_ERRATUM_A010539
+ select HAS_FEATURE_GIC4K_ALIGN
config ARCH_LS1046A
bool
@@ -135,4 +136,7 @@ config SYS_FSL_DDR4
help
Enable Freescale DDR4 controller.
+config HAS_FEATURE_GIC4K_ALIGN
+ bool
+
endmenu
diff --git a/arch/arm/cpu/armv8/fsl-layerscape/fdt.c b/arch/arm/cpu/armv8/fsl-layerscape/fdt.c
index 1a8321b..ebc7863 100644
--- a/arch/arm/cpu/armv8/fsl-layerscape/fdt.c
+++ b/arch/arm/cpu/armv8/fsl-layerscape/fdt.c
@@ -126,6 +126,52 @@ void fsl_fdt_disable_usb(void *blob)
}
}
+#ifdef CONFIG_HAS_FEATURE_GIC4K_ALIGN
+/* Fixup gic node align with 4K */
+static void fdt_fixup_gic(void *blob)
+{
+ int offset, err;
+ u64 reg[8];
+ struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR);
+ unsigned int val;
+ struct ccsr_scfg __iomem *scfg = (void *)CONFIG_SYS_FSL_SCFG_ADDR;
+
+ val = gur_in32(&gur->svr) & 0xff;
+
+ if (val == REV1_1) {
+ val = scfg_in32(&scfg->gic_align) & (0x01 << GIC_ADDR_BIT);
+ if (!val)
+ return;
+ }
+
+ offset = fdt_subnode_offset(blob, 0, "interrupt-controller at 1400000");
+ if (offset < 0) {
+ printf("WARNING: fdt_subnode_offset can't find node %s: %s\n",
+ "interrupt-controller at 1400000", fdt_strerror(offset));
+ return;
+ }
+
+ reg[0] = cpu_to_fdt64(GICD_BASE_4K);
+ reg[1] = cpu_to_fdt64(GICD_SIZE_4K);
+ reg[2] = cpu_to_fdt64(GICC_BASE_4K);
+ reg[3] = cpu_to_fdt64(GICC_SIZE_4K);
+ reg[4] = cpu_to_fdt64(GICH_BASE_4K);
+ reg[5] = cpu_to_fdt64(GICH_SIZE_4K);
+ reg[6] = cpu_to_fdt64(GICV_BASE_4K);
+ reg[7] = cpu_to_fdt64(GICV_SIZE_4K);
+
+ err = fdt_setprop(blob, offset, "reg", reg, sizeof(reg));
+ if (err < 0) {
+ printf("WARNING: fdt_setprop can't set %s from node %s: %s\n",
+ "reg", "interrupt-controller at 1400000",
+ fdt_strerror(err));
+ return;
+ }
+
+ return;
+}
+#endif
+
void ft_cpu_setup(void *blob, bd_t *bd)
{
#ifdef CONFIG_FSL_LSCH2
@@ -170,4 +216,7 @@ void ft_cpu_setup(void *blob, bd_t *bd)
#endif
fsl_fdt_disable_usb(blob);
+#ifdef CONFIG_HAS_FEATURE_GIC4K_ALIGN
+ fdt_fixup_gic(blob);
+#endif
}
diff --git a/arch/arm/cpu/armv8/fsl-layerscape/lowlevel.S b/arch/arm/cpu/armv8/fsl-layerscape/lowlevel.S
index 5d0b7a4..e2b8698 100644
--- a/arch/arm/cpu/armv8/fsl-layerscape/lowlevel.S
+++ b/arch/arm/cpu/armv8/fsl-layerscape/lowlevel.S
@@ -14,6 +14,48 @@
#include <asm/arch/mp.h>
#endif
+#ifdef CONFIG_HAS_FEATURE_GIC4K_ALIGN
+
+/* fixup GIC offset
+* For LS1043a rev1.0, GIC base address align with 4k.
+* For LS1043a rev1.1, if DCFG_GIC400_ALIGN[GIC_ADDR_BIT]
+* is set, GIC base address align with 4K, or else align
+* with 64k.
+* output:
+* x0: the base address of GICD
+* x1: the base address of GICC
+*/
+ENTRY(fix_gic_offset)
+ ldr x0, =GICD_BASE
+ ldr x1, =GICC_BASE
+ ldr x3, =DCFG_CCSR_SVR
+ ldr w3, [x3]
+ rev w3, w3
+ ands w3, w3, #0xff
+ cmp w3, #REV1_0
+ b.eq 1f
+ ldr x3, =SCFG_GIC400_ALIGN
+ ldr w3, [x3]
+ rev w3, w3
+ tbnz w3, #GIC_ADDR_BIT, 1f
+ ret
+1:
+ ldr x0, =GICD_BASE_4K
+ ldr x1, =GICC_BASE_4K
+ ret
+ENDPROC(fix_gic_offset)
+
+ENTRY(smp_kick_all_cpus)
+ /* Kick secondary cpus up by SGI 0 interrupt */
+ mov x29, lr /* Save LR */
+ bl fix_gic_offset
+ bl gic_kick_secondary_cpus
+ mov lr, x29 /* Restore LR */
+ ret
+ENDPROC(smp_kick_all_cpus)
+
+#endif
+
ENTRY(lowlevel_init)
mov x29, lr /* Save LR */
@@ -105,15 +147,23 @@ ENTRY(lowlevel_init)
/* Initialize GIC Secure Bank Status */
#if defined(CONFIG_GICV2) || defined(CONFIG_GICV3)
branch_if_slave x0, 1f
+#ifdef CONFIG_HAS_FEATURE_GIC4K_ALIGN
+ bl fix_gic_offset
+#else
ldr x0, =GICD_BASE
+#endif
bl gic_init_secure
1:
#ifdef CONFIG_GICV3
ldr x0, =GICR_BASE
bl gic_init_secure_percpu
#elif defined(CONFIG_GICV2)
+#ifdef CONFIG_HAS_FEATURE_GIC4K_ALIGN
+ bl fix_gic_offset
+#else
ldr x0, =GICD_BASE
ldr x1, =GICC_BASE
+#endif
bl gic_init_secure_percpu
#endif
#endif
@@ -335,7 +385,12 @@ ENTRY(secondary_boot_func)
#if defined(CONFIG_GICV3)
gic_wait_for_interrupt_m x0
#elif defined(CONFIG_GICV2)
+#ifdef CONFIG_HAS_FEATURE_GIC4K_ALIGN
+ bl fix_gic_offset
+ mov x0, x1
+#else
ldr x0, =GICC_BASE
+#endif
gic_wait_for_interrupt_m x0, w1
#endif
diff --git a/arch/arm/include/asm/arch-fsl-layerscape/config.h b/arch/arm/include/asm/arch-fsl-layerscape/config.h
index 4201e0f..47e21c5 100644
--- a/arch/arm/include/asm/arch-fsl-layerscape/config.h
+++ b/arch/arm/include/asm/arch-fsl-layerscape/config.h
@@ -172,8 +172,24 @@
#define SMMU_BASE 0x09000000
/* Generic Interrupt Controller Definitions */
-#define GICD_BASE 0x01401000
-#define GICC_BASE 0x01402000
+#define GICD_BASE 0x01410000
+#define GICC_BASE 0x01420000
+#ifdef CONFIG_HAS_FEATURE_GIC4K_ALIGN
+#define GICD_BASE_4K 0x01401000
+#define GICC_BASE_4K 0x01402000
+#define GICH_BASE_4K 0x01404000
+#define GICV_BASE_4K 0x01406000
+#define GICD_SIZE_4K 0x1000
+#define GICC_SIZE_4K 0x2000
+#define GICH_SIZE_4K 0x2000
+#define GICV_SIZE_4K 0x2000
+#endif
+
+#define DCFG_CCSR_SVR 0x1ee00a4
+#define REV1_0 0x10
+#define REV1_1 0x11
+#define GIC_ADDR_BIT 31
+#define SCFG_GIC400_ALIGN 0x1570188
#define CONFIG_SYS_FSL_ERRATUM_A008850
#define CONFIG_SYS_FSL_ERRATUM_A009663
diff --git a/arch/arm/include/asm/arch-fsl-layerscape/immap_lsch2.h b/arch/arm/include/asm/arch-fsl-layerscape/immap_lsch2.h
index d88543d..1dfef53 100644
--- a/arch/arm/include/asm/arch-fsl-layerscape/immap_lsch2.h
+++ b/arch/arm/include/asm/arch-fsl-layerscape/immap_lsch2.h
@@ -359,7 +359,8 @@ struct ccsr_scfg {
u32 qspi_cfg;
u8 res_160[0x180-0x160];
u32 dmamcr;
- u8 res_184[0x18c-0x184];
+ u8 res_184[0x188-0x184];
+ u32 gic_align;
u32 debug_icid;
u8 res_190[0x1a4-0x190];
u32 snpcnfgcr;
--
2.1.0.27.g96db324
More information about the U-Boot
mailing list