From ef50d6c06ece74fb17e8d7510e62cad9df8b810d Mon Sep 17 00:00:00 2001 From: Kumar Gala Date: Tue, 12 Aug 2008 11:14:19 -0500 Subject: [PATCH] mpc85xx: Add support for the MPC8536 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 Signed-off-by: Srikanth Srinivasan Signed-off-by: Dejan Minic Signed-off-by: Jason Jin Signed-off-by: Dave Liu --- 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 80b80ffe46..627e61b059 100644 --- a/cpu/mpc85xx/Makefile +++ b/cpu/mpc85xx/Makefile @@ -49,6 +49,7 @@ COBJS-$(CONFIG_MPC8544) += ddr-gen2.o COBJS-$(CONFIG_MPC8572) += ddr-gen3.o COBJS-$(CONFIG_MPC8536) += ddr-gen3.o +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 5c2231de67..2fe3cea3f1 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 4feb7519aa..783c5bae77 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 0000000000..ae091e6ad0 --- /dev/null +++ b/cpu/mpc85xx/mpc8536_serdes.c @@ -0,0 +1,180 @@ +/* + * Copyright (C) 2008 Freescale Semicondutor, Inc. All rights reserved. + * Dave Liu + * + * 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 +#include +#include +#include + +/* 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 699441b46a..1cda1e34eb 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 e4e5c3198a..2e946143bc 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 be2ce24778..c09b07d36a 100644 --- a/include/asm-ppc/global_data.h +++ b/include/asm-ppc/global_data.h @@ -69,9 +69,6 @@ typedef struct global_data { #endif /* CONFIG_MPC834X */ #if defined(CONFIG_MPC8315) u32 tdm_clk; -#endif -#if defined(CONFIG_MPC837X) - u32 sdhc_clk; #endif u32 core_clk; u32 enc_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 113ba482da..559d6ea6ca 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 dce4717f42..e07e5d3be8 100644 --- a/include/asm-ppc/processor.h +++ b/include/asm-ppc/processor.h @@ -926,6 +926,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 165456bc8c..ae642b1c4a 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 -- 2.30.2