diff options
| author | Anton Vorontsov <avorontsov@ru.mvista.com> | 2008-10-02 18:32:25 +0400 | 
|---|---|---|
| committer | Kim Phillips <kim.phillips@freescale.com> | 2008-10-21 18:34:08 -0500 | 
| commit | 1da83a63d8e1b4bddeb82581b1745a09aac3e2d3 (patch) | |
| tree | 6f18419b18f857942012bf226bac9534b166d68a | |
| parent | e6d9c8916de9c24f2c52d0b01cf00d2e74a04cd8 (diff) | |
| download | olio-uboot-2014.01-1da83a63d8e1b4bddeb82581b1745a09aac3e2d3.tar.xz olio-uboot-2014.01-1da83a63d8e1b4bddeb82581b1745a09aac3e2d3.zip | |
mpc83xx: add SGMII riser module support for the MPC8378E-MDS boards
This involves configuring the SerDes and fixing up the flags and
PHY addresses for the TSECs.
For Linux we also fix up the device tree.
Signed-off-by: Anton Vorontsov <avorontsov@ru.mvista.com>
Signed-off-by: Kim Phillips <kim.phillips@freescale.com>
| -rw-r--r-- | board/freescale/mpc837xemds/mpc837xemds.c | 123 | ||||
| -rw-r--r-- | include/configs/MPC837XEMDS.h | 2 | 
2 files changed, 125 insertions, 0 deletions
| diff --git a/board/freescale/mpc837xemds/mpc837xemds.c b/board/freescale/mpc837xemds/mpc837xemds.c index 155907ee9..f4bdb8991 100644 --- a/board/freescale/mpc837xemds/mpc837xemds.c +++ b/board/freescale/mpc837xemds/mpc837xemds.c @@ -15,6 +15,7 @@  #include <asm/io.h>  #include <asm/fsl_serdes.h>  #include <spd_sdram.h> +#include <tsec.h>  #if defined(CONFIG_OF_LIBFDT)  #include <libfdt.h>  #endif @@ -44,6 +45,8 @@ int board_early_init_f(void)  				 FSL_SERDES_CLK_100, FSL_SERDES_VDD_1V);  		break;  	case SPR_8378: +		fsl_setup_serdes(CONFIG_FSL_SERDES1, FSL_SERDES_PROTO_SGMII, +				 FSL_SERDES_CLK_125, FSL_SERDES_VDD_1V);  		fsl_setup_serdes(CONFIG_FSL_SERDES2, FSL_SERDES_PROTO_PEX,  				 FSL_SERDES_CLK_100, FSL_SERDES_VDD_1V);  		break; @@ -62,6 +65,125 @@ int board_early_init_f(void)  	return 0;  } +#if defined(CONFIG_TSEC1) || defined(CONFIG_TSEC2) +int board_eth_init(bd_t *bd) +{ +	struct tsec_info_struct tsec_info[2]; +	struct immap __iomem *im = (struct immap __iomem *)CONFIG_SYS_IMMR; +	u32 rcwh = in_be32(&im->reset.rcwh); +	u32 tsec_mode; +	int num = 0; + +	/* New line after Net: */ +	printf("\n"); + +#ifdef CONFIG_TSEC1 +	SET_STD_TSEC_INFO(tsec_info[num], 1); + +	printf(CONFIG_TSEC1_NAME ": "); + +	tsec_mode = rcwh & HRCWH_TSEC1M_MASK; +	if (tsec_mode == HRCWH_TSEC1M_IN_RGMII) { +		printf("RGMII\n"); +		/* this is default, no need to fixup */ +	} else if (tsec_mode == HRCWH_TSEC1M_IN_SGMII) { +		printf("SGMII\n"); +		tsec_info[num].phyaddr = TSEC1_PHY_ADDR_SGMII; +		tsec_info[num].flags = TSEC_GIGABIT; +	} else { +		printf("unsupported PHY type\n"); +	} +	num++; +#endif +#ifdef CONFIG_TSEC2 +	SET_STD_TSEC_INFO(tsec_info[num], 2); + +	printf(CONFIG_TSEC2_NAME ": "); + +	tsec_mode = rcwh & HRCWH_TSEC2M_MASK; +	if (tsec_mode == HRCWH_TSEC2M_IN_RGMII) { +		printf("RGMII\n"); +		/* this is default, no need to fixup */ +	} else if (tsec_mode == HRCWH_TSEC2M_IN_SGMII) { +		printf("SGMII\n"); +		tsec_info[num].phyaddr = TSEC2_PHY_ADDR_SGMII; +		tsec_info[num].flags = TSEC_GIGABIT; +	} else { +		printf("unsupported PHY type\n"); +	} +	num++; +#endif +	return tsec_eth_init(bd, tsec_info, num); +} + +static void __ft_tsec_fixup(void *blob, bd_t *bd, const char *alias, +			    int phy_addr) +{ +	const char *phy_type = "sgmii"; +	const u32 *ph; +	int off; +	int err; + +	off = fdt_path_offset(blob, alias); +	if (off < 0) { +		printf("WARNING: could not find %s alias: %s.\n", alias, +			fdt_strerror(off)); +		return; +	} + +	err = fdt_setprop(blob, off, "phy-connection-type", phy_type, +			  strlen(phy_type) + 1); +	if (err) { +		printf("WARNING: could not set phy-connection-type for %s: " +			"%s.\n", alias, fdt_strerror(err)); +		return; +	} + +	ph = (u32 *)fdt_getprop(blob, off, "phy-handle", 0); +	if (!ph) { +		printf("WARNING: could not get phy-handle for %s.\n", +			alias); +		return; +	} + +	off = fdt_node_offset_by_phandle(blob, *ph); +	if (off < 0) { +		printf("WARNING: could not get phy node for %s: %s\n", alias, +			fdt_strerror(off)); +		return; +	} + +	phy_addr = cpu_to_fdt32(phy_addr); +	err = fdt_setprop(blob, off, "reg", &phy_addr, sizeof(phy_addr)); +	if (err < 0) { +		printf("WARNING: could not set phy node's reg for %s: " +			"%s.\n", alias, fdt_strerror(err)); +		return; +	} +} + +static void ft_tsec_fixup(void *blob, bd_t *bd) +{ +	struct immap __iomem *im = (struct immap __iomem *)CONFIG_SYS_IMMR; +	u32 rcwh = in_be32(&im->reset.rcwh); +	u32 tsec_mode; + +#ifdef CONFIG_TSEC1 +	tsec_mode = rcwh & HRCWH_TSEC1M_MASK; +	if (tsec_mode == HRCWH_TSEC1M_IN_SGMII) +		__ft_tsec_fixup(blob, bd, "ethernet0", TSEC1_PHY_ADDR_SGMII); +#endif + +#ifdef CONFIG_TSEC2 +	tsec_mode = rcwh & HRCWH_TSEC2M_MASK; +	if (tsec_mode == HRCWH_TSEC2M_IN_SGMII) +		__ft_tsec_fixup(blob, bd, "ethernet1", TSEC2_PHY_ADDR_SGMII); +#endif +} +#else +static inline void ft_tsec_fixup(void *blob, bd_t *bd) {} +#endif /* defined(CONFIG_TSEC1) || defined(CONFIG_TSEC2) */ +  int board_early_init_r(void)  {  #ifdef CONFIG_PQ_MDS_PIB @@ -152,6 +274,7 @@ int checkboard(void)  void ft_board_setup(void *blob, bd_t *bd)  {  	ft_cpu_setup(blob, bd); +	ft_tsec_fixup(blob, bd);  #ifdef CONFIG_PCI  	ft_pci_setup(blob, bd);  #endif diff --git a/include/configs/MPC837XEMDS.h b/include/configs/MPC837XEMDS.h index aeb61a9d5..e2f0942ce 100644 --- a/include/configs/MPC837XEMDS.h +++ b/include/configs/MPC837XEMDS.h @@ -382,6 +382,8 @@  #define CONFIG_TSEC2_NAME	"eTSEC1"  #define TSEC1_PHY_ADDR		2  #define TSEC2_PHY_ADDR		3 +#define TSEC1_PHY_ADDR_SGMII	8 +#define TSEC2_PHY_ADDR_SGMII	4  #define TSEC1_PHYIDX		0  #define TSEC2_PHYIDX		0  #define TSEC1_FLAGS		(TSEC_GIGABIT | TSEC_REDUCED) |