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 } 119