summaryrefslogtreecommitdiff
path: root/arch/arm/cpu/armv8/fsl-layerscape/fdt.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/cpu/armv8/fsl-layerscape/fdt.c')
-rw-r--r--arch/arm/cpu/armv8/fsl-layerscape/fdt.c64
1 files changed, 64 insertions, 0 deletions
diff --git a/arch/arm/cpu/armv8/fsl-layerscape/fdt.c b/arch/arm/cpu/armv8/fsl-layerscape/fdt.c
index c10ccf9..f289172 100644
--- a/arch/arm/cpu/armv8/fsl-layerscape/fdt.c
+++ b/arch/arm/cpu/armv8/fsl-layerscape/fdt.c
@@ -133,6 +133,67 @@ void fsl_fdt_disable_usb(void *blob)
}
}
+#ifdef CONFIG_HAS_FEATURE_GIC64K_ALIGN
+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;
+ int align_64k = 0;
+
+ val = gur_in32(&gur->svr);
+
+ if (SVR_SOC_VER(val) != SVR_LS1043A) {
+ align_64k = 1;
+ } else if (SVR_REV(val) != REV1_0) {
+ val = scfg_in32(&scfg->gic_align) & (0x01 << GIC_ADDR_BIT);
+ if (!val)
+ align_64k = 1;
+ }
+
+ offset = fdt_subnode_offset(blob, 0, "interrupt-controller@1400000");
+ if (offset < 0) {
+ printf("WARNING: fdt_subnode_offset can't find node %s: %s\n",
+ "interrupt-controller@1400000", fdt_strerror(offset));
+ return;
+ }
+
+ /* Fixup gic node align with 64K */
+ if (align_64k) {
+ reg[0] = cpu_to_fdt64(GICD_BASE_64K);
+ reg[1] = cpu_to_fdt64(GICD_SIZE_64K);
+ reg[2] = cpu_to_fdt64(GICC_BASE_64K);
+ reg[3] = cpu_to_fdt64(GICC_SIZE_64K);
+ reg[4] = cpu_to_fdt64(GICH_BASE_64K);
+ reg[5] = cpu_to_fdt64(GICH_SIZE_64K);
+ reg[6] = cpu_to_fdt64(GICV_BASE_64K);
+ reg[7] = cpu_to_fdt64(GICV_SIZE_64K);
+ } else {
+ /* Fixup gic node align with default */
+ reg[0] = cpu_to_fdt64(GICD_BASE);
+ reg[1] = cpu_to_fdt64(GICD_SIZE);
+ reg[2] = cpu_to_fdt64(GICC_BASE);
+ reg[3] = cpu_to_fdt64(GICC_SIZE);
+ reg[4] = cpu_to_fdt64(GICH_BASE);
+ reg[5] = cpu_to_fdt64(GICH_SIZE);
+ reg[6] = cpu_to_fdt64(GICV_BASE);
+ reg[7] = cpu_to_fdt64(GICV_SIZE);
+ }
+
+ 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@1400000",
+ fdt_strerror(err));
+ return;
+ }
+
+ return;
+}
+#endif
+
void ft_cpu_setup(void *blob, bd_t *bd)
{
#ifdef CONFIG_FSL_LSCH2
@@ -177,4 +238,7 @@ void ft_cpu_setup(void *blob, bd_t *bd)
#endif
fsl_fdt_disable_usb(blob);
+#ifdef CONFIG_HAS_FEATURE_GIC64K_ALIGN
+ fdt_fixup_gic(blob);
+#endif
}