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