1 /* 2 * Copyright 2012-15 Advanced Micro Devices, Inc. 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/bios_parser_types.h" 31 32 #include "../command_table_helper.h" 33 34 static uint8_t phy_id_to_atom(enum transmitter t) 35 { 36 uint8_t atom_phy_id; 37 38 switch (t) { 39 case TRANSMITTER_UNIPHY_A: 40 atom_phy_id = ATOM_PHY_ID_UNIPHYA; 41 break; 42 case TRANSMITTER_UNIPHY_B: 43 atom_phy_id = ATOM_PHY_ID_UNIPHYB; 44 break; 45 case TRANSMITTER_UNIPHY_C: 46 atom_phy_id = ATOM_PHY_ID_UNIPHYC; 47 break; 48 case TRANSMITTER_UNIPHY_D: 49 atom_phy_id = ATOM_PHY_ID_UNIPHYD; 50 break; 51 case TRANSMITTER_UNIPHY_E: 52 atom_phy_id = ATOM_PHY_ID_UNIPHYE; 53 break; 54 case TRANSMITTER_UNIPHY_F: 55 atom_phy_id = ATOM_PHY_ID_UNIPHYF; 56 break; 57 case TRANSMITTER_UNIPHY_G: 58 atom_phy_id = ATOM_PHY_ID_UNIPHYG; 59 break; 60 default: 61 atom_phy_id = ATOM_PHY_ID_UNIPHYA; 62 break; 63 } 64 return atom_phy_id; 65 } 66 67 static uint8_t signal_type_to_atom_dig_mode(enum signal_type s) 68 { 69 uint8_t atom_dig_mode = ATOM_TRANSMITTER_DIGMODE_V5_DP; 70 71 switch (s) { 72 case SIGNAL_TYPE_DISPLAY_PORT: 73 case SIGNAL_TYPE_EDP: 74 atom_dig_mode = ATOM_TRANSMITTER_DIGMODE_V5_DP; 75 break; 76 case SIGNAL_TYPE_LVDS: 77 atom_dig_mode = ATOM_TRANSMITTER_DIGMODE_V5_LVDS; 78 break; 79 case SIGNAL_TYPE_DVI_SINGLE_LINK: 80 case SIGNAL_TYPE_DVI_DUAL_LINK: 81 atom_dig_mode = ATOM_TRANSMITTER_DIGMODE_V5_DVI; 82 break; 83 case SIGNAL_TYPE_HDMI_TYPE_A: 84 atom_dig_mode = ATOM_TRANSMITTER_DIGMODE_V5_HDMI; 85 break; 86 case SIGNAL_TYPE_DISPLAY_PORT_MST: 87 atom_dig_mode = ATOM_TRANSMITTER_DIGMODE_V5_DP_MST; 88 break; 89 default: 90 atom_dig_mode = ATOM_TRANSMITTER_DIGMODE_V5_DVI; 91 break; 92 } 93 94 return atom_dig_mode; 95 } 96 97 static uint8_t clock_source_id_to_atom_phy_clk_src_id( 98 enum clock_source_id id) 99 { 100 uint8_t atom_phy_clk_src_id = 0; 101 102 switch (id) { 103 case CLOCK_SOURCE_ID_PLL0: 104 atom_phy_clk_src_id = ATOM_TRANSMITTER_CONFIG_V5_P0PLL; 105 break; 106 case CLOCK_SOURCE_ID_PLL1: 107 atom_phy_clk_src_id = ATOM_TRANSMITTER_CONFIG_V5_P1PLL; 108 break; 109 case CLOCK_SOURCE_ID_PLL2: 110 atom_phy_clk_src_id = ATOM_TRANSMITTER_CONFIG_V5_P2PLL; 111 break; 112 case CLOCK_SOURCE_ID_EXTERNAL: 113 atom_phy_clk_src_id = ATOM_TRANSMITTER_CONFIG_V5_REFCLK_SRC_EXT; 114 break; 115 default: 116 atom_phy_clk_src_id = ATOM_TRANSMITTER_CONFIG_V5_P1PLL; 117 break; 118 } 119 120 return atom_phy_clk_src_id >> 2; 121 } 122 123 static uint8_t hpd_sel_to_atom(enum hpd_source_id id) 124 { 125 uint8_t atom_hpd_sel = 0; 126 127 switch (id) { 128 case HPD_SOURCEID1: 129 atom_hpd_sel = ATOM_TRANSMITTER_CONFIG_V5_HPD1_SEL; 130 break; 131 case HPD_SOURCEID2: 132 atom_hpd_sel = ATOM_TRANSMITTER_CONFIG_V5_HPD2_SEL; 133 break; 134 case HPD_SOURCEID3: 135 atom_hpd_sel = ATOM_TRANSMITTER_CONFIG_V5_HPD3_SEL; 136 break; 137 case HPD_SOURCEID4: 138 atom_hpd_sel = ATOM_TRANSMITTER_CONFIG_V5_HPD4_SEL; 139 break; 140 case HPD_SOURCEID5: 141 atom_hpd_sel = ATOM_TRANSMITTER_CONFIG_V5_HPD5_SEL; 142 break; 143 case HPD_SOURCEID6: 144 atom_hpd_sel = ATOM_TRANSMITTER_CONFIG_V5_HPD6_SEL; 145 break; 146 case HPD_SOURCEID_UNKNOWN: 147 default: 148 atom_hpd_sel = 0; 149 break; 150 } 151 return atom_hpd_sel >> 4; 152 } 153 154 static uint8_t dig_encoder_sel_to_atom(enum engine_id id) 155 { 156 uint8_t atom_dig_encoder_sel = 0; 157 158 switch (id) { 159 case ENGINE_ID_DIGA: 160 atom_dig_encoder_sel = ATOM_TRANMSITTER_V5__DIGA_SEL; 161 break; 162 case ENGINE_ID_DIGB: 163 atom_dig_encoder_sel = ATOM_TRANMSITTER_V5__DIGB_SEL; 164 break; 165 case ENGINE_ID_DIGC: 166 atom_dig_encoder_sel = ATOM_TRANMSITTER_V5__DIGC_SEL; 167 break; 168 case ENGINE_ID_DIGD: 169 atom_dig_encoder_sel = ATOM_TRANMSITTER_V5__DIGD_SEL; 170 break; 171 case ENGINE_ID_DIGE: 172 atom_dig_encoder_sel = ATOM_TRANMSITTER_V5__DIGE_SEL; 173 break; 174 case ENGINE_ID_DIGF: 175 atom_dig_encoder_sel = ATOM_TRANMSITTER_V5__DIGF_SEL; 176 break; 177 case ENGINE_ID_DIGG: 178 atom_dig_encoder_sel = ATOM_TRANMSITTER_V5__DIGG_SEL; 179 break; 180 case ENGINE_ID_UNKNOWN: 181 /* No DIG_FRONT is associated to DIG_BACKEND */ 182 atom_dig_encoder_sel = 0; 183 break; 184 default: 185 atom_dig_encoder_sel = ATOM_TRANMSITTER_V5__DIGA_SEL; 186 break; 187 } 188 189 return 0; 190 } 191 192 static bool clock_source_id_to_atom( 193 enum clock_source_id id, 194 uint32_t *atom_pll_id) 195 { 196 bool result = true; 197 198 if (atom_pll_id != NULL) 199 switch (id) { 200 case CLOCK_SOURCE_ID_PLL0: 201 *atom_pll_id = ATOM_PPLL0; 202 break; 203 case CLOCK_SOURCE_ID_PLL1: 204 *atom_pll_id = ATOM_PPLL1; 205 break; 206 case CLOCK_SOURCE_ID_PLL2: 207 *atom_pll_id = ATOM_PPLL2; 208 break; 209 case CLOCK_SOURCE_ID_EXTERNAL: 210 *atom_pll_id = ATOM_PPLL_INVALID; 211 break; 212 case CLOCK_SOURCE_ID_DFS: 213 *atom_pll_id = ATOM_EXT_PLL1; 214 break; 215 case CLOCK_SOURCE_ID_VCE: 216 /* for VCE encoding, 217 * we need to pass in ATOM_PPLL_INVALID 218 */ 219 *atom_pll_id = ATOM_PPLL_INVALID; 220 break; 221 case CLOCK_SOURCE_ID_DP_DTO: 222 /* When programming DP DTO PLL ID should be invalid */ 223 *atom_pll_id = ATOM_PPLL_INVALID; 224 break; 225 case CLOCK_SOURCE_ID_UNDEFINED: 226 /* Should not happen */ 227 *atom_pll_id = ATOM_PPLL_INVALID; 228 result = false; 229 break; 230 default: 231 result = false; 232 break; 233 } 234 235 return result; 236 } 237 238 static bool engine_bp_to_atom(enum engine_id id, uint32_t *atom_engine_id) 239 { 240 bool result = false; 241 242 if (atom_engine_id != NULL) 243 switch (id) { 244 case ENGINE_ID_DIGA: 245 *atom_engine_id = ASIC_INT_DIG1_ENCODER_ID; 246 result = true; 247 break; 248 case ENGINE_ID_DIGB: 249 *atom_engine_id = ASIC_INT_DIG2_ENCODER_ID; 250 result = true; 251 break; 252 case ENGINE_ID_DIGC: 253 *atom_engine_id = ASIC_INT_DIG3_ENCODER_ID; 254 result = true; 255 break; 256 case ENGINE_ID_DIGD: 257 *atom_engine_id = ASIC_INT_DIG4_ENCODER_ID; 258 result = true; 259 break; 260 case ENGINE_ID_DIGE: 261 *atom_engine_id = ASIC_INT_DIG5_ENCODER_ID; 262 result = true; 263 break; 264 case ENGINE_ID_DIGF: 265 *atom_engine_id = ASIC_INT_DIG6_ENCODER_ID; 266 result = true; 267 break; 268 case ENGINE_ID_DIGG: 269 *atom_engine_id = ASIC_INT_DIG7_ENCODER_ID; 270 result = true; 271 break; 272 case ENGINE_ID_DACA: 273 *atom_engine_id = ASIC_INT_DAC1_ENCODER_ID; 274 result = true; 275 break; 276 default: 277 break; 278 } 279 280 return result; 281 } 282 283 static uint8_t encoder_action_to_atom(enum bp_encoder_control_action action) 284 { 285 uint8_t atom_action = 0; 286 287 switch (action) { 288 case ENCODER_CONTROL_ENABLE: 289 atom_action = ATOM_ENABLE; 290 break; 291 case ENCODER_CONTROL_DISABLE: 292 atom_action = ATOM_DISABLE; 293 break; 294 case ENCODER_CONTROL_SETUP: 295 atom_action = ATOM_ENCODER_CMD_SETUP; 296 break; 297 case ENCODER_CONTROL_INIT: 298 atom_action = ATOM_ENCODER_INIT; 299 break; 300 default: 301 BREAK_TO_DEBUGGER(); /* Unhandle action in driver.!! */ 302 break; 303 } 304 305 return atom_action; 306 } 307 308 static uint8_t disp_power_gating_action_to_atom( 309 enum bp_pipe_control_action action) 310 { 311 uint8_t atom_pipe_action = 0; 312 313 switch (action) { 314 case ASIC_PIPE_DISABLE: 315 atom_pipe_action = ATOM_DISABLE; 316 break; 317 case ASIC_PIPE_ENABLE: 318 atom_pipe_action = ATOM_ENABLE; 319 break; 320 case ASIC_PIPE_INIT: 321 atom_pipe_action = ATOM_INIT; 322 break; 323 default: 324 ASSERT_CRITICAL(false); /* Unhandle action in driver! */ 325 break; 326 } 327 328 return atom_pipe_action; 329 } 330 331 /* function table */ 332 static const struct command_table_helper command_table_helper_funcs = { 333 .controller_id_to_atom = dal_cmd_table_helper_controller_id_to_atom, 334 .encoder_action_to_atom = encoder_action_to_atom, 335 .engine_bp_to_atom = engine_bp_to_atom, 336 .clock_source_id_to_atom = clock_source_id_to_atom, 337 .clock_source_id_to_atom_phy_clk_src_id = 338 clock_source_id_to_atom_phy_clk_src_id, 339 .signal_type_to_atom_dig_mode = signal_type_to_atom_dig_mode, 340 .hpd_sel_to_atom = hpd_sel_to_atom, 341 .dig_encoder_sel_to_atom = dig_encoder_sel_to_atom, 342 .phy_id_to_atom = phy_id_to_atom, 343 .disp_power_gating_action_to_atom = disp_power_gating_action_to_atom, 344 .assign_control_parameter = NULL, 345 .clock_source_id_to_ref_clk_src = NULL, 346 .transmitter_bp_to_atom = NULL, 347 .encoder_id_to_atom = dal_cmd_table_helper_encoder_id_to_atom, 348 .encoder_mode_bp_to_atom = dal_cmd_table_helper_encoder_mode_bp_to_atom, 349 }; 350 351 /* 352 * dal_cmd_tbl_helper_dce110_get_table 353 * 354 * @brief 355 * Initialize command table helper functions 356 * 357 * @param 358 * const struct command_table_helper **h - [out] struct of functions 359 * 360 */ 361 const struct command_table_helper *dal_cmd_tbl_helper_dce110_get_table(void) 362 { 363 return &command_table_helper_funcs; 364 } 365