提交 8fbbec12 编写于 作者: T Tom Rini

Merge https://gitlab.denx.de/u-boot/custodians/u-boot-fsl-qoriq into next

- updates and fixes on ls1028a, lx2, ls1046a, MC-DPSPARSER support
......@@ -27,14 +27,6 @@ config ARCH_LS1021A
menu "LS102xA architecture"
depends on ARCH_LS1021A
config FSL_PCIE_COMPAT
string "PCIe compatible of Kernel DT"
depends on PCIE_LAYERSCAPE
default "fsl,ls1021a-pcie" if ARCH_LS1021A
help
This compatible is used to find pci controller node in Kernel DT
to complete fixup.
config LS1_DEEP_SLEEP
bool "Deep sleep"
depends on ARCH_LS1021A
......
......@@ -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
......
......@@ -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
......@@ -1152,6 +1158,9 @@ int arch_early_init_r(void)
#endif
#ifdef CONFIG_SYS_DPAA_QBMAN
setup_qbman_portals();
#endif
#ifdef CONFIG_PCIE_ECAM_GENERIC
set_ecam_icids();
#endif
return 0;
}
......
......@@ -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
}
......@@ -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 */
......@@ -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();
}
......
......@@ -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);
......
......@@ -127,12 +127,14 @@
compatible = "arm,pl011";
reg = <0x0 0x21c0000 0x0 0x1000>;
clocks = <&clockgen 4 0>;
status = "disabled";
};
uart1: serial@21d0000 {
compatible = "arm,pl011";
reg = <0x0 0x21d0000 0x0 0x1000>;
clocks = <&clockgen 4 0>;
status = "disabled";
};
uart2: serial@21e0000 {
......
......@@ -23,7 +23,13 @@
#define CONFIG_SYS_FSL_CH3_CLK_GRPA_ADDR (CONFIG_SYS_IMMR + 0x00300000)
#define CONFIG_SYS_FSL_CH3_CLK_GRPB_ADDR (CONFIG_SYS_IMMR + 0x00310000)
#define CONFIG_SYS_FSL_CH3_CLK_CTRL_ADDR (CONFIG_SYS_IMMR + 0x00370000)
#ifndef CONFIG_NXP_LSCH3_2
#define SYS_FSL_QSPI_ADDR (CONFIG_SYS_IMMR + 0x010c0000)
#else
#define SYS_NXP_FSPI_ADDR (CONFIG_SYS_IMMR + 0x010c0000)
#define SYS_NXP_FSPI_LUTKEY_BASE_ADDR 0x18
#define SYS_NXP_FSPI_LUT_BASE_ADDR 0x200
#endif
#define CONFIG_SYS_FSL_ESDHC_ADDR (CONFIG_SYS_IMMR + 0x01140000)
#define FSL_ESDHC1_BASE_ADDR CONFIG_SYS_FSL_ESDHC_ADDR
#define FSL_ESDHC2_BASE_ADDR (CONFIG_SYS_IMMR + 0x01150000)
......@@ -252,8 +258,14 @@
#define DCSR_USB_PHY_RX_OVRD_IN_HI 0x200C
#define USB_PHY_RX_EQ_VAL_1 0x0000
#define USB_PHY_RX_EQ_VAL_2 0x0080
#if defined(CONFIG_ARCH_LS2080A) || defined(CONFIG_ARCH_LS1088A) || \
defined(CONFIG_ARCH_LS1028A)
#define USB_PHY_RX_EQ_VAL_3 0x0380
#define USB_PHY_RX_EQ_VAL_4 0x0b80
#elif defined(CONFIG_ARCH_LX2160A)
#define USB_PHY_RX_EQ_VAL_3 0x0080
#define USB_PHY_RX_EQ_VAL_4 0x0880
#endif
#define DCSR_USB_IOCR1 0x108004
#define DCSR_USB_PCSTXSWINGFULL 0x71
......
......@@ -140,6 +140,13 @@ void init_pfe_scfg_dcfg_regs(void);
int qspi_ahb_init(void);
#endif
#ifdef CONFIG_FSPI_AHB_EN_4BYTE
#define SYS_NXP_FSPI_LUTCR_LOCK 0x00000001
#define SYS_NXP_FSPI_LUTCR_UNLOCK 0x00000002
#define SYS_NXP_FSPI_LUTKEY 0x5AF05AF0
int fspi_ahb_init(void);
#endif
void cpu_name(char *name);
#ifdef CONFIG_SYS_FSL_ERRATUM_A009635
void erratum_a009635(void);
......
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* Copyright 2015-2018 NXP
* Copyright 2015-2019 NXP
* Copyright 2014 Freescale Semiconductor, Inc.
*
*/
......@@ -42,6 +42,10 @@
* -the MC is responsible for allocating and setting up 'isolation context
* IDs (ICIDs) based on the allocated stream IDs for all DPAA2 devices.
*
* - ECAM (integrated PCI)
* - U-Boot applies the value here to HW and does DT fix-up for both
* 'iommu-map' and 'msi-map'
*
* On Chasis-3 SoCs stream IDs are programmed in AMQ registers (32-bits) for
* each of the different bus masters. The relationship between
* the AMQ registers and stream IDs is defined in the table below:
......@@ -83,14 +87,12 @@
/* PCI - programmed in PEXn_LUT */
#define FSL_PEX_STREAM_ID_START 7
#ifdef CONFIG_ARCH_LX2160A
#define FSL_PEX_STREAM_ID_NUM (0x100)
#endif
#if defined(CONFIG_ARCH_LS2080A) || defined(CONFIG_ARCH_LS1028A)
#define FSL_PEX_STREAM_ID_END 22
#elif defined(CONFIG_ARCH_LS1088A)
#define FSL_PEX_STREAM_ID_END 18
#elif defined(CONFIG_ARCH_LX2160A)
#define FSL_PEX_STREAM_ID_END (0x100)
#endif
......@@ -98,6 +100,10 @@
#define FSL_DPAA2_STREAM_ID_START 23
#define FSL_DPAA2_STREAM_ID_END 63
/* PCI IEPs, this overlaps DPAA2 but these two are exclusive at least for now */
#define FSL_ECAM_STREAM_ID_START 32
#define FSL_ECAM_STREAM_ID_END 63
#define FSL_SEC_STREAM_ID 64
#define FSL_SEC_JR1_STREAM_ID 65
#define FSL_SEC_JR2_STREAM_ID 66
......
......@@ -86,7 +86,19 @@ int board_init(void)
if (!i2c_get_chip_for_busnum(0, I2C_MUX_PCA_ADDR_PRI, 1, &dev))
dm_i2c_write(dev, 0x0b, &val, 1);
#endif
#endif
#if defined(CONFIG_TARGET_LS1028ARDB)
u8 reg;
reg = QIXIS_READ(brdcfg[4]);
/*
* Field | Function
* 3 | DisplayPort Power Enable (net DP_PWR_EN):
* DPPWR | 0= DP_PWR is enabled.
*/
reg &= ~(DP_PWD_EN_DEFAULT_MASK);
QIXIS_WRITE(brdcfg[4], reg);
#endif
return 0;
}
......
......@@ -24,7 +24,8 @@
#define LS1046A_PORSR1_REG 0x1EE0000
#define BOOT_SRC_SD 0x20000000
#define BOOT_SRC_MASK 0xFF800000
#define BOARD_REV_GPIO 13
#define BOARD_REV_GPIO_SHIFT 17
#define BOARD_REV_MASK 0x03
#define USB2_SEL_MASK 0x00000100
#define BYTE_SWAP_32(word) ((((word) & 0xff000000) >> 24) | \
......@@ -87,10 +88,14 @@ int board_early_init_f(void)
static inline uint8_t get_board_version(void)
{
u8 val;
struct ccsr_gpio *pgpio = (void *)(GPIO2_BASE_ADDR);
val = (in_le32(&pgpio->gpdat) >> BOARD_REV_GPIO) & 0x03;
/* GPIO 13 and GPIO 14 are used for Board Rev */
u32 gpio_val = ((in_be32(&pgpio->gpdat) >> BOARD_REV_GPIO_SHIFT))
& BOARD_REV_MASK;
/* GPIOs' are 0..31 in Big Endiness, swap GPIO 13 and GPIO 14 */
u8 val = ((gpio_val >> 1) | (gpio_val << 1)) & BOARD_REV_MASK;
return val;
}
......
......@@ -91,20 +91,24 @@ config SPL_SYS_REPORT_STACK_F_USAGE
occurrence of non 0xaa bytes.
This default implementation works for stacks growing down only.
menu "PowerPC SPL Boot options"
depends on PPC && (SUPPORT_SPL && !SPL_FRAMEWORK)
menu "PowerPC and LayerScape SPL Boot options"
config SPL_NAND_BOOT
bool "Load SPL from NAND flash"
depends on PPC && (SUPPORT_SPL && !SPL_FRAMEWORK)
config SPL_MMC_BOOT
bool "Load SPL from SD Card / eMMC"
depends on PPC && (SUPPORT_SPL && !SPL_FRAMEWORK)
config SPL_SPI_BOOT
bool "Load SPL from SPI flash"
depends on PPC && (SUPPORT_SPL && !SPL_FRAMEWORK)
config SPL_FSL_PBL
bool "Create SPL in Freescale PBI format"
depends on (PPC || ARCH_LS1021A || ARCH_LS1043A || ARCH_LS1046A) && \
SUPPORT_SPL
help
Create boot binary having SPL binary in PBI format concatenated with
u-boot binary.
......
......@@ -7,6 +7,7 @@ CONFIG_ENV_OFFSET=0x100000
CONFIG_NR_DRAM_BANKS=1
CONFIG_SPL=y
CONFIG_AHCI=y
CONFIG_SPL_FSL_PBL=y
CONFIG_SPL_TEXT_BASE=0x10000000
CONFIG_SYS_EXTRA_OPTIONS="RAMBOOT_PBL,SD_BOOT,SD_BOOT_QSPI"
CONFIG_MISC_INIT_R=y
......
......@@ -10,6 +10,7 @@ CONFIG_ENV_OFFSET=0x140000
CONFIG_NR_DRAM_BANKS=1
CONFIG_SPL=y
CONFIG_AHCI=y
CONFIG_SPL_FSL_PBL=y
CONFIG_SPL_TEXT_BASE=0x10000000
CONFIG_FIT=y
CONFIG_FIT_VERBOSE=y
......
......@@ -11,6 +11,7 @@ CONFIG_ENV_OFFSET=0x300000
CONFIG_NR_DRAM_BANKS=1
CONFIG_SPL=y
CONFIG_AHCI=y
CONFIG_SPL_FSL_PBL=y
CONFIG_SPL_TEXT_BASE=0x10000000
CONFIG_FIT=y
CONFIG_FIT_VERBOSE=y
......
......@@ -11,6 +11,7 @@ CONFIG_ENV_OFFSET=0x300000
CONFIG_NR_DRAM_BANKS=1
CONFIG_SPL=y
CONFIG_AHCI=y
CONFIG_SPL_FSL_PBL=y
CONFIG_SPL_TEXT_BASE=0x10000000
CONFIG_FIT=y
CONFIG_FIT_VERBOSE=y
......
......@@ -10,6 +10,7 @@ CONFIG_SPL_DRIVERS_MISC_SUPPORT=y
CONFIG_ENV_SIZE=0x20000
CONFIG_NR_DRAM_BANKS=1
CONFIG_SPL=y
CONFIG_SPL_FSL_PBL=y
CONFIG_SPL_TEXT_BASE=0x10000000
CONFIG_DISTRO_DEFAULTS=y
CONFIG_FIT=y
......
......@@ -10,6 +10,7 @@ CONFIG_ENV_OFFSET=0x300000
CONFIG_NR_DRAM_BANKS=1
CONFIG_SPL=y
CONFIG_AHCI=y
CONFIG_SPL_FSL_PBL=y
CONFIG_SPL_TEXT_BASE=0x10000000
CONFIG_DISTRO_DEFAULTS=y
CONFIG_FIT=y
......
......@@ -10,6 +10,7 @@ CONFIG_ENV_OFFSET=0x300000
CONFIG_NR_DRAM_BANKS=1
CONFIG_SPL=y
CONFIG_AHCI=y
CONFIG_SPL_FSL_PBL=y
CONFIG_SPL_TEXT_BASE=0x10000000
CONFIG_DISTRO_DEFAULTS=y
CONFIG_FIT=y
......
......@@ -3,6 +3,7 @@ CONFIG_TARGET_LS1028AQDS=y
CONFIG_TFABOOT=y
CONFIG_SYS_MALLOC_F_LEN=0x6000
CONFIG_NXP_ESBC=y
CONFIG_FSPI_AHB_EN_4BYTE=y
CONFIG_SYS_FSL_SDHC_CLK_DIV=1
CONFIG_ENV_SIZE=0x2000
CONFIG_NR_DRAM_BANKS=2
......
......@@ -2,6 +2,7 @@ CONFIG_ARM=y
CONFIG_TARGET_LS1028AQDS=y
CONFIG_TFABOOT=y
CONFIG_SYS_MALLOC_F_LEN=0x6000
CONFIG_FSPI_AHB_EN_4BYTE=y
CONFIG_SYS_FSL_SDHC_CLK_DIV=1
CONFIG_ENV_SIZE=0x2000
CONFIG_ENV_OFFSET=0x500000
......
......@@ -3,6 +3,7 @@ CONFIG_TARGET_LS1028ARDB=y
CONFIG_TFABOOT=y
CONFIG_SYS_MALLOC_F_LEN=0x6000
CONFIG_NXP_ESBC=y
CONFIG_FSPI_AHB_EN_4BYTE=y
CONFIG_SYS_FSL_SDHC_CLK_DIV=1
CONFIG_ENV_SIZE=0x2000
CONFIG_NR_DRAM_BANKS=2
......
......@@ -2,6 +2,7 @@ CONFIG_ARM=y
CONFIG_TARGET_LS1028ARDB=y
CONFIG_TFABOOT=y
CONFIG_SYS_MALLOC_F_LEN=0x6000
CONFIG_FSPI_AHB_EN_4BYTE=y
CONFIG_SYS_FSL_SDHC_CLK_DIV=1
CONFIG_ENV_SIZE=0x2000
CONFIG_ENV_OFFSET=0x500000
......@@ -80,4 +81,8 @@ CONFIG_USB_XHCI_DWC3=y
CONFIG_WDT=y
CONFIG_WDT_SP805=y
CONFIG_OF_LIBFDT_OVERLAY=y
CONFIG_USB_HOST_ETHER=y
CONFIG_USB_ETHER_RTL8152=y
CONFIG_USB_ETHER_ASIX=y
CONFIG_USB_ETHER_ASIX88179=y
CONFIG_EFI_LOADER_BOUNCE_BUFFER=y
......@@ -11,6 +11,7 @@ CONFIG_ENV_OFFSET=0x300000
CONFIG_NR_DRAM_BANKS=2
CONFIG_SPL=y
CONFIG_AHCI=y
CONFIG_SPL_FSL_PBL=y
CONFIG_SPL_TEXT_BASE=0x10000000
CONFIG_DISTRO_DEFAULTS=y
CONFIG_FIT_VERBOSE=y
......
......@@ -12,6 +12,7 @@ CONFIG_ENV_OFFSET=0x300000
CONFIG_NR_DRAM_BANKS=2
CONFIG_SPL=y
CONFIG_AHCI=y
CONFIG_SPL_FSL_PBL=y
CONFIG_SPL_TEXT_BASE=0x10000000
CONFIG_DISTRO_DEFAULTS=y
CONFIG_FIT_VERBOSE=y
......
......@@ -12,6 +12,7 @@ CONFIG_ENV_OFFSET=0x300000
CONFIG_NR_DRAM_BANKS=2
CONFIG_SPL=y
CONFIG_AHCI=y
CONFIG_SPL_FSL_PBL=y
CONFIG_SPL_TEXT_BASE=0x10000000
CONFIG_DISTRO_DEFAULTS=y
CONFIG_FIT_VERBOSE=y
......
......@@ -10,6 +10,7 @@ CONFIG_SPL_DRIVERS_MISC_SUPPORT=y
CONFIG_ENV_SIZE=0x2000
CONFIG_NR_DRAM_BANKS=2
CONFIG_SPL=y
CONFIG_SPL_FSL_PBL=y
CONFIG_SPL_TEXT_BASE=0x10000000
CONFIG_DISTRO_DEFAULTS=y
CONFIG_FIT_VERBOSE=y
......
......@@ -10,6 +10,7 @@ CONFIG_ENV_SIZE=0x2000
CONFIG_ENV_OFFSET=0x300000
CONFIG_NR_DRAM_BANKS=2
CONFIG_SPL=y
CONFIG_SPL_FSL_PBL=y
CONFIG_SPL_TEXT_BASE=0x10000000
CONFIG_DISTRO_DEFAULTS=y
CONFIG_FIT_VERBOSE=y
......
......@@ -11,6 +11,7 @@ CONFIG_SPL_DRIVERS_MISC_SUPPORT=y
CONFIG_ENV_SIZE=0x2000
CONFIG_NR_DRAM_BANKS=2
CONFIG_SPL=y
CONFIG_SPL_FSL_PBL=y
CONFIG_SPL_TEXT_BASE=0x10000000
CONFIG_DISTRO_DEFAULTS=y
CONFIG_FIT_VERBOSE=y
......
......@@ -11,6 +11,7 @@ CONFIG_ENV_SIZE=0x2000
CONFIG_ENV_OFFSET=0x300000
CONFIG_NR_DRAM_BANKS=2
CONFIG_SPL=y
CONFIG_SPL_FSL_PBL=y
CONFIG_SPL_TEXT_BASE=0x10000000
CONFIG_DISTRO_DEFAULTS=y
CONFIG_FIT_VERBOSE=y
......
......@@ -8,6 +8,7 @@ CONFIG_ENV_OFFSET=0x300000
CONFIG_NR_DRAM_BANKS=2
CONFIG_SPL=y
CONFIG_AHCI=y
CONFIG_SPL_FSL_PBL=y
CONFIG_SPL_TEXT_BASE=0x10000000
CONFIG_DISTRO_DEFAULTS=y
CONFIG_FIT_VERBOSE=y
......
......@@ -12,6 +12,7 @@ CONFIG_ENV_OFFSET=0x300000
CONFIG_NR_DRAM_BANKS=2
CONFIG_SPL=y
CONFIG_AHCI=y
CONFIG_SPL_FSL_PBL=y
CONFIG_SPL_TEXT_BASE=0x10000000
CONFIG_DISTRO_DEFAULTS=y
CONFIG_FIT_VERBOSE=y
......
......@@ -12,6 +12,7 @@ CONFIG_ENV_OFFSET=0x300000
CONFIG_NR_DRAM_BANKS=2
CONFIG_SPL=y
CONFIG_AHCI=y
CONFIG_SPL_FSL_PBL=y
CONFIG_SPL_TEXT_BASE=0x10000000
CONFIG_DISTRO_DEFAULTS=y
CONFIG_FIT_VERBOSE=y
......
......@@ -12,6 +12,7 @@ CONFIG_ENV_OFFSET=0x300000
CONFIG_NR_DRAM_BANKS=2
CONFIG_SPL=y
CONFIG_AHCI=y
CONFIG_SPL_FSL_PBL=y
CONFIG_SPL_TEXT_BASE=0x10000000
CONFIG_DISTRO_DEFAULTS=y
CONFIG_FIT_VERBOSE=y
......
......@@ -11,6 +11,7 @@ CONFIG_SPL_DRIVERS_MISC_SUPPORT=y
CONFIG_ENV_SIZE=0x2000
CONFIG_NR_DRAM_BANKS=2
CONFIG_SPL=y
CONFIG_SPL_FSL_PBL=y
CONFIG_SPL_TEXT_BASE=0x10000000
CONFIG_DISTRO_DEFAULTS=y
CONFIG_FIT_VERBOSE=y
......
......@@ -12,6 +12,7 @@ CONFIG_ENV_OFFSET=0x300000
CONFIG_NR_DRAM_BANKS=2
CONFIG_SPL=y
CONFIG_AHCI=y
CONFIG_SPL_FSL_PBL=y
CONFIG_SPL_TEXT_BASE=0x10000000
CONFIG_DISTRO_DEFAULTS=y
CONFIG_FIT_VERBOSE=y
......
......@@ -4,6 +4,7 @@ CONFIG_TFABOOT=y
CONFIG_SYS_TEXT_BASE=0x82000000
CONFIG_SYS_MALLOC_F_LEN=0x6000
CONFIG_NXP_ESBC=y
CONFIG_FSPI_AHB_EN_4BYTE=y
CONFIG_ENV_SIZE=0x2000
CONFIG_NR_DRAM_BANKS=3
CONFIG_ARMV8_SEC_FIRMWARE_SUPPORT=y
......
......@@ -3,6 +3,7 @@ CONFIG_TARGET_LX2160AQDS=y
CONFIG_TFABOOT=y
CONFIG_SYS_TEXT_BASE=0x82000000
CONFIG_SYS_MALLOC_F_LEN=0x6000
CONFIG_FSPI_AHB_EN_4BYTE=y
CONFIG_ENV_SIZE=0x2000
CONFIG_ENV_OFFSET=0x500000
CONFIG_NR_DRAM_BANKS=3
......
......@@ -5,6 +5,7 @@ CONFIG_SYS_TEXT_BASE=0x82000000
CONFIG_SYS_MALLOC_F_LEN=0x6000
CONFIG_NXP_ESBC=y
CONFIG_EMC2305=y
CONFIG_FSPI_AHB_EN_4BYTE=y
CONFIG_ENV_SIZE=0x2000
CONFIG_NR_DRAM_BANKS=3
CONFIG_ARMV8_SEC_FIRMWARE_SUPPORT=y
......
......@@ -4,6 +4,7 @@ CONFIG_TFABOOT=y
CONFIG_SYS_TEXT_BASE=0x82000000
CONFIG_SYS_MALLOC_F_LEN=0x6000
CONFIG_EMC2305=y
CONFIG_FSPI_AHB_EN_4BYTE=y
CONFIG_ENV_SIZE=0x2000
CONFIG_ENV_OFFSET=0x500000
CONFIG_NR_DRAM_BANKS=3
......
......@@ -22,4 +22,16 @@ config SYS_MC_RSV_MEM_ALIGN
Reserved memory needs to be aligned for MC to use. Default value
is 512MB.
config MC_DRAM_SPB_OFFSET
hex "Soft Parser SPB DRAM offset"
default 0x00F40000
help
Set the DRAM offset for Soft Parser Blob.
config MC_SPB_MAX_SIZE
hex "Soft Parser SPB maximum size"
default 0x00020000
help
Set the maximum size for Soft Parser Blob.
endif # FSL_MC_ENET
# SPDX-License-Identifier: GPL-2.0+
#
# Copyright 2014 Freescale Semiconductor, Inc.
# Copyright 2018 NXP
# Layerscape MC driver
obj-y += mc.o \
......@@ -9,5 +10,6 @@ obj-y += mc.o \
dprc.o \
dpbp.o \
dpni.o \
dpmac.o
dpmac.o \
dpsparser.o
obj-y += dpio/
// SPDX-License-Identifier: GPL-2.0+
/*
* Data Path Soft Parser
*
* Copyright 2018 NXP
*/
#include <fsl-mc/fsl_mc_sys.h>
#include <fsl-mc/fsl_mc_cmd.h>
#include <fsl-mc/fsl_dpsparser.h>
int dpsparser_open(struct fsl_mc_io *mc_io,
u32 cmd_flags,
u16 *token)
{
struct mc_command cmd = { 0 };
int err;
/* prepare command */
cmd.header = mc_encode_cmd_header(DPSPARSER_CMDID_OPEN,
cmd_flags,
0);
/* send command to mc*/
err = mc_send_command(mc_io, &cmd);
if (err)
return err;
/* retrieve response parameters */
*token = MC_CMD_HDR_READ_TOKEN(cmd.header);
return err;
}
int dpsparser_close(struct fsl_mc_io *mc_io,
u32 cmd_flags,
u16 token)
{
struct mc_command cmd = { 0 };
/* prepare command */
cmd.header = mc_encode_cmd_header(DPSPARSER_CMDID_CLOSE, cmd_flags,
token);
/* send command to mc*/
return mc_send_command(mc_io, &cmd);
}
int dpsparser_create(struct fsl_mc_io *mc_io,
u16 token,
u32 cmd_flags,
u32 *obj_id)
{
struct mc_command cmd = { 0 };
int err;
/* prepare command */
cmd.header = mc_encode_cmd_header(DPSPARSER_CMDID_CREATE,
cmd_flags,
token);
/* send command to mc*/
err = mc_send_command(mc_io, &cmd);
if (err)
return err;
/* retrieve response parameters */
MC_CMD_READ_OBJ_ID(cmd, *obj_id);
return 0;
}
int dpsparser_destroy(struct fsl_mc_io *mc_io,
u16 token,
u32 cmd_flags,
u32 obj_id)
{
struct mc_command cmd = { 0 };
/* prepare command */
cmd.header = mc_encode_cmd_header(DPSPARSER_CMDID_DESTROY,
cmd_flags,
token);
/* set object id to destroy */
CMD_DESTROY_SET_OBJ_ID_PARAM0(cmd, obj_id);
/* send command to mc*/
return mc_send_command(mc_io, &cmd);
}
int dpsparser_apply_spb(struct fsl_mc_io *mc_io,
u32 cmd_flags,
u16 token,
u64 blob_addr,
u16 *error)
{
struct mc_command cmd = { 0 };
int err;
/* prepare command */
cmd.header = mc_encode_cmd_header(DPSPARSER_CMDID_APPLY_SPB,
cmd_flags,
token);
DPSPARSER_CMD_BLOB_SET_ADDR(cmd, blob_addr);
/* send command to mc*/
err = mc_send_command(mc_io, &cmd);
if (err)
return err;
/* retrieve response parameters: MC error code */
DPSPARSER_CMD_BLOB_REPORT_ERROR(cmd, *error);
return 0;
}
int dpsparser_get_api_version(struct fsl_mc_io *mc_io,
u32 cmd_flags,
u16 *major_ver,
u16 *minor_ver)
{
struct mc_command cmd = { 0 };
int err;
/* prepare command */
cmd.header = mc_encode_cmd_header(DPSPARSER_CMDID_GET_API_VERSION,
cmd_flags, 0);
/* send command to mc */
err = mc_send_command(mc_io, &cmd);
if (err)
return err;
/* retrieve response parameters */
mc_cmd_read_api_version(&cmd, major_ver, minor_ver);
return 0;
}
// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright 2014 Freescale Semiconductor, Inc.
* Copyright 2017 NXP
* Copyright 2017-2018 NXP
*/
#include <common.h>
......@@ -21,6 +20,7 @@
#include <fsl-mc/fsl_dprc.h>
#include <fsl-mc/fsl_dpio.h>
#include <fsl-mc/fsl_dpni.h>
#include <fsl-mc/fsl_dpsparser.h>
#include <fsl-mc/fsl_qbman_portal.h>
#include <fsl-mc/ldpaa_wriop.h>
......@@ -35,6 +35,7 @@
DECLARE_GLOBAL_DATA_PTR;
static int mc_memset_resv_ram;
static struct mc_version mc_ver_info;
static int mc_boot_status = -1;
static int mc_dpl_applied = -1;
#ifdef CONFIG_SYS_LS_MC_DRAM_AIOP_IMG_OFFSET
......@@ -49,6 +50,9 @@ struct fsl_dpbp_obj *dflt_dpbp = NULL;
struct fsl_dpio_obj *dflt_dpio = NULL;
struct fsl_dpni_obj *dflt_dpni = NULL;
static u64 mc_lazy_dpl_addr;
static u32 dpsparser_obj_id;
static u16 dpsparser_handle;
static char *mc_err_msg_apply_spb[] = MC_ERROR_MSG_APPLY_SPB;
#ifdef DEBUG
void dump_ram_words(const char *title, void *addr)
......@@ -92,7 +96,6 @@ void dump_mc_ccsr_regs(struct mc_ccsr_registers __iomem *mc_ccsr_regs)
#endif /* DEBUG */
#ifndef CONFIG_SYS_LS_MC_FW_IN_DDR
/**
* Copying MC firmware or DPL image to DDR
*/
......@@ -105,6 +108,7 @@ static int mc_copy_image(const char *title,
return 0;
}
#ifndef CONFIG_SYS_LS_MC_FW_IN_DDR
/**
* MC firmware FIT image parser checks if the image is in FIT
* format, verifies integrity of the image and calculates
......@@ -691,7 +695,6 @@ int mc_init(u64 mc_fw_addr, u64 mc_dpc_addr)
const void *raw_image_addr;
size_t raw_image_size = 0;
#endif
struct mc_version mc_ver_info;
u8 mc_ram_num_256mb_blocks;
size_t mc_ram_size = mc_get_dram_block_size();
......@@ -1447,6 +1450,170 @@ err:
return err;
}
static bool is_dpsparser_supported(void)
{
/* dpsparser support was first introduced in MC version: 10.12.0 */
if (mc_ver_info.major < 10)
return false;
if (mc_ver_info.major == 10)
return (mc_ver_info.minor >= 12);
return true;
}
static int dpsparser_version_check(struct fsl_mc_io *mc_io)
{
int error;
u16 major_ver, minor_ver;
if (!is_dpsparser_supported())
return 0;
error = dpsparser_get_api_version(mc_io, 0,
&major_ver,
&minor_ver);
if (error < 0) {
printf("dpsparser_get_api_version() failed: %d\n", error);
return error;
}
if (major_ver < DPSPARSER_VER_MAJOR || (major_ver ==
DPSPARSER_VER_MAJOR && minor_ver < DPSPARSER_VER_MINOR)) {
printf("DPSPARSER version mismatch found %u.%u,",
major_ver, minor_ver);
printf("supported version is %u.%u\n",
DPSPARSER_VER_MAJOR, DPSPARSER_VER_MINOR);
}
return error;
}
static int dpsparser_init(void)
{
int err = 0;
if (!is_dpsparser_supported())
return 0;
err = dpsparser_create(dflt_mc_io,
dflt_dprc_handle,
MC_CMD_NO_FLAGS,
&dpsparser_obj_id);
if (err)
printf("dpsparser_create() failed\n");
err = dpsparser_version_check(dflt_mc_io);
if (err < 0) {
printf("dpsparser_version_check() failed: %d\n", err);
goto err_version_check;
}
err = dpsparser_open(dflt_mc_io,
MC_CMD_NO_FLAGS,
&dpsparser_handle);
if (err < 0) {
printf("dpsparser_open() failed: %d\n", err);
goto err_open;
}
return err;
err_open:
err_version_check:
dpsparser_destroy(dflt_mc_io,
dflt_dprc_handle,
MC_CMD_NO_FLAGS, dpsparser_obj_id);
return err;
}
#ifdef DPSPARSER_DESTROY
/* TODO: refactoring needed in the future to allow DPSPARSER object destroy
* Workaround: DO NOT destroy DPSPARSER object because it needs to be available
* on Apply DPL
*/
static int dpsparser_exit(void)
{
int err;
if (!is_dpsparser_supported())
return 0;
dpsparser_close(dflt_mc_io, MC_CMD_NO_FLAGS, dpsparser_handle);
if (err < 0) {
printf("dpsparser_close() failed: %d\n", err);
goto err;
}
err = dpsparser_destroy(dflt_mc_io, dflt_dprc_handle,
MC_CMD_NO_FLAGS, dpsparser_obj_id);
if (err < 0) {
printf("dpsparser_destroy() failed: %d\n", err);
goto err;
}
return 0;
err:
return err;
}
#endif
int mc_apply_spb(u64 mc_spb_addr)
{
int err = 0;
u16 error, err_arr_size;
u64 mc_spb_offset;
u32 spb_size;
struct sp_blob_header *sp_blob;
u64 mc_ram_addr = mc_get_dram_addr();
if (!is_dpsparser_supported())
return 0;
if (!mc_spb_addr) {
printf("fsl-mc: Invalid Blob address\n");
return -1;
}
#ifdef CONFIG_MC_DRAM_SPB_OFFSET
mc_spb_offset = CONFIG_MC_DRAM_SPB_OFFSET;
#else
#error "CONFIG_MC_DRAM_SPB_OFFSET not defined"
#endif
// Read blob header and get size of SPB blob
sp_blob = (struct sp_blob_header *)mc_spb_addr;
spb_size = le32_to_cpu(sp_blob->length);
if (spb_size > CONFIG_MC_SPB_MAX_SIZE) {
printf("\nfsl-mc: ERROR: Bad SPB image (too large: %d)\n",
spb_size);
return -EINVAL;
}
mc_copy_image("MC SP Blob", mc_spb_addr, spb_size,
mc_ram_addr + mc_spb_offset);
//Invoke MC command to apply SPB blob
printf("fsl-mc: Applying soft parser blob... ");
err = dpsparser_apply_spb(dflt_mc_io, MC_CMD_NO_FLAGS, dpsparser_handle,
mc_spb_offset, &error);
if (err)
return err;
if (error == 0) {
printf("SUCCESS\n");
} else {
printf("FAILED with error code = %d:\n", error);
err_arr_size = (u16)ARRAY_SIZE(mc_err_msg_apply_spb);
if (error > 0 && error < err_arr_size)
printf(mc_err_msg_apply_spb[error]);
else
printf(MC_ERROR_MSG_SPB_UNKNOWN);
}
return err;
}
static int mc_init_object(void)
{
int err = 0;
......@@ -1475,6 +1642,12 @@ static int mc_init_object(void)
goto err;
}
err = dpsparser_init();
if (err < 0) {
printf("dpsparser_init() failed: %d\n", err);
goto err;
}
return 0;
err:
return err;
......@@ -1608,39 +1781,87 @@ static int do_fsl_mc(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
}
break;
case 'l':
case 'l': {
/* lazyapply */
u64 mc_dpl_addr;
if (argc < 4)
goto usage;
if (get_dpl_apply_status() == 0) {
printf("fsl-mc: DPL already applied\n");
return err;
}
mc_dpl_addr = simple_strtoull(argv[3], NULL, 16);
if (get_mc_boot_status() != 0) {
printf("fsl-mc: Deploying data path layout ..");
printf("ERROR (MC is not booted)\n");
return -ENODEV;
}
/*
* We will do the actual dpaa exit and dpl apply
* later from announce_and_cleanup().
*/
mc_lazy_dpl_addr = mc_dpl_addr;
break;
}
case 'a': {
u64 mc_dpl_addr;
/* apply */
char sub_cmd;
u64 mc_apply_addr;
if (argc < 4)
goto usage;
if (argc < 4)
goto usage;
sub_cmd = argv[2][0];
switch (sub_cmd) {
case 'd':
case 'D':
if (get_dpl_apply_status() == 0) {
printf("fsl-mc: DPL already applied\n");
return err;
}
mc_dpl_addr = simple_strtoull(argv[3], NULL,
16);
if (get_mc_boot_status() != 0) {
printf("fsl-mc: Deploying data path layout ..");
printf("ERROR (MC is not booted)\n");
return -ENODEV;
}
if (argv[1][0] == 'l') {
/*
* We will do the actual dpaa exit and dpl apply
* later from announce_and_cleanup().
*/
mc_lazy_dpl_addr = mc_dpl_addr;
} else {
/* The user wants it applied now */
if (!fsl_mc_ldpaa_exit(NULL))
err = mc_apply_dpl(mc_dpl_addr);
mc_apply_addr = simple_strtoull(argv[3], NULL, 16);
/* The user wants DPL applied now */
if (!fsl_mc_ldpaa_exit(NULL))
err = mc_apply_dpl(mc_apply_addr);
break;
case 's':
if (!is_dpsparser_supported()) {
printf("fsl-mc: apply spb command .. ");
printf("ERROR: requires at least MC 10.12.0\n");
return err;
}
if (get_mc_boot_status() != 0) {
printf("fsl-mc: Deploying Soft Parser Blob...");
printf("ERROR (MC is not booted)\n");
return err;
}
mc_apply_addr = simple_strtoull(argv[3], NULL, 16);
/* Apply spb (Soft Parser Blob) */
err = mc_apply_spb(mc_apply_addr);
break;
default:
printf("Invalid option: %s\n", argv[2]);
goto usage;
}
break;
}
default:
printf("Invalid option: %s\n", argv[1]);
......@@ -1658,6 +1879,7 @@ U_BOOT_CMD(
"start mc [FW_addr] [DPC_addr] - Start Management Complex\n"
"fsl_mc apply DPL [DPL_addr] - Apply DPL file\n"
"fsl_mc lazyapply DPL [DPL_addr] - Apply DPL file on exit\n"
"fsl_mc apply spb [spb_addr] - Apply SPB Soft Parser Blob\n"
"fsl_mc start aiop [FW_addr] - Start AIOP\n"
);
......
......@@ -143,6 +143,30 @@ config PCIE_LAYERSCAPE_GEN4
several PCIe controllers. The PCIe controller can work in RC or
EP mode according to RCW[HOST_AGT_PEX] setting.
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
default "fsl,ls1021a-pcie" if ARCH_LS1021A
help
This compatible is used to find pci controller node in Kernel DT
to complete fixup.
config FSL_PCIE_EP_COMPAT
string "PCIe EP compatible of Kernel DT"
depends on PCIE_LAYERSCAPE || PCIE_LAYERSCAPE_GEN4
default "fsl,lx2160a-pcie-ep" if ARCH_LX2160A
default "fsl,ls-pcie-ep"
help
This compatible is used to find pci controller ep node in Kernel DT
to complete fixup.
config PCIE_INTEL_FPGA
bool "Intel FPGA PCIe support"
depends on DM_PCI
......
......@@ -36,7 +36,7 @@ obj-$(CONFIG_PCIE_FSL) += pcie_fsl.o pcie_fsl_fixup.o
obj-$(CONFIG_PCIE_LAYERSCAPE) += pcie_layerscape.o
obj-$(CONFIG_PCIE_LAYERSCAPE) += pcie_layerscape_fixup.o
obj-$(CONFIG_PCIE_LAYERSCAPE_GEN4) += pcie_layerscape_gen4.o \
pcie_layerscape_gen4_fixup.o
pcie_layerscape_gen4_fixup.o pcie_layerscape.o
obj-$(CONFIG_PCI_XILINX) += pcie_xilinx.o
obj-$(CONFIG_PCI_PHYTIUM) += pcie_phytium.o
obj-$(CONFIG_PCIE_INTEL_FPGA) += pcie_intel_fpga.o
......
// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright 2017 NXP
* Copyright 2017-2019 NXP
* Copyright 2014-2015 Freescale Semiconductor, Inc.
* Layerscape PCIe driver
*/
......@@ -339,6 +339,7 @@ static void ls_pcie_setup_ctrl(struct ls_pcie *pcie)
dbi_writel(pcie, 0, PCIE_DBI_RO_WR_EN);
ls_pcie_disable_bars(pcie);
pcie->stream_id_cur = 0;
}
static void ls_pcie_ep_setup_atu(struct ls_pcie *pcie)
......
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* Copyright 2017 NXP
* Copyright 2017-2019 NXP
* Copyright 2014-2015 Freescale Semiconductor, Inc.
* Layerscape PCIe driver
*/
......@@ -144,6 +144,7 @@ struct ls_pcie {
bool big_endian;
bool enabled;
int next_lut_index;
int stream_id_cur;
int mode;
};
......
// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright 2017 NXP
* Copyright 2017-2019 NXP
* Copyright 2014-2015 Freescale Semiconductor, Inc.
* Layerscape PCIe driver
*/
......@@ -69,8 +69,8 @@ static void ls_pcie_lut_set_mapping(struct ls_pcie *pcie, int index, u32 devid,
* msi-map = <[devid] [phandle-to-msi-ctrl] [stream-id] [count]
* [devid] [phandle-to-msi-ctrl] [stream-id] [count]>;
*/
static void fdt_pcie_set_msi_map_entry(void *blob, struct ls_pcie *pcie,
u32 devid, u32 streamid)
static void fdt_pcie_set_msi_map_entry_ls(void *blob, struct ls_pcie *pcie,
u32 devid, u32 streamid)
{
u32 *prop;
u32 phandle;
......@@ -122,8 +122,8 @@ static void fdt_pcie_set_msi_map_entry(void *blob, struct ls_pcie *pcie,
* iommu-map = <[devid] [phandle-to-iommu-ctrl] [stream-id] [count]
* [devid] [phandle-to-iommu-ctrl] [stream-id] [count]>;
*/
static void fdt_pcie_set_iommu_map_entry(void *blob, struct ls_pcie *pcie,
u32 devid, u32 streamid)
static void fdt_pcie_set_iommu_map_entry_ls(void *blob, struct ls_pcie *pcie,
u32 devid, u32 streamid)
{
u32 *prop;
u32 iommu_map[4];
......@@ -175,7 +175,7 @@ static void fdt_pcie_set_iommu_map_entry(void *blob, struct ls_pcie *pcie,
}
}
static void fdt_fixup_pcie(void *blob)
static void fdt_fixup_pcie_ls(void *blob)
{
struct udevice *dev, *bus;
struct ls_pcie *pcie;
......@@ -209,11 +209,11 @@ static void fdt_fixup_pcie(void *blob)
ls_pcie_lut_set_mapping(pcie, index, bdf >> 8,
streamid);
/* update msi-map in device tree */
fdt_pcie_set_msi_map_entry(blob, pcie, bdf >> 8,
streamid);
fdt_pcie_set_msi_map_entry_ls(blob, pcie, bdf >> 8,
streamid);
/* update iommu-map in device tree */
fdt_pcie_set_iommu_map_entry(blob, pcie, bdf >> 8,
streamid);
fdt_pcie_set_iommu_map_entry_ls(blob, pcie, bdf >> 8,
streamid);
}
}
#endif
......@@ -253,7 +253,7 @@ static void ft_pcie_ep_fix(void *blob, struct ls_pcie *pcie)
{
int off;
off = fdt_node_offset_by_compat_reg(blob, "fsl,ls-pcie-ep",
off = fdt_node_offset_by_compat_reg(blob, CONFIG_FSL_PCIE_EP_COMPAT,
pcie->dbi_res.start);
if (off < 0)
return;
......@@ -279,7 +279,7 @@ void ft_pci_setup(void *blob, bd_t *bd)
ft_pcie_ls_setup(blob, pcie);
#if defined(CONFIG_FSL_LSCH3) || defined(CONFIG_FSL_LSCH2)
fdt_fixup_pcie(blob);
fdt_fixup_pcie_ls(blob);
#endif
}
......
......@@ -37,7 +37,7 @@ static int ls_pcie_g4_next_streamid(struct ls_pcie_g4 *pcie)
{
int stream_id = pcie->stream_id_cur;
if (stream_id > FSL_PEX_STREAM_ID_NUM)
if (stream_id > FSL_PEX_STREAM_ID_END)
return -EINVAL;
pcie->stream_id_cur++;
......@@ -64,8 +64,9 @@ static void ls_pcie_g4_lut_set_mapping(struct ls_pcie_g4 *pcie, int index,
* msi-map = <[devid] [phandle-to-msi-ctrl] [stream-id] [count]
* [devid] [phandle-to-msi-ctrl] [stream-id] [count]>;
*/
static void fdt_pcie_set_msi_map_entry(void *blob, struct ls_pcie_g4 *pcie,
u32 devid, u32 streamid)
static void fdt_pcie_set_msi_map_entry_ls_gen4(void *blob,
struct ls_pcie_g4 *pcie,
u32 devid, u32 streamid)
{
u32 *prop;
u32 phandle;
......@@ -106,8 +107,9 @@ static void fdt_pcie_set_msi_map_entry(void *blob, struct ls_pcie_g4 *pcie,
* iommu-map = <[devid] [phandle-to-iommu-ctrl] [stream-id] [count]
* [devid] [phandle-to-iommu-ctrl] [stream-id] [count]>;
*/
static void fdt_pcie_set_iommu_map_entry(void *blob, struct ls_pcie_g4 *pcie,
u32 devid, u32 streamid)
static void fdt_pcie_set_iommu_map_entry_ls_gen4(void *blob,
struct ls_pcie_g4 *pcie,
u32 devid, u32 streamid)
{
u32 *prop;
u32 iommu_map[4];
......@@ -145,7 +147,7 @@ static void fdt_pcie_set_iommu_map_entry(void *blob, struct ls_pcie_g4 *pcie,
fdt_appendprop(blob, nodeoff, "iommu-map", iommu_map, 16);
}
static void fdt_fixup_pcie(void *blob)
static void fdt_fixup_pcie_ls_gen4(void *blob)
{
struct udevice *dev, *bus;
struct ls_pcie_g4 *pcie;
......@@ -176,9 +178,11 @@ static void fdt_fixup_pcie(void *blob)
/* map PCI b.d.f to streamID in LUT */
ls_pcie_g4_lut_set_mapping(pcie, index, bdf >> 8, streamid);
/* update msi-map in device tree */
fdt_pcie_set_msi_map_entry(blob, pcie, bdf >> 8, streamid);
fdt_pcie_set_msi_map_entry_ls_gen4(blob, pcie, bdf >> 8,
streamid);
/* update iommu-map in device tree */
fdt_pcie_set_iommu_map_entry(blob, pcie, bdf >> 8, streamid);
fdt_pcie_set_iommu_map_entry_ls_gen4(blob, pcie, bdf >> 8,
streamid);
}
}
#endif
......@@ -187,7 +191,7 @@ static void ft_pcie_ep_layerscape_gen4_fix(void *blob, struct ls_pcie_g4 *pcie)
{
int off;
off = fdt_node_offset_by_compat_reg(blob, "fsl,lx2160a-pcie-ep",
off = fdt_node_offset_by_compat_reg(blob, CONFIG_FSL_PCIE_EP_COMPAT,
pcie->ccsr_res.start);
if (off < 0) {
......@@ -238,7 +242,7 @@ void ft_pci_setup(void *blob, bd_t *bd)
ft_pcie_layerscape_gen4_setup(blob, pcie);
#if defined(CONFIG_FSL_LSCH3) || defined(CONFIG_FSL_LSCH2)
fdt_fixup_pcie(blob);
fdt_fixup_pcie_ls_gen4(blob);
#endif
}
......
......@@ -210,6 +210,9 @@
#define CONFIG_SYS_EEPROM_PAGE_WRITE_BITS 3
#define CONFIG_SYS_EEPROM_PAGE_WRITE_DELAY_MS 5
/* DisplayPort */
#define DP_PWD_EN_DEFAULT_MASK 0x8
#ifdef CONFIG_NXP_ESBC
#include <asm/fsl_secure_boot.h>
#endif
......
......@@ -305,8 +305,8 @@
"mmcinfo;mmc read 0x80000000 0x5000 0x800;" \
"mmc read 0x80100000 0x7000 0x800;" \
"env exists secureboot && " \
"mmc read 0x80700000 0x3800 0x10 && " \
"mmc read 0x80740000 0x3A00 0x10 && " \
"mmc read 0x80700000 0x3800 0x20 && " \
"mmc read 0x80740000 0x3A00 0x20 && " \
"esbc_validate 0x80700000 && " \
"esbc_validate 0x80740000 ;" \
"fsl_mc start mc 0x80000000 0x80100000\0"
......@@ -327,8 +327,8 @@
"mcinitcmd=mmcinfo;mmc read 0x80000000 0x5000 0x800;" \
"mmc read 0x80100000 0x7000 0x800;" \
"env exists secureboot && " \
"mmc read 0x80700000 0x3800 0x10 && " \
"mmc read 0x80740000 0x3A00 0x10 && " \
"mmc read 0x80700000 0x3800 0x20 && " \
"mmc read 0x80740000 0x3A00 0x20 && " \
"esbc_validate 0x80700000 && " \
"esbc_validate 0x80740000 ;" \
"fsl_mc start mc 0x80000000 0x80100000\0" \
......@@ -362,7 +362,7 @@
"load_addr=0xa0000000\0" \
"kernel_size=0x2800000\0" \
"kernel_size_sd=0x14000\0" \
"kernelhdr_size_sd=0x10\0" \
"kernelhdr_size_sd=0x20\0" \
QSPI_MC_INIT_CMD \
"mcmemsize=0x70000000\0" \
BOOTENV \
......@@ -431,7 +431,7 @@
"load_addr=0xa0000000\0" \
"kernel_size=0x2800000\0" \
"kernel_size_sd=0x14000\0" \
"kernelhdr_size_sd=0x10\0" \
"kernelhdr_size_sd=0x20\0" \
MC_INIT_CMD \
BOOTENV \
"boot_scripts=ls1088ardb_boot.scr\0" \
......@@ -478,7 +478,7 @@
#undef CONFIG_BOOTCOMMAND
#ifdef CONFIG_TFABOOT
#define QSPI_NOR_BOOTCOMMAND \
"sf read 0x80001000 0xd00000 0x100000;" \
"sf read 0x80001000 0xd00000 0x100000;" \
"env exists mcinitcmd && env exists secureboot " \
" && sf read 0x80780000 0x780000 0x100000 " \
"&& esbc_validate 0x80780000;env exists mcinitcmd " \
......@@ -489,7 +489,7 @@
"env exists mcinitcmd && mmcinfo; " \
"mmc read 0x80001000 0x6800 0x800; " \
"env exists mcinitcmd && env exists secureboot " \
" && mmc read 0x80780000 0x3C00 0x10 " \
" && mmc read 0x80780000 0x3C00 0x20 " \
"&& esbc_validate 0x80780000;env exists mcinitcmd " \
"&& fsl_mc lazyapply dpl 0x80001000;" \
"run distro_bootcmd;run sd_bootcmd;" \
......@@ -512,7 +512,7 @@
"env exists mcinitcmd && mmcinfo; " \
"mmc read 0x80001000 0x6800 0x800; " \
"env exists mcinitcmd && env exists secureboot " \
" && mmc read 0x80780000 0x3C00 0x10 " \
" && mmc read 0x80780000 0x3C00 0x20 " \
"&& esbc_validate 0x80780000;env exists mcinitcmd " \
"&& fsl_mc lazyapply dpl 0x80001000;" \
"run distro_bootcmd;run sd_bootcmd;" \
......
......@@ -330,8 +330,8 @@ unsigned long get_board_sys_clk(void);
"mmcinfo;mmc read 0x80a00000 0x5000 0x1200;" \
"mmc read 0x80e00000 0x7000 0x800;" \
"env exists secureboot && " \
"mmc read 0x80700000 0x3800 0x10 && " \
"mmc read 0x80740000 0x3A00 0x10 && " \
"mmc read 0x80700000 0x3800 0x20 && " \
"mmc read 0x80740000 0x3A00 0x20 && " \
"esbc_validate 0x80700000 && " \
"esbc_validate 0x80740000 ;" \
"fsl_mc start mc 0x80a00000 0x80e00000\0"
......@@ -352,8 +352,8 @@ unsigned long get_board_sys_clk(void);
"mcinitcmd=mmcinfo;mmc read 0x80000000 0x5000 0x800;" \
"mmc read 0x80100000 0x7000 0x800;" \
"env exists secureboot && " \
"mmc read 0x80700000 0x3800 0x10 && " \
"mmc read 0x80740000 0x3A00 0x10 && " \
"mmc read 0x80700000 0x3800 0x20 && " \
"mmc read 0x80740000 0x3A00 0x20 && " \
"esbc_validate 0x80700000 && " \
"esbc_validate 0x80740000 ;" \
"fsl_mc start mc 0x80000000 0x80100000\0" \
......
......@@ -197,8 +197,8 @@ unsigned long get_board_ddr_clk(void);
"mmc read 0x80a00000 0x5000 0x1200;" \
"mmc read 0x80e00000 0x7000 0x800;" \
"env exists secureboot && " \
"mmc read 0x80700000 0x3800 0x10 && " \
"mmc read 0x80740000 0x3A00 0x10 && " \
"mmc read 0x80700000 0x3800 0x20 && " \
"mmc read 0x80740000 0x3A00 0x20 && " \
"esbc_validate 0x80700000 && " \
"esbc_validate 0x80740000 ;" \
"fsl_mc start mc 0x80a00000 0x80e00000\0"
......@@ -224,7 +224,7 @@ unsigned long get_board_ddr_clk(void);
"kernel_addr_sd=0x8000\0" \
"kernelhdr_addr_sd=0x3E00\0" \
"kernel_size_sd=0x1d000\0" \
"kernelhdr_size_sd=0x10\0" \
"kernelhdr_size_sd=0x20\0" \
"console=ttyAMA0,38400n8\0" \
BOOTENV \
"mcmemsize=0x70000000\0" \
......@@ -262,7 +262,7 @@ unsigned long get_board_ddr_clk(void);
"env exists mcinitcmd && mmcinfo; " \
"mmc read 0x80d00000 0x6800 0x800; " \
"env exists mcinitcmd && env exists secureboot " \
" && mmc read 0x80780000 0x3C00 0x10 " \
" && mmc read 0x80780000 0x3C00 0x20 " \
"&& esbc_validate 0x80780000;env exists mcinitcmd " \
"&& fsl_mc lazyapply dpl 0x80d00000;" \
"run distro_bootcmd;run sd_bootcmd;" \
......
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* Data Path Soft Parser API
*
* Copyright 2018 NXP
*/
#ifndef _FSL_DPSPARSER_H
#define _FSL_DPSPARSER_H
/* DPSPARSER last supported API version */
#define DPSPARSER_VER_MAJOR 1
#define DPSPARSER_VER_MINOR 0
/* Command IDs */
#define DPSPARSER_CMDID_CLOSE 0x8001
#define DPSPARSER_CMDID_OPEN 0x8111
#define DPSPARSER_CMDID_CREATE 0x9111
#define DPSPARSER_CMDID_DESTROY 0x9911
#define DPSPARSER_CMDID_GET_API_VERSION 0xa111
#define DPSPARSER_CMDID_APPLY_SPB 0x1181
/* cmd, param, offset, width, type, arg_name */
#define DPSPARSER_CMD_BLOB_SET_ADDR(cmd, addr) \
MC_CMD_OP(cmd, 0, 0, 64, u64, addr)
/* cmd, param, offset, width, type, arg_name */
#define DPSPARSER_CMD_BLOB_REPORT_ERROR(cmd, err) \
MC_RSP_OP(cmd, 0, 0, 16, u16, err)
/* Data Path Soft Parser API
* Contains initialization APIs and runtime control APIs for DPSPARSER
*/
struct fsl_mc_io;
/* MC Unknown error: */
#define MC_ERROR_MSG_SPB_UNKNOWN "Unknown MC error\n"
/* MC Error messages (in order for each error code defined above): */
#define MC_ERROR_MSG_APPLY_SPB \
{ \
"OK\n", \
"BLOB : Magic number does not match\n", \
"BLOB : Version does not match MC API version\n", \
"BLOB : IP revision does not match HW revision\n", \
"BLOB : Blob length is not a multiple of 4\n", \
"BLOB : Invalid length detected\n", \
"BLOB : Name length < 0 in 'blob-name'\n", \
"BLOB : Name length not a 4 multiple in 'blob-name'\n", \
"BLOB : No target HW parser selected\n", \
"BLOB : SP size is negative\n", \
"BLOB : Size is zero\n", \
"BLOB : Number of protocols is negative\n", \
"BLOB : Zero protocols\n", \
"BLOB : Protocol name is null\n", \
"BLOB : SP 'seq-start' is not in [0x40, 0xffc0) range\n", \
"BLOB : Invalid base protocol\n", \
"BLOB : Invalid parameters section\n", \
"BLOB : Invalid parameter\n", \
"BLOB : Invalid parameter configuration\n", \
"BLOB : Not aligned value\n", \
"BLOB : Invalid section TAG detected\n", \
"BLOB : Section size is zero\n", \
"BLOB : Section size not a 4 multiple\n", \
"BLOB : Section size is too big\n", \
"BLOB : No 'bytecode' section before\n", \
"BLOB : No 'sp-protocols' section before\n", \
"BLOB : No 'bytecode' section defined\n", \
"BLOB : No 'sp-protocols' section defined\n", \
"BLOB : Soft Parser BLOB parsing : Error detected\n", \
"apply spb : Soft Parser BLOB is already applied\n", \
"apply spb : BLOB address is not set\n", \
"BLOB : SP parameter offset is not a 4 multiple\n", \
"BLOB : SP parameter offset can't be less than 0x40\n", \
"BLOB : Bytecode size is not a 4 multiple\n", \
"BLOB : Bytecode size cannot be zero\n", \
"BLOB : Bytecode can't overwrite the 0xFFE address\n", \
"BLOB : No hardware parser selected as target\n", \
"BLOB : Bytecode overlap detected\n", \
"BLOB : No parser support\n", \
"BLOB : Too many bytecode sections on WRIOP ingress\n", \
"BLOB : Too many bytecode sections on WRIOP egress\n", \
"BLOB : Too many bytecode sections on AIOP\n", \
"BLOB : Duplicated protocol is already registered\n", \
"BLOB : Maximum number of allowed protocols was exceeded\n", \
"BLOB : Protocols limit exceeded\n", \
"BLOB : Protocol is linked twice\n", \
"BLOB : Soft parser is linked twice\n", \
"BLOB : Parameter offset exceeds the maximum parameters limit\n", \
"BLOB : Parameter size can't be 0 or greater than 64\n", \
"BLOB : Parameter offset plus size exceeds the maximum limit\n", \
"BLOB : Parameters number exceeds the maximum limit\n", \
"BLOB : Duplicated parameter name\n", \
"BLOB : Parameters overlapped detected\n", \
"apply spb : No dpsparser handle.\n", \
\
MC_ERROR_MSG_SPB_UNKNOWN, \
NULL, \
}
/**
* dpsparser_open() - Open a control session for the specified object.
* @mc_io: Pointer to MC portal's I/O object
* @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
* @token: Returned token; use in subsequent API calls
*
* This function can be used to open a control session for an
* already created object; an object may have been declared in
* the DPL or by calling the dpsparser_create function.
* This function returns a unique authentication token,
* associated with the specific object ID and the specific MC
* portal; this token must be used in all subsequent commands for
* this specific object
*
* Return: '0' on Success; Error code otherwise.
*/
int dpsparser_open(struct fsl_mc_io *mc_io,
u32 cmd_flags,
u16 *token);
/**
* dpsparser_close() - Close the control session of the object
* @mc_io: Pointer to MC portal's I/O object
* @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
* @token: Token of DPSPARSER object
*
* After this function is called, no further operations are
* allowed on the object without opening a new control session.
*
* Return: '0' on Success; Error code otherwise.
*/
int dpsparser_close(struct fsl_mc_io *mc_io,
u32 cmd_flags,
u16 token);
/**
* dpsparser_create() - Create the DPSPARSER object.
* @mc_io: Pointer to MC portal's I/O object
* @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
* @token: Returned token; use in subsequent API calls
*
* Create the DPSPARSER object, allocate required resources and
* perform required initialization.
*
* The object can be created either by declaring it in the
* DPL file, or by calling this function.
* This function returns a unique authentication token,
* associated with the specific object ID and the specific MC
* portal; this token must be used in all subsequent calls to
* this specific object. For objects that are created using the
* DPL file, call dpsparser_open function to get an authentication
* token first.
*
* Return: '0' on Success; Error code otherwise.
*/
int dpsparser_create(struct fsl_mc_io *mc_io,
u16 token,
u32 cmd_flags,
u32 *obj_id);
/**
* dpsparser_destroy() - Destroy the DPSPARSER object and release all its
* resources.
* @mc_io: Pointer to MC portal's I/O object
* @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
* @token: Token of DPSPARSER object
*
* Return: '0' on Success; error code otherwise.
*/
int dpsparser_destroy(struct fsl_mc_io *mc_io,
u16 token,
u32 cmd_flags,
u32 obj_id);
/**
* dpsparser_apply_spb() - Applies the Soft Parser Blob loaded at specified
* address.
* @mc_io: Pointer to MC portal's I/O object
* @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
* @token: Token of DPSPARSER object
* @blob_addr: Blob loading address
* @error: Error reported by MC related to SP Blob parsing and apply
*
* Return: '0' on Success; error code otherwise.
*/
int dpsparser_apply_spb(struct fsl_mc_io *mc_io,
u32 cmd_flags,
u16 token,
u64 blob_addr,
u16 *error);
/**
* dpsparser_get_api_version - Retrieve DPSPARSER Major and Minor version info.
*
* @mc_io: Pointer to MC portal's I/O object
* @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
* @major_ver: DPSPARSER major version
* @minor_ver: DPSPARSER minor version
*
* Return: '0' on Success; Error code otherwise.
*/
int dpsparser_get_api_version(struct fsl_mc_io *mc_io,
u32 cmd_flags,
u16 *major_ver,
u16 *minor_ver);
#endif /* _FSL_DPSPARSER_H */
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* Copyright 2014-2016 Freescale Semiconductor, Inc.
* Copyright 2017 NXP
* Copyright 2017-2018 NXP
*/
#ifndef _FSL_MC_PRIVATE_H_
......@@ -65,7 +65,22 @@ struct fsl_dpni_obj {
extern struct fsl_dpni_obj *dflt_dpni;
/**
* struct sp_blob_header - SP Blob header structure
* @magic: SP Blob magic number
* @blob_ver: SP Blob version
* @ip_rev: SP IP revision
* @length: Length of the SP Blob
*/
struct sp_blob_header {
u32 magic;
u32 blob_ver;
u32 ip_rev;
u32 length;
};
int mc_init(u64 mc_fw_addr, u64 mc_dpc_addr);
int ldpaa_eth_init(int dpmac_id, phy_interface_t enet_if);
int mc_apply_dpl(u64 mc_dpl_addr);
int mc_apply_spb(u64 mc_spb_addr);
#endif /* _FSL_MC_PRIVATE_H_ */
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册