[U-Boot] [PATCH 2/3] mpc85xx: Add support for the MPC8536

Kumar Gala galak at kernel.crashing.org
Tue Aug 12 18:14:54 CEST 2008


The MPC8536 Adds SDHC and SATA controllers to the PQ3 family.  We
also have SERDES init code for the 8536.

Signed-off-by: Kumar Gala <galak at kernel.crashing.org>
Signed-off-by: Srikanth Srinivasan <srikanth.srinivasan at freescale.com>
Signed-off-by: Dejan Minic <minic at freescale.com>
Signed-off-by: Jason Jin <Jason.jin at freescale.com>
Signed-off-by: Dave Liu <daveliu at freescale.com>
---
 cpu/mpc85xx/Makefile          |    1 +
 cpu/mpc85xx/cpu.c             |    8 ++-
 cpu/mpc85xx/cpu_init.c        |    7 ++
 cpu/mpc85xx/mpc8536_serdes.c  |  180 +++++++++++++++++++++++++++++++++++++++++
 cpu/mpc85xx/speed.c           |    4 +
 drivers/misc/fsl_law.c        |    2 +-
 include/asm-ppc/global_data.h |    6 +-
 include/asm-ppc/immap_85xx.h  |   11 +++
 include/asm-ppc/processor.h   |    2 +
 include/pci_ids.h             |    2 +
 10 files changed, 218 insertions(+), 5 deletions(-)
 create mode 100644 cpu/mpc85xx/mpc8536_serdes.c

diff --git a/cpu/mpc85xx/Makefile b/cpu/mpc85xx/Makefile
index d51a6dd..ba1f159 100644
--- a/cpu/mpc85xx/Makefile
+++ b/cpu/mpc85xx/Makefile
@@ -42,6 +42,7 @@ endif
 endif
 endif
 
+COBJS-$(CONFIG_MPC8536) += mpc8536_serdes.o
 COBJS	= traps.o cpu.o cpu_init.o speed.o interrupts.o tlb.o \
 	  pci.o serial_scc.o commproc.o ether_fcc.o qe_io.o \
 	  $(COBJS-y)
diff --git a/cpu/mpc85xx/cpu.c b/cpu/mpc85xx/cpu.c
index 5c2231d..2fe3cea 100644
--- a/cpu/mpc85xx/cpu.c
+++ b/cpu/mpc85xx/cpu.c
@@ -36,6 +36,8 @@ DECLARE_GLOBAL_DATA_PTR;
 struct cpu_type cpu_type_list [] = {
 	CPU_TYPE_ENTRY(8533, 8533),
 	CPU_TYPE_ENTRY(8533, 8533_E),
+	CPU_TYPE_ENTRY(8536, 8536),
+	CPU_TYPE_ENTRY(8536, 8536_E),
 	CPU_TYPE_ENTRY(8540, 8540),
 	CPU_TYPE_ENTRY(8541, 8541),
 	CPU_TYPE_ENTRY(8541, 8541_E),
@@ -89,6 +91,9 @@ int checkcpu (void)
 	svr = get_svr();
 	ver = SVR_SOC_VER(svr);
 	major = SVR_MAJ(svr);
+#ifdef CONFIG_MPC8536
+	major &= 0x7; /* the msb of this nibble is a mfg code */
+#endif
 	minor = SVR_MIN(svr);
 
 	puts("CPU:   ");
@@ -154,7 +159,8 @@ int checkcpu (void)
 #endif
 	clkdiv = lcrr & 0x0f;
 	if (clkdiv == 2 || clkdiv == 4 || clkdiv == 8) {
-#if defined(CONFIG_MPC8548) || defined(CONFIG_MPC8544) || defined(CONFIG_MPC8572)
+#if defined(CONFIG_MPC8548) || defined(CONFIG_MPC8544) || \
+    defined(CONFIG_MPC8572) || defined(CONFIG_MPC8536)
 		/*
 		 * Yes, the entire PQ38 family use the same
 		 * bit-representation for twice the clock divider values.
diff --git a/cpu/mpc85xx/cpu_init.c b/cpu/mpc85xx/cpu_init.c
index 4feb751..783c5ba 100644
--- a/cpu/mpc85xx/cpu_init.c
+++ b/cpu/mpc85xx/cpu_init.c
@@ -37,6 +37,10 @@
 
 DECLARE_GLOBAL_DATA_PTR;
 
+#ifdef CONFIG_MPC8536
+extern void fsl_serdes_init(void);
+#endif
+
 #ifdef CONFIG_QE
 extern qe_iop_conf_t qe_iop_conf_tab[];
 extern void qe_config_iopin(u8 port, u8 pin, int dir,
@@ -240,6 +244,9 @@ void cpu_init_f (void)
 	/* Config QE ioports */
 	config_qe_ioports();
 #endif
+#if defined(CONFIG_MPC8536)
+	fsl_serdes_init();
+#endif
 
 }
 
diff --git a/cpu/mpc85xx/mpc8536_serdes.c b/cpu/mpc85xx/mpc8536_serdes.c
new file mode 100644
index 0000000..ae091e6
--- /dev/null
+++ b/cpu/mpc85xx/mpc8536_serdes.c
@@ -0,0 +1,180 @@
+/*
+ * Copyright (C) 2008 Freescale Semicondutor, Inc. All rights reserved.
+ *	Dave Liu <daveliu at freescale.com>
+ *
+ * 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>
+
+/* PORDEVSR register */
+#define GUTS_PORDEVSR_OFFS		0xc
+#define GUTS_PORDEVSR_SERDES2_IO_SEL	0x38000000
+#define GUTS_PORDEVSR_SERDES2_IO_SEL_SHIFT	27
+
+/* SerDes CR0 register */
+#define	FSL_SRDSCR0_OFFS	0x0
+#define FSL_SRDSCR0_TXEQA_MASK	0x00007000
+#define FSL_SRDSCR0_TXEQA_SGMII	0x00004000
+#define FSL_SRDSCR0_TXEQA_SATA	0x00001000
+#define FSL_SRDSCR0_TXEQE_MASK	0x00000700
+#define FSL_SRDSCR0_TXEQE_SGMII	0x00000400
+#define FSL_SRDSCR0_TXEQE_SATA	0x00000100
+
+/* SerDes CR1 register */
+#define FSL_SRDSCR1_OFFS	0x4
+#define FSL_SRDSCR1_LANEA_MASK	0x80200000
+#define FSL_SRDSCR1_LANEA_OFF	0x80200000
+#define FSL_SRDSCR1_LANEE_MASK	0x08020000
+#define FSL_SRDSCR1_LANEE_OFF	0x08020000
+
+/* SerDes CR2 register */
+#define FSL_SRDSCR2_OFFS	0x8
+#define FSL_SRDSCR2_EICA_MASK	0x00001f00
+#define FSL_SRDSCR2_EICA_SGMII	0x00000400
+#define FSL_SRDSCR2_EICA_SATA	0x00001400
+#define FSL_SRDSCR2_EICE_MASK	0x0000001f
+#define FSL_SRDSCR2_EICE_SGMII	0x00000004
+#define FSL_SRDSCR2_EICE_SATA	0x00000014
+
+/* SerDes CR3 register */
+#define FSL_SRDSCR3_OFFS	0xc
+#define FSL_SRDSCR3_LANEA_MASK	0x3f000700
+#define FSL_SRDSCR3_LANEA_SGMII	0x00000000
+#define FSL_SRDSCR3_LANEA_SATA	0x15000500
+#define FSL_SRDSCR3_LANEE_MASK	0x003f0007
+#define FSL_SRDSCR3_LANEE_SGMII	0x00000000
+#define FSL_SRDSCR3_LANEE_SATA	0x00150005
+
+void fsl_serdes_init(void)
+{
+	void *guts = (void *)(CFG_MPC85xx_GUTS_ADDR);
+	void *sd = (void *)CFG_MPC85xx_SERDES2_ADDR;
+	u32 pordevsr = in_be32(guts + GUTS_PORDEVSR_OFFS);
+	u32 srds2_io_sel;
+	u32 tmp;
+
+	/* parse the SRDS2_IO_SEL of PORDEVSR */
+	srds2_io_sel = (pordevsr & GUTS_PORDEVSR_SERDES2_IO_SEL)
+		       >> GUTS_PORDEVSR_SERDES2_IO_SEL_SHIFT;
+
+	switch (srds2_io_sel) {
+	case 1:	/* Lane A - SATA1, Lane E - SATA2 */
+		/* CR 0 */
+		tmp = in_be32(sd + FSL_SRDSCR0_OFFS);
+		tmp &= ~FSL_SRDSCR0_TXEQA_MASK;
+		tmp |= FSL_SRDSCR0_TXEQA_SATA;
+		tmp &= ~FSL_SRDSCR0_TXEQE_MASK;
+		tmp |= FSL_SRDSCR0_TXEQE_SATA;
+		out_be32(sd + FSL_SRDSCR0_OFFS, tmp);
+		/* CR 1 */
+		tmp = in_be32(sd + FSL_SRDSCR1_OFFS);
+		tmp &= ~FSL_SRDSCR1_LANEA_MASK;
+		tmp &= ~FSL_SRDSCR1_LANEE_MASK;
+		out_be32(sd + FSL_SRDSCR1_OFFS, tmp);
+		/* CR 2 */
+		tmp = in_be32(sd + FSL_SRDSCR2_OFFS);
+		tmp &= ~FSL_SRDSCR2_EICA_MASK;
+		tmp |= FSL_SRDSCR2_EICA_SATA;
+		tmp &= ~FSL_SRDSCR2_EICE_MASK;
+		tmp |= FSL_SRDSCR2_EICE_SATA;
+		out_be32(sd + FSL_SRDSCR2_OFFS, tmp);
+		/* CR 3 */
+		tmp = in_be32(sd + FSL_SRDSCR3_OFFS);
+		tmp &= ~FSL_SRDSCR3_LANEA_MASK;
+		tmp |= FSL_SRDSCR3_LANEA_SATA;
+		tmp &= ~FSL_SRDSCR3_LANEE_MASK;
+		tmp |= FSL_SRDSCR3_LANEE_SATA;
+		out_be32(sd + FSL_SRDSCR3_OFFS, tmp);
+		break;
+	case 3: /* Lane A - SATA1, Lane E - disabled */
+		/* CR 0 */
+		tmp = in_be32(sd + FSL_SRDSCR0_OFFS);
+		tmp &= ~FSL_SRDSCR0_TXEQA_MASK;
+		tmp |= FSL_SRDSCR0_TXEQA_SATA;
+		out_be32(sd + FSL_SRDSCR0_OFFS, tmp);
+		/* CR 1 */
+		tmp = in_be32(sd + FSL_SRDSCR1_OFFS);
+		tmp &= ~FSL_SRDSCR1_LANEE_MASK;
+		tmp |= FSL_SRDSCR1_LANEE_OFF;
+		out_be32(sd + FSL_SRDSCR1_OFFS, tmp);
+		/* CR 2 */
+		tmp = in_be32(sd + FSL_SRDSCR2_OFFS);
+		tmp &= ~FSL_SRDSCR2_EICA_MASK;
+		tmp |= FSL_SRDSCR2_EICA_SATA;
+		out_be32(sd + FSL_SRDSCR2_OFFS, tmp);
+		/* CR 3 */
+		tmp = in_be32(sd + FSL_SRDSCR3_OFFS);
+		tmp &= ~FSL_SRDSCR3_LANEA_MASK;
+		tmp |= FSL_SRDSCR3_LANEA_SATA;
+		out_be32(sd + FSL_SRDSCR3_OFFS, tmp);
+		break;
+	case 4: /* Lane A - eTSEC1 SGMII, Lane E - eTSEC3 SGMII */
+		/* CR 0 */
+		tmp = in_be32(sd + FSL_SRDSCR0_OFFS);
+		tmp &= ~FSL_SRDSCR0_TXEQA_MASK;
+		tmp |= FSL_SRDSCR0_TXEQA_SGMII;
+		tmp &= ~FSL_SRDSCR0_TXEQE_MASK;
+		tmp |= FSL_SRDSCR0_TXEQE_SGMII;
+		out_be32(sd + FSL_SRDSCR0_OFFS, tmp);
+		/* CR 1 */
+		tmp = in_be32(sd + FSL_SRDSCR1_OFFS);
+		tmp &= ~FSL_SRDSCR1_LANEA_MASK;
+		tmp &= ~FSL_SRDSCR1_LANEE_MASK;
+		out_be32(sd + FSL_SRDSCR1_OFFS, tmp);
+		/* CR 2 */
+		tmp = in_be32(sd + FSL_SRDSCR2_OFFS);
+		tmp &= ~FSL_SRDSCR2_EICA_MASK;
+		tmp |= FSL_SRDSCR2_EICA_SGMII;
+		tmp &= ~FSL_SRDSCR2_EICE_MASK;
+		tmp |= FSL_SRDSCR2_EICE_SGMII;
+		out_be32(sd + FSL_SRDSCR2_OFFS, tmp);
+		/* CR 3 */
+		tmp = in_be32(sd + FSL_SRDSCR3_OFFS);
+		tmp &= ~FSL_SRDSCR3_LANEA_MASK;
+		tmp |= FSL_SRDSCR3_LANEA_SGMII;
+		tmp &= ~FSL_SRDSCR3_LANEE_MASK;
+		tmp |= FSL_SRDSCR3_LANEE_SGMII;
+		out_be32(sd + FSL_SRDSCR3_OFFS, tmp);
+		break;
+	case 6: /* Lane A - eTSEC1 SGMII, Lane E - disabled */
+		/* CR 0 */
+		tmp = in_be32(sd + FSL_SRDSCR0_OFFS);
+		tmp &= ~FSL_SRDSCR0_TXEQA_MASK;
+		tmp |= FSL_SRDSCR0_TXEQA_SGMII;
+		out_be32(sd + FSL_SRDSCR0_OFFS, tmp);
+		/* CR 1 */
+		tmp = in_be32(sd + FSL_SRDSCR1_OFFS);
+		tmp &= ~FSL_SRDSCR1_LANEE_MASK;
+		tmp |= FSL_SRDSCR1_LANEE_OFF;
+		out_be32(sd + FSL_SRDSCR1_OFFS, tmp);
+		/* CR 2 */
+		tmp = in_be32(sd + FSL_SRDSCR2_OFFS);
+		tmp &= ~FSL_SRDSCR2_EICA_MASK;
+		tmp |= FSL_SRDSCR2_EICA_SGMII;
+		out_be32(sd + FSL_SRDSCR2_OFFS, tmp);
+		/* CR 3 */
+		tmp = in_be32(sd + FSL_SRDSCR3_OFFS);
+		tmp &= ~FSL_SRDSCR3_LANEA_MASK;
+		tmp |= FSL_SRDSCR3_LANEA_SGMII;
+		out_be32(sd + FSL_SRDSCR3_OFFS, tmp);
+		break;
+	case 7: /* Lane A - disabled, Lane E - disabled */
+		/* CR 1 */
+		tmp = in_be32(sd + FSL_SRDSCR1_OFFS);
+		tmp &= ~FSL_SRDSCR1_LANEA_MASK;
+		tmp |= FSL_SRDSCR1_LANEA_OFF;
+		tmp &= ~FSL_SRDSCR1_LANEE_MASK;
+		tmp |= FSL_SRDSCR1_LANEE_OFF;
+		out_be32(sd + FSL_SRDSCR1_OFFS, tmp);
+		break;
+	default:
+		break;
+	}
+}
diff --git a/cpu/mpc85xx/speed.c b/cpu/mpc85xx/speed.c
index 699441b..1cda1e3 100644
--- a/cpu/mpc85xx/speed.c
+++ b/cpu/mpc85xx/speed.c
@@ -110,6 +110,10 @@ int get_clocks (void)
 #endif
 	gd->i2c2_clk = gd->i2c1_clk;
 
+#if defined(CONFIG_MPC8536)
+	gd->sdhc_clk = gd->bus_clk / 2;
+#endif
+
 #if defined(CONFIG_CPM2)
 	gd->vco_out = 2*sys_info.freqSystemBus;
 	gd->cpm_clk = gd->vco_out / 2;
diff --git a/drivers/misc/fsl_law.c b/drivers/misc/fsl_law.c
index 37af297..a2b0298 100644
--- a/drivers/misc/fsl_law.c
+++ b/drivers/misc/fsl_law.c
@@ -38,7 +38,7 @@ DECLARE_GLOBAL_DATA_PTR;
       defined(CONFIG_MPC8568) || \
       defined(CONFIG_MPC8641) || defined(CONFIG_MPC8610)
 #define FSL_HW_NUM_LAWS 10
-#elif defined(CONFIG_MPC8572)
+#elif defined(CONFIG_MPC8536) || defined(CONFIG_MPC8572)
 #define FSL_HW_NUM_LAWS 12
 #else
 #error FSL_HW_NUM_LAWS not defined for this platform
diff --git a/include/asm-ppc/global_data.h b/include/asm-ppc/global_data.h
index be2ce24..c09b07d 100644
--- a/include/asm-ppc/global_data.h
+++ b/include/asm-ppc/global_data.h
@@ -70,9 +70,6 @@ typedef	struct	global_data {
 #if defined(CONFIG_MPC8315)
 	u32 tdm_clk;
 #endif
-#if defined(CONFIG_MPC837X)
-	u32 sdhc_clk;
-#endif
 	u32 core_clk;
 	u32 enc_clk;
 	u32 lbiu_clk;
@@ -89,6 +86,9 @@ typedef	struct	global_data {
 	u32  mem_sec_clk;
 #endif /* CONFIG_MPC8360 */
 #endif
+#if defined(CONFIG_MPC837X) || defined(CONFIG_MPC8536)
+	u32 sdhc_clk;
+#endif
 #if defined(CONFIG_MPC83XX) || defined(CONFIG_MPC85xx) || defined(CONFIG_MPC86xx)
 	u32 i2c1_clk;
 	u32 i2c2_clk;
diff --git a/include/asm-ppc/immap_85xx.h b/include/asm-ppc/immap_85xx.h
index 113ba48..559d6ea 100644
--- a/include/asm-ppc/immap_85xx.h
+++ b/include/asm-ppc/immap_85xx.h
@@ -1560,6 +1560,7 @@ typedef struct ccsr_gur {
 #define MPC85xx_PORDEVSR_SGMII2_DIS	0x10000000
 #define MPC85xx_PORDEVSR_SGMII3_DIS	0x08000000
 #define MPC85xx_PORDEVSR_SGMII4_DIS	0x04000000
+#define MPC85xx_PORDEVSR_SRDS2_IO_SEL   0x38000000
 #define MPC85xx_PORDEVSR_IO_SEL		0x00380000
 #define MPC85xx_PORDEVSR_PCI2_ARB	0x00040000
 #define MPC85xx_PORDEVSR_PCI1_ARB	0x00020000
@@ -1653,13 +1654,23 @@ typedef struct ccsr_gur {
 #define CFG_MPC85xx_PCIX_ADDR	(CFG_IMMR + CFG_MPC85xx_PCIX_OFFSET)
 #define CFG_MPC85xx_PCIX2_OFFSET	(0x9000)
 #define CFG_MPC85xx_PCIX2_ADDR	(CFG_IMMR + CFG_MPC85xx_PCIX2_OFFSET)
+#define CFG_MPC85xx_SATA1_OFFSET	(0x18000)
+#define CFG_MPC85xx_SATA1_ADDR	(CFG_IMMR + CFG_MPC85xx_SATA1_OFFSET)
+#define CFG_MPC85xx_SATA2_OFFSET	(0x19000)
+#define CFG_MPC85xx_SATA2_ADDR	(CFG_IMMR + CFG_MPC85xx_SATA2_OFFSET)
 #define CFG_MPC85xx_L2_OFFSET	(0x20000)
 #define CFG_MPC85xx_L2_ADDR	(CFG_IMMR + CFG_MPC85xx_L2_OFFSET)
 #define CFG_MPC85xx_DMA_OFFSET	(0x21000)
 #define CFG_MPC85xx_DMA_ADDR	(CFG_IMMR + CFG_MPC85xx_DMA_OFFSET)
+#define CFG_MPC85xx_ESDHC_OFFSET	(0x2e000)
+#define CFG_MPC85xx_ESDHC_ADDR	(CFG_IMMR + CFG_MPC85xx_ESDHC_OFFSET)
 #define CFG_MPC85xx_PIC_OFFSET	(0x40000)
 #define CFG_MPC85xx_PIC_ADDR	(CFG_IMMR + CFG_MPC85xx_PIC_OFFSET)
 #define CFG_MPC85xx_CPM_OFFSET	(0x80000)
 #define CFG_MPC85xx_CPM_ADDR	(CFG_IMMR + CFG_MPC85xx_CPM_OFFSET)
+#define CFG_MPC85xx_SERDES1_OFFSET	(0xE3000)
+#define CFG_MPC85xx_SERDES1_ADDR	(CFG_IMMR + CFG_MPC85xx_SERDES2_OFFSET)
+#define CFG_MPC85xx_SERDES2_OFFSET	(0xE3100)
+#define CFG_MPC85xx_SERDES2_ADDR	(CFG_IMMR + CFG_MPC85xx_SERDES2_OFFSET)
 
 #endif /*__IMMAP_85xx__*/
diff --git a/include/asm-ppc/processor.h b/include/asm-ppc/processor.h
index e617868..465ea72 100644
--- a/include/asm-ppc/processor.h
+++ b/include/asm-ppc/processor.h
@@ -920,6 +920,8 @@
 
 #define SVR_8533	0x803400
 #define SVR_8533_E	0x803C00
+#define SVR_8536	0x803700
+#define SVR_8536_E	0x803F00
 #define SVR_8540	0x803000
 #define SVR_8541	0x807200
 #define SVR_8541_E	0x807A00
diff --git a/include/pci_ids.h b/include/pci_ids.h
index 165456b..ae642b1 100644
--- a/include/pci_ids.h
+++ b/include/pci_ids.h
@@ -2057,6 +2057,8 @@
 #define PCI_DEVICE_ID_MICROGATE_SCA	0x0030
 
 #define PCI_VENDOR_ID_FREESCALE		0x1957
+#define PCI_DEVICE_ID_MPC8536E		0x0050
+#define PCI_DEVICE_ID_MPC8536		0x0051
 #define PCI_DEVICE_ID_MPC8548E		0x0012
 #define PCI_DEVICE_ID_MPC8548		0x0013
 #define PCI_DEVICE_ID_MPC8543E		0x0014
-- 
1.5.5.1




More information about the U-Boot mailing list