diff options
Diffstat (limited to 'arch')
| -rw-r--r-- | arch/powerpc/cpu/mpc86xx/Makefile | 2 | ||||
| -rw-r--r-- | arch/powerpc/cpu/mpc86xx/cpu_init.c | 6 | ||||
| -rw-r--r-- | arch/powerpc/cpu/mpc86xx/mpc8610_serdes.c | 85 | ||||
| -rw-r--r-- | arch/powerpc/cpu/mpc86xx/mpc8641_serdes.c | 94 | 
4 files changed, 186 insertions, 1 deletions
| diff --git a/arch/powerpc/cpu/mpc86xx/Makefile b/arch/powerpc/cpu/mpc86xx/Makefile index 5b7d80a5b..b4ef286af 100644 --- a/arch/powerpc/cpu/mpc86xx/Makefile +++ b/arch/powerpc/cpu/mpc86xx/Makefile @@ -42,6 +42,8 @@ COBJS-$(CONFIG_MPC8641) += ddr-8641.o  COBJS-$(CONFIG_OF_LIBFDT) += fdt.o  COBJS-y	+= interrupts.o  COBJS-$(CONFIG_MP) += mp.o +COBJS-$(CONFIG_MPC8610) += mpc8610_serdes.o +COBJS-$(CONFIG_MPC8641) += mpc8641_serdes.o  COBJS-y	+= speed.o  SRCS	:= $(START:.o=.S) $(SOBJS-y:.o=.S) $(COBJS-y:.o=.c) diff --git a/arch/powerpc/cpu/mpc86xx/cpu_init.c b/arch/powerpc/cpu/mpc86xx/cpu_init.c index 82c216ba5..1d35c0c65 100644 --- a/arch/powerpc/cpu/mpc86xx/cpu_init.c +++ b/arch/powerpc/cpu/mpc86xx/cpu_init.c @@ -1,5 +1,5 @@  /* - * Copyright 2004,2009 Freescale Semiconductor, Inc. + * Copyright 2004,2009-2010 Freescale Semiconductor, Inc.   * Jeff Brown   * Srikanth Srinivasan (srikanth.srinivasan@freescale.com)   * @@ -31,6 +31,7 @@  #include <mpc86xx.h>  #include <asm/mmu.h>  #include <asm/fsl_law.h> +#include <asm/fsl_serdes.h>  #include <asm/mp.h>  void setup_bats(void); @@ -76,6 +77,9 @@ void cpu_init_f(void)   */  int cpu_init_r(void)  { +	/* needs to be in ram since code uses global static vars */ +	fsl_serdes_init(); +  #if defined(CONFIG_MP)  	setup_mp();  #endif diff --git a/arch/powerpc/cpu/mpc86xx/mpc8610_serdes.c b/arch/powerpc/cpu/mpc86xx/mpc8610_serdes.c new file mode 100644 index 000000000..0dc1975bf --- /dev/null +++ b/arch/powerpc/cpu/mpc86xx/mpc8610_serdes.c @@ -0,0 +1,85 @@ +/* + * Copyright 2010 Freescale Semiconductor, Inc. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * 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. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <config.h> +#include <common.h> +#include <asm/io.h> +#include <asm/immap_86xx.h> +#include <asm/fsl_serdes.h> + +#define SRDS1_MAX_LANES		4 +#define SRDS2_MAX_LANES		4 + +static u32 serdes1_prtcl_map, serdes2_prtcl_map; + +static u8 serdes1_cfg_tbl[][SRDS1_MAX_LANES] = { +	[0x1] = {PCIE1, PCIE1, PCIE1, PCIE1}, +	[0x4] = {PCIE1, PCIE1, PCIE1, PCIE1}, +	[0x7] = {NONE, NONE, NONE, NONE}, +}; + +static u8 serdes2_cfg_tbl[][SRDS2_MAX_LANES] = { +	[0x0] = {PCIE2, PCIE2, PCIE2, PCIE2}, +	[0x4] = {PCIE2, PCIE2, PCIE2, PCIE2}, +	[0x7] = {NONE, NONE, NONE, NONE}, +}; + +int is_serdes_configured(enum srds_prtcl device) +{ +	int ret = (1 << device) & serdes1_prtcl_map; + +	if (ret) +		return ret; + +	return (1 << device) & serdes2_prtcl_map; +} + +void fsl_serdes_init(void) +{ +	immap_t *immap = (immap_t *) CONFIG_SYS_CCSRBAR; +	ccsr_gur_t *gur = &immap->im_gur; +	u32 pordevsr = in_be32(&gur->pordevsr); +	u32 srds_cfg = (pordevsr & MPC8610_PORDEVSR_IO_SEL) >> +				MPC8610_PORDEVSR_IO_SEL_SHIFT; +	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; +	} +	for (lane = 0; lane < SRDS1_MAX_LANES; lane++) { +		enum srds_prtcl lane_prtcl = serdes1_cfg_tbl[srds_cfg][lane]; +		serdes1_prtcl_map |= (1 << lane_prtcl); +	} + +	if (srds_cfg > ARRAY_SIZE(serdes2_cfg_tbl)) { +		printf("Invalid PORDEVSR[IO_SEL_SRDS] = %d\n", srds_cfg); +		return; +	} + +	for (lane = 0; lane < SRDS2_MAX_LANES; lane++) { +		enum srds_prtcl lane_prtcl = serdes2_cfg_tbl[srds_cfg][lane]; +		serdes2_prtcl_map |= (1 << lane_prtcl); +	} +} diff --git a/arch/powerpc/cpu/mpc86xx/mpc8641_serdes.c b/arch/powerpc/cpu/mpc86xx/mpc8641_serdes.c new file mode 100644 index 000000000..3ae9069f1 --- /dev/null +++ b/arch/powerpc/cpu/mpc86xx/mpc8641_serdes.c @@ -0,0 +1,94 @@ +/* + * Copyright 2010 Freescale Semiconductor, Inc. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * 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. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <config.h> +#include <common.h> +#include <asm/io.h> +#include <asm/immap_86xx.h> +#include <asm/fsl_serdes.h> + +#define SRDS1_MAX_LANES		4 +#define SRDS2_MAX_LANES		4 + +static u32 serdes1_prtcl_map, serdes2_prtcl_map; + +static u8 serdes1_cfg_tbl[][SRDS1_MAX_LANES] = { +	[0x2] = {PCIE1, PCIE1, PCIE1, PCIE1}, +	[0x3] = {PCIE1, PCIE1, PCIE1, PCIE1}, +	[0x5] = {PCIE1, PCIE1, PCIE1, PCIE1}, +	[0x6] = {PCIE1, PCIE1, PCIE1, PCIE1}, +	[0x7] = {PCIE1, PCIE1, PCIE1, PCIE1}, +	[0xf] = {PCIE1, PCIE1, PCIE1, PCIE1}, +}; + +static u8 serdes2_cfg_tbl[][SRDS2_MAX_LANES] = { +	[0x3] = {PCIE2, PCIE2, PCIE2, PCIE2}, +	[0x5] = {SRIO1, SRIO1, SRIO1, SRIO1}, +	[0x6] = {SRIO1, SRIO1, SRIO1, SRIO1}, +	[0x7] = {SRIO1, SRIO1, SRIO1, SRIO1}, +	[0x9] = {SRIO1, SRIO1, SRIO1, SRIO1}, +	[0xa] = {SRIO1, SRIO1, SRIO1, SRIO1}, +	[0xb] = {SRIO1, SRIO1, SRIO1, SRIO1}, +	[0xe] = {PCIE2, PCIE2, PCIE2, PCIE2}, +	[0xf] = {PCIE2, PCIE2, PCIE2, PCIE2}, +}; + +int is_serdes_configured(enum srds_prtcl device) +{ +	int ret = (1 << device) & serdes1_prtcl_map; + +	if (ret) +		return ret; + +	return (1 << device) & serdes2_prtcl_map; +} + +void fsl_serdes_init(void) +{ +	immap_t *immap = (immap_t *) CONFIG_SYS_CCSRBAR; +	ccsr_gur_t *gur = &immap->im_gur; +	u32 pordevsr = in_be32(&gur->pordevsr); +	u32 srds_cfg = (pordevsr & MPC8641_PORDEVSR_IO_SEL) >> +				MPC8641_PORDEVSR_IO_SEL_SHIFT; +	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; +	} +	for (lane = 0; lane < SRDS1_MAX_LANES; lane++) { +		enum srds_prtcl lane_prtcl = serdes1_cfg_tbl[srds_cfg][lane]; +		serdes1_prtcl_map |= (1 << lane_prtcl); +	} + +	if (srds_cfg > ARRAY_SIZE(serdes2_cfg_tbl)) { +		printf("Invalid PORDEVSR[IO_SEL_SRDS] = %d\n", srds_cfg); +		return; +	} + +	for (lane = 0; lane < SRDS2_MAX_LANES; lane++) { +		enum srds_prtcl lane_prtcl = serdes2_cfg_tbl[srds_cfg][lane]; +		serdes2_prtcl_map |= (1 << lane_prtcl); +	} +} |