uboot/arch/arm/cpu/armv7/ls102xa/fsl_ls1_serdes.c
<<
>>
Prefs
   1/*
   2 * Copyright 2014 Freescale Semiconductor, Inc.
   3 *
   4 * SPDX-License-Identifier:     GPL-2.0+
   5 */
   6
   7#include <common.h>
   8#include <asm/arch/fsl_serdes.h>
   9#include <asm/arch/immap_ls102xa.h>
  10#include <linux/errno.h>
  11#include <asm/io.h>
  12#include "fsl_ls1_serdes.h"
  13
  14#ifdef CONFIG_SYS_FSL_SRDS_1
  15static u64 serdes1_prtcl_map;
  16#endif
  17#ifdef CONFIG_SYS_FSL_SRDS_2
  18static u64 serdes2_prtcl_map;
  19#endif
  20
  21int is_serdes_configured(enum srds_prtcl device)
  22{
  23        u64 ret = 0;
  24
  25#ifdef CONFIG_SYS_FSL_SRDS_1
  26        if (!(serdes1_prtcl_map & (1ULL << NONE)))
  27                fsl_serdes_init();
  28
  29        ret |= (1ULL << device) & serdes1_prtcl_map;
  30#endif
  31#ifdef CONFIG_SYS_FSL_SRDS_2
  32        if (!(serdes2_prtcl_map & (1ULL << NONE)))
  33                fsl_serdes_init();
  34
  35        ret |= (1ULL << device) & serdes2_prtcl_map;
  36#endif
  37
  38        return !!ret;
  39}
  40
  41int serdes_get_first_lane(u32 sd, enum srds_prtcl device)
  42{
  43        struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR);
  44        u32 cfg = in_be32(&gur->rcwsr[4]);
  45        int i;
  46
  47        switch (sd) {
  48#ifdef CONFIG_SYS_FSL_SRDS_1
  49        case FSL_SRDS_1:
  50                cfg &= RCWSR4_SRDS1_PRTCL_MASK;
  51                cfg >>= RCWSR4_SRDS1_PRTCL_SHIFT;
  52                break;
  53#endif
  54#ifdef CONFIG_SYS_FSL_SRDS_2
  55        case FSL_SRDS_2:
  56                cfg &= RCWSR4_SRDS2_PRTCL_MASK;
  57                cfg >>= RCWSR4_SRDS2_PRTCL_SHIFT;
  58                break;
  59#endif
  60        default:
  61                printf("invalid SerDes%d\n", sd);
  62                break;
  63        }
  64        /* Is serdes enabled at all? */
  65        if (unlikely(cfg == 0))
  66                return -ENODEV;
  67
  68        for (i = 0; i < SRDS_MAX_LANES; i++) {
  69                if (serdes_get_prtcl(sd, cfg, i) == device)
  70                        return i;
  71        }
  72
  73        return -ENODEV;
  74}
  75
  76u64 serdes_init(u32 sd, u32 sd_addr, u32 sd_prctl_mask, u32 sd_prctl_shift)
  77{
  78        struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR);
  79        u64 serdes_prtcl_map = 0;
  80        u32 cfg;
  81        int lane;
  82
  83        cfg = in_be32(&gur->rcwsr[4]) & sd_prctl_mask;
  84        cfg >>= sd_prctl_shift;
  85        printf("Using SERDES%d Protocol: %d (0x%x)\n", sd + 1, cfg, cfg);
  86
  87        if (!is_serdes_prtcl_valid(sd, cfg))
  88                printf("SERDES%d[PRTCL] = 0x%x is not valid\n", sd + 1, cfg);
  89
  90        for (lane = 0; lane < SRDS_MAX_LANES; lane++) {
  91                enum srds_prtcl lane_prtcl = serdes_get_prtcl(sd, cfg, lane);
  92
  93                serdes_prtcl_map |= (1ULL << lane_prtcl);
  94        }
  95
  96        /* Set the first bit to indicate serdes has been initialized */
  97        serdes_prtcl_map |= (1ULL << NONE);
  98
  99        return serdes_prtcl_map;
 100}
 101
 102void fsl_serdes_init(void)
 103{
 104#ifdef CONFIG_SYS_FSL_SRDS_1
 105        if (!(serdes1_prtcl_map & (1ULL << NONE)))
 106                serdes1_prtcl_map = serdes_init(FSL_SRDS_1,
 107                                        CONFIG_SYS_FSL_SERDES_ADDR,
 108                                        RCWSR4_SRDS1_PRTCL_MASK,
 109                                        RCWSR4_SRDS1_PRTCL_SHIFT);
 110#endif
 111#ifdef CONFIG_SYS_FSL_SRDS_2
 112        if (!(serdes2_prtcl_map & (1ULL << NONE)))
 113                serdes2_prtcl_map = serdes_init(FSL_SRDS_2,
 114                                        CONFIG_SYS_FSL_SERDES_ADDR +
 115                                        FSL_SRDS_2 * 0x1000,
 116                                        RCWSR4_SRDS2_PRTCL_MASK,
 117                                        RCWSR4_SRDS2_PRTCL_SHIFT);
 118#endif
 119}
 120
 121const char *serdes_clock_to_string(u32 clock)
 122{
 123        switch (clock) {
 124        case SRDS_PLLCR0_RFCK_SEL_100:
 125                return "100";
 126        case SRDS_PLLCR0_RFCK_SEL_125:
 127                return "125";
 128        default:
 129                return "100";
 130        }
 131}
 132