armv8/ls1043a: fixup GIC offset for ls1043a rev1
[oweals/u-boot.git] / arch / arm / cpu / armv8 / fsl-layerscape / fdt.c
index 1a8321b0e4064d9c7f780b18e72d72cd286b2528..f289172c6c508c742f8ddb37fd174de36aae322b 100644 (file)
@@ -5,6 +5,7 @@
  */
 
 #include <common.h>
+#include <efi_loader.h>
 #include <libfdt.h>
 #include <fdt_support.h>
 #include <phy.h>
@@ -41,7 +42,8 @@ void ft_fixup_cpu(void *blob)
        int addr_cells;
        u64 val, core_id;
        size_t *boot_code_size = &(__secondary_boot_code_size);
-#if defined(CONFIG_ARMV8_SEC_FIRMWARE_SUPPORT) && defined(CONFIG_ARMV8_PSCI)
+#if defined(CONFIG_ARMV8_SEC_FIRMWARE_SUPPORT) && \
+       defined(CONFIG_FSL_PPA_ARMV8_PSCI)
        int node;
        u32 psci_ver;
 
@@ -105,6 +107,11 @@ remove_psci_node:
 
        fdt_add_mem_rsv(blob, (uintptr_t)&secondary_boot_code,
                        *boot_code_size);
+#if defined(CONFIG_EFI_LOADER) && !defined(CONFIG_SPL_BUILD)
+       efi_add_memory_map((uintptr_t)&secondary_boot_code,
+                          ALIGN(*boot_code_size, EFI_PAGE_SIZE) >> EFI_PAGE_SHIFT,
+                          EFI_RESERVED_MEMORY_TYPE, false);
+#endif
 }
 #endif
 
@@ -126,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
@@ -170,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
 }