uboot/arch/powerpc/cpu/mpc85xx/p1022_serdes.c
<<
>>
Prefs
   1/*
   2 * Copyright 2010 Freescale Semiconductor, Inc.
   3 * Author: Timur Tabi <timur@freescale.com>
   4 *
   5 * This program is free software; you can redistribute it and/or modify it
   6 * under the terms of the GNU General Public License as published by the Free
   7 * Software Foundation; either version 2 of the License, or (at your option)
   8 * any later version.
   9 */
  10
  11#include <config.h>
  12#include <common.h>
  13#include <asm/io.h>
  14#include <asm/immap_85xx.h>
  15#include <asm/fsl_serdes.h>
  16
  17#define SRDS1_MAX_LANES         4
  18#define SRDS2_MAX_LANES         2
  19
  20static u32 serdes1_prtcl_map, serdes2_prtcl_map;
  21
  22static const u8 serdes1_cfg_tbl[][SRDS1_MAX_LANES] = {
  23        [0x00] = {NONE, NONE, NONE, NONE},
  24        [0x01] = {NONE, NONE, NONE, NONE},
  25        [0x02] = {NONE, NONE, NONE, NONE},
  26        [0x03] = {NONE, NONE, NONE, NONE},
  27        [0x04] = {NONE, NONE, NONE, NONE},
  28        [0x06] = {PCIE1, PCIE3, SGMII_TSEC1, PCIE2},
  29        [0x07] = {PCIE1, PCIE3, SGMII_TSEC1, PCIE2},
  30        [0x09] = {PCIE1, NONE, NONE, NONE},
  31        [0x0a] = {PCIE1, PCIE3, SGMII_TSEC1, SGMII_TSEC2},
  32        [0x0b] = {PCIE1, PCIE3, SGMII_TSEC1, SGMII_TSEC2},
  33        [0x0d] = {PCIE1, PCIE1, SGMII_TSEC1, SGMII_TSEC2},
  34        [0x0e] = {PCIE1, PCIE1, SGMII_TSEC1, SGMII_TSEC2},
  35        [0x0f] = {PCIE1, PCIE1, SGMII_TSEC1, SGMII_TSEC2},
  36        [0x15] = {PCIE1, PCIE3, PCIE2, PCIE2},
  37        [0x16] = {PCIE1, PCIE3, PCIE2, PCIE2},
  38        [0x17] = {PCIE1, PCIE3, PCIE2, PCIE2},
  39        [0x18] = {PCIE1, PCIE1, PCIE2, PCIE2},
  40        [0x19] = {PCIE1, PCIE1, PCIE2, PCIE2},
  41        [0x1a] = {PCIE1, PCIE1, PCIE2, PCIE2},
  42        [0x1b] = {PCIE1, PCIE1, PCIE2, PCIE2},
  43        [0x1c] = {PCIE1, PCIE1, PCIE1, PCIE1},
  44        [0x1d] = {PCIE1, PCIE1, PCIE2, PCIE2},
  45        [0x1e] = {PCIE1, PCIE1, PCIE2, PCIE2},
  46        [0x1f] = {PCIE1, PCIE1, PCIE2, PCIE2},
  47};
  48
  49static const u8 serdes2_cfg_tbl[][SRDS2_MAX_LANES] = {
  50        [0x00] = {PCIE3, PCIE3},
  51        [0x01] = {PCIE2, PCIE3},
  52        [0x02] = {SATA1, SATA2},
  53        [0x03] = {SGMII_TSEC1, SGMII_TSEC2},
  54        [0x04] = {NONE, NONE},
  55        [0x06] = {SATA1, SATA2},
  56        [0x07] = {NONE, NONE},
  57        [0x09] = {PCIE3, PCIE2},
  58        [0x0a] = {SATA1, SATA2},
  59        [0x0b] = {NONE, NONE},
  60        [0x0d] = {PCIE3, PCIE2},
  61        [0x0e] = {SATA1, SATA2},
  62        [0x0f] = {NONE, NONE},
  63        [0x15] = {SGMII_TSEC1, SGMII_TSEC2},
  64        [0x16] = {SATA1, SATA2},
  65        [0x17] = {NONE, NONE},
  66        [0x18] = {PCIE3, PCIE3},
  67        [0x19] = {SGMII_TSEC1, SGMII_TSEC2},
  68        [0x1a] = {SATA1, SATA2},
  69        [0x1b] = {NONE, NONE},
  70        [0x1c] = {PCIE3, PCIE3},
  71        [0x1d] = {SGMII_TSEC1, SGMII_TSEC2},
  72        [0x1e] = {SATA1, SATA2},
  73        [0x1f] = {NONE, NONE},
  74};
  75
  76int is_serdes_configured(enum srds_prtcl device)
  77{
  78        int ret = (1 << device) & serdes1_prtcl_map;
  79
  80        if (ret)
  81                return ret;
  82
  83        return (1 << device) & serdes2_prtcl_map;
  84}
  85
  86void fsl_serdes_init(void)
  87{
  88        ccsr_gur_t *gur = (void *)CONFIG_SYS_MPC85xx_GUTS_ADDR;
  89        u32 pordevsr = in_be32(&gur->pordevsr);
  90        u32 srds_cfg = (pordevsr & MPC85xx_PORDEVSR_IO_SEL) >>
  91                                MPC85xx_PORDEVSR_IO_SEL_SHIFT;
  92        int lane;
  93
  94        debug("PORDEVSR[IO_SEL_SRDS] = %x\n", srds_cfg);
  95
  96        if (srds_cfg > ARRAY_SIZE(serdes1_cfg_tbl)) {
  97                printf("Invalid PORDEVSR[IO_SEL_SRDS] = %d\n", srds_cfg);
  98                return;
  99        }
 100        for (lane = 0; lane < SRDS1_MAX_LANES; lane++) {
 101                enum srds_prtcl lane_prtcl = serdes1_cfg_tbl[srds_cfg][lane];
 102                serdes1_prtcl_map |= (1 << lane_prtcl);
 103        }
 104
 105        if (srds_cfg > ARRAY_SIZE(serdes2_cfg_tbl)) {
 106                printf("Invalid PORDEVSR[IO_SEL_SRDS] = %d\n", srds_cfg);
 107                return;
 108        }
 109
 110        for (lane = 0; lane < SRDS2_MAX_LANES; lane++) {
 111                enum srds_prtcl lane_prtcl = serdes2_cfg_tbl[srds_cfg][lane];
 112                serdes2_prtcl_map |= (1 << lane_prtcl);
 113        }
 114}
 115