summaryrefslogtreecommitdiff
path: root/arch/arm/cpu/armv8/fsl-layerscape
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/cpu/armv8/fsl-layerscape')
-rw-r--r--arch/arm/cpu/armv8/fsl-layerscape/Kconfig20
-rw-r--r--arch/arm/cpu/armv8/fsl-layerscape/cpu.c62
-rw-r--r--arch/arm/cpu/armv8/fsl-layerscape/fdt.c3
-rw-r--r--arch/arm/cpu/armv8/fsl-layerscape/fsl_lsch3_serdes.c53
-rw-r--r--arch/arm/cpu/armv8/fsl-layerscape/ppa.c143
-rw-r--r--arch/arm/cpu/armv8/fsl-layerscape/soc.c4
6 files changed, 249 insertions, 36 deletions
diff --git a/arch/arm/cpu/armv8/fsl-layerscape/Kconfig b/arch/arm/cpu/armv8/fsl-layerscape/Kconfig
index a99b1c6a99..b24462bede 100644
--- a/arch/arm/cpu/armv8/fsl-layerscape/Kconfig
+++ b/arch/arm/cpu/armv8/fsl-layerscape/Kconfig
@@ -73,6 +73,7 @@ config ARCH_LS2080A
select SYS_FSL_ERRATUM_A009803
select SYS_FSL_ERRATUM_A009942
select SYS_FSL_ERRATUM_A010165
+ select SYS_FSL_ERRATUM_A009203
select ARCH_EARLY_INIT_R
select BOARD_EARLY_INIT_F
@@ -134,6 +135,8 @@ config FSL_LS_PPA
choice
prompt "FSL Layerscape PPA firmware loading-media select"
depends on FSL_LS_PPA
+ default SYS_LS_PPA_FW_IN_MMC if SD_BOOT
+ default SYS_LS_PPA_FW_IN_NAND if NAND_BOOT
default SYS_LS_PPA_FW_IN_XIP
config SYS_LS_PPA_FW_IN_XIP
@@ -142,13 +145,27 @@ config SYS_LS_PPA_FW_IN_XIP
Say Y here if the PPA firmware locate at XIP flash, such
as NOR or QSPI flash.
+config SYS_LS_PPA_FW_IN_MMC
+ bool "eMMC or SD Card"
+ help
+ Say Y here if the PPA firmware locate at eMMC/SD card.
+
+config SYS_LS_PPA_FW_IN_NAND
+ bool "NAND"
+ help
+ Say Y here if the PPA firmware locate at NAND flash.
+
endchoice
config SYS_LS_PPA_FW_ADDR
hex "Address of PPA firmware loading from"
depends on FSL_LS_PPA
default 0x40500000 if SYS_LS_PPA_FW_IN_XIP && QSPI_BOOT
+ default 0x580a00000 if SYS_LS_PPA_FW_IN_XIP && ARCH_LS2080A
default 0x60500000 if SYS_LS_PPA_FW_IN_XIP
+ default 0x500000 if SYS_LS_PPA_FW_IN_MMC
+ default 0x500000 if SYS_LS_PPA_FW_IN_NAND
+
help
If the PPA firmware locate at XIP flash, such as NOR or
QSPI flash, this address is a directly memory-mapped.
@@ -307,6 +324,9 @@ config SYS_FSL_ERRATUM_A008585
config SYS_FSL_ERRATUM_A008850
bool
+config SYS_FSL_ERRATUM_A009203
+ bool
+
config SYS_FSL_ERRATUM_A009635
bool
diff --git a/arch/arm/cpu/armv8/fsl-layerscape/cpu.c b/arch/arm/cpu/armv8/fsl-layerscape/cpu.c
index 7e66ee08b5..d446527616 100644
--- a/arch/arm/cpu/armv8/fsl-layerscape/cpu.c
+++ b/arch/arm/cpu/armv8/fsl-layerscape/cpu.c
@@ -5,6 +5,7 @@
*/
#include <common.h>
+#include <fsl_ddr_sdram.h>
#include <asm/io.h>
#include <linux/errno.h>
#include <asm/system.h>
@@ -89,6 +90,49 @@ static inline void early_mmu_setup(void)
set_sctlr(get_sctlr() | CR_M);
}
+static void fix_pcie_mmu_map(void)
+{
+#ifdef CONFIG_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
@@ -103,6 +147,9 @@ static inline void final_mmu_setup(void)
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 */
@@ -436,7 +483,14 @@ int arch_early_init_r(void)
#endif
#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();
@@ -610,7 +664,7 @@ phys_size_t get_effective_memsize(void)
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;
@@ -719,6 +773,8 @@ void dram_init_banksize(void)
}
}
#endif
+
+ return 0;
}
#if defined(CONFIG_EFI_LOADER) && !defined(CONFIG_SPL_BUILD)
@@ -821,7 +877,7 @@ void update_early_mmu_table(void)
__weak int dram_init(void)
{
- gd->ram_size = initdram(0);
+ fsl_initdram();
#if !defined(CONFIG_SPL) || defined(CONFIG_SPL_BUILD)
/* This will break-before-make MMU for DDR */
update_early_mmu_table();
diff --git a/arch/arm/cpu/armv8/fsl-layerscape/fdt.c b/arch/arm/cpu/armv8/fsl-layerscape/fdt.c
index 26d4a303a5..762a95b945 100644
--- a/arch/arm/cpu/armv8/fsl-layerscape/fdt.c
+++ b/arch/arm/cpu/armv8/fsl-layerscape/fdt.c
@@ -387,8 +387,9 @@ void ft_cpu_setup(void *blob, bd_t *bd)
#ifdef CONFIG_SYS_DPAA_FMAN
fdt_fixup_fman_firmware(blob);
#endif
+#ifndef CONFIG_LS1012A
fsl_fdt_disable_usb(blob);
-
+#endif
#ifdef CONFIG_HAS_FEATURE_GIC64K_ALIGN
fdt_fixup_gic(blob);
#endif
diff --git a/arch/arm/cpu/armv8/fsl-layerscape/fsl_lsch3_serdes.c b/arch/arm/cpu/armv8/fsl-layerscape/fsl_lsch3_serdes.c
index 7faa86c3fd..955e0b7478 100644
--- a/arch/arm/cpu/armv8/fsl-layerscape/fsl_lsch3_serdes.c
+++ b/arch/arm/cpu/armv8/fsl-layerscape/fsl_lsch3_serdes.c
@@ -23,6 +23,11 @@ int xfi_dpmac[XFI8 + 1];
int sgmii_dpmac[SGMII16 + 1];
#endif
+__weak void wriop_init_dpmac_qsgmii(int sd, int lane_prtcl)
+{
+ return;
+}
+
int is_serdes_configured(enum srds_prtcl device)
{
int ret = 0;
@@ -46,20 +51,22 @@ int is_serdes_configured(enum srds_prtcl device)
int serdes_get_first_lane(u32 sd, enum srds_prtcl device)
{
struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR);
- u32 cfg = gur_in32(&gur->rcwsr[28]);
+ u32 cfg = 0;
int i;
switch (sd) {
#ifdef CONFIG_SYS_FSL_SRDS_1
case FSL_SRDS_1:
- cfg &= FSL_CHASSIS3_RCWSR28_SRDS1_PRTCL_MASK;
- cfg >>= FSL_CHASSIS3_RCWSR28_SRDS1_PRTCL_SHIFT;
+ cfg = gur_in32(&gur->rcwsr[FSL_CHASSIS3_SRDS1_REGSR - 1]);
+ cfg &= FSL_CHASSIS3_SRDS1_PRTCL_MASK;
+ cfg >>= FSL_CHASSIS3_SRDS1_PRTCL_SHIFT;
break;
#endif
#ifdef CONFIG_SYS_FSL_SRDS_2
case FSL_SRDS_2:
- cfg &= FSL_CHASSIS3_RCWSR28_SRDS2_PRTCL_MASK;
- cfg >>= FSL_CHASSIS3_RCWSR28_SRDS2_PRTCL_SHIFT;
+ cfg = gur_in32(&gur->rcwsr[FSL_CHASSIS3_SRDS2_REGSR - 1]);
+ cfg &= FSL_CHASSIS3_SRDS2_PRTCL_MASK;
+ cfg >>= FSL_CHASSIS3_SRDS2_PRTCL_SHIFT;
break;
#endif
default:
@@ -78,8 +85,8 @@ int serdes_get_first_lane(u32 sd, enum srds_prtcl device)
return -ENODEV;
}
-void serdes_init(u32 sd, u32 sd_addr, u32 sd_prctl_mask, u32 sd_prctl_shift,
- u8 serdes_prtcl_map[SERDES_PRCTL_COUNT])
+void serdes_init(u32 sd, u32 sd_addr, u32 rcwsr, u32 sd_prctl_mask,
+ u32 sd_prctl_shift, u8 serdes_prtcl_map[SERDES_PRCTL_COUNT])
{
struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR);
u32 cfg;
@@ -90,7 +97,7 @@ void serdes_init(u32 sd, u32 sd_addr, u32 sd_prctl_mask, u32 sd_prctl_shift,
memset(serdes_prtcl_map, 0, sizeof(u8) * SERDES_PRCTL_COUNT);
- cfg = gur_in32(&gur->rcwsr[28]) & sd_prctl_mask;
+ cfg = gur_in32(&gur->rcwsr[rcwsr - 1]) & sd_prctl_mask;
cfg >>= sd_prctl_shift;
printf("Using SERDES%d Protocol: %d (0x%x)\n", sd + 1, cfg, cfg);
@@ -106,28 +113,10 @@ void serdes_init(u32 sd, u32 sd_addr, u32 sd_prctl_mask, u32 sd_prctl_shift,
#ifdef CONFIG_FSL_MC_ENET
switch (lane_prtcl) {
case QSGMII_A:
- wriop_init_dpmac(sd, 5, (int)lane_prtcl);
- wriop_init_dpmac(sd, 6, (int)lane_prtcl);
- wriop_init_dpmac(sd, 7, (int)lane_prtcl);
- wriop_init_dpmac(sd, 8, (int)lane_prtcl);
- break;
case QSGMII_B:
- wriop_init_dpmac(sd, 1, (int)lane_prtcl);
- wriop_init_dpmac(sd, 2, (int)lane_prtcl);
- wriop_init_dpmac(sd, 3, (int)lane_prtcl);
- wriop_init_dpmac(sd, 4, (int)lane_prtcl);
- break;
case QSGMII_C:
- wriop_init_dpmac(sd, 13, (int)lane_prtcl);
- wriop_init_dpmac(sd, 14, (int)lane_prtcl);
- wriop_init_dpmac(sd, 15, (int)lane_prtcl);
- wriop_init_dpmac(sd, 16, (int)lane_prtcl);
- break;
case QSGMII_D:
- wriop_init_dpmac(sd, 9, (int)lane_prtcl);
- wriop_init_dpmac(sd, 10, (int)lane_prtcl);
- wriop_init_dpmac(sd, 11, (int)lane_prtcl);
- wriop_init_dpmac(sd, 12, (int)lane_prtcl);
+ wriop_init_dpmac_qsgmii(sd, (int)lane_prtcl);
break;
default:
if (lane_prtcl >= XFI1 && lane_prtcl <= XFI8)
@@ -165,15 +154,17 @@ void fsl_serdes_init(void)
#ifdef CONFIG_SYS_FSL_SRDS_1
serdes_init(FSL_SRDS_1,
CONFIG_SYS_FSL_LSCH3_SERDES_ADDR,
- FSL_CHASSIS3_RCWSR28_SRDS1_PRTCL_MASK,
- FSL_CHASSIS3_RCWSR28_SRDS1_PRTCL_SHIFT,
+ FSL_CHASSIS3_SRDS1_REGSR,
+ FSL_CHASSIS3_SRDS1_PRTCL_MASK,
+ FSL_CHASSIS3_SRDS1_PRTCL_SHIFT,
serdes1_prtcl_map);
#endif
#ifdef CONFIG_SYS_FSL_SRDS_2
serdes_init(FSL_SRDS_2,
CONFIG_SYS_FSL_LSCH3_SERDES_ADDR + FSL_SRDS_2 * 0x10000,
- FSL_CHASSIS3_RCWSR28_SRDS2_PRTCL_MASK,
- FSL_CHASSIS3_RCWSR28_SRDS2_PRTCL_SHIFT,
+ FSL_CHASSIS3_SRDS2_REGSR,
+ FSL_CHASSIS3_SRDS2_PRTCL_MASK,
+ FSL_CHASSIS3_SRDS2_PRTCL_SHIFT,
serdes2_prtcl_map);
#endif
}
diff --git a/arch/arm/cpu/armv8/fsl-layerscape/ppa.c b/arch/arm/cpu/armv8/fsl-layerscape/ppa.c
index b68e87d657..b35ad5fb6f 100644
--- a/arch/arm/cpu/armv8/fsl-layerscape/ppa.c
+++ b/arch/arm/cpu/armv8/fsl-layerscape/ppa.c
@@ -4,6 +4,7 @@
* SPDX-License-Identifier: GPL-2.0+
*/
#include <common.h>
+#include <malloc.h>
#include <config.h>
#include <errno.h>
#include <asm/system.h>
@@ -21,9 +22,17 @@
#include <fsl_validate.h>
#endif
+#ifdef CONFIG_SYS_LS_PPA_FW_IN_NAND
+#include <nand.h>
+#elif defined(CONFIG_SYS_LS_PPA_FW_IN_MMC)
+#include <mmc.h>
+#endif
+
+DECLARE_GLOBAL_DATA_PTR;
+
int ppa_init(void)
{
- const void *ppa_fit_addr;
+ void *ppa_fit_addr;
u32 *boot_loc_ptr_l, *boot_loc_ptr_h;
int ret;
@@ -34,10 +43,137 @@ int ppa_init(void)
#ifdef CONFIG_SYS_LS_PPA_FW_IN_XIP
ppa_fit_addr = (void *)CONFIG_SYS_LS_PPA_FW_ADDR;
+ debug("%s: PPA image load from XIP\n", __func__);
+#else /* !CONFIG_SYS_LS_PPA_FW_IN_XIP */
+ size_t fw_length, fdt_header_len = sizeof(struct fdt_header);
+
+ /* Copy PPA image from MMC/SD/NAND to allocated memory */
+#ifdef CONFIG_SYS_LS_PPA_FW_IN_MMC
+ struct mmc *mmc;
+ int dev = CONFIG_SYS_MMC_ENV_DEV;
+ struct fdt_header *fitp;
+ u32 cnt;
+ u32 blk = CONFIG_SYS_LS_PPA_FW_ADDR / 512;
+
+ debug("%s: PPA image load from eMMC/SD\n", __func__);
+
+ ret = mmc_initialize(gd->bd);
+ if (ret) {
+ printf("%s: mmc_initialize() failed\n", __func__);
+ return ret;
+ }
+ mmc = find_mmc_device(dev);
+ if (!mmc) {
+ printf("PPA: MMC cannot find device for PPA firmware\n");
+ return -ENODEV;
+ }
+
+ ret = mmc_init(mmc);
+ if (ret) {
+ printf("%s: mmc_init() failed\n", __func__);
+ return ret;
+ }
+
+ fitp = malloc(roundup(fdt_header_len, 512));
+ if (!fitp) {
+ printf("PPA: malloc failed for FIT header(size 0x%zx)\n",
+ roundup(fdt_header_len, 512));
+ return -ENOMEM;
+ }
+
+ cnt = DIV_ROUND_UP(fdt_header_len, 512);
+ debug("%s: MMC read PPA FIT header: dev # %u, block # %u, count %u\n",
+ __func__, dev, blk, cnt);
+ ret = mmc->block_dev.block_read(&mmc->block_dev, blk, cnt, fitp);
+ if (ret != cnt) {
+ free(fitp);
+ printf("MMC/SD read of PPA FIT header at offset 0x%x failed\n",
+ CONFIG_SYS_LS_PPA_FW_ADDR);
+ return -EIO;
+ }
+
+ /* flush cache after read */
+ flush_cache((ulong)fitp, cnt * 512);
+
+ ret = fdt_check_header(fitp);
+ if (ret) {
+ free(fitp);
+ printf("%s: fdt_check_header() failed\n", __func__);
+ return ret;
+ }
+
+ fw_length = fdt_totalsize(fitp);
+ free(fitp);
+
+ fw_length = roundup(fw_length, 512);
+ ppa_fit_addr = malloc(fw_length);
+ if (!ppa_fit_addr) {
+ printf("PPA: malloc failed for PPA image(size 0x%zx)\n",
+ fw_length);
+ return -ENOMEM;
+ }
+
+ cnt = DIV_ROUND_UP(fw_length, 512);
+ debug("%s: MMC read PPA FIT image: dev # %u, block # %u, count %u\n",
+ __func__, dev, blk, cnt);
+ ret = mmc->block_dev.block_read(&mmc->block_dev,
+ blk, cnt, ppa_fit_addr);
+ if (ret != cnt) {
+ free(ppa_fit_addr);
+ printf("MMC/SD read of PPA FIT header at offset 0x%x failed\n",
+ CONFIG_SYS_LS_PPA_FW_ADDR);
+ return -EIO;
+ }
+
+ /* flush cache after read */
+ flush_cache((ulong)ppa_fit_addr, cnt * 512);
+
+#elif defined(CONFIG_SYS_LS_PPA_FW_IN_NAND)
+ struct fdt_header fit;
+
+ debug("%s: PPA image load from NAND\n", __func__);
+
+ nand_init();
+ ret = nand_read(nand_info[0], (loff_t)CONFIG_SYS_LS_PPA_FW_ADDR,
+ &fdt_header_len, (u_char *)&fit);
+ if (ret == -EUCLEAN) {
+ printf("NAND read of PPA FIT header at offset 0x%x failed\n",
+ CONFIG_SYS_LS_PPA_FW_ADDR);
+ return -EIO;
+ }
+
+ ret = fdt_check_header(&fit);
+ if (ret) {
+ printf("%s: fdt_check_header() failed\n", __func__);
+ return ret;
+ }
+
+ fw_length = fdt_totalsize(&fit);
+
+ ppa_fit_addr = malloc(fw_length);
+ if (!ppa_fit_addr) {
+ printf("PPA: malloc failed for PPA image(size 0x%zx)\n",
+ fw_length);
+ return -ENOMEM;
+ }
+
+ ret = nand_read(nand_info[0], (loff_t)CONFIG_SYS_LS_PPA_FW_ADDR,
+ &fw_length, (u_char *)ppa_fit_addr);
+ if (ret == -EUCLEAN) {
+ free(ppa_fit_addr);
+ printf("NAND read of PPA firmware at offset 0x%x failed\n",
+ CONFIG_SYS_LS_PPA_FW_ADDR);
+ return -EIO;
+ }
+
+ /* flush cache after read */
+ flush_cache((ulong)ppa_fit_addr, fw_length);
#else
#error "No CONFIG_SYS_LS_PPA_FW_IN_xxx defined"
#endif
+#endif
+
#ifdef CONFIG_CHAIN_OF_TRUST
ppa_img_addr = (uintptr_t)ppa_fit_addr;
if (fsl_check_boot_mode_secure() != 0) {
@@ -65,5 +201,10 @@ int ppa_init(void)
boot_loc_ptr_l, boot_loc_ptr_h);
ret = sec_firmware_init(ppa_fit_addr, boot_loc_ptr_l, boot_loc_ptr_h);
+#if defined(CONFIG_SYS_LS_PPA_FW_IN_MMC) || \
+ defined(CONFIG_SYS_LS_PPA_FW_IN_NAND)
+ free(ppa_fit_addr);
+#endif
+
return ret;
}
diff --git a/arch/arm/cpu/armv8/fsl-layerscape/soc.c b/arch/arm/cpu/armv8/fsl-layerscape/soc.c
index b54a937971..9e3cdd78af 100644
--- a/arch/arm/cpu/armv8/fsl-layerscape/soc.c
+++ b/arch/arm/cpu/armv8/fsl-layerscape/soc.c
@@ -152,6 +152,7 @@ static void erratum_rcw_src(void)
* This erratum requires setting glitch_en bit to enable
* digital glitch filter to improve clock stability.
*/
+#ifdef CONFIG_SYS_FSL_ERRATUM_A009203
static void erratum_a009203(void)
{
u8 __iomem *ptr;
@@ -178,6 +179,7 @@ static void erratum_a009203(void)
#endif
#endif
}
+#endif
void bypass_smmu(void)
{
@@ -191,7 +193,9 @@ void fsl_lsch3_early_init_f(void)
{
erratum_rcw_src();
init_early_memctl_regs(); /* tighten IFC timing */
+#ifdef CONFIG_SYS_FSL_ERRATUM_A009203
erratum_a009203();
+#endif
erratum_a008514();
erratum_a008336();
#ifdef CONFIG_CHAIN_OF_TRUST