X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=arch%2Farm%2Fcpu%2Farmv8%2Ffsl-layerscape%2Fsoc.c;h=0cb010012e7add46e725741cbcb535e2bb9047f4;hb=2ee490a0245b65826a8ce8e42e34c9bf805d3656;hp=8d40405923aa8f4258548c6ef86c67d494682970;hpb=70f959c3c45bd408ba4f7b18a3a69afd9ccfe739;p=u-boot diff --git a/arch/arm/cpu/armv8/fsl-layerscape/soc.c b/arch/arm/cpu/armv8/fsl-layerscape/soc.c index 8d40405923..0cb010012e 100644 --- a/arch/arm/cpu/armv8/fsl-layerscape/soc.c +++ b/arch/arm/cpu/armv8/fsl-layerscape/soc.c @@ -6,14 +6,43 @@ #include #include +#include +#include #include #include #include #include +#ifdef CONFIG_CHAIN_OF_TRUST +#include +#endif DECLARE_GLOBAL_DATA_PTR; -#if defined(CONFIG_LS2080A) || defined(CONFIG_LS2085A) +bool soc_has_dp_ddr(void) +{ + struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR); + u32 svr = gur_in32(&gur->svr); + + /* LS2085A has DP_DDR */ + if (SVR_SOC_VER(svr) == SVR_LS2085) + return true; + + return false; +} + +bool soc_has_aiop(void) +{ + struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR); + u32 svr = gur_in32(&gur->svr); + + /* LS2085A has AIOP */ + if (SVR_SOC_VER(svr) == SVR_LS2085) + return true; + + return false; +} + +#ifdef CONFIG_LS2080A /* * This erratum requires setting a value to eddrtqcr1 to * optimal the DDR performance. @@ -146,7 +175,14 @@ static void erratum_a009203(void) #endif #endif } - +void bypass_smmu(void) +{ + u32 val; + val = (in_le32(SMMU_SCR0) | SCR0_CLIENTPD_MASK) & ~(SCR0_USFCFG_MASK); + out_le32(SMMU_SCR0, val); + val = (in_le32(SMMU_NSCR0) | SCR0_CLIENTPD_MASK) & ~(SCR0_USFCFG_MASK); + out_le32(SMMU_NSCR0, val); +} void fsl_lsch3_early_init_f(void) { erratum_a008751(); @@ -155,9 +191,86 @@ void fsl_lsch3_early_init_f(void) erratum_a009203(); erratum_a008514(); erratum_a008336(); +#ifdef CONFIG_CHAIN_OF_TRUST + /* In case of Secure Boot, the IBR configures the SMMU + * to allow only Secure transactions. + * SMMU must be reset in bypass mode. + * Set the ClientPD bit and Clear the USFCFG Bit + */ + if (fsl_check_boot_mode_secure() == 1) + bypass_smmu(); +#endif } +#ifdef CONFIG_SCSI_AHCI_PLAT +int sata_init(void) +{ + struct ccsr_ahci __iomem *ccsr_ahci; + + ccsr_ahci = (void *)CONFIG_SYS_SATA2; + out_le32(&ccsr_ahci->ppcfg, AHCI_PORT_PHY_1_CFG); + out_le32(&ccsr_ahci->ptc, AHCI_PORT_TRANS_CFG); + + ccsr_ahci = (void *)CONFIG_SYS_SATA1; + out_le32(&ccsr_ahci->ppcfg, AHCI_PORT_PHY_1_CFG); + out_le32(&ccsr_ahci->ptc, AHCI_PORT_TRANS_CFG); + + ahci_init((void __iomem *)CONFIG_SYS_SATA1); + scsi_scan(0); + + return 0; +} +#endif + #elif defined(CONFIG_LS1043A) +#ifdef CONFIG_SCSI_AHCI_PLAT +int sata_init(void) +{ + struct ccsr_ahci __iomem *ccsr_ahci = (void *)CONFIG_SYS_SATA; + + out_le32(&ccsr_ahci->ppcfg, AHCI_PORT_PHY_1_CFG); + out_le32(&ccsr_ahci->pp2c, AHCI_PORT_PHY_2_CFG); + out_le32(&ccsr_ahci->pp3c, AHCI_PORT_PHY_3_CFG); + out_le32(&ccsr_ahci->ptc, AHCI_PORT_TRANS_CFG); + + ahci_init((void __iomem *)CONFIG_SYS_SATA); + scsi_scan(0); + + return 0; +} +#endif + +static void erratum_a009929(void) +{ +#ifdef CONFIG_SYS_FSL_ERRATUM_A009929 + struct ccsr_gur *gur = (void *)CONFIG_SYS_FSL_GUTS_ADDR; + u32 __iomem *dcsr_cop_ccp = (void *)CONFIG_SYS_DCSR_COP_CCP_ADDR; + u32 rstrqmr1 = gur_in32(&gur->rstrqmr1); + + rstrqmr1 |= 0x00000400; + gur_out32(&gur->rstrqmr1, rstrqmr1); + writel(0x01000000, dcsr_cop_ccp); +#endif +} + +/* + * This erratum requires setting a value to eddrtqcr1 to optimal + * the DDR performance. The eddrtqcr1 register is in SCFG space + * of LS1043A and the offset is 0x157_020c. + */ +#if defined(CONFIG_SYS_FSL_ERRATUM_A009660) \ + && defined(CONFIG_SYS_FSL_ERRATUM_A008514) +#error A009660 and A008514 can not be both enabled. +#endif + +static void erratum_a009660(void) +{ +#ifdef CONFIG_SYS_FSL_ERRATUM_A009660 + u32 *eddrtqcr1 = (void *)CONFIG_SYS_FSL_SCFG_ADDR + 0x20c; + out_be32(eddrtqcr1, 0x63b20042); +#endif +} + void fsl_lsch2_early_init_f(void) { struct ccsr_cci400 *cci = (struct ccsr_cci400 *)CONFIG_SYS_CCI400_ADDR; @@ -167,6 +280,9 @@ void fsl_lsch2_early_init_f(void) init_early_memctl_regs(); /* tighten IFC timing */ #endif +#if defined(CONFIG_FSL_QSPI) && !defined(CONFIG_QSPI_BOOT) + out_be32(&scfg->qspi_cfg, SCFG_QSPI_CLKSEL); +#endif /* Make SEC reads and writes snoopable */ setbits_be32(&scfg->snpcnfgcr, SCFG_SNPCNFGCR_SECRDSNP | SCFG_SNPCNFGCR_SECWRSNP); @@ -177,12 +293,23 @@ void fsl_lsch2_early_init_f(void) */ out_le32(&cci->slave[4].snoop_ctrl, CCI400_DVM_MESSAGE_REQ_EN | CCI400_SNOOP_REQ_EN); + + /* Erratum */ + erratum_a009929(); + erratum_a009660(); } #endif #ifdef CONFIG_BOARD_LATE_INIT int board_late_init(void) { +#ifdef CONFIG_SCSI_AHCI_PLAT + sata_init(); +#endif +#ifdef CONFIG_CHAIN_OF_TRUST + fsl_setenv_chain_of_trust(); +#endif + return 0; } #endif