uboot/arch/powerpc/cpu/mpc85xx/p1022_serdes.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 * Copyright 2010 Freescale Semiconductor, Inc.
   4 * Author: Timur Tabi <timur@freescale.com>
   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         4
  14#define SRDS2_MAX_LANES         2
  15
  16static u32 serdes1_prtcl_map, serdes2_prtcl_map;
  17
  18static const u8 serdes1_cfg_tbl[][SRDS1_MAX_LANES] = {
  19        [0x00] = {NONE, NONE, NONE, NONE},
  20        [0x01] = {NONE, NONE, NONE, NONE},
  21        [0x02] = {NONE, NONE, NONE, NONE},
  22        [0x03] = {NONE, NONE, NONE, NONE},
  23        [0x04] = {NONE, NONE, NONE, NONE},
  24        [0x06] = {PCIE1, PCIE3, SGMII_TSEC1, PCIE2},
  25        [0x07] = {PCIE1, PCIE3, SGMII_TSEC1, PCIE2},
  26        [0x09] = {PCIE1, NONE, NONE, NONE},
  27        [0x0a] = {PCIE1, PCIE3, SGMII_TSEC1, SGMII_TSEC2},
  28        [0x0b] = {PCIE1, PCIE3, SGMII_TSEC1, SGMII_TSEC2},
  29        [0x0d] = {PCIE1, PCIE1, SGMII_TSEC1, SGMII_TSEC2},
  30        [0x0e] = {PCIE1, PCIE1, SGMII_TSEC1, SGMII_TSEC2},
  31        [0x0f] = {PCIE1, PCIE1, SGMII_TSEC1, SGMII_TSEC2},
  32        [0x15] = {PCIE1, PCIE3, PCIE2, PCIE2},
  33        [0x16] = {PCIE1, PCIE3, PCIE2, PCIE2},
  34        [0x17] = {PCIE1, PCIE3, PCIE2, PCIE2},
  35        [0x18] = {PCIE1, PCIE1, PCIE2, PCIE2},
  36        [0x19] = {PCIE1, PCIE1, PCIE2, PCIE2},
  37        [0x1a] = {PCIE1, PCIE1, PCIE2, PCIE2},
  38        [0x1b] = {PCIE1, PCIE1, PCIE2, PCIE2},
  39        [0x1c] = {PCIE1, PCIE1, PCIE1, PCIE1},
  40        [0x1d] = {PCIE1, PCIE1, PCIE2, PCIE2},
  41        [0x1e] = {PCIE1, PCIE1, PCIE2, PCIE2},
  42        [0x1f] = {PCIE1, PCIE1, PCIE2, PCIE2},
  43};
  44
  45static const u8 serdes2_cfg_tbl[][SRDS2_MAX_LANES] = {
  46        [0x00] = {PCIE3, PCIE3},
  47        [0x01] = {PCIE2, PCIE3},
  48        [0x02] = {SATA1, SATA2},
  49        [0x03] = {SGMII_TSEC1, SGMII_TSEC2},
  50        [0x04] = {NONE, NONE},
  51        [0x06] = {SATA1, SATA2},
  52        [0x07] = {NONE, NONE},
  53        [0x09] = {PCIE3, PCIE2},
  54        [0x0a] = {SATA1, SATA2},
  55        [0x0b] = {NONE, NONE},
  56        [0x0d] = {PCIE3, PCIE2},
  57        [0x0e] = {SATA1, SATA2},
  58        [0x0f] = {NONE, NONE},
  59        [0x15] = {SGMII_TSEC1, SGMII_TSEC2},
  60        [0x16] = {SATA1, SATA2},
  61        [0x17] = {NONE, NONE},
  62        [0x18] = {PCIE3, PCIE3},
  63        [0x19] = {SGMII_TSEC1, SGMII_TSEC2},
  64        [0x1a] = {SATA1, SATA2},
  65        [0x1b] = {NONE, NONE},
  66        [0x1c] = {PCIE3, PCIE3},
  67        [0x1d] = {SGMII_TSEC1, SGMII_TSEC2},
  68        [0x1e] = {SATA1, SATA2},
  69        [0x1f] = {NONE, NONE},
  70};
  71
  72int is_serdes_configured(enum srds_prtcl device)
  73{
  74        int ret;
  75
  76        if (!(serdes1_prtcl_map & (1 << NONE)))
  77                fsl_serdes_init();
  78
  79        ret = (1 << device) & serdes1_prtcl_map;
  80
  81        if (ret)
  82                return ret;
  83
  84        if (!(serdes2_prtcl_map & (1 << NONE)))
  85                fsl_serdes_init();
  86
  87        return (1 << device) & serdes2_prtcl_map;
  88}
  89
  90void fsl_serdes_init(void)
  91{
  92        ccsr_gur_t *gur = (void *)CONFIG_SYS_MPC85xx_GUTS_ADDR;
  93        u32 pordevsr = in_be32(&gur->pordevsr);
  94        u32 srds_cfg = (pordevsr & MPC85xx_PORDEVSR_IO_SEL) >>
  95                                MPC85xx_PORDEVSR_IO_SEL_SHIFT;
  96        int lane;
  97
  98        if (serdes1_prtcl_map & (1 << NONE) &&
  99            serdes2_prtcl_map & (1 << NONE))
 100                return;
 101
 102        debug("PORDEVSR[IO_SEL_SRDS] = %x\n", srds_cfg);
 103
 104        if (srds_cfg >= ARRAY_SIZE(serdes1_cfg_tbl)) {
 105                printf("Invalid PORDEVSR[IO_SEL_SRDS] = %d\n", srds_cfg);
 106                return;
 107        }
 108        for (lane = 0; lane < SRDS1_MAX_LANES; lane++) {
 109                enum srds_prtcl lane_prtcl = serdes1_cfg_tbl[srds_cfg][lane];
 110                serdes1_prtcl_map |= (1 << lane_prtcl);
 111        }
 112
 113        /* Set the first bit to indicate serdes has been initialized */
 114        serdes1_prtcl_map |= (1 << NONE);
 115
 116        if (srds_cfg >= ARRAY_SIZE(serdes2_cfg_tbl)) {
 117                printf("Invalid PORDEVSR[IO_SEL_SRDS] = %d\n", srds_cfg);
 118                return;
 119        }
 120
 121        for (lane = 0; lane < SRDS2_MAX_LANES; lane++) {
 122                enum srds_prtcl lane_prtcl = serdes2_cfg_tbl[srds_cfg][lane];
 123                serdes2_prtcl_map |= (1 << lane_prtcl);
 124        }
 125
 126        /* Set the first bit to indicate serdes has been initialized */
 127        serdes2_prtcl_map |= (1 << NONE);
 128}
 129