diff options
Diffstat (limited to 'plat/nxp/soc-ls1046a')
25 files changed, 3007 insertions, 0 deletions
diff --git a/plat/nxp/soc-ls1046a/aarch64/ls1046a.S b/plat/nxp/soc-ls1046a/aarch64/ls1046a.S new file mode 100644 index 0000000..daa0542 --- /dev/null +++ b/plat/nxp/soc-ls1046a/aarch64/ls1046a.S @@ -0,0 +1,937 @@ +/* + * Copyright 2020-2022 NXP + * + * SPDX-License-Identifier: BSD-3-Clause + * + */ + +#include <asm_macros.S> +#include <dcfg_lsch2.h> +#include <nxp_timer.h> +#include <plat_gic.h> +#include <scfg.h> + +#include <bl31_data.h> +#include <plat_psci.h> +#include <platform_def.h> + +#define DAIF_DATA AUX_01_DATA +#define TIMER_CNTRL_DATA AUX_02_DATA + +.global soc_init_lowlevel +.global soc_init_percpu +.global _soc_core_release +.global _soc_core_restart +.global _soc_ck_disabled +.global _soc_sys_reset +.global _soc_sys_off +.global _soc_set_start_addr +.global _getGICC_BaseAddr +.global _getGICD_BaseAddr +.global _soc_core_prep_off +.global _soc_core_entr_off +.global _soc_core_exit_off +.global _soc_core_prep_stdby +.global _soc_core_entr_stdby +.global _soc_core_exit_stdby +.global _soc_core_prep_pwrdn +.global _soc_core_entr_pwrdn +.global _soc_core_exit_pwrdn +.global _soc_clstr_prep_stdby +.global _soc_clstr_exit_stdby +.global _soc_clstr_prep_pwrdn +.global _soc_clstr_exit_pwrdn +.global _soc_sys_prep_stdby +.global _soc_sys_exit_stdby +.global _soc_sys_prep_pwrdn +.global _soc_sys_pwrdn_wfi +.global _soc_sys_exit_pwrdn + + +/* This function initialize the soc + * in: void + * out: void + */ +func soc_init_lowlevel + ret +endfunc soc_init_lowlevel + + +/* void soc_init_percpu(void) + * this function performs any soc-specific initialization that is needed on + * a per-core basis + * in: none + * out: none + * uses x0, x1, x2, x3 + */ +func soc_init_percpu + mov x3, x30 + + bl plat_my_core_mask + mov x2, x0 + + /* see if this core is marked for prefetch disable */ + mov x0, #PREFETCH_DIS_OFFSET + bl _get_global_data /* 0-1 */ + tst x0, x2 + b.eq 1f + bl _disable_ldstr_pfetch_A72 /* 0 */ +1: + mov x30, x3 + ret +endfunc soc_init_percpu + +/* part of CPU_ON + * this function releases a secondary core from reset + * in: x0 = core_mask_lsb + * out: none + * uses: x0, x1, x2, x3 + */ +func _soc_core_release + +#if (TEST_BL31) + rbit w2, w0 + /* x2 = core mask msb */ +#else + mov x2, x0 +#endif + /* write COREBCR */ + mov x1, #NXP_SCFG_ADDR + rev w3, w2 + str w3, [x1, #SCFG_COREBCR_OFFSET] + isb + + /* read-modify-write BRR */ + mov x1, #NXP_DCFG_ADDR + ldr w2, [x1, #DCFG_BRR_OFFSET] + rev w3, w2 + orr w3, w3, w0 + rev w2, w3 + str w2, [x1, #DCFG_BRR_OFFSET] + isb + + /* send event */ + sev + isb + ret +endfunc _soc_core_release + + +/* part of CPU_ON + * this function restarts a core shutdown via _soc_core_entr_off + * in: x0 = core mask lsb (of the target cpu) + * out: x0 == 0, on success + * x0 != 0, on failure + * uses x0, x1, x2, x3, x4, x5 + */ +func _soc_core_restart + mov x5, x30 + mov x3, x0 + + /* + * unset ph20 request in RCPM_PCPH20CLEARR + * this is an lsb-0 register + */ + ldr x1, =NXP_RCPM_ADDR + rev w2, w3 + str w2, [x1, #RCPM_PCPH20CLRR_OFFSET] + dsb sy + isb + + bl _getGICD_BaseAddr + mov x4, x0 + + /* enable forwarding of group 0 interrupts by setting GICD_CTLR[0] = 1 */ + ldr w1, [x4, #GICD_CTLR_OFFSET] + orr w1, w1, #GICD_CTLR_EN_GRP0 + str w1, [x4, #GICD_CTLR_OFFSET] + dsb sy + isb + + + /* + * fire SGI by writing to GICD_SGIR the following values: + * [25:24] = 0x0 (forward interrupt to the CPU interfaces + * specified in CPUTargetList field) + * [23:16] = core mask lsb[7:0] (forward interrupt to target cpu) + * [15] = 0 (forward SGI only if it is configured as group 0 interrupt) + * [3:0] = 0xF (interrupt ID = 15) + */ + lsl w1, w3, #16 + orr w1, w1, #0xF + str w1, [x4, #GICD_SGIR_OFFSET] + dsb sy + isb + + /* load '0' on success */ + mov x0, xzr + + mov x30, x5 + ret +endfunc _soc_core_restart + +/* + * This function determines if a core is disabled via COREDISR + * in: w0 = core_mask_lsb + * out: w0 = 0, core not disabled + * w0 != 0, core disabled + * uses x0, x1, x2 + */ +func _soc_ck_disabled + /* get base addr of dcfg block */ + mov x1, #NXP_DCFG_ADDR + + /* read COREDISR */ + ldr w1, [x1, #DCFG_COREDISR_OFFSET] + rev w2, w1 + + /* test core bit */ + and w0, w2, w0 + ret +endfunc _soc_ck_disabled + +/* + *This function resets the system via SoC-specific methods + * in: none + * out: none + * uses x0, x1, x2, x3 + */ +func _soc_sys_reset + ldr x2, =NXP_DCFG_ADDR + + /* make sure the mask is cleared in the reset request mask register */ + mov w1, wzr + str w1, [x2, #DCFG_RSTRQMR1_OFFSET] + + /* set the reset request */ + ldr w1, =RSTCR_RESET_REQ + ldr x3, =DCFG_RSTCR_OFFSET + rev w0, w1 + str w0, [x2, x3] + + /* + * just in case this address range is mapped as cacheable, + * flush the write out of the dcaches + */ + add x3, x2, x3 + dc cvac, x3 + dsb st + isb + + /* Note: this function does not return */ +1: + wfi + b 1b +endfunc _soc_sys_reset + +/* + * Part of SYSTEM_OFF + * this function turns off the SoC clocks + * Note: this function is not intended to return, and the only allowable + * recovery is POR + * in: none + * out: none + * uses x0, x1, x2, x3, x4, x5, x6, x7, x8, x9 + */ +func _soc_sys_off + + /* mask interrupts at the core */ + mrs x1, DAIF + mov x0, #DAIF_SET_MASK + orr x0, x1, x0 + msr DAIF, x0 + + /* disable icache, dcache, mmu @ EL1 */ + mov x1, #SCTLR_I_C_M_MASK + mrs x0, sctlr_el1 + bic x0, x0, x1 + msr sctlr_el1, x0 + + /* disable dcache for EL3 */ + mrs x1, SCTLR_EL3 + bic x1, x1, #SCTLR_C_MASK + /* make sure icache is enabled */ + orr x1, x1, #SCTLR_I_MASK + msr SCTLR_EL3, x1 + isb + + /* Enable dynamic retention ctrl (CPUECTLR[2:0]) and SMP (CPUECTLR[6]) */ + mrs x0, CORTEX_A72_ECTLR_EL1 + orr x0, x0, #CPUECTLR_TIMER_8TICKS + orr x0, x0, #CPUECTLR_SMPEN_EN + msr CORTEX_A72_ECTLR_EL1, x0 + + /* set WFIL2EN in SCFG_CLUSTERPMCR */ + ldr x0, =SCFG_COREPMCR_OFFSET + ldr x1, =COREPMCR_WFIL2 + bl write_reg_scfg + + /* request LPM20 */ + mov x0, #RCPM_POWMGTCSR_OFFSET + bl read_reg_rcpm + orr x1, x0, #RCPM_POWMGTCSR_LPM20_REQ + mov x0, #RCPM_POWMGTCSR_OFFSET + bl write_reg_rcpm + + dsb sy + isb +1: + wfi + b 1b +endfunc _soc_sys_off + +/* + * Write a register in the RCPM block + * in: x0 = offset + * in: w1 = value to write + * uses x0, x1, x2, x3 + */ +func write_reg_rcpm + ldr x2, =NXP_RCPM_ADDR + /* swap for BE */ + rev w3, w1 + str w3, [x2, x0] + ret +endfunc write_reg_rcpm + +/* + * Read a register in the RCPM block + * in: x0 = offset + * out: w0 = value read + * uses x0, x1, x2 + */ +func read_reg_rcpm + ldr x2, =NXP_RCPM_ADDR + ldr w1, [x2, x0] + /* swap for BE */ + rev w0, w1 + ret +endfunc read_reg_rcpm + +/* + * Write a register in the SCFG block + * in: x0 = offset + * in: w1 = value to write + * uses x0, x1, x2, x3 + */ +func write_reg_scfg + mov x2, #NXP_SCFG_ADDR + /* swap for BE */ + rev w3, w1 + str w3, [x2, x0] + ret +endfunc write_reg_scfg + +/* + * Read a register in the SCFG block + * in: x0 = offset + * out: w0 = value read + * uses x0, x1, x2 + */ +func read_reg_scfg + mov x2, #NXP_SCFG_ADDR + ldr w1, [x2, x0] + /* swap for BE */ + rev w0, w1 + ret +endfunc read_reg_scfg + +/* + * Part of CPU_OFF + * this function programs SoC & GIC registers in preparation for shutting down + * the core + * in: x0 = core mask lsb + * out: none + * uses x0, x1, x2, x3, x4, x5, x6, x7 + */ +func _soc_core_prep_off + mov x7, x30 + mov x6, x0 + + /* Set retention control in CPUECTLR make sure smpen bit is set */ + mrs x4, CORTEX_A72_ECTLR_EL1 + bic x4, x4, #CPUECTLR_RET_MASK + orr x4, x4, #CPUECTLR_TIMER_8TICKS + orr x4, x4, #CPUECTLR_SMPEN_EN + msr CORTEX_A72_ECTLR_EL1, x4 + + /* save timer control current value */ + mov x5, #NXP_TIMER_ADDR + ldr w4, [x5, #SYS_COUNTER_CNTCR_OFFSET] + mov w2, w4 + mov x0, x6 + mov x1, #TIMER_CNTRL_DATA + bl _setCoreData + + /* enable the timer */ + orr w4, w4, #CNTCR_EN_MASK + str w4, [x5, #SYS_COUNTER_CNTCR_OFFSET] + + bl _getGICC_BaseAddr + mov x5, x0 + + /* disable signaling of ints */ + ldr w3, [x5, #GICC_CTLR_OFFSET] + bic w3, w3, #GICC_CTLR_EN_GRP0 + bic w3, w3, #GICC_CTLR_EN_GRP1 + str w3, [x5, #GICC_CTLR_OFFSET] + dsb sy + isb + + + /* + * set retention control in SCFG_RETREQCR + * Note: this register is msb 0 + */ + ldr x4, =SCFG_RETREQCR_OFFSET + mov x0, x4 + bl read_reg_scfg + rbit w1, w6 + orr w1, w0, w1 + mov x0, x4 + bl write_reg_scfg + + /* set the priority filter */ + ldr w2, [x5, #GICC_PMR_OFFSET] + orr w2, w2, #GICC_PMR_FILTER + str w2, [x5, #GICC_PMR_OFFSET] + + /* setup GICC_CTLR */ + bic w3, w3, #GICC_CTLR_ACKCTL_MASK + orr w3, w3, #GICC_CTLR_FIQ_EN_MASK + orr w3, w3, #GICC_CTLR_EOImodeS_MASK + orr w3, w3, #GICC_CTLR_CBPR_MASK + str w3, [x5, #GICC_CTLR_OFFSET] + + /* setup the banked-per-core GICD registers */ + bl _getGICD_BaseAddr + mov x5, x0 + + /* define SGI15 as Grp0 */ + ldr w2, [x5, #GICD_IGROUPR0_OFFSET] + bic w2, w2, #GICD_IGROUP0_SGI15 + str w2, [x5, #GICD_IGROUPR0_OFFSET] + + /* set priority of SGI 15 to highest... */ + ldr w2, [x5, #GICD_IPRIORITYR3_OFFSET] + bic w2, w2, #GICD_IPRIORITY_SGI15_MASK + str w2, [x5, #GICD_IPRIORITYR3_OFFSET] + + /* enable SGI 15 */ + ldr w2, [x5, #GICD_ISENABLER0_OFFSET] + orr w2, w2, #GICD_ISENABLE0_SGI15 + str w2, [x5, #GICD_ISENABLER0_OFFSET] + + /* enable the cpu interface */ + bl _getGICC_BaseAddr + mov x2, x0 + orr w3, w3, #GICC_CTLR_EN_GRP0 + str w3, [x2, #GICC_CTLR_OFFSET] + + + /* clear any pending SGIs */ + ldr x2, =GICD_CPENDSGIR_CLR_MASK + add x0, x5, #GICD_CPENDSGIR3_OFFSET + str w2, [x0] + + /* + * Set the PC_PH20_REQ bit in RCPM_PCPH20SETR + * this is an lsb-0 register + */ + mov x1, x6 + mov x0, #RCPM_PCPH20SETR_OFFSET + bl write_reg_rcpm + + dsb sy + isb + mov x30, x7 + ret +endfunc _soc_core_prep_off + +/* + * Part of CPU_OFF + * this function performs the final steps to shutdown the core + * in: x0 = core mask lsb + * out: none + * uses x0, x1, x2, x3, x4, x5 + */ +func _soc_core_entr_off + mov x5, x30 + mov x4, x0 + + bl _getGICD_BaseAddr + mov x3, x0 + +3: + /* enter low-power state by executing wfi */ + wfi + + /* see if we got hit by SGI 15 */ + add x0, x3, #GICD_SPENDSGIR3_OFFSET + ldr w2, [x0] + and w2, w2, #GICD_SPENDSGIR3_SGI15_MASK + cbz w2, 4f + + /* clear the pending SGI */ + ldr x2, =GICD_CPENDSGIR_CLR_MASK + add x0, x3, #GICD_CPENDSGIR3_OFFSET + str w2, [x0] +4: + /* check if core has been turned on */ + mov x0, x4 + bl _getCoreState + + cmp x0, #CORE_WAKEUP + b.ne 3b + + /* if we get here, then we have exited the wfi */ + dsb sy + isb + mov x30, x5 + ret +endfunc _soc_core_entr_off + +/* + * Part of CPU_OFF + * this function starts the process of starting a core back up + * in: x0 = core mask lsb + * out: none + * uses x0, x1, x2, x3, x4, x5, x6 + */ +func _soc_core_exit_off + mov x6, x30 + mov x5, x0 + + /* + * Clear ph20 request in RCPM_PCPH20CLRR - no need + * to do that here, it has been done in _soc_core_restart + */ + bl _getGICC_BaseAddr + mov x1, x0 + + /* read GICC_IAR */ + ldr w0, [x1, #GICC_IAR_OFFSET] + + /* write GICC_EIOR - signal end-of-interrupt */ + str w0, [x1, #GICC_EOIR_OFFSET] + + /* write GICC_DIR - disable interrupt */ + str w0, [x1, #GICC_DIR_OFFSET] + + /* disable signaling of grp0 ints */ + ldr w3, [x1, #GICC_CTLR_OFFSET] + bic w3, w3, #GICC_CTLR_EN_GRP0 + str w3, [x1, #GICC_CTLR_OFFSET] + + /* + * Unset retention request in SCFG_RETREQCR + * Note: this register is msb-0 + */ + ldr x4, =SCFG_RETREQCR_OFFSET + mov x0, x4 + bl read_reg_scfg + rbit w1, w5 + bic w1, w0, w1 + mov x0, x4 + bl write_reg_scfg + + /* restore timer ctrl */ + mov x0, x5 + mov x1, #TIMER_CNTRL_DATA + bl _getCoreData + /* w0 = timer ctrl saved value */ + mov x2, #NXP_TIMER_ADDR + str w0, [x2, #SYS_COUNTER_CNTCR_OFFSET] + + dsb sy + isb + mov x30, x6 + ret +endfunc _soc_core_exit_off + +/* + * Function loads a 64-bit execution address of the core in the soc registers + * BOOTLOCPTRL/H + * in: x0, 64-bit address to write to BOOTLOCPTRL/H + * uses x0, x1, x2, x3 + */ +func _soc_set_start_addr + /* get the 64-bit base address of the scfg block */ + ldr x2, =NXP_SCFG_ADDR + + /* write the 32-bit BOOTLOCPTRL register */ + mov x1, x0 + rev w3, w1 + str w3, [x2, #SCFG_BOOTLOCPTRL_OFFSET] + + /* write the 32-bit BOOTLOCPTRH register */ + lsr x1, x0, #32 + rev w3, w1 + str w3, [x2, #SCFG_BOOTLOCPTRH_OFFSET] + ret +endfunc _soc_set_start_addr + +/* + * This function returns the base address of the gic distributor + * in: none + * out: x0 = base address of gic distributor + * uses x0 + */ +func _getGICD_BaseAddr +#if (TEST_BL31) + /* defect in simulator - gic base addresses are on 4Kb boundary */ + ldr x0, =NXP_GICD_4K_ADDR +#else + ldr x0, =NXP_GICD_64K_ADDR +#endif + ret +endfunc _getGICD_BaseAddr + +/* + * This function returns the base address of the gic controller + * in: none + * out: x0 = base address of gic controller + * uses x0 + */ +func _getGICC_BaseAddr +#if (TEST_BL31) + /* defect in simulator - gic base addresses are on 4Kb boundary */ + ldr x0, =NXP_GICC_4K_ADDR +#else + ldr x0, =NXP_GICC_64K_ADDR +#endif + ret +endfunc _getGICC_BaseAddr + +/* + * Part of CPU_SUSPEND + * this function puts the calling core into standby state + * in: x0 = core mask lsb + * out: none + * uses x0 + */ +func _soc_core_entr_stdby + dsb sy + isb + wfi + + ret +endfunc _soc_core_entr_stdby + + +/* + * Part of CPU_SUSPEND + * this function performs SoC-specific programming prior to standby + * in: x0 = core mask lsb + * out: none + * uses x0, x1 + */ +func _soc_core_prep_stdby + /* clear CORTEX_A72_ECTLR_EL1[2:0] */ + mrs x1, CORTEX_A72_ECTLR_EL1 + bic x1, x1, #CPUECTLR_TIMER_MASK + msr CORTEX_A72_ECTLR_EL1, x1 + + ret +endfunc _soc_core_prep_stdby + +/* + * Part of CPU_SUSPEND + * this function performs any SoC-specific cleanup after standby state + * in: x0 = core mask lsb + * out: none + * uses none + */ +func _soc_core_exit_stdby + ret +endfunc _soc_core_exit_stdby + +/* + * Part of CPU_SUSPEND + * this function performs SoC-specific programming prior to power-down + * in: x0 = core mask lsb + * out: none + * uses x0, x1, x2, x3, x4, x5 + */ +func _soc_core_prep_pwrdn + mov x5, x30 + mov x4, x0 + + /* enable CPU retention + set smp */ + mrs x1, CORTEX_A72_ECTLR_EL1 + orr x1, x1, #0x1 + orr x1, x1, #CPUECTLR_SMPEN_MASK + msr CORTEX_A72_ECTLR_EL1, x1 + + /* + * set the retention request in SCFG_RETREQCR + * this is an msb-0 register + */ + ldr x3, =SCFG_RETREQCR_OFFSET + mov x0, x3 + bl read_reg_scfg + rbit w1, w4 + orr w1, w0, w1 + mov x0, x3 + bl write_reg_scfg + + /* + * Set the PC_PH20_REQ bit in RCPM_PCPH20SETR + * this is an lsb-0 register + */ + mov x1, x4 + mov x0, #RCPM_PCPH20SETR_OFFSET + bl write_reg_rcpm + + mov x30, x5 + ret +endfunc _soc_core_prep_pwrdn + +/* + * Part of CPU_SUSPEND + * this function puts the calling core into a power-down state + * in: x0 = core mask lsb + * out: none + * uses x0 + */ +func _soc_core_entr_pwrdn + dsb sy + isb + wfi + + ret +endfunc _soc_core_entr_pwrdn + +/* + * Part of CPU_SUSPEND + * this function cleans up after a core exits power-down + * in: x0 = core mask lsb + * out: none + * uses x0, x1, x2, x3, x4, x5 + */ +func _soc_core_exit_pwrdn + mov x5, x30 + mov x4, x0 + + /* + * Set the PC_PH20_REQ bit in RCPM_PCPH20CLRR + * this is an lsb-0 register + */ + mov x1, x4 + mov x0, #RCPM_PCPH20CLRR_OFFSET + bl write_reg_rcpm + + /* + * Unset the retention request in SCFG_RETREQCR + * this is an msb-0 register + */ + ldr x3, =SCFG_RETREQCR_OFFSET + mov x0, x3 + bl read_reg_scfg + rbit w1, w4 + bic w1, w0, w1 + mov x0, x3 + bl write_reg_scfg + + mov x30, x5 + ret +endfunc _soc_core_exit_pwrdn + +/* + * Part of CPU_SUSPEND + * this function performs SoC-specific programming prior to standby + * in: x0 = core mask lsb + * out: none + * uses none + */ +func _soc_clstr_prep_stdby + /* clear CORTEX_A72_ECTLR_EL1[2:0] */ + mrs x1, CORTEX_A72_ECTLR_EL1 + bic x1, x1, #CPUECTLR_TIMER_MASK + msr CORTEX_A72_ECTLR_EL1, x1 + + ret +endfunc _soc_clstr_prep_stdby + +/* + * Part of CPU_SUSPEND + * this function performs any SoC-specific cleanup after standby state + * in: x0 = core mask lsb + * out: none + * uses none + */ +func _soc_clstr_exit_stdby + ret +endfunc _soc_clstr_exit_stdby + +/* + * Part of CPU_SUSPEND + * this function performs SoC-specific programming prior to power-down + * in: x0 = core mask lsb + * out: none + * uses x0, x1, x2, x3, x4, x5 + */ +func _soc_clstr_prep_pwrdn + mov x5, x30 + mov x4, x0 + + /* enable CPU retention + set smp */ + mrs x1, CORTEX_A72_ECTLR_EL1 + orr x1, x1, #0x1 + orr x1, x1, #CPUECTLR_SMPEN_MASK + msr CORTEX_A72_ECTLR_EL1, x1 + + /* + * Set the retention request in SCFG_RETREQCR + * this is an msb-0 register. + */ + ldr x3, =SCFG_RETREQCR_OFFSET + mov x0, x3 + bl read_reg_scfg + rbit w1, w4 + orr w1, w0, w1 + mov x0, x3 + bl write_reg_scfg + + /* + * Set the PC_PH20_REQ bit in RCPM_PCPH20SETR + * this is an lsb-0 register. + */ + mov x1, x4 + mov x0, #RCPM_PCPH20SETR_OFFSET + bl write_reg_rcpm + + mov x30, x5 + ret +endfunc _soc_clstr_prep_pwrdn + +/* + * Part of CPU_SUSPEND + * this function cleans up after a core exits power-down + * in: x0 = core mask lsb + * out: none + * uses x0, x1, x2, x3, x4, x5 + */ +func _soc_clstr_exit_pwrdn + mov x5, x30 + mov x4, x0 + + /* + * Set the PC_PH20_REQ bit in RCPM_PCPH20CLRR + * this is an lsb-0 register. + */ + mov x1, x4 + mov x0, #RCPM_PCPH20CLRR_OFFSET + bl write_reg_rcpm + + /* + * Unset the retention request in SCFG_RETREQCR + * this is an msb-0 register. + */ + ldr x3, =SCFG_RETREQCR_OFFSET + mov x0, x3 + bl read_reg_scfg + rbit w1, w4 + bic w1, w0, w1 + mov x0, x3 + bl write_reg_scfg + + mov x30, x5 + ret +endfunc _soc_clstr_exit_pwrdn + +/* + * Part of CPU_SUSPEND + * this function performs SoC-specific programming prior to standby + * in: x0 = core mask lsb + * out: none + * uses none + */ +func _soc_sys_prep_stdby + /* clear CORTEX_A72_ECTLR_EL1[2:0] */ + mrs x1, CORTEX_A72_ECTLR_EL1 + bic x1, x1, #CPUECTLR_TIMER_MASK + msr CORTEX_A72_ECTLR_EL1, x1 + + ret +endfunc _soc_sys_prep_stdby + +/* Part of CPU_SUSPEND + * this function performs any SoC-specific cleanup after standby state + * in: x0 = core mask lsb + * out: none + * uses none + */ +func _soc_sys_exit_stdby + ret +endfunc _soc_sys_exit_stdby + +/* + * Part of CPU_SUSPEND + * this function performs SoC-specific programming prior to + * suspend-to-power-down + * in: x0 = core mask lsb + * out: none + * uses x0, x1, x2, x3, x4 + */ +func _soc_sys_prep_pwrdn + mov x4, x30 + + /* Enable dynamic retention contrl (CPUECTLR[2:0]) and SMP (CPUECTLR[6]) */ + mrs x0, CORTEX_A72_ECTLR_EL1 + bic x0, x0, #CPUECTLR_TIMER_MASK + orr x0, x0, #CPUECTLR_TIMER_8TICKS + orr x0, x0, #CPUECTLR_SMPEN_EN + msr CORTEX_A72_ECTLR_EL1, x0 + + /* Set WFIL2EN in SCFG_CLUSTERPMCR */ + ldr x0, =SCFG_COREPMCR_OFFSET + ldr x1, =COREPMCR_WFIL2 + bl write_reg_scfg + + isb + mov x30, x4 + ret +endfunc _soc_sys_prep_pwrdn + +/* + * Part of CPU_SUSPEND + * this function puts the calling core, and potentially the soc, into a + * low-power state + * in: x0 = core mask lsb + * out: x0 = 0, success + * x0 < 0, failure + * uses x0, x1, x2, x3, x4 + */ +func _soc_sys_pwrdn_wfi + mov x4, x30 + + /* request LPM20 */ + mov x0, #RCPM_POWMGTCSR_OFFSET + bl read_reg_rcpm + orr x1, x0, #RCPM_POWMGTCSR_LPM20_REQ + mov x0, #RCPM_POWMGTCSR_OFFSET + bl write_reg_rcpm + + dsb sy + isb + wfi + + mov x30, x4 + ret +endfunc _soc_sys_pwrdn_wfi + +/* + * Part of CPU_SUSPEND + * this function performs any SoC-specific cleanup after power-down + * in: x0 = core mask lsb + * out: none + * uses x0, x1 + */ +func _soc_sys_exit_pwrdn + /* clear WFIL2_EN in SCFG_COREPMCR */ + mov x1, #NXP_SCFG_ADDR + str wzr, [x1, #SCFG_COREPMCR_OFFSET] + + ret +endfunc _soc_sys_exit_pwrdn diff --git a/plat/nxp/soc-ls1046a/aarch64/ls1046a_helpers.S b/plat/nxp/soc-ls1046a/aarch64/ls1046a_helpers.S new file mode 100644 index 0000000..a213594 --- /dev/null +++ b/plat/nxp/soc-ls1046a/aarch64/ls1046a_helpers.S @@ -0,0 +1,92 @@ +/* + * Copyright 2018-2022 NXP + * + * SPDX-License-Identifier: BSD-3-Clause + * + */ + +#include <arch.h> +#include <asm_macros.S> + +#include <platform_def.h> + + .globl plat_secondary_cold_boot_setup + .globl plat_is_my_cpu_primary + .globl plat_reset_handler + .globl platform_mem_init + +func platform_mem1_init + ret +endfunc platform_mem1_init + +func platform_mem_init + ret +endfunc platform_mem_init + +func l2_mem_init + /* Initialize the L2 RAM latency */ + mrs x1, S3_1_c11_c0_2 + mov x0, #0x1C7 + /* Clear L2 Tag RAM latency and L2 Data RAM latency */ + bic x1, x1, x0 + /* Set L2 data ram latency bits [2:0] */ + orr x1, x1, #0x2 + /* set L2 tag ram latency bits [8:6] */ + orr x1, x1, #0x80 + msr S3_1_c11_c0_2, x1 + isb + ret +endfunc l2_mem_init + +func apply_platform_errata + ret +endfunc apply_platform_errata + +func plat_reset_handler + mov x29, x30 +#if (defined(IMAGE_BL2) && RESET_TO_BL2) + bl l2_mem_init +#endif + bl apply_platform_errata + +#if defined(IMAGE_BL31) + ldr x0, =POLICY_SMMU_PAGESZ_64K + cbz x0, 1f + /* Set the SMMU page size in the SACR register */ + bl _set_smmu_pagesz_64 +#endif +1: + /* + * May be cntfrq_el0 needs to be assigned + * the value COUNTER_FREQUENCY + */ + mov x30, x29 + ret +endfunc plat_reset_handler + +/* + * void plat_secondary_cold_boot_setup (void); + * + * This function performs any platform specific actions + * needed for a secondary cpu after a cold reset e.g + * mark the cpu's presence, mechanism to place it in a + * holding pen etc. + */ +func plat_secondary_cold_boot_setup + /* ls1046a does not do cold boot for secondary CPU */ +cb_panic: + b cb_panic +endfunc plat_secondary_cold_boot_setup + +/* + * unsigned int plat_is_my_cpu_primary (void); + * + * Find out whether the current cpu is the primary cpu. + */ +func plat_is_my_cpu_primary + mrs x0, mpidr_el1 + and x0, x0, #(MPIDR_CLUSTER_MASK | MPIDR_CPU_MASK) + cmp x0, 0x0 + cset w0, eq + ret +endfunc plat_is_my_cpu_primary diff --git a/plat/nxp/soc-ls1046a/include/ns_access.h b/plat/nxp/soc-ls1046a/include/ns_access.h new file mode 100644 index 0000000..25c1964 --- /dev/null +++ b/plat/nxp/soc-ls1046a/include/ns_access.h @@ -0,0 +1,174 @@ +/* + * Copyright 2017-2018, 2020-2022 NXP + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef NS_ACCESS_H +#define NS_ACCESS_H + +#include <csu.h> + +enum csu_cslx_ind { + CSU_CSLX_PCIE2_IO = 0, + CSU_CSLX_PCIE1_IO, + CSU_CSLX_MG2TPR_IP, + CSU_CSLX_IFC_MEM, + CSU_CSLX_OCRAM, + CSU_CSLX_GIC, + CSU_CSLX_PCIE1, + CSU_CSLX_OCRAM2, + CSU_CSLX_QSPI_MEM, + CSU_CSLX_PCIE2, + CSU_CSLX_SATA, + CSU_CSLX_USB1, + CSU_CSLX_QM_BM_SWPORTAL, + CSU_CSLX_PCIE3 = 16, + CSU_CSLX_PCIE3_IO, + CSU_CSLX_USB3 = 20, + CSU_CSLX_USB2, + CSU_CSLX_PFE = 23, + CSU_CSLX_SERDES = 32, + CSU_CSLX_QDMA, + CSU_CSLX_LPUART2, + CSU_CSLX_LPUART1, + CSU_CSLX_LPUART4, + CSU_CSLX_LPUART3, + CSU_CSLX_LPUART6, + CSU_CSLX_LPUART5, + CSU_CSLX_DSPI1 = 41, + CSU_CSLX_QSPI, + CSU_CSLX_ESDHC, + CSU_CSLX_IFC = 45, + CSU_CSLX_I2C1, + CSU_CSLX_USB_2, + CSU_CSLX_I2C3 = 48, + CSU_CSLX_I2C2, + CSU_CSLX_DUART2 = 50, + CSU_CSLX_DUART1, + CSU_CSLX_WDT2, + CSU_CSLX_WDT1, + CSU_CSLX_EDMA, + CSU_CSLX_SYS_CNT, + CSU_CSLX_DMA_MUX2, + CSU_CSLX_DMA_MUX1, + CSU_CSLX_DDR, + CSU_CSLX_QUICC, + CSU_CSLX_DCFG_CCU_RCPM = 60, + CSU_CSLX_SECURE_BOOTROM, + CSU_CSLX_SFP, + CSU_CSLX_TMU, + CSU_CSLX_SECURE_MONITOR, + CSU_CSLX_SCFG, + CSU_CSLX_FM = 66, + CSU_CSLX_SEC5_5, + CSU_CSLX_BM, + CSU_CSLX_QM, + CSU_CSLX_GPIO2 = 70, + CSU_CSLX_GPIO1, + CSU_CSLX_GPIO4, + CSU_CSLX_GPIO3, + CSU_CSLX_PLATFORM_CONT, + CSU_CSLX_CSU, + CSU_CSLX_IIC4 = 77, + CSU_CSLX_WDT4, + CSU_CSLX_WDT3, + CSU_CSLX_ESDHC2 = 80, + CSU_CSLX_WDT5 = 81, + CSU_CSLX_SAI2, + CSU_CSLX_SAI1, + CSU_CSLX_SAI4, + CSU_CSLX_SAI3, + CSU_CSLX_FTM2 = 86, + CSU_CSLX_FTM1, + CSU_CSLX_FTM4, + CSU_CSLX_FTM3, + CSU_CSLX_FTM6 = 90, + CSU_CSLX_FTM5, + CSU_CSLX_FTM8, + CSU_CSLX_FTM7, + CSU_CSLX_DSCR = 121, +}; + +struct csu_ns_dev_st ns_dev[] = { + {CSU_CSLX_PCIE2_IO, CSU_ALL_RW}, + {CSU_CSLX_PCIE1_IO, CSU_ALL_RW}, + {CSU_CSLX_MG2TPR_IP, CSU_ALL_RW}, + {CSU_CSLX_IFC_MEM, CSU_ALL_RW}, + {CSU_CSLX_OCRAM, CSU_S_SUP_RW}, + {CSU_CSLX_GIC, CSU_ALL_RW}, + {CSU_CSLX_PCIE1, CSU_ALL_RW}, + {CSU_CSLX_OCRAM2, CSU_S_SUP_RW}, + {CSU_CSLX_QSPI_MEM, CSU_ALL_RW}, + {CSU_CSLX_PCIE2, CSU_ALL_RW}, + {CSU_CSLX_SATA, CSU_ALL_RW}, + {CSU_CSLX_USB1, CSU_ALL_RW}, + {CSU_CSLX_QM_BM_SWPORTAL, CSU_ALL_RW}, + {CSU_CSLX_PCIE3, CSU_ALL_RW}, + {CSU_CSLX_PCIE3_IO, CSU_ALL_RW}, + {CSU_CSLX_USB3, CSU_ALL_RW}, + {CSU_CSLX_USB2, CSU_ALL_RW}, + {CSU_CSLX_PFE, CSU_ALL_RW}, + {CSU_CSLX_SERDES, CSU_ALL_RW}, + {CSU_CSLX_QDMA, CSU_ALL_RW}, + {CSU_CSLX_LPUART2, CSU_ALL_RW}, + {CSU_CSLX_LPUART1, CSU_ALL_RW}, + {CSU_CSLX_LPUART4, CSU_ALL_RW}, + {CSU_CSLX_LPUART3, CSU_ALL_RW}, + {CSU_CSLX_LPUART6, CSU_ALL_RW}, + {CSU_CSLX_LPUART5, CSU_ALL_RW}, + {CSU_CSLX_DSPI1, CSU_ALL_RW}, + {CSU_CSLX_QSPI, CSU_ALL_RW}, + {CSU_CSLX_ESDHC, CSU_ALL_RW}, + {CSU_CSLX_IFC, CSU_ALL_RW}, + {CSU_CSLX_I2C1, CSU_ALL_RW}, + {CSU_CSLX_USB_2, CSU_ALL_RW}, + {CSU_CSLX_I2C3, CSU_ALL_RW}, + {CSU_CSLX_I2C2, CSU_ALL_RW}, + {CSU_CSLX_DUART2, CSU_ALL_RW}, + {CSU_CSLX_DUART1, CSU_ALL_RW}, + {CSU_CSLX_WDT2, CSU_ALL_RW}, + {CSU_CSLX_WDT1, CSU_ALL_RW}, + {CSU_CSLX_EDMA, CSU_ALL_RW}, + {CSU_CSLX_SYS_CNT, CSU_ALL_RW}, + {CSU_CSLX_DMA_MUX2, CSU_ALL_RW}, + {CSU_CSLX_DMA_MUX1, CSU_ALL_RW}, + {CSU_CSLX_DDR, CSU_ALL_RW}, + {CSU_CSLX_QUICC, CSU_ALL_RW}, + {CSU_CSLX_DCFG_CCU_RCPM, CSU_ALL_RW}, + {CSU_CSLX_SECURE_BOOTROM, CSU_ALL_RW}, + {CSU_CSLX_SFP, CSU_ALL_RW}, + {CSU_CSLX_TMU, CSU_ALL_RW}, + {CSU_CSLX_SECURE_MONITOR, CSU_ALL_RW}, + {CSU_CSLX_SCFG, CSU_ALL_RW}, + {CSU_CSLX_FM, CSU_ALL_RW}, + {CSU_CSLX_SEC5_5, CSU_ALL_RW}, + {CSU_CSLX_BM, CSU_ALL_RW}, + {CSU_CSLX_QM, CSU_ALL_RW}, + {CSU_CSLX_GPIO2, CSU_ALL_RW}, + {CSU_CSLX_GPIO1, CSU_ALL_RW}, + {CSU_CSLX_GPIO4, CSU_ALL_RW}, + {CSU_CSLX_GPIO3, CSU_ALL_RW}, + {CSU_CSLX_PLATFORM_CONT, CSU_ALL_RW}, + {CSU_CSLX_CSU, CSU_ALL_RW}, + {CSU_CSLX_IIC4, CSU_ALL_RW}, + {CSU_CSLX_WDT4, CSU_ALL_RW}, + {CSU_CSLX_WDT3, CSU_ALL_RW}, + {CSU_CSLX_ESDHC2, CSU_ALL_RW}, + {CSU_CSLX_WDT5, CSU_ALL_RW}, + {CSU_CSLX_SAI2, CSU_ALL_RW}, + {CSU_CSLX_SAI1, CSU_ALL_RW}, + {CSU_CSLX_SAI4, CSU_ALL_RW}, + {CSU_CSLX_SAI3, CSU_ALL_RW}, + {CSU_CSLX_FTM2, CSU_ALL_RW}, + {CSU_CSLX_FTM1, CSU_ALL_RW}, + {CSU_CSLX_FTM4, CSU_ALL_RW}, + {CSU_CSLX_FTM3, CSU_ALL_RW}, + {CSU_CSLX_FTM6, CSU_ALL_RW}, + {CSU_CSLX_FTM5, CSU_ALL_RW}, + {CSU_CSLX_FTM8, CSU_ALL_RW}, + {CSU_CSLX_FTM7, CSU_ALL_RW}, + {CSU_CSLX_DSCR, CSU_ALL_RW}, +}; + +#endif /* NS_ACCESS_H */ diff --git a/plat/nxp/soc-ls1046a/include/soc.h b/plat/nxp/soc-ls1046a/include/soc.h new file mode 100644 index 0000000..67810c3 --- /dev/null +++ b/plat/nxp/soc-ls1046a/include/soc.h @@ -0,0 +1,125 @@ +/* + * Copyright 2018-2022 NXP + * + * SPDX-License-Identifier: BSD-3-Clause + * + */ + +#ifndef SOC_H +#define SOC_H + +/* Chassis specific defines - common across SoC's of a particular platform */ +#include <dcfg_lsch2.h> + +#include <soc_default_base_addr.h> +#include <soc_default_helper_macros.h> + +/* DDR Regions Info */ +#define NUM_DRAM_REGIONS U(3) +#define NXP_DRAM0_ADDR ULL(0x80000000) +#define NXP_DRAM0_MAX_SIZE ULL(0x80000000) /* 2 GB */ + +#define NXP_DRAM1_ADDR ULL(0x880000000) +#define NXP_DRAM1_MAX_SIZE ULL(0x780000000) /* 30 GB */ + +#define NXP_DRAM2_ADDR ULL(0x8800000000) +#define NXP_DRAM2_MAX_SIZE ULL(0x7800000000) /* 480 GB */ + +/*DRAM0 Size defined in platform_def.h */ +#define NXP_DRAM0_SIZE PLAT_DEF_DRAM0_SIZE + +/* + * SVR Definition (not include major and minor rev) + * A: without security + * AE: with security + */ +#define SVR_LS1026A 0x870709 +#define SVR_LS1026AE 0x870708 +#define SVR_LS1046A 0x870701 +#define SVR_LS1046AE 0x870700 + +/* Number of cores in platform */ +/* Used by common code for array initialization */ +#define NUMBER_OF_CLUSTERS U(1) +#define CORES_PER_CLUSTER U(4) +#define PLATFORM_CORE_COUNT (NUMBER_OF_CLUSTERS * CORES_PER_CLUSTER) + +/* + * Required LS standard platform porting definitions + * for CCI-400 + */ +#define NXP_CCI_CLUSTER0_SL_IFACE_IX 4 + + +/* Defines required for using XLAT tables from ARM common code */ +#define PLAT_PHY_ADDR_SPACE_SIZE (1ULL << 40) +#define PLAT_VIRT_ADDR_SPACE_SIZE (1ULL << 40) + +/* Clock Divisors */ +#define NXP_PLATFORM_CLK_DIVIDER U(1) +#define NXP_UART_CLK_DIVIDER U(2) + +/* set to 0 if the clusters are not symmetrical */ +#define SYMMETRICAL_CLUSTERS U(1) + + /* + * set this switch to 1 if you need to keep the debug block + * clocked during system power-down + */ +#define DEBUG_ACTIVE 0 + + /* + * pwr mgmt features supported in the soc-specific code: + * value == 0x0 the soc code does not support this feature + * value != 0x0 the soc code supports this feature + */ +#define SOC_CORE_RELEASE 0x1 +#define SOC_CORE_RESTART 0x1 +#define SOC_CORE_OFF 0x1 +#define SOC_CORE_STANDBY 0x1 +#define SOC_CORE_PWR_DWN 0x1 +#define SOC_CLUSTER_STANDBY 0x1 +#define SOC_CLUSTER_PWR_DWN 0x1 +#define SOC_SYSTEM_STANDBY 0x1 +#define SOC_SYSTEM_PWR_DWN 0x1 +#define SOC_SYSTEM_OFF 0x1 +#define SOC_SYSTEM_RESET 0x1 + +/* Start: Macros used by lib/psci files */ +#define SYSTEM_PWR_DOMAINS 1 +#define PLAT_NUM_PWR_DOMAINS (PLATFORM_CORE_COUNT + \ + NUMBER_OF_CLUSTERS + \ + SYSTEM_PWR_DOMAINS) + +/* Power state coordination occurs at the system level */ +#define PLAT_MAX_PWR_LVL MPIDR_AFFLVL2 + +/* define retention state */ +#define PLAT_MAX_RET_STATE (PSCI_LOCAL_STATE_RUN + 1) + +/* define power-down state */ +#define PLAT_MAX_OFF_STATE (PLAT_MAX_RET_STATE + 1) + +/* + * Some data must be aligned on the biggest cache line size in the platform. + * This is known only to the platform as it might have a combination of + * integrated and external caches. + * + * CACHE_WRITEBACK_GRANULE is defined in soc.def + */ + + /* One cache line needed for bakery locks on ARM platforms */ +#define PLAT_PERCPU_BAKERY_LOCK_SIZE (1 * CACHE_WRITEBACK_GRANULE) + +#ifndef __ASSEMBLER__ +/* CCI slave interfaces */ +static const int cci_map[] = { + NXP_CCI_CLUSTER0_SL_IFACE_IX, +}; + +void soc_init_lowlevel(void); +void soc_init_percpu(void); +void _soc_set_start_addr(unsigned long addr); +#endif + +#endif /* SOC_H */ diff --git a/plat/nxp/soc-ls1046a/ls1046afrwy/ddr_init.c b/plat/nxp/soc-ls1046a/ls1046afrwy/ddr_init.c new file mode 100644 index 0000000..3d561c7 --- /dev/null +++ b/plat/nxp/soc-ls1046a/ls1046afrwy/ddr_init.c @@ -0,0 +1,177 @@ +/* + * Copyright 2018-2022 NXP + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <assert.h> +#include <errno.h> +#include <string.h> + +#include <common/debug.h> +#include <ddr.h> +#include <lib/utils.h> + +#include <errata.h> +#include <platform_def.h> + +#ifdef CONFIG_STATIC_DDR +const struct ddr_cfg_regs static_1600 = { + .cs[0].config = U(0x80010412), + .cs[0].bnds = U(0x7F), + .sdram_cfg[0] = U(0xE50C0008), + .sdram_cfg[1] = U(0x00401010), + .sdram_cfg[2] = U(0x1), + .timing_cfg[0] = U(0xFA550018), + .timing_cfg[1] = U(0xBAB40C52), + .timing_cfg[2] = U(0x0048C11C), + .timing_cfg[3] = U(0x01111000), + .timing_cfg[4] = U(0x00000002), + .timing_cfg[5] = U(0x03401400), + .timing_cfg[6] = U(0x0), + .timing_cfg[7] = U(0x23300000), + .timing_cfg[8] = U(0x02116600), + .timing_cfg[9] = U(0x0), + .dq_map[0] = U(0x0), + .dq_map[1] = U(0x0), + .dq_map[2] = U(0x0), + .dq_map[3] = U(0x0), + .sdram_mode[0] = U(0x01010210), + .sdram_mode[1] = U(0x0), + .sdram_mode[8] = U(0x00000500), + .sdram_mode[9] = U(0x04000000), + .interval = U(0x18600618), + .zq_cntl = U(0x8A090705), + .ddr_sr_cntr = U(0x0), + .clk_cntl = U(0x2000000), + .cdr[0] = U(0x80040000), + .cdr[1] = U(0xC1), + .wrlvl_cntl[0] = U(0x86550607), + .wrlvl_cntl[1] = U(0x07070708), + .wrlvl_cntl[2] = U(0x0808088), +}; + +long long board_static_ddr(struct ddr_info *priv) +{ + memcpy(&priv->ddr_reg, &static_1600, sizeof(static_1600)); + + return 0x80000000ULL; +} +#else /* ifndef CONFIG_STATIC_DDR */ +static const struct rc_timing rcz[] = { + {U(1600), U(8), U(7)}, + {U(2100), U(8), U(7)}, + {} +}; + +static const struct board_timing ram[] = { + {U(0x1f), rcz, U(0x01010101), U(0x01010101)}, +}; + +int ddr_board_options(struct ddr_info *priv) +{ + int ret; + struct memctl_opt *popts = &priv->opt; + + ret = cal_board_params(priv, ram, ARRAY_SIZE(ram)); + if (ret != 0) { + return ret; + } + + popts->bstopre = 0; + popts->half_strength_drive_en = 1; + popts->cpo_sample = U(0x46); + popts->ddr_cdr1 = DDR_CDR1_DHC_EN | DDR_CDR1_ODT(DDR_CDR_ODT_50ohm); + popts->ddr_cdr2 = DDR_CDR2_ODT(DDR_CDR_ODT_50ohm) | + DDR_CDR2_VREF_TRAIN_EN; + popts->output_driver_impedance = 1; + + return 0; +} + +/* DDR model number: MT40A512M16JY-083E:B */ +struct dimm_params ddr_raw_timing = { + .n_ranks = U(1), + .rank_density = ULL(4294967296), + .capacity = ULL(4294967296), + .primary_sdram_width = U(64), + .ec_sdram_width = U(8), + .rdimm = U(0), + .mirrored_dimm = U(0), + .n_row_addr = U(16), + .n_col_addr = U(10), + .bank_group_bits = U(1), + .edc_config = U(2), + .burst_lengths_bitmask = U(0x0c), + .tckmin_x_ps = 750, + .tckmax_ps = 1900, + .caslat_x = U(0x0001FFE00), + .taa_ps = 13500, + .trcd_ps = 13500, + .trp_ps = 13500, + .tras_ps = 33000, + .trc_ps = 46500, + .twr_ps = 15000, + .trfc1_ps = 350000, + .trfc2_ps = 260000, + .trfc4_ps = 160000, + .tfaw_ps = 30000, + .trrds_ps = 5300, + .trrdl_ps = 6400, + .tccdl_ps = 5355, + .refresh_rate_ps = U(7800000), + .dq_mapping[0] = U(0x0), + .dq_mapping[1] = U(0x0), + .dq_mapping[2] = U(0x0), + .dq_mapping[3] = U(0x0), + .dq_mapping[4] = U(0x0), + .dq_mapping_ors = U(0), + .rc = U(0x1f), +}; + +int ddr_get_ddr_params(struct dimm_params *pdimm, struct ddr_conf *conf) +{ + static const char dimm_model[] = "Fixed DDR on board"; + + conf->dimm_in_use[0] = 1; + memcpy(pdimm, &ddr_raw_timing, sizeof(struct dimm_params)); + memcpy(pdimm->mpart, dimm_model, sizeof(dimm_model) - 1); + + return 1; +} +#endif /* ifdef CONFIG_STATIC_DDR */ + +long long init_ddr(void) +{ + int spd_addr[] = {NXP_SPD_EEPROM0}; + struct ddr_info info; + struct sysinfo sys; + long long dram_size; + + zeromem(&sys, sizeof(sys)); + if (get_clocks(&sys)) { + ERROR("System clocks are not set\n"); + assert(0); + } + debug("platform clock %lu\n", sys.freq_platform); + debug("DDR PLL1 %lu\n", sys.freq_ddr_pll0); + debug("DDR PLL2 %lu\n", sys.freq_ddr_pll1); + + zeromem(&info, sizeof(struct ddr_info)); + info.num_ctlrs = 1; + info.dimm_on_ctlr = 1; + info.clk = get_ddr_freq(&sys, 0); + info.spd_addr = spd_addr; + info.ddr[0] = (void *)NXP_DDR_ADDR; + + dram_size = dram_init(&info); + if (dram_size < 0) { + ERROR("DDR init failed.\n"); + } + +#ifdef ERRATA_SOC_A008850 + erratum_a008850_post(); +#endif + + return dram_size; +} diff --git a/plat/nxp/soc-ls1046a/ls1046afrwy/plat_def.h b/plat/nxp/soc-ls1046a/ls1046afrwy/plat_def.h new file mode 100644 index 0000000..5134a00 --- /dev/null +++ b/plat/nxp/soc-ls1046a/ls1046afrwy/plat_def.h @@ -0,0 +1,79 @@ +/* + * Copyright 2018-2022 NXP + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef PLAT_DEF_H +#define PLAT_DEF_H + +#include <arch.h> +/* + * Required without TBBR. + * To include the defines for DDR PHY Images. + */ +#include <tbbr_img_def.h> + +#include "policy.h" +#include <soc.h> + +#define NXP_SPD_EEPROM0 0x51 + +#define NXP_SYSCLK_FREQ 100000000 +#define NXP_DDRCLK_FREQ 100000000 + +/* UART related definition */ +#define NXP_CONSOLE_ADDR NXP_UART_ADDR +#define NXP_CONSOLE_BAUDRATE 115200 + +/* Size of cacheable stacks */ +#if defined(IMAGE_BL2) +#if defined(TRUSTED_BOARD_BOOT) +#define PLATFORM_STACK_SIZE 0x2000 +#else +#define PLATFORM_STACK_SIZE 0x1000 +#endif +#elif defined(IMAGE_BL31) +#define PLATFORM_STACK_SIZE 0x1000 +#endif + +/* SD block buffer */ +#define NXP_SD_BLOCK_BUF_SIZE (0x8000) +#define NXP_SD_BLOCK_BUF_ADDR ULL(0x80000000) + +#define BL2_LIMIT (NXP_OCRAM_ADDR + NXP_OCRAM_SIZE) + +/* IO defines as needed by IO driver framework */ +#define MAX_IO_DEVICES U(3) +#define MAX_IO_BLOCK_DEVICES U(1) +#define MAX_IO_HANDLES U(4) + +/* + * FIP image defines - Offset at which FIP Image would be present + * Image would include Bl31 , Bl33 and Bl32 (optional) + */ +#ifdef POLICY_FUSE_PROVISION +#define MAX_FIP_DEVICES U(2) +#endif + +#ifndef MAX_FIP_DEVICES +#define MAX_FIP_DEVICES U(1) +#endif + +/* + * ID of the secure physical generic timer interrupt used by the BL32. + */ +#define BL32_IRQ_SEC_PHY_TIMER 29 + +/* + * Define properties of Group 1 Secure and Group 0 interrupts as per GICv3 + * terminology. On a GICv2 system or mode, the lists will be merged and treated + * as Group 0 interrupts. + */ +#define PLAT_LS_G1S_IRQ_PROPS(grp) \ + INTR_PROP_DESC(BL32_IRQ_SEC_PHY_TIMER, GIC_HIGHEST_SEC_PRIORITY, grp, \ + GIC_INTR_CFG_LEVEL) + +#define PLAT_LS_G0_IRQ_PROPS(grp) + +#endif /* PLAT_DEF_H */ diff --git a/plat/nxp/soc-ls1046a/ls1046afrwy/platform.c b/plat/nxp/soc-ls1046a/ls1046afrwy/platform.c new file mode 100644 index 0000000..cef920f --- /dev/null +++ b/plat/nxp/soc-ls1046a/ls1046afrwy/platform.c @@ -0,0 +1,28 @@ +/* + * Copyright 2020-2022 NXP + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <plat_common.h> + +#pragma weak board_enable_povdd +#pragma weak board_disable_povdd + +bool board_enable_povdd(void) +{ +#ifdef CONFIG_POVDD_ENABLE + return true; +#else + return false; +#endif +} + +bool board_disable_povdd(void) +{ +#ifdef CONFIG_POVDD_ENABLE + return true; +#else + return false; +#endif +} diff --git a/plat/nxp/soc-ls1046a/ls1046afrwy/platform.mk b/plat/nxp/soc-ls1046a/ls1046afrwy/platform.mk new file mode 100644 index 0000000..1f7fad6 --- /dev/null +++ b/plat/nxp/soc-ls1046a/ls1046afrwy/platform.mk @@ -0,0 +1,39 @@ +# +# Copyright 2018-2022 NXP +# +# SPDX-License-Identifier: BSD-3-Clause +# + +# board-specific build parameters + +BOOT_MODE ?= qspi +BOARD := ls1046afrwy +POVDD_ENABLE := no + +# DDR Compilation Configs +CONFIG_STATIC_DDR := 0 +CONFIG_DDR_NODIMM := 1 +DDRC_NUM_DIMM := 0 +NUM_OF_DDRC := 1 +DDRC_NUM_CS := 1 +DDR_ECC_EN := yes + +# On-Board Flash Details +QSPI_FLASH_SZ := 0x20000000 +NOR_FLASH_SZ := 0x20000000 + +# Platform specific features. +WARM_BOOT := no + +# Adding Platform files build files +BL2_SOURCES += ${BOARD_PATH}/ddr_init.c\ + ${BOARD_PATH}/platform.c + +SUPPORTED_BOOT_MODE := qspi \ + sd + +# Adding platform board build info +include plat/nxp/common/plat_make_helper/plat_common_def.mk + +# Adding SoC build info +include plat/nxp/soc-ls1046a/soc.mk diff --git a/plat/nxp/soc-ls1046a/ls1046afrwy/platform_def.h b/plat/nxp/soc-ls1046a/ls1046afrwy/platform_def.h new file mode 100644 index 0000000..7f98bb1 --- /dev/null +++ b/plat/nxp/soc-ls1046a/ls1046afrwy/platform_def.h @@ -0,0 +1,13 @@ +/* + * Copyright 2018-2022 NXP + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef PLATFORM_DEF_H +#define PLATFORM_DEF_H + +#include <plat_def.h> +#include <plat_default_def.h> + +#endif /* PLATFORM_DEF_H */ diff --git a/plat/nxp/soc-ls1046a/ls1046afrwy/policy.h b/plat/nxp/soc-ls1046a/ls1046afrwy/policy.h new file mode 100644 index 0000000..c6c325f --- /dev/null +++ b/plat/nxp/soc-ls1046a/ls1046afrwy/policy.h @@ -0,0 +1,16 @@ +/* + * Copyright 2022 NXP + * + * SPDX-License-Identifier: BSD-3-Clause + * + */ + +#ifndef POLICY_H +#define POLICY_H + +/* Set this to 0x0 to leave the default SMMU page size in sACR + * Set this to 0x1 to change the SMMU page size to 64K + */ +#define POLICY_SMMU_PAGESZ_64K 0x1 + +#endif /* POLICY_H */ diff --git a/plat/nxp/soc-ls1046a/ls1046aqds/ddr_init.c b/plat/nxp/soc-ls1046a/ls1046aqds/ddr_init.c new file mode 100644 index 0000000..89c9c0a --- /dev/null +++ b/plat/nxp/soc-ls1046a/ls1046aqds/ddr_init.c @@ -0,0 +1,91 @@ +/* + * Copyright 2018-2022 NXP + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <assert.h> +#include <errno.h> + +#include <common/debug.h> +#include <ddr.h> +#include <lib/utils.h> + +#include <errata.h> +#include "platform_def.h" + +static const struct rc_timing rce[] = { + {U(1600), U(8), U(7)}, + {U(1867), U(8), U(7)}, + {U(2134), U(8), U(9)}, + {} +}; + +static const struct board_timing udimm[] = { + {U(0x04), rce, U(0x01020304), U(0x06070805)}, +}; + +int ddr_board_options(struct ddr_info *priv) +{ + int ret; + struct memctl_opt *popts = &priv->opt; + + if (popts->rdimm) { + debug("RDIMM parameters not set.\n"); + return -EINVAL; + } + + ret = cal_board_params(priv, udimm, ARRAY_SIZE(udimm)); + if (ret != 0) { + return ret; + } + + popts->wrlvl_override = U(1); + popts->wrlvl_sample = U(0x0); /* 32 clocks */ + popts->ddr_cdr1 = DDR_CDR1_DHC_EN | + DDR_CDR1_ODT(DDR_CDR_ODT_80ohm); + popts->ddr_cdr2 = DDR_CDR2_ODT(DDR_CDR_ODT_80ohm) | + DDR_CDR2_VREF_TRAIN_EN | + DDR_CDR2_VREF_RANGE_2; + + /* optimize cpo for erratum A-009942 */ + popts->cpo_sample = U(0x70); + + return 0; +} + +long long init_ddr(void) +{ + int spd_addr[] = { NXP_SPD_EEPROM0 }; + struct ddr_info info; + struct sysinfo sys; + long long dram_size; + + zeromem(&sys, sizeof(sys)); + if (get_clocks(&sys)) { + ERROR("System clocks are not set\n"); + assert(0); + } + debug("platform clock %lu\n", sys.freq_platform); + debug("DDR PLL1 %lu\n", sys.freq_ddr_pll0); + debug("DDR PLL2 %lu\n", sys.freq_ddr_pll1); + + zeromem(&info, sizeof(struct ddr_info)); + info.num_ctlrs = 1; + info.dimm_on_ctlr = 1; + info.clk = get_ddr_freq(&sys, 0); + info.spd_addr = spd_addr; + info.ddr[0] = (void *)NXP_DDR_ADDR; + + dram_size = dram_init(&info); + + if (dram_size < 0) { + ERROR("DDR init failed.\n"); + } + +#ifdef ERRATA_SOC_A008850 + erratum_a008850_post(); +#endif + + return dram_size; +} diff --git a/plat/nxp/soc-ls1046a/ls1046aqds/plat_def.h b/plat/nxp/soc-ls1046a/ls1046aqds/plat_def.h new file mode 100644 index 0000000..aa69a66 --- /dev/null +++ b/plat/nxp/soc-ls1046a/ls1046aqds/plat_def.h @@ -0,0 +1,79 @@ +/* + * Copyright 2018-2022 NXP + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef PLAT_DEF_H +#define PLAT_DEF_H + +#include <arch.h> +/* Required without TBBR. + * To include the defines for DDR PHY + * Images. + */ +#include <tbbr_img_def.h> + +#include <policy.h> +#include <soc.h> + +#define NXP_SPD_EEPROM0 0x51 + +#define NXP_SYSCLK_FREQ 100000000 +#define NXP_DDRCLK_FREQ 100000000 + +/* UART related definition */ +#define NXP_CONSOLE_ADDR NXP_UART_ADDR +#define NXP_CONSOLE_BAUDRATE 115200 + +/* Size of cacheable stacks */ +#if defined(IMAGE_BL2) +#if defined(TRUSTED_BOARD_BOOT) +#define PLATFORM_STACK_SIZE 0x2000 +#else +#define PLATFORM_STACK_SIZE 0x1000 +#endif +#elif defined(IMAGE_BL31) +#define PLATFORM_STACK_SIZE 0x1000 +#endif + +/* SD block buffer */ +#define NXP_SD_BLOCK_BUF_SIZE (0x00100000) +#define NXP_SD_BLOCK_BUF_ADDR ULL(0x80000000) + +#define BL2_LIMIT (NXP_OCRAM_ADDR + NXP_OCRAM_SIZE) + +/* IO defines as needed by IO driver framework */ +#define MAX_IO_DEVICES U(3) +#define MAX_IO_BLOCK_DEVICES U(1) +#define MAX_IO_HANDLES U(4) + +/* + * FIP image defines - Offset at which FIP Image would be present + * Image would include Bl31 , Bl33 and Bl32 (optional) + */ +#ifdef POLICY_FUSE_PROVISION +#define MAX_FIP_DEVICES U(2) +#endif + +#ifndef MAX_FIP_DEVICES +#define MAX_FIP_DEVICES U(1) +#endif + +/* + * ID of the secure physical generic timer interrupt used by the BL32. + */ +#define BL32_IRQ_SEC_PHY_TIMER 29 + +/* + * Define properties of Group 1 Secure and Group 0 interrupts as per GICv3 + * terminology. On a GICv2 system or mode, the lists will be merged and treated + * as Group 0 interrupts. + */ +#define PLAT_LS_G1S_IRQ_PROPS(grp) \ + INTR_PROP_DESC(BL32_IRQ_SEC_PHY_TIMER, GIC_HIGHEST_SEC_PRIORITY, grp, \ + GIC_INTR_CFG_LEVEL) + +#define PLAT_LS_G0_IRQ_PROPS(grp) + +#endif diff --git a/plat/nxp/soc-ls1046a/ls1046aqds/platform.c b/plat/nxp/soc-ls1046a/ls1046aqds/platform.c new file mode 100644 index 0000000..cef920f --- /dev/null +++ b/plat/nxp/soc-ls1046a/ls1046aqds/platform.c @@ -0,0 +1,28 @@ +/* + * Copyright 2020-2022 NXP + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <plat_common.h> + +#pragma weak board_enable_povdd +#pragma weak board_disable_povdd + +bool board_enable_povdd(void) +{ +#ifdef CONFIG_POVDD_ENABLE + return true; +#else + return false; +#endif +} + +bool board_disable_povdd(void) +{ +#ifdef CONFIG_POVDD_ENABLE + return true; +#else + return false; +#endif +} diff --git a/plat/nxp/soc-ls1046a/ls1046aqds/platform.mk b/plat/nxp/soc-ls1046a/ls1046aqds/platform.mk new file mode 100644 index 0000000..9600b93 --- /dev/null +++ b/plat/nxp/soc-ls1046a/ls1046aqds/platform.mk @@ -0,0 +1,39 @@ +# +# Copyright 2018-2022 NXP +# +# SPDX-License-Identifier: BSD-3-Clause +# + +# board-specific build parameters +BOOT_MODE ?= qspi +BOARD := ls1046aqds +POVDD_ENABLE := no + + # DDR Compilation Configs +NUM_OF_DDRC := 1 +DDRC_NUM_DIMM := 1 +DDRC_NUM_CS := 4 +DDR_ECC_EN := yes +CONFIG_STATIC_DDR := 0 + +# On-Board Flash Details +QSPI_FLASH_SZ := 0x20000000 +NOR_FLASH_SZ := 0x20000000 + +# Platform specific features. +WARM_BOOT := no + +# Adding Platform files build files +BL2_SOURCES += ${BOARD_PATH}/ddr_init.c\ + ${BOARD_PATH}/platform.c + +SUPPORTED_BOOT_MODE := qspi \ + sd \ + nor \ + nand + +# Adding platform board build info +include plat/nxp/common/plat_make_helper/plat_common_def.mk + +# Adding SoC build info +include plat/nxp/soc-ls1046a/soc.mk diff --git a/plat/nxp/soc-ls1046a/ls1046aqds/platform_def.h b/plat/nxp/soc-ls1046a/ls1046aqds/platform_def.h new file mode 100644 index 0000000..7f98bb1 --- /dev/null +++ b/plat/nxp/soc-ls1046a/ls1046aqds/platform_def.h @@ -0,0 +1,13 @@ +/* + * Copyright 2018-2022 NXP + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef PLATFORM_DEF_H +#define PLATFORM_DEF_H + +#include <plat_def.h> +#include <plat_default_def.h> + +#endif /* PLATFORM_DEF_H */ diff --git a/plat/nxp/soc-ls1046a/ls1046aqds/policy.h b/plat/nxp/soc-ls1046a/ls1046aqds/policy.h new file mode 100644 index 0000000..c6c325f --- /dev/null +++ b/plat/nxp/soc-ls1046a/ls1046aqds/policy.h @@ -0,0 +1,16 @@ +/* + * Copyright 2022 NXP + * + * SPDX-License-Identifier: BSD-3-Clause + * + */ + +#ifndef POLICY_H +#define POLICY_H + +/* Set this to 0x0 to leave the default SMMU page size in sACR + * Set this to 0x1 to change the SMMU page size to 64K + */ +#define POLICY_SMMU_PAGESZ_64K 0x1 + +#endif /* POLICY_H */ diff --git a/plat/nxp/soc-ls1046a/ls1046ardb/ddr_init.c b/plat/nxp/soc-ls1046a/ls1046ardb/ddr_init.c new file mode 100644 index 0000000..b9940cf --- /dev/null +++ b/plat/nxp/soc-ls1046a/ls1046ardb/ddr_init.c @@ -0,0 +1,267 @@ +/* + * Copyright 2018-2022 NXP + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <assert.h> +#include <errno.h> +#include <string.h> + +#include <common/debug.h> +#include <ddr.h> +#include <lib/utils.h> + +#include <errata.h> +#include <platform_def.h> + +#ifdef CONFIG_STATIC_DDR +const struct ddr_cfg_regs static_2100 = { + .cs[0].config = U(0x80040322), + .cs[0].bnds = U(0x1FF), + .cs[1].config = U(0x80000322), + .cs[1].bnds = U(0x1FF), + .sdram_cfg[0] = U(0xE5004000), + .sdram_cfg[1] = U(0x401151), + .timing_cfg[0] = U(0xD1770018), + .timing_cfg[1] = U(0xF2FC9245), + .timing_cfg[2] = U(0x594197), + .timing_cfg[3] = U(0x2101100), + .timing_cfg[4] = U(0x220002), + .timing_cfg[5] = U(0x5401400), + .timing_cfg[7] = U(0x26600000), + .timing_cfg[8] = U(0x5446A00), + .dq_map[0] = U(0x32C57554), + .dq_map[1] = U(0xD4BB0BD4), + .dq_map[2] = U(0x2EC2F554), + .dq_map[3] = U(0xD95D4001), + .sdram_mode[0] = U(0x3010631), + .sdram_mode[1] = U(0x100200), + .sdram_mode[9] = U(0x8400000), + .sdram_mode[8] = U(0x500), + .sdram_mode[2] = U(0x10631), + .sdram_mode[3] = U(0x100200), + .sdram_mode[10] = U(0x400), + .sdram_mode[11] = U(0x8400000), + .sdram_mode[4] = U(0x10631), + .sdram_mode[5] = U(0x100200), + .sdram_mode[12] = U(0x400), + .sdram_mode[13] = U(0x8400000), + .sdram_mode[6] = U(0x10631), + .sdram_mode[7] = U(0x100200), + .sdram_mode[14] = U(0x400), + .sdram_mode[15] = U(0x8400000), + .interval = U(0x1FFE07FF), + .zq_cntl = U(0x8A090705), + .clk_cntl = U(0x2000000), + .cdr[0] = U(0x80040000), + .cdr[1] = U(0xC1), + .wrlvl_cntl[0] = U(0x86750609), + .wrlvl_cntl[1] = U(0xA0B0C0D), + .wrlvl_cntl[2] = U(0xF10110E), +}; + +const struct ddr_cfg_regs static_1800 = { + .cs[0].config = U(0x80040322), + .cs[0].bnds = U(0x1FF), + .cs[1].config = U(0x80000322), + .cs[1].bnds = U(0x1FF), + .sdram_cfg[0] = U(0xE5004000), + .sdram_cfg[1] = U(0x401151), + .timing_cfg[0] = U(0x91660018), + .timing_cfg[1] = U(0xDDD82045), + .timing_cfg[2] = U(0x512153), + .timing_cfg[3] = U(0x10E1100), + .timing_cfg[4] = U(0x220002), + .timing_cfg[5] = U(0x4401400), + .timing_cfg[7] = U(0x14400000), + .timing_cfg[8] = U(0x3335900), + .dq_map[0] = U(0x32C57554), + .dq_map[1] = U(0xD4BB0BD4), + .dq_map[2] = U(0x2EC2F554), + .dq_map[3] = U(0xD95D4001), + .sdram_mode[0] = U(0x3010421), + .sdram_mode[1] = U(0x80200), + .sdram_mode[9] = U(0x4400000), + .sdram_mode[8] = U(0x500), + .sdram_mode[2] = U(0x10421), + .sdram_mode[3] = U(0x80200), + .sdram_mode[10] = U(0x400), + .sdram_mode[11] = U(0x4400000), + .sdram_mode[4] = U(0x10421), + .sdram_mode[5] = U(0x80200), + .sdram_mode[12] = U(0x400), + .sdram_mode[13] = U(0x4400000), + .sdram_mode[6] = U(0x10421), + .sdram_mode[7] = U(0x80200), + .sdram_mode[14] = U(0x400), + .sdram_mode[15] = U(0x4400000), + .interval = U(0x1B6C06DB), + .zq_cntl = U(0x8A090705), + .clk_cntl = U(0x2000000), + .cdr[0] = U(0x80040000), + .cdr[1] = U(0xC1), + .wrlvl_cntl[0] = U(0x86750607), + .wrlvl_cntl[1] = U(0x8090A0B), + .wrlvl_cntl[2] = U(0xD0E0F0C), +}; + +const struct ddr_cfg_regs static_1600 = { + .cs[0].config = U(0x80040322), + .cs[0].bnds = U(0x1FF), + .cs[1].config = U(0x80000322), + .cs[1].bnds = U(0x1FF), + .sdram_cfg[0] = U(0xE5004000), + .sdram_cfg[1] = U(0x401151), + .sdram_cfg[2] = U(0x0), + .timing_cfg[0] = U(0x91550018), + .timing_cfg[1] = U(0xBAB48E44), + .timing_cfg[2] = U(0x490111), + .timing_cfg[3] = U(0x10C1000), + .timing_cfg[4] = U(0x220002), + .timing_cfg[5] = U(0x3401400), + .timing_cfg[6] = U(0x0), + .timing_cfg[7] = U(0x13300000), + .timing_cfg[8] = U(0x1224800), + .timing_cfg[9] = U(0x0), + .dq_map[0] = U(0x32C57554), + .dq_map[1] = U(0xD4BB0BD4), + .dq_map[2] = U(0x2EC2F554), + .dq_map[3] = U(0xD95D4001), + .sdram_mode[0] = U(0x3010211), + .sdram_mode[1] = U(0x0), + .sdram_mode[9] = U(0x400000), + .sdram_mode[8] = U(0x500), + .sdram_mode[2] = U(0x10211), + .sdram_mode[3] = U(0x0), + .sdram_mode[10] = U(0x400), + .sdram_mode[11] = U(0x400000), + .sdram_mode[4] = U(0x10211), + .sdram_mode[5] = U(0x0), + .sdram_mode[12] = U(0x400), + .sdram_mode[13] = U(0x400000), + .sdram_mode[6] = U(0x10211), + .sdram_mode[7] = U(0x0), + .sdram_mode[14] = U(0x400), + .sdram_mode[15] = U(0x400000), + .interval = U(0x18600618), + .zq_cntl = U(0x8A090705), + .ddr_sr_cntr = U(0x0), + .clk_cntl = U(0x2000000), + .cdr[0] = U(0x80040000), + .cdr[1] = U(0xC1), + .wrlvl_cntl[0] = U(0x86750607), + .wrlvl_cntl[1] = U(0x8090A0B), + .wrlvl_cntl[2] = U(0xD0E0F0C), +}; + +struct static_table { + unsigned long rate; + const struct ddr_cfg_regs *regs; +}; + +const struct static_table table[] = { + {1600, &static_1600}, + {1800, &static_1800}, + {2100, &static_2100}, +}; + +long long board_static_ddr(struct ddr_info *priv) +{ + const unsigned long clk = priv->clk / 1000000; + long long size = 0; + int i; + + for (i = 0; i < ARRAY_SIZE(table); i++) { + if (table[i].rate >= clk) { + break; + } + } + if (i < ARRAY_SIZE(table)) { + VERBOSE("Found static setting for rate %ld\n", table[i].rate); + memcpy(&priv->ddr_reg, table[i].regs, + sizeof(struct ddr_cfg_regs)); + size = 0x200000000UL; + } else { + ERROR("Not static settings for rate %ld\n", clk); + } + + return size; +} +#else /* ifndef CONFIG_STATIC_DDR */ +static const struct rc_timing rce[] = { + {U(1600), U(8), U(7)}, + {U(1867), U(8), U(7)}, + {U(2134), U(8), U(9)}, + {} +}; + +static const struct board_timing udimm[] = { + {U(0x04), rce, U(0x01020304), U(0x06070805)}, + {U(0x1f), rce, U(0x01020304), U(0x06070805)}, +}; + +int ddr_board_options(struct ddr_info *priv) +{ + int ret; + struct memctl_opt *popts = &priv->opt; + + if (popts->rdimm) { + debug("RDIMM parameters not set.\n"); + return -EINVAL; + } + + ret = cal_board_params(priv, udimm, ARRAY_SIZE(udimm)); + if (ret != 0) { + return ret; + } + + popts->wrlvl_override = U(1); + popts->wrlvl_sample = U(0x0); /* 32 clocks */ + popts->cpo_sample = U(0x61); + popts->ddr_cdr1 = DDR_CDR1_DHC_EN | + DDR_CDR1_ODT(DDR_CDR_ODT_80ohm); + popts->ddr_cdr2 = DDR_CDR2_ODT(DDR_CDR_ODT_80ohm) | + DDR_CDR2_VREF_TRAIN_EN | + DDR_CDR2_VREF_RANGE_2; + popts->bstopre = U(0); + + return 0; +} +#endif /* ifdef CONFIG_STATIC_DDR */ + +long long init_ddr(void) +{ + int spd_addr[] = {NXP_SPD_EEPROM0}; + struct ddr_info info; + struct sysinfo sys; + long long dram_size; + + zeromem(&sys, sizeof(sys)); + if (get_clocks(&sys)) { + ERROR("System clocks are not set\n"); + assert(0); + } + debug("platform clock %lu\n", sys.freq_platform); + debug("DDR PLL1 %lu\n", sys.freq_ddr_pll0); + debug("DDR PLL2 %lu\n", sys.freq_ddr_pll1); + + zeromem(&info, sizeof(struct ddr_info)); + info.num_ctlrs = U(1); + info.dimm_on_ctlr = U(1); + info.clk = get_ddr_freq(&sys, 0); + info.spd_addr = spd_addr; + info.ddr[0] = (void *)NXP_DDR_ADDR; + + dram_size = dram_init(&info); + + if (dram_size < 0) { + ERROR("DDR init failed.\n"); + } + +#ifdef ERRATA_SOC_A008850 + erratum_a008850_post(); +#endif + + return dram_size; +} diff --git a/plat/nxp/soc-ls1046a/ls1046ardb/plat_def.h b/plat/nxp/soc-ls1046a/ls1046ardb/plat_def.h new file mode 100644 index 0000000..b5e66ae --- /dev/null +++ b/plat/nxp/soc-ls1046a/ls1046ardb/plat_def.h @@ -0,0 +1,79 @@ +/* + * Copyright 2018-2022 NXP + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef PLAT_DEF_H +#define PLAT_DEF_H + +#include <arch.h> +/* + * Required without TBBR. + * To include the defines for DDR PHY Images. + */ +#include <tbbr_img_def.h> + +#include "policy.h" +#include <soc.h> + +#define NXP_SPD_EEPROM0 0x51 + +#define NXP_SYSCLK_FREQ 100000000 +#define NXP_DDRCLK_FREQ 100000000 + +/* UART related definition */ +#define NXP_CONSOLE_ADDR NXP_UART_ADDR +#define NXP_CONSOLE_BAUDRATE 115200 + +/* Size of cacheable stacks */ +#if defined(IMAGE_BL2) +#if defined(TRUSTED_BOARD_BOOT) +#define PLATFORM_STACK_SIZE 0x2000 +#else +#define PLATFORM_STACK_SIZE 0x1000 +#endif +#elif defined(IMAGE_BL31) +#define PLATFORM_STACK_SIZE 0x1000 +#endif + +/* SD block buffer */ +#define NXP_SD_BLOCK_BUF_SIZE (0x00100000) +#define NXP_SD_BLOCK_BUF_ADDR ULL(0x80000000) + +#define BL2_LIMIT (NXP_OCRAM_ADDR + NXP_OCRAM_SIZE) + +/* IO defines as needed by IO driver framework */ +#define MAX_IO_DEVICES U(3) +#define MAX_IO_BLOCK_DEVICES U(1) +#define MAX_IO_HANDLES U(4) + +/* + * FIP image defines - Offset at which FIP Image would be present + * Image would include Bl31 , Bl33 and Bl32 (optional) + */ +#ifdef POLICY_FUSE_PROVISION +#define MAX_FIP_DEVICES U(2) +#endif + +#ifndef MAX_FIP_DEVICES +#define MAX_FIP_DEVICES U(1) +#endif + +/* + * ID of the secure physical generic timer interrupt used by the BL32. + */ +#define BL32_IRQ_SEC_PHY_TIMER 29 + +/* + * Define properties of Group 1 Secure and Group 0 interrupts as per GICv3 + * terminology. On a GICv2 system or mode, the lists will be merged and treated + * as Group 0 interrupts. + */ +#define PLAT_LS_G1S_IRQ_PROPS(grp) \ + INTR_PROP_DESC(BL32_IRQ_SEC_PHY_TIMER, GIC_HIGHEST_SEC_PRIORITY, grp, \ + GIC_INTR_CFG_LEVEL) + +#define PLAT_LS_G0_IRQ_PROPS(grp) + +#endif /* PLAT_DEF_H */ diff --git a/plat/nxp/soc-ls1046a/ls1046ardb/platform.c b/plat/nxp/soc-ls1046a/ls1046ardb/platform.c new file mode 100644 index 0000000..cef920f --- /dev/null +++ b/plat/nxp/soc-ls1046a/ls1046ardb/platform.c @@ -0,0 +1,28 @@ +/* + * Copyright 2020-2022 NXP + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <plat_common.h> + +#pragma weak board_enable_povdd +#pragma weak board_disable_povdd + +bool board_enable_povdd(void) +{ +#ifdef CONFIG_POVDD_ENABLE + return true; +#else + return false; +#endif +} + +bool board_disable_povdd(void) +{ +#ifdef CONFIG_POVDD_ENABLE + return true; +#else + return false; +#endif +} diff --git a/plat/nxp/soc-ls1046a/ls1046ardb/platform.mk b/plat/nxp/soc-ls1046a/ls1046ardb/platform.mk new file mode 100644 index 0000000..32e6db5 --- /dev/null +++ b/plat/nxp/soc-ls1046a/ls1046ardb/platform.mk @@ -0,0 +1,38 @@ +# +# Copyright 2018-2022 NXP +# +# SPDX-License-Identifier: BSD-3-Clause +# + +# board-specific build parameters +BOOT_MODE ?= qspi +BOARD := ls1046ardb +POVDD_ENABLE := no + +# DDR Compilation Configs +NUM_OF_DDRC := 1 +DDRC_NUM_DIMM := 1 +DDRC_NUM_CS := 4 +DDR_ECC_EN := yes +CONFIG_STATIC_DDR := 0 + +# On-Board Flash Details +QSPI_FLASH_SZ := 0x20000000 +NOR_FLASH_SZ := 0x20000000 + +# Platform specific features. +WARM_BOOT := no + +# Adding Platform files build files +BL2_SOURCES += ${BOARD_PATH}/ddr_init.c\ + ${BOARD_PATH}/platform.c + +SUPPORTED_BOOT_MODE := qspi \ + sd \ + emmc + +# Adding platform board build info +include plat/nxp/common/plat_make_helper/plat_common_def.mk + +# Adding SoC build info +include plat/nxp/soc-ls1046a/soc.mk diff --git a/plat/nxp/soc-ls1046a/ls1046ardb/platform_def.h b/plat/nxp/soc-ls1046a/ls1046ardb/platform_def.h new file mode 100644 index 0000000..7f98bb1 --- /dev/null +++ b/plat/nxp/soc-ls1046a/ls1046ardb/platform_def.h @@ -0,0 +1,13 @@ +/* + * Copyright 2018-2022 NXP + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef PLATFORM_DEF_H +#define PLATFORM_DEF_H + +#include <plat_def.h> +#include <plat_default_def.h> + +#endif /* PLATFORM_DEF_H */ diff --git a/plat/nxp/soc-ls1046a/ls1046ardb/policy.h b/plat/nxp/soc-ls1046a/ls1046ardb/policy.h new file mode 100644 index 0000000..c6c325f --- /dev/null +++ b/plat/nxp/soc-ls1046a/ls1046ardb/policy.h @@ -0,0 +1,16 @@ +/* + * Copyright 2022 NXP + * + * SPDX-License-Identifier: BSD-3-Clause + * + */ + +#ifndef POLICY_H +#define POLICY_H + +/* Set this to 0x0 to leave the default SMMU page size in sACR + * Set this to 0x1 to change the SMMU page size to 64K + */ +#define POLICY_SMMU_PAGESZ_64K 0x1 + +#endif /* POLICY_H */ diff --git a/plat/nxp/soc-ls1046a/soc.c b/plat/nxp/soc-ls1046a/soc.c new file mode 100644 index 0000000..6dfea89 --- /dev/null +++ b/plat/nxp/soc-ls1046a/soc.c @@ -0,0 +1,399 @@ +/* + * Copyright 2018-2022 NXP + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <assert.h> + +#include <arch.h> +#include <caam.h> +#include <cassert.h> +#include <cci.h> +#include <common/debug.h> +#include <dcfg.h> +#ifdef I2C_INIT +#include <i2c.h> +#endif +#include <lib/mmio.h> +#include <lib/xlat_tables/xlat_tables_v2.h> +#include <ls_interconnect.h> +#ifdef POLICY_FUSE_PROVISION +#include <nxp_gpio.h> +#endif +#include <nxp_smmu.h> +#include <nxp_timer.h> +#include <plat_console.h> +#include <plat_gic.h> +#include <plat_tzc400.h> +#include <scfg.h> +#if defined(NXP_SFP_ENABLED) +#include <sfp.h> +#endif + +#include <errata.h> +#include <ns_access.h> +#ifdef CONFIG_OCRAM_ECC_EN +#include <ocram.h> +#endif +#include <plat_common.h> +#include <platform_def.h> +#include <soc.h> + +static dcfg_init_info_t dcfg_init_data = { + .g_nxp_dcfg_addr = NXP_DCFG_ADDR, + .nxp_sysclk_freq = NXP_SYSCLK_FREQ, + .nxp_ddrclk_freq = NXP_DDRCLK_FREQ, + .nxp_plat_clk_divider = NXP_PLATFORM_CLK_DIVIDER, +}; + +/* Function to return the SoC SYS CLK */ +static unsigned int get_sys_clk(void) +{ + return NXP_SYSCLK_FREQ; +} + +/* + * Function returns the base counter frequency + * after reading the first entry at CNTFID0 (0x20 offset). + * + * Function is used by: + * 1. ARM common code for PSCI management. + * 2. ARM Generic Timer init. + * + */ +unsigned int plat_get_syscnt_freq2(void) +{ + unsigned int counter_base_frequency; + + counter_base_frequency = get_sys_clk() / 4; + + return counter_base_frequency; +} + +#ifdef IMAGE_BL2 +/* Functions for BL2 */ + +static struct soc_type soc_list[] = { + SOC_ENTRY(LS1046A, LS1046A, 1, 4), + SOC_ENTRY(LS1046AE, LS1046AE, 1, 4), + SOC_ENTRY(LS1026A, LS1026A, 1, 2), + SOC_ENTRY(LS1026AE, LS1026AE, 1, 2), +}; + +#ifdef POLICY_FUSE_PROVISION +static gpio_init_info_t gpio_init_data = { + .gpio1_base_addr = NXP_GPIO1_ADDR, + .gpio2_base_addr = NXP_GPIO2_ADDR, + .gpio3_base_addr = NXP_GPIO3_ADDR, + .gpio4_base_addr = NXP_GPIO4_ADDR, +}; +#endif + +/* + * Function to set the base counter frequency at + * the first entry of the Frequency Mode Table, + * at CNTFID0 (0x20 offset). + * + * Set the value of the pirmary core register cntfrq_el0. + */ +static void set_base_freq_CNTFID0(void) +{ + /* + * Below register specifies the base frequency of the system counter. + * As per NXP Board Manuals: + * The system counter always works with SYS_REF_CLK/4 frequency clock. + */ + unsigned int counter_base_frequency = get_sys_clk() / 4; + + /* Setting the frequency in the Frequency modes table. + * + * Note: The value for ls1046ardb board at this offset + * is not RW as stated. This offset have the + * fixed value of 100000400 Hz. + * + * The below code line has no effect. + * Keeping it for other platforms where it has effect. + */ + mmio_write_32(NXP_TIMER_ADDR + CNTFID_OFF, counter_base_frequency); + + write_cntfrq_el0(counter_base_frequency); +} + +void soc_preload_setup(void) +{ + +} + +/* + * This function implements soc specific erratas + * This is called before DDR is initialized or MMU is enabled + */ +void soc_early_init(void) +{ + uint8_t num_clusters, cores_per_cluster; + dram_regions_info_t *dram_regions_info = get_dram_regions_info(); + +#ifdef CONFIG_OCRAM_ECC_EN + ocram_init(NXP_OCRAM_ADDR, NXP_OCRAM_SIZE); +#endif + dcfg_init(&dcfg_init_data); +#ifdef POLICY_FUSE_PROVISION + gpio_init(&gpio_init_data); + sec_init(NXP_CAAM_ADDR); +#endif +#if LOG_LEVEL > 0 + /* Initialize the console to provide early debug support */ + + plat_console_init(NXP_CONSOLE_ADDR, + NXP_UART_CLK_DIVIDER, NXP_CONSOLE_BAUDRATE); +#endif + set_base_freq_CNTFID0(); + + /* Enable snooping on SEC read and write transactions */ + scfg_setbits32((void *)(NXP_SCFG_ADDR + SCFG_SNPCNFGCR_OFFSET), + SCFG_SNPCNFGCR_SECRDSNP | SCFG_SNPCNFGCR_SECWRSNP); + + /* + * Initialize Interconnect for this cluster during cold boot. + * No need for locks as no other CPU is active. + */ + cci_init(NXP_CCI_ADDR, cci_map, ARRAY_SIZE(cci_map)); + + /* + * Enable Interconnect coherency for the primary CPU's cluster. + */ + get_cluster_info(soc_list, ARRAY_SIZE(soc_list), &num_clusters, &cores_per_cluster); + plat_ls_interconnect_enter_coherency(num_clusters); + + /* + * Unlock write access for SMMU SMMU_CBn_ACTLR in all Non-secure contexts. + */ + smmu_cache_unlock(NXP_SMMU_ADDR); + INFO("SMMU Cache Unlocking is Configured.\n"); + +#if TRUSTED_BOARD_BOOT + uint32_t mode; + + sfp_init(NXP_SFP_ADDR); + /* + * For secure boot disable SMMU. + * Later when platform security policy comes in picture, + * this might get modified based on the policy + */ + if (check_boot_mode_secure(&mode) == true) { + bypass_smmu(NXP_SMMU_ADDR); + } + + /* + * For Mbedtls currently crypto is not supported via CAAM + * enable it when that support is there. In tbbr.mk + * the CAAM_INTEG is set as 0. + */ +#ifndef MBEDTLS_X509 + /* Initialize the crypto accelerator if enabled */ + if (is_sec_enabled() == false) { + INFO("SEC is disabled.\n"); + } else { + sec_init(NXP_CAAM_ADDR); + } +#endif +#elif defined(POLICY_FUSE_PROVISION) + gpio_init(&gpio_init_data); + sfp_init(NXP_SFP_ADDR); + sec_init(NXP_CAAM_ADDR); +#endif + + soc_errata(); + + /* Initialize system level generic timer for Layerscape Socs. */ + delay_timer_init(NXP_TIMER_ADDR); + +#ifdef DDR_INIT + i2c_init(NXP_I2C_ADDR); + dram_regions_info->total_dram_size = init_ddr(); +#endif +} + +void soc_bl2_prepare_exit(void) +{ +#if defined(NXP_SFP_ENABLED) && defined(DISABLE_FUSE_WRITE) + set_sfp_wr_disable(); +#endif +} + +/* This function returns the boot device based on RCW_SRC */ +enum boot_device get_boot_dev(void) +{ + enum boot_device src = BOOT_DEVICE_NONE; + uint32_t porsr1; + uint32_t rcw_src, val; + + porsr1 = read_reg_porsr1(); + + rcw_src = (porsr1 & PORSR1_RCW_MASK) >> PORSR1_RCW_SHIFT; + + val = rcw_src & RCW_SRC_NAND_MASK; + + if (val == RCW_SRC_NAND_VAL) { + val = rcw_src & NAND_RESERVED_MASK; + if ((val != NAND_RESERVED_1) && (val != NAND_RESERVED_2)) { + src = BOOT_DEVICE_IFC_NAND; + INFO("RCW BOOT SRC is IFC NAND\n"); + } + } else { + /* RCW SRC NOR */ + val = rcw_src & RCW_SRC_NOR_MASK; + if (val == NOR_8B_VAL || val == NOR_16B_VAL) { + src = BOOT_DEVICE_IFC_NOR; + INFO("RCW BOOT SRC is IFC NOR\n"); + } else { + switch (rcw_src) { + case QSPI_VAL1: + case QSPI_VAL2: + src = BOOT_DEVICE_QSPI; + INFO("RCW BOOT SRC is QSPI\n"); + break; + case SD_VAL: + src = BOOT_DEVICE_EMMC; + INFO("RCW BOOT SRC is SD/EMMC\n"); + break; + default: + src = BOOT_DEVICE_NONE; + } + } + } + + return src; +} + +/* This function sets up access permissions on memory regions */ +void soc_mem_access(void) +{ + dram_regions_info_t *info_dram_regions = get_dram_regions_info(); + struct tzc400_reg tzc400_reg_list[MAX_NUM_TZC_REGION]; + unsigned int dram_idx, index = 0U; + + for (dram_idx = 0U; dram_idx < info_dram_regions->num_dram_regions; + dram_idx++) { + if (info_dram_regions->region[dram_idx].size == 0) { + ERROR("DDR init failure, or"); + ERROR("DRAM regions not populated correctly.\n"); + break; + } + + index = populate_tzc400_reg_list(tzc400_reg_list, + dram_idx, index, + info_dram_regions->region[dram_idx].addr, + info_dram_regions->region[dram_idx].size, + NXP_SECURE_DRAM_SIZE, NXP_SP_SHRD_DRAM_SIZE); + } + + mem_access_setup(NXP_TZC_ADDR, index, tzc400_reg_list); +} + +#else /* IMAGE_BL2 */ +/* Functions for BL31 */ + +const unsigned char _power_domain_tree_desc[] = {1, 1, 4}; + +CASSERT(NUMBER_OF_CLUSTERS && NUMBER_OF_CLUSTERS <= 256, + assert_invalid_ls1046_cluster_count); + +/* This function returns the SoC topology */ +const unsigned char *plat_get_power_domain_tree_desc(void) +{ + return _power_domain_tree_desc; +} + +/* + * This function returns the core count within the cluster corresponding to + * `mpidr`. + */ +unsigned int plat_ls_get_cluster_core_count(u_register_t mpidr) +{ + return CORES_PER_CLUSTER; +} + +void soc_early_platform_setup2(void) +{ + dcfg_init(&dcfg_init_data); + /* Initialize system level generic timer for SoCs */ + delay_timer_init(NXP_TIMER_ADDR); + +#if LOG_LEVEL > 0 + /* Initialize the console to provide early debug support */ + plat_console_init(NXP_CONSOLE_ADDR, + NXP_UART_CLK_DIVIDER, NXP_CONSOLE_BAUDRATE); +#endif +} + +void soc_platform_setup(void) +{ + static uint32_t target_mask_array[PLATFORM_CORE_COUNT]; + /* + * On a GICv2 system, the Group 1 secure interrupts are treated + * as Group 0 interrupts. + */ + static interrupt_prop_t ls_interrupt_props[] = { + PLAT_LS_G1S_IRQ_PROPS(GICV2_INTR_GROUP0), + PLAT_LS_G0_IRQ_PROPS(GICV2_INTR_GROUP0) + }; + + plat_ls_gic_driver_init( +#if (TEST_BL31) + /* Defect in simulator - GIC base addresses (4Kb aligned) */ + NXP_GICD_4K_ADDR, + NXP_GICC_4K_ADDR, +#else + NXP_GICD_64K_ADDR, + NXP_GICC_64K_ADDR, +#endif + PLATFORM_CORE_COUNT, + ls_interrupt_props, + ARRAY_SIZE(ls_interrupt_props), + target_mask_array); + + plat_ls_gic_init(); + enable_init_timer(); +} + +/* This function initializes the soc from the BL31 module */ +void soc_init(void) +{ + /* low-level init of the soc */ + soc_init_lowlevel(); + _init_global_data(); + soc_init_percpu(); + _initialize_psci(); + + /* + * Initialize the interconnect during cold boot. + * No need for locks as no other CPU is active. + */ + cci_init(NXP_CCI_ADDR, cci_map, ARRAY_SIZE(cci_map)); + + /* + * Enable coherency in interconnect for the primary CPU's cluster. + * Earlier bootloader stages might already do this but we can't + * assume so. No harm in executing this code twice. + */ + cci_enable_snoop_dvm_reqs(MPIDR_AFFLVL1_VAL(read_mpidr())); + + /* Init CSU to enable non-secure access to peripherals */ + enable_layerscape_ns_access(ns_dev, ARRAY_SIZE(ns_dev), NXP_CSU_ADDR); + + /* Initialize the crypto accelerator if enabled */ + if (is_sec_enabled() == false) { + INFO("SEC is disabled.\n"); + } else { + sec_init(NXP_CAAM_ADDR); + } +} + +void soc_runtime_setup(void) +{ + +} + +#endif /* IMAGE_BL2 */ diff --git a/plat/nxp/soc-ls1046a/soc.def b/plat/nxp/soc-ls1046a/soc.def new file mode 100644 index 0000000..50fc9c9 --- /dev/null +++ b/plat/nxp/soc-ls1046a/soc.def @@ -0,0 +1,107 @@ +# +# Copyright 2022 NXP +# +# SPDX-License-Identifier: BSD-3-Clause +# +# +#------------------------------------------------------------------------------ +# +# This file contains the basic architecture definitions that drive the build +# +# ----------------------------------------------------------------------------- + +CORE_TYPE := a72 + +CACHE_LINE := 6 + +# set to GIC400 or GIC500 +GIC := GIC400 + +# set to CCI400 or CCN504 or CCN508 +INTERCONNECT := CCI400 + +# indicate layerscape chassis level - set to 3=LSCH3 or 2=LSCH2 +CHASSIS := 2 + +# TZC IP Details TZC used is TZC380 or TZC400 +TZC_ID := TZC400 + +# CONSOLE Details available is NS16550 or PL011 +CONSOLE := NS16550 + + # Select the DDR PHY generation to be used +PLAT_DDR_PHY := PHY_GEN1 + +PHYS_SYS := 64 + +# ddr controller - set to MMDC or NXP +DDRCNTLR := NXP + +# ddr phy - set to NXP or SNPS +DDRPHY := NXP + +# Area of OCRAM reserved by ROM code +NXP_ROM_RSVD := 0x8000 + +# Max Size of CSF header. Required to define BL2 TEXT LIMIT in soc.def +# Input to CST create_hdr_esbc tool +CSF_HDR_SZ := 0x4000 + +# In IMAGE_BL2, compile time flag for handling Cache coherency +# with CAAM for BL2 running from OCRAM +SEC_MEM_NON_COHERENT := yes + +# OCRAM MAP +OCRAM_START_ADDR := 0x10000000 +OCRAM_SIZE := 0x20000 + +# BL2 binary is placed at start of OCRAM. +# Also used by create_pbl.mk. +BL2_BASE := 0x10000000 + +# After BL2 bin, OCRAM is used by ROM Code: +# (OCRAM_START_ADDR + BL2_BIN_SIZE) -> (NXP_ROM_RSVD - 1) + +# After ROM Code, OCRAM is used by CSF header. +# (OCRAM_START_ADDR + BL2_TEXT_LIMIT + NXP_ROM_RSVD) -> (CSF_HDR_SZ - 1) + +# BL2_HDR_LOC has to be (OCRAM_START_ADDR + OCRAM_SIZE - NXP_ROM_RSVD - CSF_HDR_SZ) +# This value should be greater than BL2_TEXT_LIMIT +# Input to CST create_hdr_isbc tool +BL2_HDR_LOC_HDR ?= $(shell echo $$(( $(OCRAM_START_ADDR) + $(OCRAM_SIZE) - $(NXP_ROM_RSVD) - $(CSF_HDR_SZ)))) +# Covert to HEX to be used by create_pbl.mk +BL2_HDR_LOC := $$(echo "obase=16; ${BL2_HDR_LOC_HDR}" | bc) + +# Core Errata +ERRATA_A72_859971 := 1 + +# SoC ERRATAS +ERRATA_SOC_A008850 := 1 +ERRATA_SOC_A010539 := 1 + +# DDR Errata +ERRATA_DDR_A008511 := 1 +ERRATA_DDR_A009803 := 1 +ERRATA_DDR_A009942 := 1 +ERRATA_DDR_A010165 := 1 + +# enable dynamic memory mapping +PLAT_XLAT_TABLES_DYNAMIC := 1 + +# Define Endianness of each module +NXP_GUR_ENDIANNESS := BE +NXP_DDR_ENDIANNESS := BE +NXP_SEC_ENDIANNESS := BE +NXP_SFP_ENDIANNESS := BE +NXP_SNVS_ENDIANNESS := BE +NXP_ESDHC_ENDIANNESS := BE +NXP_QSPI_ENDIANNESS := BE +NXP_FSPI_ENDIANNESS := BE +NXP_SCFG_ENDIANNESS := BE +NXP_GPIO_ENDIANNESS := BE +NXP_IFC_ENDIANNESS := BE + +NXP_SFP_VER := 3_2 + +# OCRAM ECC Enabled +OCRAM_ECC_EN := yes diff --git a/plat/nxp/soc-ls1046a/soc.mk b/plat/nxp/soc-ls1046a/soc.mk new file mode 100644 index 0000000..7644027 --- /dev/null +++ b/plat/nxp/soc-ls1046a/soc.mk @@ -0,0 +1,114 @@ +# +# Copyright 2018-2022 NXP +# +# SPDX-License-Identifier: BSD-3-Clause +# + +# SoC-specific build parameters +SOC := ls1046a +PLAT_PATH := plat/nxp +PLAT_COMMON_PATH:= plat/nxp/common +PLAT_DRIVERS_PATH:= drivers/nxp +PLAT_SOC_PATH := ${PLAT_PATH}/soc-${SOC} +BOARD_PATH := ${PLAT_SOC_PATH}/${BOARD} + +# Get SoC-specific defnitions +include ${PLAT_SOC_PATH}/soc.def +include ${PLAT_COMMON_PATH}/plat_make_helper/soc_common_def.mk +include ${PLAT_COMMON_PATH}/plat_make_helper/plat_build_macros.mk + +# For Security Features +DISABLE_FUSE_WRITE := 1 +$(eval $(call SET_NXP_MAKE_FLAG,SMMU_NEEDED,BL2)) +ifeq (${TRUSTED_BOARD_BOOT}, 1) +$(eval $(call SET_NXP_MAKE_FLAG,SFP_NEEDED,BL2)) +$(eval $(call SET_NXP_MAKE_FLAG,SNVS_NEEDED,BL2)) +SECURE_BOOT := yes +endif +$(eval $(call SET_NXP_MAKE_FLAG,CRYPTO_NEEDED,BL_COMM)) + +# Selecting Drivers for SoC +$(eval $(call SET_NXP_MAKE_FLAG,DCFG_NEEDED,BL_COMM)) +$(eval $(call SET_NXP_MAKE_FLAG,CSU_NEEDED,BL_COMM)) +$(eval $(call SET_NXP_MAKE_FLAG,TIMER_NEEDED,BL_COMM)) +$(eval $(call SET_NXP_MAKE_FLAG,INTERCONNECT_NEEDED,BL_COMM)) +$(eval $(call SET_NXP_MAKE_FLAG,GIC_NEEDED,BL31)) +$(eval $(call SET_NXP_MAKE_FLAG,CONSOLE_NEEDED,BL_COMM)) +$(eval $(call SET_NXP_MAKE_FLAG,PMU_NEEDED,BL_COMM)) +$(eval $(call SET_NXP_MAKE_FLAG,DDR_DRIVER_NEEDED,BL2)) +$(eval $(call SET_NXP_MAKE_FLAG,TZASC_NEEDED,BL2)) +$(eval $(call SET_NXP_MAKE_FLAG,I2C_NEEDED,BL2)) +$(eval $(call SET_NXP_MAKE_FLAG,IMG_LOADR_NEEDED,BL2)) + +# Selecting PSCI & SIP_SVC support +$(eval $(call SET_NXP_MAKE_FLAG,PSCI_NEEDED,BL31)) +$(eval $(call SET_NXP_MAKE_FLAG,SIPSVC_NEEDED,BL31)) + +# Source File Addition +PLAT_INCLUDES += -I${PLAT_COMMON_PATH}/include/default\ + -I${BOARD_PATH}\ + -I${PLAT_COMMON_PATH}/include/default/ch_${CHASSIS}\ + -I${PLAT_SOC_PATH}/include\ + -I${PLAT_COMMON_PATH}/soc_errata + +ifeq (${SECURE_BOOT},yes) +include ${PLAT_COMMON_PATH}/tbbr/tbbr.mk +endif + +ifeq ($(WARM_BOOT),yes) +include ${PLAT_COMMON_PATH}/warm_reset/warm_reset.mk +endif + +ifeq (${NXP_NV_SW_MAINT_LAST_EXEC_DATA}, yes) +include ${PLAT_COMMON_PATH}/nv_storage/nv_storage.mk +endif + +ifeq (${PSCI_NEEDED}, yes) +include ${PLAT_COMMON_PATH}/psci/psci.mk +endif + +ifeq (${SIPSVC_NEEDED}, yes) +include ${PLAT_COMMON_PATH}/sip_svc/sipsvc.mk +endif + +# For fuse-fip & fuse-programming +ifeq (${FUSE_PROG}, 1) +include ${PLAT_COMMON_PATH}/fip_handler/fuse_fip/fuse.mk +endif + +ifeq (${IMG_LOADR_NEEDED},yes) +include $(PLAT_COMMON_PATH)/img_loadr/img_loadr.mk +endif + +# Adding source files for the above selected drivers. +include ${PLAT_DRIVERS_PATH}/drivers.mk + +# Adding SoC specific files +include ${PLAT_COMMON_PATH}/soc_errata/errata.mk + +PLAT_INCLUDES += ${NV_STORAGE_INCLUDES}\ + ${WARM_RST_INCLUDES} + +BL31_SOURCES += ${PLAT_SOC_PATH}/$(ARCH)/${SOC}.S\ + ${WARM_RST_BL31_SOURCES}\ + ${PSCI_SOURCES}\ + ${SIPSVC_SOURCES}\ + ${PLAT_COMMON_PATH}/$(ARCH)/bl31_data.S + +PLAT_BL_COMMON_SOURCES += ${PLAT_COMMON_PATH}/$(ARCH)/ls_helpers.S\ + ${PLAT_SOC_PATH}/aarch64/${SOC}_helpers.S\ + ${NV_STORAGE_SOURCES}\ + ${WARM_RST_BL_COMM_SOURCES}\ + ${PLAT_SOC_PATH}/soc.c + +ifeq (${TEST_BL31}, 1) +BL31_SOURCES += ${PLAT_SOC_PATH}/$(ARCH)/bootmain64.S\ + ${PLAT_SOC_PATH}/$(ARCH)/nonboot64.S +endif + +BL2_SOURCES += ${DDR_CNTLR_SOURCES}\ + ${TBBR_SOURCES}\ + ${FUSE_SOURCES} + +# Adding TFA setup files +include ${PLAT_PATH}/common/setup/common.mk |