]> git.karo-electronics.de Git - karo-tx-uboot.git/blob - drivers/phy/marvell/comphy_mux.c
drivers/phy: Add Marvell SerDes / PHY drivers used on Armada 3k
[karo-tx-uboot.git] / drivers / phy / marvell / comphy_mux.c
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  */
20 static 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                 mux_opt = mux_data->mux_values;
31                 for (opt = 0, valid = 0; opt < mux_data->max_lane_values;
32                      opt++, mux_opt++) {
33                         if (mux_opt->type == comphy_map_data->type) {
34                                 valid = 1;
35                                 break;
36                         }
37                 }
38                 if (valid == 0) {
39                         debug("lane number %d, had invalid type %d\n",
40                               lane, comphy_map_data->type);
41                         debug("set lane %d as type %d\n", lane,
42                               PHY_TYPE_UNCONNECTED);
43                         comphy_map_data->type = PHY_TYPE_UNCONNECTED;
44                 } else {
45                         debug("lane number %d, has type %d\n",
46                               lane, comphy_map_data->type);
47                 }
48         }
49
50         debug_exit();
51 }
52
53 static u32 comphy_mux_get_mux_value(struct comphy_mux_data *mux_data,
54                                     u32 type, int lane)
55 {
56         struct comphy_mux_options *mux_opt;
57         int opt;
58         u32 value = 0;
59
60         debug_enter();
61
62         mux_opt = mux_data->mux_values;
63         for (opt = 0 ; opt < mux_data->max_lane_values; opt++, mux_opt++) {
64                 if (mux_opt->type == type) {
65                         value = mux_opt->mux_value;
66                         break;
67                 }
68         }
69
70         debug_exit();
71
72         return value;
73 }
74
75 static void comphy_mux_reg_write(struct comphy_mux_data *mux_data,
76                                  struct comphy_map *comphy_map_data,
77                                  int comphy_max_lanes,
78                                  void __iomem *selector_base, u32 bitcount)
79 {
80         u32 lane, value, offset, mask;
81
82         debug_enter();
83
84         for (lane = 0; lane < comphy_max_lanes;
85              lane++, comphy_map_data++, mux_data++) {
86                 offset = lane * bitcount;
87                 mask = (((1 << bitcount) - 1) << offset);
88                 value = (comphy_mux_get_mux_value(mux_data,
89                                                   comphy_map_data->type,
90                                                   lane) << offset);
91                 reg_set(selector_base, value, mask);
92         }
93
94         debug_exit();
95 }
96
97 void comphy_mux_init(struct chip_serdes_phy_config *chip_cfg,
98                      struct comphy_map *comphy_map_data,
99                      void __iomem *selector_base)
100 {
101         struct comphy_mux_data *mux_data;
102         u32 mux_bitcount;
103         u32 comphy_max_lanes;
104
105         debug_enter();
106
107         comphy_max_lanes = chip_cfg->comphy_lanes_count;
108         mux_data = chip_cfg->mux_data;
109         mux_bitcount = chip_cfg->comphy_mux_bitcount;
110
111         /* check if the configuration is valid */
112         comphy_mux_check_config(mux_data, comphy_map_data, comphy_max_lanes);
113         /* Init COMPHY selectors */
114         comphy_mux_reg_write(mux_data, comphy_map_data, comphy_max_lanes,
115                              selector_base, mux_bitcount);
116
117         debug_exit();
118 }