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