diff options
Diffstat (limited to 'arch/arm/cpu/armv8/fsl-layerscape')
-rw-r--r-- | arch/arm/cpu/armv8/fsl-layerscape/Kconfig | 32 | ||||
-rw-r--r-- | arch/arm/cpu/armv8/fsl-layerscape/cpu.c | 9 | ||||
-rw-r--r-- | arch/arm/cpu/armv8/fsl-layerscape/fdt.c | 9 | ||||
-rw-r--r-- | arch/arm/cpu/armv8/fsl-layerscape/ls1028_ids.c | 93 | ||||
-rw-r--r-- | arch/arm/cpu/armv8/fsl-layerscape/soc.c | 56 | ||||
-rw-r--r-- | arch/arm/cpu/armv8/fsl-layerscape/spl.c | 2 |
6 files changed, 185 insertions, 16 deletions
diff --git a/arch/arm/cpu/armv8/fsl-layerscape/Kconfig b/arch/arm/cpu/armv8/fsl-layerscape/Kconfig index f1578b10bc..ed478ddd48 100644 --- a/arch/arm/cpu/armv8/fsl-layerscape/Kconfig +++ b/arch/arm/cpu/armv8/fsl-layerscape/Kconfig @@ -219,6 +219,7 @@ config ARCH_LX2160A select SYS_FSL_DDR_VER_50 select SYS_FSL_EC1 select SYS_FSL_EC2 + select SYS_FSL_ERRATUM_A050106 select SYS_FSL_HAS_RGMII select SYS_FSL_HAS_SEC select SYS_FSL_HAS_CCN508 @@ -252,20 +253,6 @@ menu "Layerscape architecture" 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 @@ -348,6 +335,14 @@ config SYS_FSL_ERRATUM_A009008 config SYS_FSL_ERRATUM_A009798 bool "Workaround for USB PHY erratum A009798" +config SYS_FSL_ERRATUM_A050106 + bool "Workaround for USB PHY erratum A050106" + help + USB3.0 Receiver needs to enable fixed equalization + for each of PHY instances in an SOC. This is similar + to erratum A-009007, but this one is for LX2160A, + and the register value is different. + config SYS_FSL_ERRATUM_A010315 bool "Workaround for PCIe erratum A010315" @@ -388,6 +383,15 @@ config QSPI_AHB_INIT 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 FSPI_AHB_EN_4BYTE + bool "Enable 4-byte Fast Read command for AHB mode" + default n + help + The default setting for FlexSPI AHB bus just supports 3-byte addressing. + But some FlexSPI flash sizes are up to 64MBytes. + This flag enables fast read command for AHB mode and modifies required + LUT to support full FlexSPI flash. + config SYS_CCI400_OFFSET hex "Offset for CCI400 base" depends on SYS_FSL_HAS_CCI400 diff --git a/arch/arm/cpu/armv8/fsl-layerscape/cpu.c b/arch/arm/cpu/armv8/fsl-layerscape/cpu.c index 6c87c1b11a..639f531649 100644 --- a/arch/arm/cpu/armv8/fsl-layerscape/cpu.c +++ b/arch/arm/cpu/armv8/fsl-layerscape/cpu.c @@ -1101,6 +1101,12 @@ static void config_core_prefetch(void) } } +#ifdef CONFIG_PCIE_ECAM_GENERIC +__weak void set_ecam_icids(void) +{ +} +#endif + int arch_early_init_r(void) { #ifdef CONFIG_SYS_FSL_ERRATUM_A009635 @@ -1153,6 +1159,9 @@ int arch_early_init_r(void) #ifdef CONFIG_SYS_DPAA_QBMAN setup_qbman_portals(); #endif +#ifdef CONFIG_PCIE_ECAM_GENERIC + set_ecam_icids(); +#endif return 0; } diff --git a/arch/arm/cpu/armv8/fsl-layerscape/fdt.c b/arch/arm/cpu/armv8/fsl-layerscape/fdt.c index e993209593..1e7e46e88a 100644 --- a/arch/arm/cpu/armv8/fsl-layerscape/fdt.c +++ b/arch/arm/cpu/armv8/fsl-layerscape/fdt.c @@ -421,6 +421,12 @@ static void fdt_disable_multimedia(void *blob, unsigned int svr) } #endif +#ifdef CONFIG_PCIE_ECAM_GENERIC +__weak void fdt_fixup_ecam(void *blob) +{ +} +#endif + void ft_cpu_setup(void *blob, bd_t *bd) { struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR); @@ -485,4 +491,7 @@ void ft_cpu_setup(void *blob, bd_t *bd) #ifdef CONFIG_ARCH_LS1028A fdt_disable_multimedia(blob, svr); #endif +#ifdef CONFIG_PCIE_ECAM_GENERIC + fdt_fixup_ecam(blob); +#endif } diff --git a/arch/arm/cpu/armv8/fsl-layerscape/ls1028_ids.c b/arch/arm/cpu/armv8/fsl-layerscape/ls1028_ids.c index 9462298fbf..8110412da6 100644 --- a/arch/arm/cpu/armv8/fsl-layerscape/ls1028_ids.c +++ b/arch/arm/cpu/armv8/fsl-layerscape/ls1028_ids.c @@ -33,3 +33,96 @@ struct icid_id_table icid_tbl[] = { }; int icid_tbl_sz = ARRAY_SIZE(icid_tbl); + +/* integrated PCI is handled separately as it's not part of CCSR/SCFG */ +#ifdef CONFIG_PCIE_ECAM_GENERIC + +#define ECAM_IERB_BASE 0x1f0800000ULL +#define ECAM_IERB_OFFSET_NA -1 +#define ECAM_IERB_FUNC_CNT ARRAY_SIZE(ierb_offset) +/* cache related transaction attributes for PCIe functions */ +#define ECAM_IERB_MSICAR (ECAM_IERB_BASE + 0xa400) +#define ECAM_IERB_MSICAR_VALUE 0x30 + +/* offset of IERB config register per PCI function */ +static int ierb_offset[] = { + 0x0800, + 0x1800, + 0x2800, + 0x3800, + 0x4800, + 0x5800, + 0x6800, + ECAM_IERB_OFFSET_NA, + 0x0804, + 0x0808, + 0x1804, + 0x1808, +}; + +/* + * Use a custom function for LS1028A, for now this is the only SoC with IERB + * and we're currently considering reorganizing IERB for future SoCs. + */ +void set_ecam_icids(void) +{ + int i; + + out_le32(ECAM_IERB_MSICAR, ECAM_IERB_MSICAR_VALUE); + + for (i = 0; i < ECAM_IERB_FUNC_CNT; i++) { + if (ierb_offset[i] == ECAM_IERB_OFFSET_NA) + continue; + + out_le32(ECAM_IERB_BASE + ierb_offset[i], + FSL_ECAM_STREAM_ID_START + i); + } +} + +static int fdt_setprop_inplace_idx_u32(void *fdt, int nodeoffset, + const char *name, uint32_t idx, u32 val) +{ + val = cpu_to_be32(val); + return fdt_setprop_inplace_namelen_partial(fdt, nodeoffset, name, + strlen(name), + idx * sizeof(val), &val, + sizeof(val)); +} + +static int fdt_getprop_len(void *fdt, int nodeoffset, const char *name) +{ + int len; + + if (fdt_getprop_namelen(fdt, nodeoffset, name, strlen(name), &len)) + return len; + + return 0; +} + +void fdt_fixup_ecam(void *blob) +{ + int off; + + off = fdt_node_offset_by_compatible(blob, 0, "pci-host-ecam-generic"); + if (off < 0) { + debug("ECAM node not found\n"); + return; + } + + if (fdt_getprop_len(blob, off, "msi-map") != 16 || + fdt_getprop_len(blob, off, "iommu-map") != 16) { + log_err("invalid msi/iommu-map propertly size in ECAM node\n"); + return; + } + + fdt_setprop_inplace_idx_u32(blob, off, "msi-map", 2, + FSL_ECAM_STREAM_ID_START); + fdt_setprop_inplace_idx_u32(blob, off, "msi-map", 3, + ECAM_IERB_FUNC_CNT); + + fdt_setprop_inplace_idx_u32(blob, off, "iommu-map", 2, + FSL_ECAM_STREAM_ID_START); + fdt_setprop_inplace_idx_u32(blob, off, "iommu-map", 3, + ECAM_IERB_FUNC_CNT); +} +#endif /* CONFIG_PCIE_ECAM_GENERIC */ diff --git a/arch/arm/cpu/armv8/fsl-layerscape/soc.c b/arch/arm/cpu/armv8/fsl-layerscape/soc.c index 70933a2e03..578f8d12de 100644 --- a/arch/arm/cpu/armv8/fsl-layerscape/soc.c +++ b/arch/arm/cpu/armv8/fsl-layerscape/soc.c @@ -147,7 +147,7 @@ static void erratum_a008997(void) 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) + defined(CONFIG_ARCH_LS1028A) || defined(CONFIG_ARCH_LX2160A) #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); \ @@ -181,6 +181,15 @@ static void erratum_a009007(void) } #if defined(CONFIG_FSL_LSCH3) +static void erratum_a050106(void) +{ +#if defined(CONFIG_ARCH_LX2160A) + 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 +} /* * This erratum requires setting a value to eddrtqcr1 to * optimal the DDR performance. @@ -332,6 +341,7 @@ void fsl_lsch3_early_init_f(void) erratum_a009798(); erratum_a008997(); erratum_a009007(); + erratum_a050106(); #ifdef CONFIG_CHAIN_OF_TRUST /* In case of Secure Boot, the IBR configures the SMMU * to allow only Secure transactions. @@ -676,6 +686,47 @@ void fsl_lsch2_early_init_f(void) } #endif +#ifdef CONFIG_FSPI_AHB_EN_4BYTE +int fspi_ahb_init(void) +{ + /* Enable 4bytes address support and fast read */ + u32 *fspi_lut, lut_key, *fspi_key; + + fspi_key = (void *)SYS_NXP_FSPI_ADDR + SYS_NXP_FSPI_LUTKEY_BASE_ADDR; + fspi_lut = (void *)SYS_NXP_FSPI_ADDR + SYS_NXP_FSPI_LUT_BASE_ADDR; + + lut_key = in_be32(fspi_key); + + if (lut_key == SYS_NXP_FSPI_LUTKEY) { + /* That means the register is BE */ + out_be32(fspi_key, SYS_NXP_FSPI_LUTKEY); + /* Unlock the lut table */ + out_be32(fspi_key + 1, SYS_NXP_FSPI_LUTCR_UNLOCK); + /* Create READ LUT */ + out_be32(fspi_lut, 0x0820040c); + out_be32(fspi_lut + 1, 0x24003008); + out_be32(fspi_lut + 2, 0x00000000); + /* Lock the lut table */ + out_be32(fspi_key, SYS_NXP_FSPI_LUTKEY); + out_be32(fspi_key + 1, SYS_NXP_FSPI_LUTCR_LOCK); + } else { + /* That means the register is LE */ + out_le32(fspi_key, SYS_NXP_FSPI_LUTKEY); + /* Unlock the lut table */ + out_le32(fspi_key + 1, SYS_NXP_FSPI_LUTCR_UNLOCK); + /* Create READ LUT */ + out_le32(fspi_lut, 0x0820040c); + out_le32(fspi_lut + 1, 0x24003008); + out_le32(fspi_lut + 2, 0x00000000); + /* Lock the lut table */ + out_le32(fspi_key, SYS_NXP_FSPI_LUTKEY); + out_le32(fspi_key + 1, SYS_NXP_FSPI_LUTCR_LOCK); + } + + return 0; +} +#endif + #ifdef CONFIG_QSPI_AHB_INIT /* Enable 4bytes address support and fast read */ int qspi_ahb_init(void) @@ -868,6 +919,9 @@ int board_late_init(void) #ifdef CONFIG_QSPI_AHB_INIT qspi_ahb_init(); #endif +#ifdef CONFIG_FSPI_AHB_EN_4BYTE + fspi_ahb_init(); +#endif return fsl_board_late_init(); } diff --git a/arch/arm/cpu/armv8/fsl-layerscape/spl.c b/arch/arm/cpu/armv8/fsl-layerscape/spl.c index 58a39e1123..ed3a605663 100644 --- a/arch/arm/cpu/armv8/fsl-layerscape/spl.c +++ b/arch/arm/cpu/armv8/fsl-layerscape/spl.c @@ -129,7 +129,7 @@ int spl_start_uboot(void) } #endif /* CONFIG_SPL_OS_BOOT */ #ifdef CONFIG_SPL_LOAD_FIT -int board_fit_config_name_match(const char *name) +__weak 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); |