*/
#include <common.h>
+#include <fsl_ddr_sdram.h>
#include <asm/io.h>
#include <linux/errno.h>
#include <asm/system.h>
#include <asm/arch/soc.h>
#include <asm/arch/cpu.h>
#include <asm/arch/speed.h>
-#ifdef CONFIG_MP
#include <asm/arch/mp.h>
-#endif
#include <efi_loader.h>
#include <fm_eth.h>
#include <fsl-mc/fsl_mc.h>
#ifdef CONFIG_FSL_ESDHC
#include <fsl_esdhc.h>
#endif
-#ifdef CONFIG_ARMV8_SEC_FIRMWARE_SUPPORT
#include <asm/armv8/sec_firmware.h>
-#endif
#ifdef CONFIG_SYS_FSL_DDR
#include <fsl_ddr.h>
#endif
set_sctlr(get_sctlr() | CR_M);
}
+static void fix_pcie_mmu_map(void)
+{
+#ifdef CONFIG_ARCH_LS2080A
+ unsigned int i;
+ u32 svr, ver;
+ struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR);
+
+ svr = gur_in32(&gur->svr);
+ ver = SVR_SOC_VER(svr);
+
+ /* Fix PCIE base and size for LS2088A */
+ if ((ver == SVR_LS2088A) || (ver == SVR_LS2084A) ||
+ (ver == SVR_LS2048A) || (ver == SVR_LS2044A)) {
+ for (i = 0; i < ARRAY_SIZE(final_map); i++) {
+ switch (final_map[i].phys) {
+ case CONFIG_SYS_PCIE1_PHYS_ADDR:
+ final_map[i].phys = 0x2000000000ULL;
+ final_map[i].virt = 0x2000000000ULL;
+ final_map[i].size = 0x800000000ULL;
+ break;
+ case CONFIG_SYS_PCIE2_PHYS_ADDR:
+ final_map[i].phys = 0x2800000000ULL;
+ final_map[i].virt = 0x2800000000ULL;
+ final_map[i].size = 0x800000000ULL;
+ break;
+ case CONFIG_SYS_PCIE3_PHYS_ADDR:
+ final_map[i].phys = 0x3000000000ULL;
+ final_map[i].virt = 0x3000000000ULL;
+ final_map[i].size = 0x800000000ULL;
+ break;
+ case CONFIG_SYS_PCIE4_PHYS_ADDR:
+ final_map[i].phys = 0x3800000000ULL;
+ final_map[i].virt = 0x3800000000ULL;
+ final_map[i].size = 0x800000000ULL;
+ break;
+ default:
+ break;
+ }
+ }
+ }
+#endif
+}
+
/*
* The final tables look similar to early tables, but different in detail.
* These tables are in DRAM. Sub tables are added to enable cache for
unsigned int el = current_el();
int index;
+ /* fix the final_map before filling in the block entries */
+ fix_pcie_mmu_map();
+
mem_map = final_map;
/* Update mapping for DDR to actual size */
return error;
}
-int arch_early_init_r(void)
+static inline int check_psci(void)
{
-#ifdef CONFIG_MP
- int rv = 1;
- u32 psci_ver = 0xffffffff;
-#endif
+ unsigned int psci_ver;
+
+ psci_ver = sec_firmware_support_psci_version();
+ if (psci_ver == PSCI_INVALID_VER)
+ return 1;
+ return 0;
+}
+
+int arch_early_init_r(void)
+{
#ifdef CONFIG_SYS_FSL_ERRATUM_A009635
- erratum_a009635();
+ u32 svr_dev_id;
+ /*
+ * erratum A009635 is valid only for LS2080A SoC and
+ * its personalitiesi
+ */
+ svr_dev_id = get_svr() >> 16;
+ if (svr_dev_id == SVR_DEV_LS2080A)
+ erratum_a009635();
#endif
#if defined(CONFIG_SYS_FSL_ERRATUM_A009942) && defined(CONFIG_SYS_FSL_DDR)
erratum_a009942_check_cpo();
#endif
-#ifdef CONFIG_MP
-#if defined(CONFIG_ARMV8_SEC_FIRMWARE_SUPPORT) && \
- defined(CONFIG_SEC_FIRMWARE_ARMV8_PSCI)
- /* Check the psci version to determine if the psci is supported */
- psci_ver = sec_firmware_support_psci_version();
-#endif
- if (psci_ver == 0xffffffff) {
- rv = fsl_layerscape_wake_seconday_cores();
- if (rv)
+ if (check_psci()) {
+ debug("PSCI: PSCI does not exist.\n");
+
+ /* if PSCI does not exist, boot secondary cores here */
+ if (fsl_layerscape_wake_seconday_cores())
printf("Did not wake secondary cores\n");
}
-#endif
#ifdef CONFIG_SYS_HAS_SERDES
fsl_serdes_init();
#ifdef CONFIG_FSL_LSCH3
u32 __iomem *cltbenr = (u32 *)CONFIG_SYS_FSL_PMU_CLTBENR;
#endif
-#ifdef CONFIG_LS2080A
+#ifdef CONFIG_ARCH_LS2080A
u32 __iomem *pctbenr = (u32 *)FSL_PMU_PCTBENR_OFFSET;
u32 svr_dev_id;
#endif
out_le32(cltbenr, 0xf);
#endif
-#ifdef CONFIG_LS2080A
+#ifdef CONFIG_ARCH_LS2080A
/*
* In certain Layerscape SoCs, the clock for each core's
* has an enable bit in the PMU Physical Core Time Base Enable
return ea_size;
}
-void dram_init_banksize(void)
+int dram_init_banksize(void)
{
#ifdef CONFIG_SYS_DP_DDR_BASE_PHY
phys_size_t dp_ddr_size;
}
}
#endif
+
+ return 0;
}
#if defined(CONFIG_EFI_LOADER) && !defined(CONFIG_SPL_BUILD)
}
}
#endif
+
+/*
+ * Before DDR size is known, early MMU table have DDR mapped as device memory
+ * to avoid speculative access. To relocate U-Boot to DDR, "normal memory"
+ * needs to be set for these mappings.
+ * If a special case configures DDR with holes in the mapping, the holes need
+ * to be marked as invalid. This is not implemented in this function.
+ */
+void update_early_mmu_table(void)
+{
+ if (!gd->arch.tlb_addr)
+ return;
+
+ if (gd->ram_size <= CONFIG_SYS_FSL_DRAM_SIZE1) {
+ mmu_change_region_attr(
+ CONFIG_SYS_SDRAM_BASE,
+ gd->ram_size,
+ PTE_BLOCK_MEMTYPE(MT_NORMAL) |
+ PTE_BLOCK_OUTER_SHARE |
+ PTE_BLOCK_NS |
+ PTE_TYPE_VALID);
+ } else {
+ mmu_change_region_attr(
+ CONFIG_SYS_SDRAM_BASE,
+ CONFIG_SYS_DDR_BLOCK1_SIZE,
+ PTE_BLOCK_MEMTYPE(MT_NORMAL) |
+ PTE_BLOCK_OUTER_SHARE |
+ PTE_BLOCK_NS |
+ PTE_TYPE_VALID);
+#ifdef CONFIG_SYS_DDR_BLOCK3_BASE
+#ifndef CONFIG_SYS_DDR_BLOCK2_SIZE
+#error "Missing CONFIG_SYS_DDR_BLOCK2_SIZE"
+#endif
+ if (gd->ram_size - CONFIG_SYS_DDR_BLOCK1_SIZE >
+ CONFIG_SYS_DDR_BLOCK2_SIZE) {
+ mmu_change_region_attr(
+ CONFIG_SYS_DDR_BLOCK2_BASE,
+ CONFIG_SYS_DDR_BLOCK2_SIZE,
+ PTE_BLOCK_MEMTYPE(MT_NORMAL) |
+ PTE_BLOCK_OUTER_SHARE |
+ PTE_BLOCK_NS |
+ PTE_TYPE_VALID);
+ mmu_change_region_attr(
+ CONFIG_SYS_DDR_BLOCK3_BASE,
+ gd->ram_size -
+ CONFIG_SYS_DDR_BLOCK1_SIZE -
+ CONFIG_SYS_DDR_BLOCK2_SIZE,
+ PTE_BLOCK_MEMTYPE(MT_NORMAL) |
+ PTE_BLOCK_OUTER_SHARE |
+ PTE_BLOCK_NS |
+ PTE_TYPE_VALID);
+ } else
+#endif
+ {
+ mmu_change_region_attr(
+ CONFIG_SYS_DDR_BLOCK2_BASE,
+ gd->ram_size -
+ CONFIG_SYS_DDR_BLOCK1_SIZE,
+ PTE_BLOCK_MEMTYPE(MT_NORMAL) |
+ PTE_BLOCK_OUTER_SHARE |
+ PTE_BLOCK_NS |
+ PTE_TYPE_VALID);
+ }
+ }
+}
+
+__weak int dram_init(void)
+{
+ fsl_initdram();
+#if !defined(CONFIG_SPL) || defined(CONFIG_SPL_BUILD)
+ /* This will break-before-make MMU for DDR */
+ update_early_mmu_table();
+#endif
+
+ return 0;
+}