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