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