1/* $NetBSD: amdgpu_command_table_helper.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.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 39bool dal_bios_parser_init_cmd_tbl_helper( 40 const struct command_table_helper **h, 41 enum dce_version dce) 42{ 43 switch (dce) { 44 case DCE_VERSION_8_0: 45 case DCE_VERSION_8_1: 46 case DCE_VERSION_8_3: 47 *h = dal_cmd_tbl_helper_dce80_get_table(); 48 return true; 49 50 case DCE_VERSION_10_0: 51 *h = dal_cmd_tbl_helper_dce110_get_table(); 52 return true; 53 54 case DCE_VERSION_11_0: 55 *h = dal_cmd_tbl_helper_dce110_get_table(); 56 return true; 57 58 case DCE_VERSION_11_2: 59 case DCE_VERSION_11_22: 60 *h = dal_cmd_tbl_helper_dce112_get_table(); 61 return true; 62 63 default: 64 /* Unsupported DCE */ 65 BREAK_TO_DEBUGGER(); 66 return false; 67 } 68} 69 70/* real implementations */ 71 72bool dal_cmd_table_helper_controller_id_to_atom( 73 enum controller_id id, 74 uint8_t *atom_id) 75{ 76 if (atom_id == NULL) { 77 BREAK_TO_DEBUGGER(); 78 return false; 79 } 80 81 switch (id) { 82 case CONTROLLER_ID_D0: 83 *atom_id = ATOM_CRTC1; 84 return true; 85 case CONTROLLER_ID_D1: 86 *atom_id = ATOM_CRTC2; 87 return true; 88 case CONTROLLER_ID_D2: 89 *atom_id = ATOM_CRTC3; 90 return true; 91 case CONTROLLER_ID_D3: 92 *atom_id = ATOM_CRTC4; 93 return true; 94 case CONTROLLER_ID_D4: 95 *atom_id = ATOM_CRTC5; 96 return true; 97 case CONTROLLER_ID_D5: 98 *atom_id = ATOM_CRTC6; 99 return true; 100 case CONTROLLER_ID_UNDERLAY0: 101 *atom_id = ATOM_UNDERLAY_PIPE0; 102 return true; 103 case CONTROLLER_ID_UNDEFINED: 104 *atom_id = ATOM_CRTC_INVALID; 105 return true; 106 default: 107 /* Wrong controller id */ 108 BREAK_TO_DEBUGGER(); 109 return false; 110 } 111} 112 113/** 114* translate_transmitter_bp_to_atom 115* 116* @brief 117* Translate the Transmitter to the corresponding ATOM BIOS value 118* 119* @param 120* input transmitter 121* output digitalTransmitter 122* // =00: Digital Transmitter1 ( UNIPHY linkAB ) 123* // =01: Digital Transmitter2 ( UNIPHY linkCD ) 124* // =02: Digital Transmitter3 ( UNIPHY linkEF ) 125*/ 126uint8_t dal_cmd_table_helper_transmitter_bp_to_atom( 127 enum transmitter t) 128{ 129 switch (t) { 130 case TRANSMITTER_UNIPHY_A: 131 case TRANSMITTER_UNIPHY_B: 132 case TRANSMITTER_TRAVIS_LCD: 133 return 0; 134 case TRANSMITTER_UNIPHY_C: 135 case TRANSMITTER_UNIPHY_D: 136 return 1; 137 case TRANSMITTER_UNIPHY_E: 138 case TRANSMITTER_UNIPHY_F: 139 return 2; 140 default: 141 /* Invalid Transmitter Type! */ 142 BREAK_TO_DEBUGGER(); 143 return 0; 144 } 145} 146 147uint32_t dal_cmd_table_helper_encoder_mode_bp_to_atom( 148 enum signal_type s, 149 bool enable_dp_audio) 150{ 151 switch (s) { 152 case SIGNAL_TYPE_DVI_SINGLE_LINK: 153 case SIGNAL_TYPE_DVI_DUAL_LINK: 154 return ATOM_ENCODER_MODE_DVI; 155 case SIGNAL_TYPE_HDMI_TYPE_A: 156 return ATOM_ENCODER_MODE_HDMI; 157 case SIGNAL_TYPE_LVDS: 158 return ATOM_ENCODER_MODE_LVDS; 159 case SIGNAL_TYPE_EDP: 160 case SIGNAL_TYPE_DISPLAY_PORT_MST: 161 case SIGNAL_TYPE_DISPLAY_PORT: 162 case SIGNAL_TYPE_VIRTUAL: 163 if (enable_dp_audio) 164 return ATOM_ENCODER_MODE_DP_AUDIO; 165 else 166 return ATOM_ENCODER_MODE_DP; 167 case SIGNAL_TYPE_RGB: 168 return ATOM_ENCODER_MODE_CRT; 169 default: 170 return ATOM_ENCODER_MODE_CRT; 171 } 172} 173 174void dal_cmd_table_helper_assign_control_parameter( 175 const struct command_table_helper *h, 176 struct bp_encoder_control *control, 177 DIG_ENCODER_CONTROL_PARAMETERS_V2 *ctrl_param) 178{ 179 /* there are three transmitter blocks, each one has two links 4-lanes 180 * each, A+B, C+D, E+F, Uniphy A, C and E are enumerated as link 0 in 181 * each transmitter block B, D and F as link 1, third transmitter block 182 * has non splitable links (UniphyE and UniphyF can not be configured 183 * separately to drive two different streams) 184 */ 185 if ((control->transmitter == TRANSMITTER_UNIPHY_B) || 186 (control->transmitter == TRANSMITTER_UNIPHY_D) || 187 (control->transmitter == TRANSMITTER_UNIPHY_F)) { 188 /* Bit2: Link Select 189 * =0: PHY linkA/C/E 190 * =1: PHY linkB/D/F 191 */ 192 ctrl_param->acConfig.ucLinkSel = 1; 193 } 194 195 /* Bit[4:3]: Transmitter Selection 196 * =00: Digital Transmitter1 ( UNIPHY linkAB ) 197 * =01: Digital Transmitter2 ( UNIPHY linkCD ) 198 * =02: Digital Transmitter3 ( UNIPHY linkEF ) 199 * =03: Reserved 200 */ 201 ctrl_param->acConfig.ucTransmitterSel = 202 (uint8_t)(h->transmitter_bp_to_atom(control->transmitter)); 203 204 /* We need to convert from KHz units into 10KHz units */ 205 ctrl_param->ucAction = h->encoder_action_to_atom(control->action); 206 ctrl_param->usPixelClock = cpu_to_le16((uint16_t)(control->pixel_clock / 10)); 207 ctrl_param->ucEncoderMode = 208 (uint8_t)(h->encoder_mode_bp_to_atom( 209 control->signal, control->enable_dp_audio)); 210 ctrl_param->ucLaneNum = (uint8_t)(control->lanes_number); 211} 212 213bool dal_cmd_table_helper_clock_source_id_to_ref_clk_src( 214 enum clock_source_id id, 215 uint32_t *ref_clk_src_id) 216{ 217 if (ref_clk_src_id == NULL) { 218 BREAK_TO_DEBUGGER(); 219 return false; 220 } 221 222 switch (id) { 223 case CLOCK_SOURCE_ID_PLL1: 224 *ref_clk_src_id = ENCODER_REFCLK_SRC_P1PLL; 225 return true; 226 case CLOCK_SOURCE_ID_PLL2: 227 *ref_clk_src_id = ENCODER_REFCLK_SRC_P2PLL; 228 return true; 229 case CLOCK_SOURCE_ID_DCPLL: 230 *ref_clk_src_id = ENCODER_REFCLK_SRC_DCPLL; 231 return true; 232 case CLOCK_SOURCE_ID_EXTERNAL: 233 *ref_clk_src_id = ENCODER_REFCLK_SRC_EXTCLK; 234 return true; 235 case CLOCK_SOURCE_ID_UNDEFINED: 236 *ref_clk_src_id = ENCODER_REFCLK_SRC_INVALID; 237 return true; 238 default: 239 /* Unsupported clock source id */ 240 BREAK_TO_DEBUGGER(); 241 return false; 242 } 243} 244 245uint8_t dal_cmd_table_helper_encoder_id_to_atom( 246 enum encoder_id id) 247{ 248 switch (id) { 249 case ENCODER_ID_INTERNAL_LVDS: 250 return ENCODER_OBJECT_ID_INTERNAL_LVDS; 251 case ENCODER_ID_INTERNAL_TMDS1: 252 return ENCODER_OBJECT_ID_INTERNAL_TMDS1; 253 case ENCODER_ID_INTERNAL_TMDS2: 254 return ENCODER_OBJECT_ID_INTERNAL_TMDS2; 255 case ENCODER_ID_INTERNAL_DAC1: 256 return ENCODER_OBJECT_ID_INTERNAL_DAC1; 257 case ENCODER_ID_INTERNAL_DAC2: 258 return ENCODER_OBJECT_ID_INTERNAL_DAC2; 259 case ENCODER_ID_INTERNAL_LVTM1: 260 return ENCODER_OBJECT_ID_INTERNAL_LVTM1; 261 case ENCODER_ID_INTERNAL_HDMI: 262 return ENCODER_OBJECT_ID_HDMI_INTERNAL; 263 case ENCODER_ID_EXTERNAL_TRAVIS: 264 return ENCODER_OBJECT_ID_TRAVIS; 265 case ENCODER_ID_EXTERNAL_NUTMEG: 266 return ENCODER_OBJECT_ID_NUTMEG; 267 case ENCODER_ID_INTERNAL_KLDSCP_TMDS1: 268 return ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1; 269 case ENCODER_ID_INTERNAL_KLDSCP_DAC1: 270 return ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1; 271 case ENCODER_ID_INTERNAL_KLDSCP_DAC2: 272 return ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2; 273 case ENCODER_ID_EXTERNAL_MVPU_FPGA: 274 return ENCODER_OBJECT_ID_MVPU_FPGA; 275 case ENCODER_ID_INTERNAL_DDI: 276 return ENCODER_OBJECT_ID_INTERNAL_DDI; 277 case ENCODER_ID_INTERNAL_UNIPHY: 278 return ENCODER_OBJECT_ID_INTERNAL_UNIPHY; 279 case ENCODER_ID_INTERNAL_KLDSCP_LVTMA: 280 return ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA; 281 case ENCODER_ID_INTERNAL_UNIPHY1: 282 return ENCODER_OBJECT_ID_INTERNAL_UNIPHY1; 283 case ENCODER_ID_INTERNAL_UNIPHY2: 284 return ENCODER_OBJECT_ID_INTERNAL_UNIPHY2; 285 case ENCODER_ID_INTERNAL_UNIPHY3: 286 return ENCODER_OBJECT_ID_INTERNAL_UNIPHY3; 287 case ENCODER_ID_INTERNAL_WIRELESS: 288 return ENCODER_OBJECT_ID_INTERNAL_VCE; 289 case ENCODER_ID_UNKNOWN: 290 return ENCODER_OBJECT_ID_NONE; 291 default: 292 /* Invalid encoder id */ 293 BREAK_TO_DEBUGGER(); 294 return ENCODER_OBJECT_ID_NONE; 295 } 296} 297