armv8/ls1043ardb: Add LS1043ARDB board support

LS1043ARDB Specification:
-------------------------
Memory subsystem:
 * 2GByte DDR4 SDRAM (32bit bus)
 * 128 Mbyte NOR flash single-chip memory
 * 512 Mbyte NAND flash
 * 16 Mbyte high-speed SPI flash
 * SD connector to interface with the SD memory card

Ethernet:
 * XFI 10G port
 * QSGMII with 4x 1G ports
 * Two RGMII ports

PCIe:
 * PCIe2 (Lanes C) to mini-PCIe slot
 * PCIe3 (Lanes D) to PCIe slot

USB 3.0: two super speed USB 3.0 type A ports

UART: supports two UARTs up to 115200 bps for console

Signed-off-by: Hou Zhiqiang <B48286@freescale.com>
Signed-off-by: Li Yang <leoli@freescale.com>
Signed-off-by: Mingkai Hu <Mingkai.Hu@freescale.com>
Signed-off-by: York Sun <yorksun@freescale.com>
Signed-off-by: Gong Qianyu <Qianyu.Gong@freescale.com>
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 2632099..26c87df 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -627,6 +627,12 @@
 	select CPU_V7
 	select SUPPORT_SPL
 
+config TARGET_LS1043ARDB
+	bool "Support ls1043ardb"
+	select ARM64
+	help
+	  Support for Freescale LS1043ARDB platform.
+
 config TARGET_H2200
 	bool "Support h2200"
 	select CPU_PXA
@@ -743,6 +749,7 @@
 source "board/freescale/ls2085ardb/Kconfig"
 source "board/freescale/ls1021aqds/Kconfig"
 source "board/freescale/ls1021atwr/Kconfig"
+source "board/freescale/ls1043ardb/Kconfig"
 source "board/freescale/mx23evk/Kconfig"
 source "board/freescale/mx25pdk/Kconfig"
 source "board/freescale/mx28evk/Kconfig"
diff --git a/arch/arm/cpu/armv8/fsl-layerscape/Makefile b/arch/arm/cpu/armv8/fsl-layerscape/Makefile
index 4754e59..6fa08c8 100644
--- a/arch/arm/cpu/armv8/fsl-layerscape/Makefile
+++ b/arch/arm/cpu/armv8/fsl-layerscape/Makefile
@@ -23,4 +23,8 @@
 
 ifneq ($(CONFIG_LS2085A),)
 obj-$(CONFIG_SYS_HAS_SERDES) += ls2085a_serdes.o
+else
+ifneq ($(CONFIG_LS1043A),)
+obj-$(CONFIG_SYS_HAS_SERDES) += ls1043a_serdes.o
+endif
 endif
diff --git a/arch/arm/cpu/armv8/fsl-layerscape/ls1043a_serdes.c b/arch/arm/cpu/armv8/fsl-layerscape/ls1043a_serdes.c
new file mode 100644
index 0000000..e54d389
--- /dev/null
+++ b/arch/arm/cpu/armv8/fsl-layerscape/ls1043a_serdes.c
@@ -0,0 +1,86 @@
+/*
+ * Copyright 2015 Freescale Semiconductor, Inc.
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#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;
+}