powerpc/85xx: Add C29x SoC support

The Freescale C29x family is a high performance crypto co-processor.
It combines a single e500v2 core with necessary SEC engine. There're
three SoC types(C291, C292, C293) with the following features:

 - 512K L2 Cache/SRAM and 512 KB platform SRAM
 - DDR3/DDR3L 32bit DDR controller
 - One PCI express (x1, x2, x4) Gen 2.0 Controller
 - Trust Architecture 2.0
 - SEC6.0 engine

Signed-off-by: Mingkai Hu <Mingkai.Hu@freescale.com>
Signed-off-by: Po Liu <Po.Liu@freescale.com>
diff --git a/arch/powerpc/cpu/mpc85xx/Makefile b/arch/powerpc/cpu/mpc85xx/Makefile
index 0d1e8f1..f70f0d7 100644
--- a/arch/powerpc/cpu/mpc85xx/Makefile
+++ b/arch/powerpc/cpu/mpc85xx/Makefile
@@ -46,6 +46,7 @@
 COBJS-$(CONFIG_MPC8544) += ddr-gen2.o
 
 # supports ddr1/2/3
+COBJS-$(CONFIG_PPC_C29X)	+= ddr-gen3.o
 COBJS-$(CONFIG_MPC8572) += ddr-gen3.o
 COBJS-$(CONFIG_MPC8536) += ddr-gen3.o
 COBJS-$(CONFIG_MPC8569)	+= ddr-gen3.o
@@ -100,6 +101,7 @@
 COBJS-$(CONFIG_SYS_FSL_QORIQ_CHASSIS2) += fsl_corenet2_serdes.o
 
 # SoC specific SERDES support
+COBJS-$(CONFIG_PPC_C29X)	+= c29x_serdes.o
 COBJS-$(CONFIG_MPC8536) += mpc8536_serdes.o
 COBJS-$(CONFIG_MPC8544) += mpc8544_serdes.o
 COBJS-$(CONFIG_MPC8548) += mpc8548_serdes.o
diff --git a/arch/powerpc/cpu/mpc85xx/c29x_serdes.c b/arch/powerpc/cpu/mpc85xx/c29x_serdes.c
new file mode 100644
index 0000000..4b3214d
--- /dev/null
+++ b/arch/powerpc/cpu/mpc85xx/c29x_serdes.c
@@ -0,0 +1,65 @@
+/*
+ * Copyright 2013 Freescale Semiconductor, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ */
+
+#include <config.h>
+#include <common.h>
+#include <asm/io.h>
+#include <asm/immap_85xx.h>
+#include <asm/fsl_serdes.h>
+
+#define SRDS1_MAX_LANES		4
+
+static u32 serdes1_prtcl_map;
+
+struct serdes_config {
+	u32 protocol;
+	u8 lanes[SRDS1_MAX_LANES];
+};
+
+static const struct serdes_config serdes1_cfg_tbl[] = {
+	/* SerDes 1 */
+	{1, {PCIE1, PCIE1, PCIE1, PCIE1} },
+	{2, {PCIE1, PCIE1, PCIE1, PCIE1} },
+	{3, {PCIE1, PCIE1, NONE, NONE} },
+	{4, {PCIE1, PCIE1, NONE, NONE} },
+	{5, {PCIE1, NONE, NONE, NONE} },
+	{6, {PCIE1, NONE, NONE, NONE} },
+	{}
+};
+
+int is_serdes_configured(enum srds_prtcl device)
+{
+	return (1 << device) & serdes1_prtcl_map;
+}
+
+void fsl_serdes_init(void)
+{
+	ccsr_gur_t *gur = (void *)CONFIG_SYS_MPC85xx_GUTS_ADDR;
+	u32 pordevsr = in_be32(&gur->pordevsr);
+	u32 srds_cfg = (pordevsr & MPC85xx_PORDEVSR_IO_SEL) >>
+				MPC85xx_PORDEVSR_IO_SEL_SHIFT;
+	const struct serdes_config *ptr;
+	int lane;
+
+	debug("PORDEVSR[IO_SEL_SRDS] = %x\n", srds_cfg);
+
+	if (srds_cfg > ARRAY_SIZE(serdes1_cfg_tbl)) {
+		printf("Invalid PORDEVSR[IO_SEL_SRDS] = %d\n", srds_cfg);
+		return;
+	}
+
+	ptr = &serdes1_cfg_tbl[srds_cfg];
+	if (!ptr->protocol)
+		return;
+
+	for (lane = 0; lane < SRDS1_MAX_LANES; lane++) {
+		enum srds_prtcl lane_prtcl = ptr->lanes[lane];
+		serdes1_prtcl_map |= (1 << lane_prtcl);
+	}
+}
diff --git a/arch/powerpc/cpu/mpc8xxx/cpu.c b/arch/powerpc/cpu/mpc8xxx/cpu.c
index 7369582..c67be4e 100644
--- a/arch/powerpc/cpu/mpc8xxx/cpu.c
+++ b/arch/powerpc/cpu/mpc8xxx/cpu.c
@@ -79,6 +79,9 @@
 	CPU_TYPE_ENTRY(BSC9131, 9131, 1),
 	CPU_TYPE_ENTRY(BSC9132, 9132, 2),
 	CPU_TYPE_ENTRY(BSC9232, 9232, 2),
+	CPU_TYPE_ENTRY(C291, C291, 1),
+	CPU_TYPE_ENTRY(C292, C292, 1),
+	CPU_TYPE_ENTRY(C293, C293, 1),
 #elif defined(CONFIG_MPC86xx)
 	CPU_TYPE_ENTRY(8610, 8610, 1),
 	CPU_TYPE_ENTRY(8641, 8641, 2),