1 /* 2 * Copyright 2020 Mauro Rossi <issor.oruam@gmail.com> 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining a 5 * copy of this software and associated documentation files (the "Software"), 6 * to deal in the Software without restriction, including without limitation 7 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 * and/or sell copies of the Software, and to permit persons to whom the 9 * Software is furnished to do so, subject to the following conditions: 10 * 11 * The above copyright notice and this permission notice shall be included in 12 * all copies or substantial portions of the Software. 13 * 14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR 18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 20 * OTHER DEALINGS IN THE SOFTWARE. 21 * 22 * Authors: AMD 23 * 24 */ 25 26 #include "dm_services.h" 27 28 #include "atom.h" 29 30 #include "include/grph_object_id.h" 31 #include "include/grph_object_defs.h" 32 #include "include/bios_parser_types.h" 33 34 #include "../command_table_helper.h" 35 36 static uint8_t encoder_action_to_atom(enum bp_encoder_control_action action) 37 { 38 uint8_t atom_action = 0; 39 40 switch (action) { 41 case ENCODER_CONTROL_ENABLE: 42 atom_action = ATOM_ENABLE; 43 break; 44 case ENCODER_CONTROL_DISABLE: 45 atom_action = ATOM_DISABLE; 46 break; 47 case ENCODER_CONTROL_SETUP: 48 atom_action = ATOM_ENCODER_CMD_SETUP; 49 break; 50 case ENCODER_CONTROL_INIT: 51 atom_action = ATOM_ENCODER_INIT; 52 break; 53 default: 54 BREAK_TO_DEBUGGER(); /* Unhandle action in driver.!! */ 55 break; 56 } 57 58 return atom_action; 59 } 60 61 static bool engine_bp_to_atom(enum engine_id id, uint32_t *atom_engine_id) 62 { 63 bool result = false; 64 65 if (atom_engine_id != NULL) 66 switch (id) { 67 case ENGINE_ID_DIGA: 68 *atom_engine_id = ASIC_INT_DIG1_ENCODER_ID; 69 result = true; 70 break; 71 case ENGINE_ID_DIGB: 72 *atom_engine_id = ASIC_INT_DIG2_ENCODER_ID; 73 result = true; 74 break; 75 case ENGINE_ID_DIGC: 76 *atom_engine_id = ASIC_INT_DIG3_ENCODER_ID; 77 result = true; 78 break; 79 case ENGINE_ID_DIGD: 80 *atom_engine_id = ASIC_INT_DIG4_ENCODER_ID; 81 result = true; 82 break; 83 case ENGINE_ID_DIGE: 84 *atom_engine_id = ASIC_INT_DIG5_ENCODER_ID; 85 result = true; 86 break; 87 case ENGINE_ID_DIGF: 88 *atom_engine_id = ASIC_INT_DIG6_ENCODER_ID; 89 result = true; 90 break; 91 case ENGINE_ID_DIGG: 92 *atom_engine_id = ASIC_INT_DIG7_ENCODER_ID; 93 result = true; 94 break; 95 case ENGINE_ID_DACA: 96 *atom_engine_id = ASIC_INT_DAC1_ENCODER_ID; 97 result = true; 98 break; 99 default: 100 break; 101 } 102 103 return result; 104 } 105 106 static bool clock_source_id_to_atom( 107 enum clock_source_id id, 108 uint32_t *atom_pll_id) 109 { 110 bool result = true; 111 112 if (atom_pll_id != NULL) 113 switch (id) { 114 case CLOCK_SOURCE_ID_PLL0: 115 *atom_pll_id = ATOM_PPLL0; 116 break; 117 case CLOCK_SOURCE_ID_PLL1: 118 *atom_pll_id = ATOM_PPLL1; 119 break; 120 case CLOCK_SOURCE_ID_PLL2: 121 *atom_pll_id = ATOM_PPLL2; 122 break; 123 case CLOCK_SOURCE_ID_EXTERNAL: 124 *atom_pll_id = ATOM_PPLL_INVALID; 125 break; 126 case CLOCK_SOURCE_ID_DFS: 127 *atom_pll_id = ATOM_EXT_PLL1; 128 break; 129 case CLOCK_SOURCE_ID_VCE: 130 /* for VCE encoding, 131 * we need to pass in ATOM_PPLL_INVALID 132 */ 133 *atom_pll_id = ATOM_PPLL_INVALID; 134 break; 135 case CLOCK_SOURCE_ID_DP_DTO: 136 /* When programming DP DTO PLL ID should be invalid */ 137 *atom_pll_id = ATOM_PPLL_INVALID; 138 break; 139 case CLOCK_SOURCE_ID_UNDEFINED: 140 BREAK_TO_DEBUGGER(); /* check when this will happen! */ 141 *atom_pll_id = ATOM_PPLL_INVALID; 142 result = false; 143 break; 144 default: 145 result = false; 146 break; 147 } 148 149 return result; 150 } 151 152 static uint8_t clock_source_id_to_atom_phy_clk_src_id( 153 enum clock_source_id id) 154 { 155 uint8_t atom_phy_clk_src_id = 0; 156 157 switch (id) { 158 case CLOCK_SOURCE_ID_PLL0: 159 atom_phy_clk_src_id = ATOM_TRANSMITTER_CONFIG_V5_P0PLL; 160 break; 161 case CLOCK_SOURCE_ID_PLL1: 162 atom_phy_clk_src_id = ATOM_TRANSMITTER_CONFIG_V5_P1PLL; 163 break; 164 case CLOCK_SOURCE_ID_PLL2: 165 atom_phy_clk_src_id = ATOM_TRANSMITTER_CONFIG_V5_P2PLL; 166 break; 167 case CLOCK_SOURCE_ID_EXTERNAL: 168 atom_phy_clk_src_id = ATOM_TRANSMITTER_CONFIG_V5_REFCLK_SRC_EXT; 169 break; 170 default: 171 atom_phy_clk_src_id = ATOM_TRANSMITTER_CONFIG_V5_P1PLL; 172 break; 173 } 174 175 return atom_phy_clk_src_id >> 2; 176 } 177 178 static uint8_t signal_type_to_atom_dig_mode(enum signal_type s) 179 { 180 uint8_t atom_dig_mode = ATOM_TRANSMITTER_DIGMODE_V5_DP; 181 182 switch (s) { 183 case SIGNAL_TYPE_DISPLAY_PORT: 184 case SIGNAL_TYPE_EDP: 185 atom_dig_mode = ATOM_TRANSMITTER_DIGMODE_V5_DP; 186 break; 187 case SIGNAL_TYPE_LVDS: 188 atom_dig_mode = ATOM_TRANSMITTER_DIGMODE_V5_LVDS; 189 break; 190 case SIGNAL_TYPE_DVI_SINGLE_LINK: 191 case SIGNAL_TYPE_DVI_DUAL_LINK: 192 atom_dig_mode = ATOM_TRANSMITTER_DIGMODE_V5_DVI; 193 break; 194 case SIGNAL_TYPE_HDMI_TYPE_A: 195 atom_dig_mode = ATOM_TRANSMITTER_DIGMODE_V5_HDMI; 196 break; 197 case SIGNAL_TYPE_DISPLAY_PORT_MST: 198 atom_dig_mode = ATOM_TRANSMITTER_DIGMODE_V5_DP_MST; 199 break; 200 default: 201 atom_dig_mode = ATOM_TRANSMITTER_DIGMODE_V5_DVI; 202 break; 203 } 204 205 return atom_dig_mode; 206 } 207 208 static uint8_t hpd_sel_to_atom(enum hpd_source_id id) 209 { 210 uint8_t atom_hpd_sel = 0; 211 212 switch (id) { 213 case HPD_SOURCEID1: 214 atom_hpd_sel = ATOM_TRANSMITTER_CONFIG_V5_HPD1_SEL; 215 break; 216 case HPD_SOURCEID2: 217 atom_hpd_sel = ATOM_TRANSMITTER_CONFIG_V5_HPD2_SEL; 218 break; 219 case HPD_SOURCEID3: 220 atom_hpd_sel = ATOM_TRANSMITTER_CONFIG_V5_HPD3_SEL; 221 break; 222 case HPD_SOURCEID4: 223 atom_hpd_sel = ATOM_TRANSMITTER_CONFIG_V5_HPD4_SEL; 224 break; 225 case HPD_SOURCEID5: 226 atom_hpd_sel = ATOM_TRANSMITTER_CONFIG_V5_HPD5_SEL; 227 break; 228 case HPD_SOURCEID6: 229 atom_hpd_sel = ATOM_TRANSMITTER_CONFIG_V5_HPD6_SEL; 230 break; 231 case HPD_SOURCEID_UNKNOWN: 232 default: 233 atom_hpd_sel = 0; 234 break; 235 } 236 return atom_hpd_sel >> 4; 237 } 238 239 static uint8_t dig_encoder_sel_to_atom(enum engine_id id) 240 { 241 uint8_t atom_dig_encoder_sel = 0; 242 243 switch (id) { 244 case ENGINE_ID_DIGA: 245 atom_dig_encoder_sel = ATOM_TRANMSITTER_V5__DIGA_SEL; 246 break; 247 case ENGINE_ID_DIGB: 248 atom_dig_encoder_sel = ATOM_TRANMSITTER_V5__DIGB_SEL; 249 break; 250 case ENGINE_ID_DIGC: 251 atom_dig_encoder_sel = ATOM_TRANMSITTER_V5__DIGC_SEL; 252 break; 253 case ENGINE_ID_DIGD: 254 atom_dig_encoder_sel = ATOM_TRANMSITTER_V5__DIGD_SEL; 255 break; 256 case ENGINE_ID_DIGE: 257 atom_dig_encoder_sel = ATOM_TRANMSITTER_V5__DIGE_SEL; 258 break; 259 case ENGINE_ID_DIGF: 260 atom_dig_encoder_sel = ATOM_TRANMSITTER_V5__DIGF_SEL; 261 break; 262 case ENGINE_ID_DIGG: 263 atom_dig_encoder_sel = ATOM_TRANMSITTER_V5__DIGG_SEL; 264 break; 265 default: 266 atom_dig_encoder_sel = ATOM_TRANMSITTER_V5__DIGA_SEL; 267 break; 268 } 269 270 return atom_dig_encoder_sel; 271 } 272 273 static uint8_t phy_id_to_atom(enum transmitter t) 274 { 275 uint8_t atom_phy_id; 276 277 switch (t) { 278 case TRANSMITTER_UNIPHY_A: 279 atom_phy_id = ATOM_PHY_ID_UNIPHYA; 280 break; 281 case TRANSMITTER_UNIPHY_B: 282 atom_phy_id = ATOM_PHY_ID_UNIPHYB; 283 break; 284 case TRANSMITTER_UNIPHY_C: 285 atom_phy_id = ATOM_PHY_ID_UNIPHYC; 286 break; 287 case TRANSMITTER_UNIPHY_D: 288 atom_phy_id = ATOM_PHY_ID_UNIPHYD; 289 break; 290 case TRANSMITTER_UNIPHY_E: 291 atom_phy_id = ATOM_PHY_ID_UNIPHYE; 292 break; 293 case TRANSMITTER_UNIPHY_F: 294 atom_phy_id = ATOM_PHY_ID_UNIPHYF; 295 break; 296 case TRANSMITTER_UNIPHY_G: 297 atom_phy_id = ATOM_PHY_ID_UNIPHYG; 298 break; 299 default: 300 atom_phy_id = ATOM_PHY_ID_UNIPHYA; 301 break; 302 } 303 return atom_phy_id; 304 } 305 306 static uint8_t disp_power_gating_action_to_atom( 307 enum bp_pipe_control_action action) 308 { 309 uint8_t atom_pipe_action = 0; 310 311 switch (action) { 312 case ASIC_PIPE_DISABLE: 313 atom_pipe_action = ATOM_DISABLE; 314 break; 315 case ASIC_PIPE_ENABLE: 316 atom_pipe_action = ATOM_ENABLE; 317 break; 318 case ASIC_PIPE_INIT: 319 atom_pipe_action = ATOM_INIT; 320 break; 321 default: 322 BREAK_TO_DEBUGGER(); /* Unhandle action in driver! */ 323 break; 324 } 325 326 return atom_pipe_action; 327 } 328 329 static const struct command_table_helper command_table_helper_funcs = { 330 .controller_id_to_atom = dal_cmd_table_helper_controller_id_to_atom, 331 .encoder_action_to_atom = encoder_action_to_atom, 332 .engine_bp_to_atom = engine_bp_to_atom, 333 .clock_source_id_to_atom = clock_source_id_to_atom, 334 .clock_source_id_to_atom_phy_clk_src_id = 335 clock_source_id_to_atom_phy_clk_src_id, 336 .signal_type_to_atom_dig_mode = signal_type_to_atom_dig_mode, 337 .hpd_sel_to_atom = hpd_sel_to_atom, 338 .dig_encoder_sel_to_atom = dig_encoder_sel_to_atom, 339 .phy_id_to_atom = phy_id_to_atom, 340 .disp_power_gating_action_to_atom = disp_power_gating_action_to_atom, 341 .assign_control_parameter = 342 dal_cmd_table_helper_assign_control_parameter, 343 .clock_source_id_to_ref_clk_src = 344 dal_cmd_table_helper_clock_source_id_to_ref_clk_src, 345 .transmitter_bp_to_atom = dal_cmd_table_helper_transmitter_bp_to_atom, 346 .encoder_id_to_atom = dal_cmd_table_helper_encoder_id_to_atom, 347 .encoder_mode_bp_to_atom = 348 dal_cmd_table_helper_encoder_mode_bp_to_atom, 349 }; 350 351 const struct command_table_helper *dal_cmd_tbl_helper_dce60_get_table(void) 352 { 353 return &command_table_helper_funcs; 354 } 355