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),
diff --git a/arch/powerpc/include/asm/config_mpc85xx.h b/arch/powerpc/include/asm/config_mpc85xx.h
index f946389..ce1bf05 100644
--- a/arch/powerpc/include/asm/config_mpc85xx.h
+++ b/arch/powerpc/include/asm/config_mpc85xx.h
@@ -626,6 +626,18 @@
 #define CONFIG_SYS_FSL_USB_INTERNAL_UTMI_PHY
 #define CONFIG_SYS_CCSRBAR_DEFAULT	0xfe000000
 
+#elif defined(CONFIG_PPC_C29X)
+#define CONFIG_MAX_CPUS			1
+#define CONFIG_FSL_SDHC_V2_3
+#define CONFIG_SYS_FSL_NUM_LAWS		12
+#define CONFIG_SYS_PPC_E500_DEBUG_TLB	3
+#define CONFIG_TSECV2_1
+#define CONFIG_SYS_FSL_SEC_COMPAT	6
+#define CONFIG_SYS_FSL_ERRATUM_ESDHC111
+#define CONFIG_NUM_DDR_CONTROLLERS	1
+#define CONFIG_SYS_FSL_IFC_BANK_COUNT	8
+#define CONFIG_SYS_CCSRBAR_DEFAULT	0xff700000
+
 #else
 #error Processor type not defined for this platform
 #endif
diff --git a/arch/powerpc/include/asm/fsl_law.h b/arch/powerpc/include/asm/fsl_law.h
index fa51e59..37d3a22 100644
--- a/arch/powerpc/include/asm/fsl_law.h
+++ b/arch/powerpc/include/asm/fsl_law.h
@@ -92,6 +92,7 @@
 	LAW_TRGT_IF_LBC = 0x04,
 	LAW_TRGT_IF_CCSR = 0x08,
 	LAW_TRGT_IF_DSP_CCSR = 0x09,
+	LAW_TRGT_IF_PLATFORM_SRAM = 0x0a,
 	LAW_TRGT_IF_DDR_INTRLV = 0x0b,
 	LAW_TRGT_IF_RIO = 0x0c,
 #if defined(CONFIG_BSC9132)
diff --git a/arch/powerpc/include/asm/immap_85xx.h b/arch/powerpc/include/asm/immap_85xx.h
index db9f220..2ed384e 100644
--- a/arch/powerpc/include/asm/immap_85xx.h
+++ b/arch/powerpc/include/asm/immap_85xx.h
@@ -2147,6 +2147,11 @@
 #ifdef CONFIG_MPC8536
 #define MPC85xx_PORPLLSR_DDR_RATIO	0x3e000000
 #define MPC85xx_PORPLLSR_DDR_RATIO_SHIFT	25
+#elif defined(CONFIG_PPC_C29X)
+#define MPC85xx_PORPLLSR_DDR_RATIO	0x00003f00
+#define MPC85xx_PORPLLSR_DDR_RATIO_SHIFT	(9 - ((gur->pordevsr2 \
+					& MPC85xx_PORDEVSR2_DDR_SPD_0) \
+					>> MPC85xx_PORDEVSR2_DDR_SPD_0_SHIFT))
 #else
 #if defined(CONFIG_BSC9131) || defined(CONFIG_BSC9132)
 #define MPC85xx_PORPLLSR_DDR_RATIO	0x00003f00
@@ -2194,6 +2199,9 @@
 #elif defined(CONFIG_BSC9132)
 #define MPC85xx_PORDEVSR_IO_SEL		0x00FE0000
 #define MPC85xx_PORDEVSR_IO_SEL_SHIFT	17
+#elif defined(CONFIG_PPC_C29X)
+#define MPC85xx_PORDEVSR_IO_SEL		0x00e00000
+#define MPC85xx_PORDEVSR_IO_SEL_SHIFT	21
 #else
 #define MPC85xx_PORDEVSR_IO_SEL		0x00780000
 #define MPC85xx_PORDEVSR_IO_SEL_SHIFT	19
@@ -2209,6 +2217,10 @@
 #define MPC85xx_PORDEVSR_RIO_DEV_ID	0x00000007
 	u32	pordbgmsr;	/* POR debug mode status */
 	u32	pordevsr2;	/* POR I/O device status 2 */
+#if defined(CONFIG_PPC_C29X)
+#define MPC85xx_PORDEVSR2_DDR_SPD_0	0x00000008
+#define MPC85xx_PORDEVSR2_DDR_SPD_0_SHIFT	3
+#endif
 /* The 8544 RM says this is bit 26, but it's really bit 24 */
 #define MPC85xx_PORDEVSR2_SEC_CFG	0x00000080
 	u8	res1[8];
@@ -2355,6 +2367,11 @@
 #define MPC85xx_PMUXCR0_SIM_SEL_MASK	0x0003b000
 #define MPC85xx_PMUXCR0_SIM_SEL		0x00014000
 #endif
+#if defined(CONFIG_PPC_C29X)
+#define MPC85xx_PMUXCR_SPI_MASK			0x00000300
+#define MPC85xx_PMUXCR_SPI			0x00000000
+#define MPC85xx_PMUXCR_SPI_GPIO			0x00000100
+#endif
 	u32	pmuxcr2;	/* Alt. function signal multiplex control 2 */
 #if defined(CONFIG_P1010) || defined(CONFIG_P1014)
 #define MPC85xx_PMUXCR2_UART_GPIO		0x40000000
@@ -3026,12 +3043,18 @@
 #define CONFIG_SYS_MPC85xx_USB2_OFFSET		0x23000
 #ifdef CONFIG_TSECV2
 #define CONFIG_SYS_TSEC1_OFFSET			0xB0000
+#elif defined(CONFIG_TSECV2_1)
+#define CONFIG_SYS_TSEC1_OFFSET			0x10000
 #else
 #define CONFIG_SYS_TSEC1_OFFSET			0x24000
 #endif
 #define CONFIG_SYS_MDIO1_OFFSET			0x24000
 #define CONFIG_SYS_MPC85xx_ESDHC_OFFSET		0x2e000
+#if defined(CONFIG_PPC_C29X)
+#define CONFIG_SYS_FSL_SEC_OFFSET		0x80000
+#else
 #define CONFIG_SYS_FSL_SEC_OFFSET		0x30000
+#endif
 #define CONFIG_SYS_MPC85xx_SERDES2_OFFSET	0xE3100
 #define CONFIG_SYS_MPC85xx_SERDES1_OFFSET	0xE3000
 #define CONFIG_SYS_SNVS_OFFSET			0xE6000
diff --git a/arch/powerpc/include/asm/processor.h b/arch/powerpc/include/asm/processor.h
index 56b22d8..64a6f9c 100644
--- a/arch/powerpc/include/asm/processor.h
+++ b/arch/powerpc/include/asm/processor.h
@@ -1119,6 +1119,9 @@
 #define SVR_T4240	0x824000
 #define SVR_T4120	0x824001
 #define SVR_T4160	0x824100
+#define SVR_C291	0x850000
+#define SVR_C292	0x850020
+#define SVR_C293	0x850030
 #define SVR_B4860	0X868000
 #define SVR_G4860	0x868001
 #define SVR_G4060	0x868003