mirror of
https://github.com/Fishwaldo/u-boot.git
synced 2025-03-19 13:41:31 +00:00
p4080/serdes: Implement the XAUI workaround for SERDES9 erratum
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>
This commit is contained in:
parent
3d28c5c8ed
commit
df8af0b4a6
5 changed files with 116 additions and 0 deletions
|
@ -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)
|
#if defined(CONFIG_SYS_P4080_ERRATUM_SERDES8)
|
||||||
puts("Work-around for Erratum SERDES8 enabled\n");
|
puts("Work-around for Erratum SERDES8 enabled\n");
|
||||||
#endif
|
#endif
|
||||||
|
#if defined(CONFIG_SYS_P4080_ERRATUM_SERDES9)
|
||||||
|
puts("Work-around for Erratum SERDES9 enabled\n");
|
||||||
|
#endif
|
||||||
#if defined(CONFIG_SYS_P4080_ERRATUM_CPU22)
|
#if defined(CONFIG_SYS_P4080_ERRATUM_CPU22)
|
||||||
puts("Work-around for Erratum CPU22 enabled\n");
|
puts("Work-around for Erratum CPU22 enabled\n");
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -168,6 +168,90 @@ int serdes_get_first_lane(enum srds_prtcl device)
|
||||||
return __serdes_get_first_lane(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
|
#ifndef CONFIG_SYS_DCSRBAR_PHYS
|
||||||
#define CONFIG_SYS_DCSRBAR_PHYS 0x80000000 /* Must be 1GB-aligned for rev1.0 */
|
#define CONFIG_SYS_DCSRBAR_PHYS 0x80000000 /* Must be 1GB-aligned for rev1.0 */
|
||||||
#define CONFIG_SYS_DCSRBAR 0x80000000
|
#define CONFIG_SYS_DCSRBAR 0x80000000
|
||||||
|
@ -317,6 +401,9 @@ void fsl_serdes_init(void)
|
||||||
char srds_lpd_opt[16];
|
char srds_lpd_opt[16];
|
||||||
const char *srds_lpd_arg;
|
const char *srds_lpd_arg;
|
||||||
size_t arglen;
|
size_t arglen;
|
||||||
|
#endif
|
||||||
|
#ifdef CONFIG_SYS_P4080_ERRATUM_SERDES9
|
||||||
|
enum srds_prtcl device;
|
||||||
#endif
|
#endif
|
||||||
char buffer[HWCONFIG_BUFFER_SIZE];
|
char buffer[HWCONFIG_BUFFER_SIZE];
|
||||||
char *buf = NULL;
|
char *buf = NULL;
|
||||||
|
@ -452,6 +539,17 @@ void fsl_serdes_init(void)
|
||||||
break;
|
break;
|
||||||
case XAUI_FM1:
|
case XAUI_FM1:
|
||||||
case XAUI_FM2:
|
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)
|
if (lane_prtcl == XAUI_FM1)
|
||||||
serdes8_devdisr2 |= FSL_CORENET_DEVDISR2_FM1 |
|
serdes8_devdisr2 |= FSL_CORENET_DEVDISR2_FM1 |
|
||||||
FSL_CORENET_DEVDISR2_10GEC1;
|
FSL_CORENET_DEVDISR2_10GEC1;
|
||||||
|
@ -470,6 +568,8 @@ void fsl_serdes_init(void)
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
puts("\n");
|
puts("\n");
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
for (idx = 0; idx < SRDS_MAX_BANK; idx++) {
|
for (idx = 0; idx < SRDS_MAX_BANK; idx++) {
|
||||||
|
@ -527,4 +627,11 @@ void fsl_serdes_init(void)
|
||||||
continue;
|
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
|
||||||
}
|
}
|
||||||
|
|
|
@ -304,6 +304,7 @@
|
||||||
#define CONFIG_SYS_FSL_ERRATUM_ESDHC136
|
#define CONFIG_SYS_FSL_ERRATUM_ESDHC136
|
||||||
#define CONFIG_SYS_P4080_ERRATUM_CPU22
|
#define CONFIG_SYS_P4080_ERRATUM_CPU22
|
||||||
#define CONFIG_SYS_P4080_ERRATUM_SERDES8
|
#define CONFIG_SYS_P4080_ERRATUM_SERDES8
|
||||||
|
#define CONFIG_SYS_P4080_ERRATUM_SERDES9
|
||||||
|
|
||||||
/* P5010 is single core version of P5020 */
|
/* P5010 is single core version of P5020 */
|
||||||
#elif defined(CONFIG_PPC_P5010)
|
#elif defined(CONFIG_PPC_P5010)
|
||||||
|
|
|
@ -55,6 +55,9 @@ void fsl_serdes_init(void);
|
||||||
|
|
||||||
#ifdef CONFIG_FSL_CORENET
|
#ifdef CONFIG_FSL_CORENET
|
||||||
int serdes_get_first_lane(enum srds_prtcl device);
|
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
|
||||||
|
|
||||||
#endif /* __FSL_SERDES_H */
|
#endif /* __FSL_SERDES_H */
|
||||||
|
|
|
@ -2137,6 +2137,8 @@ typedef struct serdes_corenet {
|
||||||
#define SRDS_TECR0_TEQ_TYPE_2LVL 0x10000000
|
#define SRDS_TECR0_TEQ_TYPE_2LVL 0x10000000
|
||||||
u32 res3;
|
u32 res3;
|
||||||
u32 ttlcr0; /* Transition Tracking Loop Ctrl 0 */
|
u32 ttlcr0; /* Transition Tracking Loop Ctrl 0 */
|
||||||
|
#define SRDS_TTLCR0_FLT_SEL_MASK 0x3f000000
|
||||||
|
#define SRDS_TTLCR0_PM_DIS 0x00004000
|
||||||
u32 res4[7];
|
u32 res4[7];
|
||||||
} lane[24];
|
} lane[24];
|
||||||
u32 res6[384];
|
u32 res6[384];
|
||||||
|
|
Loading…
Add table
Reference in a new issue