uboot/arch/powerpc/cpu/mpc85xx/mpc8544_serdes.c
<<
>>
Prefs
   1/*
   2 * Copyright 2010 Freescale Semiconductor, Inc.
   3 *
   4 * SPDX-License-Identifier:     GPL-2.0+
   5 */
   6
   7#include <config.h>
   8#include <common.h>
   9#include <asm/io.h>
  10#include <asm/immap_85xx.h>
  11#include <asm/fsl_serdes.h>
  12
  13#define SRDS1_MAX_LANES         8
  14#define SRDS2_MAX_LANES         4
  15
  16static u32 serdes1_prtcl_map, serdes2_prtcl_map;
  17
  18static u8 serdes1_cfg_tbl[][SRDS1_MAX_LANES] = {
  19        [0x2] = {PCIE1, PCIE1, PCIE1, PCIE1, NONE, NONE, NONE, NONE},
  20        [0x3] = {PCIE1, PCIE1, PCIE1, PCIE1, NONE, NONE, NONE, NONE},
  21        [0x4] = {PCIE1, PCIE1, PCIE1, PCIE1, PCIE2, PCIE2, PCIE2, PCIE2},
  22        [0x5] = {PCIE1, PCIE1, PCIE1, PCIE1, PCIE2, PCIE2, PCIE2, PCIE2},
  23        [0x6] = {PCIE1, PCIE1, PCIE1, PCIE1, PCIE2, PCIE2, PCIE2, PCIE2},
  24        [0x7] = {PCIE1, PCIE1, PCIE1, PCIE1, PCIE2, PCIE2, PCIE2, PCIE2},
  25};
  26
  27static u8 serdes2_cfg_tbl[][SRDS2_MAX_LANES] = {
  28        [0x1] = {NONE, NONE, SGMII_TSEC1, SGMII_TSEC3},
  29        [0x3] = {NONE, NONE, SGMII_TSEC1, SGMII_TSEC3},
  30        [0x5] = {NONE, NONE, SGMII_TSEC1, SGMII_TSEC3},
  31        [0x6] = {PCIE3, NONE, NONE, NONE},
  32        [0x7] = {PCIE3, NONE, SGMII_TSEC1, SGMII_TSEC3},
  33};
  34
  35int is_serdes_configured(enum srds_prtcl device)
  36{
  37        int ret;
  38
  39        if (!(serdes1_prtcl_map & (1 << NONE)))
  40                fsl_serdes_init();
  41
  42        ret = (1 << device) & serdes1_prtcl_map;
  43
  44        if (ret)
  45                return ret;
  46
  47        if (!(serdes2_prtcl_map & (1 << NONE)))
  48                fsl_serdes_init();
  49
  50        return (1 << device) & serdes2_prtcl_map;
  51}
  52
  53void fsl_serdes_init(void)
  54{
  55        ccsr_gur_t *gur = (void *)CONFIG_SYS_MPC85xx_GUTS_ADDR;
  56        u32 pordevsr = in_be32(&gur->pordevsr);
  57        u32 srds_cfg = (pordevsr & MPC85xx_PORDEVSR_IO_SEL) >>
  58                                MPC85xx_PORDEVSR_IO_SEL_SHIFT;
  59        int lane;
  60
  61        if (serdes1_prtcl_map & (1 << NONE) &&
  62            serdes2_prtcl_map & (1 << NONE))
  63                return;
  64
  65        debug("PORDEVSR[IO_SEL_SRDS] = %x\n", srds_cfg);
  66
  67        if (srds_cfg >= ARRAY_SIZE(serdes1_cfg_tbl)) {
  68                printf("Invalid PORDEVSR[IO_SEL_SRDS] = %d\n", srds_cfg);
  69                return;
  70        }
  71        for (lane = 0; lane < SRDS1_MAX_LANES; lane++) {
  72                enum srds_prtcl lane_prtcl = serdes1_cfg_tbl[srds_cfg][lane];
  73                serdes1_prtcl_map |= (1 << lane_prtcl);
  74        }
  75
  76        /* Set the first bit to indicate serdes has been initialized */
  77        serdes1_prtcl_map |= (1 << NONE);
  78
  79        if (srds_cfg >= ARRAY_SIZE(serdes2_cfg_tbl)) {
  80                printf("Invalid PORDEVSR[IO_SEL_SRDS] = %d\n", srds_cfg);
  81                return;
  82        }
  83
  84        for (lane = 0; lane < SRDS2_MAX_LANES; lane++) {
  85                enum srds_prtcl lane_prtcl = serdes2_cfg_tbl[srds_cfg][lane];
  86                serdes2_prtcl_map |= (1 << lane_prtcl);
  87        }
  88
  89        if (pordevsr & MPC85xx_PORDEVSR_SGMII1_DIS)
  90                serdes2_prtcl_map &= ~(1 << SGMII_TSEC1);
  91
  92        if (pordevsr & MPC85xx_PORDEVSR_SGMII3_DIS)
  93                serdes2_prtcl_map &= ~(1 << SGMII_TSEC3);
  94
  95        /* Set the first bit to indicate serdes has been initialized */
  96        serdes2_prtcl_map |= (1 << NONE);
  97}
  98