[U-Boot] [PATCH 1/2] powerpc/85xx: fsl_corenet_serdes code rework

From: Emil Medve Emilian.Medve@freescale.com
Rework and add some new APIs to the fsl_corenet_serdes code for use by erratum and drivers.
* Rename serdes_get_bank() to serdes_get_bank_by_lane() * Add serdes_get_first_lane returns which SERDES lane is used by device
Signed-off-by: Emil Medve Emilian.Medve@Freescale.com Signed-off-by: Timur Tabi timur@freescale.com Signed-off-by: Kumar Gala galak@kernel.crashing.org --- arch/powerpc/cpu/mpc85xx/fsl_corenet_serdes.c | 40 +++++++++++++++++++++++- arch/powerpc/cpu/mpc85xx/fsl_corenet_serdes.h | 2 +- arch/powerpc/include/asm/fsl_serdes.h | 4 ++ 3 files changed, 43 insertions(+), 3 deletions(-)
diff --git a/arch/powerpc/cpu/mpc85xx/fsl_corenet_serdes.c b/arch/powerpc/cpu/mpc85xx/fsl_corenet_serdes.c index f58d6d6..1177247 100644 --- a/arch/powerpc/cpu/mpc85xx/fsl_corenet_serdes.c +++ b/arch/powerpc/cpu/mpc85xx/fsl_corenet_serdes.c @@ -29,6 +29,7 @@ #include <asm/io.h> #include <asm/processor.h> #include <asm/fsl_law.h> +#include <asm/errno.h> #include "fsl_corenet_serdes.h"
static u32 serdes_prtcl_map; @@ -91,7 +92,7 @@ int serdes_get_lane_idx(int lane) return lanes[lane].idx; }
-int serdes_get_bank(int lane) +int serdes_get_bank_by_lane(int lane) { return lanes[lane].bank; } @@ -132,6 +133,41 @@ int is_serdes_configured(enum srds_prtcl device) return (1 << device) & serdes_prtcl_map; }
+static int __serdes_get_first_lane(uint32_t prtcl, enum srds_prtcl device) +{ + int i; + + for (i = 0; i < SRDS_MAX_LANES; i++) { + if (serdes_get_prtcl(prtcl, i) == device) + return i; + } + + return -ENODEV; +} + +/* + * Returns the SERDES lane (0..SRDS_MAX_LANES-1) that routes to the given + * device. This depends on the current SERDES protocol, as defined in the RCW. + * + * Returns a negative error code if SERDES is disabled or the given device is + * not supported in the current SERDES protocol. + */ +int serdes_get_first_lane(enum srds_prtcl device) +{ + u32 prtcl; + const ccsr_gur_t *gur; + + gur = (typeof(gur))CONFIG_SYS_MPC85xx_GUTS_ADDR; + + /* Is serdes enabled at all? */ + if (unlikely((in_be32(&gur->rcwsr[5]) & 0x2000) == 0)) + return -ENODEV; + + prtcl = (in_be32(&gur->rcwsr[4]) & FSL_CORENET_RCWSR4_SRDS_PRTCL) >> 26; + + return __serdes_get_first_lane(prtcl, device); +} + #ifndef CONFIG_SYS_DCSRBAR_PHYS #define CONFIG_SYS_DCSRBAR_PHYS 0x80000000 /* Must be 1GB-aligned for rev1.0 */ #define CONFIG_SYS_DCSRBAR 0x80000000 @@ -325,7 +361,7 @@ void fsl_serdes_init(void) for (lane = 0; lane < SRDS_MAX_LANES; lane++) { enum srds_prtcl lane_prtcl = serdes_get_prtcl(cfg, lane); if (serdes_lane_enabled(lane)) { - have_bank[serdes_get_bank(lane)] = 1; + have_bank[serdes_get_bank_by_lane(lane)] = 1; serdes_prtcl_map |= (1 << lane_prtcl); } } diff --git a/arch/powerpc/cpu/mpc85xx/fsl_corenet_serdes.h b/arch/powerpc/cpu/mpc85xx/fsl_corenet_serdes.h index 42d771e..f261351 100644 --- a/arch/powerpc/cpu/mpc85xx/fsl_corenet_serdes.h +++ b/arch/powerpc/cpu/mpc85xx/fsl_corenet_serdes.h @@ -33,7 +33,7 @@ enum srds_bank {
int is_serdes_prtcl_valid(u32 prtcl); int serdes_get_lane_idx(int lane); -int serdes_get_bank(int lane); +int serdes_get_bank_by_lane(int lane); int serdes_lane_enabled(int lane); enum srds_prtcl serdes_get_prtcl(int cfg, int lane);
diff --git a/arch/powerpc/include/asm/fsl_serdes.h b/arch/powerpc/include/asm/fsl_serdes.h index 85518eb..9d9f2e4 100644 --- a/arch/powerpc/include/asm/fsl_serdes.h +++ b/arch/powerpc/include/asm/fsl_serdes.h @@ -53,4 +53,8 @@ enum srds_prtcl { int is_serdes_configured(enum srds_prtcl device); void fsl_serdes_init(void);
+#ifdef CONFIG_FSL_CORENET +int serdes_get_first_lane(enum srds_prtcl device); +#endif + #endif /* __FSL_SERDES_H */

From: Emil Medve Emilian.Medve@freescale.com
Signed-off-by: Emil Medve Emilian.Medve@Freescale.com Signed-off-by: Timur Tabi timur@freescale.com Signed-off-by: Kumar Gala galak@kernel.crashing.org --- arch/powerpc/cpu/mpc85xx/cmd_errata.c | 3 + arch/powerpc/cpu/mpc85xx/fsl_corenet_serdes.c | 107 +++++++++++++++++++++++++ arch/powerpc/include/asm/config_mpc85xx.h | 1 + arch/powerpc/include/asm/fsl_serdes.h | 3 + arch/powerpc/include/asm/immap_85xx.h | 2 + 5 files changed, 116 insertions(+), 0 deletions(-)
diff --git a/arch/powerpc/cpu/mpc85xx/cmd_errata.c b/arch/powerpc/cpu/mpc85xx/cmd_errata.c index e94975a..0564816 100644 --- a/arch/powerpc/cpu/mpc85xx/cmd_errata.c +++ b/arch/powerpc/cpu/mpc85xx/cmd_errata.c @@ -44,6 +44,9 @@ static int do_errata(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) #if defined(CONFIG_SYS_P4080_ERRATUM_SERDES8) puts("Work-around for Erratum SERDES8 enabled\n"); #endif +#if defined(CONFIG_SYS_P4080_ERRATUM_SERDES9) + puts("Work-around for Erratum SERDES9 enabled\n"); +#endif #if defined(CONFIG_SYS_P4080_ERRATUM_CPU22) puts("Work-around for Erratum CPU22 enabled\n"); #endif diff --git a/arch/powerpc/cpu/mpc85xx/fsl_corenet_serdes.c b/arch/powerpc/cpu/mpc85xx/fsl_corenet_serdes.c index 1177247..d39f963 100644 --- a/arch/powerpc/cpu/mpc85xx/fsl_corenet_serdes.c +++ b/arch/powerpc/cpu/mpc85xx/fsl_corenet_serdes.c @@ -168,6 +168,90 @@ int serdes_get_first_lane(enum srds_prtcl device) return __serdes_get_first_lane(prtcl, device); }
+#ifdef CONFIG_SYS_P4080_ERRATUM_SERDES9 +/* + * Returns the SERDES bank (1, 2, or 3) that a given device is on for a given + * SERDES protocol. + * + * Returns a negative error code if the given device is not supported for the + * given SERDES protocol. + */ +static int serdes_get_bank_by_device(uint32_t prtcl, enum srds_prtcl device) +{ + int lane; + + lane = __serdes_get_first_lane(prtcl, device); + if (unlikely(lane < 0)) + return lane; + + return serdes_get_bank_by_lane(lane); +} + +static uint32_t __serdes_get_lane_count(uint32_t prtcl, enum srds_prtcl device, + int first) +{ + int lane; + + for (lane = first; lane < SRDS_MAX_LANES; lane++) { + if (serdes_get_prtcl(prtcl, lane) != device) + break; + } + + return lane - first; +} + +static void __serdes_reset_rx(serdes_corenet_t *regs, + uint32_t prtcl, + enum srds_prtcl device) +{ + int lane, idx, first, last; + + lane = __serdes_get_first_lane(prtcl, device); + if (unlikely(lane < 0)) + return; + first = serdes_get_lane_idx(lane); + last = first + __serdes_get_lane_count(prtcl, device, lane); + + /* + * Set BnGCRy0[RRST] = 0 for each lane in the each bank that is + * selected as XAUI to place the lane into reset. + */ + for (idx = first; idx < last; idx++) + clrbits_be32(®s->lane[idx].gcr0, SRDS_GCR0_RRST); + + /* Wait at least 250 ns */ + udelay(1); + + /* + * Set BnGCRy0[RRST] = 1 for each lane in the each bank that is + * selected as XAUI to bring the lane out of reset. + */ + for (idx = first; idx < last; idx++) + setbits_be32(®s->lane[idx].gcr0, SRDS_GCR0_RRST); +} + +void serdes_reset_rx(enum srds_prtcl device) +{ + u32 prtcl; + const ccsr_gur_t *gur; + serdes_corenet_t *regs; + + if (unlikely(device == NONE)) + return; + + gur = (typeof(gur))CONFIG_SYS_MPC85xx_GUTS_ADDR; + + /* Is serdes enabled at all? */ + if (unlikely((in_be32(&gur->rcwsr[5]) & 0x2000) == 0)) + return; + + regs = (typeof(regs))CONFIG_SYS_FSL_CORENET_SERDES_ADDR; + prtcl = (in_be32(&gur->rcwsr[4]) & FSL_CORENET_RCWSR4_SRDS_PRTCL) >> 26; + + __serdes_reset_rx(regs, prtcl, device); +} +#endif + #ifndef CONFIG_SYS_DCSRBAR_PHYS #define CONFIG_SYS_DCSRBAR_PHYS 0x80000000 /* Must be 1GB-aligned for rev1.0 */ #define CONFIG_SYS_DCSRBAR 0x80000000 @@ -318,6 +402,9 @@ void fsl_serdes_init(void) const char *srds_lpd_arg; size_t arglen; #endif +#ifdef CONFIG_SYS_P4080_ERRATUM_SERDES9 + enum srds_prtcl device; +#endif char buffer[HWCONFIG_BUFFER_SIZE]; char *buf = NULL;
@@ -452,6 +539,17 @@ void fsl_serdes_init(void) break; case XAUI_FM1: case XAUI_FM2: +#ifdef CONFIG_SYS_P4080_ERRATUM_SERDES9 + /* + * Set BnTTLCRy0[FLT_SEL] = 000011 and set + * BnTTLCRy0[17] = 1 for each of the SerDes lanes + * selected as XAUI on each bank before XAUI is + * initialized. + */ + clrsetbits_be32(&srds_regs->lane[idx].ttlcr0, + SRDS_TTLCR0_FLT_SEL_MASK, + 0x03000000 | SRDS_TTLCR0_PM_DIS); +#endif if (lane_prtcl == XAUI_FM1) serdes8_devdisr2 |= FSL_CORENET_DEVDISR2_FM1 | FSL_CORENET_DEVDISR2_10GEC1; @@ -472,6 +570,8 @@ void fsl_serdes_init(void) puts("\n"); #endif
+#endif + for (idx = 0; idx < SRDS_MAX_BANK; idx++) { u32 rstctl;
@@ -527,4 +627,11 @@ void fsl_serdes_init(void) continue; } } + +#ifdef CONFIG_SYS_P4080_ERRATUM_SERDES9 + for (device = XAUI_FM1; device <= XAUI_FM2; device++) { + if (is_serdes_configured(device)) + __serdes_reset_rx(srds_regs, cfg, device); + } +#endif } diff --git a/arch/powerpc/include/asm/config_mpc85xx.h b/arch/powerpc/include/asm/config_mpc85xx.h index 41fd86c..88bc030 100644 --- a/arch/powerpc/include/asm/config_mpc85xx.h +++ b/arch/powerpc/include/asm/config_mpc85xx.h @@ -304,6 +304,7 @@ #define CONFIG_SYS_FSL_ERRATUM_ESDHC136 #define CONFIG_SYS_P4080_ERRATUM_CPU22 #define CONFIG_SYS_P4080_ERRATUM_SERDES8 +#define CONFIG_SYS_P4080_ERRATUM_SERDES9
/* P5010 is single core version of P5020 */ #elif defined(CONFIG_PPC_P5010) diff --git a/arch/powerpc/include/asm/fsl_serdes.h b/arch/powerpc/include/asm/fsl_serdes.h index 9d9f2e4..0f31af1 100644 --- a/arch/powerpc/include/asm/fsl_serdes.h +++ b/arch/powerpc/include/asm/fsl_serdes.h @@ -55,6 +55,9 @@ void fsl_serdes_init(void);
#ifdef CONFIG_FSL_CORENET int serdes_get_first_lane(enum srds_prtcl device); +#ifdef CONFIG_SYS_P4080_ERRATUM_SERDES9 +void serdes_reset_rx(enum srds_prtcl device); +#endif #endif
#endif /* __FSL_SERDES_H */ diff --git a/arch/powerpc/include/asm/immap_85xx.h b/arch/powerpc/include/asm/immap_85xx.h index c39c95f..4c71057 100644 --- a/arch/powerpc/include/asm/immap_85xx.h +++ b/arch/powerpc/include/asm/immap_85xx.h @@ -2138,6 +2138,8 @@ typedef struct serdes_corenet { #define SRDS_TECR0_TEQ_TYPE_2LVL 0x10000000 u32 res3; u32 ttlcr0; /* Transition Tracking Loop Ctrl 0 */ +#define SRDS_TTLCR0_FLT_SEL_MASK 0x3f000000 +#define SRDS_TTLCR0_PM_DIS 0x00004000 u32 res4[7]; } lane[24]; u32 res6[384];

On Apr 9, 2011, at 3:40 PM, Kumar Gala wrote:
From: Emil Medve Emilian.Medve@freescale.com
Signed-off-by: Emil Medve Emilian.Medve@Freescale.com Signed-off-by: Timur Tabi timur@freescale.com Signed-off-by: Kumar Gala galak@kernel.crashing.org
arch/powerpc/cpu/mpc85xx/cmd_errata.c | 3 + arch/powerpc/cpu/mpc85xx/fsl_corenet_serdes.c | 107 +++++++++++++++++++++++++ arch/powerpc/include/asm/config_mpc85xx.h | 1 + arch/powerpc/include/asm/fsl_serdes.h | 3 + arch/powerpc/include/asm/immap_85xx.h | 2 + 5 files changed, 116 insertions(+), 0 deletions(-)
applied to 85xx
- k

On Apr 9, 2011, at 3:40 PM, Kumar Gala wrote:
From: Emil Medve Emilian.Medve@freescale.com
Rework and add some new APIs to the fsl_corenet_serdes code for use by erratum and drivers.
- Rename serdes_get_bank() to serdes_get_bank_by_lane()
- Add serdes_get_first_lane returns which SERDES lane is used by device
Signed-off-by: Emil Medve Emilian.Medve@Freescale.com Signed-off-by: Timur Tabi timur@freescale.com Signed-off-by: Kumar Gala galak@kernel.crashing.org
arch/powerpc/cpu/mpc85xx/fsl_corenet_serdes.c | 40 +++++++++++++++++++++++- arch/powerpc/cpu/mpc85xx/fsl_corenet_serdes.h | 2 +- arch/powerpc/include/asm/fsl_serdes.h | 4 ++ 3 files changed, 43 insertions(+), 3 deletions(-)
applied to 85xx
- k
participants (1)
-
Kumar Gala