uboot/drivers/phy/marvell/comphy_mux.c
<<
>>
Prefs
   1/*
   2 * Copyright (C) 2015-2016 Marvell International Ltd.
   3 *
   4 * SPDX-License-Identifier:     GPL-2.0+
   5 */
   6
   7#include <common.h>
   8#include <asm/io.h>
   9
  10#include "comphy.h"
  11#include "comphy_hpipe.h"
  12
  13/*
  14 * comphy_mux_check_config()
  15 * description: this function passes over the COMPHY lanes and check if the type
  16 *              is valid for specific lane. If the type is not valid,
  17 *              the function update the struct and set the type of the lane as
  18 *              PHY_TYPE_UNCONNECTED
  19 */
  20static void comphy_mux_check_config(struct comphy_mux_data *mux_data,
  21                struct comphy_map *comphy_map_data, int comphy_max_lanes)
  22{
  23        struct comphy_mux_options *mux_opt;
  24        int lane, opt, valid;
  25
  26        debug_enter();
  27
  28        for (lane = 0; lane < comphy_max_lanes;
  29             lane++, comphy_map_data++, mux_data++) {
  30                /* Don't check ignored COMPHYs */
  31                if (comphy_map_data->type == PHY_TYPE_IGNORE)
  32                        continue;
  33
  34                mux_opt = mux_data->mux_values;
  35                for (opt = 0, valid = 0; opt < mux_data->max_lane_values;
  36                     opt++, mux_opt++) {
  37                        if (mux_opt->type == comphy_map_data->type) {
  38                                valid = 1;
  39                                break;
  40                        }
  41                }
  42                if (valid == 0) {
  43                        debug("lane number %d, had invalid type %d\n",
  44                              lane, comphy_map_data->type);
  45                        debug("set lane %d as type %d\n", lane,
  46                              PHY_TYPE_UNCONNECTED);
  47                        comphy_map_data->type = PHY_TYPE_UNCONNECTED;
  48                } else {
  49                        debug("lane number %d, has type %d\n",
  50                              lane, comphy_map_data->type);
  51                }
  52        }
  53
  54        debug_exit();
  55}
  56
  57static u32 comphy_mux_get_mux_value(struct comphy_mux_data *mux_data,
  58                                    u32 type, int lane)
  59{
  60        struct comphy_mux_options *mux_opt;
  61        int opt;
  62        u32 value = 0;
  63
  64        debug_enter();
  65
  66        mux_opt = mux_data->mux_values;
  67        for (opt = 0 ; opt < mux_data->max_lane_values; opt++, mux_opt++) {
  68                if (mux_opt->type == type) {
  69                        value = mux_opt->mux_value;
  70                        break;
  71                }
  72        }
  73
  74        debug_exit();
  75
  76        return value;
  77}
  78
  79static void comphy_mux_reg_write(struct comphy_mux_data *mux_data,
  80                                 struct comphy_map *comphy_map_data,
  81                                 int comphy_max_lanes,
  82                                 void __iomem *selector_base, u32 bitcount)
  83{
  84        u32 lane, value, offset, mask;
  85
  86        debug_enter();
  87
  88        for (lane = 0; lane < comphy_max_lanes;
  89             lane++, comphy_map_data++, mux_data++) {
  90                if (comphy_map_data->type == PHY_TYPE_IGNORE)
  91                        continue;
  92
  93                offset = lane * bitcount;
  94                mask = (((1 << bitcount) - 1) << offset);
  95                value = (comphy_mux_get_mux_value(mux_data,
  96                                                  comphy_map_data->type,
  97                                                  lane) << offset);
  98                reg_set(selector_base, value, mask);
  99        }
 100
 101        debug_exit();
 102}
 103
 104void comphy_mux_init(struct chip_serdes_phy_config *chip_cfg,
 105                     struct comphy_map *comphy_map_data,
 106                     void __iomem *selector_base)
 107{
 108        struct comphy_mux_data *mux_data;
 109        u32 mux_bitcount;
 110        u32 comphy_max_lanes;
 111
 112        debug_enter();
 113
 114        comphy_max_lanes = chip_cfg->comphy_lanes_count;
 115        mux_data = chip_cfg->mux_data;
 116        mux_bitcount = chip_cfg->comphy_mux_bitcount;
 117
 118        /* check if the configuration is valid */
 119        comphy_mux_check_config(mux_data, comphy_map_data, comphy_max_lanes);
 120        /* Init COMPHY selectors */
 121        comphy_mux_reg_write(mux_data, comphy_map_data, comphy_max_lanes,
 122                             selector_base, mux_bitcount);
 123
 124        debug_exit();
 125}
 126