GK SDK 源码库: XMIPCLinuxV100R005C00SPC030 (kernel/tools/open_source excluded)
This commit is contained in:
@@ -0,0 +1,603 @@
|
||||
config ARCH_LS1012A
|
||||
bool
|
||||
select ARMV8_SET_SMPEN
|
||||
select ARM_ERRATA_855873 if !TFABOOT
|
||||
select FSL_LAYERSCAPE
|
||||
select FSL_LSCH2
|
||||
select SYS_FSL_SRDS_1
|
||||
select SYS_HAS_SERDES
|
||||
select SYS_FSL_DDR_BE
|
||||
select SYS_FSL_MMDC
|
||||
select SYS_FSL_ERRATUM_A010315
|
||||
select SYS_FSL_ERRATUM_A009798
|
||||
select SYS_FSL_ERRATUM_A008997
|
||||
select SYS_FSL_ERRATUM_A009007
|
||||
select SYS_FSL_ERRATUM_A009008
|
||||
select ARCH_EARLY_INIT_R
|
||||
select BOARD_EARLY_INIT_F
|
||||
select SYS_I2C_MXC
|
||||
select SYS_I2C_MXC_I2C1
|
||||
select SYS_I2C_MXC_I2C2
|
||||
imply PANIC_HANG
|
||||
|
||||
config ARCH_LS1028A
|
||||
bool
|
||||
select ARMV8_SET_SMPEN
|
||||
select FSL_LSCH3
|
||||
select NXP_LSCH3_2
|
||||
select SYS_FSL_HAS_CCI400
|
||||
select SYS_FSL_SRDS_1
|
||||
select SYS_HAS_SERDES
|
||||
select SYS_FSL_DDR
|
||||
select SYS_FSL_DDR_LE
|
||||
select SYS_FSL_DDR_VER_50
|
||||
select SYS_FSL_HAS_DDR3
|
||||
select SYS_FSL_HAS_DDR4
|
||||
select SYS_FSL_HAS_SEC
|
||||
select SYS_FSL_SEC_COMPAT_5
|
||||
select SYS_FSL_SEC_LE
|
||||
select FSL_TZASC_1
|
||||
select ARCH_EARLY_INIT_R
|
||||
select BOARD_EARLY_INIT_F
|
||||
select SYS_I2C_MXC
|
||||
select SYS_FSL_ERRATUM_A008997
|
||||
select SYS_FSL_ERRATUM_A009007
|
||||
select SYS_FSL_ERRATUM_A008514 if !TFABOOT
|
||||
select SYS_FSL_ERRATUM_A009663 if !TFABOOT
|
||||
select SYS_FSL_ERRATUM_A009942 if !TFABOOT
|
||||
select SYS_FSL_ERRATUM_A050382
|
||||
imply PANIC_HANG
|
||||
|
||||
config ARCH_LS1043A
|
||||
bool
|
||||
select ARMV8_SET_SMPEN
|
||||
select ARM_ERRATA_855873 if !TFABOOT
|
||||
select FSL_LAYERSCAPE
|
||||
select FSL_LSCH2
|
||||
select SYS_FSL_SRDS_1
|
||||
select SYS_HAS_SERDES
|
||||
select SYS_FSL_DDR
|
||||
select SYS_FSL_DDR_BE
|
||||
select SYS_FSL_DDR_VER_50
|
||||
select SYS_FSL_ERRATUM_A008850 if !TFABOOT
|
||||
select SYS_FSL_ERRATUM_A008997
|
||||
select SYS_FSL_ERRATUM_A009007
|
||||
select SYS_FSL_ERRATUM_A009008
|
||||
select SYS_FSL_ERRATUM_A009660 if !TFABOOT
|
||||
select SYS_FSL_ERRATUM_A009663 if !TFABOOT
|
||||
select SYS_FSL_ERRATUM_A009798
|
||||
select SYS_FSL_ERRATUM_A009929
|
||||
select SYS_FSL_ERRATUM_A009942 if !TFABOOT
|
||||
select SYS_FSL_ERRATUM_A010315
|
||||
select SYS_FSL_ERRATUM_A010539
|
||||
select SYS_FSL_HAS_DDR3
|
||||
select SYS_FSL_HAS_DDR4
|
||||
select ARCH_EARLY_INIT_R
|
||||
select BOARD_EARLY_INIT_F
|
||||
select SYS_I2C_MXC
|
||||
select SYS_I2C_MXC_I2C1
|
||||
select SYS_I2C_MXC_I2C2
|
||||
select SYS_I2C_MXC_I2C3
|
||||
select SYS_I2C_MXC_I2C4
|
||||
imply CMD_PCI
|
||||
|
||||
config ARCH_LS1046A
|
||||
bool
|
||||
select ARMV8_SET_SMPEN
|
||||
select FSL_LAYERSCAPE
|
||||
select FSL_LSCH2
|
||||
select SYS_FSL_SRDS_1
|
||||
select SYS_HAS_SERDES
|
||||
select SYS_FSL_DDR
|
||||
select SYS_FSL_DDR_BE
|
||||
select SYS_FSL_DDR_VER_50
|
||||
select SYS_FSL_ERRATUM_A008336 if !TFABOOT
|
||||
select SYS_FSL_ERRATUM_A008511 if !TFABOOT
|
||||
select SYS_FSL_ERRATUM_A008850 if !TFABOOT
|
||||
select SYS_FSL_ERRATUM_A008997
|
||||
select SYS_FSL_ERRATUM_A009007
|
||||
select SYS_FSL_ERRATUM_A009008
|
||||
select SYS_FSL_ERRATUM_A009798
|
||||
select SYS_FSL_ERRATUM_A009801
|
||||
select SYS_FSL_ERRATUM_A009803 if !TFABOOT
|
||||
select SYS_FSL_ERRATUM_A009942 if !TFABOOT
|
||||
select SYS_FSL_ERRATUM_A010165 if !TFABOOT
|
||||
select SYS_FSL_ERRATUM_A010539
|
||||
select SYS_FSL_HAS_DDR4
|
||||
select SYS_FSL_SRDS_2
|
||||
select ARCH_EARLY_INIT_R
|
||||
select BOARD_EARLY_INIT_F
|
||||
select SYS_I2C_MXC
|
||||
select SYS_I2C_MXC_I2C1
|
||||
select SYS_I2C_MXC_I2C2
|
||||
select SYS_I2C_MXC_I2C3
|
||||
select SYS_I2C_MXC_I2C4
|
||||
imply SCSI
|
||||
imply SCSI_AHCI
|
||||
|
||||
config ARCH_LS1088A
|
||||
bool
|
||||
select ARMV8_SET_SMPEN
|
||||
select ARM_ERRATA_855873 if !TFABOOT
|
||||
select FSL_LAYERSCAPE
|
||||
select FSL_LSCH3
|
||||
select SYS_FSL_SRDS_1
|
||||
select SYS_HAS_SERDES
|
||||
select SYS_FSL_DDR
|
||||
select SYS_FSL_DDR_LE
|
||||
select SYS_FSL_DDR_VER_50
|
||||
select SYS_FSL_EC1
|
||||
select SYS_FSL_EC2
|
||||
select SYS_FSL_ERRATUM_A009803 if !TFABOOT
|
||||
select SYS_FSL_ERRATUM_A009942 if !TFABOOT
|
||||
select SYS_FSL_ERRATUM_A010165 if !TFABOOT
|
||||
select SYS_FSL_ERRATUM_A008511 if !TFABOOT
|
||||
select SYS_FSL_ERRATUM_A008850 if !TFABOOT
|
||||
select SYS_FSL_ERRATUM_A009007
|
||||
select SYS_FSL_HAS_CCI400
|
||||
select SYS_FSL_HAS_DDR4
|
||||
select SYS_FSL_HAS_RGMII
|
||||
select SYS_FSL_HAS_SEC
|
||||
select SYS_FSL_SEC_COMPAT_5
|
||||
select SYS_FSL_SEC_LE
|
||||
select SYS_FSL_SRDS_1
|
||||
select SYS_FSL_SRDS_2
|
||||
select FSL_TZASC_1
|
||||
select FSL_TZASC_400
|
||||
select FSL_TZPC_BP147
|
||||
select ARCH_EARLY_INIT_R
|
||||
select BOARD_EARLY_INIT_F
|
||||
select SYS_I2C_MXC
|
||||
select SYS_I2C_MXC_I2C1 if !TFABOOT
|
||||
select SYS_I2C_MXC_I2C2 if !TFABOOT
|
||||
select SYS_I2C_MXC_I2C3 if !TFABOOT
|
||||
select SYS_I2C_MXC_I2C4 if !TFABOOT
|
||||
imply SCSI
|
||||
imply PANIC_HANG
|
||||
|
||||
config ARCH_LS2080A
|
||||
bool
|
||||
select ARMV8_SET_SMPEN
|
||||
select ARM_ERRATA_826974
|
||||
select ARM_ERRATA_828024
|
||||
select ARM_ERRATA_829520
|
||||
select ARM_ERRATA_833471
|
||||
select FSL_LAYERSCAPE
|
||||
select FSL_LSCH3
|
||||
select SYS_FSL_SRDS_1
|
||||
select SYS_HAS_SERDES
|
||||
select SYS_FSL_DDR
|
||||
select SYS_FSL_DDR_LE
|
||||
select SYS_FSL_DDR_VER_50
|
||||
select SYS_FSL_HAS_CCN504
|
||||
select SYS_FSL_HAS_DP_DDR
|
||||
select SYS_FSL_HAS_SEC
|
||||
select SYS_FSL_HAS_DDR4
|
||||
select SYS_FSL_SEC_COMPAT_5
|
||||
select SYS_FSL_SEC_LE
|
||||
select SYS_FSL_SRDS_2
|
||||
select FSL_TZASC_1
|
||||
select FSL_TZASC_2
|
||||
select FSL_TZASC_400
|
||||
select FSL_TZPC_BP147
|
||||
select SYS_FSL_ERRATUM_A008336 if !TFABOOT
|
||||
select SYS_FSL_ERRATUM_A008511 if !TFABOOT
|
||||
select SYS_FSL_ERRATUM_A008514 if !TFABOOT
|
||||
select SYS_FSL_ERRATUM_A008585
|
||||
select SYS_FSL_ERRATUM_A008997
|
||||
select SYS_FSL_ERRATUM_A009007
|
||||
select SYS_FSL_ERRATUM_A009008
|
||||
select SYS_FSL_ERRATUM_A009635
|
||||
select SYS_FSL_ERRATUM_A009663 if !TFABOOT
|
||||
select SYS_FSL_ERRATUM_A009798
|
||||
select SYS_FSL_ERRATUM_A009801
|
||||
select SYS_FSL_ERRATUM_A009803 if !TFABOOT
|
||||
select SYS_FSL_ERRATUM_A009942 if !TFABOOT
|
||||
select SYS_FSL_ERRATUM_A010165 if !TFABOOT
|
||||
select SYS_FSL_ERRATUM_A009203
|
||||
select ARCH_EARLY_INIT_R
|
||||
select BOARD_EARLY_INIT_F
|
||||
select SYS_I2C_MXC
|
||||
select SYS_I2C_MXC_I2C1 if !TFABOOT
|
||||
select SYS_I2C_MXC_I2C2 if !TFABOOT
|
||||
select SYS_I2C_MXC_I2C3 if !TFABOOT
|
||||
select SYS_I2C_MXC_I2C4 if !TFABOOT
|
||||
imply DISTRO_DEFAULTS
|
||||
imply PANIC_HANG
|
||||
|
||||
config ARCH_LX2160A
|
||||
bool
|
||||
select ARMV8_SET_SMPEN
|
||||
select FSL_LSCH3
|
||||
select NXP_LSCH3_2
|
||||
select SYS_HAS_SERDES
|
||||
select SYS_FSL_SRDS_1
|
||||
select SYS_FSL_SRDS_2
|
||||
select SYS_NXP_SRDS_3
|
||||
select SYS_FSL_DDR
|
||||
select SYS_FSL_DDR_LE
|
||||
select SYS_FSL_DDR_VER_50
|
||||
select SYS_FSL_EC1
|
||||
select SYS_FSL_EC2
|
||||
select SYS_FSL_HAS_RGMII
|
||||
select SYS_FSL_HAS_SEC
|
||||
select SYS_FSL_HAS_CCN508
|
||||
select SYS_FSL_HAS_DDR4
|
||||
select SYS_FSL_SEC_COMPAT_5
|
||||
select SYS_FSL_SEC_LE
|
||||
select ARCH_EARLY_INIT_R
|
||||
select BOARD_EARLY_INIT_F
|
||||
select SYS_I2C_MXC
|
||||
imply DISTRO_DEFAULTS
|
||||
imply PANIC_HANG
|
||||
imply SCSI
|
||||
imply SCSI_AHCI
|
||||
|
||||
config FSL_LSCH2
|
||||
bool
|
||||
select SYS_FSL_HAS_CCI400
|
||||
select SYS_FSL_HAS_SEC
|
||||
select SYS_FSL_SEC_COMPAT_5
|
||||
select SYS_FSL_SEC_BE
|
||||
|
||||
config FSL_LSCH3
|
||||
bool
|
||||
|
||||
config NXP_LSCH3_2
|
||||
bool
|
||||
|
||||
menu "Layerscape architecture"
|
||||
depends on FSL_LSCH2 || FSL_LSCH3
|
||||
|
||||
config FSL_LAYERSCAPE
|
||||
bool
|
||||
|
||||
config FSL_PCIE_COMPAT
|
||||
string "PCIe compatible of Kernel DT"
|
||||
depends on PCIE_LAYERSCAPE || PCIE_LAYERSCAPE_GEN4
|
||||
default "fsl,ls1012a-pcie" if ARCH_LS1012A
|
||||
default "fsl,ls1028a-pcie" if ARCH_LS1028A
|
||||
default "fsl,ls1043a-pcie" if ARCH_LS1043A
|
||||
default "fsl,ls1046a-pcie" if ARCH_LS1046A
|
||||
default "fsl,ls2080a-pcie" if ARCH_LS2080A
|
||||
default "fsl,ls1088a-pcie" if ARCH_LS1088A
|
||||
default "fsl,lx2160a-pcie" if ARCH_LX2160A
|
||||
help
|
||||
This compatible is used to find pci controller node in Kernel DT
|
||||
to complete fixup.
|
||||
|
||||
config HAS_FEATURE_GIC64K_ALIGN
|
||||
bool
|
||||
default y if ARCH_LS1043A
|
||||
|
||||
config HAS_FEATURE_ENHANCED_MSI
|
||||
bool
|
||||
default y if ARCH_LS1043A
|
||||
|
||||
menu "Layerscape PPA"
|
||||
config FSL_LS_PPA
|
||||
bool "FSL Layerscape PPA firmware support"
|
||||
depends on !ARMV8_PSCI
|
||||
select ARMV8_SEC_FIRMWARE_SUPPORT
|
||||
select SEC_FIRMWARE_ARMV8_PSCI
|
||||
select ARMV8_SEC_FIRMWARE_ERET_ADDR_REVERT if FSL_LSCH2
|
||||
help
|
||||
The FSL Primary Protected Application (PPA) is a software component
|
||||
which is loaded during boot stage, and then remains resident in RAM
|
||||
and runs in the TrustZone after boot.
|
||||
Say y to enable it.
|
||||
|
||||
config SPL_FSL_LS_PPA
|
||||
bool "FSL Layerscape PPA firmware support for SPL build"
|
||||
depends on !ARMV8_PSCI
|
||||
select SPL_ARMV8_SEC_FIRMWARE_SUPPORT
|
||||
select SEC_FIRMWARE_ARMV8_PSCI
|
||||
select ARMV8_SEC_FIRMWARE_ERET_ADDR_REVERT if FSL_LSCH2
|
||||
help
|
||||
The FSL Primary Protected Application (PPA) is a software component
|
||||
which is loaded during boot stage, and then remains resident in RAM
|
||||
and runs in the TrustZone after boot. This is to load PPA during SPL
|
||||
stage instead of the RAM version of U-Boot. Once PPA is initialized,
|
||||
the rest of U-Boot (including RAM version) runs at EL2.
|
||||
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
|
||||
bool "XIP"
|
||||
help
|
||||
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 LS_PPA_ESBC_HDR_SIZE
|
||||
hex "Length of PPA ESBC header"
|
||||
depends on FSL_LS_PPA && CHAIN_OF_TRUST && !SYS_LS_PPA_FW_IN_XIP
|
||||
default 0x2000
|
||||
help
|
||||
Length (in bytes) of PPA ESBC header to be copied from MMC/SD or
|
||||
NAND to memory to validate PPA image.
|
||||
|
||||
endmenu
|
||||
|
||||
config SYS_FSL_ERRATUM_A008997
|
||||
bool "Workaround for USB PHY erratum A008997"
|
||||
|
||||
config SYS_FSL_ERRATUM_A009007
|
||||
bool
|
||||
help
|
||||
Workaround for USB PHY erratum A009007
|
||||
|
||||
config SYS_FSL_ERRATUM_A009008
|
||||
bool "Workaround for USB PHY erratum A009008"
|
||||
|
||||
config SYS_FSL_ERRATUM_A009798
|
||||
bool "Workaround for USB PHY erratum A009798"
|
||||
|
||||
config SYS_FSL_ERRATUM_A010315
|
||||
bool "Workaround for PCIe erratum A010315"
|
||||
|
||||
config SYS_FSL_ERRATUM_A010539
|
||||
bool "Workaround for PIN MUX erratum A010539"
|
||||
|
||||
config MAX_CPUS
|
||||
int "Maximum number of CPUs permitted for Layerscape"
|
||||
default 2 if ARCH_LS1028A
|
||||
default 4 if ARCH_LS1043A
|
||||
default 4 if ARCH_LS1046A
|
||||
default 16 if ARCH_LS2080A
|
||||
default 8 if ARCH_LS1088A
|
||||
default 16 if ARCH_LX2160A
|
||||
default 1
|
||||
help
|
||||
Set this number to the maximum number of possible CPUs in the SoC.
|
||||
SoCs may have multiple clusters with each cluster may have multiple
|
||||
ports. If some ports are reserved but higher ports are used for
|
||||
cores, count the reserved ports. This will allocate enough memory
|
||||
in spin table to properly handle all cores.
|
||||
|
||||
config EMC2305
|
||||
bool "Fan controller"
|
||||
help
|
||||
Enable the EMC2305 fan controller for configuration of fan
|
||||
speed.
|
||||
|
||||
config NXP_ESBC
|
||||
bool "NXP_ESBC"
|
||||
help
|
||||
Enable Freescale Secure Boot feature
|
||||
|
||||
config QSPI_AHB_INIT
|
||||
bool "Init the QSPI AHB bus"
|
||||
help
|
||||
The default setting for QSPI AHB bus just support 3bytes addressing.
|
||||
But some QSPI flash size up to 64MBytes, so initialize the QSPI AHB
|
||||
bus for those flashes to support the full QSPI flash size.
|
||||
|
||||
config SYS_CCI400_OFFSET
|
||||
hex "Offset for CCI400 base"
|
||||
depends on SYS_FSL_HAS_CCI400
|
||||
default 0x3090000 if ARCH_LS1088A || ARCH_LS1028A
|
||||
default 0x180000 if FSL_LSCH2
|
||||
help
|
||||
Offset for CCI400 base
|
||||
CCI400 base addr = CCSRBAR + CCI400_OFFSET
|
||||
|
||||
config SYS_FSL_IFC_BANK_COUNT
|
||||
int "Maximum banks of Integrated flash controller"
|
||||
depends on ARCH_LS1043A || ARCH_LS1046A || ARCH_LS2080A || ARCH_LS1088A
|
||||
default 4 if ARCH_LS1043A
|
||||
default 4 if ARCH_LS1046A
|
||||
default 8 if ARCH_LS2080A || ARCH_LS1088A
|
||||
|
||||
config SYS_FSL_HAS_CCI400
|
||||
bool
|
||||
|
||||
config SYS_FSL_HAS_CCN504
|
||||
bool
|
||||
|
||||
config SYS_FSL_HAS_CCN508
|
||||
bool
|
||||
|
||||
config SYS_FSL_HAS_DP_DDR
|
||||
bool
|
||||
|
||||
config SYS_FSL_SRDS_1
|
||||
bool
|
||||
|
||||
config SYS_FSL_SRDS_2
|
||||
bool
|
||||
|
||||
config SYS_NXP_SRDS_3
|
||||
bool
|
||||
|
||||
config SYS_HAS_SERDES
|
||||
bool
|
||||
|
||||
config FSL_TZASC_1
|
||||
bool
|
||||
|
||||
config FSL_TZASC_2
|
||||
bool
|
||||
|
||||
config FSL_TZASC_400
|
||||
bool
|
||||
|
||||
config FSL_TZPC_BP147
|
||||
bool
|
||||
endmenu
|
||||
|
||||
menu "Layerscape clock tree configuration"
|
||||
depends on FSL_LSCH2 || FSL_LSCH3
|
||||
|
||||
config SYS_FSL_CLK
|
||||
bool "Enable clock tree initialization"
|
||||
default y
|
||||
|
||||
config CLUSTER_CLK_FREQ
|
||||
int "Reference clock of core cluster"
|
||||
depends on ARCH_LS1012A
|
||||
default 100000000
|
||||
help
|
||||
This number is the reference clock frequency of core PLL.
|
||||
For most platforms, the core PLL and Platform PLL have the same
|
||||
reference clock, but for some platforms, LS1012A for instance,
|
||||
they are provided sepatately.
|
||||
|
||||
config SYS_FSL_PCLK_DIV
|
||||
int "Platform clock divider"
|
||||
default 1 if ARCH_LS1028A
|
||||
default 1 if ARCH_LS1043A
|
||||
default 1 if ARCH_LS1046A
|
||||
default 1 if ARCH_LS1088A
|
||||
default 2
|
||||
help
|
||||
This is the divider that is used to derive Platform clock from
|
||||
Platform PLL, in another word:
|
||||
Platform_clk = Platform_PLL_freq / this_divider
|
||||
|
||||
config SYS_FSL_DSPI_CLK_DIV
|
||||
int "DSPI clock divider"
|
||||
default 1 if ARCH_LS1043A
|
||||
default 2
|
||||
help
|
||||
This is the divider that is used to derive DSPI clock from Platform
|
||||
clock, in another word DSPI_clk = Platform_clk / this_divider.
|
||||
|
||||
config SYS_FSL_DUART_CLK_DIV
|
||||
int "DUART clock divider"
|
||||
default 1 if ARCH_LS1043A
|
||||
default 4 if ARCH_LX2160A
|
||||
default 2
|
||||
help
|
||||
This is the divider that is used to derive DUART clock from Platform
|
||||
clock, in another word DUART_clk = Platform_clk / this_divider.
|
||||
|
||||
config SYS_FSL_I2C_CLK_DIV
|
||||
int "I2C clock divider"
|
||||
default 1 if ARCH_LS1043A
|
||||
default 4 if ARCH_LS1012A
|
||||
default 4 if ARCH_LS1028A
|
||||
default 8 if ARCH_LX2160A
|
||||
default 8 if ARCH_LS1088A
|
||||
default 2
|
||||
help
|
||||
This is the divider that is used to derive I2C clock from Platform
|
||||
clock, in another word I2C_clk = Platform_clk / this_divider.
|
||||
|
||||
config SYS_FSL_IFC_CLK_DIV
|
||||
int "IFC clock divider"
|
||||
default 1 if ARCH_LS1043A
|
||||
default 4 if ARCH_LS1012A
|
||||
default 4 if ARCH_LS1028A
|
||||
default 8 if ARCH_LX2160A
|
||||
default 8 if ARCH_LS1088A
|
||||
default 2
|
||||
help
|
||||
This is the divider that is used to derive IFC clock from Platform
|
||||
clock, in another word IFC_clk = Platform_clk / this_divider.
|
||||
|
||||
config SYS_FSL_LPUART_CLK_DIV
|
||||
int "LPUART clock divider"
|
||||
default 1 if ARCH_LS1043A
|
||||
default 2
|
||||
help
|
||||
This is the divider that is used to derive LPUART clock from Platform
|
||||
clock, in another word LPUART_clk = Platform_clk / this_divider.
|
||||
|
||||
config SYS_FSL_SDHC_CLK_DIV
|
||||
int "SDHC clock divider"
|
||||
default 1 if ARCH_LS1043A
|
||||
default 1 if ARCH_LS1012A
|
||||
default 2
|
||||
help
|
||||
This is the divider that is used to derive SDHC clock from Platform
|
||||
clock, in another word SDHC_clk = Platform_clk / this_divider.
|
||||
|
||||
config SYS_FSL_QMAN_CLK_DIV
|
||||
int "QMAN clock divider"
|
||||
default 1 if ARCH_LS1043A
|
||||
default 2
|
||||
help
|
||||
This is the divider that is used to derive QMAN clock from Platform
|
||||
clock, in another word QMAN_clk = Platform_clk / this_divider.
|
||||
endmenu
|
||||
|
||||
config RESV_RAM
|
||||
bool
|
||||
help
|
||||
Reserve memory from the top, tracked by gd->arch.resv_ram. This
|
||||
reserved RAM can be used by special driver that resides in memory
|
||||
after U-Boot exits. It's up to implementation to allocate and allow
|
||||
access to this reserved memory. For example, the reserved RAM can
|
||||
be at the high end of physical memory. The reserve RAM may be
|
||||
excluded from memory bank(s) passed to OS, or marked as reserved.
|
||||
|
||||
config SYS_FSL_EC1
|
||||
bool
|
||||
help
|
||||
Ethernet controller 1, this is connected to
|
||||
MAC17 for LX2160A or to MAC3 for other SoCs
|
||||
Provides DPAA2 capabilities
|
||||
|
||||
config SYS_FSL_EC2
|
||||
bool
|
||||
help
|
||||
Ethernet controller 2, this is connected to
|
||||
MAC18 for LX2160A or to MAC4 for other SoCs
|
||||
Provides DPAA2 capabilities
|
||||
|
||||
config SYS_FSL_ERRATUM_A008336
|
||||
bool
|
||||
|
||||
config SYS_FSL_ERRATUM_A008514
|
||||
bool
|
||||
|
||||
config SYS_FSL_ERRATUM_A008585
|
||||
bool
|
||||
|
||||
config SYS_FSL_ERRATUM_A008850
|
||||
bool
|
||||
|
||||
config SYS_FSL_ERRATUM_A009203
|
||||
bool
|
||||
|
||||
config SYS_FSL_ERRATUM_A009635
|
||||
bool
|
||||
|
||||
config SYS_FSL_ERRATUM_A009660
|
||||
bool
|
||||
|
||||
config SYS_FSL_ERRATUM_A009929
|
||||
bool
|
||||
|
||||
config SYS_FSL_ERRATUM_A050382
|
||||
bool
|
||||
|
||||
config SYS_FSL_HAS_RGMII
|
||||
bool
|
||||
depends on SYS_FSL_EC1 || SYS_FSL_EC2
|
||||
|
||||
config SPL_LDSCRIPT
|
||||
default "arch/arm/cpu/armv8/u-boot-spl.lds" if ARCH_LS1043A || ARCH_LS1046A || ARCH_LS2080A
|
||||
|
||||
config HAS_FSL_XHCI_USB
|
||||
bool
|
||||
default y if ARCH_LS1043A || ARCH_LS1046A
|
||||
help
|
||||
For some SoC(such as LS1043A and LS1046A), USB and QE-HDLC multiplex use
|
||||
pins, select it when the pins are assigned to USB.
|
||||
@@ -0,0 +1,58 @@
|
||||
# SPDX-License-Identifier: GPL-2.0+
|
||||
# Copyright 2016-2018 NXP
|
||||
# Copyright 2014-2015, Freescale Semiconductor
|
||||
|
||||
obj-y += cpu.o
|
||||
obj-y += lowlevel.o
|
||||
obj-y += soc.o
|
||||
ifndef CONFIG_SPL_BUILD
|
||||
obj-$(CONFIG_MP) += mp.o
|
||||
obj-$(CONFIG_OF_LIBFDT) += fdt.o
|
||||
endif
|
||||
obj-$(CONFIG_SPL) += spl.o
|
||||
obj-$(CONFIG_$(SPL_)FSL_LS_PPA) += ppa.o
|
||||
|
||||
ifneq ($(CONFIG_FSL_LSCH3),)
|
||||
obj-y += fsl_lsch3_speed.o
|
||||
obj-$(CONFIG_SYS_HAS_SERDES) += fsl_lsch3_serdes.o
|
||||
else
|
||||
ifneq ($(CONFIG_FSL_LSCH2),)
|
||||
obj-y += fsl_lsch2_speed.o
|
||||
obj-$(CONFIG_SYS_HAS_SERDES) += fsl_lsch2_serdes.o
|
||||
endif
|
||||
endif
|
||||
|
||||
ifneq ($(CONFIG_ARCH_LX2160A),)
|
||||
obj-$(CONFIG_SYS_HAS_SERDES) += lx2160a_serdes.o
|
||||
obj-y += icid.o lx2160_ids.o
|
||||
endif
|
||||
|
||||
ifneq ($(CONFIG_ARCH_LS2080A),)
|
||||
obj-$(CONFIG_SYS_HAS_SERDES) += ls2080a_serdes.o
|
||||
obj-y += icid.o ls2088_ids.o
|
||||
endif
|
||||
|
||||
ifneq ($(CONFIG_ARCH_LS1043A),)
|
||||
obj-$(CONFIG_SYS_HAS_SERDES) += ls1043a_serdes.o
|
||||
obj-$(CONFIG_ARMV8_PSCI) += ls1043a_psci.o
|
||||
obj-y += icid.o ls1043_ids.o
|
||||
endif
|
||||
|
||||
ifneq ($(CONFIG_ARCH_LS1012A),)
|
||||
obj-$(CONFIG_SYS_HAS_SERDES) += ls1012a_serdes.o
|
||||
endif
|
||||
|
||||
ifneq ($(CONFIG_ARCH_LS1046A),)
|
||||
obj-$(CONFIG_SYS_HAS_SERDES) += ls1046a_serdes.o
|
||||
obj-y += icid.o ls1046_ids.o
|
||||
endif
|
||||
|
||||
ifneq ($(CONFIG_ARCH_LS1088A),)
|
||||
obj-$(CONFIG_SYS_HAS_SERDES) += ls1088a_serdes.o
|
||||
obj-y += icid.o ls1088_ids.o
|
||||
endif
|
||||
|
||||
ifneq ($(CONFIG_ARCH_LS1028A),)
|
||||
obj-$(CONFIG_SYS_HAS_SERDES) += ls1028a_serdes.o
|
||||
obj-y += icid.o ls1028_ids.o
|
||||
endif
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,8 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0+ */
|
||||
/*
|
||||
* Copyright 2014-2015, Freescale Semiconductor
|
||||
*/
|
||||
|
||||
int fsl_qoriq_core_to_cluster(unsigned int core);
|
||||
u32 initiator_type(u32 cluster, int init_id);
|
||||
u32 cpu_mask(void);
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
Core instruction prefetch disable
|
||||
---------------------------------
|
||||
To disable instruction prefetch of core; hwconfig needs to be updated.
|
||||
for e.g.
|
||||
setenv hwconfig 'fsl_ddr:bank_intlv=auto;core_prefetch:disable=0x02'
|
||||
|
||||
Here 0x02 can be replaced with any valid value except Mask[0] bit. It
|
||||
represents 64 bit mask. The 64-bit Mask has one bit for each core.
|
||||
Mask[0] = core0
|
||||
Mask[1] = core1
|
||||
Mask[2] = core2
|
||||
etc
|
||||
If the bit is set ('b1) in the mask, then prefetch is disabled for
|
||||
that core when it is released from reset.
|
||||
|
||||
core0 prefetch should not be disabled i.e. Mask[0] should never be set.
|
||||
Setting Mask[0] may lead to undefined behavior.
|
||||
|
||||
Once disabled, prefetch remains disabled until the next reset.
|
||||
There is no function to re-enable prefetch.
|
||||
@@ -0,0 +1,150 @@
|
||||
Falcon boot option
|
||||
------------------
|
||||
Falcon boot is a short cut boot method for SD/eMMC targets. It skips loading the
|
||||
RAM version U-Boot. Instead, it loads FIT image and boot directly to Linux.
|
||||
CONFIG_SPL_OS_BOOT enables falcon boot. CONFIG_SPL_LOAD_FIT enables the FIT
|
||||
image support (also need CONFIG_SPL_OF_LIBFDT, CONFIG_SPL_FIT and optionally
|
||||
CONFIG_SPL_GZIP).
|
||||
|
||||
To enable falcon boot, a hook function spl_start_uboot() returns 0 to indicate
|
||||
booting U-Boot is not the first choice. The kernel FIT image needs to be put
|
||||
at CONFIG_SYS_MMCSD_RAW_MODE_KERNEL_SECTOR. SPL mmc driver reads the header to
|
||||
determine if this is a FIT image. If true, FIT image components are parsed and
|
||||
copied or decompressed (if applicable) to their destinations. If FIT image is
|
||||
not found, normal U-Boot flow will follow.
|
||||
|
||||
An important part of falcon boot is to prepare the device tree. A normal U-Boot
|
||||
does FDT fixups when booting Linux. For falcon boot, Linux boots directly from
|
||||
SPL, skipping the normal U-Boot. The device tree has to be prepared in advance.
|
||||
A command "spl export" should be called under the normal RAM version U-Boot.
|
||||
It is equivalent to go through "bootm" step-by-step until device tree fixup is
|
||||
done. The device tree in memory is the one needed for falcon boot. Falcon boot
|
||||
flow suggests to save this image to SD/eMMC at the location pointed by macro
|
||||
CONFIG_SYS_MMCSD_RAW_MODE_ARGS_SECTOR, with maximum size specified by macro
|
||||
CONFIG_SYS_MMCSD_RAW_MODE_ARGS_SECTORS. However, when FIT image is used for
|
||||
Linux, the device tree stored in FIT image overwrites the memory loaded by spl
|
||||
driver from these sectors. We could change this loading order to favor the
|
||||
stored sectors. But when secure boot is enabled, these sectors are used for
|
||||
signature header and needs to be loaded before the FIT image. So it is important
|
||||
to understand the device tree in FIT image should be the one actually used, or
|
||||
leave it absent to favor the stored sectors. It is easier to deploy the FIT
|
||||
image with embedded static device tree to multiple boards.
|
||||
|
||||
Macro CONFIG_SYS_SPL_ARGS_ADDR serves two purposes. One is the pointer to load
|
||||
the stored sectors to. Normally this is the static device tree. The second
|
||||
purpose is the memory location of signature header for secure boot. After the
|
||||
FIT image is loaded into memory, it is validated against the signature header
|
||||
before individual components are extracted (and optionally decompressed) into
|
||||
their final memory locations, respectively. After the validation, the header
|
||||
is no longer used. The static device tree is copied into this location. So
|
||||
this macro is passed as the location of device tree when booting Linux.
|
||||
|
||||
Steps to prepare static device tree
|
||||
-----------------------------------
|
||||
To prepare the static device tree for Layerscape boards, it is important to
|
||||
understand the fixups in U-Boot. Memory size and location, as well as reserved
|
||||
memory blocks are added/updated. Ethernet MAC addressed are updated. FMan
|
||||
microcode (if used) is embedded in the device tree. Kernel command line and
|
||||
initrd information are embedded. Others including CPU status, boot method,
|
||||
Ethernet port status, etc. are also updated.
|
||||
|
||||
Following normal booting process, all variables are set, all images are loaded
|
||||
before "bootm" command would be issued to boot, run command
|
||||
|
||||
spl export fdt <address>
|
||||
|
||||
where the address is the location of FIT image. U-Boot goes through the booting
|
||||
process as if "bootm start", "bootm loados", "bootm ramdisk"... commands but
|
||||
stops before "bootm go". There we have the fixed-up device tree in memory.
|
||||
We can check the device tree header by these commands
|
||||
|
||||
fdt addr <fdt address>
|
||||
fdt header
|
||||
|
||||
Where the fdt address is the device tree in memory. It is printed by U-Boot.
|
||||
It is useful to know the exact size. One way to extract this static device
|
||||
tree is to save it to eMMC/SD using command in U-Boot, and extract under Linux
|
||||
with these commands, repectively
|
||||
|
||||
mmc write <address> <sector> <sectors>
|
||||
dd if=/dev/mmcblk0 of=<filename> bs=512 skip=<sector> count=<sectors>
|
||||
|
||||
Note, U-Boot takes values as hexadecimals while Linux takes them as decimals by
|
||||
default. If using NAND or other storage, the commands are slightly different.
|
||||
When we have the static device tree image, we can re-make the FIT image with
|
||||
it. It is important to specify the load addresses in FIT image for every
|
||||
components. Otherwise U-Boot cannot load them correctly.
|
||||
|
||||
Generate FIT image with static device tree
|
||||
------------------------------------------
|
||||
Example:
|
||||
|
||||
/dts-v1/;
|
||||
|
||||
/ {
|
||||
description = "Image file for the LS1043A Linux Kernel";
|
||||
#address-cells = <1>;
|
||||
|
||||
images {
|
||||
kernel {
|
||||
description = "ARM64 Linux kernel";
|
||||
data = /incbin/("./arch/arm64/boot/Image.gz");
|
||||
type = "kernel";
|
||||
arch = "arm64";
|
||||
os = "linux";
|
||||
compression = "gzip";
|
||||
load = <0x80080000>;
|
||||
entry = <0x80080000>;
|
||||
};
|
||||
fdt-1 {
|
||||
description = "Flattened Device Tree blob";
|
||||
data = /incbin/("./fsl-ls1043ardb-static.dtb");
|
||||
type = "flat_dt";
|
||||
arch = "arm64";
|
||||
compression = "none";
|
||||
load = <0x90000000>;
|
||||
};
|
||||
ramdisk {
|
||||
description = "LS1043 Ramdisk";
|
||||
data = /incbin/("./rootfs.cpio.gz");
|
||||
type = "ramdisk";
|
||||
arch = "arm64";
|
||||
os = "linux";
|
||||
compression = "none";
|
||||
load = <0xa0000000>;
|
||||
};
|
||||
};
|
||||
|
||||
configurations {
|
||||
default = "config-1";
|
||||
config-1 {
|
||||
description = "Boot Linux kernel";
|
||||
kernel = "kernel";
|
||||
fdt = "fdt-1";
|
||||
ramdisk = "ramdisk";
|
||||
loadables = "fdt", "ramdisk";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
The "loadables" is not optional. It tells SPL which images to load into memory.
|
||||
|
||||
Falcon mode with QSPI boot
|
||||
--------------------------
|
||||
To use falcon mode with QSPI boot, SPL needs to be enabled. Similar to SD or
|
||||
NAND boot, a RAM version full feature U-Boot is needed. Unlike SD or NAND boot,
|
||||
SPL with QSPI doesn't need to combine SPL image with RAM version image. Two
|
||||
separated images are used, u-boot-spl.pbl and u-boot.img. The former is SPL
|
||||
image with RCW and PBI commands to load the SPL payload into On-Chip RAM. The
|
||||
latter is RAM version U-Boot in FIT format (or legacy format if FIT is not
|
||||
used).
|
||||
|
||||
Other things to consider
|
||||
-----------------------
|
||||
Falcon boot skips a lot of initialization in U-Boot. If Linux expects the
|
||||
hardware to be initialized by U-Boot, the related code should be ported to SPL
|
||||
build. For example, if Linux expect Ethernet PHY to be initialized in U-Boot
|
||||
(which is not a common case), the PHY initialization has to be included in
|
||||
falcon boot. This increases the SPL image size and should be handled carefully.
|
||||
If Linux has PHY driver enabled, it still depends on the correct MDIO bus setup
|
||||
in U-Boot. Normal U-Boot sets the MDC ratio to generate a proper clock signal.
|
||||
@@ -0,0 +1,20 @@
|
||||
#
|
||||
# Copyright 2015 Freescale Semiconductor
|
||||
#
|
||||
# SPDX-License-Identifier: GPL-2.0+
|
||||
#
|
||||
|
||||
Freescale LayerScape with Chassis Generation 2
|
||||
|
||||
This architecture supports Freescale ARMv8 SoCs with Chassis generation 2,
|
||||
for example LS1043A.
|
||||
|
||||
Watchdog support Overview
|
||||
-------------------
|
||||
Support watchdog driver for LSCH2. The driver is disabled in default.
|
||||
You can enable it by setting CONFIG_IMX_WATCHDOG.
|
||||
Use following config to set watchdog timeout, if this config is not defined,
|
||||
the default timeout value is 128s which is the maximum. Set 10 seconds for
|
||||
example:
|
||||
Set CONFIG_WATCHDOG_RESET_DISABLE to disable reset watchdog, so that the
|
||||
watchdog will not be fed in u-boot.
|
||||
@@ -0,0 +1,400 @@
|
||||
#
|
||||
# Copyright 2014-2015 Freescale Semiconductor
|
||||
#
|
||||
# SPDX-License-Identifier: GPL-2.0+
|
||||
#
|
||||
|
||||
Freescale LayerScape with Chassis Generation 3
|
||||
|
||||
This architecture supports Freescale ARMv8 SoCs with Chassis generation 3,
|
||||
for example LS2080A.
|
||||
|
||||
DDR Layout
|
||||
============
|
||||
Entire DDR region splits into two regions.
|
||||
- Region 1 is at address 0x8000_0000 to 0xffff_ffff.
|
||||
- Region 2 is at 0x80_8000_0000 to the top of total memory,
|
||||
for example 16GB, 0x83_ffff_ffff.
|
||||
|
||||
All DDR memory is marked as cache-enabled.
|
||||
|
||||
When MC and Debug server is enabled, they carve 512MB away from the high
|
||||
end of DDR. For example, if the total DDR is 16GB, it shrinks to 15.5GB
|
||||
with MC and Debug server enabled. Linux only sees 15.5GB.
|
||||
|
||||
The reserved 512MB layout looks like
|
||||
|
||||
+---------------+ <-- top/end of memory
|
||||
| 256MB | debug server
|
||||
+---------------+
|
||||
| 256MB | MC
|
||||
+---------------+
|
||||
| ... |
|
||||
|
||||
MC requires the memory to be aligned with 512MB, so even debug server is
|
||||
not enabled, 512MB is reserved, not 256MB.
|
||||
|
||||
Flash Layout
|
||||
============
|
||||
|
||||
(1) A typical layout of various images (including Linux and other firmware images)
|
||||
is shown below considering a 32MB NOR flash device present on most
|
||||
pre-silicon platforms (simulator and emulator):
|
||||
|
||||
-------------------------
|
||||
| FIT Image |
|
||||
| (linux + DTB + RFS) |
|
||||
------------------------- ----> 0x0120_0000
|
||||
| Debug Server FW |
|
||||
------------------------- ----> 0x00C0_0000
|
||||
| AIOP FW |
|
||||
------------------------- ----> 0x0070_0000
|
||||
| MC FW |
|
||||
------------------------- ----> 0x006C_0000
|
||||
| MC DPL Blob |
|
||||
------------------------- ----> 0x0020_0000
|
||||
| BootLoader + Env|
|
||||
------------------------- ----> 0x0000_1000
|
||||
| PBI |
|
||||
------------------------- ----> 0x0000_0080
|
||||
| RCW |
|
||||
------------------------- ----> 0x0000_0000
|
||||
|
||||
32-MB NOR flash layout for pre-silicon platforms (simulator and emulator)
|
||||
|
||||
(2) A typical layout of various images (including Linux and other firmware images)
|
||||
is shown below considering a 128MB NOR flash device present on QDS and RDB
|
||||
boards:
|
||||
----------------------------------------- ----> 0x5_8800_0000 ---
|
||||
| .. Unused .. (7M) | |
|
||||
----------------------------------------- ----> 0x5_8790_0000 |
|
||||
| FIT Image (linux + DTB + RFS) (40M) | |
|
||||
----------------------------------------- ----> 0x5_8510_0000 |
|
||||
| PHY firmware (2M) | |
|
||||
----------------------------------------- ----> 0x5_84F0_0000 | 64K
|
||||
| Debug Server FW (2M) | | Alt
|
||||
----------------------------------------- ----> 0x5_84D0_0000 | Bank
|
||||
| AIOP FW (4M) | |
|
||||
----------------------------------------- ----> 0x5_8490_0000 (vbank4)
|
||||
| MC DPC Blob (1M) | |
|
||||
----------------------------------------- ----> 0x5_8480_0000 |
|
||||
| MC DPL Blob (1M) | |
|
||||
----------------------------------------- ----> 0x5_8470_0000 |
|
||||
| MC FW (4M) | |
|
||||
----------------------------------------- ----> 0x5_8430_0000 |
|
||||
| BootLoader Environment (1M) | |
|
||||
----------------------------------------- ----> 0x5_8420_0000 |
|
||||
| BootLoader (1M) | |
|
||||
----------------------------------------- ----> 0x5_8410_0000 |
|
||||
| RCW and PBI (1M) | |
|
||||
----------------------------------------- ----> 0x5_8400_0000 ---
|
||||
| .. Unused .. (7M) | |
|
||||
----------------------------------------- ----> 0x5_8390_0000 |
|
||||
| FIT Image (linux + DTB + RFS) (40M) | |
|
||||
----------------------------------------- ----> 0x5_8110_0000 |
|
||||
| PHY firmware (2M) | |
|
||||
----------------------------------------- ----> 0x5_80F0_0000 | 64K
|
||||
| Debug Server FW (2M) | | Bank
|
||||
----------------------------------------- ----> 0x5_80D0_0000 |
|
||||
| AIOP FW (4M) | |
|
||||
----------------------------------------- ----> 0x5_8090_0000 (vbank0)
|
||||
| MC DPC Blob (1M) | |
|
||||
----------------------------------------- ----> 0x5_8080_0000 |
|
||||
| MC DPL Blob (1M) | |
|
||||
----------------------------------------- ----> 0x5_8070_0000 |
|
||||
| MC FW (4M) | |
|
||||
----------------------------------------- ----> 0x5_8030_0000 |
|
||||
| BootLoader Environment (1M) | |
|
||||
----------------------------------------- ----> 0x5_8020_0000 |
|
||||
| BootLoader (1M) | |
|
||||
----------------------------------------- ----> 0x5_8010_0000 |
|
||||
| RCW and PBI (1M) | |
|
||||
----------------------------------------- ----> 0x5_8000_0000 ---
|
||||
|
||||
128-MB NOR flash layout for QDS and RDB boards
|
||||
|
||||
Environment Variables
|
||||
=====================
|
||||
mcboottimeout: MC boot timeout in milliseconds. If this variable is not defined
|
||||
the value CONFIG_SYS_LS_MC_BOOT_TIMEOUT_MS will be assumed.
|
||||
|
||||
mcmemsize: MC DRAM block size in hex. If this variable is not defined, the value
|
||||
CONFIG_SYS_LS_MC_DRAM_BLOCK_MIN_SIZE will be assumed.
|
||||
|
||||
mcinitcmd: This environment variable is defined to initiate MC and DPL deployment
|
||||
from the location where it is stored(NOR, NAND, SD, SATA, USB)during
|
||||
u-boot booting.If this variable is not defined then MC_BOOT_ENV_VAR
|
||||
will be null and MC will not be booted and DPL will not be applied
|
||||
during U-boot booting.However the MC, DPC and DPL can be applied from
|
||||
console independently.
|
||||
The variable needs to be set from the console once and then on
|
||||
rebooting the parameters set in the variable will automatically be
|
||||
executed. The commmand is demostrated taking an example of mc boot
|
||||
using NOR Flash i.e. MC, DPL, and DPC is stored in the NOR flash:
|
||||
|
||||
cp.b 0xa0000000 0x580300000 $filesize
|
||||
cp.b 0x80000000 0x580800000 $filesize
|
||||
cp.b 0x90000000 0x580700000 $filesize
|
||||
|
||||
setenv mcinitcmd 'fsl_mc start mc 0x580300000 0x580800000'
|
||||
|
||||
If only linux is to be booted then the mcinitcmd environment should be set as
|
||||
|
||||
setenv mcinitcmd 'fsl_mc start mc 0x580300000 0x580800000;fsl_mc apply DPL 0x580700000'
|
||||
|
||||
Here the addresses 0xa0000000, 0x80000000, 0x80000000 are of DDR to where
|
||||
MC binary, DPC binary and DPL binary are stored and 0x580300000, 0x580800000
|
||||
and 0x580700000 are addresses in NOR where these are copied. It is to be
|
||||
noted that these addresses in 'fsl_mc start mc 0x580300000 0x580800000;fsl_mc apply DPL 0x580700000'
|
||||
can be replaced with the addresses of DDR to
|
||||
which these will be copied in case of these binaries being stored in other
|
||||
devices like SATA, USB, NAND, SD etc.
|
||||
|
||||
Booting from NAND
|
||||
-------------------
|
||||
Booting from NAND requires two images, RCW and u-boot-with-spl.bin.
|
||||
The difference between NAND boot RCW image and NOR boot image is the PBI
|
||||
command sequence. Below is one example for PBI commands for LS2085AQDS which
|
||||
uses NAND device with 2KB/page, block size 128KB.
|
||||
|
||||
1) CCSR 4-byte write to 0x00e00404, data=0x00000000
|
||||
2) CCSR 4-byte write to 0x00e00400, data=0x1800a000
|
||||
The above two commands set bootloc register to 0x00000000_1800a000 where
|
||||
the u-boot code will be running in OCRAM.
|
||||
|
||||
3) Block Copy: SRC=0x0107, SRC_ADDR=0x00020000, DEST_ADDR=0x1800a000,
|
||||
BLOCK_SIZE=0x00014000
|
||||
This command copies u-boot image from NAND device into OCRAM. The values need
|
||||
to adjust accordingly.
|
||||
|
||||
SRC should match the cfg_rcw_src, the reset config pins. It depends
|
||||
on the NAND device. See reference manual for cfg_rcw_src.
|
||||
SRC_ADDR is the offset of u-boot-with-spl.bin image in NAND device. In
|
||||
the example above, 128KB. For easy maintenance, we put it at
|
||||
the beginning of next block from RCW.
|
||||
DEST_ADDR is fixed at 0x1800a000, matching bootloc set above.
|
||||
BLOCK_SIZE is the size to be copied by PBI.
|
||||
|
||||
RCW image should be written to the beginning of NAND device. Example of using
|
||||
u-boot command
|
||||
|
||||
nand write <rcw image in memory> 0 <size of rcw image>
|
||||
|
||||
To form the NAND image, build u-boot with NAND config, for example,
|
||||
ls2080aqds_nand_defconfig. The image needed is u-boot-with-spl.bin.
|
||||
The u-boot image should be written to match SRC_ADDR, in above example 0x20000.
|
||||
|
||||
nand write <u-boot image in memory> 200000 <size of u-boot image>
|
||||
|
||||
With these two images in NAND device, the board can boot from NAND.
|
||||
|
||||
Another example for LS2085ARDB boards,
|
||||
|
||||
1) CCSR 4-byte write to 0x00e00404, data=0x00000000
|
||||
2) CCSR 4-byte write to 0x00e00400, data=0x1800a000
|
||||
3) Block Copy: SRC=0x0119, SRC_ADDR=0x00080000, DEST_ADDR=0x1800a000,
|
||||
BLOCK_SIZE=0x00014000
|
||||
|
||||
nand write <rcw image in memory> 0 <size of rcw image>
|
||||
nand write <u-boot image in memory> 80000 <size of u-boot image>
|
||||
|
||||
Notice the difference from QDS is SRC, SRC_ADDR and the offset of u-boot image
|
||||
to match board NAND device with 4KB/page, block size 512KB.
|
||||
|
||||
Note, LS2088A and LS1088A don't support booting from NAND.
|
||||
|
||||
Booting from SD/eMMC
|
||||
-------------------
|
||||
Booting from SD/eMMC requires two images, RCW and u-boot-with-spl.bin.
|
||||
The difference between SD boot RCW image and QSPI-NOR boot image is the
|
||||
PBI command sequence. Below is one example for PBI commands for RDB
|
||||
and QDS which uses SD device with block size 512. Block location can be
|
||||
calculated by dividing offset with block size.
|
||||
|
||||
1) Block Copy: SRC=0x0040, SRC_ADDR=0x00100000, DEST_ADDR=0x1800a000,
|
||||
BLOCK_SIZE=0x00016000
|
||||
|
||||
This command copies u-boot image from SD device into OCRAM. The values
|
||||
need to adjust accordingly for SD/eMMC
|
||||
|
||||
SRC should match the cfg_rcw_src, the reset config pins.
|
||||
The value for source(SRC) can be 0x0040 or 0x0041
|
||||
depending upon SD or eMMC.
|
||||
SRC_ADDR is the offset of u-boot-with-spl.bin image in SD device.
|
||||
In the example above, 1MB. This is same as QSPI-NOR.
|
||||
DEST_ADDR is configured at 0x1800a000, matching bootloc set above.
|
||||
BLOCK_SIZE is the size to be copied by PBI.
|
||||
|
||||
2) CCSR 4-byte write to 0x01e00404, data=0x00000000
|
||||
3) CCSR 4-byte write to 0x01e00400, data=0x1800a000
|
||||
The above two commands set bootloc register to 0x00000000_1800a000 where
|
||||
the u-boot code will be running in OCRAM.
|
||||
|
||||
|
||||
RCW image should be written at 8th block of device(SD/eMMC). Example of
|
||||
using u-boot command
|
||||
|
||||
mmc erase 0x8 0x10
|
||||
mmc write <rcw image in memory> 0x8 <size of rcw in block count typical value=10>
|
||||
|
||||
To form the SD-Boot image, build u-boot with SD config, for example,
|
||||
ls1088ardb_sdcard_qspi_defconfig. The image needed is u-boot-with-spl.bin.
|
||||
The u-boot image should be written to match SRC_ADDR, in above example
|
||||
offset 0x100000 in other work it means block location 0x800
|
||||
|
||||
mmc erase 0x800 0x1800
|
||||
mmc write <u-boot image in memory> 0x800 <size of u-boot image in block count>
|
||||
|
||||
With these two images in SD/eMMC device, the board can boot from SD/eMMC.
|
||||
|
||||
MMU Translation Tables
|
||||
======================
|
||||
|
||||
(1) Early MMU Tables:
|
||||
|
||||
Level 0 Level 1 Level 2
|
||||
------------------ ------------------ ------------------
|
||||
| 0x00_0000_0000 | -----> | 0x00_0000_0000 | -----> | 0x00_0000_0000 |
|
||||
------------------ ------------------ ------------------
|
||||
| 0x80_0000_0000 | --| | 0x00_4000_0000 | | 0x00_0020_0000 |
|
||||
------------------ | ------------------ ------------------
|
||||
| invalid | | | 0x00_8000_0000 | | 0x00_0040_0000 |
|
||||
------------------ | ------------------ ------------------
|
||||
| | 0x00_c000_0000 | | 0x00_0060_0000 |
|
||||
| ------------------ ------------------
|
||||
| | 0x01_0000_0000 | | 0x00_0080_0000 |
|
||||
| ------------------ ------------------
|
||||
| ... ...
|
||||
| ------------------
|
||||
| | 0x05_8000_0000 | --|
|
||||
| ------------------ |
|
||||
| | 0x05_c000_0000 | |
|
||||
| ------------------ |
|
||||
| ... |
|
||||
| ------------------ | ------------------
|
||||
|--> | 0x80_0000_0000 | |-> | 0x00_3000_0000 |
|
||||
------------------ ------------------
|
||||
| 0x80_4000_0000 | | 0x00_3020_0000 |
|
||||
------------------ ------------------
|
||||
| 0x80_8000_0000 | | 0x00_3040_0000 |
|
||||
------------------ ------------------
|
||||
| 0x80_c000_0000 | | 0x00_3060_0000 |
|
||||
------------------ ------------------
|
||||
| 0x81_0000_0000 | | 0x00_3080_0000 |
|
||||
------------------ ------------------
|
||||
... ...
|
||||
|
||||
(2) Final MMU Tables:
|
||||
|
||||
Level 0 Level 1 Level 2
|
||||
------------------ ------------------ ------------------
|
||||
| 0x00_0000_0000 | -----> | 0x00_0000_0000 | -----> | 0x00_0000_0000 |
|
||||
------------------ ------------------ ------------------
|
||||
| 0x80_0000_0000 | --| | 0x00_4000_0000 | | 0x00_0020_0000 |
|
||||
------------------ | ------------------ ------------------
|
||||
| invalid | | | 0x00_8000_0000 | | 0x00_0040_0000 |
|
||||
------------------ | ------------------ ------------------
|
||||
| | 0x00_c000_0000 | | 0x00_0060_0000 |
|
||||
| ------------------ ------------------
|
||||
| | 0x01_0000_0000 | | 0x00_0080_0000 |
|
||||
| ------------------ ------------------
|
||||
| ... ...
|
||||
| ------------------
|
||||
| | 0x08_0000_0000 | --|
|
||||
| ------------------ |
|
||||
| | 0x08_4000_0000 | |
|
||||
| ------------------ |
|
||||
| ... |
|
||||
| ------------------ | ------------------
|
||||
|--> | 0x80_0000_0000 | |--> | 0x08_0000_0000 |
|
||||
------------------ ------------------
|
||||
| 0x80_4000_0000 | | 0x08_0020_0000 |
|
||||
------------------ ------------------
|
||||
| 0x80_8000_0000 | | 0x08_0040_0000 |
|
||||
------------------ ------------------
|
||||
| 0x80_c000_0000 | | 0x08_0060_0000 |
|
||||
------------------ ------------------
|
||||
| 0x81_0000_0000 | | 0x08_0080_0000 |
|
||||
------------------ ------------------
|
||||
... ...
|
||||
|
||||
|
||||
DPAA2 commands to manage Management Complex (MC)
|
||||
------------------------------------------------
|
||||
DPAA2 commands has been introduced to manage Management Complex
|
||||
(MC). These commands are used to start mc, aiop and apply DPL
|
||||
from u-boot command prompt.
|
||||
|
||||
Please note Management complex Firmware(MC), DPL and DPC are no
|
||||
more deployed during u-boot boot-sequence.
|
||||
|
||||
Commands:
|
||||
a) fsl_mc start mc <FW_addr> <DPC_addr> - Start Management Complex
|
||||
b) fsl_mc apply DPL <DPL_addr> - Apply DPL file
|
||||
c) fsl_mc start aiop <FW_addr> - Start AIOP
|
||||
|
||||
How to use commands :-
|
||||
1. Command sequence for u-boot ethernet:
|
||||
a) fsl_mc start mc <FW_addr> <DPC_addr> - Start Management Complex
|
||||
b) DPMAC net-devices are now available for use
|
||||
|
||||
Example-
|
||||
Assumption: MC firmware, DPL and DPC dtb is already programmed
|
||||
on NOR flash.
|
||||
|
||||
=> fsl_mc start mc 580300000 580800000
|
||||
=> setenv ethact DPMAC1@xgmii
|
||||
=> ping $serverip
|
||||
|
||||
2. Command sequence for Linux boot:
|
||||
a) fsl_mc start mc <FW_addr> <DPC_addr> - Start Management Complex
|
||||
b) fsl_mc apply DPL <DPL_addr> - Apply DPL file
|
||||
c) No DPMAC net-devices are available for use in u-boot
|
||||
d) boot Linux
|
||||
|
||||
Example-
|
||||
Assumption: MC firmware, DPL and DPC dtb is already programmed
|
||||
on NOR flash.
|
||||
|
||||
=> fsl_mc start mc 580300000 580800000
|
||||
=> setenv ethact DPMAC1@xgmii
|
||||
=> tftp a0000000 kernel.itb
|
||||
=> fsl_mc apply dpl 580700000
|
||||
=> bootm a0000000
|
||||
|
||||
3. Command sequence for AIOP boot:
|
||||
a) fsl_mc start mc <FW_addr> <DPC_addr> - Start Management Complex
|
||||
b) fsl_mc start aiop <FW_addr> - Start AIOP
|
||||
c) fsl_mc apply DPL <DPL_addr> - Apply DPL file
|
||||
d) No DPMAC net-devices are availabe for use in u-boot
|
||||
Please note actual AIOP start will happen during DPL parsing of
|
||||
Management complex
|
||||
|
||||
Example-
|
||||
Assumption: MC firmware, DPL, DPC dtb and AIOP firmware is already
|
||||
programmed on NOR flash.
|
||||
|
||||
=> fsl_mc start mc 580300000 580800000
|
||||
=> fsl_mc start aiop 0x580900000
|
||||
=> setenv ethact DPMAC1@xgmii
|
||||
=> fsl_mc apply dpl 580700000
|
||||
|
||||
Errata A009635
|
||||
---------------
|
||||
If the core runs at higher than x3 speed of the platform, there is
|
||||
possiblity about sev instruction to getting missed by other cores.
|
||||
This is because of SoC Run Control block may not able to sample
|
||||
the EVENTI(Sev) signals.
|
||||
|
||||
Workaround: Configure Run Control and EPU to periodically send out EVENTI signals to
|
||||
wake up A57 cores
|
||||
|
||||
Errata workaround uses Env variable "a009635_interval_val". It uses decimal
|
||||
value.
|
||||
- Default value of env variable is platform clock (MHz)
|
||||
|
||||
- User can modify default value by updating the env variable
|
||||
setenv a009635_interval_val 600; saveenv;
|
||||
It configure platform clock as 600 MHz
|
||||
|
||||
- Env variable as 0 signifies no workaround
|
||||
@@ -0,0 +1,27 @@
|
||||
#
|
||||
# Copyright 2018 NXP
|
||||
#
|
||||
# SPDX-License-Identifier: GPL-2.0+
|
||||
#
|
||||
|
||||
NXP LayerScape with Chassis Generation 3.2
|
||||
|
||||
This architecture supports NXP ARMv8 SoCs with Chassis generation 3.2
|
||||
for example LX2160A.
|
||||
|
||||
This architecture is enhancement over Chassis Generation 3 with
|
||||
few differences mentioned below
|
||||
|
||||
1)DDR Layout
|
||||
============
|
||||
Entire DDR region splits into three regions.
|
||||
- Region 1 is at address 0x8000_0000 to 0xffff_ffff.
|
||||
- Region 2 is at address 0x20_8000_0000 to 0x3f_ffff_ffff,
|
||||
- Region 3 is at address 0x60_0000_0000 to the top of memory,
|
||||
for example 140GB, 0x63_7fff_ffff.
|
||||
|
||||
All DDR memory is marked as cache-enabled.
|
||||
|
||||
2)IFC is removed
|
||||
|
||||
3)Number of I2C controllers increased to 8
|
||||
@@ -0,0 +1,42 @@
|
||||
QSPI Boot source support Overview
|
||||
-------------------
|
||||
1. LS1043A
|
||||
LS1043AQDS
|
||||
2. LS2080A
|
||||
LS2080AQDS
|
||||
3. LS1012A
|
||||
LS1012AQDS
|
||||
LS1012ARDB
|
||||
4. LS1046A
|
||||
LS1046AQDS
|
||||
LS1046ARDB
|
||||
|
||||
Booting from QSPI
|
||||
-------------------
|
||||
Booting from QSPI requires two images, RCW and u-boot-dtb.bin.
|
||||
The difference between QSPI boot RCW image and NOR boot image is the PBI
|
||||
command sequence for setting the boot location pointer. It's should point
|
||||
to the address for u-boot in QSPI flash.
|
||||
|
||||
RCW image should be written to the beginning of QSPI flash device.
|
||||
Example of using u-boot command
|
||||
|
||||
=> sf probe 0:0
|
||||
SF: Detected S25FL256S_64K with page size 256 Bytes, erase size 64 KiB, total 32 MiB
|
||||
=> sf erase 0 +<size of rcw image>
|
||||
SF: 65536 bytes @ 0x0 Erased: OK
|
||||
=> sf write <rcw image in memory> 0 <size of rcw image>
|
||||
SF: 164 bytes @ 0x0 Written: OK
|
||||
|
||||
To get the QSPI image, build u-boot with QSPI config, for example,
|
||||
<board_name>_qspi_defconfig. The image needed is u-boot-dtb.bin.
|
||||
The u-boot image should be written to 0x10000(but 0x1000 for LS1043A, LS2080A).
|
||||
|
||||
=> sf probe 0:0
|
||||
SF: Detected S25FL256S_64K with page size 256 Bytes, erase size 64 KiB, total 32 MiB
|
||||
=> sf erase 10000 +<size of u-boot image>
|
||||
SF: 589824 bytes @ 0x10000 Erased: OK
|
||||
=> sf write <u-boot image in memory> 10000 <size of u-boot image>
|
||||
SF: 580966 bytes @ 0x10000 Written: OK
|
||||
|
||||
With these two images in QSPI flash device, the board can boot from QSPI.
|
||||
@@ -0,0 +1,381 @@
|
||||
SoC overview
|
||||
|
||||
1. LS1043A
|
||||
2. LS1088A
|
||||
3. LS2080A
|
||||
4. LS1012A
|
||||
5. LS1046A
|
||||
6. LS2088A
|
||||
7. LS2081A
|
||||
8. LX2160A
|
||||
9. LS1028A
|
||||
|
||||
LS1043A
|
||||
---------
|
||||
The LS1043A integrated multicore processor combines four ARM Cortex-A53
|
||||
processor cores with datapath acceleration optimized for L2/3 packet
|
||||
processing, single pass security offload and robust traffic management
|
||||
and quality of service.
|
||||
|
||||
The LS1043A SoC includes the following function and features:
|
||||
- Four 64-bit ARM Cortex-A53 CPUs
|
||||
- 1 MB unified L2 Cache
|
||||
- One 32-bit DDR3L/DDR4 SDRAM memory controllers with ECC and interleaving
|
||||
support
|
||||
- Data Path Acceleration Architecture (DPAA) incorporating acceleration the
|
||||
the following functions:
|
||||
- Packet parsing, classification, and distribution (FMan)
|
||||
- Queue management for scheduling, packet sequencing, and congestion
|
||||
management (QMan)
|
||||
- Hardware buffer management for buffer allocation and de-allocation (BMan)
|
||||
- Cryptography acceleration (SEC)
|
||||
- Ethernet interfaces by FMan
|
||||
- Up to 1 x XFI supporting 10G interface
|
||||
- Up to 1 x QSGMII
|
||||
- Up to 4 x SGMII supporting 1000Mbps
|
||||
- Up to 2 x SGMII supporting 2500Mbps
|
||||
- Up to 2 x RGMII supporting 1000Mbps
|
||||
- High-speed peripheral interfaces
|
||||
- Three PCIe 2.0 controllers, one supporting x4 operation
|
||||
- One serial ATA (SATA 3.0) controllers
|
||||
- Additional peripheral interfaces
|
||||
- Three high-speed USB 3.0 controllers with integrated PHY
|
||||
- Enhanced secure digital host controller (eSDXC/eMMC)
|
||||
- Quad Serial Peripheral Interface (QSPI) Controller
|
||||
- Serial peripheral interface (SPI) controller
|
||||
- Four I2C controllers
|
||||
- Two DUARTs
|
||||
- Integrated flash controller supporting NAND and NOR flash
|
||||
- QorIQ platform's trust architecture 2.1
|
||||
|
||||
LS1088A
|
||||
--------
|
||||
The QorIQ LS1088A processor is built on the Layerscape
|
||||
architecture combining eight ARM A53 processor cores
|
||||
with advanced, high-performance datapath acceleration
|
||||
and networks, peripheral interfaces required for
|
||||
networking, wireless infrastructure, and general-purpose
|
||||
embedded applications.
|
||||
|
||||
LS1088A is compliant with the Layerscape Chassis Generation 3.
|
||||
|
||||
Features summary:
|
||||
- 8 32-bit / 64-bit ARM v8 Cortex-A53 CPUs
|
||||
- Cores are in 2 cluster of 4-cores each
|
||||
- 1MB L2 - Cache per cluster
|
||||
- Cache coherent interconnect (CCI-400)
|
||||
- 1 64-bit DDR4 SDRAM memory controller with ECC
|
||||
- Data path acceleration architecture 2.0 (DPAA2)
|
||||
- 4-Lane 10GHz SerDes comprising of WRIOP
|
||||
- 4-Lane 10GHz SerDes comprising of PCI, SATA, uQE(TDM/HLDC/UART)
|
||||
- Ethernet interfaces: SGMIIs, RGMIIs, QSGMIIs, XFIs
|
||||
- QSPI, SPI, IFC2.0 supporting NAND, NOR flash
|
||||
- 3 PCIe3.0 , 1 SATA3.0, 2 USB3.0, 1 SDXC, 2 DUARTs etc
|
||||
- 2 DUARTs
|
||||
- 4 I2C, GPIO
|
||||
- Thermal monitor unit(TMU)
|
||||
- 4 Flextimers and 1 generic timer
|
||||
- Support for hardware virtualization and partitioning enforcement
|
||||
- QorIQ platform's trust architecture 3.0
|
||||
- Service processor (SP) provides pre-boot initialization and secure-boot
|
||||
capabilities
|
||||
|
||||
LS2080A
|
||||
--------
|
||||
The LS2080A integrated multicore processor combines eight ARM Cortex-A57
|
||||
processor cores with high-performance data path acceleration logic and network
|
||||
and peripheral bus interfaces required for networking, telecom/datacom,
|
||||
wireless infrastructure, and mil/aerospace applications.
|
||||
|
||||
The LS2080A SoC includes the following function and features:
|
||||
|
||||
- Eight 64-bit ARM Cortex-A57 CPUs
|
||||
- 1 MB platform cache with ECC
|
||||
- Two 64-bit DDR4 SDRAM memory controllers with ECC and interleaving support
|
||||
- One secondary 32-bit DDR4 SDRAM memory controller, intended for use by
|
||||
the AIOP
|
||||
- Data path acceleration architecture (DPAA2) incorporating acceleration for
|
||||
the following functions:
|
||||
- Packet parsing, classification, and distribution (WRIOP)
|
||||
- Queue and Hardware buffer management for scheduling, packet sequencing, and
|
||||
congestion management, buffer allocation and de-allocation (QBMan)
|
||||
- Cryptography acceleration (SEC) at up to 10 Gbps
|
||||
- RegEx pattern matching acceleration (PME) at up to 10 Gbps
|
||||
- Decompression/compression acceleration (DCE) at up to 20 Gbps
|
||||
- Accelerated I/O processing (AIOP) at up to 20 Gbps
|
||||
- QDMA engine
|
||||
- 16 SerDes lanes at up to 10.3125 GHz
|
||||
- Ethernet interfaces
|
||||
- Up to eight 10 Gbps Ethernet MACs
|
||||
- Up to eight 1 / 2.5 Gbps Ethernet MACs
|
||||
- High-speed peripheral interfaces
|
||||
- Four PCIe 3.0 controllers, one supporting SR-IOV
|
||||
- Additional peripheral interfaces
|
||||
- Two serial ATA (SATA 3.0) controllers
|
||||
- Two high-speed USB 3.0 controllers with integrated PHY
|
||||
- Enhanced secure digital host controller (eSDXC/eMMC)
|
||||
- Serial peripheral interface (SPI) controller
|
||||
- Quad Serial Peripheral Interface (QSPI) Controller
|
||||
- Four I2C controllers
|
||||
- Two DUARTs
|
||||
- Integrated flash controller (IFC 2.0) supporting NAND and NOR flash
|
||||
- Support for hardware virtualization and partitioning enforcement
|
||||
- QorIQ platform's trust architecture 3.0
|
||||
- Service processor (SP) provides pre-boot initialization and secure-boot
|
||||
capabilities
|
||||
|
||||
LS1012A
|
||||
--------
|
||||
The LS1012A features an advanced 64-bit ARM v8 Cortex-
|
||||
A53 processor, with 32 KB of parity protected L1-I cache,
|
||||
32 KB of ECC protected L1-D cache, as well as 256 KB of
|
||||
ECC protected L2 cache.
|
||||
|
||||
The LS1012A SoC includes the following function and features:
|
||||
- One 64-bit ARM v8 Cortex-A53 core with the following capabilities:
|
||||
- ARM v8 cryptography extensions
|
||||
- One 16-bit DDR3L SDRAM memory controller, Up to 1.0 GT/s, Supports
|
||||
16-/8-bit operation (no ECC support)
|
||||
- ARM core-link CCI-400 cache coherent interconnect
|
||||
- Packet Forwarding Engine (PFE)
|
||||
- Cryptography acceleration (SEC)
|
||||
- Ethernet interfaces supported by PFE:
|
||||
- One Configurable x3 SerDes:
|
||||
Two Serdes PLLs supported for usage by any SerDes data lane
|
||||
Support for up to 6 GBaud operation
|
||||
- High-speed peripheral interfaces:
|
||||
- One PCI Express Gen2 controller, supporting x1 operation
|
||||
- One serial ATA (SATA Gen 3.0) controller
|
||||
- One USB 3.0/2.0 controller with integrated PHY
|
||||
- One USB 2.0 controller with ULPI interface. .
|
||||
- Additional peripheral interfaces:
|
||||
- One quad serial peripheral interface (QuadSPI) controller
|
||||
- One serial peripheral interface (SPI) controller
|
||||
- Two enhanced secure digital host controllers
|
||||
- Two I2C controllers
|
||||
- One 16550 compliant DUART (two UART interfaces)
|
||||
- Two general purpose IOs (GPIO)
|
||||
- Two FlexTimers
|
||||
- Five synchronous audio interfaces (SAI)
|
||||
- Pre-boot loader (PBL) provides pre-boot initialization and RCW loading
|
||||
- Single-source clocking solution enabling generation of core, platform,
|
||||
DDR, SerDes, and USB clocks from a single external crystal and internal
|
||||
crystaloscillator
|
||||
- Thermal monitor unit (TMU) with +/- 3C accuracy
|
||||
- Two WatchDog timers
|
||||
- ARM generic timer
|
||||
- QorIQ platform's trust architecture 2.1
|
||||
|
||||
LS1046A
|
||||
--------
|
||||
The LS1046A integrated multicore processor combines four ARM Cortex-A72
|
||||
processor cores with datapath acceleration optimized for L2/3 packet
|
||||
processing, single pass security offload and robust traffic management
|
||||
and quality of service.
|
||||
|
||||
The LS1046A SoC includes the following function and features:
|
||||
- Four 64-bit ARM Cortex-A72 CPUs
|
||||
- 2 MB unified L2 Cache
|
||||
- One 64-bit DDR4 SDRAM memory controllers with ECC and interleaving
|
||||
support
|
||||
- Data Path Acceleration Architecture (DPAA) incorporating acceleration the
|
||||
the following functions:
|
||||
- Packet parsing, classification, and distribution (FMan)
|
||||
- Queue management for scheduling, packet sequencing, and congestion
|
||||
management (QMan)
|
||||
- Hardware buffer management for buffer allocation and de-allocation (BMan)
|
||||
- Cryptography acceleration (SEC)
|
||||
- Two Configurable x4 SerDes
|
||||
- Two PLLs per four-lane SerDes
|
||||
- Support for 10G operation
|
||||
- Ethernet interfaces by FMan
|
||||
- Up to 2 x XFI supporting 10G interface (MAC 9, 10)
|
||||
- Up to 1 x QSGMII (MAC 5, 6, 10, 1)
|
||||
- Up to 4 x SGMII supporting 1000Mbps (MAC 5, 6, 9, 10)
|
||||
- Up to 3 x SGMII supporting 2500Mbps (MAC 5, 9, 10)
|
||||
- Up to 2 x RGMII supporting 1000Mbps (MAC 3, 4)
|
||||
- High-speed peripheral interfaces
|
||||
- Three PCIe 3.0 controllers, one supporting x4 operation
|
||||
- One serial ATA (SATA 3.0) controllers
|
||||
- Additional peripheral interfaces
|
||||
- Three high-speed USB 3.0 controllers with integrated PHY
|
||||
- Enhanced secure digital host controller (eSDXC/eMMC)
|
||||
- Quad Serial Peripheral Interface (QSPI) Controller
|
||||
- Serial peripheral interface (SPI) controller
|
||||
- Four I2C controllers
|
||||
- Two DUARTs
|
||||
- Integrated flash controller (IFC) supporting NAND and NOR flash
|
||||
- QorIQ platform's trust architecture 2.1
|
||||
|
||||
LS2088A
|
||||
--------
|
||||
The LS2088A integrated multicore processor combines eight ARM Cortex-A72
|
||||
processor cores with high-performance data path acceleration logic and network
|
||||
and peripheral bus interfaces required for networking, telecom/datacom,
|
||||
wireless infrastructure, and mil/aerospace applications.
|
||||
|
||||
The LS2088A SoC includes the following function and features:
|
||||
|
||||
- Eight 64-bit ARM Cortex-A72 CPUs
|
||||
- 1 MB platform cache with ECC
|
||||
- Two 64-bit DDR4 SDRAM memory controllers with ECC and interleaving support
|
||||
- One secondary 32-bit DDR4 SDRAM memory controller, intended for use by
|
||||
the AIOP
|
||||
- Data path acceleration architecture (DPAA2) incorporating acceleration for
|
||||
the following functions:
|
||||
- Packet parsing, classification, and distribution (WRIOP)
|
||||
- Queue and Hardware buffer management for scheduling, packet sequencing, and
|
||||
congestion management, buffer allocation and de-allocation (QBMan)
|
||||
- Cryptography acceleration (SEC) at up to 10 Gbps
|
||||
- RegEx pattern matching acceleration (PME) at up to 10 Gbps
|
||||
- Decompression/compression acceleration (DCE) at up to 20 Gbps
|
||||
- Accelerated I/O processing (AIOP) at up to 20 Gbps
|
||||
- QDMA engine
|
||||
- 16 SerDes lanes at up to 10.3125 GHz
|
||||
- Ethernet interfaces
|
||||
- Up to eight 10 Gbps Ethernet MACs
|
||||
- Up to eight 1 / 2.5 Gbps Ethernet MACs
|
||||
- High-speed peripheral interfaces
|
||||
- Four PCIe 3.0 controllers, one supporting SR-IOV
|
||||
- Additional peripheral interfaces
|
||||
- Two serial ATA (SATA 3.0) controllers
|
||||
- Two high-speed USB 3.0 controllers with integrated PHY
|
||||
- Enhanced secure digital host controller (eSDXC/eMMC)
|
||||
- Serial peripheral interface (SPI) controller
|
||||
- Quad Serial Peripheral Interface (QSPI) Controller
|
||||
- Four I2C controllers
|
||||
- Two DUARTs
|
||||
- Integrated flash controller (IFC 2.0) supporting NAND and NOR flash
|
||||
- Support for hardware virtualization and partitioning enforcement
|
||||
- QorIQ platform's trust architecture 3.0
|
||||
- Service processor (SP) provides pre-boot initialization and secure-boot
|
||||
capabilities
|
||||
|
||||
LS2088A SoC has 3 more similar SoC personalities
|
||||
1)LS2048A, few difference w.r.t. LS2088A:
|
||||
a) Four 64-bit ARM v8 Cortex-A72 CPUs
|
||||
|
||||
2)LS2084A, few difference w.r.t. LS2088A:
|
||||
a) No AIOP
|
||||
b) No 32-bit DDR3 SDRAM memory
|
||||
c) 5 * 1/10G + 5 *1G WRIOP
|
||||
d) No L2 switch
|
||||
|
||||
3)LS2044A, few difference w.r.t. LS2084A:
|
||||
a) Four 64-bit ARM v8 Cortex-A72 CPUs
|
||||
|
||||
LS2081A
|
||||
--------
|
||||
LS2081A is 40-pin derivative of LS2084A.
|
||||
So feature-wise it is same as LS2084A.
|
||||
Refer to LS2084A(LS2088A) section above for details.
|
||||
|
||||
It has one more similar SoC personality
|
||||
1)LS2041A, few difference w.r.t. LS2081A:
|
||||
a) Four 64-bit ARM v8 Cortex-A72 CPUs
|
||||
|
||||
LX2160A
|
||||
--------
|
||||
The QorIQ LX2160A processor is built in the 16FFC process on
|
||||
the Layerscape architecture combining sixteen ARM A72 processor
|
||||
cores with advanced, high-performance datapath acceleration and
|
||||
network, peripheral interfaces required for networking, wireless
|
||||
infrastructure, storage, and general-purpose embedded applications.
|
||||
|
||||
LX2160A is compliant with the Layerscape Chassis Generation 3.2.
|
||||
|
||||
The LX2160A SoC includes the following function and features:
|
||||
Sixteen 32-bit / 64-bit ARM v8 A72 CPUs
|
||||
Cache Coherent Interconnect Fabric (CCN508 aka “Eliot”)
|
||||
Two 64-bit 3.2GT/s DDR4 SDRAM memory controllers with ECC.
|
||||
Data path acceleration architecture (DPAA2)
|
||||
24 Serdes lanes at up to 25 GHz
|
||||
Ethernet interfaces
|
||||
Single WRIOP tile supporting 130Gbps using 18 MACs
|
||||
Support for 10G-SXGMII (aka USXGMII).
|
||||
Support for SGMII (and 1000Base-KX)
|
||||
Support for XFI (and 10GBase-KR)
|
||||
Support for CAUI4 (100G); CAUI2 (50G) and 25G-AUI(25G).
|
||||
Support for XLAUI (and 40GBase-KR4) for 40G.
|
||||
Support for two RGMII parallel interfaces.
|
||||
Energy efficient Ethernet support (802.3az)
|
||||
IEEE 1588 support.
|
||||
High-speed peripheral interfaces
|
||||
Two PCIe Gen 4.0 8-lane controllers supporting SR-IOV,
|
||||
Four PCIe Gen 4.0 4-lane controllers.
|
||||
Four serial ATA (SATA 3.0) controllers.
|
||||
Two USB 3.0 controllers with integrated PHY
|
||||
Two Enhanced secure digital host controllers
|
||||
Two Controller Area Network (CAN) modules
|
||||
Flexible Serial peripheral interface (FlexSPI) controller.
|
||||
Three Serial peripheral interface (SPI) controllers.
|
||||
Eight I2C Controllers.
|
||||
Four PL011 UARTs supporting two 4-pin UART ports or four 2-pin UART ports.
|
||||
General Purpose IO (GPIO)
|
||||
Support for hardware virtualization and partitioning (ARM MMU-500)
|
||||
Support for GIC (ARM GIC-500)
|
||||
QorIQ platform Trust Architecture 3.0
|
||||
One Secure WatchDog timer and one Non-Secure Watchdog timer.
|
||||
ARM Generic Timer
|
||||
Two Flextimers
|
||||
Debug supporting run control, data acquisition, high-speed trace,
|
||||
performance/event monitoring
|
||||
Thermal Monitor Unit (TMU) with +/- 2C accuracy
|
||||
Support for Voltage ID (VID) for yield improvement
|
||||
|
||||
LX2160A SoC has 2 more similar SoC personalities
|
||||
1)LX2120A, few difference w.r.t. LX2160A:
|
||||
a) Twelve 64-bit ARM v8 Cortex-A72 CPUs
|
||||
|
||||
2)LX2080A, few difference w.r.t. LX2160A:
|
||||
a) Eight 64-bit ARM v8 Cortex-A72 CPUs
|
||||
|
||||
|
||||
LS1028A
|
||||
--------
|
||||
The QorIQ LS1028A processor integrates two 64-bit Arm Cortex-A72 cores with
|
||||
a GPU and LCD controller, as well as two TSN-enabled Ethernet controllers and
|
||||
a TSNenabled 4-port switch.
|
||||
|
||||
The high performance Cortex-A72 cores, performing above 16,000 CoreMarks,
|
||||
combined with 2.5 Gbit Ethernet, PCI express Gen 3.0, SATA 3.0, USB 3.0 and
|
||||
Octal/Quad SPI interfaces provide capabilities for a number of industrial and
|
||||
embedded applications. The device provides excellent integration with the
|
||||
new Time-Sensitive Networking standard, and enables a number of
|
||||
TSN applications.
|
||||
|
||||
The LS1028A SoC includes the following function and features:
|
||||
- Two 64-bit ARM v8 A72 CPUs
|
||||
- Cache Coherent interconnect (CCI-400)
|
||||
- One 32-bit DDR3L/DDR4 SDRAM memory controller with ECC
|
||||
- eDP/Displayport interface
|
||||
- Graphics processing unit
|
||||
- One Configurable x4 SerDes
|
||||
- Ethernet interfaces
|
||||
- Non-switched: One Ethernet MAC supporting 2.5G, 1G, 100M, 10M, one
|
||||
ethernet MAC supporting 1G, 100M, 10M.
|
||||
- Switched: TSN IP to support four 2.5/1G interfaces.
|
||||
- None of the MACs support MACSEC
|
||||
- Support for RGMII, SGMII (and 1000Base-KX), SGMII 2.5x, QSGMII
|
||||
- Support for 10G-SXGMII and 10G-QXGMII.
|
||||
- Energy efficient Ethernet support (802.3az)
|
||||
- IEEE 1588 support
|
||||
- High-speed peripheral interfaces
|
||||
- Two PCIe 3.0 controllers, one supporting x4 operation
|
||||
- One serial ATA (SATA 3.0) controller
|
||||
- Additional peripheral interfaces
|
||||
- Two high-speed USB 2.0/3.0 controllers with integrated PHY each
|
||||
supporting host or device modes
|
||||
- Two Enhanced secure digital host controllers (SD/SDIO/eMMC)
|
||||
- Two Serial peripheral interface (SPI) controllers
|
||||
- Eight I2C controllers
|
||||
- Two UART controllers
|
||||
- Additional six Industrual UARTs (LPUART).
|
||||
- One FlexSPI controller
|
||||
- General Purpose IO (GPIO)
|
||||
- Two CAN-FD interfaces
|
||||
- Eight Flextimers with PWM I/O
|
||||
- Support for hardware virtualization and partitioning enforcement
|
||||
- Layerscape Trust Architecture
|
||||
- Service Processor (SP) provides pre-boot initialization and secure-boot
|
||||
capabilities
|
||||
@@ -0,0 +1,488 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Copyright 2014-2015 Freescale Semiconductor, Inc.
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <efi_loader.h>
|
||||
#include <linux/libfdt.h>
|
||||
#include <fdt_support.h>
|
||||
#include <phy.h>
|
||||
#ifdef CONFIG_FSL_LSCH3
|
||||
#include <asm/arch/fdt.h>
|
||||
#endif
|
||||
#ifdef CONFIG_FSL_ESDHC
|
||||
#include <fsl_esdhc.h>
|
||||
#endif
|
||||
#ifdef CONFIG_SYS_DPAA_FMAN
|
||||
#include <fsl_fman.h>
|
||||
#endif
|
||||
#ifdef CONFIG_MP
|
||||
#include <asm/arch/mp.h>
|
||||
#endif
|
||||
#include <fsl_sec.h>
|
||||
#include <asm/arch-fsl-layerscape/soc.h>
|
||||
#ifdef CONFIG_ARMV8_SEC_FIRMWARE_SUPPORT
|
||||
#include <asm/armv8/sec_firmware.h>
|
||||
#endif
|
||||
#include <asm/arch/speed.h>
|
||||
#include <fsl_qbman.h>
|
||||
|
||||
int fdt_fixup_phy_connection(void *blob, int offset, phy_interface_t phyc)
|
||||
{
|
||||
return fdt_setprop_string(blob, offset, "phy-connection-type",
|
||||
phy_string_for_interface(phyc));
|
||||
}
|
||||
|
||||
#ifdef CONFIG_MP
|
||||
void ft_fixup_cpu(void *blob)
|
||||
{
|
||||
int off;
|
||||
__maybe_unused u64 spin_tbl_addr = (u64)get_spin_tbl_addr();
|
||||
fdt32_t *reg;
|
||||
int addr_cells;
|
||||
u64 val, core_id;
|
||||
size_t *boot_code_size = &(__secondary_boot_code_size);
|
||||
u32 mask = cpu_pos_mask();
|
||||
int off_prev = -1;
|
||||
|
||||
off = fdt_path_offset(blob, "/cpus");
|
||||
if (off < 0) {
|
||||
puts("couldn't find /cpus node\n");
|
||||
return;
|
||||
}
|
||||
|
||||
fdt_support_default_count_cells(blob, off, &addr_cells, NULL);
|
||||
|
||||
off = fdt_node_offset_by_prop_value(blob, off_prev, "device_type",
|
||||
"cpu", 4);
|
||||
while (off != -FDT_ERR_NOTFOUND) {
|
||||
reg = (fdt32_t *)fdt_getprop(blob, off, "reg", 0);
|
||||
if (reg) {
|
||||
core_id = fdt_read_number(reg, addr_cells);
|
||||
if (!test_bit(id_to_core(core_id), &mask)) {
|
||||
fdt_del_node(blob, off);
|
||||
off = off_prev;
|
||||
}
|
||||
}
|
||||
off_prev = off;
|
||||
off = fdt_node_offset_by_prop_value(blob, off_prev,
|
||||
"device_type", "cpu", 4);
|
||||
}
|
||||
|
||||
#if defined(CONFIG_ARMV8_SEC_FIRMWARE_SUPPORT) && \
|
||||
defined(CONFIG_SEC_FIRMWARE_ARMV8_PSCI)
|
||||
int node;
|
||||
u32 psci_ver;
|
||||
|
||||
/* Check the psci version to determine if the psci is supported */
|
||||
psci_ver = sec_firmware_support_psci_version();
|
||||
if (psci_ver == 0xffffffff) {
|
||||
/* remove psci DT node */
|
||||
node = fdt_path_offset(blob, "/psci");
|
||||
if (node >= 0)
|
||||
goto remove_psci_node;
|
||||
|
||||
node = fdt_node_offset_by_compatible(blob, -1, "arm,psci");
|
||||
if (node >= 0)
|
||||
goto remove_psci_node;
|
||||
|
||||
node = fdt_node_offset_by_compatible(blob, -1, "arm,psci-0.2");
|
||||
if (node >= 0)
|
||||
goto remove_psci_node;
|
||||
|
||||
node = fdt_node_offset_by_compatible(blob, -1, "arm,psci-1.0");
|
||||
if (node >= 0)
|
||||
goto remove_psci_node;
|
||||
|
||||
remove_psci_node:
|
||||
if (node >= 0)
|
||||
fdt_del_node(blob, node);
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
off = fdt_path_offset(blob, "/cpus");
|
||||
if (off < 0) {
|
||||
puts("couldn't find /cpus node\n");
|
||||
return;
|
||||
}
|
||||
fdt_support_default_count_cells(blob, off, &addr_cells, NULL);
|
||||
|
||||
off = fdt_node_offset_by_prop_value(blob, -1, "device_type", "cpu", 4);
|
||||
while (off != -FDT_ERR_NOTFOUND) {
|
||||
reg = (fdt32_t *)fdt_getprop(blob, off, "reg", 0);
|
||||
if (reg) {
|
||||
core_id = fdt_read_number(reg, addr_cells);
|
||||
if (core_id == 0 || (is_core_online(core_id))) {
|
||||
val = spin_tbl_addr;
|
||||
val += id_to_core(core_id) *
|
||||
SPIN_TABLE_ELEM_SIZE;
|
||||
val = cpu_to_fdt64(val);
|
||||
fdt_setprop_string(blob, off, "enable-method",
|
||||
"spin-table");
|
||||
fdt_setprop(blob, off, "cpu-release-addr",
|
||||
&val, sizeof(val));
|
||||
} else {
|
||||
debug("skipping offline core\n");
|
||||
}
|
||||
} else {
|
||||
puts("Warning: found cpu node without reg property\n");
|
||||
}
|
||||
off = fdt_node_offset_by_prop_value(blob, off, "device_type",
|
||||
"cpu", 4);
|
||||
}
|
||||
|
||||
fdt_add_mem_rsv(blob, (uintptr_t)&secondary_boot_code,
|
||||
*boot_code_size);
|
||||
#if CONFIG_IS_ENABLED(EFI_LOADER)
|
||||
efi_add_memory_map((uintptr_t)&secondary_boot_code,
|
||||
ALIGN(*boot_code_size, EFI_PAGE_SIZE) >> EFI_PAGE_SHIFT,
|
||||
EFI_RESERVED_MEMORY_TYPE, false);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
void fsl_fdt_disable_usb(void *blob)
|
||||
{
|
||||
int off;
|
||||
/*
|
||||
* SYSCLK is used as a reference clock for USB. When the USB
|
||||
* controller is used, SYSCLK must meet the additional requirement
|
||||
* of 100 MHz.
|
||||
*/
|
||||
if (CONFIG_SYS_CLK_FREQ != 100000000) {
|
||||
off = fdt_node_offset_by_compatible(blob, -1, "snps,dwc3");
|
||||
while (off != -FDT_ERR_NOTFOUND) {
|
||||
fdt_status_disabled(blob, off);
|
||||
off = fdt_node_offset_by_compatible(blob, off,
|
||||
"snps,dwc3");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef CONFIG_HAS_FEATURE_GIC64K_ALIGN
|
||||
static void fdt_fixup_gic(void *blob)
|
||||
{
|
||||
int offset, err;
|
||||
u64 reg[8];
|
||||
struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR);
|
||||
unsigned int val;
|
||||
struct ccsr_scfg __iomem *scfg = (void *)CONFIG_SYS_FSL_SCFG_ADDR;
|
||||
int align_64k = 0;
|
||||
|
||||
val = gur_in32(&gur->svr);
|
||||
|
||||
if (!IS_SVR_DEV(val, SVR_DEV(SVR_LS1043A))) {
|
||||
align_64k = 1;
|
||||
} else if (SVR_REV(val) != REV1_0) {
|
||||
val = scfg_in32(&scfg->gic_align) & (0x01 << GIC_ADDR_BIT);
|
||||
if (!val)
|
||||
align_64k = 1;
|
||||
}
|
||||
|
||||
offset = fdt_subnode_offset(blob, 0, "interrupt-controller@1400000");
|
||||
if (offset < 0) {
|
||||
printf("WARNING: fdt_subnode_offset can't find node %s: %s\n",
|
||||
"interrupt-controller@1400000", fdt_strerror(offset));
|
||||
return;
|
||||
}
|
||||
|
||||
/* Fixup gic node align with 64K */
|
||||
if (align_64k) {
|
||||
reg[0] = cpu_to_fdt64(GICD_BASE_64K);
|
||||
reg[1] = cpu_to_fdt64(GICD_SIZE_64K);
|
||||
reg[2] = cpu_to_fdt64(GICC_BASE_64K);
|
||||
reg[3] = cpu_to_fdt64(GICC_SIZE_64K);
|
||||
reg[4] = cpu_to_fdt64(GICH_BASE_64K);
|
||||
reg[5] = cpu_to_fdt64(GICH_SIZE_64K);
|
||||
reg[6] = cpu_to_fdt64(GICV_BASE_64K);
|
||||
reg[7] = cpu_to_fdt64(GICV_SIZE_64K);
|
||||
} else {
|
||||
/* Fixup gic node align with default */
|
||||
reg[0] = cpu_to_fdt64(GICD_BASE);
|
||||
reg[1] = cpu_to_fdt64(GICD_SIZE);
|
||||
reg[2] = cpu_to_fdt64(GICC_BASE);
|
||||
reg[3] = cpu_to_fdt64(GICC_SIZE);
|
||||
reg[4] = cpu_to_fdt64(GICH_BASE);
|
||||
reg[5] = cpu_to_fdt64(GICH_SIZE);
|
||||
reg[6] = cpu_to_fdt64(GICV_BASE);
|
||||
reg[7] = cpu_to_fdt64(GICV_SIZE);
|
||||
}
|
||||
|
||||
err = fdt_setprop(blob, offset, "reg", reg, sizeof(reg));
|
||||
if (err < 0) {
|
||||
printf("WARNING: fdt_setprop can't set %s from node %s: %s\n",
|
||||
"reg", "interrupt-controller@1400000",
|
||||
fdt_strerror(err));
|
||||
return;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_HAS_FEATURE_ENHANCED_MSI
|
||||
static int _fdt_fixup_msi_node(void *blob, const char *name,
|
||||
int irq_0, int irq_1, int rev)
|
||||
{
|
||||
int err, offset, len;
|
||||
u32 tmp[4][3];
|
||||
void *p;
|
||||
|
||||
offset = fdt_path_offset(blob, name);
|
||||
if (offset < 0) {
|
||||
printf("WARNING: fdt_path_offset can't find path %s: %s\n",
|
||||
name, fdt_strerror(offset));
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*fixup the property of interrupts*/
|
||||
|
||||
tmp[0][0] = cpu_to_fdt32(0x0);
|
||||
tmp[0][1] = cpu_to_fdt32(irq_0);
|
||||
tmp[0][2] = cpu_to_fdt32(0x4);
|
||||
|
||||
if (rev > REV1_0) {
|
||||
tmp[1][0] = cpu_to_fdt32(0x0);
|
||||
tmp[1][1] = cpu_to_fdt32(irq_1);
|
||||
tmp[1][2] = cpu_to_fdt32(0x4);
|
||||
tmp[2][0] = cpu_to_fdt32(0x0);
|
||||
tmp[2][1] = cpu_to_fdt32(irq_1 + 1);
|
||||
tmp[2][2] = cpu_to_fdt32(0x4);
|
||||
tmp[3][0] = cpu_to_fdt32(0x0);
|
||||
tmp[3][1] = cpu_to_fdt32(irq_1 + 2);
|
||||
tmp[3][2] = cpu_to_fdt32(0x4);
|
||||
len = sizeof(tmp);
|
||||
} else {
|
||||
len = sizeof(tmp[0]);
|
||||
}
|
||||
|
||||
err = fdt_setprop(blob, offset, "interrupts", tmp, len);
|
||||
if (err < 0) {
|
||||
printf("WARNING: fdt_setprop can't set %s from node %s: %s\n",
|
||||
"interrupts", name, fdt_strerror(err));
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*fixup the property of reg*/
|
||||
p = (char *)fdt_getprop(blob, offset, "reg", &len);
|
||||
if (!p) {
|
||||
printf("WARNING: fdt_getprop can't get %s from node %s\n",
|
||||
"reg", name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
memcpy((char *)tmp, p, len);
|
||||
|
||||
if (rev > REV1_0)
|
||||
*((u32 *)tmp + 3) = cpu_to_fdt32(0x1000);
|
||||
else
|
||||
*((u32 *)tmp + 3) = cpu_to_fdt32(0x8);
|
||||
|
||||
err = fdt_setprop(blob, offset, "reg", tmp, len);
|
||||
if (err < 0) {
|
||||
printf("WARNING: fdt_setprop can't set %s from node %s: %s\n",
|
||||
"reg", name, fdt_strerror(err));
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*fixup the property of compatible*/
|
||||
if (rev > REV1_0)
|
||||
err = fdt_setprop_string(blob, offset, "compatible",
|
||||
"fsl,ls1043a-v1.1-msi");
|
||||
else
|
||||
err = fdt_setprop_string(blob, offset, "compatible",
|
||||
"fsl,ls1043a-msi");
|
||||
if (err < 0) {
|
||||
printf("WARNING: fdt_setprop can't set %s from node %s: %s\n",
|
||||
"compatible", name, fdt_strerror(err));
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int _fdt_fixup_pci_msi(void *blob, const char *name, int rev)
|
||||
{
|
||||
int offset, len, err;
|
||||
void *p;
|
||||
int val;
|
||||
u32 tmp[4][8];
|
||||
|
||||
offset = fdt_path_offset(blob, name);
|
||||
if (offset < 0) {
|
||||
printf("WARNING: fdt_path_offset can't find path %s: %s\n",
|
||||
name, fdt_strerror(offset));
|
||||
return 0;
|
||||
}
|
||||
|
||||
p = (char *)fdt_getprop(blob, offset, "interrupt-map", &len);
|
||||
if (!p || len != sizeof(tmp)) {
|
||||
printf("WARNING: fdt_getprop can't get %s from node %s\n",
|
||||
"interrupt-map", name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
memcpy((char *)tmp, p, len);
|
||||
|
||||
val = fdt32_to_cpu(tmp[0][6]);
|
||||
if (rev == REV1_0) {
|
||||
tmp[1][6] = cpu_to_fdt32(val + 1);
|
||||
tmp[2][6] = cpu_to_fdt32(val + 2);
|
||||
tmp[3][6] = cpu_to_fdt32(val + 3);
|
||||
} else {
|
||||
tmp[1][6] = cpu_to_fdt32(val);
|
||||
tmp[2][6] = cpu_to_fdt32(val);
|
||||
tmp[3][6] = cpu_to_fdt32(val);
|
||||
}
|
||||
|
||||
err = fdt_setprop(blob, offset, "interrupt-map", tmp, sizeof(tmp));
|
||||
if (err < 0) {
|
||||
printf("WARNING: fdt_setprop can't set %s from node %s: %s.\n",
|
||||
"interrupt-map", name, fdt_strerror(err));
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Fixup msi node for ls1043a rev1.1*/
|
||||
|
||||
static void fdt_fixup_msi(void *blob)
|
||||
{
|
||||
struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR);
|
||||
unsigned int rev;
|
||||
|
||||
rev = gur_in32(&gur->svr);
|
||||
|
||||
if (!IS_SVR_DEV(rev, SVR_DEV(SVR_LS1043A)))
|
||||
return;
|
||||
|
||||
rev = SVR_REV(rev);
|
||||
|
||||
_fdt_fixup_msi_node(blob, "/soc/msi-controller1@1571000",
|
||||
116, 111, rev);
|
||||
_fdt_fixup_msi_node(blob, "/soc/msi-controller2@1572000",
|
||||
126, 121, rev);
|
||||
_fdt_fixup_msi_node(blob, "/soc/msi-controller3@1573000",
|
||||
160, 155, rev);
|
||||
|
||||
_fdt_fixup_pci_msi(blob, "/soc/pcie@3400000", rev);
|
||||
_fdt_fixup_pci_msi(blob, "/soc/pcie@3500000", rev);
|
||||
_fdt_fixup_pci_msi(blob, "/soc/pcie@3600000", rev);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ARMV8_SEC_FIRMWARE_SUPPORT
|
||||
/* Remove JR node used by SEC firmware */
|
||||
void fdt_fixup_remove_jr(void *blob)
|
||||
{
|
||||
int jr_node, addr_cells, len;
|
||||
int crypto_node = fdt_path_offset(blob, "crypto");
|
||||
u64 jr_offset, used_jr;
|
||||
fdt32_t *reg;
|
||||
|
||||
used_jr = sec_firmware_used_jobring_offset();
|
||||
fdt_support_default_count_cells(blob, crypto_node, &addr_cells, NULL);
|
||||
|
||||
jr_node = fdt_node_offset_by_compatible(blob, crypto_node,
|
||||
"fsl,sec-v4.0-job-ring");
|
||||
|
||||
while (jr_node != -FDT_ERR_NOTFOUND) {
|
||||
reg = (fdt32_t *)fdt_getprop(blob, jr_node, "reg", &len);
|
||||
jr_offset = fdt_read_number(reg, addr_cells);
|
||||
if (jr_offset == used_jr) {
|
||||
fdt_del_node(blob, jr_node);
|
||||
break;
|
||||
}
|
||||
jr_node = fdt_node_offset_by_compatible(blob, jr_node,
|
||||
"fsl,sec-v4.0-job-ring");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ARCH_LS1028A
|
||||
static void fdt_disable_multimedia(void *blob, unsigned int svr)
|
||||
{
|
||||
int off;
|
||||
|
||||
if (IS_MULTIMEDIA_EN(svr))
|
||||
return;
|
||||
|
||||
/* Disable eDP/LCD node */
|
||||
off = fdt_node_offset_by_compatible(blob, -1, "arm,mali-dp500");
|
||||
if (off != -FDT_ERR_NOTFOUND)
|
||||
fdt_status_disabled(blob, off);
|
||||
|
||||
/* Disable GPU node */
|
||||
off = fdt_node_offset_by_compatible(blob, -1, "fsl,ls1028a-gpu");
|
||||
if (off != -FDT_ERR_NOTFOUND)
|
||||
fdt_status_disabled(blob, off);
|
||||
}
|
||||
#endif
|
||||
|
||||
void ft_cpu_setup(void *blob, bd_t *bd)
|
||||
{
|
||||
struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR);
|
||||
unsigned int svr = gur_in32(&gur->svr);
|
||||
|
||||
/* delete crypto node if not on an E-processor */
|
||||
if (!IS_E_PROCESSOR(svr))
|
||||
fdt_fixup_crypto_node(blob, 0);
|
||||
#if CONFIG_SYS_FSL_SEC_COMPAT >= 4
|
||||
else {
|
||||
ccsr_sec_t __iomem *sec;
|
||||
|
||||
#ifdef CONFIG_ARMV8_SEC_FIRMWARE_SUPPORT
|
||||
fdt_fixup_remove_jr(blob);
|
||||
fdt_fixup_kaslr(blob);
|
||||
#endif
|
||||
|
||||
sec = (void __iomem *)CONFIG_SYS_FSL_SEC_ADDR;
|
||||
fdt_fixup_crypto_node(blob, sec_in32(&sec->secvid_ms));
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_MP
|
||||
ft_fixup_cpu(blob);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SYS_NS16550
|
||||
do_fixup_by_compat_u32(blob, "fsl,ns16550",
|
||||
"clock-frequency", CONFIG_SYS_NS16550_CLK, 1);
|
||||
#endif
|
||||
|
||||
do_fixup_by_path_u32(blob, "/sysclk", "clock-frequency",
|
||||
CONFIG_SYS_CLK_FREQ, 1);
|
||||
|
||||
#if defined(CONFIG_PCIE_LAYERSCAPE) || defined(CONFIG_PCIE_LAYERSCAPE_GEN4)
|
||||
ft_pci_setup(blob, bd);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_FSL_ESDHC
|
||||
fdt_fixup_esdhc(blob, bd);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SYS_DPAA_QBMAN
|
||||
fdt_fixup_bportals(blob);
|
||||
fdt_fixup_qportals(blob);
|
||||
do_fixup_by_compat_u32(blob, "fsl,qman",
|
||||
"clock-frequency", get_qman_freq(), 1);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SYS_DPAA_FMAN
|
||||
fdt_fixup_fman_firmware(blob);
|
||||
#endif
|
||||
#ifndef CONFIG_ARCH_LS1012A
|
||||
fsl_fdt_disable_usb(blob);
|
||||
#endif
|
||||
#ifdef CONFIG_HAS_FEATURE_GIC64K_ALIGN
|
||||
fdt_fixup_gic(blob);
|
||||
#endif
|
||||
#ifdef CONFIG_HAS_FEATURE_ENHANCED_MSI
|
||||
fdt_fixup_msi(blob);
|
||||
#endif
|
||||
#ifdef CONFIG_ARCH_LS1028A
|
||||
fdt_disable_multimedia(blob, svr);
|
||||
#endif
|
||||
}
|
||||
+419
@@ -0,0 +1,419 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Copyright 2015 Freescale Semiconductor, Inc.
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <asm/io.h>
|
||||
#include <linux/errno.h>
|
||||
#include <asm/arch/fsl_serdes.h>
|
||||
#include <asm/arch/soc.h>
|
||||
|
||||
#ifdef CONFIG_SYS_FSL_SRDS_1
|
||||
static u8 serdes1_prtcl_map[SERDES_PRCTL_COUNT];
|
||||
#endif
|
||||
#ifdef CONFIG_SYS_FSL_SRDS_2
|
||||
static u8 serdes2_prtcl_map[SERDES_PRCTL_COUNT];
|
||||
#endif
|
||||
|
||||
int is_serdes_configured(enum srds_prtcl device)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
#ifdef CONFIG_SYS_FSL_SRDS_1
|
||||
if (!serdes1_prtcl_map[NONE])
|
||||
fsl_serdes_init();
|
||||
|
||||
ret |= serdes1_prtcl_map[device];
|
||||
#endif
|
||||
#ifdef CONFIG_SYS_FSL_SRDS_2
|
||||
if (!serdes2_prtcl_map[NONE])
|
||||
fsl_serdes_init();
|
||||
|
||||
ret |= serdes2_prtcl_map[device];
|
||||
#endif
|
||||
|
||||
return !!ret;
|
||||
}
|
||||
|
||||
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[4]);
|
||||
int i;
|
||||
|
||||
switch (sd) {
|
||||
#ifdef CONFIG_SYS_FSL_SRDS_1
|
||||
case FSL_SRDS_1:
|
||||
cfg &= FSL_CHASSIS2_RCWSR4_SRDS1_PRTCL_MASK;
|
||||
cfg >>= FSL_CHASSIS2_RCWSR4_SRDS1_PRTCL_SHIFT;
|
||||
break;
|
||||
#endif
|
||||
#ifdef CONFIG_SYS_FSL_SRDS_2
|
||||
case FSL_SRDS_2:
|
||||
cfg &= FSL_CHASSIS2_RCWSR4_SRDS2_PRTCL_MASK;
|
||||
cfg >>= FSL_CHASSIS2_RCWSR4_SRDS2_PRTCL_SHIFT;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
printf("invalid SerDes%d\n", sd);
|
||||
break;
|
||||
}
|
||||
|
||||
/* Is serdes enabled at all? */
|
||||
if (unlikely(cfg == 0))
|
||||
return -ENODEV;
|
||||
|
||||
for (i = 0; i < SRDS_MAX_LANES; i++) {
|
||||
if (serdes_get_prtcl(sd, cfg, i) == device)
|
||||
return i;
|
||||
}
|
||||
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
int get_serdes_protocol(void)
|
||||
{
|
||||
struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR);
|
||||
u32 cfg = gur_in32(&gur->rcwsr[4]) &
|
||||
FSL_CHASSIS2_RCWSR4_SRDS1_PRTCL_MASK;
|
||||
cfg >>= FSL_CHASSIS2_RCWSR4_SRDS1_PRTCL_SHIFT;
|
||||
|
||||
return cfg;
|
||||
}
|
||||
|
||||
const char *serdes_clock_to_string(u32 clock)
|
||||
{
|
||||
switch (clock) {
|
||||
case SRDS_PLLCR0_RFCK_SEL_100:
|
||||
return "100";
|
||||
case SRDS_PLLCR0_RFCK_SEL_125:
|
||||
return "125";
|
||||
case SRDS_PLLCR0_RFCK_SEL_156_25:
|
||||
return "156.25";
|
||||
default:
|
||||
return "100";
|
||||
}
|
||||
}
|
||||
|
||||
void serdes_init(u32 sd, u32 sd_addr, 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;
|
||||
int lane;
|
||||
|
||||
if (serdes_prtcl_map[NONE])
|
||||
return;
|
||||
|
||||
memset(serdes_prtcl_map, 0, sizeof(u8) * SERDES_PRCTL_COUNT);
|
||||
|
||||
cfg = gur_in32(&gur->rcwsr[4]) & sd_prctl_mask;
|
||||
cfg >>= sd_prctl_shift;
|
||||
printf("Using SERDES%d Protocol: %d (0x%x)\n", sd + 1, cfg, cfg);
|
||||
|
||||
if (!is_serdes_prtcl_valid(sd, cfg))
|
||||
printf("SERDES%d[PRTCL] = 0x%x is not valid\n", sd + 1, cfg);
|
||||
|
||||
for (lane = 0; lane < SRDS_MAX_LANES; lane++) {
|
||||
enum srds_prtcl lane_prtcl = serdes_get_prtcl(sd, cfg, lane);
|
||||
|
||||
if (unlikely(lane_prtcl >= SERDES_PRCTL_COUNT))
|
||||
debug("Unknown SerDes lane protocol %d\n", lane_prtcl);
|
||||
else
|
||||
serdes_prtcl_map[lane_prtcl] = 1;
|
||||
}
|
||||
|
||||
/* Set the first element to indicate serdes has been initialized */
|
||||
serdes_prtcl_map[NONE] = 1;
|
||||
}
|
||||
|
||||
__weak int get_serdes_volt(void)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
__weak int set_serdes_volt(int svdd)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
int setup_serdes_volt(u32 svdd)
|
||||
{
|
||||
struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR);
|
||||
struct ccsr_serdes *serdes1_base;
|
||||
#ifdef CONFIG_SYS_FSL_SRDS_2
|
||||
struct ccsr_serdes *serdes2_base;
|
||||
#endif
|
||||
u32 cfg_rcw4 = gur_in32(&gur->rcwsr[4]);
|
||||
u32 cfg_rcw5 = gur_in32(&gur->rcwsr[5]);
|
||||
u32 cfg_tmp, reg = 0;
|
||||
int svdd_cur, svdd_tar;
|
||||
int ret;
|
||||
int i;
|
||||
|
||||
/* Only support switch SVDD to 900mV/1000mV */
|
||||
if (svdd != 900 && svdd != 1000)
|
||||
return -EINVAL;
|
||||
|
||||
svdd_tar = svdd;
|
||||
svdd_cur = get_serdes_volt();
|
||||
if (svdd_cur < 0)
|
||||
return -EINVAL;
|
||||
|
||||
debug("%s: current SVDD: %dmV; target SVDD: %dmV\n",
|
||||
__func__, svdd_cur, svdd_tar);
|
||||
if (svdd_cur == svdd_tar)
|
||||
return 0;
|
||||
|
||||
serdes1_base = (void *)CONFIG_SYS_FSL_SERDES_ADDR;
|
||||
#ifdef CONFIG_SYS_FSL_SRDS_2
|
||||
serdes2_base = (void *)serdes1_base + 0x10000;
|
||||
#endif
|
||||
|
||||
/* Put the all enabled lanes in reset */
|
||||
#ifdef CONFIG_SYS_FSL_SRDS_1
|
||||
cfg_tmp = cfg_rcw4 & FSL_CHASSIS2_RCWSR4_SRDS1_PRTCL_MASK;
|
||||
cfg_tmp >>= FSL_CHASSIS2_RCWSR4_SRDS1_PRTCL_SHIFT;
|
||||
|
||||
for (i = 0; i < 4 && cfg_tmp & (0xf << (3 - i)); i++) {
|
||||
reg = in_be32(&serdes1_base->lane[i].gcr0);
|
||||
reg &= 0xFF9FFFFF;
|
||||
out_be32(&serdes1_base->lane[i].gcr0, reg);
|
||||
}
|
||||
#endif
|
||||
#ifdef CONFIG_SYS_FSL_SRDS_2
|
||||
cfg_tmp = cfg_rcw4 & FSL_CHASSIS2_RCWSR4_SRDS2_PRTCL_MASK;
|
||||
cfg_tmp >>= FSL_CHASSIS2_RCWSR4_SRDS2_PRTCL_SHIFT;
|
||||
|
||||
for (i = 0; i < 4 && cfg_tmp & (0xf << (3 - i)); i++) {
|
||||
reg = in_be32(&serdes2_base->lane[i].gcr0);
|
||||
reg &= 0xFF9FFFFF;
|
||||
out_be32(&serdes2_base->lane[i].gcr0, reg);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Put the all enabled PLL in reset */
|
||||
#ifdef CONFIG_SYS_FSL_SRDS_1
|
||||
cfg_tmp = (cfg_rcw5 >> 22) & 0x3;
|
||||
for (i = 0; i < 2 && !(cfg_tmp & (0x1 << (1 - i))); i++) {
|
||||
reg = in_be32(&serdes1_base->bank[i].rstctl);
|
||||
reg &= 0xFFFFFFBF;
|
||||
reg |= 0x10000000;
|
||||
out_be32(&serdes1_base->bank[i].rstctl, reg);
|
||||
udelay(1);
|
||||
|
||||
reg = in_be32(&serdes1_base->bank[i].rstctl);
|
||||
reg &= 0xFFFFFF1F;
|
||||
out_be32(&serdes1_base->bank[i].rstctl, reg);
|
||||
}
|
||||
udelay(1);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SYS_FSL_SRDS_2
|
||||
cfg_tmp = (cfg_rcw5 >> 20) & 0x3;
|
||||
for (i = 0; i < 2 && !(cfg_tmp & (0x1 << (1 - i))); i++) {
|
||||
reg = in_be32(&serdes2_base->bank[i].rstctl);
|
||||
reg &= 0xFFFFFFBF;
|
||||
reg |= 0x10000000;
|
||||
out_be32(&serdes2_base->bank[i].rstctl, reg);
|
||||
udelay(1);
|
||||
|
||||
reg = in_be32(&serdes2_base->bank[i].rstctl);
|
||||
reg &= 0xFFFFFF1F;
|
||||
out_be32(&serdes2_base->bank[i].rstctl, reg);
|
||||
}
|
||||
udelay(1);
|
||||
#endif
|
||||
|
||||
/* Put the Rx/Tx calibration into reset */
|
||||
#ifdef CONFIG_SYS_FSL_SRDS_1
|
||||
reg = in_be32(&serdes1_base->srdstcalcr);
|
||||
reg &= 0xF7FFFFFF;
|
||||
out_be32(&serdes1_base->srdstcalcr, reg);
|
||||
reg = in_be32(&serdes1_base->srdsrcalcr);
|
||||
reg &= 0xF7FFFFFF;
|
||||
out_be32(&serdes1_base->srdsrcalcr, reg);
|
||||
|
||||
#endif
|
||||
#ifdef CONFIG_SYS_FSL_SRDS_2
|
||||
reg = in_be32(&serdes2_base->srdstcalcr);
|
||||
reg &= 0xF7FFFFFF;
|
||||
out_be32(&serdes2_base->srdstcalcr, reg);
|
||||
reg = in_be32(&serdes2_base->srdsrcalcr);
|
||||
reg &= 0xF7FFFFFF;
|
||||
out_be32(&serdes2_base->srdsrcalcr, reg);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* If SVDD set failed, will not return directly, so that the
|
||||
* serdes lanes can complete reseting.
|
||||
*/
|
||||
ret = set_serdes_volt(svdd_tar);
|
||||
if (ret)
|
||||
printf("%s: Failed to set SVDD\n", __func__);
|
||||
|
||||
/* Wait for SVDD to stabilize */
|
||||
udelay(100);
|
||||
|
||||
/* For each PLL that’s not disabled via RCW */
|
||||
#ifdef CONFIG_SYS_FSL_SRDS_1
|
||||
cfg_tmp = (cfg_rcw5 >> 22) & 0x3;
|
||||
for (i = 0; i < 2 && !(cfg_tmp & (0x1 << (1 - i))); i++) {
|
||||
reg = in_be32(&serdes1_base->bank[i].rstctl);
|
||||
reg |= 0x00000020;
|
||||
out_be32(&serdes1_base->bank[i].rstctl, reg);
|
||||
udelay(1);
|
||||
|
||||
reg = in_be32(&serdes1_base->bank[i].rstctl);
|
||||
reg |= 0x00000080;
|
||||
out_be32(&serdes1_base->bank[i].rstctl, reg);
|
||||
|
||||
/* Take the Rx/Tx calibration out of reset */
|
||||
if (!(cfg_tmp == 0x3 && i == 1)) {
|
||||
udelay(1);
|
||||
reg = in_be32(&serdes1_base->srdstcalcr);
|
||||
reg |= 0x08000000;
|
||||
out_be32(&serdes1_base->srdstcalcr, reg);
|
||||
reg = in_be32(&serdes1_base->srdsrcalcr);
|
||||
reg |= 0x08000000;
|
||||
out_be32(&serdes1_base->srdsrcalcr, reg);
|
||||
}
|
||||
}
|
||||
udelay(1);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SYS_FSL_SRDS_2
|
||||
cfg_tmp = (cfg_rcw5 >> 20) & 0x3;
|
||||
for (i = 0; i < 2 && !(cfg_tmp & (0x1 << (1 - i))); i++) {
|
||||
reg = in_be32(&serdes2_base->bank[i].rstctl);
|
||||
reg |= 0x00000020;
|
||||
out_be32(&serdes2_base->bank[i].rstctl, reg);
|
||||
udelay(1);
|
||||
|
||||
reg = in_be32(&serdes2_base->bank[i].rstctl);
|
||||
reg |= 0x00000080;
|
||||
out_be32(&serdes2_base->bank[i].rstctl, reg);
|
||||
|
||||
/* Take the Rx/Tx calibration out of reset */
|
||||
if (!(cfg_tmp == 0x3 && i == 1)) {
|
||||
udelay(1);
|
||||
reg = in_be32(&serdes2_base->srdstcalcr);
|
||||
reg |= 0x08000000;
|
||||
out_be32(&serdes2_base->srdstcalcr, reg);
|
||||
reg = in_be32(&serdes2_base->srdsrcalcr);
|
||||
reg |= 0x08000000;
|
||||
out_be32(&serdes2_base->srdsrcalcr, reg);
|
||||
}
|
||||
}
|
||||
udelay(1);
|
||||
|
||||
#endif
|
||||
|
||||
/* Wait for at lesat 625us to ensure the PLLs being reset are locked */
|
||||
udelay(800);
|
||||
|
||||
#ifdef CONFIG_SYS_FSL_SRDS_1
|
||||
cfg_tmp = (cfg_rcw5 >> 22) & 0x3;
|
||||
for (i = 0; i < 2 && !(cfg_tmp & (0x1 << (1 - i))); i++) {
|
||||
/* if the PLL is not locked, set RST_ERR */
|
||||
reg = in_be32(&serdes1_base->bank[i].pllcr0);
|
||||
if (!((reg >> 23) & 0x1)) {
|
||||
reg = in_be32(&serdes1_base->bank[i].rstctl);
|
||||
reg |= 0x20000000;
|
||||
out_be32(&serdes1_base->bank[i].rstctl, reg);
|
||||
} else {
|
||||
udelay(1);
|
||||
reg = in_be32(&serdes1_base->bank[i].rstctl);
|
||||
reg &= 0xFFFFFFEF;
|
||||
reg |= 0x00000040;
|
||||
out_be32(&serdes1_base->bank[i].rstctl, reg);
|
||||
udelay(1);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SYS_FSL_SRDS_2
|
||||
cfg_tmp = (cfg_rcw5 >> 20) & 0x3;
|
||||
for (i = 0; i < 2 && !(cfg_tmp & (0x1 << (1 - i))); i++) {
|
||||
reg = in_be32(&serdes2_base->bank[i].pllcr0);
|
||||
if (!((reg >> 23) & 0x1)) {
|
||||
reg = in_be32(&serdes2_base->bank[i].rstctl);
|
||||
reg |= 0x20000000;
|
||||
out_be32(&serdes2_base->bank[i].rstctl, reg);
|
||||
} else {
|
||||
udelay(1);
|
||||
reg = in_be32(&serdes2_base->bank[i].rstctl);
|
||||
reg &= 0xFFFFFFEF;
|
||||
reg |= 0x00000040;
|
||||
out_be32(&serdes2_base->bank[i].rstctl, reg);
|
||||
udelay(1);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Take the all enabled lanes out of reset */
|
||||
#ifdef CONFIG_SYS_FSL_SRDS_1
|
||||
cfg_tmp = cfg_rcw4 & FSL_CHASSIS2_RCWSR4_SRDS1_PRTCL_MASK;
|
||||
cfg_tmp >>= FSL_CHASSIS2_RCWSR4_SRDS1_PRTCL_SHIFT;
|
||||
|
||||
for (i = 0; i < 4 && cfg_tmp & (0xf << (3 - i)); i++) {
|
||||
reg = in_be32(&serdes1_base->lane[i].gcr0);
|
||||
reg |= 0x00600000;
|
||||
out_be32(&serdes1_base->lane[i].gcr0, reg);
|
||||
}
|
||||
#endif
|
||||
#ifdef CONFIG_SYS_FSL_SRDS_2
|
||||
cfg_tmp = cfg_rcw4 & FSL_CHASSIS2_RCWSR4_SRDS2_PRTCL_MASK;
|
||||
cfg_tmp >>= FSL_CHASSIS2_RCWSR4_SRDS2_PRTCL_SHIFT;
|
||||
|
||||
for (i = 0; i < 4 && cfg_tmp & (0xf << (3 - i)); i++) {
|
||||
reg = in_be32(&serdes2_base->lane[i].gcr0);
|
||||
reg |= 0x00600000;
|
||||
out_be32(&serdes2_base->lane[i].gcr0, reg);
|
||||
}
|
||||
#endif
|
||||
/* For each PLL being reset, and achieved PLL lock set RST_DONE */
|
||||
#ifdef CONFIG_SYS_FSL_SRDS_1
|
||||
cfg_tmp = (cfg_rcw5 >> 22) & 0x3;
|
||||
for (i = 0; i < 2; i++) {
|
||||
reg = in_be32(&serdes1_base->bank[i].pllcr0);
|
||||
if (!(cfg_tmp & (0x1 << (1 - i))) && ((reg >> 23) & 0x1)) {
|
||||
reg = in_be32(&serdes1_base->bank[i].rstctl);
|
||||
reg |= 0x40000000;
|
||||
out_be32(&serdes1_base->bank[i].rstctl, reg);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#ifdef CONFIG_SYS_FSL_SRDS_2
|
||||
cfg_tmp = (cfg_rcw5 >> 20) & 0x3;
|
||||
for (i = 0; i < 2; i++) {
|
||||
reg = in_be32(&serdes2_base->bank[i].pllcr0);
|
||||
if (!(cfg_tmp & (0x1 << (1 - i))) && ((reg >> 23) & 0x1)) {
|
||||
reg = in_be32(&serdes2_base->bank[i].rstctl);
|
||||
reg |= 0x40000000;
|
||||
out_be32(&serdes2_base->bank[i].rstctl, reg);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void fsl_serdes_init(void)
|
||||
{
|
||||
#ifdef CONFIG_SYS_FSL_SRDS_1
|
||||
serdes_init(FSL_SRDS_1,
|
||||
CONFIG_SYS_FSL_SERDES_ADDR,
|
||||
FSL_CHASSIS2_RCWSR4_SRDS1_PRTCL_MASK,
|
||||
FSL_CHASSIS2_RCWSR4_SRDS1_PRTCL_SHIFT,
|
||||
serdes1_prtcl_map);
|
||||
#endif
|
||||
#ifdef CONFIG_SYS_FSL_SRDS_2
|
||||
serdes_init(FSL_SRDS_2,
|
||||
CONFIG_SYS_FSL_SERDES_ADDR,
|
||||
FSL_CHASSIS2_RCWSR4_SRDS2_PRTCL_MASK,
|
||||
FSL_CHASSIS2_RCWSR4_SRDS2_PRTCL_SHIFT,
|
||||
serdes2_prtcl_map);
|
||||
#endif
|
||||
}
|
||||
@@ -0,0 +1,268 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Copyright 2015 Freescale Semiconductor, Inc.
|
||||
* Copyright 2019 NXP.
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <cpu_func.h>
|
||||
#include <linux/compiler.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/processor.h>
|
||||
#include <asm/arch/clock.h>
|
||||
#include <asm/arch/soc.h>
|
||||
#include <fsl_ifc.h>
|
||||
#include "cpu.h"
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
#ifndef CONFIG_SYS_FSL_NUM_CC_PLLS
|
||||
#define CONFIG_SYS_FSL_NUM_CC_PLLS 2
|
||||
#endif
|
||||
|
||||
void get_sys_info(struct sys_info *sys_info)
|
||||
{
|
||||
struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR);
|
||||
/* rcw_tmp is needed to get FMAN clock, or to get cluster group A
|
||||
* mux 2 clock for LS1043A/LS1046A.
|
||||
*/
|
||||
#if defined(CONFIG_SYS_DPAA_FMAN) || \
|
||||
defined(CONFIG_TARGET_LS1046ARDB) || \
|
||||
defined(CONFIG_TARGET_LS1043ARDB)
|
||||
u32 rcw_tmp;
|
||||
#endif
|
||||
struct ccsr_clk *clk = (void *)(CONFIG_SYS_FSL_CLK_ADDR);
|
||||
unsigned int cpu;
|
||||
const u8 core_cplx_pll[8] = {
|
||||
[0] = 0, /* CC1 PPL / 1 */
|
||||
[1] = 0, /* CC1 PPL / 2 */
|
||||
[4] = 1, /* CC2 PPL / 1 */
|
||||
[5] = 1, /* CC2 PPL / 2 */
|
||||
};
|
||||
|
||||
const u8 core_cplx_pll_div[8] = {
|
||||
[0] = 1, /* CC1 PPL / 1 */
|
||||
[1] = 2, /* CC1 PPL / 2 */
|
||||
[4] = 1, /* CC2 PPL / 1 */
|
||||
[5] = 2, /* CC2 PPL / 2 */
|
||||
};
|
||||
|
||||
uint i, cluster;
|
||||
uint freq_c_pll[CONFIG_SYS_FSL_NUM_CC_PLLS];
|
||||
uint ratio[CONFIG_SYS_FSL_NUM_CC_PLLS];
|
||||
unsigned long sysclk = CONFIG_SYS_CLK_FREQ;
|
||||
unsigned long cluster_clk;
|
||||
|
||||
sys_info->freq_systembus = sysclk;
|
||||
#ifndef CONFIG_CLUSTER_CLK_FREQ
|
||||
#define CONFIG_CLUSTER_CLK_FREQ CONFIG_SYS_CLK_FREQ
|
||||
#endif
|
||||
cluster_clk = CONFIG_CLUSTER_CLK_FREQ;
|
||||
|
||||
#ifdef CONFIG_DDR_CLK_FREQ
|
||||
sys_info->freq_ddrbus = CONFIG_DDR_CLK_FREQ;
|
||||
#else
|
||||
sys_info->freq_ddrbus = sysclk;
|
||||
#endif
|
||||
|
||||
/* The freq_systembus is used to record frequency of platform PLL */
|
||||
sys_info->freq_systembus *= (gur_in32(&gur->rcwsr[0]) >>
|
||||
FSL_CHASSIS2_RCWSR0_SYS_PLL_RAT_SHIFT) &
|
||||
FSL_CHASSIS2_RCWSR0_SYS_PLL_RAT_MASK;
|
||||
|
||||
#ifdef CONFIG_ARCH_LS1012A
|
||||
sys_info->freq_ddrbus = 2 * sys_info->freq_systembus;
|
||||
#else
|
||||
sys_info->freq_ddrbus *= (gur_in32(&gur->rcwsr[0]) >>
|
||||
FSL_CHASSIS2_RCWSR0_MEM_PLL_RAT_SHIFT) &
|
||||
FSL_CHASSIS2_RCWSR0_MEM_PLL_RAT_MASK;
|
||||
#endif
|
||||
|
||||
for (i = 0; i < CONFIG_SYS_FSL_NUM_CC_PLLS; i++) {
|
||||
ratio[i] = (in_be32(&clk->pllcgsr[i].pllcngsr) >> 1) & 0xff;
|
||||
if (ratio[i] > 4)
|
||||
freq_c_pll[i] = cluster_clk * ratio[i];
|
||||
else
|
||||
freq_c_pll[i] = sys_info->freq_systembus * ratio[i];
|
||||
}
|
||||
|
||||
for_each_cpu(i, cpu, cpu_numcores(), cpu_mask()) {
|
||||
cluster = fsl_qoriq_core_to_cluster(cpu);
|
||||
u32 c_pll_sel = (in_be32(&clk->clkcsr[cluster].clkcncsr) >> 27)
|
||||
& 0xf;
|
||||
u32 cplx_pll = core_cplx_pll[c_pll_sel];
|
||||
|
||||
sys_info->freq_processor[cpu] =
|
||||
freq_c_pll[cplx_pll] / core_cplx_pll_div[c_pll_sel];
|
||||
}
|
||||
|
||||
#define HWA_CGA_M1_CLK_SEL 0xe0000000
|
||||
#define HWA_CGA_M1_CLK_SHIFT 29
|
||||
#ifdef CONFIG_SYS_DPAA_FMAN
|
||||
rcw_tmp = in_be32(&gur->rcwsr[7]);
|
||||
switch ((rcw_tmp & HWA_CGA_M1_CLK_SEL) >> HWA_CGA_M1_CLK_SHIFT) {
|
||||
case 2:
|
||||
sys_info->freq_fman[0] = freq_c_pll[0] / 2;
|
||||
break;
|
||||
case 3:
|
||||
sys_info->freq_fman[0] = freq_c_pll[0] / 3;
|
||||
break;
|
||||
case 4:
|
||||
sys_info->freq_fman[0] = freq_c_pll[0] / 4;
|
||||
break;
|
||||
case 5:
|
||||
sys_info->freq_fman[0] = sys_info->freq_systembus;
|
||||
break;
|
||||
case 6:
|
||||
sys_info->freq_fman[0] = freq_c_pll[1] / 2;
|
||||
break;
|
||||
case 7:
|
||||
sys_info->freq_fman[0] = freq_c_pll[1] / 3;
|
||||
break;
|
||||
default:
|
||||
printf("Error: Unknown FMan1 clock select!\n");
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_FSL_ESDHC
|
||||
#define HWA_CGA_M2_CLK_SEL 0x00000007
|
||||
#define HWA_CGA_M2_CLK_SHIFT 0
|
||||
#if defined(CONFIG_TARGET_LS1046ARDB) || defined(CONFIG_TARGET_LS1043ARDB)
|
||||
rcw_tmp = in_be32(&gur->rcwsr[15]);
|
||||
switch ((rcw_tmp & HWA_CGA_M2_CLK_SEL) >> HWA_CGA_M2_CLK_SHIFT) {
|
||||
case 1:
|
||||
sys_info->freq_cga_m2 = freq_c_pll[1];
|
||||
break;
|
||||
#if defined(CONFIG_TARGET_LS1046ARDB)
|
||||
case 2:
|
||||
sys_info->freq_cga_m2 = freq_c_pll[1] / 2;
|
||||
break;
|
||||
#endif
|
||||
case 3:
|
||||
sys_info->freq_cga_m2 = freq_c_pll[1] / 3;
|
||||
break;
|
||||
#if defined(CONFIG_TARGET_LS1046ARDB)
|
||||
case 6:
|
||||
sys_info->freq_cga_m2 = freq_c_pll[0] / 2;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
printf("Error: Unknown peripheral clock select!\n");
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_FSL_IFC)
|
||||
sys_info->freq_localbus = sys_info->freq_systembus /
|
||||
CONFIG_SYS_FSL_IFC_CLK_DIV;
|
||||
#endif
|
||||
#ifdef CONFIG_SYS_DPAA_QBMAN
|
||||
sys_info->freq_qman = (sys_info->freq_systembus /
|
||||
CONFIG_SYS_FSL_PCLK_DIV) /
|
||||
CONFIG_SYS_FSL_QMAN_CLK_DIV;
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SYS_DPAA_QBMAN
|
||||
unsigned long get_qman_freq(void)
|
||||
{
|
||||
struct sys_info sys_info;
|
||||
|
||||
get_sys_info(&sys_info);
|
||||
|
||||
return sys_info.freq_qman;
|
||||
}
|
||||
#endif
|
||||
|
||||
int get_clocks(void)
|
||||
{
|
||||
struct sys_info sys_info;
|
||||
|
||||
get_sys_info(&sys_info);
|
||||
gd->cpu_clk = sys_info.freq_processor[0];
|
||||
gd->bus_clk = sys_info.freq_systembus / CONFIG_SYS_FSL_PCLK_DIV;
|
||||
gd->mem_clk = sys_info.freq_ddrbus;
|
||||
|
||||
#ifdef CONFIG_FSL_ESDHC
|
||||
#if defined(CONFIG_FSL_ESDHC_USE_PERIPHERAL_CLK)
|
||||
#if defined(CONFIG_TARGET_LS1046ARDB)
|
||||
gd->arch.sdhc_clk = sys_info.freq_cga_m2 / 2;
|
||||
#endif
|
||||
#if defined(CONFIG_TARGET_LS1043ARDB)
|
||||
gd->arch.sdhc_clk = sys_info.freq_cga_m2;
|
||||
#endif
|
||||
#if defined(CONFIG_TARGET_LS1012ARDB)
|
||||
gd->arch.sdhc_clk = sys_info.freq_systembus;
|
||||
#endif
|
||||
#else
|
||||
gd->arch.sdhc_clk = (sys_info.freq_systembus /
|
||||
CONFIG_SYS_FSL_PCLK_DIV) /
|
||||
CONFIG_SYS_FSL_SDHC_CLK_DIV;
|
||||
#endif
|
||||
#endif
|
||||
if (gd->cpu_clk != 0)
|
||||
return 0;
|
||||
else
|
||||
return 1;
|
||||
}
|
||||
|
||||
/********************************************
|
||||
* get_bus_freq
|
||||
* return platform clock in Hz
|
||||
*********************************************/
|
||||
ulong get_bus_freq(ulong dummy)
|
||||
{
|
||||
if (!gd->bus_clk)
|
||||
get_clocks();
|
||||
|
||||
return gd->bus_clk;
|
||||
}
|
||||
|
||||
ulong get_ddr_freq(ulong dummy)
|
||||
{
|
||||
if (!gd->mem_clk)
|
||||
get_clocks();
|
||||
|
||||
return gd->mem_clk;
|
||||
}
|
||||
|
||||
int get_serial_clock(void)
|
||||
{
|
||||
return get_bus_freq(0) / CONFIG_SYS_FSL_DUART_CLK_DIV;
|
||||
}
|
||||
|
||||
int get_i2c_freq(ulong dummy)
|
||||
{
|
||||
return get_bus_freq(0) / CONFIG_SYS_FSL_I2C_CLK_DIV;
|
||||
}
|
||||
|
||||
int get_dspi_freq(ulong dummy)
|
||||
{
|
||||
return get_bus_freq(0) / CONFIG_SYS_FSL_DSPI_CLK_DIV;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_FSL_LPUART
|
||||
int get_uart_freq(ulong dummy)
|
||||
{
|
||||
return get_bus_freq(0) / CONFIG_SYS_FSL_LPUART_CLK_DIV;
|
||||
}
|
||||
#endif
|
||||
|
||||
unsigned int mxc_get_clock(enum mxc_clock clk)
|
||||
{
|
||||
switch (clk) {
|
||||
case MXC_I2C_CLK:
|
||||
return get_i2c_freq(0);
|
||||
case MXC_DSPI_CLK:
|
||||
return get_dspi_freq(0);
|
||||
#ifdef CONFIG_FSL_LPUART
|
||||
case MXC_UART_CLK:
|
||||
return get_uart_freq(0);
|
||||
#endif
|
||||
default:
|
||||
printf("Unsupported clock\n");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
+602
@@ -0,0 +1,602 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Copyright 2016-2018 NXP
|
||||
* Copyright 2014-2015 Freescale Semiconductor, Inc.
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <asm/io.h>
|
||||
#include <linux/errno.h>
|
||||
#include <asm/arch/fsl_serdes.h>
|
||||
#include <asm/arch/soc.h>
|
||||
#include <fsl-mc/ldpaa_wriop.h>
|
||||
|
||||
#ifdef CONFIG_SYS_FSL_SRDS_1
|
||||
static u8 serdes1_prtcl_map[SERDES_PRCTL_COUNT];
|
||||
#endif
|
||||
#ifdef CONFIG_SYS_FSL_SRDS_2
|
||||
static u8 serdes2_prtcl_map[SERDES_PRCTL_COUNT];
|
||||
#endif
|
||||
#ifdef CONFIG_SYS_NXP_SRDS_3
|
||||
static u8 serdes3_prtcl_map[SERDES_PRCTL_COUNT];
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_FSL_MC_ENET) && !defined(CONFIG_SPL_BUILD)
|
||||
#ifdef CONFIG_ARCH_LX2160A
|
||||
int xfi_dpmac[XFI14 + 1];
|
||||
int sgmii_dpmac[SGMII18 + 1];
|
||||
int a25gaui_dpmac[_25GE10 + 1];
|
||||
int xlaui_dpmac[_40GE2 + 1];
|
||||
int caui2_dpmac[_50GE2 + 1];
|
||||
int caui4_dpmac[_100GE2 + 1];
|
||||
#else
|
||||
int xfi_dpmac[XFI8 + 1];
|
||||
int sgmii_dpmac[SGMII16 + 1];
|
||||
#endif
|
||||
#endif
|
||||
|
||||
__weak void wriop_init_dpmac_qsgmii(int sd, int lane_prtcl)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
*The return value of this func is the serdes protocol used.
|
||||
*Typically this function is called number of times depending
|
||||
*upon the number of serdes blocks in the Silicon.
|
||||
*Zero is used to denote that no serdes was enabled,
|
||||
*this is the case when golden RCW was used where DPAA2 bring was
|
||||
*intentionally removed to achieve boot to prompt
|
||||
*/
|
||||
|
||||
__weak int serdes_get_number(int serdes, int cfg)
|
||||
{
|
||||
return cfg;
|
||||
}
|
||||
|
||||
int is_serdes_configured(enum srds_prtcl device)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
#ifdef CONFIG_SYS_FSL_SRDS_1
|
||||
if (!serdes1_prtcl_map[NONE])
|
||||
fsl_serdes_init();
|
||||
|
||||
ret |= serdes1_prtcl_map[device];
|
||||
#endif
|
||||
#ifdef CONFIG_SYS_FSL_SRDS_2
|
||||
if (!serdes2_prtcl_map[NONE])
|
||||
fsl_serdes_init();
|
||||
|
||||
ret |= serdes2_prtcl_map[device];
|
||||
#endif
|
||||
#ifdef CONFIG_SYS_NXP_SRDS_3
|
||||
if (!serdes3_prtcl_map[NONE])
|
||||
fsl_serdes_init();
|
||||
|
||||
ret |= serdes3_prtcl_map[device];
|
||||
#endif
|
||||
|
||||
return !!ret;
|
||||
}
|
||||
|
||||
int serdes_get_first_lane(u32 sd, enum srds_prtcl device)
|
||||
{
|
||||
struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR);
|
||||
u32 cfg = 0;
|
||||
int i;
|
||||
|
||||
switch (sd) {
|
||||
#ifdef CONFIG_SYS_FSL_SRDS_1
|
||||
case FSL_SRDS_1:
|
||||
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 = gur_in32(&gur->rcwsr[FSL_CHASSIS3_SRDS2_REGSR - 1]);
|
||||
cfg &= FSL_CHASSIS3_SRDS2_PRTCL_MASK;
|
||||
cfg >>= FSL_CHASSIS3_SRDS2_PRTCL_SHIFT;
|
||||
break;
|
||||
#endif
|
||||
#ifdef CONFIG_SYS_NXP_SRDS_3
|
||||
case NXP_SRDS_3:
|
||||
cfg = gur_in32(&gur->rcwsr[FSL_CHASSIS3_SRDS3_REGSR - 1]);
|
||||
cfg &= FSL_CHASSIS3_SRDS3_PRTCL_MASK;
|
||||
cfg >>= FSL_CHASSIS3_SRDS3_PRTCL_SHIFT;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
printf("invalid SerDes%d\n", sd);
|
||||
break;
|
||||
}
|
||||
|
||||
cfg = serdes_get_number(sd, cfg);
|
||||
|
||||
/* Is serdes enabled at all? */
|
||||
if (cfg == 0)
|
||||
return -ENODEV;
|
||||
|
||||
for (i = 0; i < SRDS_MAX_LANES; i++) {
|
||||
if (serdes_get_prtcl(sd, cfg, i) == device)
|
||||
return i;
|
||||
}
|
||||
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
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;
|
||||
int lane;
|
||||
|
||||
if (serdes_prtcl_map[NONE])
|
||||
return;
|
||||
|
||||
memset(serdes_prtcl_map, 0, sizeof(u8) * SERDES_PRCTL_COUNT);
|
||||
|
||||
cfg = gur_in32(&gur->rcwsr[rcwsr - 1]) & sd_prctl_mask;
|
||||
cfg >>= sd_prctl_shift;
|
||||
|
||||
cfg = serdes_get_number(sd, cfg);
|
||||
printf("Using SERDES%d Protocol: %d (0x%x)\n", sd + 1, cfg, cfg);
|
||||
|
||||
if (!is_serdes_prtcl_valid(sd, cfg))
|
||||
printf("SERDES%d[PRTCL] = 0x%x is not valid\n", sd + 1, cfg);
|
||||
|
||||
for (lane = 0; lane < SRDS_MAX_LANES; lane++) {
|
||||
enum srds_prtcl lane_prtcl = serdes_get_prtcl(sd, cfg, lane);
|
||||
if (unlikely(lane_prtcl >= SERDES_PRCTL_COUNT))
|
||||
debug("Unknown SerDes lane protocol %d\n", lane_prtcl);
|
||||
else {
|
||||
serdes_prtcl_map[lane_prtcl] = 1;
|
||||
#if defined(CONFIG_FSL_MC_ENET) && !defined(CONFIG_SPL_BUILD)
|
||||
#ifdef CONFIG_ARCH_LX2160A
|
||||
if (lane_prtcl >= XFI1 && lane_prtcl <= XFI14)
|
||||
wriop_init_dpmac(sd, xfi_dpmac[lane_prtcl],
|
||||
(int)lane_prtcl);
|
||||
|
||||
if (lane_prtcl >= SGMII1 && lane_prtcl <= SGMII18)
|
||||
wriop_init_dpmac(sd, sgmii_dpmac[lane_prtcl],
|
||||
(int)lane_prtcl);
|
||||
|
||||
if (lane_prtcl >= _25GE1 && lane_prtcl <= _25GE10)
|
||||
wriop_init_dpmac(sd, a25gaui_dpmac[lane_prtcl],
|
||||
(int)lane_prtcl);
|
||||
|
||||
if (lane_prtcl >= _40GE1 && lane_prtcl <= _40GE2)
|
||||
wriop_init_dpmac(sd, xlaui_dpmac[lane_prtcl],
|
||||
(int)lane_prtcl);
|
||||
|
||||
if (lane_prtcl >= _50GE1 && lane_prtcl <= _50GE2)
|
||||
wriop_init_dpmac(sd, caui2_dpmac[lane_prtcl],
|
||||
(int)lane_prtcl);
|
||||
|
||||
if (lane_prtcl >= _100GE1 && lane_prtcl <= _100GE2)
|
||||
wriop_init_dpmac(sd, caui4_dpmac[lane_prtcl],
|
||||
(int)lane_prtcl);
|
||||
|
||||
#else
|
||||
switch (lane_prtcl) {
|
||||
case QSGMII_A:
|
||||
case QSGMII_B:
|
||||
case QSGMII_C:
|
||||
case QSGMII_D:
|
||||
wriop_init_dpmac_qsgmii(sd, (int)lane_prtcl);
|
||||
break;
|
||||
default:
|
||||
if (lane_prtcl >= XFI1 && lane_prtcl <= XFI8)
|
||||
wriop_init_dpmac(sd,
|
||||
xfi_dpmac[lane_prtcl],
|
||||
(int)lane_prtcl);
|
||||
|
||||
if (lane_prtcl >= SGMII1 &&
|
||||
lane_prtcl <= SGMII16)
|
||||
wriop_init_dpmac(sd, sgmii_dpmac[
|
||||
lane_prtcl],
|
||||
(int)lane_prtcl);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
/* Set the first element to indicate serdes has been initialized */
|
||||
serdes_prtcl_map[NONE] = 1;
|
||||
}
|
||||
|
||||
__weak int get_serdes_volt(void)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
__weak int set_serdes_volt(int svdd)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
#define LNAGCR0_RT_RSTB 0x00600000
|
||||
|
||||
#define RSTCTL_RESET_MASK 0x000000E0
|
||||
|
||||
#define RSTCTL_RSTREQ 0x80000000
|
||||
#define RSTCTL_RST_DONE 0x40000000
|
||||
#define RSTCTL_RSTERR 0x20000000
|
||||
|
||||
#define RSTCTL_SDEN 0x00000020
|
||||
#define RSTCTL_SDRST_B 0x00000040
|
||||
#define RSTCTL_PLLRST_B 0x00000080
|
||||
|
||||
#define TCALCR_CALRST_B 0x08000000
|
||||
|
||||
struct serdes_prctl_info {
|
||||
u32 id;
|
||||
u32 mask;
|
||||
u32 shift;
|
||||
};
|
||||
|
||||
struct serdes_prctl_info srds_prctl_info[] = {
|
||||
#ifdef CONFIG_SYS_FSL_SRDS_1
|
||||
{.id = 1,
|
||||
.mask = FSL_CHASSIS3_SRDS1_PRTCL_MASK,
|
||||
.shift = FSL_CHASSIS3_SRDS1_PRTCL_SHIFT
|
||||
},
|
||||
|
||||
#endif
|
||||
#ifdef CONFIG_SYS_FSL_SRDS_2
|
||||
{.id = 2,
|
||||
.mask = FSL_CHASSIS3_SRDS2_PRTCL_MASK,
|
||||
.shift = FSL_CHASSIS3_SRDS2_PRTCL_SHIFT
|
||||
},
|
||||
#endif
|
||||
#ifdef CONFIG_SYS_NXP_SRDS_3
|
||||
{.id = 3,
|
||||
.mask = FSL_CHASSIS3_SRDS3_PRTCL_MASK,
|
||||
.shift = FSL_CHASSIS3_SRDS3_PRTCL_SHIFT
|
||||
},
|
||||
#endif
|
||||
{} /* NULL ENTRY */
|
||||
};
|
||||
|
||||
static int get_serdes_prctl_info_idx(u32 serdes_id)
|
||||
{
|
||||
int pos = 0;
|
||||
struct serdes_prctl_info *srds_info;
|
||||
|
||||
/* loop until NULL ENTRY defined by .id=0 */
|
||||
for (srds_info = srds_prctl_info; srds_info->id != 0;
|
||||
srds_info++, pos++) {
|
||||
if (srds_info->id == serdes_id)
|
||||
return pos;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static void do_enabled_lanes_reset(u32 serdes_id, u32 cfg,
|
||||
struct ccsr_serdes __iomem *serdes_base,
|
||||
bool cmplt)
|
||||
{
|
||||
int i, pos;
|
||||
u32 cfg_tmp;
|
||||
|
||||
pos = get_serdes_prctl_info_idx(serdes_id);
|
||||
if (pos == -1) {
|
||||
printf("invalid serdes_id %d\n", serdes_id);
|
||||
return;
|
||||
}
|
||||
|
||||
cfg_tmp = cfg & srds_prctl_info[pos].mask;
|
||||
cfg_tmp >>= srds_prctl_info[pos].shift;
|
||||
|
||||
for (i = 0; i < 4 && cfg_tmp & (0xf << (3 - i)); i++) {
|
||||
if (cmplt)
|
||||
setbits_le32(&serdes_base->lane[i].gcr0,
|
||||
LNAGCR0_RT_RSTB);
|
||||
else
|
||||
clrbits_le32(&serdes_base->lane[i].gcr0,
|
||||
LNAGCR0_RT_RSTB);
|
||||
}
|
||||
}
|
||||
|
||||
static void do_pll_reset(u32 cfg,
|
||||
struct ccsr_serdes __iomem *serdes_base)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 2 && !(cfg & (0x1 << (1 - i))); i++) {
|
||||
clrbits_le32(&serdes_base->bank[i].rstctl,
|
||||
RSTCTL_RESET_MASK);
|
||||
udelay(1);
|
||||
|
||||
setbits_le32(&serdes_base->bank[i].rstctl,
|
||||
RSTCTL_RSTREQ);
|
||||
}
|
||||
udelay(1);
|
||||
}
|
||||
|
||||
static void do_rx_tx_cal_reset(struct ccsr_serdes __iomem *serdes_base)
|
||||
{
|
||||
clrbits_le32(&serdes_base->srdstcalcr, TCALCR_CALRST_B);
|
||||
clrbits_le32(&serdes_base->srdstcalcr, TCALCR_CALRST_B);
|
||||
}
|
||||
|
||||
static void do_rx_tx_cal_reset_comp(u32 cfg, int i,
|
||||
struct ccsr_serdes __iomem *serdes_base)
|
||||
{
|
||||
if (!(cfg == 0x3 && i == 1)) {
|
||||
udelay(1);
|
||||
setbits_le32(&serdes_base->srdstcalcr, TCALCR_CALRST_B);
|
||||
setbits_le32(&serdes_base->srdstcalcr, TCALCR_CALRST_B);
|
||||
}
|
||||
udelay(1);
|
||||
}
|
||||
|
||||
static void do_pll_reset_done(u32 cfg,
|
||||
struct ccsr_serdes __iomem *serdes_base)
|
||||
{
|
||||
int i;
|
||||
u32 reg = 0;
|
||||
|
||||
for (i = 0; i < 2; i++) {
|
||||
reg = in_le32(&serdes_base->bank[i].pllcr0);
|
||||
if (!(cfg & (0x1 << (1 - i))) && ((reg >> 23) & 0x1)) {
|
||||
setbits_le32(&serdes_base->bank[i].rstctl,
|
||||
RSTCTL_RST_DONE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void do_serdes_enable(u32 cfg,
|
||||
struct ccsr_serdes __iomem *serdes_base)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 2 && !(cfg & (0x1 << (1 - i))); i++) {
|
||||
setbits_le32(&serdes_base->bank[i].rstctl, RSTCTL_SDEN);
|
||||
udelay(1);
|
||||
|
||||
setbits_le32(&serdes_base->bank[i].rstctl, RSTCTL_PLLRST_B);
|
||||
udelay(1);
|
||||
/* Take the Rx/Tx calibration out of reset */
|
||||
do_rx_tx_cal_reset_comp(cfg, i, serdes_base);
|
||||
}
|
||||
}
|
||||
|
||||
static void do_pll_lock(u32 cfg,
|
||||
struct ccsr_serdes __iomem *serdes_base)
|
||||
{
|
||||
int i;
|
||||
u32 reg = 0;
|
||||
|
||||
for (i = 0; i < 2 && !(cfg & (0x1 << (1 - i))); i++) {
|
||||
/* if the PLL is not locked, set RST_ERR */
|
||||
reg = in_le32(&serdes_base->bank[i].pllcr0);
|
||||
if (!((reg >> 23) & 0x1)) {
|
||||
setbits_le32(&serdes_base->bank[i].rstctl,
|
||||
RSTCTL_RSTERR);
|
||||
} else {
|
||||
udelay(1);
|
||||
setbits_le32(&serdes_base->bank[i].rstctl,
|
||||
RSTCTL_SDRST_B);
|
||||
udelay(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int setup_serdes_volt(u32 svdd)
|
||||
{
|
||||
struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR);
|
||||
struct ccsr_serdes __iomem *serdes1_base =
|
||||
(void *)CONFIG_SYS_FSL_LSCH3_SERDES_ADDR;
|
||||
u32 cfg_rcwsrds1 = gur_in32(&gur->rcwsr[FSL_CHASSIS3_SRDS1_REGSR - 1]);
|
||||
#ifdef CONFIG_SYS_FSL_SRDS_2
|
||||
struct ccsr_serdes __iomem *serdes2_base =
|
||||
(void *)(CONFIG_SYS_FSL_LSCH3_SERDES_ADDR + 0x10000);
|
||||
u32 cfg_rcwsrds2 = gur_in32(&gur->rcwsr[FSL_CHASSIS3_SRDS2_REGSR - 1]);
|
||||
#endif
|
||||
#ifdef CONFIG_SYS_NXP_SRDS_3
|
||||
struct ccsr_serdes __iomem *serdes3_base =
|
||||
(void *)(CONFIG_SYS_FSL_LSCH3_SERDES_ADDR + 0x20000);
|
||||
u32 cfg_rcwsrds3 = gur_in32(&gur->rcwsr[FSL_CHASSIS3_SRDS3_REGSR - 1]);
|
||||
#endif
|
||||
u32 cfg_tmp;
|
||||
int svdd_cur, svdd_tar;
|
||||
int ret = 1;
|
||||
|
||||
/* Only support switch SVDD to 900mV */
|
||||
if (svdd != 900)
|
||||
return -EINVAL;
|
||||
|
||||
/* Scale up to the LTC resolution is 1/4096V */
|
||||
svdd = (svdd * 4096) / 1000;
|
||||
|
||||
svdd_tar = svdd;
|
||||
svdd_cur = get_serdes_volt();
|
||||
if (svdd_cur < 0)
|
||||
return -EINVAL;
|
||||
|
||||
debug("%s: current SVDD: %x; target SVDD: %x\n",
|
||||
__func__, svdd_cur, svdd_tar);
|
||||
if (svdd_cur == svdd_tar)
|
||||
return 0;
|
||||
|
||||
/* Put the all enabled lanes in reset */
|
||||
#ifdef CONFIG_SYS_FSL_SRDS_1
|
||||
do_enabled_lanes_reset(1, cfg_rcwsrds1, serdes1_base, false);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SYS_FSL_SRDS_2
|
||||
do_enabled_lanes_reset(2, cfg_rcwsrds2, serdes2_base, false);
|
||||
#endif
|
||||
#ifdef CONFIG_SYS_NXP_SRDS_3
|
||||
do_enabled_lanes_reset(3, cfg_rcwsrds3, serdes3_base, false);
|
||||
#endif
|
||||
|
||||
/* Put the all enabled PLL in reset */
|
||||
#ifdef CONFIG_SYS_FSL_SRDS_1
|
||||
cfg_tmp = cfg_rcwsrds1 & 0x3;
|
||||
do_pll_reset(cfg_tmp, serdes1_base);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SYS_FSL_SRDS_2
|
||||
cfg_tmp = cfg_rcwsrds1 & 0xC;
|
||||
cfg_tmp >>= 2;
|
||||
do_pll_reset(cfg_tmp, serdes2_base);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SYS_NXP_SRDS_3
|
||||
cfg_tmp = cfg_rcwsrds3 & 0x30;
|
||||
cfg_tmp >>= 4;
|
||||
do_pll_reset(cfg_tmp, serdes3_base);
|
||||
#endif
|
||||
|
||||
/* Put the Rx/Tx calibration into reset */
|
||||
#ifdef CONFIG_SYS_FSL_SRDS_1
|
||||
do_rx_tx_cal_reset(serdes1_base);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SYS_FSL_SRDS_2
|
||||
do_rx_tx_cal_reset(serdes2_base);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SYS_NXP_SRDS_3
|
||||
do_rx_tx_cal_reset(serdes3_base);
|
||||
#endif
|
||||
|
||||
ret = set_serdes_volt(svdd);
|
||||
if (ret < 0) {
|
||||
printf("could not change SVDD\n");
|
||||
ret = -1;
|
||||
}
|
||||
|
||||
/* For each PLL that’s not disabled via RCW enable the SERDES */
|
||||
#ifdef CONFIG_SYS_FSL_SRDS_1
|
||||
cfg_tmp = cfg_rcwsrds1 & 0x3;
|
||||
do_serdes_enable(cfg_tmp, serdes1_base);
|
||||
#endif
|
||||
#ifdef CONFIG_SYS_FSL_SRDS_2
|
||||
cfg_tmp = cfg_rcwsrds1 & 0xC;
|
||||
cfg_tmp >>= 2;
|
||||
do_serdes_enable(cfg_tmp, serdes2_base);
|
||||
#endif
|
||||
#ifdef CONFIG_SYS_NXP_SRDS_3
|
||||
cfg_tmp = cfg_rcwsrds3 & 0x30;
|
||||
cfg_tmp >>= 4;
|
||||
do_serdes_enable(cfg_tmp, serdes3_base);
|
||||
#endif
|
||||
|
||||
/* Wait for at at least 625us, ensure the PLLs being reset are locked */
|
||||
udelay(800);
|
||||
|
||||
#ifdef CONFIG_SYS_FSL_SRDS_1
|
||||
cfg_tmp = cfg_rcwsrds1 & 0x3;
|
||||
do_pll_lock(cfg_tmp, serdes1_base);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SYS_FSL_SRDS_2
|
||||
cfg_tmp = cfg_rcwsrds1 & 0xC;
|
||||
cfg_tmp >>= 2;
|
||||
do_pll_lock(cfg_tmp, serdes2_base);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SYS_NXP_SRDS_3
|
||||
cfg_tmp = cfg_rcwsrds3 & 0x30;
|
||||
cfg_tmp >>= 4;
|
||||
do_pll_lock(cfg_tmp, serdes3_base);
|
||||
#endif
|
||||
|
||||
/* Take the all enabled lanes out of reset */
|
||||
#ifdef CONFIG_SYS_FSL_SRDS_1
|
||||
do_enabled_lanes_reset(1, cfg_rcwsrds1, serdes1_base, true);
|
||||
#endif
|
||||
#ifdef CONFIG_SYS_FSL_SRDS_2
|
||||
do_enabled_lanes_reset(2, cfg_rcwsrds2, serdes2_base, true);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SYS_NXP_SRDS_3
|
||||
do_enabled_lanes_reset(3, cfg_rcwsrds3, serdes3_base, true);
|
||||
#endif
|
||||
|
||||
/* For each PLL being reset, and achieved PLL lock set RST_DONE */
|
||||
#ifdef CONFIG_SYS_FSL_SRDS_1
|
||||
cfg_tmp = cfg_rcwsrds1 & 0x3;
|
||||
do_pll_reset_done(cfg_tmp, serdes1_base);
|
||||
#endif
|
||||
#ifdef CONFIG_SYS_FSL_SRDS_2
|
||||
cfg_tmp = cfg_rcwsrds1 & 0xC;
|
||||
cfg_tmp >>= 2;
|
||||
do_pll_reset_done(cfg_tmp, serdes2_base);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SYS_NXP_SRDS_3
|
||||
cfg_tmp = cfg_rcwsrds3 & 0x30;
|
||||
cfg_tmp >>= 4;
|
||||
do_pll_reset_done(cfg_tmp, serdes3_base);
|
||||
#endif
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void fsl_serdes_init(void)
|
||||
{
|
||||
#if defined(CONFIG_FSL_MC_ENET) && !defined(CONFIG_SPL_BUILD)
|
||||
int i , j;
|
||||
|
||||
#ifdef CONFIG_ARCH_LX2160A
|
||||
for (i = XFI1, j = 1; i <= XFI14; i++, j++)
|
||||
xfi_dpmac[i] = j;
|
||||
|
||||
for (i = SGMII1, j = 1; i <= SGMII18; i++, j++)
|
||||
sgmii_dpmac[i] = j;
|
||||
|
||||
for (i = _25GE1, j = 1; i <= _25GE10; i++, j++)
|
||||
a25gaui_dpmac[i] = j;
|
||||
|
||||
for (i = _40GE1, j = 1; i <= _40GE2; i++, j++)
|
||||
xlaui_dpmac[i] = j;
|
||||
|
||||
for (i = _50GE1, j = 1; i <= _50GE2; i++, j++)
|
||||
caui2_dpmac[i] = j;
|
||||
|
||||
for (i = _100GE1, j = 1; i <= _100GE2; i++, j++)
|
||||
caui4_dpmac[i] = j;
|
||||
#else
|
||||
for (i = XFI1, j = 1; i <= XFI8; i++, j++)
|
||||
xfi_dpmac[i] = j;
|
||||
|
||||
for (i = SGMII1, j = 1; i <= SGMII16; i++, j++)
|
||||
sgmii_dpmac[i] = j;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SYS_FSL_SRDS_1
|
||||
serdes_init(FSL_SRDS_1,
|
||||
CONFIG_SYS_FSL_LSCH3_SERDES_ADDR,
|
||||
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_SRDS2_REGSR,
|
||||
FSL_CHASSIS3_SRDS2_PRTCL_MASK,
|
||||
FSL_CHASSIS3_SRDS2_PRTCL_SHIFT,
|
||||
serdes2_prtcl_map);
|
||||
#endif
|
||||
#ifdef CONFIG_SYS_NXP_SRDS_3
|
||||
serdes_init(NXP_SRDS_3,
|
||||
CONFIG_SYS_FSL_LSCH3_SERDES_ADDR + NXP_SRDS_3 * 0x10000,
|
||||
FSL_CHASSIS3_SRDS3_REGSR,
|
||||
FSL_CHASSIS3_SRDS3_PRTCL_MASK,
|
||||
FSL_CHASSIS3_SRDS3_PRTCL_SHIFT,
|
||||
serdes3_prtcl_map);
|
||||
#endif
|
||||
}
|
||||
@@ -0,0 +1,256 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Copyright 2014-2015, Freescale Semiconductor, Inc.
|
||||
* Copyright 2019 NXP Semiconductors
|
||||
*
|
||||
* Derived from arch/power/cpu/mpc85xx/speed.c
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <cpu_func.h>
|
||||
#include <linux/compiler.h>
|
||||
#include <fsl_ifc.h>
|
||||
#include <asm/processor.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/arch-fsl-layerscape/immap_lsch3.h>
|
||||
#include <asm/arch/clock.h>
|
||||
#include <asm/arch/soc.h>
|
||||
#include "cpu.h"
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
#ifndef CONFIG_SYS_FSL_NUM_CC_PLLS
|
||||
#define CONFIG_SYS_FSL_NUM_CC_PLLS 6
|
||||
#endif
|
||||
|
||||
|
||||
void get_sys_info(struct sys_info *sys_info)
|
||||
{
|
||||
struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR);
|
||||
struct ccsr_clk_cluster_group __iomem *clk_grp[2] = {
|
||||
(void *)(CONFIG_SYS_FSL_CH3_CLK_GRPA_ADDR),
|
||||
(void *)(CONFIG_SYS_FSL_CH3_CLK_GRPB_ADDR)
|
||||
};
|
||||
struct ccsr_clk_ctrl __iomem *clk_ctrl =
|
||||
(void *)(CONFIG_SYS_FSL_CH3_CLK_CTRL_ADDR);
|
||||
unsigned int cpu;
|
||||
const u8 core_cplx_pll[16] = {
|
||||
[0] = 0, /* CC1 PPL / 1 */
|
||||
[1] = 0, /* CC1 PPL / 2 */
|
||||
[2] = 0, /* CC1 PPL / 4 */
|
||||
[4] = 1, /* CC2 PPL / 1 */
|
||||
[5] = 1, /* CC2 PPL / 2 */
|
||||
[6] = 1, /* CC2 PPL / 4 */
|
||||
[8] = 2, /* CC3 PPL / 1 */
|
||||
[9] = 2, /* CC3 PPL / 2 */
|
||||
[10] = 2, /* CC3 PPL / 4 */
|
||||
[12] = 3, /* CC4 PPL / 1 */
|
||||
[13] = 3, /* CC4 PPL / 2 */
|
||||
[14] = 3, /* CC4 PPL / 4 */
|
||||
};
|
||||
|
||||
const u8 core_cplx_pll_div[16] = {
|
||||
[0] = 1, /* CC1 PPL / 1 */
|
||||
[1] = 2, /* CC1 PPL / 2 */
|
||||
[2] = 4, /* CC1 PPL / 4 */
|
||||
[4] = 1, /* CC2 PPL / 1 */
|
||||
[5] = 2, /* CC2 PPL / 2 */
|
||||
[6] = 4, /* CC2 PPL / 4 */
|
||||
[8] = 1, /* CC3 PPL / 1 */
|
||||
[9] = 2, /* CC3 PPL / 2 */
|
||||
[10] = 4, /* CC3 PPL / 4 */
|
||||
[12] = 1, /* CC4 PPL / 1 */
|
||||
[13] = 2, /* CC4 PPL / 2 */
|
||||
[14] = 4, /* CC4 PPL / 4 */
|
||||
};
|
||||
|
||||
uint i, cluster;
|
||||
#if defined(CONFIG_ARCH_LS1028A) || defined(CONFIG_ARCH_LS1088A)
|
||||
uint rcw_tmp;
|
||||
#endif
|
||||
uint freq_c_pll[CONFIG_SYS_FSL_NUM_CC_PLLS];
|
||||
uint ratio[CONFIG_SYS_FSL_NUM_CC_PLLS];
|
||||
unsigned long sysclk = CONFIG_SYS_CLK_FREQ;
|
||||
int cc_group[12] = CONFIG_SYS_FSL_CLUSTER_CLOCKS;
|
||||
u32 c_pll_sel, cplx_pll;
|
||||
void *offset;
|
||||
|
||||
sys_info->freq_systembus = sysclk;
|
||||
#ifdef CONFIG_DDR_CLK_FREQ
|
||||
sys_info->freq_ddrbus = CONFIG_DDR_CLK_FREQ;
|
||||
#ifdef CONFIG_SYS_FSL_HAS_DP_DDR
|
||||
sys_info->freq_ddrbus2 = CONFIG_DDR_CLK_FREQ;
|
||||
#endif
|
||||
#else
|
||||
sys_info->freq_ddrbus = sysclk;
|
||||
#ifdef CONFIG_SYS_FSL_HAS_DP_DDR
|
||||
sys_info->freq_ddrbus2 = sysclk;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* The freq_systembus is used to record frequency of platform PLL */
|
||||
sys_info->freq_systembus *= (gur_in32(&gur->rcwsr[0]) >>
|
||||
FSL_CHASSIS3_RCWSR0_SYS_PLL_RAT_SHIFT) &
|
||||
FSL_CHASSIS3_RCWSR0_SYS_PLL_RAT_MASK;
|
||||
sys_info->freq_ddrbus *= (gur_in32(&gur->rcwsr[0]) >>
|
||||
FSL_CHASSIS3_RCWSR0_MEM_PLL_RAT_SHIFT) &
|
||||
FSL_CHASSIS3_RCWSR0_MEM_PLL_RAT_MASK;
|
||||
#ifdef CONFIG_SYS_FSL_HAS_DP_DDR
|
||||
if (soc_has_dp_ddr()) {
|
||||
sys_info->freq_ddrbus2 *= (gur_in32(&gur->rcwsr[0]) >>
|
||||
FSL_CHASSIS3_RCWSR0_MEM2_PLL_RAT_SHIFT) &
|
||||
FSL_CHASSIS3_RCWSR0_MEM2_PLL_RAT_MASK;
|
||||
} else {
|
||||
sys_info->freq_ddrbus2 = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
for (i = 0; i < CONFIG_SYS_FSL_NUM_CC_PLLS; i++) {
|
||||
/*
|
||||
* fixme: prefer to combine the following into one line, but
|
||||
* cannot pass compiling without warning about in_le32.
|
||||
*/
|
||||
offset = (void *)((size_t)clk_grp[i/3] +
|
||||
offsetof(struct ccsr_clk_cluster_group,
|
||||
pllngsr[i%3].gsr));
|
||||
ratio[i] = (in_le32(offset) >> 1) & 0x3f;
|
||||
freq_c_pll[i] = sysclk * ratio[i];
|
||||
}
|
||||
|
||||
for_each_cpu(i, cpu, cpu_numcores(), cpu_mask()) {
|
||||
cluster = fsl_qoriq_core_to_cluster(cpu);
|
||||
c_pll_sel = (in_le32(&clk_ctrl->clkcncsr[cluster].csr) >> 27)
|
||||
& 0xf;
|
||||
cplx_pll = core_cplx_pll[c_pll_sel];
|
||||
cplx_pll += cc_group[cluster] - 1;
|
||||
sys_info->freq_processor[cpu] =
|
||||
freq_c_pll[cplx_pll] / core_cplx_pll_div[c_pll_sel];
|
||||
}
|
||||
|
||||
#if defined(CONFIG_FSL_IFC)
|
||||
sys_info->freq_localbus = sys_info->freq_systembus /
|
||||
CONFIG_SYS_FSL_IFC_CLK_DIV;
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_ARCH_LS1028A) || defined(CONFIG_ARCH_LS1088A)
|
||||
#define HWA_CGA_M2_CLK_SEL 0x00380000
|
||||
#define HWA_CGA_M2_CLK_SHIFT 19
|
||||
rcw_tmp = in_le32(&gur->rcwsr[5]);
|
||||
switch ((rcw_tmp & HWA_CGA_M2_CLK_SEL) >> HWA_CGA_M2_CLK_SHIFT) {
|
||||
case 1:
|
||||
sys_info->freq_cga_m2 = freq_c_pll[1];
|
||||
break;
|
||||
case 2:
|
||||
sys_info->freq_cga_m2 = freq_c_pll[1] / 2;
|
||||
break;
|
||||
case 3:
|
||||
sys_info->freq_cga_m2 = freq_c_pll[1] / 3;
|
||||
break;
|
||||
case 4:
|
||||
sys_info->freq_cga_m2 = freq_c_pll[1] / 4;
|
||||
break;
|
||||
case 6:
|
||||
sys_info->freq_cga_m2 = freq_c_pll[0] / 2;
|
||||
break;
|
||||
case 7:
|
||||
sys_info->freq_cga_m2 = freq_c_pll[0] / 3;
|
||||
break;
|
||||
default:
|
||||
printf("Error: Unknown peripheral clock select!\n");
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
#if defined(CONFIG_ARCH_LX2160A) || defined(CONFIG_ARCH_LS2080A)
|
||||
sys_info->freq_cga_m2 = sys_info->freq_systembus;
|
||||
#endif
|
||||
}
|
||||
|
||||
int get_clocks(void)
|
||||
{
|
||||
struct sys_info sys_info;
|
||||
get_sys_info(&sys_info);
|
||||
gd->cpu_clk = sys_info.freq_processor[0];
|
||||
gd->bus_clk = sys_info.freq_systembus / CONFIG_SYS_FSL_PCLK_DIV;
|
||||
gd->mem_clk = sys_info.freq_ddrbus;
|
||||
#ifdef CONFIG_SYS_FSL_HAS_DP_DDR
|
||||
gd->arch.mem2_clk = sys_info.freq_ddrbus2;
|
||||
#endif
|
||||
#if defined(CONFIG_FSL_ESDHC)
|
||||
#if defined(CONFIG_FSL_ESDHC_USE_PERIPHERAL_CLK)
|
||||
#if defined(CONFIG_ARCH_LS1028A) || defined(CONFIG_ARCH_LX2160A)
|
||||
gd->arch.sdhc_clk = sys_info.freq_cga_m2 / 2;
|
||||
#endif
|
||||
#if defined(CONFIG_ARCH_LS2080A) || defined(CONFIG_ARCH_LS1088A)
|
||||
gd->arch.sdhc_clk = sys_info.freq_cga_m2;
|
||||
#endif
|
||||
#else
|
||||
gd->arch.sdhc_clk = gd->bus_clk / CONFIG_SYS_FSL_SDHC_CLK_DIV;
|
||||
#endif
|
||||
#endif /* defined(CONFIG_FSL_ESDHC) */
|
||||
|
||||
if (gd->cpu_clk != 0)
|
||||
return 0;
|
||||
else
|
||||
return 1;
|
||||
}
|
||||
|
||||
/********************************************
|
||||
* get_bus_freq
|
||||
* return platform clock in Hz
|
||||
*********************************************/
|
||||
ulong get_bus_freq(ulong dummy)
|
||||
{
|
||||
if (!gd->bus_clk)
|
||||
get_clocks();
|
||||
|
||||
return gd->bus_clk;
|
||||
}
|
||||
|
||||
/********************************************
|
||||
* get_ddr_freq
|
||||
* return ddr bus freq in Hz
|
||||
*********************************************/
|
||||
ulong get_ddr_freq(ulong ctrl_num)
|
||||
{
|
||||
if (!gd->mem_clk)
|
||||
get_clocks();
|
||||
|
||||
/*
|
||||
* DDR controller 0 & 1 are on memory complex 0
|
||||
* DDR controller 2 is on memory complext 1
|
||||
*/
|
||||
#ifdef CONFIG_SYS_FSL_HAS_DP_DDR
|
||||
if (ctrl_num >= 2)
|
||||
return gd->arch.mem2_clk;
|
||||
#endif
|
||||
|
||||
return gd->mem_clk;
|
||||
}
|
||||
|
||||
int get_i2c_freq(ulong dummy)
|
||||
{
|
||||
return get_bus_freq(0) / CONFIG_SYS_FSL_I2C_CLK_DIV;
|
||||
}
|
||||
|
||||
int get_dspi_freq(ulong dummy)
|
||||
{
|
||||
return get_bus_freq(0) / CONFIG_SYS_FSL_DSPI_CLK_DIV;
|
||||
}
|
||||
|
||||
int get_serial_clock(void)
|
||||
{
|
||||
return get_bus_freq(0) / CONFIG_SYS_FSL_DUART_CLK_DIV;
|
||||
}
|
||||
|
||||
unsigned int mxc_get_clock(enum mxc_clock clk)
|
||||
{
|
||||
switch (clk) {
|
||||
case MXC_I2C_CLK:
|
||||
return get_i2c_freq(0);
|
||||
case MXC_DSPI_CLK:
|
||||
return get_dspi_freq(0);
|
||||
default:
|
||||
printf("Unsupported clock\n");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,195 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Copyright 2018 NXP
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <linux/libfdt.h>
|
||||
#include <fdt_support.h>
|
||||
|
||||
#include <asm/io.h>
|
||||
#include <asm/processor.h>
|
||||
#include <asm/arch-fsl-layerscape/fsl_icid.h>
|
||||
#include <fsl_fman.h>
|
||||
|
||||
static void set_icid(struct icid_id_table *tbl, int size)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < size; i++)
|
||||
if (tbl[i].le)
|
||||
out_le32((u32 *)(tbl[i].reg_addr), tbl[i].reg);
|
||||
else
|
||||
out_be32((u32 *)(tbl[i].reg_addr), tbl[i].reg);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SYS_DPAA_FMAN
|
||||
void set_fman_icids(struct fman_icid_id_table *tbl, int size)
|
||||
{
|
||||
int i;
|
||||
ccsr_fman_t *fm = (void *)CONFIG_SYS_FSL_FM1_ADDR;
|
||||
|
||||
for (i = 0; i < size; i++) {
|
||||
out_be32(&fm->fm_bmi_common.fmbm_ppid[tbl[i].port_id - 1],
|
||||
tbl[i].icid);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void set_icids(void)
|
||||
{
|
||||
/* setup general icid offsets */
|
||||
set_icid(icid_tbl, icid_tbl_sz);
|
||||
|
||||
#ifdef CONFIG_SYS_DPAA_FMAN
|
||||
set_fman_icids(fman_icid_tbl, fman_icid_tbl_sz);
|
||||
#endif
|
||||
}
|
||||
|
||||
int fdt_set_iommu_prop(void *blob, int off, int smmu_ph, u32 *ids, int num_ids)
|
||||
{
|
||||
int i, ret;
|
||||
u32 prop[8];
|
||||
|
||||
/*
|
||||
* Note: The "iommus" property definition mentions Stream IDs while
|
||||
* this code handles ICIDs. The current implementation assumes that
|
||||
* ICIDs and Stream IDs are equal.
|
||||
*/
|
||||
for (i = 0; i < num_ids; i++) {
|
||||
prop[i * 2] = cpu_to_fdt32(smmu_ph);
|
||||
prop[i * 2 + 1] = cpu_to_fdt32(ids[i]);
|
||||
}
|
||||
ret = fdt_setprop(blob, off, "iommus",
|
||||
prop, sizeof(u32) * num_ids * 2);
|
||||
if (ret) {
|
||||
printf("WARNING unable to set iommus: %s\n", fdt_strerror(ret));
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int fdt_fixup_icid_tbl(void *blob, int smmu_ph,
|
||||
struct icid_id_table *tbl, int size)
|
||||
{
|
||||
int i, err, off;
|
||||
|
||||
for (i = 0; i < size; i++) {
|
||||
if (!tbl[i].compat)
|
||||
continue;
|
||||
|
||||
off = fdt_node_offset_by_compat_reg(blob,
|
||||
tbl[i].compat,
|
||||
tbl[i].compat_addr);
|
||||
if (off > 0) {
|
||||
err = fdt_set_iommu_prop(blob, off, smmu_ph,
|
||||
&tbl[i].id, 1);
|
||||
if (err)
|
||||
return err;
|
||||
} else {
|
||||
printf("WARNING could not find node %s: %s.\n",
|
||||
tbl[i].compat, fdt_strerror(off));
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SYS_DPAA_FMAN
|
||||
int get_fman_port_icid(int port_id, struct fman_icid_id_table *tbl,
|
||||
const int size)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < size; i++) {
|
||||
if (tbl[i].port_id == port_id)
|
||||
return tbl[i].icid;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
void fdt_fixup_fman_port_icid_by_compat(void *blob, int smmu_ph,
|
||||
const char *compat)
|
||||
{
|
||||
int noff, len, icid;
|
||||
const u32 *prop;
|
||||
|
||||
noff = fdt_node_offset_by_compatible(blob, -1, compat);
|
||||
while (noff > 0) {
|
||||
prop = fdt_getprop(blob, noff, "cell-index", &len);
|
||||
if (!prop) {
|
||||
printf("WARNING missing cell-index for fman port\n");
|
||||
continue;
|
||||
}
|
||||
if (len != 4) {
|
||||
printf("WARNING bad cell-index size for fman port\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
icid = get_fman_port_icid(fdt32_to_cpu(*prop),
|
||||
fman_icid_tbl, fman_icid_tbl_sz);
|
||||
if (icid < 0) {
|
||||
printf("WARNING unknown ICID for fman port %d\n",
|
||||
*prop);
|
||||
continue;
|
||||
}
|
||||
|
||||
fdt_set_iommu_prop(blob, noff, smmu_ph, (u32 *)&icid, 1);
|
||||
|
||||
noff = fdt_node_offset_by_compatible(blob, noff, compat);
|
||||
}
|
||||
}
|
||||
|
||||
void fdt_fixup_fman_icids(void *blob, int smmu_ph)
|
||||
{
|
||||
static const char * const compats[] = {
|
||||
"fsl,fman-v3-port-oh",
|
||||
"fsl,fman-v3-port-rx",
|
||||
"fsl,fman-v3-port-tx",
|
||||
};
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(compats); i++)
|
||||
fdt_fixup_fman_port_icid_by_compat(blob, smmu_ph, compats[i]);
|
||||
}
|
||||
#endif
|
||||
|
||||
int fdt_get_smmu_phandle(void *blob)
|
||||
{
|
||||
int noff, smmu_ph;
|
||||
|
||||
noff = fdt_node_offset_by_compatible(blob, -1, "arm,mmu-500");
|
||||
if (noff < 0) {
|
||||
printf("WARNING failed to get smmu node: %s\n",
|
||||
fdt_strerror(noff));
|
||||
return noff;
|
||||
}
|
||||
|
||||
smmu_ph = fdt_get_phandle(blob, noff);
|
||||
if (!smmu_ph) {
|
||||
smmu_ph = fdt_create_phandle(blob, noff);
|
||||
if (!smmu_ph) {
|
||||
printf("WARNING failed to get smmu phandle\n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return smmu_ph;
|
||||
}
|
||||
|
||||
void fdt_fixup_icid(void *blob)
|
||||
{
|
||||
int smmu_ph;
|
||||
|
||||
smmu_ph = fdt_get_smmu_phandle(blob);
|
||||
if (smmu_ph < 0)
|
||||
return;
|
||||
|
||||
fdt_fixup_icid_tbl(blob, smmu_ph, icid_tbl, icid_tbl_sz);
|
||||
|
||||
#ifdef CONFIG_SYS_DPAA_FMAN
|
||||
fdt_fixup_fman_icids(blob, smmu_ph);
|
||||
#endif
|
||||
}
|
||||
@@ -0,0 +1,569 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0+ */
|
||||
/*
|
||||
* (C) Copyright 2014-2015 Freescale Semiconductor
|
||||
* Copyright 2019 NXP
|
||||
*
|
||||
* Extracted from armv8/start.S
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include <linux/linkage.h>
|
||||
#include <asm/gic.h>
|
||||
#include <asm/macro.h>
|
||||
#include <asm/arch-fsl-layerscape/soc.h>
|
||||
#ifdef CONFIG_MP
|
||||
#include <asm/arch/mp.h>
|
||||
#endif
|
||||
#ifdef CONFIG_FSL_LSCH3
|
||||
#include <asm/arch-fsl-layerscape/immap_lsch3.h>
|
||||
#endif
|
||||
#include <asm/u-boot.h>
|
||||
|
||||
/* Get GIC offset
|
||||
* For LS1043a rev1.0, GIC base address align with 4k.
|
||||
* For LS1043a rev1.1, if DCFG_GIC400_ALIGN[GIC_ADDR_BIT]
|
||||
* is set, GIC base address align with 4K, or else align
|
||||
* with 64k.
|
||||
* output:
|
||||
* x0: the base address of GICD
|
||||
* x1: the base address of GICC
|
||||
*/
|
||||
ENTRY(get_gic_offset)
|
||||
ldr x0, =GICD_BASE
|
||||
#ifdef CONFIG_GICV2
|
||||
ldr x1, =GICC_BASE
|
||||
#endif
|
||||
#ifdef CONFIG_HAS_FEATURE_GIC64K_ALIGN
|
||||
ldr x2, =DCFG_CCSR_SVR
|
||||
ldr w2, [x2]
|
||||
rev w2, w2
|
||||
lsr w3, w2, #16
|
||||
ldr w4, =SVR_DEV(SVR_LS1043A)
|
||||
cmp w3, w4
|
||||
b.ne 1f
|
||||
ands w2, w2, #0xff
|
||||
cmp w2, #REV1_0
|
||||
b.eq 1f
|
||||
ldr x2, =SCFG_GIC400_ALIGN
|
||||
ldr w2, [x2]
|
||||
rev w2, w2
|
||||
tbnz w2, #GIC_ADDR_BIT, 1f
|
||||
ldr x0, =GICD_BASE_64K
|
||||
#ifdef CONFIG_GICV2
|
||||
ldr x1, =GICC_BASE_64K
|
||||
#endif
|
||||
1:
|
||||
#endif
|
||||
ret
|
||||
ENDPROC(get_gic_offset)
|
||||
|
||||
ENTRY(smp_kick_all_cpus)
|
||||
/* Kick secondary cpus up by SGI 0 interrupt */
|
||||
#if defined(CONFIG_GICV2) || defined(CONFIG_GICV3)
|
||||
mov x29, lr /* Save LR */
|
||||
bl get_gic_offset
|
||||
bl gic_kick_secondary_cpus
|
||||
mov lr, x29 /* Restore LR */
|
||||
#endif
|
||||
ret
|
||||
ENDPROC(smp_kick_all_cpus)
|
||||
|
||||
|
||||
ENTRY(lowlevel_init)
|
||||
mov x29, lr /* Save LR */
|
||||
|
||||
/* unmask SError and abort */
|
||||
msr daifclr, #4
|
||||
|
||||
/* Set HCR_EL2[AMO] so SError @EL2 is taken */
|
||||
mrs x0, hcr_el2
|
||||
orr x0, x0, #0x20 /* AMO */
|
||||
msr hcr_el2, x0
|
||||
isb
|
||||
|
||||
switch_el x1, 1f, 100f, 100f /* skip if not in EL3 */
|
||||
1:
|
||||
|
||||
#if defined (CONFIG_SYS_FSL_HAS_CCN504)
|
||||
|
||||
/* Set Wuo bit for RN-I 20 */
|
||||
#ifdef CONFIG_ARCH_LS2080A
|
||||
ldr x0, =CCI_AUX_CONTROL_BASE(20)
|
||||
ldr x1, =0x00000010
|
||||
bl ccn504_set_aux
|
||||
|
||||
/*
|
||||
* Set forced-order mode in RNI-6, RNI-20
|
||||
* This is required for performance optimization on LS2088A
|
||||
* LS2080A family does not support setting forced-order mode,
|
||||
* so skip this operation for LS2080A family
|
||||
*/
|
||||
bl get_svr
|
||||
lsr w0, w0, #16
|
||||
ldr w1, =SVR_DEV(SVR_LS2080A)
|
||||
cmp w0, w1
|
||||
b.eq 1f
|
||||
|
||||
ldr x0, =CCI_AUX_CONTROL_BASE(6)
|
||||
ldr x1, =0x00000020
|
||||
bl ccn504_set_aux
|
||||
ldr x0, =CCI_AUX_CONTROL_BASE(20)
|
||||
ldr x1, =0x00000020
|
||||
bl ccn504_set_aux
|
||||
1:
|
||||
#endif
|
||||
|
||||
/* Add fully-coherent masters to DVM domain */
|
||||
ldr x0, =CCI_MN_BASE
|
||||
ldr x1, =CCI_MN_RNF_NODEID_LIST
|
||||
ldr x2, =CCI_MN_DVM_DOMAIN_CTL_SET
|
||||
bl ccn504_add_masters_to_dvm
|
||||
|
||||
/* Set all RN-I ports to QoS of 15 */
|
||||
ldr x0, =CCI_S0_QOS_CONTROL_BASE(0)
|
||||
ldr x1, =0x00FF000C
|
||||
bl ccn504_set_qos
|
||||
ldr x0, =CCI_S1_QOS_CONTROL_BASE(0)
|
||||
ldr x1, =0x00FF000C
|
||||
bl ccn504_set_qos
|
||||
ldr x0, =CCI_S2_QOS_CONTROL_BASE(0)
|
||||
ldr x1, =0x00FF000C
|
||||
bl ccn504_set_qos
|
||||
|
||||
ldr x0, =CCI_S0_QOS_CONTROL_BASE(2)
|
||||
ldr x1, =0x00FF000C
|
||||
bl ccn504_set_qos
|
||||
ldr x0, =CCI_S1_QOS_CONTROL_BASE(2)
|
||||
ldr x1, =0x00FF000C
|
||||
bl ccn504_set_qos
|
||||
ldr x0, =CCI_S2_QOS_CONTROL_BASE(2)
|
||||
ldr x1, =0x00FF000C
|
||||
bl ccn504_set_qos
|
||||
|
||||
ldr x0, =CCI_S0_QOS_CONTROL_BASE(6)
|
||||
ldr x1, =0x00FF000C
|
||||
bl ccn504_set_qos
|
||||
ldr x0, =CCI_S1_QOS_CONTROL_BASE(6)
|
||||
ldr x1, =0x00FF000C
|
||||
bl ccn504_set_qos
|
||||
ldr x0, =CCI_S2_QOS_CONTROL_BASE(6)
|
||||
ldr x1, =0x00FF000C
|
||||
bl ccn504_set_qos
|
||||
|
||||
ldr x0, =CCI_S0_QOS_CONTROL_BASE(12)
|
||||
ldr x1, =0x00FF000C
|
||||
bl ccn504_set_qos
|
||||
ldr x0, =CCI_S1_QOS_CONTROL_BASE(12)
|
||||
ldr x1, =0x00FF000C
|
||||
bl ccn504_set_qos
|
||||
ldr x0, =CCI_S2_QOS_CONTROL_BASE(12)
|
||||
ldr x1, =0x00FF000C
|
||||
bl ccn504_set_qos
|
||||
|
||||
ldr x0, =CCI_S0_QOS_CONTROL_BASE(16)
|
||||
ldr x1, =0x00FF000C
|
||||
bl ccn504_set_qos
|
||||
ldr x0, =CCI_S1_QOS_CONTROL_BASE(16)
|
||||
ldr x1, =0x00FF000C
|
||||
bl ccn504_set_qos
|
||||
ldr x0, =CCI_S2_QOS_CONTROL_BASE(16)
|
||||
ldr x1, =0x00FF000C
|
||||
bl ccn504_set_qos
|
||||
|
||||
ldr x0, =CCI_S0_QOS_CONTROL_BASE(20)
|
||||
ldr x1, =0x00FF000C
|
||||
bl ccn504_set_qos
|
||||
ldr x0, =CCI_S1_QOS_CONTROL_BASE(20)
|
||||
ldr x1, =0x00FF000C
|
||||
bl ccn504_set_qos
|
||||
ldr x0, =CCI_S2_QOS_CONTROL_BASE(20)
|
||||
ldr x1, =0x00FF000C
|
||||
bl ccn504_set_qos
|
||||
#endif /* CONFIG_SYS_FSL_HAS_CCN504 */
|
||||
|
||||
#ifdef SMMU_BASE
|
||||
/* Set the SMMU page size in the sACR register */
|
||||
ldr x1, =SMMU_BASE
|
||||
ldr w0, [x1, #0x10]
|
||||
orr w0, w0, #1 << 16 /* set sACR.pagesize to indicate 64K page */
|
||||
str w0, [x1, #0x10]
|
||||
#endif
|
||||
|
||||
/* Initialize GIC Secure Bank Status */
|
||||
#if defined(CONFIG_GICV2) || defined(CONFIG_GICV3)
|
||||
branch_if_slave x0, 1f
|
||||
bl get_gic_offset
|
||||
bl gic_init_secure
|
||||
1:
|
||||
#ifdef CONFIG_GICV3
|
||||
ldr x0, =GICR_BASE
|
||||
bl gic_init_secure_percpu
|
||||
#elif defined(CONFIG_GICV2)
|
||||
bl get_gic_offset
|
||||
bl gic_init_secure_percpu
|
||||
#endif
|
||||
#endif
|
||||
|
||||
100:
|
||||
branch_if_master x0, x1, 2f
|
||||
|
||||
#if defined(CONFIG_MP) && defined(CONFIG_ARMV8_MULTIENTRY)
|
||||
ldr x0, =secondary_boot_func
|
||||
blr x0
|
||||
#endif
|
||||
|
||||
2:
|
||||
switch_el x1, 1f, 100f, 100f /* skip if not in EL3 */
|
||||
1:
|
||||
#ifdef CONFIG_FSL_TZPC_BP147
|
||||
/* Set Non Secure access for all devices protected via TZPC */
|
||||
ldr x1, =TZPCDECPROT_0_SET_BASE /* Decode Protection-0 Set Reg */
|
||||
orr w0, w0, #1 << 3 /* DCFG_RESET is accessible from NS world */
|
||||
str w0, [x1]
|
||||
|
||||
isb
|
||||
dsb sy
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_FSL_TZASC_400
|
||||
/*
|
||||
* LS2080 and its personalities does not support TZASC
|
||||
* So skip TZASC related operations
|
||||
*/
|
||||
bl get_svr
|
||||
lsr w0, w0, #16
|
||||
ldr w1, =SVR_DEV(SVR_LS2080A)
|
||||
cmp w0, w1
|
||||
b.eq 1f
|
||||
|
||||
/* Set TZASC so that:
|
||||
* a. We use only Region0 whose global secure write/read is EN
|
||||
* b. We use only Region0 whose NSAID write/read is EN
|
||||
*
|
||||
* NOTE: As per the CCSR map doc, TZASC 3 and TZASC 4 are just
|
||||
* placeholders.
|
||||
*/
|
||||
|
||||
.macro tzasc_prog, xreg
|
||||
|
||||
mov x12, TZASC1_BASE
|
||||
mov x16, #0x10000
|
||||
mul x14, \xreg, x16
|
||||
add x14, x14,x12
|
||||
mov x1, #0x8
|
||||
add x1, x1, x14
|
||||
|
||||
ldr w0, [x1] /* Filter 0 Gate Keeper Register */
|
||||
orr w0, w0, #1 << 0 /* Set open_request for Filter 0 */
|
||||
str w0, [x1]
|
||||
|
||||
mov x1, #0x110
|
||||
add x1, x1, x14
|
||||
|
||||
ldr w0, [x1] /* Region-0 Attributes Register */
|
||||
orr w0, w0, #1 << 31 /* Set Sec global write en, Bit[31] */
|
||||
orr w0, w0, #1 << 30 /* Set Sec global read en, Bit[30] */
|
||||
str w0, [x1]
|
||||
|
||||
mov x1, #0x114
|
||||
add x1, x1, x14
|
||||
|
||||
ldr w0, [x1] /* Region-0 Access Register */
|
||||
mov w0, #0xFFFFFFFF /* Set nsaid_wr_en and nsaid_rd_en */
|
||||
str w0, [x1]
|
||||
.endm
|
||||
|
||||
#ifdef CONFIG_FSL_TZASC_1
|
||||
mov x13, #0
|
||||
tzasc_prog x13
|
||||
|
||||
#endif
|
||||
#ifdef CONFIG_FSL_TZASC_2
|
||||
mov x13, #1
|
||||
tzasc_prog x13
|
||||
|
||||
#endif
|
||||
isb
|
||||
dsb sy
|
||||
#endif
|
||||
100:
|
||||
1:
|
||||
#ifdef CONFIG_ARCH_LS1046A
|
||||
switch_el x1, 1f, 100f, 100f /* skip if not in EL3 */
|
||||
1:
|
||||
/* 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
|
||||
100:
|
||||
#endif
|
||||
|
||||
#if !defined(CONFIG_TFABOOT) && \
|
||||
(defined(CONFIG_FSL_LSCH2) && !defined(CONFIG_SPL_BUILD))
|
||||
bl fsl_ocram_init
|
||||
#endif
|
||||
|
||||
mov lr, x29 /* Restore LR */
|
||||
ret
|
||||
ENDPROC(lowlevel_init)
|
||||
|
||||
#if defined(CONFIG_FSL_LSCH2) && !defined(CONFIG_SPL_BUILD)
|
||||
ENTRY(fsl_ocram_init)
|
||||
mov x28, lr /* Save LR */
|
||||
bl fsl_clear_ocram
|
||||
bl fsl_ocram_clear_ecc_err
|
||||
mov lr, x28 /* Restore LR */
|
||||
ret
|
||||
ENDPROC(fsl_ocram_init)
|
||||
|
||||
ENTRY(fsl_clear_ocram)
|
||||
/* Clear OCRAM */
|
||||
ldr x0, =CONFIG_SYS_FSL_OCRAM_BASE
|
||||
ldr x1, =(CONFIG_SYS_FSL_OCRAM_BASE + CONFIG_SYS_FSL_OCRAM_SIZE)
|
||||
mov x2, #0
|
||||
clear_loop:
|
||||
str x2, [x0]
|
||||
add x0, x0, #8
|
||||
cmp x0, x1
|
||||
b.lo clear_loop
|
||||
ret
|
||||
ENDPROC(fsl_clear_ocram)
|
||||
|
||||
ENTRY(fsl_ocram_clear_ecc_err)
|
||||
/* OCRAM1/2 ECC status bit */
|
||||
mov w1, #0x60
|
||||
ldr x0, =DCSR_DCFG_SBEESR2
|
||||
str w1, [x0]
|
||||
ldr x0, =DCSR_DCFG_MBEESR2
|
||||
str w1, [x0]
|
||||
ret
|
||||
ENDPROC(fsl_ocram_init)
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_FSL_LSCH3
|
||||
.globl get_svr
|
||||
get_svr:
|
||||
ldr x1, =FSL_LSCH3_SVR
|
||||
ldr w0, [x1]
|
||||
ret
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_SYS_FSL_HAS_CCN504) || defined(CONFIG_SYS_FSL_HAS_CCN508)
|
||||
hnf_pstate_poll:
|
||||
/* x0 has the desired status, return only if operation succeed
|
||||
* clobber x1, x2, x6
|
||||
*/
|
||||
mov x1, x0
|
||||
mov w6, #8 /* HN-F node count */
|
||||
mov x0, #0x18
|
||||
movk x0, #0x420, lsl #16 /* HNF0_PSTATE_STATUS */
|
||||
1:
|
||||
ldr x2, [x0]
|
||||
cmp x2, x1 /* check status */
|
||||
b.eq 2f
|
||||
b 1b
|
||||
2:
|
||||
add x0, x0, #0x10000 /* move to next node */
|
||||
subs w6, w6, #1
|
||||
cbnz w6, 1b
|
||||
ret
|
||||
|
||||
hnf_set_pstate:
|
||||
/* x0 has the desired state, clobber x1, x2, x6 */
|
||||
mov x1, x0
|
||||
/* power state to SFONLY */
|
||||
mov w6, #8 /* HN-F node count */
|
||||
mov x0, #0x10
|
||||
movk x0, #0x420, lsl #16 /* HNF0_PSTATE_REQ */
|
||||
1: /* set pstate to sfonly */
|
||||
ldr x2, [x0]
|
||||
and x2, x2, #0xfffffffffffffffc /* & HNFPSTAT_MASK */
|
||||
orr x2, x2, x1
|
||||
str x2, [x0]
|
||||
add x0, x0, #0x10000 /* move to next node */
|
||||
subs w6, w6, #1
|
||||
cbnz w6, 1b
|
||||
|
||||
ret
|
||||
|
||||
ENTRY(__asm_flush_l3_dcache)
|
||||
/*
|
||||
* Return status in x0
|
||||
* success 0
|
||||
*/
|
||||
mov x29, lr
|
||||
|
||||
dsb sy
|
||||
mov x0, #0x1 /* HNFPSTAT_SFONLY */
|
||||
bl hnf_set_pstate
|
||||
|
||||
mov x0, #0x4 /* SFONLY status */
|
||||
bl hnf_pstate_poll
|
||||
|
||||
dsb sy
|
||||
mov x0, #0x3 /* HNFPSTAT_FAM */
|
||||
bl hnf_set_pstate
|
||||
|
||||
mov x0, #0xc /* FAM status */
|
||||
bl hnf_pstate_poll
|
||||
|
||||
mov x0, #0
|
||||
mov lr, x29
|
||||
ret
|
||||
ENDPROC(__asm_flush_l3_dcache)
|
||||
#endif /* CONFIG_SYS_FSL_HAS_CCN504 */
|
||||
|
||||
#ifdef CONFIG_MP
|
||||
/* Keep literals not used by the secondary boot code outside it */
|
||||
.ltorg
|
||||
|
||||
/* Using 64 bit alignment since the spin table is accessed as data */
|
||||
.align 4
|
||||
.global secondary_boot_code
|
||||
/* Secondary Boot Code starts here */
|
||||
secondary_boot_code:
|
||||
.global __spin_table
|
||||
__spin_table:
|
||||
.space CONFIG_MAX_CPUS*SPIN_TABLE_ELEM_SIZE
|
||||
|
||||
.align 2
|
||||
ENTRY(secondary_boot_func)
|
||||
/*
|
||||
* MPIDR_EL1 Fields:
|
||||
* MPIDR[1:0] = AFF0_CPUID <- Core ID (0,1)
|
||||
* MPIDR[7:2] = AFF0_RES
|
||||
* MPIDR[15:8] = AFF1_CLUSTERID <- Cluster ID (0,1,2,3)
|
||||
* MPIDR[23:16] = AFF2_CLUSTERID
|
||||
* MPIDR[24] = MT
|
||||
* MPIDR[29:25] = RES0
|
||||
* MPIDR[30] = U
|
||||
* MPIDR[31] = ME
|
||||
* MPIDR[39:32] = AFF3
|
||||
*
|
||||
* Linear Processor ID (LPID) calculation from MPIDR_EL1:
|
||||
* (We only use AFF0_CPUID and AFF1_CLUSTERID for now
|
||||
* until AFF2_CLUSTERID and AFF3 have non-zero values)
|
||||
*
|
||||
* LPID = MPIDR[15:8] | MPIDR[1:0]
|
||||
*/
|
||||
mrs x0, mpidr_el1
|
||||
ubfm x1, x0, #8, #15
|
||||
ubfm x2, x0, #0, #1
|
||||
orr x10, x2, x1, lsl #2 /* x10 has LPID */
|
||||
ubfm x9, x0, #0, #15 /* x9 contains MPIDR[15:0] */
|
||||
/*
|
||||
* offset of the spin table element for this core from start of spin
|
||||
* table (each elem is padded to 64 bytes)
|
||||
*/
|
||||
lsl x1, x10, #6
|
||||
ldr x0, =__spin_table
|
||||
/* physical address of this cpus spin table element */
|
||||
add x11, x1, x0
|
||||
|
||||
ldr x0, =__real_cntfrq
|
||||
ldr x0, [x0]
|
||||
msr cntfrq_el0, x0 /* set with real frequency */
|
||||
str x9, [x11, #16] /* LPID */
|
||||
mov x4, #1
|
||||
str x4, [x11, #8] /* STATUS */
|
||||
dsb sy
|
||||
#if defined(CONFIG_GICV3)
|
||||
gic_wait_for_interrupt_m x0
|
||||
#elif defined(CONFIG_GICV2)
|
||||
bl get_gic_offset
|
||||
mov x0, x1
|
||||
gic_wait_for_interrupt_m x0, w1
|
||||
#endif
|
||||
|
||||
slave_cpu:
|
||||
wfe
|
||||
ldr x0, [x11]
|
||||
cbz x0, slave_cpu
|
||||
#ifndef CONFIG_ARMV8_SWITCH_TO_EL1
|
||||
mrs x1, sctlr_el2
|
||||
#else
|
||||
mrs x1, sctlr_el1
|
||||
#endif
|
||||
tbz x1, #25, cpu_is_le
|
||||
rev x0, x0 /* BE to LE conversion */
|
||||
cpu_is_le:
|
||||
ldr x5, [x11, #24]
|
||||
cbz x5, 1f
|
||||
|
||||
#ifdef CONFIG_ARMV8_SWITCH_TO_EL1
|
||||
adr x4, secondary_switch_to_el1
|
||||
ldr x5, =ES_TO_AARCH64
|
||||
#else
|
||||
ldr x4, [x11]
|
||||
ldr x5, =ES_TO_AARCH32
|
||||
#endif
|
||||
bl secondary_switch_to_el2
|
||||
|
||||
1:
|
||||
#ifdef CONFIG_ARMV8_SWITCH_TO_EL1
|
||||
adr x4, secondary_switch_to_el1
|
||||
#else
|
||||
ldr x4, [x11]
|
||||
#endif
|
||||
ldr x5, =ES_TO_AARCH64
|
||||
bl secondary_switch_to_el2
|
||||
|
||||
ENDPROC(secondary_boot_func)
|
||||
|
||||
ENTRY(secondary_switch_to_el2)
|
||||
switch_el x6, 1f, 0f, 0f
|
||||
0: ret
|
||||
1: armv8_switch_to_el2_m x4, x5, x6
|
||||
ENDPROC(secondary_switch_to_el2)
|
||||
|
||||
ENTRY(secondary_switch_to_el1)
|
||||
mrs x0, mpidr_el1
|
||||
ubfm x1, x0, #8, #15
|
||||
ubfm x2, x0, #0, #1
|
||||
orr x10, x2, x1, lsl #2 /* x10 has LPID */
|
||||
|
||||
lsl x1, x10, #6
|
||||
ldr x0, =__spin_table
|
||||
/* physical address of this cpus spin table element */
|
||||
add x11, x1, x0
|
||||
|
||||
ldr x4, [x11]
|
||||
|
||||
ldr x5, [x11, #24]
|
||||
cbz x5, 2f
|
||||
|
||||
ldr x5, =ES_TO_AARCH32
|
||||
bl switch_to_el1
|
||||
|
||||
2: ldr x5, =ES_TO_AARCH64
|
||||
|
||||
switch_to_el1:
|
||||
switch_el x6, 0f, 1f, 0f
|
||||
0: ret
|
||||
1: armv8_switch_to_el1_m x4, x5, x6
|
||||
ENDPROC(secondary_switch_to_el1)
|
||||
|
||||
/* Ensure that the literals used by the secondary boot code are
|
||||
* assembled within it (this is required so that we can protect
|
||||
* this area with a single memreserve region
|
||||
*/
|
||||
.ltorg
|
||||
|
||||
/* 64 bit alignment for elements accessed as data */
|
||||
.align 4
|
||||
.global __real_cntfrq
|
||||
__real_cntfrq:
|
||||
.quad COUNTER_FREQUENCY
|
||||
.globl __secondary_boot_code_size
|
||||
.type __secondary_boot_code_size, %object
|
||||
/* Secondary Boot Code ends here */
|
||||
__secondary_boot_code_size:
|
||||
.quad .-secondary_boot_code
|
||||
#endif
|
||||
@@ -0,0 +1,73 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Copyright 2016 Freescale Semiconductor, Inc.
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <asm/arch/fsl_serdes.h>
|
||||
#include <asm/arch/immap_lsch2.h>
|
||||
|
||||
struct serdes_config {
|
||||
u32 protocol;
|
||||
u8 lanes[SRDS_MAX_LANES];
|
||||
};
|
||||
|
||||
static struct serdes_config serdes1_cfg_tbl[] = {
|
||||
{0x2208, {SGMII_2500_FM1_DTSEC1, SGMII_2500_FM1_DTSEC2, NONE, SATA1} },
|
||||
{0x0008, {NONE, NONE, NONE, SATA1} },
|
||||
{0x3508, {SGMII_FM1_DTSEC1, PCIE1, NONE, SATA1} },
|
||||
{0x3305, {SGMII_FM1_DTSEC1, SGMII_FM1_DTSEC2, NONE, PCIE1} },
|
||||
{0x2205, {SGMII_2500_FM1_DTSEC1, SGMII_2500_FM1_DTSEC2, NONE, PCIE1} },
|
||||
{0x2305, {SGMII_2500_FM1_DTSEC1, SGMII_FM1_DTSEC2, NONE, PCIE1} },
|
||||
{0x9508, {TX_CLK, PCIE1, NONE, SATA1} },
|
||||
{0x3905, {SGMII_FM1_DTSEC1, TX_CLK, NONE, PCIE1} },
|
||||
{0x9305, {TX_CLK, SGMII_FM1_DTSEC2, NONE, PCIE1} },
|
||||
{}
|
||||
};
|
||||
|
||||
static struct serdes_config *serdes_cfg_tbl[] = {
|
||||
serdes1_cfg_tbl,
|
||||
};
|
||||
|
||||
enum srds_prtcl serdes_get_prtcl(int serdes, int cfg, int lane)
|
||||
{
|
||||
struct serdes_config *ptr;
|
||||
|
||||
if (serdes >= ARRAY_SIZE(serdes_cfg_tbl))
|
||||
return 0;
|
||||
|
||||
ptr = serdes_cfg_tbl[serdes];
|
||||
while (ptr->protocol) {
|
||||
if (ptr->protocol == cfg)
|
||||
return ptr->lanes[lane];
|
||||
ptr++;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int is_serdes_prtcl_valid(int serdes, u32 prtcl)
|
||||
{
|
||||
int i;
|
||||
struct serdes_config *ptr;
|
||||
|
||||
if (serdes >= ARRAY_SIZE(serdes_cfg_tbl))
|
||||
return 0;
|
||||
|
||||
ptr = serdes_cfg_tbl[serdes];
|
||||
while (ptr->protocol) {
|
||||
if (ptr->protocol == prtcl)
|
||||
break;
|
||||
ptr++;
|
||||
}
|
||||
|
||||
if (!ptr->protocol)
|
||||
return 0;
|
||||
|
||||
for (i = 0; i < SRDS_MAX_LANES; i++) {
|
||||
if (ptr->lanes[i] != NONE)
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Copyright 2019 NXP
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <asm/arch-fsl-layerscape/immap_lsch3.h>
|
||||
#include <asm/arch-fsl-layerscape/fsl_icid.h>
|
||||
#include <asm/arch-fsl-layerscape/fsl_portals.h>
|
||||
|
||||
struct icid_id_table icid_tbl[] = {
|
||||
SET_USB_ICID(1, "snps,dwc3", FSL_USB1_STREAM_ID),
|
||||
SET_USB_ICID(2, "snps,dwc3", FSL_USB2_STREAM_ID),
|
||||
SET_SDHC_ICID(1, FSL_SDMMC_STREAM_ID),
|
||||
SET_SDHC_ICID(2, FSL_SDMMC2_STREAM_ID),
|
||||
SET_SATA_ICID(1, "fsl,ls1028a-ahci", FSL_SATA1_STREAM_ID),
|
||||
SET_EDMA_ICID(FSL_EDMA_STREAM_ID),
|
||||
SET_QDMA_ICID("fsl,ls1028a-qdma", FSL_DMA_STREAM_ID),
|
||||
SET_GPU_ICID("fsl,ls1028a-gpu", FSL_GPU_STREAM_ID),
|
||||
SET_DISPLAY_ICID(FSL_DISPLAY_STREAM_ID),
|
||||
#ifdef CONFIG_FSL_CAAM
|
||||
SET_SEC_JR_ICID_ENTRY(0, FSL_SEC_JR1_STREAM_ID),
|
||||
SET_SEC_JR_ICID_ENTRY(1, FSL_SEC_JR2_STREAM_ID),
|
||||
SET_SEC_JR_ICID_ENTRY(2, FSL_SEC_JR3_STREAM_ID),
|
||||
SET_SEC_JR_ICID_ENTRY(3, FSL_SEC_JR4_STREAM_ID),
|
||||
SET_SEC_RTIC_ICID_ENTRY(0, FSL_SEC_STREAM_ID),
|
||||
SET_SEC_RTIC_ICID_ENTRY(1, FSL_SEC_STREAM_ID),
|
||||
SET_SEC_RTIC_ICID_ENTRY(2, FSL_SEC_STREAM_ID),
|
||||
SET_SEC_RTIC_ICID_ENTRY(3, FSL_SEC_STREAM_ID),
|
||||
SET_SEC_DECO_ICID_ENTRY(0, FSL_SEC_STREAM_ID),
|
||||
SET_SEC_DECO_ICID_ENTRY(1, FSL_SEC_STREAM_ID),
|
||||
#endif
|
||||
};
|
||||
|
||||
int icid_tbl_sz = ARRAY_SIZE(icid_tbl);
|
||||
@@ -0,0 +1,86 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Copyright 2019 NXP
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <asm/arch/fsl_serdes.h>
|
||||
|
||||
struct serdes_config {
|
||||
u32 protocol;
|
||||
u8 lanes[SRDS_MAX_LANES];
|
||||
u8 rcw_lanes[SRDS_MAX_LANES];
|
||||
};
|
||||
|
||||
static struct serdes_config serdes1_cfg_tbl[] = {
|
||||
/* SerDes 1 */
|
||||
{0xCC5B, {PCIE1, QSGMII_B, PCIE2, PCIE2} },
|
||||
{0xEB99, {SGMII1, SGMII1, PCIE2, SATA1} },
|
||||
{0xCC99, {SGMII1, SGMII1, PCIE2, PCIE2} },
|
||||
{0xBB99, {SGMII1, SGMII1, PCIE2, PCIE1} },
|
||||
{0x9999, {SGMII1, SGMII2, SGMII3, SGMII4} },
|
||||
{0xEBCC, {PCIE1, PCIE1, PCIE2, SATA1} },
|
||||
{0xCCCC, {PCIE1, PCIE1, PCIE2, PCIE2} },
|
||||
{0xDDDD, {PCIE1, PCIE1, PCIE1, PCIE1} },
|
||||
{0xE031, {SXGMII1, QXGMII2, NONE, SATA1} },
|
||||
{0xB991, {SXGMII1, SGMII1, SGMII2, PCIE1} },
|
||||
{0xBB31, {SXGMII1, QXGMII2, PCIE2, PCIE1} },
|
||||
{0xCC31, {SXGMII1, QXGMII2, PCIE2, PCIE2} },
|
||||
{0xBB51, {SXGMII1, QSGMII_B, PCIE2, PCIE1} },
|
||||
{0xBB38, {SGMII_T1, QXGMII2, PCIE2, PCIE1} },
|
||||
{0xCC38, {SGMII_T1, QXGMII2, PCIE2, PCIE2} },
|
||||
{0xBB58, {SGMII_T1, QSGMII_B, PCIE2, PCIE1} },
|
||||
{0xCC58, {SGMII_T1, QSGMII_B, PCIE2, PCIE2} },
|
||||
{0xCC8B, {PCIE1, SGMII_T1, PCIE2, PCIE2} },
|
||||
{0xEB58, {SGMII_T1, QSGMII_B, PCIE2, SATA1} },
|
||||
{0xEB8B, {PCIE1, SGMII_T1, PCIE2, SATA1} },
|
||||
{0xE8CC, {PCIE1, PCIE1, SGMII_T1, SATA1} },
|
||||
{}
|
||||
};
|
||||
|
||||
static struct serdes_config *serdes_cfg_tbl[] = {
|
||||
serdes1_cfg_tbl,
|
||||
};
|
||||
|
||||
enum srds_prtcl serdes_get_prtcl(int serdes, int cfg, int lane)
|
||||
{
|
||||
struct serdes_config *ptr;
|
||||
|
||||
if (serdes >= ARRAY_SIZE(serdes_cfg_tbl))
|
||||
return 0;
|
||||
|
||||
ptr = serdes_cfg_tbl[serdes];
|
||||
while (ptr->protocol) {
|
||||
if (ptr->protocol == cfg)
|
||||
return ptr->lanes[lane];
|
||||
ptr++;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int is_serdes_prtcl_valid(int serdes, u32 prtcl)
|
||||
{
|
||||
int i;
|
||||
struct serdes_config *ptr;
|
||||
|
||||
if (serdes >= ARRAY_SIZE(serdes_cfg_tbl))
|
||||
return 0;
|
||||
|
||||
ptr = serdes_cfg_tbl[serdes];
|
||||
while (ptr->protocol) {
|
||||
if (ptr->protocol == prtcl)
|
||||
break;
|
||||
ptr++;
|
||||
}
|
||||
|
||||
if (!ptr->protocol)
|
||||
return 0;
|
||||
|
||||
for (i = 0; i < SRDS_MAX_LANES; i++) {
|
||||
if (ptr->lanes[i] != NONE)
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Copyright 2018 NXP
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <asm/arch-fsl-layerscape/immap_lsch2.h>
|
||||
#include <asm/arch-fsl-layerscape/fsl_icid.h>
|
||||
#include <asm/arch-fsl-layerscape/fsl_portals.h>
|
||||
#include <fsl_sec.h>
|
||||
|
||||
#ifdef CONFIG_SYS_DPAA_QBMAN
|
||||
struct qportal_info qp_info[CONFIG_SYS_QMAN_NUM_PORTALS] = {
|
||||
SET_QP_INFO(FSL_DPAA1_STREAM_ID_END, 0),
|
||||
SET_QP_INFO(FSL_DPAA1_STREAM_ID_END, 0),
|
||||
SET_QP_INFO(FSL_DPAA1_STREAM_ID_END, 0),
|
||||
SET_QP_INFO(FSL_DPAA1_STREAM_ID_END, 0),
|
||||
SET_QP_INFO(FSL_DPAA1_STREAM_ID_END, 0),
|
||||
SET_QP_INFO(FSL_DPAA1_STREAM_ID_END, 0),
|
||||
SET_QP_INFO(FSL_DPAA1_STREAM_ID_END, 0),
|
||||
SET_QP_INFO(FSL_DPAA1_STREAM_ID_END, 0),
|
||||
SET_QP_INFO(FSL_DPAA1_STREAM_ID_END, 0),
|
||||
SET_QP_INFO(FSL_DPAA1_STREAM_ID_END, 0),
|
||||
};
|
||||
#endif
|
||||
|
||||
struct icid_id_table icid_tbl[] = {
|
||||
#ifdef CONFIG_SYS_DPAA_QBMAN
|
||||
SET_QMAN_ICID(FSL_DPAA1_STREAM_ID_START),
|
||||
SET_BMAN_ICID(FSL_DPAA1_STREAM_ID_START + 1),
|
||||
#endif
|
||||
|
||||
SET_SDHC_ICID(FSL_SDHC_STREAM_ID),
|
||||
|
||||
SET_USB_ICID(1, "snps,dwc3", FSL_USB1_STREAM_ID),
|
||||
SET_USB_ICID(2, "snps,dwc3", FSL_USB2_STREAM_ID),
|
||||
SET_USB_ICID(3, "snps,dwc3", FSL_USB3_STREAM_ID),
|
||||
|
||||
SET_SATA_ICID("fsl,ls1043a-ahci", FSL_SATA_STREAM_ID),
|
||||
SET_QDMA_ICID("fsl,ls1043a-qdma", FSL_QDMA_STREAM_ID),
|
||||
SET_EDMA_ICID(FSL_EDMA_STREAM_ID),
|
||||
SET_ETR_ICID(FSL_ETR_STREAM_ID),
|
||||
SET_DEBUG_ICID(FSL_DEBUG_STREAM_ID),
|
||||
SET_QE_ICID(FSL_QE_STREAM_ID),
|
||||
#ifdef CONFIG_FSL_CAAM
|
||||
SET_SEC_QI_ICID(FSL_DPAA1_STREAM_ID_END),
|
||||
SET_SEC_JR_ICID_ENTRY(0, FSL_DPAA1_STREAM_ID_START + 3),
|
||||
SET_SEC_JR_ICID_ENTRY(1, FSL_DPAA1_STREAM_ID_START + 4),
|
||||
SET_SEC_JR_ICID_ENTRY(2, FSL_DPAA1_STREAM_ID_START + 5),
|
||||
SET_SEC_JR_ICID_ENTRY(3, FSL_DPAA1_STREAM_ID_START + 6),
|
||||
SET_SEC_RTIC_ICID_ENTRY(0, FSL_DPAA1_STREAM_ID_START + 7),
|
||||
SET_SEC_RTIC_ICID_ENTRY(1, FSL_DPAA1_STREAM_ID_START + 8),
|
||||
SET_SEC_RTIC_ICID_ENTRY(2, FSL_DPAA1_STREAM_ID_START + 9),
|
||||
SET_SEC_RTIC_ICID_ENTRY(3, FSL_DPAA1_STREAM_ID_START + 10),
|
||||
SET_SEC_DECO_ICID_ENTRY(0, FSL_DPAA1_STREAM_ID_START + 11),
|
||||
SET_SEC_DECO_ICID_ENTRY(1, FSL_DPAA1_STREAM_ID_START + 12),
|
||||
#endif
|
||||
};
|
||||
|
||||
int icid_tbl_sz = ARRAY_SIZE(icid_tbl);
|
||||
|
||||
#ifdef CONFIG_SYS_DPAA_FMAN
|
||||
struct fman_icid_id_table fman_icid_tbl[] = {
|
||||
/* port id, icid */
|
||||
SET_FMAN_ICID_ENTRY(0x02, FSL_DPAA1_STREAM_ID_END),
|
||||
SET_FMAN_ICID_ENTRY(0x03, FSL_DPAA1_STREAM_ID_END),
|
||||
SET_FMAN_ICID_ENTRY(0x04, FSL_DPAA1_STREAM_ID_END),
|
||||
SET_FMAN_ICID_ENTRY(0x05, FSL_DPAA1_STREAM_ID_END),
|
||||
SET_FMAN_ICID_ENTRY(0x06, FSL_DPAA1_STREAM_ID_END),
|
||||
SET_FMAN_ICID_ENTRY(0x07, FSL_DPAA1_STREAM_ID_END),
|
||||
SET_FMAN_ICID_ENTRY(0x08, FSL_DPAA1_STREAM_ID_END),
|
||||
SET_FMAN_ICID_ENTRY(0x09, FSL_DPAA1_STREAM_ID_END),
|
||||
SET_FMAN_ICID_ENTRY(0x0a, FSL_DPAA1_STREAM_ID_END),
|
||||
SET_FMAN_ICID_ENTRY(0x0b, FSL_DPAA1_STREAM_ID_END),
|
||||
SET_FMAN_ICID_ENTRY(0x0c, FSL_DPAA1_STREAM_ID_END),
|
||||
SET_FMAN_ICID_ENTRY(0x0d, FSL_DPAA1_STREAM_ID_END),
|
||||
SET_FMAN_ICID_ENTRY(0x28, FSL_DPAA1_STREAM_ID_END),
|
||||
SET_FMAN_ICID_ENTRY(0x29, FSL_DPAA1_STREAM_ID_END),
|
||||
SET_FMAN_ICID_ENTRY(0x2a, FSL_DPAA1_STREAM_ID_END),
|
||||
SET_FMAN_ICID_ENTRY(0x2b, FSL_DPAA1_STREAM_ID_END),
|
||||
SET_FMAN_ICID_ENTRY(0x2c, FSL_DPAA1_STREAM_ID_END),
|
||||
SET_FMAN_ICID_ENTRY(0x2d, FSL_DPAA1_STREAM_ID_END),
|
||||
SET_FMAN_ICID_ENTRY(0x10, FSL_DPAA1_STREAM_ID_END),
|
||||
SET_FMAN_ICID_ENTRY(0x11, FSL_DPAA1_STREAM_ID_END),
|
||||
SET_FMAN_ICID_ENTRY(0x30, FSL_DPAA1_STREAM_ID_END),
|
||||
SET_FMAN_ICID_ENTRY(0x31, FSL_DPAA1_STREAM_ID_END),
|
||||
};
|
||||
|
||||
int fman_icid_tbl_sz = ARRAY_SIZE(fman_icid_tbl);
|
||||
#endif
|
||||
@@ -0,0 +1,19 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0+ */
|
||||
/*
|
||||
* Copyright 2016 Freescale Semiconductor, Inc.
|
||||
* Author: Hongbo Zhang <hongbo.zhang@nxp.com>
|
||||
* This file implements LS102X platform PSCI SYSTEM-SUSPEND function
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include <linux/linkage.h>
|
||||
#include <asm/psci.h>
|
||||
|
||||
.pushsection ._secure.text, "ax"
|
||||
|
||||
.globl psci_version
|
||||
psci_version:
|
||||
ldr w0, =0x00010000 /* PSCI v1.0 */
|
||||
ret
|
||||
|
||||
.popsection
|
||||
@@ -0,0 +1,85 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Copyright 2015 Freescale Semiconductor, Inc.
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <asm/arch/fsl_serdes.h>
|
||||
#include <asm/arch/immap_lsch2.h>
|
||||
|
||||
struct serdes_config {
|
||||
u32 protocol;
|
||||
u8 lanes[SRDS_MAX_LANES];
|
||||
};
|
||||
|
||||
static struct serdes_config serdes1_cfg_tbl[] = {
|
||||
/* SerDes 1 */
|
||||
{0x1555, {XFI_FM1_MAC9, PCIE1, PCIE2, PCIE3} },
|
||||
{0x2555, {SGMII_2500_FM1_DTSEC9, PCIE1, PCIE2, PCIE3} },
|
||||
{0x4555, {QSGMII_FM1_A, PCIE1, PCIE2, PCIE3} },
|
||||
{0x4558, {QSGMII_FM1_A, PCIE1, PCIE2, SATA1} },
|
||||
{0x1355, {XFI_FM1_MAC9, SGMII_FM1_DTSEC2, PCIE2, PCIE3} },
|
||||
{0x2355, {SGMII_2500_FM1_DTSEC9, SGMII_FM1_DTSEC2, PCIE2, PCIE3} },
|
||||
{0x3335, {SGMII_FM1_DTSEC9, SGMII_FM1_DTSEC2, SGMII_FM1_DTSEC5,
|
||||
PCIE3} },
|
||||
{0x3355, {SGMII_FM1_DTSEC9, SGMII_FM1_DTSEC2, PCIE2, PCIE3} },
|
||||
{0x3358, {SGMII_FM1_DTSEC9, SGMII_FM1_DTSEC2, PCIE2, SATA1} },
|
||||
{0x3555, {SGMII_FM1_DTSEC9, PCIE1, PCIE2, PCIE3} },
|
||||
{0x3558, {SGMII_FM1_DTSEC9, PCIE1, PCIE2, SATA1} },
|
||||
{0x7000, {PCIE1, PCIE1, PCIE1, PCIE1} },
|
||||
{0x9998, {PCIE1, PCIE2, PCIE3, SATA1} },
|
||||
{0x6058, {PCIE1, PCIE1, PCIE2, SATA1} },
|
||||
{0x1455, {XFI_FM1_MAC9, QSGMII_FM1_A, PCIE2, PCIE3} },
|
||||
{0x2455, {SGMII_2500_FM1_DTSEC9, QSGMII_FM1_A, PCIE2, PCIE3} },
|
||||
{0x2255, {SGMII_2500_FM1_DTSEC9, SGMII_2500_FM1_DTSEC2, PCIE2, PCIE3} },
|
||||
{0x3333, {SGMII_FM1_DTSEC9, SGMII_FM1_DTSEC2, SGMII_FM1_DTSEC5,
|
||||
SGMII_FM1_DTSEC6} },
|
||||
{}
|
||||
};
|
||||
|
||||
static struct serdes_config *serdes_cfg_tbl[] = {
|
||||
serdes1_cfg_tbl,
|
||||
};
|
||||
|
||||
enum srds_prtcl serdes_get_prtcl(int serdes, int cfg, int lane)
|
||||
{
|
||||
struct serdes_config *ptr;
|
||||
|
||||
if (serdes >= ARRAY_SIZE(serdes_cfg_tbl))
|
||||
return 0;
|
||||
|
||||
ptr = serdes_cfg_tbl[serdes];
|
||||
while (ptr->protocol) {
|
||||
if (ptr->protocol == cfg)
|
||||
return ptr->lanes[lane];
|
||||
ptr++;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int is_serdes_prtcl_valid(int serdes, u32 prtcl)
|
||||
{
|
||||
int i;
|
||||
struct serdes_config *ptr;
|
||||
|
||||
if (serdes >= ARRAY_SIZE(serdes_cfg_tbl))
|
||||
return 0;
|
||||
|
||||
ptr = serdes_cfg_tbl[serdes];
|
||||
while (ptr->protocol) {
|
||||
if (ptr->protocol == prtcl)
|
||||
break;
|
||||
ptr++;
|
||||
}
|
||||
|
||||
if (!ptr->protocol)
|
||||
return 0;
|
||||
|
||||
for (i = 0; i < SRDS_MAX_LANES; i++) {
|
||||
if (ptr->lanes[i] != NONE)
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Copyright 2018 NXP
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <asm/arch-fsl-layerscape/immap_lsch2.h>
|
||||
#include <asm/arch-fsl-layerscape/fsl_icid.h>
|
||||
#include <asm/arch-fsl-layerscape/fsl_portals.h>
|
||||
|
||||
#ifdef CONFIG_SYS_DPAA_QBMAN
|
||||
struct qportal_info qp_info[CONFIG_SYS_QMAN_NUM_PORTALS] = {
|
||||
SET_QP_INFO(FSL_DPAA1_STREAM_ID_END, 0),
|
||||
SET_QP_INFO(FSL_DPAA1_STREAM_ID_END, 0),
|
||||
SET_QP_INFO(FSL_DPAA1_STREAM_ID_END, 0),
|
||||
SET_QP_INFO(FSL_DPAA1_STREAM_ID_END, 0),
|
||||
SET_QP_INFO(FSL_DPAA1_STREAM_ID_END, 0),
|
||||
SET_QP_INFO(FSL_DPAA1_STREAM_ID_END, 0),
|
||||
SET_QP_INFO(FSL_DPAA1_STREAM_ID_END, 0),
|
||||
SET_QP_INFO(FSL_DPAA1_STREAM_ID_END, 0),
|
||||
SET_QP_INFO(FSL_DPAA1_STREAM_ID_END, 0),
|
||||
SET_QP_INFO(FSL_DPAA1_STREAM_ID_END, 0),
|
||||
};
|
||||
#endif
|
||||
|
||||
struct icid_id_table icid_tbl[] = {
|
||||
#ifdef CONFIG_SYS_DPAA_QBMAN
|
||||
SET_QMAN_ICID(FSL_DPAA1_STREAM_ID_START),
|
||||
SET_BMAN_ICID(FSL_DPAA1_STREAM_ID_START + 1),
|
||||
#endif
|
||||
|
||||
SET_SDHC_ICID(FSL_SDHC_STREAM_ID),
|
||||
|
||||
SET_USB_ICID(1, "snps,dwc3", FSL_USB1_STREAM_ID),
|
||||
SET_USB_ICID(2, "snps,dwc3", FSL_USB2_STREAM_ID),
|
||||
SET_USB_ICID(3, "snps,dwc3", FSL_USB3_STREAM_ID),
|
||||
|
||||
SET_SATA_ICID("fsl,ls1046a-ahci", FSL_SATA_STREAM_ID),
|
||||
SET_QDMA_ICID("fsl,ls1046a-qdma", FSL_QDMA_STREAM_ID),
|
||||
SET_EDMA_ICID(FSL_EDMA_STREAM_ID),
|
||||
SET_ETR_ICID(FSL_ETR_STREAM_ID),
|
||||
SET_DEBUG_ICID(FSL_DEBUG_STREAM_ID),
|
||||
#ifdef CONFIG_FSL_CAAM
|
||||
SET_SEC_QI_ICID(FSL_DPAA1_STREAM_ID_END),
|
||||
SET_SEC_JR_ICID_ENTRY(0, FSL_DPAA1_STREAM_ID_START + 3),
|
||||
SET_SEC_JR_ICID_ENTRY(1, FSL_DPAA1_STREAM_ID_START + 4),
|
||||
SET_SEC_JR_ICID_ENTRY(2, FSL_DPAA1_STREAM_ID_START + 5),
|
||||
SET_SEC_JR_ICID_ENTRY(3, FSL_DPAA1_STREAM_ID_START + 6),
|
||||
SET_SEC_RTIC_ICID_ENTRY(0, FSL_DPAA1_STREAM_ID_START + 7),
|
||||
SET_SEC_RTIC_ICID_ENTRY(1, FSL_DPAA1_STREAM_ID_START + 8),
|
||||
SET_SEC_RTIC_ICID_ENTRY(2, FSL_DPAA1_STREAM_ID_START + 9),
|
||||
SET_SEC_RTIC_ICID_ENTRY(3, FSL_DPAA1_STREAM_ID_START + 10),
|
||||
SET_SEC_DECO_ICID_ENTRY(0, FSL_DPAA1_STREAM_ID_START + 11),
|
||||
SET_SEC_DECO_ICID_ENTRY(1, FSL_DPAA1_STREAM_ID_START + 12),
|
||||
SET_SEC_DECO_ICID_ENTRY(2, FSL_DPAA1_STREAM_ID_START + 13),
|
||||
#endif
|
||||
};
|
||||
|
||||
int icid_tbl_sz = ARRAY_SIZE(icid_tbl);
|
||||
|
||||
#ifdef CONFIG_SYS_DPAA_FMAN
|
||||
struct fman_icid_id_table fman_icid_tbl[] = {
|
||||
/* port id, icid */
|
||||
SET_FMAN_ICID_ENTRY(0x02, FSL_DPAA1_STREAM_ID_END),
|
||||
SET_FMAN_ICID_ENTRY(0x03, FSL_DPAA1_STREAM_ID_END),
|
||||
SET_FMAN_ICID_ENTRY(0x04, FSL_DPAA1_STREAM_ID_END),
|
||||
SET_FMAN_ICID_ENTRY(0x05, FSL_DPAA1_STREAM_ID_END),
|
||||
SET_FMAN_ICID_ENTRY(0x06, FSL_DPAA1_STREAM_ID_END),
|
||||
SET_FMAN_ICID_ENTRY(0x07, FSL_DPAA1_STREAM_ID_END),
|
||||
SET_FMAN_ICID_ENTRY(0x08, FSL_DPAA1_STREAM_ID_END),
|
||||
SET_FMAN_ICID_ENTRY(0x09, FSL_DPAA1_STREAM_ID_END),
|
||||
SET_FMAN_ICID_ENTRY(0x0a, FSL_DPAA1_STREAM_ID_END),
|
||||
SET_FMAN_ICID_ENTRY(0x0b, FSL_DPAA1_STREAM_ID_END),
|
||||
SET_FMAN_ICID_ENTRY(0x0c, FSL_DPAA1_STREAM_ID_END),
|
||||
SET_FMAN_ICID_ENTRY(0x0d, FSL_DPAA1_STREAM_ID_END),
|
||||
SET_FMAN_ICID_ENTRY(0x28, FSL_DPAA1_STREAM_ID_END),
|
||||
SET_FMAN_ICID_ENTRY(0x29, FSL_DPAA1_STREAM_ID_END),
|
||||
SET_FMAN_ICID_ENTRY(0x2a, FSL_DPAA1_STREAM_ID_END),
|
||||
SET_FMAN_ICID_ENTRY(0x2b, FSL_DPAA1_STREAM_ID_END),
|
||||
SET_FMAN_ICID_ENTRY(0x2c, FSL_DPAA1_STREAM_ID_END),
|
||||
SET_FMAN_ICID_ENTRY(0x2d, FSL_DPAA1_STREAM_ID_END),
|
||||
SET_FMAN_ICID_ENTRY(0x10, FSL_DPAA1_STREAM_ID_END),
|
||||
SET_FMAN_ICID_ENTRY(0x11, FSL_DPAA1_STREAM_ID_END),
|
||||
SET_FMAN_ICID_ENTRY(0x30, FSL_DPAA1_STREAM_ID_END),
|
||||
SET_FMAN_ICID_ENTRY(0x31, FSL_DPAA1_STREAM_ID_END),
|
||||
};
|
||||
|
||||
int fman_icid_tbl_sz = ARRAY_SIZE(fman_icid_tbl);
|
||||
#endif
|
||||
@@ -0,0 +1,100 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Copyright 2016 Freescale Semiconductor, Inc.
|
||||
* Copyright 2019 NXP
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <asm/arch/fsl_serdes.h>
|
||||
#include <asm/arch/immap_lsch2.h>
|
||||
|
||||
struct serdes_config {
|
||||
u32 protocol;
|
||||
u8 lanes[SRDS_MAX_LANES];
|
||||
};
|
||||
|
||||
static struct serdes_config serdes1_cfg_tbl[] = {
|
||||
/* SerDes 1 */
|
||||
{0x3333, {SGMII_FM1_DTSEC9, SGMII_FM1_DTSEC10, SGMII_FM1_DTSEC5,
|
||||
SGMII_FM1_DTSEC6} },
|
||||
{0x1133, {XFI_FM1_MAC9, XFI_FM1_MAC10, SGMII_FM1_DTSEC5,
|
||||
SGMII_FM1_DTSEC6} },
|
||||
{0x1333, {XFI_FM1_MAC9, SGMII_FM1_DTSEC10, SGMII_FM1_DTSEC5,
|
||||
SGMII_FM1_DTSEC6} },
|
||||
{0x2333, {SGMII_2500_FM1_DTSEC9, SGMII_FM1_DTSEC10, SGMII_FM1_DTSEC5,
|
||||
SGMII_FM1_DTSEC6} },
|
||||
{0x2233, {SGMII_2500_FM1_DTSEC9, SGMII_2500_FM1_DTSEC10,
|
||||
SGMII_FM1_DTSEC5, SGMII_FM1_DTSEC6} },
|
||||
{0x1040, {XFI_FM1_MAC9, NONE, QSGMII_FM1_A, NONE} },
|
||||
{0x2040, {SGMII_2500_FM1_DTSEC9, NONE, QSGMII_FM1_A, NONE} },
|
||||
{0x1163, {XFI_FM1_MAC9, XFI_FM1_MAC10, PCIE1, SGMII_FM1_DTSEC6} },
|
||||
{0x2263, {SGMII_2500_FM1_DTSEC9, SGMII_2500_FM1_DTSEC10, PCIE1,
|
||||
SGMII_FM1_DTSEC6} },
|
||||
{0x3363, {SGMII_FM1_DTSEC9, SGMII_FM1_DTSEC10, PCIE1,
|
||||
SGMII_FM1_DTSEC6} },
|
||||
{0x2223, {SGMII_2500_FM1_DTSEC9, SGMII_2500_FM1_DTSEC10,
|
||||
SGMII_2500_FM1_DTSEC5, SGMII_FM1_DTSEC6} },
|
||||
{0x3040, {SGMII_FM1_DTSEC9, NONE, QSGMII_FM1_A, NONE} },
|
||||
{}
|
||||
};
|
||||
|
||||
static struct serdes_config serdes2_cfg_tbl[] = {
|
||||
/* SerDes 2 */
|
||||
{0x8888, {PCIE1, PCIE1, PCIE1, PCIE1} },
|
||||
{0x5559, {PCIE1, PCIE2, PCIE3, SATA1} },
|
||||
{0x5577, {PCIE1, PCIE2, PCIE3, PCIE3} },
|
||||
{0x5506, {PCIE1, PCIE2, NONE, PCIE3} },
|
||||
{0x0506, {NONE, PCIE2, NONE, PCIE3} },
|
||||
{0x0559, {NONE, PCIE2, PCIE3, SATA1} },
|
||||
{0x5A59, {PCIE1, SGMII_FM1_DTSEC2, PCIE3, SATA1} },
|
||||
{0x5A06, {PCIE1, SGMII_FM1_DTSEC2, NONE, PCIE3} },
|
||||
{}
|
||||
};
|
||||
|
||||
static struct serdes_config *serdes_cfg_tbl[] = {
|
||||
serdes1_cfg_tbl,
|
||||
serdes2_cfg_tbl,
|
||||
};
|
||||
|
||||
enum srds_prtcl serdes_get_prtcl(int serdes, int cfg, int lane)
|
||||
{
|
||||
struct serdes_config *ptr;
|
||||
|
||||
if (serdes >= ARRAY_SIZE(serdes_cfg_tbl))
|
||||
return 0;
|
||||
|
||||
ptr = serdes_cfg_tbl[serdes];
|
||||
while (ptr->protocol) {
|
||||
if (ptr->protocol == cfg)
|
||||
return ptr->lanes[lane];
|
||||
ptr++;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int is_serdes_prtcl_valid(int serdes, u32 prtcl)
|
||||
{
|
||||
int i;
|
||||
struct serdes_config *ptr;
|
||||
|
||||
if (serdes >= ARRAY_SIZE(serdes_cfg_tbl))
|
||||
return 0;
|
||||
|
||||
ptr = serdes_cfg_tbl[serdes];
|
||||
while (ptr->protocol) {
|
||||
if (ptr->protocol == prtcl)
|
||||
break;
|
||||
ptr++;
|
||||
}
|
||||
|
||||
if (!ptr->protocol)
|
||||
return 0;
|
||||
|
||||
for (i = 0; i < SRDS_MAX_LANES; i++) {
|
||||
if (ptr->lanes[i] != NONE)
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Copyright 2019 NXP
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <asm/arch-fsl-layerscape/immap_lsch3.h>
|
||||
#include <asm/arch-fsl-layerscape/fsl_icid.h>
|
||||
#include <asm/arch-fsl-layerscape/fsl_portals.h>
|
||||
|
||||
struct icid_id_table icid_tbl[] = {
|
||||
SET_SDHC_ICID(1, FSL_SDMMC_STREAM_ID),
|
||||
SET_USB_ICID(1, "snps,dwc3", FSL_USB1_STREAM_ID),
|
||||
SET_USB_ICID(2, "snps,dwc3", FSL_USB2_STREAM_ID),
|
||||
SET_SATA_ICID(1, "fsl,ls1088a-ahci", FSL_SATA1_STREAM_ID),
|
||||
#ifdef CONFIG_FSL_CAAM
|
||||
SET_SEC_JR_ICID_ENTRY(0, FSL_SEC_JR1_STREAM_ID),
|
||||
SET_SEC_JR_ICID_ENTRY(1, FSL_SEC_JR2_STREAM_ID),
|
||||
SET_SEC_JR_ICID_ENTRY(2, FSL_SEC_JR3_STREAM_ID),
|
||||
SET_SEC_JR_ICID_ENTRY(3, FSL_SEC_JR4_STREAM_ID),
|
||||
SET_SEC_RTIC_ICID_ENTRY(0, FSL_SEC_STREAM_ID),
|
||||
SET_SEC_RTIC_ICID_ENTRY(1, FSL_SEC_STREAM_ID),
|
||||
SET_SEC_RTIC_ICID_ENTRY(2, FSL_SEC_STREAM_ID),
|
||||
SET_SEC_RTIC_ICID_ENTRY(3, FSL_SEC_STREAM_ID),
|
||||
SET_SEC_DECO_ICID_ENTRY(0, FSL_SEC_STREAM_ID),
|
||||
SET_SEC_DECO_ICID_ENTRY(1, FSL_SEC_STREAM_ID),
|
||||
SET_SEC_DECO_ICID_ENTRY(2, FSL_SEC_STREAM_ID),
|
||||
SET_SEC_DECO_ICID_ENTRY(3, FSL_SEC_STREAM_ID),
|
||||
#endif
|
||||
};
|
||||
|
||||
int icid_tbl_sz = ARRAY_SIZE(icid_tbl);
|
||||
@@ -0,0 +1,125 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Copyright 2017 NXP
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <asm/arch/fsl_serdes.h>
|
||||
|
||||
struct serdes_config {
|
||||
u8 ip_protocol;
|
||||
u8 lanes[SRDS_MAX_LANES];
|
||||
u8 rcw_lanes[SRDS_MAX_LANES];
|
||||
};
|
||||
|
||||
static struct serdes_config serdes1_cfg_tbl[] = {
|
||||
/* SerDes 1 */
|
||||
{0x12, {SGMII3, SGMII7, SGMII1, SGMII2 }, {3, 3, 3, 3 } },
|
||||
{0x15, {SGMII3, SGMII7, XFI1, XFI2 }, {3, 3, 1, 1 } },
|
||||
{0x16, {SGMII3, SGMII7, SGMII1, XFI2 }, {3, 3, 3, 1 } },
|
||||
{0x17, {SGMII3, SGMII7, SGMII1, SGMII2 }, {3, 3, 3, 2 } },
|
||||
{0x18, {SGMII3, SGMII7, SGMII1, SGMII2 }, {3, 3, 2, 2 } },
|
||||
{0x19, {SGMII3, QSGMII_B, XFI1, XFI2}, {3, 4, 1, 1 } },
|
||||
{0x1A, {SGMII3, QSGMII_B, SGMII1, XFI2 }, {3, 4, 3, 1 } },
|
||||
{0x1B, {SGMII3, QSGMII_B, SGMII1, SGMII2 }, {3, 4, 3, 2 } },
|
||||
{0x1C, {SGMII3, QSGMII_B, SGMII1, SGMII2 }, {3, 4, 2, 2 } },
|
||||
{0x1D, {QSGMII_A, QSGMII_B, XFI1, XFI2 }, {4, 4, 1, 1 } },
|
||||
{0x1E, {QSGMII_A, QSGMII_B, SGMII1, XFI2 }, {4, 4, 3, 1 } },
|
||||
{0x1F, {QSGMII_A, QSGMII_B, SGMII1, SGMII2 }, {4, 4, 3, 2 } },
|
||||
{0x20, {QSGMII_A, QSGMII_B, SGMII1, SGMII2 }, {4, 4, 2, 2 } },
|
||||
{0x35, {SGMII3, QSGMII_B, SGMII1, SGMII2 }, {3, 4, 3, 3 } },
|
||||
{0x36, {QSGMII_A, QSGMII_B, SGMII1, SGMII2 }, {4, 4, 3, 3 } },
|
||||
{0x3A, {SGMII3, PCIE1, SGMII1, SGMII2 }, {3, 5, 3, 3 } },
|
||||
{}
|
||||
};
|
||||
static struct serdes_config serdes2_cfg_tbl[] = {
|
||||
/* SerDes 2 */
|
||||
{0x0C, {PCIE1, PCIE1, PCIE1, PCIE1 }, {8, 8, 8, 8 } },
|
||||
{0x0D, {PCIE1, PCIE2, PCIE3, SATA1 }, {5, 5, 5, 9 } },
|
||||
{0x0E, {PCIE1, PCIE1, PCIE2, SATA1 }, {7, 7, 6, 9 } },
|
||||
{0x13, {PCIE1, PCIE1, PCIE3, PCIE3 }, {7, 7, 7, 7 } },
|
||||
{0x14, {PCIE1, PCIE2, PCIE3, PCIE3 }, {5, 5, 7, 7 } },
|
||||
{0x3C, {NONE, PCIE2, NONE, PCIE3 }, {0, 5, 0, 6 } },
|
||||
{}
|
||||
};
|
||||
|
||||
static struct serdes_config *serdes_cfg_tbl[] = {
|
||||
serdes1_cfg_tbl,
|
||||
serdes2_cfg_tbl,
|
||||
};
|
||||
|
||||
int serdes_get_number(int serdes, int cfg)
|
||||
{
|
||||
struct serdes_config *ptr;
|
||||
int i, j, index, lnk;
|
||||
int is_found, max_lane = SRDS_MAX_LANES;
|
||||
|
||||
if (serdes >= ARRAY_SIZE(serdes_cfg_tbl))
|
||||
return 0;
|
||||
|
||||
ptr = serdes_cfg_tbl[serdes];
|
||||
|
||||
while (ptr->ip_protocol) {
|
||||
is_found = 1;
|
||||
for (i = 0, j = max_lane - 1; i < max_lane; i++, j--) {
|
||||
lnk = cfg & (0xf << 4 * i);
|
||||
lnk = lnk >> (4 * i);
|
||||
|
||||
index = (serdes == FSL_SRDS_1) ? j : i;
|
||||
|
||||
if (ptr->rcw_lanes[index] == lnk && is_found)
|
||||
is_found = 1;
|
||||
else
|
||||
is_found = 0;
|
||||
}
|
||||
|
||||
if (is_found)
|
||||
return ptr->ip_protocol;
|
||||
ptr++;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
enum srds_prtcl serdes_get_prtcl(int serdes, int cfg, int lane)
|
||||
{
|
||||
struct serdes_config *ptr;
|
||||
|
||||
if (serdes >= ARRAY_SIZE(serdes_cfg_tbl))
|
||||
return 0;
|
||||
|
||||
ptr = serdes_cfg_tbl[serdes];
|
||||
while (ptr->ip_protocol) {
|
||||
if (ptr->ip_protocol == cfg)
|
||||
return ptr->lanes[lane];
|
||||
ptr++;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int is_serdes_prtcl_valid(int serdes, u32 prtcl)
|
||||
{
|
||||
int i;
|
||||
struct serdes_config *ptr;
|
||||
|
||||
if (serdes >= ARRAY_SIZE(serdes_cfg_tbl))
|
||||
return 0;
|
||||
|
||||
ptr = serdes_cfg_tbl[serdes];
|
||||
while (ptr->ip_protocol) {
|
||||
if (ptr->ip_protocol == prtcl)
|
||||
break;
|
||||
ptr++;
|
||||
}
|
||||
|
||||
if (!ptr->ip_protocol)
|
||||
return 0;
|
||||
|
||||
for (i = 0; i < SRDS_MAX_LANES; i++) {
|
||||
if (ptr->lanes[i] != NONE)
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,123 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Copyright 2014-2015 Freescale Semiconductor, Inc.
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <asm/arch/fsl_serdes.h>
|
||||
|
||||
struct serdes_config {
|
||||
u8 protocol;
|
||||
u8 lanes[SRDS_MAX_LANES];
|
||||
};
|
||||
|
||||
static struct serdes_config serdes1_cfg_tbl[] = {
|
||||
/* SerDes 1 */
|
||||
{0x03, {PCIE2, PCIE2, PCIE2, PCIE2, PCIE1, PCIE1, PCIE1, PCIE1 } },
|
||||
{0x05, {PCIE2, PCIE2, PCIE2, PCIE2, SGMII4, SGMII3, SGMII2, SGMII1 } },
|
||||
{0x07, {SGMII8, SGMII7, SGMII6, SGMII5, SGMII4, SGMII3, SGMII2,
|
||||
SGMII1 } },
|
||||
{0x09, {SGMII8, SGMII7, SGMII6, SGMII5, SGMII4, SGMII3, SGMII2,
|
||||
SGMII1 } },
|
||||
{0x0A, {SGMII8, SGMII7, SGMII6, SGMII5, SGMII4, SGMII3, SGMII2,
|
||||
SGMII1 } },
|
||||
{0x0C, {SGMII8, SGMII7, SGMII6, SGMII5, SGMII4, SGMII3, SGMII2,
|
||||
SGMII1 } },
|
||||
{0x0E, {SGMII8, SGMII7, SGMII6, SGMII5, SGMII4, SGMII3, SGMII2,
|
||||
SGMII1 } },
|
||||
{0x26, {SGMII8, SGMII7, SGMII6, SGMII5, SGMII4, SGMII3, XFI2, XFI1 } },
|
||||
{0x28, {SGMII8, SGMII7, SGMII6, SGMII5, XFI4, XFI3, XFI2, XFI1 } },
|
||||
{0x2A, {XFI8, XFI7, XFI6, XFI5, XFI4, XFI3, XFI2, XFI1 } },
|
||||
{0x2B, {SGMII8, SGMII7, SGMII6, SGMII5, XAUI1, XAUI1, XAUI1, XAUI1 } },
|
||||
{0x32, {XAUI2, XAUI2, XAUI2, XAUI2, XAUI1, XAUI1, XAUI1, XAUI1 } },
|
||||
{0x33, {PCIE2, PCIE2, PCIE2, PCIE2, QSGMII_D, QSGMII_C, QSGMII_B,
|
||||
QSGMII_A} },
|
||||
{0x35, {QSGMII_D, QSGMII_C, QSGMII_B, PCIE2, XFI4, XFI3, XFI2, XFI1 } },
|
||||
{0x39, {SGMII8, SGMII7, SGMII6, PCIE2, SGMII4, SGMII3, SGMII2,
|
||||
PCIE1 } },
|
||||
{0x3B, {XFI8, XFI7, XFI6, PCIE2, XFI4, XFI3, XFI2, PCIE1 } },
|
||||
{0x4B, {PCIE2, PCIE2, PCIE2, PCIE2, XFI4, XFI3, XFI2, XFI1 } },
|
||||
{0x4C, {XFI8, XFI7, XFI6, XFI5, PCIE1, PCIE1, PCIE1, PCIE1 } },
|
||||
{0x4D, {SGMII8, SGMII7, PCIE2, PCIE2, SGMII4, SGMII3, PCIE1, PCIE1 } },
|
||||
{}
|
||||
};
|
||||
static struct serdes_config serdes2_cfg_tbl[] = {
|
||||
/* SerDes 2 */
|
||||
{0x07, {SGMII9, SGMII10, SGMII11, SGMII12, SGMII13, SGMII14, SGMII15,
|
||||
SGMII16 } },
|
||||
{0x09, {SGMII9, SGMII10, SGMII11, SGMII12, SGMII13, SGMII14, SGMII15,
|
||||
SGMII16 } },
|
||||
{0x0A, {SGMII9, SGMII10, SGMII11, SGMII12, SGMII13, SGMII14, SGMII15,
|
||||
SGMII16 } },
|
||||
{0x0C, {SGMII9, SGMII10, SGMII11, SGMII12, SGMII13, SGMII14, SGMII15,
|
||||
SGMII16 } },
|
||||
{0x0E, {SGMII9, SGMII10, SGMII11, SGMII12, SGMII13, SGMII14, SGMII15,
|
||||
SGMII16 } },
|
||||
{0x3D, {PCIE3, PCIE3, PCIE3, PCIE3, PCIE3, PCIE3, PCIE3, PCIE3 } },
|
||||
{0x3E, {PCIE3, PCIE3, PCIE3, PCIE3, PCIE3, PCIE3, PCIE3, PCIE3 } },
|
||||
{0x3F, {PCIE3, PCIE3, PCIE3, PCIE3, PCIE4, PCIE4, PCIE4, PCIE4 } },
|
||||
{0x40, {PCIE3, PCIE3, PCIE3, PCIE3, PCIE4, PCIE4, PCIE4, PCIE4 } },
|
||||
{0x41, {PCIE3, PCIE3, PCIE3, PCIE3, PCIE4, PCIE4, SATA1, SATA2 } },
|
||||
{0x42, {PCIE3, PCIE3, PCIE3, PCIE3, PCIE4, PCIE4, SATA1, SATA2 } },
|
||||
{0x43, {PCIE3, PCIE3, PCIE3, PCIE3, NONE, NONE, SATA1, SATA2 } },
|
||||
{0x44, {PCIE3, PCIE3, PCIE3, PCIE3, NONE, NONE, SATA1, SATA2 } },
|
||||
{0x45, {SGMII9, SGMII10, SGMII11, SGMII12, PCIE4, PCIE4, PCIE4,
|
||||
PCIE4 } },
|
||||
{0x47, {PCIE3, SGMII10, SGMII11, SGMII12, PCIE4, SGMII14, SGMII15,
|
||||
SGMII16 } },
|
||||
{0x49, {SGMII9, SGMII10, SGMII11, SGMII12, PCIE4, PCIE4, SATA1,
|
||||
SATA2 } },
|
||||
{0x4A, {SGMII9, SGMII10, SGMII11, SGMII12, PCIE4, PCIE4, SATA1,
|
||||
SATA2 } },
|
||||
{0x51, {PCIE3, PCIE3, PCIE3, PCIE3, PCIE4, PCIE4, PCIE4, PCIE4 } },
|
||||
{0x57, {PCIE3, PCIE3, PCIE3, PCIE3, PCIE4, PCIE4, SGMII15, SGMII16 } },
|
||||
{}
|
||||
};
|
||||
|
||||
static struct serdes_config *serdes_cfg_tbl[] = {
|
||||
serdes1_cfg_tbl,
|
||||
serdes2_cfg_tbl,
|
||||
};
|
||||
|
||||
enum srds_prtcl serdes_get_prtcl(int serdes, int cfg, int lane)
|
||||
{
|
||||
struct serdes_config *ptr;
|
||||
|
||||
if (serdes >= ARRAY_SIZE(serdes_cfg_tbl))
|
||||
return 0;
|
||||
|
||||
ptr = serdes_cfg_tbl[serdes];
|
||||
while (ptr->protocol) {
|
||||
if (ptr->protocol == cfg)
|
||||
return ptr->lanes[lane];
|
||||
ptr++;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int is_serdes_prtcl_valid(int serdes, u32 prtcl)
|
||||
{
|
||||
int i;
|
||||
struct serdes_config *ptr;
|
||||
|
||||
if (serdes >= ARRAY_SIZE(serdes_cfg_tbl))
|
||||
return 0;
|
||||
|
||||
ptr = serdes_cfg_tbl[serdes];
|
||||
while (ptr->protocol) {
|
||||
if (ptr->protocol == prtcl)
|
||||
break;
|
||||
ptr++;
|
||||
}
|
||||
|
||||
if (!ptr->protocol)
|
||||
return 0;
|
||||
|
||||
for (i = 0; i < SRDS_MAX_LANES; i++) {
|
||||
if (ptr->lanes[i] != NONE)
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Copyright 2019 NXP
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <asm/arch-fsl-layerscape/immap_lsch3.h>
|
||||
#include <asm/arch-fsl-layerscape/fsl_icid.h>
|
||||
#include <asm/arch-fsl-layerscape/fsl_portals.h>
|
||||
|
||||
struct icid_id_table icid_tbl[] = {
|
||||
SET_SDHC_ICID(1, FSL_SDMMC_STREAM_ID),
|
||||
SET_USB_ICID(1, "snps,dwc3", FSL_USB1_STREAM_ID),
|
||||
SET_USB_ICID(2, "snps,dwc3", FSL_USB2_STREAM_ID),
|
||||
SET_SATA_ICID(1, "fsl,ls2080a-ahci", FSL_SATA1_STREAM_ID),
|
||||
SET_SATA_ICID(2, "fsl,ls2080a-ahci", FSL_SATA2_STREAM_ID),
|
||||
#ifdef CONFIG_FSL_CAAM
|
||||
SET_SEC_JR_ICID_ENTRY(0, FSL_SEC_JR1_STREAM_ID),
|
||||
SET_SEC_JR_ICID_ENTRY(1, FSL_SEC_JR2_STREAM_ID),
|
||||
SET_SEC_JR_ICID_ENTRY(2, FSL_SEC_JR3_STREAM_ID),
|
||||
SET_SEC_JR_ICID_ENTRY(3, FSL_SEC_JR4_STREAM_ID),
|
||||
SET_SEC_RTIC_ICID_ENTRY(0, FSL_SEC_STREAM_ID),
|
||||
SET_SEC_RTIC_ICID_ENTRY(1, FSL_SEC_STREAM_ID),
|
||||
SET_SEC_RTIC_ICID_ENTRY(2, FSL_SEC_STREAM_ID),
|
||||
SET_SEC_RTIC_ICID_ENTRY(3, FSL_SEC_STREAM_ID),
|
||||
SET_SEC_DECO_ICID_ENTRY(0, FSL_SEC_STREAM_ID),
|
||||
SET_SEC_DECO_ICID_ENTRY(1, FSL_SEC_STREAM_ID),
|
||||
SET_SEC_DECO_ICID_ENTRY(2, FSL_SEC_STREAM_ID),
|
||||
SET_SEC_DECO_ICID_ENTRY(3, FSL_SEC_STREAM_ID),
|
||||
SET_SEC_DECO_ICID_ENTRY(4, FSL_SEC_STREAM_ID),
|
||||
SET_SEC_DECO_ICID_ENTRY(5, FSL_SEC_STREAM_ID),
|
||||
#endif
|
||||
};
|
||||
|
||||
int icid_tbl_sz = ARRAY_SIZE(icid_tbl);
|
||||
@@ -0,0 +1,48 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Copyright 2019 NXP
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <asm/arch-fsl-layerscape/immap_lsch3.h>
|
||||
#include <asm/arch-fsl-layerscape/fsl_icid.h>
|
||||
#include <asm/arch-fsl-layerscape/fsl_portals.h>
|
||||
|
||||
struct icid_id_table icid_tbl[] = {
|
||||
SET_SDHC_ICID(1, FSL_SDMMC_STREAM_ID),
|
||||
SET_SDHC_ICID(2, FSL_SDMMC2_STREAM_ID),
|
||||
SET_USB_ICID(1, "snps,dwc3", FSL_USB1_STREAM_ID),
|
||||
SET_USB_ICID(2, "snps,dwc3", FSL_USB2_STREAM_ID),
|
||||
SET_SATA_ICID(1, "fsl,lx2160a-ahci", FSL_SATA1_STREAM_ID),
|
||||
SET_SATA_ICID(2, "fsl,lx2160a-ahci", FSL_SATA2_STREAM_ID),
|
||||
SET_SATA_ICID(3, "fsl,lx2160a-ahci", FSL_SATA3_STREAM_ID),
|
||||
SET_SATA_ICID(4, "fsl,lx2160a-ahci", FSL_SATA4_STREAM_ID),
|
||||
#ifdef CONFIG_FSL_CAAM
|
||||
SET_SEC_JR_ICID_ENTRY(0, FSL_SEC_JR1_STREAM_ID),
|
||||
SET_SEC_JR_ICID_ENTRY(1, FSL_SEC_JR2_STREAM_ID),
|
||||
SET_SEC_JR_ICID_ENTRY(2, FSL_SEC_JR3_STREAM_ID),
|
||||
SET_SEC_JR_ICID_ENTRY(3, FSL_SEC_JR4_STREAM_ID),
|
||||
SET_SEC_RTIC_ICID_ENTRY(0, FSL_SEC_STREAM_ID),
|
||||
SET_SEC_RTIC_ICID_ENTRY(1, FSL_SEC_STREAM_ID),
|
||||
SET_SEC_RTIC_ICID_ENTRY(2, FSL_SEC_STREAM_ID),
|
||||
SET_SEC_RTIC_ICID_ENTRY(3, FSL_SEC_STREAM_ID),
|
||||
SET_SEC_DECO_ICID_ENTRY(0, FSL_SEC_STREAM_ID),
|
||||
SET_SEC_DECO_ICID_ENTRY(1, FSL_SEC_STREAM_ID),
|
||||
SET_SEC_DECO_ICID_ENTRY(2, FSL_SEC_STREAM_ID),
|
||||
SET_SEC_DECO_ICID_ENTRY(3, FSL_SEC_STREAM_ID),
|
||||
SET_SEC_DECO_ICID_ENTRY(4, FSL_SEC_STREAM_ID),
|
||||
SET_SEC_DECO_ICID_ENTRY(5, FSL_SEC_STREAM_ID),
|
||||
SET_SEC_DECO_ICID_ENTRY(6, FSL_SEC_STREAM_ID),
|
||||
SET_SEC_DECO_ICID_ENTRY(7, FSL_SEC_STREAM_ID),
|
||||
SET_SEC_DECO_ICID_ENTRY(8, FSL_SEC_STREAM_ID),
|
||||
SET_SEC_DECO_ICID_ENTRY(9, FSL_SEC_STREAM_ID),
|
||||
SET_SEC_DECO_ICID_ENTRY(10, FSL_SEC_STREAM_ID),
|
||||
SET_SEC_DECO_ICID_ENTRY(11, FSL_SEC_STREAM_ID),
|
||||
SET_SEC_DECO_ICID_ENTRY(12, FSL_SEC_STREAM_ID),
|
||||
SET_SEC_DECO_ICID_ENTRY(13, FSL_SEC_STREAM_ID),
|
||||
SET_SEC_DECO_ICID_ENTRY(14, FSL_SEC_STREAM_ID),
|
||||
SET_SEC_DECO_ICID_ENTRY(15, FSL_SEC_STREAM_ID),
|
||||
#endif
|
||||
};
|
||||
|
||||
int icid_tbl_sz = ARRAY_SIZE(icid_tbl);
|
||||
@@ -0,0 +1,132 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Copyright 2018 NXP
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <asm/arch/fsl_serdes.h>
|
||||
|
||||
struct serdes_config {
|
||||
u8 protocol;
|
||||
u8 lanes[SRDS_MAX_LANES];
|
||||
};
|
||||
|
||||
static struct serdes_config serdes1_cfg_tbl[] = {
|
||||
/* SerDes 1 */
|
||||
{0x01, {PCIE2, PCIE2, PCIE2, PCIE2, PCIE1, PCIE1, PCIE1, PCIE1 } },
|
||||
{0x02, {PCIE2, PCIE2, PCIE2, PCIE2, SGMII6, SGMII5, SGMII4, SGMII3 } },
|
||||
{0x03, {PCIE2, PCIE2, PCIE2, PCIE2, XFI6, XFI5, XFI4,
|
||||
XFI3 } },
|
||||
{0x04, {SGMII10, SGMII9, SGMII8, SGMII7, SGMII6, SGMII5, SGMII4,
|
||||
SGMII3 } },
|
||||
{0x05, {XFI10, XFI9, XFI8, XFI7, PCIE1, PCIE1, PCIE1,
|
||||
PCIE1 } },
|
||||
{0x06, {SGMII10, SGMII9, SGMII8, SGMII7, SGMII6, SGMII5, XFI4,
|
||||
XFI3 } },
|
||||
{0x07, {SGMII10, SGMII9, SGMII8, SGMII7, XFI6, XFI5, XFI4,
|
||||
XFI3 } },
|
||||
{0x08, {XFI10, XFI9, XFI8, XFI7, XFI6, XFI5, XFI4, XFI3 } },
|
||||
{0x09, {SGMII10, SGMII9, SGMII8, PCIE2, SGMII6, SGMII5, SGMII4,
|
||||
PCIE1 } },
|
||||
{0x0A, {XFI10, XFI9, XFI8, PCIE2, XFI6, XFI5, XFI4, PCIE1 } },
|
||||
{0x0B, {SGMII10, SGMII9, PCIE2, PCIE2, SGMII6, SGMII5, PCIE1, PCIE1 } },
|
||||
{0x0C, {SGMII10, SGMII9, PCIE2, PCIE2, PCIE1, PCIE1, PCIE1, PCIE1 } },
|
||||
{0x0D, {_100GE2, _100GE2, _100GE2, _100GE2, _100GE1, _100GE1, _100GE1,
|
||||
_100GE1 } },
|
||||
{0x0E, {PCIE2, PCIE2, PCIE2, PCIE2, _100GE1, _100GE1, _100GE1,
|
||||
_100GE1 } },
|
||||
{0x0F, {PCIE2, PCIE2, PCIE2, PCIE2, _50GE2, _50GE2, _50GE1, _50GE1 } },
|
||||
{0x10, {PCIE2, PCIE2, PCIE2, PCIE2, _25GE6, _25GE5, _50GE1, _50GE1 } },
|
||||
{0x11, {PCIE2, PCIE2, PCIE2, PCIE2, _25GE6, _25GE5, _25GE4, _25GE3 } },
|
||||
{0x12, {XFI10, XFI9, XFI8, XFI7, _25GE6, _25GE5, XFI4,
|
||||
XFI3 } },
|
||||
{0x13, {_40GE2, _40GE2, _40GE2, _40GE2, _25GE6, _25GE5, XFI4, XFI3 } },
|
||||
{0x14, {_40GE2, _40GE2, _40GE2, _40GE2, _40GE1, _40GE1, _40GE1,
|
||||
_40GE1 } },
|
||||
{0x15, {_25GE10, _25GE9, PCIE2, PCIE2, _25GE6, _25GE5, _25GE4,
|
||||
_25GE3 } },
|
||||
{0x16, {XFI10, XFI9, PCIE2, PCIE2, XFI6, XFI5, XFI4, XFI3 } },
|
||||
{}
|
||||
};
|
||||
|
||||
static struct serdes_config serdes2_cfg_tbl[] = {
|
||||
/* SerDes 2 */
|
||||
{0x01, {PCIE3, PCIE3, SATA1, SATA2, PCIE4, PCIE4, PCIE4, PCIE4 } },
|
||||
{0x02, {PCIE3, PCIE3, PCIE3, PCIE3, PCIE3, PCIE3, PCIE3, PCIE3 } },
|
||||
{0x03, {PCIE3, PCIE3, PCIE3, PCIE3, PCIE4, PCIE4, PCIE4, PCIE4 } },
|
||||
{0x04, {PCIE3, PCIE3, PCIE3, PCIE3, PCIE4, PCIE4, SATA1, SATA2 } },
|
||||
{0x05, {PCIE3, PCIE3, PCIE3, PCIE3, SATA3, SATA4, SATA1, SATA2 } },
|
||||
{0x06, {PCIE3, PCIE3, PCIE3, PCIE3, SGMII15, SGMII16, XFI13,
|
||||
XFI14 } },
|
||||
{0x07, {PCIE3, SGMII12, SGMII17, SGMII18, PCIE4, SGMII16, XFI13,
|
||||
XFI14 } },
|
||||
{0x08, {NONE, NONE, SATA1, SATA2, SATA3, SATA4, XFI13, XFI14 } },
|
||||
{0x09, {SGMII11, SGMII12, SGMII17, SGMII18, SGMII15, SGMII16, SGMII13,
|
||||
SGMII14} },
|
||||
{0x0A, {SGMII11, SGMII12, SGMII17, SGMII18, PCIE4, PCIE4, PCIE4,
|
||||
PCIE4 } },
|
||||
{0x0B, {PCIE3, SGMII12, SGMII17, SGMII18, PCIE4, SGMII16, SGMII13,
|
||||
SGMII14 } },
|
||||
{0x0C, {SGMII11, SGMII12, SGMII17, SGMII18, PCIE4, PCIE4, SATA1,
|
||||
SATA2 } },
|
||||
{0x0D, {PCIE3, PCIE3, PCIE3, PCIE3, PCIE4, PCIE4, SGMII13, SGMII14 } },
|
||||
{0x0E, {PCIE3, PCIE3, SGMII17, SGMII18, PCIE4, PCIE4, SGMII13,
|
||||
SGMII14 } },
|
||||
{}
|
||||
};
|
||||
|
||||
static struct serdes_config serdes3_cfg_tbl[] = {
|
||||
/* SerDes 3 */
|
||||
{0x02, {PCIE5, PCIE5, PCIE5, PCIE5, PCIE5, PCIE5, PCIE5, PCIE5 } },
|
||||
{0x03, {PCIE5, PCIE5, PCIE5, PCIE5, PCIE6, PCIE6, PCIE6, PCIE6 } },
|
||||
{}
|
||||
};
|
||||
|
||||
static struct serdes_config *serdes_cfg_tbl[] = {
|
||||
serdes1_cfg_tbl,
|
||||
serdes2_cfg_tbl,
|
||||
serdes3_cfg_tbl,
|
||||
};
|
||||
|
||||
enum srds_prtcl serdes_get_prtcl(int serdes, int cfg, int lane)
|
||||
{
|
||||
struct serdes_config *ptr;
|
||||
|
||||
if (serdes >= ARRAY_SIZE(serdes_cfg_tbl))
|
||||
return 0;
|
||||
|
||||
ptr = serdes_cfg_tbl[serdes];
|
||||
while (ptr->protocol) {
|
||||
if (ptr->protocol == cfg)
|
||||
return ptr->lanes[lane];
|
||||
ptr++;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int is_serdes_prtcl_valid(int serdes, u32 prtcl)
|
||||
{
|
||||
int i;
|
||||
struct serdes_config *ptr;
|
||||
|
||||
if (serdes >= ARRAY_SIZE(serdes_cfg_tbl))
|
||||
return 0;
|
||||
|
||||
ptr = serdes_cfg_tbl[serdes];
|
||||
while (ptr->protocol) {
|
||||
if (ptr->protocol == prtcl)
|
||||
break;
|
||||
ptr++;
|
||||
}
|
||||
|
||||
if (!ptr->protocol)
|
||||
return 0;
|
||||
|
||||
for (i = 0; i < SRDS_MAX_LANES; i++) {
|
||||
if (ptr->lanes[i] != NONE)
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,286 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Copyright 2014-2015 Freescale Semiconductor, Inc.
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <cpu_func.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/system.h>
|
||||
#include <asm/arch/mp.h>
|
||||
#include <asm/arch/soc.h>
|
||||
#include "cpu.h"
|
||||
#include <asm/arch-fsl-layerscape/soc.h>
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
void *get_spin_tbl_addr(void)
|
||||
{
|
||||
return &__spin_table;
|
||||
}
|
||||
|
||||
phys_addr_t determine_mp_bootpg(void)
|
||||
{
|
||||
return (phys_addr_t)&secondary_boot_code;
|
||||
}
|
||||
|
||||
void update_os_arch_secondary_cores(uint8_t os_arch)
|
||||
{
|
||||
u64 *table = get_spin_tbl_addr();
|
||||
int i;
|
||||
|
||||
for (i = 1; i < CONFIG_MAX_CPUS; i++) {
|
||||
if (os_arch == IH_ARCH_DEFAULT)
|
||||
table[i * WORDS_PER_SPIN_TABLE_ENTRY +
|
||||
SPIN_TABLE_ELEM_ARCH_COMP_IDX] = OS_ARCH_SAME;
|
||||
else
|
||||
table[i * WORDS_PER_SPIN_TABLE_ENTRY +
|
||||
SPIN_TABLE_ELEM_ARCH_COMP_IDX] = OS_ARCH_DIFF;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef CONFIG_FSL_LSCH3
|
||||
void wake_secondary_core_n(int cluster, int core, int cluster_cores)
|
||||
{
|
||||
struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR);
|
||||
struct ccsr_reset __iomem *rst = (void *)(CONFIG_SYS_FSL_RST_ADDR);
|
||||
u32 mpidr = 0;
|
||||
|
||||
mpidr = ((cluster << 8) | core);
|
||||
/*
|
||||
* mpidr_el1 register value of core which needs to be released
|
||||
* is written to scratchrw[6] register
|
||||
*/
|
||||
gur_out32(&gur->scratchrw[6], mpidr);
|
||||
asm volatile("dsb st" : : : "memory");
|
||||
rst->brrl |= 1 << ((cluster * cluster_cores) + core);
|
||||
asm volatile("dsb st" : : : "memory");
|
||||
/*
|
||||
* scratchrw[6] register value is polled
|
||||
* when the value becomes zero, this means that this core is up
|
||||
* and running, next core can be released now
|
||||
*/
|
||||
while (gur_in32(&gur->scratchrw[6]) != 0)
|
||||
;
|
||||
}
|
||||
#endif
|
||||
|
||||
int fsl_layerscape_wake_seconday_cores(void)
|
||||
{
|
||||
struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR);
|
||||
#ifdef CONFIG_FSL_LSCH3
|
||||
struct ccsr_reset __iomem *rst = (void *)(CONFIG_SYS_FSL_RST_ADDR);
|
||||
u32 svr, ver, cluster, type;
|
||||
int j = 0, cluster_cores = 0;
|
||||
#elif defined(CONFIG_FSL_LSCH2)
|
||||
struct ccsr_scfg __iomem *scfg = (void *)(CONFIG_SYS_FSL_SCFG_ADDR);
|
||||
#endif
|
||||
u32 cores, cpu_up_mask = 1;
|
||||
int i, timeout = 10;
|
||||
u64 *table = get_spin_tbl_addr();
|
||||
|
||||
#ifdef COUNTER_FREQUENCY_REAL
|
||||
/* update for secondary cores */
|
||||
__real_cntfrq = COUNTER_FREQUENCY_REAL;
|
||||
flush_dcache_range((unsigned long)&__real_cntfrq,
|
||||
(unsigned long)&__real_cntfrq + 8);
|
||||
#endif
|
||||
|
||||
cores = cpu_mask();
|
||||
/* Clear spin table so that secondary processors
|
||||
* observe the correct value after waking up from wfe.
|
||||
*/
|
||||
memset(table, 0, CONFIG_MAX_CPUS*SPIN_TABLE_ELEM_SIZE);
|
||||
flush_dcache_range((unsigned long)table,
|
||||
(unsigned long)table +
|
||||
(CONFIG_MAX_CPUS*SPIN_TABLE_ELEM_SIZE));
|
||||
|
||||
printf("Waking secondary cores to start from %lx\n", gd->relocaddr);
|
||||
|
||||
#ifdef CONFIG_FSL_LSCH3
|
||||
gur_out32(&gur->bootlocptrh, (u32)(gd->relocaddr >> 32));
|
||||
gur_out32(&gur->bootlocptrl, (u32)gd->relocaddr);
|
||||
|
||||
svr = gur_in32(&gur->svr);
|
||||
ver = SVR_SOC_VER(svr);
|
||||
if (ver == SVR_LS2080A || ver == SVR_LS2085A) {
|
||||
gur_out32(&gur->scratchrw[6], 1);
|
||||
asm volatile("dsb st" : : : "memory");
|
||||
rst->brrl = cores;
|
||||
asm volatile("dsb st" : : : "memory");
|
||||
} else {
|
||||
/*
|
||||
* Release the cores out of reset one-at-a-time to avoid
|
||||
* power spikes
|
||||
*/
|
||||
i = 0;
|
||||
cluster = in_le32(&gur->tp_cluster[i].lower);
|
||||
for (j = 0; j < TP_INIT_PER_CLUSTER; j++) {
|
||||
type = initiator_type(cluster, j);
|
||||
if (type &&
|
||||
TP_ITYP_TYPE(type) == TP_ITYP_TYPE_ARM)
|
||||
cluster_cores++;
|
||||
}
|
||||
|
||||
do {
|
||||
cluster = in_le32(&gur->tp_cluster[i].lower);
|
||||
for (j = 0; j < TP_INIT_PER_CLUSTER; j++) {
|
||||
type = initiator_type(cluster, j);
|
||||
if (type &&
|
||||
TP_ITYP_TYPE(type) == TP_ITYP_TYPE_ARM)
|
||||
wake_secondary_core_n(i, j,
|
||||
cluster_cores);
|
||||
}
|
||||
i++;
|
||||
} while ((cluster & TP_CLUSTER_EOC) != TP_CLUSTER_EOC);
|
||||
}
|
||||
#elif defined(CONFIG_FSL_LSCH2)
|
||||
scfg_out32(&scfg->scratchrw[0], (u32)(gd->relocaddr >> 32));
|
||||
scfg_out32(&scfg->scratchrw[1], (u32)gd->relocaddr);
|
||||
asm volatile("dsb st" : : : "memory");
|
||||
gur_out32(&gur->brrl, cores);
|
||||
asm volatile("dsb st" : : : "memory");
|
||||
|
||||
/* Bootup online cores */
|
||||
scfg_out32(&scfg->corebcr, cores);
|
||||
#endif
|
||||
/* This is needed as a precautionary measure.
|
||||
* If some code before this has accidentally released the secondary
|
||||
* cores then the pre-bootloader code will trap them in a "wfe" unless
|
||||
* the scratchrw[6] is set. In this case we need a sev here to get these
|
||||
* cores moving again.
|
||||
*/
|
||||
asm volatile("sev");
|
||||
|
||||
while (timeout--) {
|
||||
flush_dcache_range((unsigned long)table, (unsigned long)table +
|
||||
CONFIG_MAX_CPUS * 64);
|
||||
for (i = 1; i < CONFIG_MAX_CPUS; i++) {
|
||||
if (table[i * WORDS_PER_SPIN_TABLE_ENTRY +
|
||||
SPIN_TABLE_ELEM_STATUS_IDX])
|
||||
cpu_up_mask |= 1 << i;
|
||||
}
|
||||
if (hweight32(cpu_up_mask) == hweight32(cores))
|
||||
break;
|
||||
udelay(10);
|
||||
}
|
||||
if (timeout <= 0) {
|
||||
printf("Not all cores (0x%x) are up (0x%x)\n",
|
||||
cores, cpu_up_mask);
|
||||
return 1;
|
||||
}
|
||||
printf("All (%d) cores are up.\n", hweight32(cores));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int is_core_valid(unsigned int core)
|
||||
{
|
||||
return !!((1 << core) & cpu_mask());
|
||||
}
|
||||
|
||||
static int is_pos_valid(unsigned int pos)
|
||||
{
|
||||
return !!((1 << pos) & cpu_pos_mask());
|
||||
}
|
||||
|
||||
int is_core_online(u64 cpu_id)
|
||||
{
|
||||
u64 *table;
|
||||
int pos = id_to_core(cpu_id);
|
||||
table = (u64 *)get_spin_tbl_addr() + pos * WORDS_PER_SPIN_TABLE_ENTRY;
|
||||
return table[SPIN_TABLE_ELEM_STATUS_IDX] == 1;
|
||||
}
|
||||
|
||||
int cpu_reset(u32 nr)
|
||||
{
|
||||
puts("Feature is not implemented.\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int cpu_disable(u32 nr)
|
||||
{
|
||||
puts("Feature is not implemented.\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int core_to_pos(int nr)
|
||||
{
|
||||
u32 cores = cpu_pos_mask();
|
||||
int i, count = 0;
|
||||
|
||||
if (nr == 0) {
|
||||
return 0;
|
||||
} else if (nr >= hweight32(cores)) {
|
||||
puts("Not a valid core number.\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (i = 1; i < 32; i++) {
|
||||
if (is_pos_valid(i)) {
|
||||
count++;
|
||||
if (count == nr)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (count != nr)
|
||||
return -1;
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
int cpu_status(u32 nr)
|
||||
{
|
||||
u64 *table;
|
||||
int pos;
|
||||
|
||||
if (nr == 0) {
|
||||
table = (u64 *)get_spin_tbl_addr();
|
||||
printf("table base @ 0x%p\n", table);
|
||||
} else {
|
||||
pos = core_to_pos(nr);
|
||||
if (pos < 0)
|
||||
return -1;
|
||||
table = (u64 *)get_spin_tbl_addr() + pos *
|
||||
WORDS_PER_SPIN_TABLE_ENTRY;
|
||||
printf("table @ 0x%p\n", table);
|
||||
printf(" addr - 0x%016llx\n",
|
||||
table[SPIN_TABLE_ELEM_ENTRY_ADDR_IDX]);
|
||||
printf(" status - 0x%016llx\n",
|
||||
table[SPIN_TABLE_ELEM_STATUS_IDX]);
|
||||
printf(" lpid - 0x%016llx\n",
|
||||
table[SPIN_TABLE_ELEM_LPID_IDX]);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int cpu_release(u32 nr, int argc, char * const argv[])
|
||||
{
|
||||
u64 boot_addr;
|
||||
u64 *table = (u64 *)get_spin_tbl_addr();
|
||||
int pos;
|
||||
|
||||
pos = core_to_pos(nr);
|
||||
if (pos <= 0)
|
||||
return -1;
|
||||
|
||||
table += pos * WORDS_PER_SPIN_TABLE_ENTRY;
|
||||
boot_addr = simple_strtoull(argv[0], NULL, 16);
|
||||
table[SPIN_TABLE_ELEM_ENTRY_ADDR_IDX] = boot_addr;
|
||||
flush_dcache_range((unsigned long)table,
|
||||
(unsigned long)table + SPIN_TABLE_ELEM_SIZE);
|
||||
asm volatile("dsb st");
|
||||
smp_kick_all_cpus(); /* only those with entry addr set will run */
|
||||
/*
|
||||
* When the first release command runs, all cores are set to go. Those
|
||||
* without a valid entry address will be trapped by "wfe". "sev" kicks
|
||||
* them off to check the address again. When set, they continue to run.
|
||||
*/
|
||||
asm volatile("sev");
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,281 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Copyright 2016 NXP Semiconductor, Inc.
|
||||
*/
|
||||
#include <common.h>
|
||||
#include <malloc.h>
|
||||
#include <config.h>
|
||||
#include <errno.h>
|
||||
#include <asm/system.h>
|
||||
#include <asm/types.h>
|
||||
#include <asm/arch/soc.h>
|
||||
#ifdef CONFIG_FSL_LSCH3
|
||||
#include <asm/arch/immap_lsch3.h>
|
||||
#elif defined(CONFIG_FSL_LSCH2)
|
||||
#include <asm/arch/immap_lsch2.h>
|
||||
#endif
|
||||
#ifdef CONFIG_ARMV8_SEC_FIRMWARE_SUPPORT
|
||||
#include <asm/armv8/sec_firmware.h>
|
||||
#endif
|
||||
#ifdef CONFIG_CHAIN_OF_TRUST
|
||||
#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)
|
||||
{
|
||||
unsigned int el = current_el();
|
||||
void *ppa_fit_addr;
|
||||
u32 *boot_loc_ptr_l, *boot_loc_ptr_h;
|
||||
u32 *loadable_l, *loadable_h;
|
||||
int ret;
|
||||
|
||||
#ifdef CONFIG_CHAIN_OF_TRUST
|
||||
uintptr_t ppa_esbc_hdr = 0;
|
||||
uintptr_t ppa_img_addr = 0;
|
||||
#if defined(CONFIG_SYS_LS_PPA_FW_IN_MMC) || \
|
||||
defined(CONFIG_SYS_LS_PPA_FW_IN_NAND)
|
||||
void *ppa_hdr_ddr;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Skip if running at lower exception level */
|
||||
if (el < 3) {
|
||||
debug("Skipping PPA init, running at EL%d\n", el);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#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__);
|
||||
#ifdef CONFIG_CHAIN_OF_TRUST
|
||||
ppa_esbc_hdr = CONFIG_SYS_LS_PPA_ESBC_ADDR;
|
||||
#endif
|
||||
#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;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
blk = CONFIG_SYS_LS_PPA_FW_ADDR / 512;
|
||||
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 = blk_dread(mmc_get_blk_desc(mmc), 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;
|
||||
}
|
||||
|
||||
ret = fdt_check_header(fitp);
|
||||
if (ret) {
|
||||
free(fitp);
|
||||
printf("%s: fdt_check_header() failed\n", __func__);
|
||||
return ret;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_CHAIN_OF_TRUST
|
||||
ppa_hdr_ddr = malloc(CONFIG_LS_PPA_ESBC_HDR_SIZE);
|
||||
if (!ppa_hdr_ddr) {
|
||||
printf("PPA: malloc failed for PPA header\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
blk = CONFIG_SYS_LS_PPA_ESBC_ADDR >> 9;
|
||||
cnt = DIV_ROUND_UP(CONFIG_LS_PPA_ESBC_HDR_SIZE, 512);
|
||||
ret = blk_dread(mmc_get_blk_desc(mmc), blk, cnt, ppa_hdr_ddr);
|
||||
if (ret != cnt) {
|
||||
free(ppa_hdr_ddr);
|
||||
printf("MMC/SD read of PPA header failed\n");
|
||||
return -EIO;
|
||||
}
|
||||
debug("Read PPA header to 0x%p\n", ppa_hdr_ddr);
|
||||
|
||||
ppa_esbc_hdr = (uintptr_t)ppa_hdr_ddr;
|
||||
#endif
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
blk = CONFIG_SYS_LS_PPA_FW_ADDR / 512;
|
||||
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 = blk_dread(mmc_get_blk_desc(mmc), 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;
|
||||
}
|
||||
|
||||
#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(get_nand_dev_by_index(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;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_CHAIN_OF_TRUST
|
||||
ppa_hdr_ddr = malloc(CONFIG_LS_PPA_ESBC_HDR_SIZE);
|
||||
if (!ppa_hdr_ddr) {
|
||||
printf("PPA: malloc failed for PPA header\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
fw_length = CONFIG_LS_PPA_ESBC_HDR_SIZE;
|
||||
|
||||
ret = nand_read(get_nand_dev_by_index(0),
|
||||
(loff_t)CONFIG_SYS_LS_PPA_ESBC_ADDR,
|
||||
&fw_length, (u_char *)ppa_hdr_ddr);
|
||||
if (ret == -EUCLEAN) {
|
||||
free(ppa_hdr_ddr);
|
||||
printf("NAND read of PPA firmware at offset 0x%x failed\n",
|
||||
CONFIG_SYS_LS_PPA_FW_ADDR);
|
||||
return -EIO;
|
||||
}
|
||||
debug("Read PPA header to 0x%p\n", ppa_hdr_ddr);
|
||||
|
||||
ppa_esbc_hdr = (uintptr_t)ppa_hdr_ddr;
|
||||
#endif
|
||||
|
||||
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(get_nand_dev_by_index(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;
|
||||
}
|
||||
#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) {
|
||||
/*
|
||||
* In case of failure in validation, fsl_secboot_validate
|
||||
* would not return back in case of Production environment
|
||||
* with ITS=1. In Development environment (ITS=0 and
|
||||
* SB_EN=1), the function may return back in case of
|
||||
* non-fatal failures.
|
||||
*/
|
||||
ret = fsl_secboot_validate(ppa_esbc_hdr,
|
||||
PPA_KEY_HASH,
|
||||
&ppa_img_addr);
|
||||
if (ret != 0)
|
||||
printf("SEC firmware(s) validation failed\n");
|
||||
else
|
||||
printf("SEC firmware(s) validation Successful\n");
|
||||
}
|
||||
#if defined(CONFIG_SYS_LS_PPA_FW_IN_MMC) || \
|
||||
defined(CONFIG_SYS_LS_PPA_FW_IN_NAND)
|
||||
free(ppa_hdr_ddr);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_FSL_LSCH3
|
||||
struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR);
|
||||
boot_loc_ptr_l = &gur->bootlocptrl;
|
||||
boot_loc_ptr_h = &gur->bootlocptrh;
|
||||
|
||||
/* Assign addresses to loadable ptrs */
|
||||
loadable_l = &gur->scratchrw[4];
|
||||
loadable_h = &gur->scratchrw[5];
|
||||
#elif defined(CONFIG_FSL_LSCH2)
|
||||
struct ccsr_scfg __iomem *scfg = (void *)(CONFIG_SYS_FSL_SCFG_ADDR);
|
||||
boot_loc_ptr_l = &scfg->scratchrw[1];
|
||||
boot_loc_ptr_h = &scfg->scratchrw[0];
|
||||
|
||||
/* Assign addresses to loadable ptrs */
|
||||
loadable_l = &scfg->scratchrw[2];
|
||||
loadable_h = &scfg->scratchrw[3];
|
||||
#endif
|
||||
|
||||
debug("fsl-ppa: boot_loc_ptr_l = 0x%p, boot_loc_ptr_h =0x%p\n",
|
||||
boot_loc_ptr_l, boot_loc_ptr_h);
|
||||
ret = sec_firmware_init(ppa_fit_addr, boot_loc_ptr_l, boot_loc_ptr_h,
|
||||
loadable_l, loadable_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;
|
||||
}
|
||||
@@ -0,0 +1,874 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Copyright 2014-2015 Freescale Semiconductor
|
||||
* Copyright 2019 NXP
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <env.h>
|
||||
#include <fsl_immap.h>
|
||||
#include <fsl_ifc.h>
|
||||
#include <init.h>
|
||||
#include <asm/arch/fsl_serdes.h>
|
||||
#include <asm/arch/soc.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/global_data.h>
|
||||
#include <asm/arch-fsl-layerscape/config.h>
|
||||
#include <asm/arch-fsl-layerscape/ns_access.h>
|
||||
#include <asm/arch-fsl-layerscape/fsl_icid.h>
|
||||
#ifdef CONFIG_LAYERSCAPE_NS_ACCESS
|
||||
#include <fsl_csu.h>
|
||||
#endif
|
||||
#ifdef CONFIG_SYS_FSL_DDR
|
||||
#include <fsl_ddr_sdram.h>
|
||||
#include <fsl_ddr.h>
|
||||
#endif
|
||||
#ifdef CONFIG_CHAIN_OF_TRUST
|
||||
#include <fsl_validate.h>
|
||||
#endif
|
||||
#include <fsl_immap.h>
|
||||
#ifdef CONFIG_TFABOOT
|
||||
#include <env_internal.h>
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
#endif
|
||||
|
||||
bool soc_has_dp_ddr(void)
|
||||
{
|
||||
struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR);
|
||||
u32 svr = gur_in32(&gur->svr);
|
||||
|
||||
/* LS2085A, LS2088A, LS2048A has DP_DDR */
|
||||
if ((SVR_SOC_VER(svr) == SVR_LS2085A) ||
|
||||
(SVR_SOC_VER(svr) == SVR_LS2088A) ||
|
||||
(SVR_SOC_VER(svr) == SVR_LS2048A))
|
||||
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_LS2085A)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static inline void set_usb_txvreftune(u32 __iomem *scfg, u32 offset)
|
||||
{
|
||||
scfg_clrsetbits32(scfg + offset / 4,
|
||||
0xF << 6,
|
||||
SCFG_USB_TXVREFTUNE << 6);
|
||||
}
|
||||
|
||||
static void erratum_a009008(void)
|
||||
{
|
||||
#ifdef CONFIG_SYS_FSL_ERRATUM_A009008
|
||||
u32 __iomem *scfg = (u32 __iomem *)SCFG_BASE;
|
||||
|
||||
#if defined(CONFIG_ARCH_LS1043A) || defined(CONFIG_ARCH_LS1046A) || \
|
||||
defined(CONFIG_ARCH_LS1012A)
|
||||
set_usb_txvreftune(scfg, SCFG_USB3PRM1CR_USB1);
|
||||
#if defined(CONFIG_ARCH_LS1043A) || defined(CONFIG_ARCH_LS1046A)
|
||||
set_usb_txvreftune(scfg, SCFG_USB3PRM1CR_USB2);
|
||||
set_usb_txvreftune(scfg, SCFG_USB3PRM1CR_USB3);
|
||||
#endif
|
||||
#elif defined(CONFIG_ARCH_LS2080A)
|
||||
set_usb_txvreftune(scfg, SCFG_USB3PRM1CR);
|
||||
#endif
|
||||
#endif /* CONFIG_SYS_FSL_ERRATUM_A009008 */
|
||||
}
|
||||
|
||||
static inline void set_usb_sqrxtune(u32 __iomem *scfg, u32 offset)
|
||||
{
|
||||
scfg_clrbits32(scfg + offset / 4,
|
||||
SCFG_USB_SQRXTUNE_MASK << 23);
|
||||
}
|
||||
|
||||
static void erratum_a009798(void)
|
||||
{
|
||||
#ifdef CONFIG_SYS_FSL_ERRATUM_A009798
|
||||
u32 __iomem *scfg = (u32 __iomem *)SCFG_BASE;
|
||||
|
||||
#if defined(CONFIG_ARCH_LS1043A) || defined(CONFIG_ARCH_LS1046A) || \
|
||||
defined(CONFIG_ARCH_LS1012A)
|
||||
set_usb_sqrxtune(scfg, SCFG_USB3PRM1CR_USB1);
|
||||
#if defined(CONFIG_ARCH_LS1043A) || defined(CONFIG_ARCH_LS1046A)
|
||||
set_usb_sqrxtune(scfg, SCFG_USB3PRM1CR_USB2);
|
||||
set_usb_sqrxtune(scfg, SCFG_USB3PRM1CR_USB3);
|
||||
#endif
|
||||
#elif defined(CONFIG_ARCH_LS2080A)
|
||||
set_usb_sqrxtune(scfg, SCFG_USB3PRM1CR);
|
||||
#endif
|
||||
#endif /* CONFIG_SYS_FSL_ERRATUM_A009798 */
|
||||
}
|
||||
|
||||
#if defined(CONFIG_ARCH_LS1043A) || defined(CONFIG_ARCH_LS1046A) || \
|
||||
defined(CONFIG_ARCH_LS1012A)
|
||||
static inline void set_usb_pcstxswingfull(u32 __iomem *scfg, u32 offset)
|
||||
{
|
||||
scfg_clrsetbits32(scfg + offset / 4,
|
||||
0x7F << 9,
|
||||
SCFG_USB_PCSTXSWINGFULL << 9);
|
||||
}
|
||||
#endif
|
||||
|
||||
static void erratum_a008997(void)
|
||||
{
|
||||
#ifdef CONFIG_SYS_FSL_ERRATUM_A008997
|
||||
#if defined(CONFIG_ARCH_LS1043A) || defined(CONFIG_ARCH_LS1046A) || \
|
||||
defined(CONFIG_ARCH_LS1012A)
|
||||
u32 __iomem *scfg = (u32 __iomem *)SCFG_BASE;
|
||||
|
||||
set_usb_pcstxswingfull(scfg, SCFG_USB3PRM2CR_USB1);
|
||||
#if defined(CONFIG_ARCH_LS1043A) || defined(CONFIG_ARCH_LS1046A)
|
||||
set_usb_pcstxswingfull(scfg, SCFG_USB3PRM2CR_USB2);
|
||||
set_usb_pcstxswingfull(scfg, SCFG_USB3PRM2CR_USB3);
|
||||
#endif
|
||||
#elif defined(CONFIG_ARCH_LS1028A)
|
||||
clrsetbits_le32(DCSR_BASE + DCSR_USB_IOCR1,
|
||||
0x7F << 11,
|
||||
DCSR_USB_PCSTXSWINGFULL << 11);
|
||||
#endif
|
||||
#endif /* CONFIG_SYS_FSL_ERRATUM_A008997 */
|
||||
}
|
||||
|
||||
#if defined(CONFIG_ARCH_LS1043A) || defined(CONFIG_ARCH_LS1046A) || \
|
||||
defined(CONFIG_ARCH_LS1012A)
|
||||
|
||||
#define PROGRAM_USB_PHY_RX_OVRD_IN_HI(phy) \
|
||||
out_be16((phy) + SCFG_USB_PHY_RX_OVRD_IN_HI, USB_PHY_RX_EQ_VAL_1); \
|
||||
out_be16((phy) + SCFG_USB_PHY_RX_OVRD_IN_HI, USB_PHY_RX_EQ_VAL_2); \
|
||||
out_be16((phy) + SCFG_USB_PHY_RX_OVRD_IN_HI, USB_PHY_RX_EQ_VAL_3); \
|
||||
out_be16((phy) + SCFG_USB_PHY_RX_OVRD_IN_HI, USB_PHY_RX_EQ_VAL_4)
|
||||
|
||||
#elif defined(CONFIG_ARCH_LS2080A) || defined(CONFIG_ARCH_LS1088A) || \
|
||||
defined(CONFIG_ARCH_LS1028A)
|
||||
|
||||
#define PROGRAM_USB_PHY_RX_OVRD_IN_HI(phy) \
|
||||
out_le16((phy) + DCSR_USB_PHY_RX_OVRD_IN_HI, USB_PHY_RX_EQ_VAL_1); \
|
||||
out_le16((phy) + DCSR_USB_PHY_RX_OVRD_IN_HI, USB_PHY_RX_EQ_VAL_2); \
|
||||
out_le16((phy) + DCSR_USB_PHY_RX_OVRD_IN_HI, USB_PHY_RX_EQ_VAL_3); \
|
||||
out_le16((phy) + DCSR_USB_PHY_RX_OVRD_IN_HI, USB_PHY_RX_EQ_VAL_4)
|
||||
|
||||
#endif
|
||||
|
||||
static void erratum_a009007(void)
|
||||
{
|
||||
#if defined(CONFIG_ARCH_LS1043A) || defined(CONFIG_ARCH_LS1046A) || \
|
||||
defined(CONFIG_ARCH_LS1012A)
|
||||
void __iomem *usb_phy = (void __iomem *)SCFG_USB_PHY1;
|
||||
|
||||
PROGRAM_USB_PHY_RX_OVRD_IN_HI(usb_phy);
|
||||
#if defined(CONFIG_ARCH_LS1043A) || defined(CONFIG_ARCH_LS1046A)
|
||||
usb_phy = (void __iomem *)SCFG_USB_PHY2;
|
||||
PROGRAM_USB_PHY_RX_OVRD_IN_HI(usb_phy);
|
||||
|
||||
usb_phy = (void __iomem *)SCFG_USB_PHY3;
|
||||
PROGRAM_USB_PHY_RX_OVRD_IN_HI(usb_phy);
|
||||
#endif
|
||||
#elif defined(CONFIG_ARCH_LS2080A) || defined(CONFIG_ARCH_LS1088A) || \
|
||||
defined(CONFIG_ARCH_LS1028A)
|
||||
void __iomem *dcsr = (void __iomem *)DCSR_BASE;
|
||||
|
||||
PROGRAM_USB_PHY_RX_OVRD_IN_HI(dcsr + DCSR_USB_PHY1);
|
||||
PROGRAM_USB_PHY_RX_OVRD_IN_HI(dcsr + DCSR_USB_PHY2);
|
||||
#endif /* CONFIG_SYS_FSL_ERRATUM_A009007 */
|
||||
}
|
||||
|
||||
#if defined(CONFIG_FSL_LSCH3)
|
||||
/*
|
||||
* This erratum requires setting a value to eddrtqcr1 to
|
||||
* optimal the DDR performance.
|
||||
*/
|
||||
static void erratum_a008336(void)
|
||||
{
|
||||
#ifdef CONFIG_SYS_FSL_ERRATUM_A008336
|
||||
u32 *eddrtqcr1;
|
||||
|
||||
#ifdef CONFIG_SYS_FSL_DCSR_DDR_ADDR
|
||||
eddrtqcr1 = (void *)CONFIG_SYS_FSL_DCSR_DDR_ADDR + 0x800;
|
||||
if (fsl_ddr_get_version(0) == 0x50200)
|
||||
out_le32(eddrtqcr1, 0x63b30002);
|
||||
#endif
|
||||
#ifdef CONFIG_SYS_FSL_DCSR_DDR2_ADDR
|
||||
eddrtqcr1 = (void *)CONFIG_SYS_FSL_DCSR_DDR2_ADDR + 0x800;
|
||||
if (fsl_ddr_get_version(0) == 0x50200)
|
||||
out_le32(eddrtqcr1, 0x63b30002);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* This erratum requires a register write before being Memory
|
||||
* controller 3 being enabled.
|
||||
*/
|
||||
static void erratum_a008514(void)
|
||||
{
|
||||
#ifdef CONFIG_SYS_FSL_ERRATUM_A008514
|
||||
u32 *eddrtqcr1;
|
||||
|
||||
#ifdef CONFIG_SYS_FSL_DCSR_DDR3_ADDR
|
||||
eddrtqcr1 = (void *)CONFIG_SYS_FSL_DCSR_DDR3_ADDR + 0x800;
|
||||
out_le32(eddrtqcr1, 0x63b20002);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
#ifdef CONFIG_SYS_FSL_ERRATUM_A009635
|
||||
#define PLATFORM_CYCLE_ENV_VAR "a009635_interval_val"
|
||||
|
||||
static unsigned long get_internval_val_mhz(void)
|
||||
{
|
||||
char *interval = env_get(PLATFORM_CYCLE_ENV_VAR);
|
||||
/*
|
||||
* interval is the number of platform cycles(MHz) between
|
||||
* wake up events generated by EPU.
|
||||
*/
|
||||
ulong interval_mhz = get_bus_freq(0) / (1000 * 1000);
|
||||
|
||||
if (interval)
|
||||
interval_mhz = simple_strtoul(interval, NULL, 10);
|
||||
|
||||
return interval_mhz;
|
||||
}
|
||||
|
||||
void erratum_a009635(void)
|
||||
{
|
||||
u32 val;
|
||||
unsigned long interval_mhz = get_internval_val_mhz();
|
||||
|
||||
if (!interval_mhz)
|
||||
return;
|
||||
|
||||
val = in_le32(DCSR_CGACRE5);
|
||||
writel(val | 0x00000200, DCSR_CGACRE5);
|
||||
|
||||
val = in_le32(EPU_EPCMPR5);
|
||||
writel(interval_mhz, EPU_EPCMPR5);
|
||||
val = in_le32(EPU_EPCCR5);
|
||||
writel(val | 0x82820000, EPU_EPCCR5);
|
||||
val = in_le32(EPU_EPSMCR5);
|
||||
writel(val | 0x002f0000, EPU_EPSMCR5);
|
||||
val = in_le32(EPU_EPECR5);
|
||||
writel(val | 0x20000000, EPU_EPECR5);
|
||||
val = in_le32(EPU_EPGCR);
|
||||
writel(val | 0x80000000, EPU_EPGCR);
|
||||
}
|
||||
#endif /* CONFIG_SYS_FSL_ERRATUM_A009635 */
|
||||
|
||||
static void erratum_rcw_src(void)
|
||||
{
|
||||
#if defined(CONFIG_SPL) && defined(CONFIG_NAND_BOOT)
|
||||
u32 __iomem *dcfg_ccsr = (u32 __iomem *)DCFG_BASE;
|
||||
u32 __iomem *dcfg_dcsr = (u32 __iomem *)DCFG_DCSR_BASE;
|
||||
u32 val;
|
||||
|
||||
val = in_le32(dcfg_ccsr + DCFG_PORSR1 / 4);
|
||||
val &= ~DCFG_PORSR1_RCW_SRC;
|
||||
val |= DCFG_PORSR1_RCW_SRC_NOR;
|
||||
out_le32(dcfg_dcsr + DCFG_DCSR_PORCR1 / 4, val);
|
||||
#endif
|
||||
}
|
||||
|
||||
#define I2C_DEBUG_REG 0x6
|
||||
#define I2C_GLITCH_EN 0x8
|
||||
/*
|
||||
* 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)
|
||||
{
|
||||
#ifdef CONFIG_SYS_I2C
|
||||
u8 __iomem *ptr;
|
||||
#ifdef I2C1_BASE_ADDR
|
||||
ptr = (u8 __iomem *)(I2C1_BASE_ADDR + I2C_DEBUG_REG);
|
||||
|
||||
writeb(I2C_GLITCH_EN, ptr);
|
||||
#endif
|
||||
#ifdef I2C2_BASE_ADDR
|
||||
ptr = (u8 __iomem *)(I2C2_BASE_ADDR + I2C_DEBUG_REG);
|
||||
|
||||
writeb(I2C_GLITCH_EN, ptr);
|
||||
#endif
|
||||
#ifdef I2C3_BASE_ADDR
|
||||
ptr = (u8 __iomem *)(I2C3_BASE_ADDR + I2C_DEBUG_REG);
|
||||
|
||||
writeb(I2C_GLITCH_EN, ptr);
|
||||
#endif
|
||||
#ifdef I2C4_BASE_ADDR
|
||||
ptr = (u8 __iomem *)(I2C4_BASE_ADDR + I2C_DEBUG_REG);
|
||||
|
||||
writeb(I2C_GLITCH_EN, ptr);
|
||||
#endif
|
||||
#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_rcw_src();
|
||||
#ifdef CONFIG_FSL_IFC
|
||||
init_early_memctl_regs(); /* tighten IFC timing */
|
||||
#endif
|
||||
#ifdef CONFIG_SYS_FSL_ERRATUM_A009203
|
||||
erratum_a009203();
|
||||
#endif
|
||||
erratum_a008514();
|
||||
erratum_a008336();
|
||||
erratum_a009008();
|
||||
erratum_a009798();
|
||||
erratum_a008997();
|
||||
erratum_a009007();
|
||||
#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
|
||||
|
||||
#if defined(CONFIG_ARCH_LS1088A) || defined(CONFIG_ARCH_LS1028A) || \
|
||||
defined(CONFIG_ARCH_LS2080A) || defined(CONFIG_ARCH_LX2160A)
|
||||
set_icids();
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Get VDD in the unit mV from voltage ID */
|
||||
int get_core_volt_from_fuse(void)
|
||||
{
|
||||
struct ccsr_gur *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR);
|
||||
int vdd;
|
||||
u32 fusesr;
|
||||
u8 vid;
|
||||
|
||||
/* get the voltage ID from fuse status register */
|
||||
fusesr = in_le32(&gur->dcfg_fusesr);
|
||||
debug("%s: fusesr = 0x%x\n", __func__, fusesr);
|
||||
vid = (fusesr >> FSL_CHASSIS3_DCFG_FUSESR_ALTVID_SHIFT) &
|
||||
FSL_CHASSIS3_DCFG_FUSESR_ALTVID_MASK;
|
||||
if ((vid == 0) || (vid == FSL_CHASSIS3_DCFG_FUSESR_ALTVID_MASK)) {
|
||||
vid = (fusesr >> FSL_CHASSIS3_DCFG_FUSESR_VID_SHIFT) &
|
||||
FSL_CHASSIS3_DCFG_FUSESR_VID_MASK;
|
||||
}
|
||||
debug("%s: VID = 0x%x\n", __func__, vid);
|
||||
switch (vid) {
|
||||
case 0x00: /* VID isn't supported */
|
||||
vdd = -EINVAL;
|
||||
debug("%s: The VID feature is not supported\n", __func__);
|
||||
break;
|
||||
case 0x08: /* 0.9V silicon */
|
||||
vdd = 900;
|
||||
break;
|
||||
case 0x10: /* 1.0V silicon */
|
||||
vdd = 1000;
|
||||
break;
|
||||
default: /* Other core voltage */
|
||||
vdd = -EINVAL;
|
||||
debug("%s: The VID(%x) isn't supported\n", __func__, vid);
|
||||
break;
|
||||
}
|
||||
debug("%s: The required minimum volt of CORE is %dmV\n", __func__, vdd);
|
||||
|
||||
return vdd;
|
||||
}
|
||||
|
||||
#elif defined(CONFIG_FSL_LSCH2)
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
static void erratum_a008850_early(void)
|
||||
{
|
||||
#ifdef CONFIG_SYS_FSL_ERRATUM_A008850
|
||||
/* part 1 of 2 */
|
||||
struct ccsr_cci400 __iomem *cci = (void *)(CONFIG_SYS_IMMR +
|
||||
CONFIG_SYS_CCI400_OFFSET);
|
||||
struct ccsr_ddr __iomem *ddr = (void *)CONFIG_SYS_FSL_DDR_ADDR;
|
||||
|
||||
/* Skip if running at lower exception level */
|
||||
if (current_el() < 3)
|
||||
return;
|
||||
|
||||
/* disables propagation of barrier transactions to DDRC from CCI400 */
|
||||
out_le32(&cci->ctrl_ord, CCI400_CTRLORD_TERM_BARRIER);
|
||||
|
||||
/* disable the re-ordering in DDRC */
|
||||
ddr_out32(&ddr->eor, DDR_EOR_RD_REOD_DIS | DDR_EOR_WD_REOD_DIS);
|
||||
#endif
|
||||
}
|
||||
|
||||
void erratum_a008850_post(void)
|
||||
{
|
||||
#ifdef CONFIG_SYS_FSL_ERRATUM_A008850
|
||||
/* part 2 of 2 */
|
||||
struct ccsr_cci400 __iomem *cci = (void *)(CONFIG_SYS_IMMR +
|
||||
CONFIG_SYS_CCI400_OFFSET);
|
||||
struct ccsr_ddr __iomem *ddr = (void *)CONFIG_SYS_FSL_DDR_ADDR;
|
||||
u32 tmp;
|
||||
|
||||
/* Skip if running at lower exception level */
|
||||
if (current_el() < 3)
|
||||
return;
|
||||
|
||||
/* enable propagation of barrier transactions to DDRC from CCI400 */
|
||||
out_le32(&cci->ctrl_ord, CCI400_CTRLORD_EN_BARRIER);
|
||||
|
||||
/* enable the re-ordering in DDRC */
|
||||
tmp = ddr_in32(&ddr->eor);
|
||||
tmp &= ~(DDR_EOR_RD_REOD_DIS | DDR_EOR_WD_REOD_DIS);
|
||||
ddr_out32(&ddr->eor, tmp);
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SYS_FSL_ERRATUM_A010315
|
||||
void erratum_a010315(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = PCIE1; i <= PCIE4; i++)
|
||||
if (!is_serdes_configured(i)) {
|
||||
debug("PCIe%d: disabled all R/W permission!\n", i);
|
||||
set_pcie_ns_access(i, 0);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static void erratum_a010539(void)
|
||||
{
|
||||
#if defined(CONFIG_SYS_FSL_ERRATUM_A010539) && defined(CONFIG_QSPI_BOOT)
|
||||
struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR);
|
||||
u32 porsr1;
|
||||
|
||||
porsr1 = in_be32(&gur->porsr1);
|
||||
porsr1 &= ~FSL_CHASSIS2_CCSR_PORSR1_RCW_MASK;
|
||||
out_be32((void *)(CONFIG_SYS_DCSR_DCFG_ADDR + DCFG_DCSR_PORCR1),
|
||||
porsr1);
|
||||
out_be32((void *)(CONFIG_SYS_FSL_SCFG_ADDR + 0x1a8), 0xffffffff);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Get VDD in the unit mV from voltage ID */
|
||||
int get_core_volt_from_fuse(void)
|
||||
{
|
||||
struct ccsr_gur *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR);
|
||||
int vdd;
|
||||
u32 fusesr;
|
||||
u8 vid;
|
||||
|
||||
fusesr = in_be32(&gur->dcfg_fusesr);
|
||||
debug("%s: fusesr = 0x%x\n", __func__, fusesr);
|
||||
vid = (fusesr >> FSL_CHASSIS2_DCFG_FUSESR_ALTVID_SHIFT) &
|
||||
FSL_CHASSIS2_DCFG_FUSESR_ALTVID_MASK;
|
||||
if ((vid == 0) || (vid == FSL_CHASSIS2_DCFG_FUSESR_ALTVID_MASK)) {
|
||||
vid = (fusesr >> FSL_CHASSIS2_DCFG_FUSESR_VID_SHIFT) &
|
||||
FSL_CHASSIS2_DCFG_FUSESR_VID_MASK;
|
||||
}
|
||||
debug("%s: VID = 0x%x\n", __func__, vid);
|
||||
switch (vid) {
|
||||
case 0x00: /* VID isn't supported */
|
||||
vdd = -EINVAL;
|
||||
debug("%s: The VID feature is not supported\n", __func__);
|
||||
break;
|
||||
case 0x08: /* 0.9V silicon */
|
||||
vdd = 900;
|
||||
break;
|
||||
case 0x10: /* 1.0V silicon */
|
||||
vdd = 1000;
|
||||
break;
|
||||
default: /* Other core voltage */
|
||||
vdd = -EINVAL;
|
||||
printf("%s: The VID(%x) isn't supported\n", __func__, vid);
|
||||
break;
|
||||
}
|
||||
debug("%s: The required minimum volt of CORE is %dmV\n", __func__, vdd);
|
||||
|
||||
return vdd;
|
||||
}
|
||||
|
||||
__weak int board_switch_core_volt(u32 vdd)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int setup_core_volt(u32 vdd)
|
||||
{
|
||||
return board_setup_core_volt(vdd);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SYS_FSL_DDR
|
||||
static void ddr_enable_0v9_volt(bool en)
|
||||
{
|
||||
struct ccsr_ddr __iomem *ddr = (void *)CONFIG_SYS_FSL_DDR_ADDR;
|
||||
u32 tmp;
|
||||
|
||||
tmp = ddr_in32(&ddr->ddr_cdr1);
|
||||
|
||||
if (en)
|
||||
tmp |= DDR_CDR1_V0PT9_EN;
|
||||
else
|
||||
tmp &= ~DDR_CDR1_V0PT9_EN;
|
||||
|
||||
ddr_out32(&ddr->ddr_cdr1, tmp);
|
||||
}
|
||||
#endif
|
||||
|
||||
int setup_chip_volt(void)
|
||||
{
|
||||
int vdd;
|
||||
|
||||
vdd = get_core_volt_from_fuse();
|
||||
/* Nothing to do for silicons doesn't support VID */
|
||||
if (vdd < 0)
|
||||
return vdd;
|
||||
|
||||
if (setup_core_volt(vdd))
|
||||
printf("%s: Switch core VDD to %dmV failed\n", __func__, vdd);
|
||||
#ifdef CONFIG_SYS_HAS_SERDES
|
||||
if (setup_serdes_volt(vdd))
|
||||
printf("%s: Switch SVDD to %dmV failed\n", __func__, vdd);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SYS_FSL_DDR
|
||||
if (vdd == 900)
|
||||
ddr_enable_0v9_volt(true);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_FSL_PFE
|
||||
void init_pfe_scfg_dcfg_regs(void)
|
||||
{
|
||||
struct ccsr_scfg *scfg = (struct ccsr_scfg *)CONFIG_SYS_FSL_SCFG_ADDR;
|
||||
u32 ecccr2;
|
||||
|
||||
out_be32(&scfg->pfeasbcr,
|
||||
in_be32(&scfg->pfeasbcr) | SCFG_PFEASBCR_AWCACHE0);
|
||||
out_be32(&scfg->pfebsbcr,
|
||||
in_be32(&scfg->pfebsbcr) | SCFG_PFEASBCR_AWCACHE0);
|
||||
|
||||
/* CCI-400 QoS settings for PFE */
|
||||
out_be32(&scfg->wr_qos1, (unsigned int)(SCFG_WR_QOS1_PFE1_QOS
|
||||
| SCFG_WR_QOS1_PFE2_QOS));
|
||||
out_be32(&scfg->rd_qos1, (unsigned int)(SCFG_RD_QOS1_PFE1_QOS
|
||||
| SCFG_RD_QOS1_PFE2_QOS));
|
||||
|
||||
ecccr2 = in_be32(CONFIG_SYS_DCSR_DCFG_ADDR + DCFG_DCSR_ECCCR2);
|
||||
out_be32((void *)CONFIG_SYS_DCSR_DCFG_ADDR + DCFG_DCSR_ECCCR2,
|
||||
ecccr2 | (unsigned int)DISABLE_PFE_ECC);
|
||||
}
|
||||
#endif
|
||||
|
||||
void fsl_lsch2_early_init_f(void)
|
||||
{
|
||||
struct ccsr_cci400 *cci = (struct ccsr_cci400 *)(CONFIG_SYS_IMMR +
|
||||
CONFIG_SYS_CCI400_OFFSET);
|
||||
struct ccsr_scfg *scfg = (struct ccsr_scfg *)CONFIG_SYS_FSL_SCFG_ADDR;
|
||||
#if defined(CONFIG_FSL_QSPI) && defined(CONFIG_TFABOOT)
|
||||
enum boot_src src;
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_LAYERSCAPE_NS_ACCESS
|
||||
enable_layerscape_ns_access();
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_FSL_IFC
|
||||
init_early_memctl_regs(); /* tighten IFC timing */
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_FSL_QSPI) && defined(CONFIG_TFABOOT)
|
||||
src = get_boot_src();
|
||||
if (src != BOOT_SOURCE_QSPI_NOR)
|
||||
out_be32(&scfg->qspi_cfg, SCFG_QSPI_CLKSEL);
|
||||
#else
|
||||
#if defined(CONFIG_FSL_QSPI) && !defined(CONFIG_QSPI_BOOT)
|
||||
out_be32(&scfg->qspi_cfg, SCFG_QSPI_CLKSEL);
|
||||
#endif
|
||||
#endif
|
||||
/* Make SEC reads and writes snoopable */
|
||||
#if defined(CONFIG_ARCH_LS1043A) || defined(CONFIG_ARCH_LS1046A)
|
||||
setbits_be32(&scfg->snpcnfgcr, SCFG_SNPCNFGCR_SECRDSNP |
|
||||
SCFG_SNPCNFGCR_SECWRSNP | SCFG_SNPCNFGCR_USB1RDSNP |
|
||||
SCFG_SNPCNFGCR_USB1WRSNP | SCFG_SNPCNFGCR_USB2RDSNP |
|
||||
SCFG_SNPCNFGCR_USB2WRSNP | SCFG_SNPCNFGCR_USB3RDSNP |
|
||||
SCFG_SNPCNFGCR_USB3WRSNP | SCFG_SNPCNFGCR_SATARDSNP |
|
||||
SCFG_SNPCNFGCR_SATAWRSNP);
|
||||
#else
|
||||
setbits_be32(&scfg->snpcnfgcr, SCFG_SNPCNFGCR_SECRDSNP |
|
||||
SCFG_SNPCNFGCR_SECWRSNP |
|
||||
SCFG_SNPCNFGCR_SATARDSNP |
|
||||
SCFG_SNPCNFGCR_SATAWRSNP);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Enable snoop requests and DVM message requests for
|
||||
* Slave insterface S4 (A53 core cluster)
|
||||
*/
|
||||
if (current_el() == 3) {
|
||||
out_le32(&cci->slave[4].snoop_ctrl,
|
||||
CCI400_DVM_MESSAGE_REQ_EN | CCI400_SNOOP_REQ_EN);
|
||||
}
|
||||
|
||||
/*
|
||||
* Program Central Security Unit (CSU) to grant access
|
||||
* permission for USB 2.0 controller
|
||||
*/
|
||||
#if defined(CONFIG_ARCH_LS1012A) && defined(CONFIG_USB_EHCI_FSL)
|
||||
if (current_el() == 3)
|
||||
set_devices_ns_access(CSU_CSLX_USB_2, CSU_ALL_RW);
|
||||
#endif
|
||||
/* Erratum */
|
||||
erratum_a008850_early(); /* part 1 of 2 */
|
||||
erratum_a009929();
|
||||
erratum_a009660();
|
||||
erratum_a010539();
|
||||
erratum_a009008();
|
||||
erratum_a009798();
|
||||
erratum_a008997();
|
||||
erratum_a009007();
|
||||
|
||||
#if defined(CONFIG_ARCH_LS1043A) || defined(CONFIG_ARCH_LS1046A)
|
||||
set_icids();
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_QSPI_AHB_INIT
|
||||
/* Enable 4bytes address support and fast read */
|
||||
int qspi_ahb_init(void)
|
||||
{
|
||||
u32 *qspi_lut, lut_key, *qspi_key;
|
||||
|
||||
qspi_key = (void *)SYS_FSL_QSPI_ADDR + 0x300;
|
||||
qspi_lut = (void *)SYS_FSL_QSPI_ADDR + 0x310;
|
||||
|
||||
lut_key = in_be32(qspi_key);
|
||||
|
||||
if (lut_key == 0x5af05af0) {
|
||||
/* That means the register is BE */
|
||||
out_be32(qspi_key, 0x5af05af0);
|
||||
/* Unlock the lut table */
|
||||
out_be32(qspi_key + 1, 0x00000002);
|
||||
out_be32(qspi_lut, 0x0820040c);
|
||||
out_be32(qspi_lut + 1, 0x1c080c08);
|
||||
out_be32(qspi_lut + 2, 0x00002400);
|
||||
/* Lock the lut table */
|
||||
out_be32(qspi_key, 0x5af05af0);
|
||||
out_be32(qspi_key + 1, 0x00000001);
|
||||
} else {
|
||||
/* That means the register is LE */
|
||||
out_le32(qspi_key, 0x5af05af0);
|
||||
/* Unlock the lut table */
|
||||
out_le32(qspi_key + 1, 0x00000002);
|
||||
out_le32(qspi_lut, 0x0820040c);
|
||||
out_le32(qspi_lut + 1, 0x1c080c08);
|
||||
out_le32(qspi_lut + 2, 0x00002400);
|
||||
/* Lock the lut table */
|
||||
out_le32(qspi_key, 0x5af05af0);
|
||||
out_le32(qspi_key + 1, 0x00000001);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_TFABOOT
|
||||
#define MAX_BOOTCMD_SIZE 512
|
||||
|
||||
int fsl_setenv_bootcmd(void)
|
||||
{
|
||||
int ret;
|
||||
enum boot_src src = get_boot_src();
|
||||
char bootcmd_str[MAX_BOOTCMD_SIZE];
|
||||
|
||||
switch (src) {
|
||||
#ifdef IFC_NOR_BOOTCOMMAND
|
||||
case BOOT_SOURCE_IFC_NOR:
|
||||
sprintf(bootcmd_str, IFC_NOR_BOOTCOMMAND);
|
||||
break;
|
||||
#endif
|
||||
#ifdef QSPI_NOR_BOOTCOMMAND
|
||||
case BOOT_SOURCE_QSPI_NOR:
|
||||
sprintf(bootcmd_str, QSPI_NOR_BOOTCOMMAND);
|
||||
break;
|
||||
#endif
|
||||
#ifdef XSPI_NOR_BOOTCOMMAND
|
||||
case BOOT_SOURCE_XSPI_NOR:
|
||||
sprintf(bootcmd_str, XSPI_NOR_BOOTCOMMAND);
|
||||
break;
|
||||
#endif
|
||||
#ifdef IFC_NAND_BOOTCOMMAND
|
||||
case BOOT_SOURCE_IFC_NAND:
|
||||
sprintf(bootcmd_str, IFC_NAND_BOOTCOMMAND);
|
||||
break;
|
||||
#endif
|
||||
#ifdef QSPI_NAND_BOOTCOMMAND
|
||||
case BOOT_SOURCE_QSPI_NAND:
|
||||
sprintf(bootcmd_str, QSPI_NAND_BOOTCOMMAND);
|
||||
break;
|
||||
#endif
|
||||
#ifdef XSPI_NAND_BOOTCOMMAND
|
||||
case BOOT_SOURCE_XSPI_NAND:
|
||||
sprintf(bootcmd_str, XSPI_NAND_BOOTCOMMAND);
|
||||
break;
|
||||
#endif
|
||||
#ifdef SD_BOOTCOMMAND
|
||||
case BOOT_SOURCE_SD_MMC:
|
||||
sprintf(bootcmd_str, SD_BOOTCOMMAND);
|
||||
break;
|
||||
#endif
|
||||
#ifdef SD2_BOOTCOMMAND
|
||||
case BOOT_SOURCE_SD_MMC2:
|
||||
sprintf(bootcmd_str, SD2_BOOTCOMMAND);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
#ifdef QSPI_NOR_BOOTCOMMAND
|
||||
sprintf(bootcmd_str, QSPI_NOR_BOOTCOMMAND);
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
|
||||
ret = env_set("bootcmd", bootcmd_str);
|
||||
if (ret) {
|
||||
printf("Failed to set bootcmd: ret = %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int fsl_setenv_mcinitcmd(void)
|
||||
{
|
||||
int ret = 0;
|
||||
enum boot_src src = get_boot_src();
|
||||
|
||||
switch (src) {
|
||||
#ifdef IFC_MC_INIT_CMD
|
||||
case BOOT_SOURCE_IFC_NAND:
|
||||
case BOOT_SOURCE_IFC_NOR:
|
||||
ret = env_set("mcinitcmd", IFC_MC_INIT_CMD);
|
||||
break;
|
||||
#endif
|
||||
#ifdef QSPI_MC_INIT_CMD
|
||||
case BOOT_SOURCE_QSPI_NAND:
|
||||
case BOOT_SOURCE_QSPI_NOR:
|
||||
ret = env_set("mcinitcmd", QSPI_MC_INIT_CMD);
|
||||
break;
|
||||
#endif
|
||||
#ifdef XSPI_MC_INIT_CMD
|
||||
case BOOT_SOURCE_XSPI_NAND:
|
||||
case BOOT_SOURCE_XSPI_NOR:
|
||||
ret = env_set("mcinitcmd", XSPI_MC_INIT_CMD);
|
||||
break;
|
||||
#endif
|
||||
#ifdef SD_MC_INIT_CMD
|
||||
case BOOT_SOURCE_SD_MMC:
|
||||
ret = env_set("mcinitcmd", SD_MC_INIT_CMD);
|
||||
break;
|
||||
#endif
|
||||
#ifdef SD2_MC_INIT_CMD
|
||||
case BOOT_SOURCE_SD_MMC2:
|
||||
ret = env_set("mcinitcmd", SD2_MC_INIT_CMD);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
#ifdef QSPI_MC_INIT_CMD
|
||||
ret = env_set("mcinitcmd", QSPI_MC_INIT_CMD);
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
|
||||
if (ret) {
|
||||
printf("Failed to set mcinitcmd: ret = %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_BOARD_LATE_INIT
|
||||
__weak int fsl_board_late_init(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int board_late_init(void)
|
||||
{
|
||||
#ifdef CONFIG_CHAIN_OF_TRUST
|
||||
fsl_setenv_chain_of_trust();
|
||||
#endif
|
||||
#ifdef CONFIG_TFABOOT
|
||||
/*
|
||||
* check if gd->env_addr is default_environment; then setenv bootcmd
|
||||
* and mcinitcmd.
|
||||
*/
|
||||
#ifdef CONFIG_SYS_RELOC_GD_ENV_ADDR
|
||||
if (gd->env_addr == (ulong)&default_environment[0]) {
|
||||
#else
|
||||
if (gd->env_addr + gd->reloc_off == (ulong)&default_environment[0]) {
|
||||
#endif
|
||||
fsl_setenv_bootcmd();
|
||||
fsl_setenv_mcinitcmd();
|
||||
}
|
||||
|
||||
/*
|
||||
* If the boot mode is secure, default environment is not present then
|
||||
* setenv command needs to be run by default
|
||||
*/
|
||||
#ifdef CONFIG_CHAIN_OF_TRUST
|
||||
if ((fsl_check_boot_mode_secure() == 1)) {
|
||||
fsl_setenv_bootcmd();
|
||||
fsl_setenv_mcinitcmd();
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
#ifdef CONFIG_QSPI_AHB_INIT
|
||||
qspi_ahb_init();
|
||||
#endif
|
||||
|
||||
return fsl_board_late_init();
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,140 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Copyright 2014-2015 Freescale Semiconductor, Inc.
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <cpu_func.h>
|
||||
#include <env.h>
|
||||
#include <spl.h>
|
||||
#include <asm/io.h>
|
||||
#include <fsl_ifc.h>
|
||||
#include <i2c.h>
|
||||
#include <fsl_csu.h>
|
||||
#include <asm/arch/fdt.h>
|
||||
#include <asm/arch/ppa.h>
|
||||
#include <asm/arch/soc.h>
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
u32 spl_boot_device(void)
|
||||
{
|
||||
#ifdef CONFIG_SPL_MMC_SUPPORT
|
||||
return BOOT_DEVICE_MMC1;
|
||||
#endif
|
||||
#ifdef CONFIG_SPL_NAND_SUPPORT
|
||||
return BOOT_DEVICE_NAND;
|
||||
#endif
|
||||
#ifdef CONFIG_QSPI_BOOT
|
||||
return BOOT_DEVICE_NOR;
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SPL_BUILD
|
||||
|
||||
void spl_board_init(void)
|
||||
{
|
||||
#if defined(CONFIG_NXP_ESBC) && defined(CONFIG_FSL_LSCH2)
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
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);
|
||||
#endif
|
||||
#ifdef CONFIG_LAYERSCAPE_NS_ACCESS
|
||||
enable_layerscape_ns_access();
|
||||
#endif
|
||||
#ifdef CONFIG_SPL_FSL_LS_PPA
|
||||
ppa_init();
|
||||
#endif
|
||||
}
|
||||
|
||||
void board_init_f(ulong dummy)
|
||||
{
|
||||
icache_enable();
|
||||
/* Clear global data */
|
||||
memset((void *)gd, 0, sizeof(gd_t));
|
||||
board_early_init_f();
|
||||
timer_init();
|
||||
#ifdef CONFIG_ARCH_LS2080A
|
||||
env_init();
|
||||
#endif
|
||||
get_clocks();
|
||||
|
||||
preloader_console_init();
|
||||
spl_set_bd();
|
||||
|
||||
#ifdef CONFIG_SPL_I2C_SUPPORT
|
||||
i2c_init_all();
|
||||
#endif
|
||||
#ifdef CONFIG_VID
|
||||
init_func_vid();
|
||||
#endif
|
||||
dram_init();
|
||||
#ifdef CONFIG_SPL_FSL_LS_PPA
|
||||
#ifndef CONFIG_SYS_MEM_RESERVE_SECURE
|
||||
#error Need secure RAM for PPA
|
||||
#endif
|
||||
/*
|
||||
* Secure memory location is determined in dram_init_banksize().
|
||||
* gd->ram_size is deducted by the size of secure ram.
|
||||
*/
|
||||
dram_init_banksize();
|
||||
|
||||
/*
|
||||
* After dram_init_bank_size(), we know U-Boot only uses the first
|
||||
* memory bank regardless how big the memory is.
|
||||
*/
|
||||
gd->ram_top = gd->bd->bi_dram[0].start + gd->bd->bi_dram[0].size;
|
||||
|
||||
/*
|
||||
* If PPA is loaded, U-Boot will resume running at EL2.
|
||||
* Cache and MMU will be enabled. Need a place for TLB.
|
||||
* U-Boot will be relocated to the end of available memory
|
||||
* in first bank. At this point, we cannot know how much
|
||||
* memory U-Boot uses. Put TLB table lower by SPL_TLB_SETBACK
|
||||
* to avoid overlapping. As soon as the RAM version U-Boot sets
|
||||
* up new MMU, this space is no longer needed.
|
||||
*/
|
||||
gd->ram_top -= SPL_TLB_SETBACK;
|
||||
gd->arch.tlb_size = PGTABLE_SIZE;
|
||||
gd->arch.tlb_addr = (gd->ram_top - gd->arch.tlb_size) & ~(0x10000 - 1);
|
||||
gd->arch.tlb_allocated = gd->arch.tlb_addr;
|
||||
#endif /* CONFIG_SPL_FSL_LS_PPA */
|
||||
#if defined(CONFIG_QSPI_AHB_INIT) && defined(CONFIG_QSPI_BOOT)
|
||||
qspi_ahb_init();
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SPL_OS_BOOT
|
||||
/*
|
||||
* Return
|
||||
* 0 if booting into OS is selected
|
||||
* 1 if booting into U-Boot is selected
|
||||
*/
|
||||
int spl_start_uboot(void)
|
||||
{
|
||||
env_init();
|
||||
if (env_get_yesno("boot_os") != 0)
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
#endif /* CONFIG_SPL_OS_BOOT */
|
||||
#ifdef CONFIG_SPL_LOAD_FIT
|
||||
int board_fit_config_name_match(const char *name)
|
||||
{
|
||||
/* Just empty function now - can't decide what to choose */
|
||||
debug("%s: %s\n", __func__, name);
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
#endif /* CONFIG_SPL_BUILD */
|
||||
Reference in New Issue
Block a user