mirror of
https://github.com/AsahiLinux/u-boot
synced 2024-11-28 07:31:15 +00:00
armv8: Add SerDes framework for Layerscape Architecture
Add support of SerDes framework for Layerscape Architecture. - Add support of 2 SerDes block - Add SerDes protocol parsing and detection - Create table of SerDes protocol supported by LS2085A Signed-off-by: Prabhakar Kushwaha <prabhakar@freescale.com> Signed-off-by: Minghuan Lian <Minghuan.Lian@freescale.com> Reviewed-by: York Sun <yorksun@freescale.com>
This commit is contained in:
parent
5753b0f1b0
commit
31d34c6c4b
8 changed files with 313 additions and 0 deletions
|
@ -8,5 +8,6 @@ obj-y += cpu.o
|
|||
obj-y += lowlevel.o
|
||||
obj-y += soc.o
|
||||
obj-y += speed.o
|
||||
obj-$(CONFIG_SYS_HAS_SERDES) += fsl_lsch3_serdes.o ls2085a_serdes.o
|
||||
obj-$(CONFIG_MP) += mp.o
|
||||
obj-$(CONFIG_OF_LIBFDT) += fdt.o
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
#include <asm/arch-fsl-lsch3/immap_lsch3.h>
|
||||
#include <fsl_debug_server.h>
|
||||
#include <fsl-mc/fsl_mc.h>
|
||||
#include <asm/arch/fsl_serdes.h>
|
||||
#include "cpu.h"
|
||||
#include "mp.h"
|
||||
#include "speed.h"
|
||||
|
@ -415,6 +416,9 @@ int arch_early_init_r(void)
|
|||
if (rv)
|
||||
printf("Did not wake secondary cores\n");
|
||||
|
||||
#ifdef CONFIG_SYS_HAS_SERDES
|
||||
fsl_serdes_init();
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
110
arch/arm/cpu/armv8/fsl-lsch3/fsl_lsch3_serdes.c
Normal file
110
arch/arm/cpu/armv8/fsl-lsch3/fsl_lsch3_serdes.c
Normal file
|
@ -0,0 +1,110 @@
|
|||
/*
|
||||
* Copyright 2015 Freescale Semiconductor, Inc.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/errno.h>
|
||||
#include <asm/arch/fsl_serdes.h>
|
||||
#include <asm/arch-fsl-lsch3/immap_lsch3.h>
|
||||
|
||||
#ifdef CONFIG_SYS_FSL_SRDS_1
|
||||
static u8 serdes1_prtcl_map[SERDES_PRCTL_COUNT];
|
||||
#endif
|
||||
#ifdef CONFIG_SYS_FSL_SRDS_2
|
||||
static u8 serdes2_prtcl_map[SERDES_PRCTL_COUNT];
|
||||
#endif
|
||||
|
||||
int is_serdes_configured(enum srds_prtcl device)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
#ifdef CONFIG_SYS_FSL_SRDS_1
|
||||
ret |= serdes1_prtcl_map[device];
|
||||
#endif
|
||||
#ifdef CONFIG_SYS_FSL_SRDS_2
|
||||
ret |= serdes2_prtcl_map[device];
|
||||
#endif
|
||||
|
||||
return !!ret;
|
||||
}
|
||||
|
||||
int serdes_get_first_lane(u32 sd, enum srds_prtcl device)
|
||||
{
|
||||
struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR);
|
||||
u32 cfg = in_le32(&gur->rcwsr[28]);
|
||||
int i;
|
||||
|
||||
switch (sd) {
|
||||
#ifdef CONFIG_SYS_FSL_SRDS_1
|
||||
case FSL_SRDS_1:
|
||||
cfg &= FSL_CHASSIS3_RCWSR28_SRDS1_PRTCL_MASK;
|
||||
cfg >>= FSL_CHASSIS3_RCWSR28_SRDS1_PRTCL_SHIFT;
|
||||
break;
|
||||
#endif
|
||||
#ifdef CONFIG_SYS_FSL_SRDS_2
|
||||
case FSL_SRDS_2:
|
||||
cfg &= FSL_CHASSIS3_RCWSR28_SRDS2_PRTCL_MASK;
|
||||
cfg >>= FSL_CHASSIS3_RCWSR28_SRDS2_PRTCL_SHIFT;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
printf("invalid SerDes%d\n", sd);
|
||||
break;
|
||||
}
|
||||
/* Is serdes enabled at all? */
|
||||
if (cfg == 0)
|
||||
return -ENODEV;
|
||||
|
||||
for (i = 0; i < SRDS_MAX_LANES; i++) {
|
||||
if (serdes_get_prtcl(sd, cfg, i) == device)
|
||||
return i;
|
||||
}
|
||||
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
void serdes_init(u32 sd, u32 sd_addr, u32 sd_prctl_mask, u32 sd_prctl_shift,
|
||||
u8 serdes_prtcl_map[SERDES_PRCTL_COUNT])
|
||||
{
|
||||
struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR);
|
||||
u32 cfg;
|
||||
int lane;
|
||||
|
||||
memset(serdes_prtcl_map, 0, sizeof(serdes_prtcl_map));
|
||||
|
||||
cfg = in_le32(&gur->rcwsr[28]) & sd_prctl_mask;
|
||||
cfg >>= sd_prctl_shift;
|
||||
printf("Using SERDES%d Protocol: %d (0x%x)\n", sd + 1, cfg, cfg);
|
||||
|
||||
if (!is_serdes_prtcl_valid(sd, cfg))
|
||||
printf("SERDES%d[PRTCL] = 0x%x is not valid\n", sd + 1, cfg);
|
||||
|
||||
for (lane = 0; lane < SRDS_MAX_LANES; lane++) {
|
||||
enum srds_prtcl lane_prtcl = serdes_get_prtcl(sd, cfg, lane);
|
||||
if (unlikely(lane_prtcl >= SERDES_PRCTL_COUNT))
|
||||
debug("Unknown SerDes lane protocol %d\n", lane_prtcl);
|
||||
else
|
||||
serdes_prtcl_map[lane_prtcl] = 1;
|
||||
}
|
||||
}
|
||||
|
||||
void fsl_serdes_init(void)
|
||||
{
|
||||
#ifdef CONFIG_SYS_FSL_SRDS_1
|
||||
serdes_init(FSL_SRDS_1,
|
||||
CONFIG_SYS_FSL_LSCH3_SERDES_ADDR,
|
||||
FSL_CHASSIS3_RCWSR28_SRDS1_PRTCL_MASK,
|
||||
FSL_CHASSIS3_RCWSR28_SRDS1_PRTCL_SHIFT,
|
||||
serdes1_prtcl_map);
|
||||
#endif
|
||||
#ifdef CONFIG_SYS_FSL_SRDS_2
|
||||
serdes_init(FSL_SRDS_2,
|
||||
CONFIG_SYS_FSL_LSCH3_SERDES_ADDR + FSL_SRDS_2 * 0x10000,
|
||||
FSL_CHASSIS3_RCWSR28_SRDS2_PRTCL_MASK,
|
||||
FSL_CHASSIS3_RCWSR28_SRDS2_PRTCL_SHIFT,
|
||||
serdes2_prtcl_map);
|
||||
#endif
|
||||
}
|
117
arch/arm/cpu/armv8/fsl-lsch3/ls2085a_serdes.c
Normal file
117
arch/arm/cpu/armv8/fsl-lsch3/ls2085a_serdes.c
Normal file
|
@ -0,0 +1,117 @@
|
|||
/*
|
||||
* Copyright 2015 Freescale Semiconductor, Inc.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <asm/arch/fsl_serdes.h>
|
||||
#include <asm/arch-fsl-lsch3/immap_lsch3.h>
|
||||
|
||||
struct serdes_config {
|
||||
u8 protocol;
|
||||
u8 lanes[SRDS_MAX_LANES];
|
||||
};
|
||||
|
||||
static struct serdes_config serdes1_cfg_tbl[] = {
|
||||
/* SerDes 1 */
|
||||
{0x03, {PCIE1, PCIE1, PCIE1, PCIE1, PCIE2, PCIE2, PCIE2, PCIE2 } },
|
||||
{0x05, {PCIE2, PCIE2, PCIE2, PCIE2, SGMII4, SGMII3, SGMII2, SGMII1 } },
|
||||
{0x07, {SGMII8, SGMII7, SGMII6, SGMII5, SGMII4, SGMII3, SGMII2,
|
||||
SGMII1 } },
|
||||
{0x09, {SGMII8, SGMII7, SGMII6, SGMII5, SGMII4, SGMII3, SGMII2,
|
||||
SGMII1 } },
|
||||
{0x0A, {SGMII8, SGMII7, SGMII6, SGMII5, SGMII4, SGMII3, SGMII2,
|
||||
SGMII1 } },
|
||||
{0x0C, {SGMII8, SGMII7, SGMII6, SGMII5, SGMII4, SGMII3, SGMII2,
|
||||
SGMII1 } },
|
||||
{0x0E, {SGMII8, SGMII7, SGMII6, SGMII5, SGMII4, SGMII3, SGMII2,
|
||||
SGMII1 } },
|
||||
{0x26, {SGMII8, SGMII7, SGMII6, SGMII5, SGMII4, SGMII3, XFI2, XFI1 } },
|
||||
{0x28, {SGMII8, SGMII7, SGMII6, SGMII5, XFI4, XFI3, XFI2, XFI1 } },
|
||||
{0x2A, {XFI8, XFI7, XFI6, XFI5, XFI4, XFI3, XFI2, XFI1 } },
|
||||
{0x2B, {SGMII8, SGMII7, SGMII6, SGMII5, XAUI1, XAUI1, XAUI1, XAUI1 } },
|
||||
{0x32, {XAUI2, XAUI2, XAUI2, XAUI2, XAUI1, XAUI1, XAUI1, XAUI1 } },
|
||||
{0x33, {PCIE2, PCIE2, PCIE2, PCIE2, QSGMII_D, QSGMII_C, QSGMII_B,
|
||||
QSGMII_A} },
|
||||
{0x35, {QSGMII_D, QSGMII_C, QSGMII_B, PCIE2, XFI4, XFI3, XFI2, XFI1 } },
|
||||
{}
|
||||
};
|
||||
static struct serdes_config serdes2_cfg_tbl[] = {
|
||||
/* SerDes 2 */
|
||||
{0x07, {SGMII9, SGMII10, SGMII11, SGMII12, SGMII13, SGMII14, SGMII15,
|
||||
SGMII16 } },
|
||||
{0x09, {SGMII9, SGMII10, SGMII11, SGMII12, SGMII13, SGMII14, SGMII15,
|
||||
SGMII16 } },
|
||||
{0x0A, {SGMII9, SGMII10, SGMII11, SGMII12, SGMII13, SGMII14, SGMII15,
|
||||
SGMII16 } },
|
||||
{0x0C, {SGMII9, SGMII10, SGMII11, SGMII12, SGMII13, SGMII14, SGMII15,
|
||||
SGMII16 } },
|
||||
{0x0E, {SGMII9, SGMII10, SGMII11, SGMII12, SGMII13, SGMII14, SGMII15,
|
||||
SGMII16 } },
|
||||
{0x3D, {PCIE3, PCIE3, PCIE3, PCIE3, PCIE3, PCIE3, PCIE3, PCIE3 } },
|
||||
{0x3E, {PCIE3, PCIE3, PCIE3, PCIE3, PCIE3, PCIE3, PCIE3, PCIE3 } },
|
||||
{0x3F, {PCIE3, PCIE3, PCIE3, PCIE3, PCIE4, PCIE4, PCIE4, PCIE4 } },
|
||||
{0x40, {PCIE3, PCIE3, PCIE3, PCIE3, PCIE4, PCIE4, PCIE4, PCIE4 } },
|
||||
{0x41, {PCIE3, PCIE3, PCIE3, PCIE3, PCIE4, PCIE4, SATA1, SATA2 } },
|
||||
{0x42, {PCIE3, PCIE3, PCIE3, PCIE3, PCIE4, PCIE4, SATA1, SATA2 } },
|
||||
{0x43, {PCIE3, PCIE3, PCIE3, PCIE3, NONE, NONE, SATA1, SATA2 } },
|
||||
{0x44, {PCIE3, PCIE3, PCIE3, PCIE3, NONE, NONE, SATA1, SATA2 } },
|
||||
{0x45, {PCIE3, SGMII10, SGMII11, SGMII12, PCIE4, SGMII14, SGMII15,
|
||||
SGMII16 } },
|
||||
{0x47, {SGMII9, SGMII10, SGMII11, SGMII12, PCIE4, PCIE4, PCIE4,
|
||||
PCIE4 } },
|
||||
{0x49, {SGMII9, SGMII10, SGMII11, SGMII12, PCIE4, PCIE4, SATA1,
|
||||
SATA2 } },
|
||||
{0x4A, {SGMII9, SGMII10, SGMII11, SGMII12, PCIE4, PCIE4, SATA1,
|
||||
SATA2 } },
|
||||
{}
|
||||
};
|
||||
|
||||
static struct serdes_config *serdes_cfg_tbl[] = {
|
||||
serdes1_cfg_tbl,
|
||||
serdes2_cfg_tbl,
|
||||
};
|
||||
|
||||
enum srds_prtcl serdes_get_prtcl(int serdes, int cfg, int lane)
|
||||
{
|
||||
struct serdes_config *ptr;
|
||||
|
||||
if (serdes >= ARRAY_SIZE(serdes_cfg_tbl))
|
||||
return 0;
|
||||
|
||||
ptr = serdes_cfg_tbl[serdes];
|
||||
while (ptr->protocol) {
|
||||
if (ptr->protocol == cfg)
|
||||
return ptr->lanes[lane];
|
||||
ptr++;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int is_serdes_prtcl_valid(int serdes, u32 prtcl)
|
||||
{
|
||||
int i;
|
||||
struct serdes_config *ptr;
|
||||
|
||||
if (serdes >= ARRAY_SIZE(serdes_cfg_tbl))
|
||||
return 0;
|
||||
|
||||
ptr = serdes_cfg_tbl[serdes];
|
||||
while (ptr->protocol) {
|
||||
if (ptr->protocol == prtcl)
|
||||
break;
|
||||
ptr++;
|
||||
}
|
||||
|
||||
if (!ptr->protocol)
|
||||
return 0;
|
||||
|
||||
for (i = 0; i < SRDS_MAX_LANES; i++) {
|
||||
if (ptr->lanes[i] != NONE)
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -38,6 +38,8 @@
|
|||
#define CONFIG_SYS_FSL_PMU_CLTBENR (CONFIG_SYS_FSL_PMU_ADDR + \
|
||||
0x18A0)
|
||||
|
||||
#define CONFIG_SYS_FSL_LSCH3_SERDES_ADDR (CONFIG_SYS_IMMR + 0xEA0000)
|
||||
|
||||
/* SP (Cortex-A5) related */
|
||||
#define CONFIG_SYS_FSL_SP_ADDR (CONFIG_SYS_IMMR + 0x00F00000)
|
||||
#define CONFIG_SYS_FSL_SP_VSG_GIC_ADDR (CONFIG_SYS_FSL_SP_ADDR)
|
||||
|
@ -133,6 +135,8 @@
|
|||
#define CONFIG_SYS_FSL_IFC_BANK_COUNT 8
|
||||
#define CONFIG_NUM_DDR_CONTROLLERS 3
|
||||
#define CONFIG_SYS_FSL_CLUSTER_CLOCKS { 1, 1, 4, 4 }
|
||||
#define CONFIG_SYS_FSL_SRDS_1
|
||||
#define CONFIG_SYS_FSL_SRDS_2
|
||||
#else
|
||||
#error SoC not defined
|
||||
#endif
|
||||
|
|
67
arch/arm/include/asm/arch-fsl-lsch3/fsl_serdes.h
Normal file
67
arch/arm/include/asm/arch-fsl-lsch3/fsl_serdes.h
Normal file
|
@ -0,0 +1,67 @@
|
|||
/*
|
||||
* Copyright 2015 Freescale Semiconductor, Inc.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
#ifndef __FSL_SERDES_H
|
||||
#define __FSL_SERDES_H
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#define SRDS_MAX_LANES 8
|
||||
|
||||
enum srds_prtcl {
|
||||
NONE = 0,
|
||||
PCIE1,
|
||||
PCIE2,
|
||||
PCIE3,
|
||||
PCIE4,
|
||||
SATA1,
|
||||
SATA2,
|
||||
XAUI1,
|
||||
XAUI2,
|
||||
XFI1,
|
||||
XFI2,
|
||||
XFI3,
|
||||
XFI4,
|
||||
XFI5,
|
||||
XFI6,
|
||||
XFI7,
|
||||
XFI8,
|
||||
SGMII1,
|
||||
SGMII2,
|
||||
SGMII3,
|
||||
SGMII4,
|
||||
SGMII5,
|
||||
SGMII6,
|
||||
SGMII7,
|
||||
SGMII8,
|
||||
SGMII9,
|
||||
SGMII10,
|
||||
SGMII11,
|
||||
SGMII12,
|
||||
SGMII13,
|
||||
SGMII14,
|
||||
SGMII15,
|
||||
SGMII16,
|
||||
QSGMII_A, /* A indicates MACs 1-4 */
|
||||
QSGMII_B, /* B indicates MACs 5-8 */
|
||||
QSGMII_C, /* C indicates MACs 9-12 */
|
||||
QSGMII_D, /* D indicates MACs 12-16 */
|
||||
SERDES_PRCTL_COUNT
|
||||
};
|
||||
|
||||
enum srds {
|
||||
FSL_SRDS_1 = 0,
|
||||
FSL_SRDS_2 = 1,
|
||||
};
|
||||
|
||||
int is_serdes_configured(enum srds_prtcl device);
|
||||
void fsl_serdes_init(void);
|
||||
|
||||
int serdes_get_first_lane(u32 sd, enum srds_prtcl device);
|
||||
enum srds_prtcl serdes_get_prtcl(int serdes, int cfg, int lane);
|
||||
int is_serdes_prtcl_valid(int serdes, u32 prtcl);
|
||||
|
||||
#endif /* __FSL_SERDES_H */
|
|
@ -63,6 +63,11 @@ struct ccsr_gur {
|
|||
#define FSL_CHASSIS3_RCWSR0_MEM_PLL_RAT_MASK 0x3f
|
||||
#define FSL_CHASSIS3_RCWSR0_MEM2_PLL_RAT_SHIFT 18
|
||||
#define FSL_CHASSIS3_RCWSR0_MEM2_PLL_RAT_MASK 0x3f
|
||||
#define FSL_CHASSIS3_RCWSR28_SRDS1_PRTCL_MASK 0x00FF0000
|
||||
#define FSL_CHASSIS3_RCWSR28_SRDS1_PRTCL_SHIFT 16
|
||||
#define FSL_CHASSIS3_RCWSR28_SRDS2_PRTCL_MASK 0xFF000000
|
||||
#define FSL_CHASSIS3_RCWSR28_SRDS2_PRTCL_SHIFT 24
|
||||
|
||||
u8 res_180[0x200-0x180];
|
||||
u32 scratchrw[32]; /* Scratch Read/Write */
|
||||
u8 res_280[0x300-0x280];
|
||||
|
|
|
@ -19,6 +19,11 @@
|
|||
#define CONFIG_ARM_ERRATA_828024
|
||||
#define CONFIG_ARM_ERRATA_826974
|
||||
|
||||
#include <asm/arch-fsl-lsch3/config.h>
|
||||
#if (defined(CONFIG_SYS_FSL_SRDS_1) || defined(CONFIG_SYS_FSL_SRDS_2))
|
||||
#define CONFIG_SYS_HAS_SERDES
|
||||
#endif
|
||||
|
||||
/* We need architecture specific misc initializations */
|
||||
#define CONFIG_ARCH_MISC_INIT
|
||||
|
||||
|
|
Loading…
Reference in a new issue