diff options
Diffstat (limited to 'cpu')
| -rw-r--r-- | cpu/mpc85xx/Makefile | 1 | ||||
| -rw-r--r-- | cpu/mpc85xx/cpu.c | 8 | ||||
| -rw-r--r-- | cpu/mpc85xx/cpu_init.c | 7 | ||||
| -rw-r--r-- | cpu/mpc85xx/mpc8536_serdes.c | 180 | ||||
| -rw-r--r-- | cpu/mpc85xx/speed.c | 4 | 
5 files changed, 199 insertions, 1 deletions
| diff --git a/cpu/mpc85xx/Makefile b/cpu/mpc85xx/Makefile index 80b80ffe4..627e61b05 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 5c2231de6..2fe3cea3f 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 4feb7519a..783c5bae7 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 000000000..ae091e6ad --- /dev/null +++ b/cpu/mpc85xx/mpc8536_serdes.c @@ -0,0 +1,180 @@ +/* + * Copyright (C) 2008 Freescale Semicondutor, Inc. All rights reserved. + *	Dave Liu <daveliu@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 699441b46..1cda1e34e 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; |