diff options
-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 5b7d80a..b4ef286 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 82c216b..1d35c0c 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 0000000..0dc1975 --- /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 0000000..3ae9069 --- /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); + } +} |