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 "ObjectID.h" 29 30 #include "atomfirmware.h" 31 #include "atom.h" 32 #include "include/bios_parser_interface.h" 33 34 #include "command_table2.h" 35 #include "command_table_helper2.h" 36 #include "bios_parser_helper.h" 37 #include "bios_parser_types_internal2.h" 38 #include "amdgpu.h" 39 40 #include "dc_dmub_srv.h" 41 #include "dc.h" 42 43 #define DC_LOGGER \ 44 bp->base.ctx->logger 45 46 #define GET_INDEX_INTO_MASTER_TABLE(MasterOrData, FieldName)\ 47 (((char *)(&((\ 48 struct atom_master_list_of_##MasterOrData##_functions_v2_1 *)0)\ 49 ->FieldName)-(char *)0)/sizeof(uint16_t)) 50 51 #define EXEC_BIOS_CMD_TABLE(fname, params)\ 52 (amdgpu_atom_execute_table(((struct amdgpu_device *)bp->base.ctx->driver_context)->mode_info.atom_context, \ 53 GET_INDEX_INTO_MASTER_TABLE(command, fname), \ 54 (uint32_t *)¶ms) == 0) 55 56 #define BIOS_CMD_TABLE_REVISION(fname, frev, crev)\ 57 amdgpu_atom_parse_cmd_header(((struct amdgpu_device *)bp->base.ctx->driver_context)->mode_info.atom_context, \ 58 GET_INDEX_INTO_MASTER_TABLE(command, fname), &frev, &crev) 59 60 #define BIOS_CMD_TABLE_PARA_REVISION(fname)\ 61 bios_cmd_table_para_revision(bp->base.ctx->driver_context, \ 62 GET_INDEX_INTO_MASTER_TABLE(command, fname)) 63 64 65 66 static uint32_t bios_cmd_table_para_revision(void *dev, 67 uint32_t index) 68 { 69 struct amdgpu_device *adev = dev; 70 uint8_t frev, crev; 71 72 if (amdgpu_atom_parse_cmd_header(adev->mode_info.atom_context, 73 index, 74 &frev, &crev)) 75 return crev; 76 else 77 return 0; 78 } 79 80 /****************************************************************************** 81 ****************************************************************************** 82 ** 83 ** D I G E N C O D E R C O N T R O L 84 ** 85 ****************************************************************************** 86 *****************************************************************************/ 87 88 static enum bp_result encoder_control_digx_v1_5( 89 struct bios_parser *bp, 90 struct bp_encoder_control *cntl); 91 92 static enum bp_result encoder_control_fallback( 93 struct bios_parser *bp, 94 struct bp_encoder_control *cntl); 95 96 static void init_dig_encoder_control(struct bios_parser *bp) 97 { 98 uint32_t version = 99 BIOS_CMD_TABLE_PARA_REVISION(digxencodercontrol); 100 101 switch (version) { 102 case 5: 103 bp->cmd_tbl.dig_encoder_control = encoder_control_digx_v1_5; 104 break; 105 default: 106 dm_output_to_console("Don't have dig_encoder_control for v%d\n", version); 107 bp->cmd_tbl.dig_encoder_control = encoder_control_fallback; 108 break; 109 } 110 } 111 112 static void encoder_control_dmcub( 113 struct dc_dmub_srv *dmcub, 114 struct dig_encoder_stream_setup_parameters_v1_5 *dig) 115 { 116 union dmub_rb_cmd cmd; 117 118 memset(&cmd, 0, sizeof(cmd)); 119 120 cmd.digx_encoder_control.header.type = DMUB_CMD__VBIOS; 121 cmd.digx_encoder_control.header.sub_type = 122 DMUB_CMD__VBIOS_DIGX_ENCODER_CONTROL; 123 cmd.digx_encoder_control.header.payload_bytes = 124 sizeof(cmd.digx_encoder_control) - 125 sizeof(cmd.digx_encoder_control.header); 126 cmd.digx_encoder_control.encoder_control.dig.stream_param = *dig; 127 128 dc_dmub_srv_cmd_queue(dmcub, &cmd); 129 dc_dmub_srv_cmd_execute(dmcub); 130 dc_dmub_srv_wait_idle(dmcub); 131 } 132 133 static enum bp_result encoder_control_digx_v1_5( 134 struct bios_parser *bp, 135 struct bp_encoder_control *cntl) 136 { 137 enum bp_result result = BP_RESULT_FAILURE; 138 struct dig_encoder_stream_setup_parameters_v1_5 params = {0}; 139 140 params.digid = (uint8_t)(cntl->engine_id); 141 params.action = bp->cmd_helper->encoder_action_to_atom(cntl->action); 142 143 params.pclk_10khz = cntl->pixel_clock / 10; 144 params.digmode = 145 (uint8_t)(bp->cmd_helper->encoder_mode_bp_to_atom( 146 cntl->signal, 147 cntl->enable_dp_audio)); 148 params.lanenum = (uint8_t)(cntl->lanes_number); 149 150 switch (cntl->color_depth) { 151 case COLOR_DEPTH_888: 152 params.bitpercolor = PANEL_8BIT_PER_COLOR; 153 break; 154 case COLOR_DEPTH_101010: 155 params.bitpercolor = PANEL_10BIT_PER_COLOR; 156 break; 157 case COLOR_DEPTH_121212: 158 params.bitpercolor = PANEL_12BIT_PER_COLOR; 159 break; 160 case COLOR_DEPTH_161616: 161 params.bitpercolor = PANEL_16BIT_PER_COLOR; 162 break; 163 default: 164 break; 165 } 166 167 if (cntl->signal == SIGNAL_TYPE_HDMI_TYPE_A) 168 switch (cntl->color_depth) { 169 case COLOR_DEPTH_101010: 170 params.pclk_10khz = 171 (params.pclk_10khz * 30) / 24; 172 break; 173 case COLOR_DEPTH_121212: 174 params.pclk_10khz = 175 (params.pclk_10khz * 36) / 24; 176 break; 177 case COLOR_DEPTH_161616: 178 params.pclk_10khz = 179 (params.pclk_10khz * 48) / 24; 180 break; 181 default: 182 break; 183 } 184 185 if (bp->base.ctx->dc->ctx->dmub_srv && 186 bp->base.ctx->dc->debug.dmub_command_table) { 187 encoder_control_dmcub(bp->base.ctx->dmub_srv, ¶ms); 188 return BP_RESULT_OK; 189 } 190 191 if (EXEC_BIOS_CMD_TABLE(digxencodercontrol, params)) 192 result = BP_RESULT_OK; 193 194 return result; 195 } 196 197 static enum bp_result encoder_control_fallback( 198 struct bios_parser *bp, 199 struct bp_encoder_control *cntl) 200 { 201 if (bp->base.ctx->dc->ctx->dmub_srv && 202 bp->base.ctx->dc->debug.dmub_command_table) { 203 return encoder_control_digx_v1_5(bp, cntl); 204 } 205 206 return BP_RESULT_FAILURE; 207 } 208 209 /***************************************************************************** 210 ****************************************************************************** 211 ** 212 ** TRANSMITTER CONTROL 213 ** 214 ****************************************************************************** 215 *****************************************************************************/ 216 217 static enum bp_result transmitter_control_v1_6( 218 struct bios_parser *bp, 219 struct bp_transmitter_control *cntl); 220 221 static enum bp_result transmitter_control_v1_7( 222 struct bios_parser *bp, 223 struct bp_transmitter_control *cntl); 224 225 static enum bp_result transmitter_control_fallback( 226 struct bios_parser *bp, 227 struct bp_transmitter_control *cntl); 228 229 static void init_transmitter_control(struct bios_parser *bp) 230 { 231 uint8_t frev; 232 uint8_t crev; 233 234 BIOS_CMD_TABLE_REVISION(dig1transmittercontrol, frev, crev); 235 236 switch (crev) { 237 case 6: 238 bp->cmd_tbl.transmitter_control = transmitter_control_v1_6; 239 break; 240 case 7: 241 bp->cmd_tbl.transmitter_control = transmitter_control_v1_7; 242 break; 243 default: 244 dm_output_to_console("Don't have transmitter_control for v%d\n", crev); 245 bp->cmd_tbl.transmitter_control = transmitter_control_fallback; 246 break; 247 } 248 } 249 250 static void transmitter_control_dmcub( 251 struct dc_dmub_srv *dmcub, 252 struct dig_transmitter_control_parameters_v1_6 *dig) 253 { 254 union dmub_rb_cmd cmd; 255 256 memset(&cmd, 0, sizeof(cmd)); 257 258 cmd.dig1_transmitter_control.header.type = DMUB_CMD__VBIOS; 259 cmd.dig1_transmitter_control.header.sub_type = 260 DMUB_CMD__VBIOS_DIG1_TRANSMITTER_CONTROL; 261 cmd.dig1_transmitter_control.header.payload_bytes = 262 sizeof(cmd.dig1_transmitter_control) - 263 sizeof(cmd.dig1_transmitter_control.header); 264 cmd.dig1_transmitter_control.transmitter_control.dig = *dig; 265 266 dc_dmub_srv_cmd_queue(dmcub, &cmd); 267 dc_dmub_srv_cmd_execute(dmcub); 268 dc_dmub_srv_wait_idle(dmcub); 269 } 270 271 static enum bp_result transmitter_control_v1_6( 272 struct bios_parser *bp, 273 struct bp_transmitter_control *cntl) 274 { 275 enum bp_result result = BP_RESULT_FAILURE; 276 const struct command_table_helper *cmd = bp->cmd_helper; 277 struct dig_transmitter_control_ps_allocation_v1_6 ps = { { 0 } }; 278 279 ps.param.phyid = cmd->phy_id_to_atom(cntl->transmitter); 280 ps.param.action = (uint8_t)cntl->action; 281 282 if (cntl->action == TRANSMITTER_CONTROL_SET_VOLTAGE_AND_PREEMPASIS) 283 ps.param.mode_laneset.dplaneset = (uint8_t)cntl->lane_settings; 284 else 285 ps.param.mode_laneset.digmode = 286 cmd->signal_type_to_atom_dig_mode(cntl->signal); 287 288 ps.param.lanenum = (uint8_t)cntl->lanes_number; 289 ps.param.hpdsel = cmd->hpd_sel_to_atom(cntl->hpd_sel); 290 ps.param.digfe_sel = cmd->dig_encoder_sel_to_atom(cntl->engine_id); 291 ps.param.connobj_id = (uint8_t)cntl->connector_obj_id.id; 292 ps.param.symclk_10khz = cntl->pixel_clock/10; 293 294 295 if (cntl->action == TRANSMITTER_CONTROL_ENABLE || 296 cntl->action == TRANSMITTER_CONTROL_ACTIAVATE || 297 cntl->action == TRANSMITTER_CONTROL_DEACTIVATE) { 298 DC_LOG_BIOS("%s:ps.param.symclk_10khz = %d\n",\ 299 __func__, ps.param.symclk_10khz); 300 } 301 302 if (bp->base.ctx->dc->ctx->dmub_srv && 303 bp->base.ctx->dc->debug.dmub_command_table) { 304 transmitter_control_dmcub(bp->base.ctx->dmub_srv, &ps.param); 305 return BP_RESULT_OK; 306 } 307 308 /*color_depth not used any more, driver has deep color factor in the Phyclk*/ 309 if (EXEC_BIOS_CMD_TABLE(dig1transmittercontrol, ps)) 310 result = BP_RESULT_OK; 311 return result; 312 } 313 314 static void transmitter_control_dmcub_v1_7( 315 struct dc_dmub_srv *dmcub, 316 struct dmub_dig_transmitter_control_data_v1_7 *dig) 317 { 318 union dmub_rb_cmd cmd; 319 320 memset(&cmd, 0, sizeof(cmd)); 321 322 cmd.dig1_transmitter_control.header.type = DMUB_CMD__VBIOS; 323 cmd.dig1_transmitter_control.header.sub_type = 324 DMUB_CMD__VBIOS_DIG1_TRANSMITTER_CONTROL; 325 cmd.dig1_transmitter_control.header.payload_bytes = 326 sizeof(cmd.dig1_transmitter_control) - 327 sizeof(cmd.dig1_transmitter_control.header); 328 cmd.dig1_transmitter_control.transmitter_control.dig_v1_7 = *dig; 329 330 dc_dmub_srv_cmd_queue(dmcub, &cmd); 331 dc_dmub_srv_cmd_execute(dmcub); 332 dc_dmub_srv_wait_idle(dmcub); 333 } 334 335 static enum bp_result transmitter_control_v1_7( 336 struct bios_parser *bp, 337 struct bp_transmitter_control *cntl) 338 { 339 enum bp_result result = BP_RESULT_FAILURE; 340 const struct command_table_helper *cmd = bp->cmd_helper; 341 struct dmub_dig_transmitter_control_data_v1_7 dig_v1_7 = {0}; 342 343 dig_v1_7.phyid = cmd->phy_id_to_atom(cntl->transmitter); 344 dig_v1_7.action = (uint8_t)cntl->action; 345 346 if (cntl->action == TRANSMITTER_CONTROL_SET_VOLTAGE_AND_PREEMPASIS) 347 dig_v1_7.mode_laneset.dplaneset = (uint8_t)cntl->lane_settings; 348 else 349 dig_v1_7.mode_laneset.digmode = 350 cmd->signal_type_to_atom_dig_mode(cntl->signal); 351 352 dig_v1_7.lanenum = (uint8_t)cntl->lanes_number; 353 dig_v1_7.hpdsel = cmd->hpd_sel_to_atom(cntl->hpd_sel); 354 dig_v1_7.digfe_sel = cmd->dig_encoder_sel_to_atom(cntl->engine_id); 355 dig_v1_7.connobj_id = (uint8_t)cntl->connector_obj_id.id; 356 dig_v1_7.symclk_units.symclk_10khz = cntl->pixel_clock/10; 357 358 if (cntl->action == TRANSMITTER_CONTROL_ENABLE || 359 cntl->action == TRANSMITTER_CONTROL_ACTIAVATE || 360 cntl->action == TRANSMITTER_CONTROL_DEACTIVATE) { 361 DC_LOG_BIOS("%s:dig_v1_7.symclk_units.symclk_10khz = %d\n", 362 __func__, dig_v1_7.symclk_units.symclk_10khz); 363 } 364 365 if (bp->base.ctx->dc->ctx->dmub_srv && 366 bp->base.ctx->dc->debug.dmub_command_table) { 367 transmitter_control_dmcub_v1_7(bp->base.ctx->dmub_srv, &dig_v1_7); 368 return BP_RESULT_OK; 369 } 370 371 /*color_depth not used any more, driver has deep color factor in the Phyclk*/ 372 if (EXEC_BIOS_CMD_TABLE(dig1transmittercontrol, dig_v1_7)) 373 result = BP_RESULT_OK; 374 return result; 375 } 376 377 static enum bp_result transmitter_control_fallback( 378 struct bios_parser *bp, 379 struct bp_transmitter_control *cntl) 380 { 381 if (bp->base.ctx->dc->ctx->dmub_srv && 382 bp->base.ctx->dc->debug.dmub_command_table) { 383 return transmitter_control_v1_7(bp, cntl); 384 } 385 386 return BP_RESULT_FAILURE; 387 } 388 389 /****************************************************************************** 390 ****************************************************************************** 391 ** 392 ** SET PIXEL CLOCK 393 ** 394 ****************************************************************************** 395 *****************************************************************************/ 396 397 static enum bp_result set_pixel_clock_v7( 398 struct bios_parser *bp, 399 struct bp_pixel_clock_parameters *bp_params); 400 401 static enum bp_result set_pixel_clock_fallback( 402 struct bios_parser *bp, 403 struct bp_pixel_clock_parameters *bp_params); 404 405 static void init_set_pixel_clock(struct bios_parser *bp) 406 { 407 switch (BIOS_CMD_TABLE_PARA_REVISION(setpixelclock)) { 408 case 7: 409 bp->cmd_tbl.set_pixel_clock = set_pixel_clock_v7; 410 break; 411 default: 412 dm_output_to_console("Don't have set_pixel_clock for v%d\n", 413 BIOS_CMD_TABLE_PARA_REVISION(setpixelclock)); 414 bp->cmd_tbl.set_pixel_clock = set_pixel_clock_fallback; 415 break; 416 } 417 } 418 419 static void set_pixel_clock_dmcub( 420 struct dc_dmub_srv *dmcub, 421 struct set_pixel_clock_parameter_v1_7 *clk) 422 { 423 union dmub_rb_cmd cmd; 424 425 memset(&cmd, 0, sizeof(cmd)); 426 427 cmd.set_pixel_clock.header.type = DMUB_CMD__VBIOS; 428 cmd.set_pixel_clock.header.sub_type = DMUB_CMD__VBIOS_SET_PIXEL_CLOCK; 429 cmd.set_pixel_clock.header.payload_bytes = 430 sizeof(cmd.set_pixel_clock) - 431 sizeof(cmd.set_pixel_clock.header); 432 cmd.set_pixel_clock.pixel_clock.clk = *clk; 433 434 dc_dmub_srv_cmd_queue(dmcub, &cmd); 435 dc_dmub_srv_cmd_execute(dmcub); 436 dc_dmub_srv_wait_idle(dmcub); 437 } 438 439 static enum bp_result set_pixel_clock_v7( 440 struct bios_parser *bp, 441 struct bp_pixel_clock_parameters *bp_params) 442 { 443 enum bp_result result = BP_RESULT_FAILURE; 444 struct set_pixel_clock_parameter_v1_7 clk; 445 uint8_t controller_id; 446 uint32_t pll_id; 447 448 memset(&clk, 0, sizeof(clk)); 449 450 if (bp->cmd_helper->clock_source_id_to_atom(bp_params->pll_id, &pll_id) 451 && bp->cmd_helper->controller_id_to_atom(bp_params-> 452 controller_id, &controller_id)) { 453 /* Note: VBIOS still wants to use ucCRTC name which is now 454 * 1 byte in ULONG 455 *typedef struct _CRTC_PIXEL_CLOCK_FREQ 456 *{ 457 * target the pixel clock to drive the CRTC timing. 458 * ULONG ulPixelClock:24; 459 * 0 means disable PPLL/DCPLL. Expanded to 24 bits comparing to 460 * previous version. 461 * ATOM_CRTC1~6, indicate the CRTC controller to 462 * ULONG ucCRTC:8; 463 * drive the pixel clock. not used for DCPLL case. 464 *}CRTC_PIXEL_CLOCK_FREQ; 465 *union 466 *{ 467 * pixel clock and CRTC id frequency 468 * CRTC_PIXEL_CLOCK_FREQ ulCrtcPclkFreq; 469 * ULONG ulDispEngClkFreq; dispclk frequency 470 *}; 471 */ 472 clk.crtc_id = controller_id; 473 clk.pll_id = (uint8_t) pll_id; 474 clk.encoderobjid = 475 bp->cmd_helper->encoder_id_to_atom( 476 dal_graphics_object_id_get_encoder_id( 477 bp_params->encoder_object_id)); 478 479 clk.encoder_mode = (uint8_t) bp-> 480 cmd_helper->encoder_mode_bp_to_atom( 481 bp_params->signal_type, false); 482 483 clk.pixclk_100hz = cpu_to_le32(bp_params->target_pixel_clock_100hz); 484 485 clk.deep_color_ratio = 486 (uint8_t) bp->cmd_helper-> 487 transmitter_color_depth_to_atom( 488 bp_params->color_depth); 489 490 DC_LOG_BIOS("%s:program display clock = %d, tg = %d, pll = %d, "\ 491 "colorDepth = %d\n", __func__, 492 bp_params->target_pixel_clock_100hz, (int)controller_id, 493 pll_id, bp_params->color_depth); 494 495 if (bp_params->flags.FORCE_PROGRAMMING_OF_PLL) 496 clk.miscinfo |= PIXEL_CLOCK_V7_MISC_FORCE_PROG_PPLL; 497 498 if (bp_params->flags.PROGRAM_PHY_PLL_ONLY) 499 clk.miscinfo |= PIXEL_CLOCK_V7_MISC_PROG_PHYPLL; 500 501 if (bp_params->flags.SUPPORT_YUV_420) 502 clk.miscinfo |= PIXEL_CLOCK_V7_MISC_YUV420_MODE; 503 504 if (bp_params->flags.SET_XTALIN_REF_SRC) 505 clk.miscinfo |= PIXEL_CLOCK_V7_MISC_REF_DIV_SRC_XTALIN; 506 507 if (bp_params->flags.SET_GENLOCK_REF_DIV_SRC) 508 clk.miscinfo |= PIXEL_CLOCK_V7_MISC_REF_DIV_SRC_GENLK; 509 510 if (bp_params->signal_type == SIGNAL_TYPE_DVI_DUAL_LINK) 511 clk.miscinfo |= PIXEL_CLOCK_V7_MISC_DVI_DUALLINK_EN; 512 513 if (bp->base.ctx->dc->ctx->dmub_srv && 514 bp->base.ctx->dc->debug.dmub_command_table) { 515 set_pixel_clock_dmcub(bp->base.ctx->dmub_srv, &clk); 516 return BP_RESULT_OK; 517 } 518 519 if (EXEC_BIOS_CMD_TABLE(setpixelclock, clk)) 520 result = BP_RESULT_OK; 521 } 522 return result; 523 } 524 525 static enum bp_result set_pixel_clock_fallback( 526 struct bios_parser *bp, 527 struct bp_pixel_clock_parameters *bp_params) 528 { 529 if (bp->base.ctx->dc->ctx->dmub_srv && 530 bp->base.ctx->dc->debug.dmub_command_table) { 531 return set_pixel_clock_v7(bp, bp_params); 532 } 533 534 return BP_RESULT_FAILURE; 535 } 536 537 /****************************************************************************** 538 ****************************************************************************** 539 ** 540 ** SET CRTC TIMING 541 ** 542 ****************************************************************************** 543 *****************************************************************************/ 544 545 static enum bp_result set_crtc_using_dtd_timing_v3( 546 struct bios_parser *bp, 547 struct bp_hw_crtc_timing_parameters *bp_params); 548 549 static void init_set_crtc_timing(struct bios_parser *bp) 550 { 551 uint32_t dtd_version = 552 BIOS_CMD_TABLE_PARA_REVISION(setcrtc_usingdtdtiming); 553 554 switch (dtd_version) { 555 case 3: 556 bp->cmd_tbl.set_crtc_timing = 557 set_crtc_using_dtd_timing_v3; 558 break; 559 default: 560 dm_output_to_console("Don't have set_crtc_timing for v%d\n", dtd_version); 561 bp->cmd_tbl.set_crtc_timing = NULL; 562 break; 563 } 564 } 565 566 static enum bp_result set_crtc_using_dtd_timing_v3( 567 struct bios_parser *bp, 568 struct bp_hw_crtc_timing_parameters *bp_params) 569 { 570 enum bp_result result = BP_RESULT_FAILURE; 571 struct set_crtc_using_dtd_timing_parameters params = {0}; 572 uint8_t atom_controller_id; 573 574 if (bp->cmd_helper->controller_id_to_atom( 575 bp_params->controller_id, &atom_controller_id)) 576 params.crtc_id = atom_controller_id; 577 578 /* bios usH_Size wants h addressable size */ 579 params.h_size = cpu_to_le16((uint16_t)bp_params->h_addressable); 580 /* bios usH_Blanking_Time wants borders included in blanking */ 581 params.h_blanking_time = 582 cpu_to_le16((uint16_t)(bp_params->h_total - 583 bp_params->h_addressable)); 584 /* bios usV_Size wants v addressable size */ 585 params.v_size = cpu_to_le16((uint16_t)bp_params->v_addressable); 586 /* bios usV_Blanking_Time wants borders included in blanking */ 587 params.v_blanking_time = 588 cpu_to_le16((uint16_t)(bp_params->v_total - 589 bp_params->v_addressable)); 590 /* bios usHSyncOffset is the offset from the end of h addressable, 591 * our horizontalSyncStart is the offset from the beginning 592 * of h addressable 593 */ 594 params.h_syncoffset = 595 cpu_to_le16((uint16_t)(bp_params->h_sync_start - 596 bp_params->h_addressable)); 597 params.h_syncwidth = cpu_to_le16((uint16_t)bp_params->h_sync_width); 598 /* bios usHSyncOffset is the offset from the end of v addressable, 599 * our verticalSyncStart is the offset from the beginning of 600 * v addressable 601 */ 602 params.v_syncoffset = 603 cpu_to_le16((uint16_t)(bp_params->v_sync_start - 604 bp_params->v_addressable)); 605 params.v_syncwidth = cpu_to_le16((uint16_t)bp_params->v_sync_width); 606 607 /* we assume that overscan from original timing does not get bigger 608 * than 255 609 * we will program all the borders in the Set CRTC Overscan call below 610 */ 611 612 if (bp_params->flags.HSYNC_POSITIVE_POLARITY == 0) 613 params.modemiscinfo = 614 cpu_to_le16(le16_to_cpu(params.modemiscinfo) | 615 ATOM_HSYNC_POLARITY); 616 617 if (bp_params->flags.VSYNC_POSITIVE_POLARITY == 0) 618 params.modemiscinfo = 619 cpu_to_le16(le16_to_cpu(params.modemiscinfo) | 620 ATOM_VSYNC_POLARITY); 621 622 if (bp_params->flags.INTERLACE) { 623 params.modemiscinfo = 624 cpu_to_le16(le16_to_cpu(params.modemiscinfo) | 625 ATOM_INTERLACE); 626 627 /* original DAL code has this condition to apply this 628 * for non-TV/CV only 629 * due to complex MV testing for possible impact 630 * if ( pACParameters->signal != SignalType_YPbPr && 631 * pACParameters->signal != SignalType_Composite && 632 * pACParameters->signal != SignalType_SVideo) 633 */ 634 { 635 /* HW will deduct 0.5 line from 2nd feild. 636 * i.e. for 1080i, it is 2 lines for 1st field, 637 * 2.5 lines for the 2nd feild. we need input as 5 638 * instead of 4. 639 * but it is 4 either from Edid data (spec CEA 861) 640 * or CEA timing table. 641 */ 642 le16_add_cpu(¶ms.v_syncoffset, 1); 643 } 644 } 645 646 if (bp_params->flags.HORZ_COUNT_BY_TWO) 647 params.modemiscinfo = 648 cpu_to_le16(le16_to_cpu(params.modemiscinfo) | 649 0x100); /* ATOM_DOUBLE_CLOCK_MODE */ 650 651 if (EXEC_BIOS_CMD_TABLE(setcrtc_usingdtdtiming, params)) 652 result = BP_RESULT_OK; 653 654 return result; 655 } 656 657 /****************************************************************************** 658 ****************************************************************************** 659 ** 660 ** ENABLE CRTC 661 ** 662 ****************************************************************************** 663 *****************************************************************************/ 664 665 static enum bp_result enable_crtc_v1( 666 struct bios_parser *bp, 667 enum controller_id controller_id, 668 bool enable); 669 670 static void init_enable_crtc(struct bios_parser *bp) 671 { 672 switch (BIOS_CMD_TABLE_PARA_REVISION(enablecrtc)) { 673 case 1: 674 bp->cmd_tbl.enable_crtc = enable_crtc_v1; 675 break; 676 default: 677 dm_output_to_console("Don't have enable_crtc for v%d\n", 678 BIOS_CMD_TABLE_PARA_REVISION(enablecrtc)); 679 bp->cmd_tbl.enable_crtc = NULL; 680 break; 681 } 682 } 683 684 static enum bp_result enable_crtc_v1( 685 struct bios_parser *bp, 686 enum controller_id controller_id, 687 bool enable) 688 { 689 bool result = BP_RESULT_FAILURE; 690 struct enable_crtc_parameters params = {0}; 691 uint8_t id; 692 693 if (bp->cmd_helper->controller_id_to_atom(controller_id, &id)) 694 params.crtc_id = id; 695 else 696 return BP_RESULT_BADINPUT; 697 698 if (enable) 699 params.enable = ATOM_ENABLE; 700 else 701 params.enable = ATOM_DISABLE; 702 703 if (EXEC_BIOS_CMD_TABLE(enablecrtc, params)) 704 result = BP_RESULT_OK; 705 706 return result; 707 } 708 709 /****************************************************************************** 710 ****************************************************************************** 711 ** 712 ** DISPLAY PLL 713 ** 714 ****************************************************************************** 715 *****************************************************************************/ 716 717 718 719 /****************************************************************************** 720 ****************************************************************************** 721 ** 722 ** EXTERNAL ENCODER CONTROL 723 ** 724 ****************************************************************************** 725 *****************************************************************************/ 726 727 static enum bp_result external_encoder_control_v3( 728 struct bios_parser *bp, 729 struct bp_external_encoder_control *cntl); 730 731 static void init_external_encoder_control( 732 struct bios_parser *bp) 733 { 734 switch (BIOS_CMD_TABLE_PARA_REVISION(externalencodercontrol)) { 735 case 3: 736 bp->cmd_tbl.external_encoder_control = 737 external_encoder_control_v3; 738 break; 739 default: 740 bp->cmd_tbl.external_encoder_control = NULL; 741 break; 742 } 743 } 744 745 static enum bp_result external_encoder_control_v3( 746 struct bios_parser *bp, 747 struct bp_external_encoder_control *cntl) 748 { 749 /* TODO */ 750 return BP_RESULT_OK; 751 } 752 753 /****************************************************************************** 754 ****************************************************************************** 755 ** 756 ** ENABLE DISPLAY POWER GATING 757 ** 758 ****************************************************************************** 759 *****************************************************************************/ 760 761 static enum bp_result enable_disp_power_gating_v2_1( 762 struct bios_parser *bp, 763 enum controller_id crtc_id, 764 enum bp_pipe_control_action action); 765 766 static enum bp_result enable_disp_power_gating_fallback( 767 struct bios_parser *bp, 768 enum controller_id crtc_id, 769 enum bp_pipe_control_action action); 770 771 static void init_enable_disp_power_gating( 772 struct bios_parser *bp) 773 { 774 switch (BIOS_CMD_TABLE_PARA_REVISION(enabledisppowergating)) { 775 case 1: 776 bp->cmd_tbl.enable_disp_power_gating = 777 enable_disp_power_gating_v2_1; 778 break; 779 default: 780 dm_output_to_console("Don't enable_disp_power_gating enable_crtc for v%d\n", 781 BIOS_CMD_TABLE_PARA_REVISION(enabledisppowergating)); 782 bp->cmd_tbl.enable_disp_power_gating = enable_disp_power_gating_fallback; 783 break; 784 } 785 } 786 787 static void enable_disp_power_gating_dmcub( 788 struct dc_dmub_srv *dmcub, 789 struct enable_disp_power_gating_parameters_v2_1 *pwr) 790 { 791 union dmub_rb_cmd cmd; 792 793 memset(&cmd, 0, sizeof(cmd)); 794 795 cmd.enable_disp_power_gating.header.type = DMUB_CMD__VBIOS; 796 cmd.enable_disp_power_gating.header.sub_type = 797 DMUB_CMD__VBIOS_ENABLE_DISP_POWER_GATING; 798 cmd.enable_disp_power_gating.header.payload_bytes = 799 sizeof(cmd.enable_disp_power_gating) - 800 sizeof(cmd.enable_disp_power_gating.header); 801 cmd.enable_disp_power_gating.power_gating.pwr = *pwr; 802 803 dc_dmub_srv_cmd_queue(dmcub, &cmd); 804 dc_dmub_srv_cmd_execute(dmcub); 805 dc_dmub_srv_wait_idle(dmcub); 806 } 807 808 static enum bp_result enable_disp_power_gating_v2_1( 809 struct bios_parser *bp, 810 enum controller_id crtc_id, 811 enum bp_pipe_control_action action) 812 { 813 enum bp_result result = BP_RESULT_FAILURE; 814 815 816 struct enable_disp_power_gating_ps_allocation ps = { { 0 } }; 817 uint8_t atom_crtc_id; 818 819 if (bp->cmd_helper->controller_id_to_atom(crtc_id, &atom_crtc_id)) 820 ps.param.disp_pipe_id = atom_crtc_id; 821 else 822 return BP_RESULT_BADINPUT; 823 824 ps.param.enable = 825 bp->cmd_helper->disp_power_gating_action_to_atom(action); 826 827 if (bp->base.ctx->dc->ctx->dmub_srv && 828 bp->base.ctx->dc->debug.dmub_command_table) { 829 enable_disp_power_gating_dmcub(bp->base.ctx->dmub_srv, 830 &ps.param); 831 return BP_RESULT_OK; 832 } 833 834 if (EXEC_BIOS_CMD_TABLE(enabledisppowergating, ps.param)) 835 result = BP_RESULT_OK; 836 837 return result; 838 } 839 840 static enum bp_result enable_disp_power_gating_fallback( 841 struct bios_parser *bp, 842 enum controller_id crtc_id, 843 enum bp_pipe_control_action action) 844 { 845 if (bp->base.ctx->dc->ctx->dmub_srv && 846 bp->base.ctx->dc->debug.dmub_command_table) { 847 return enable_disp_power_gating_v2_1(bp, crtc_id, action); 848 } 849 850 return BP_RESULT_FAILURE; 851 } 852 853 /****************************************************************************** 854 ******************************************************************************* 855 ** 856 ** SET DCE CLOCK 857 ** 858 ******************************************************************************* 859 *******************************************************************************/ 860 861 static enum bp_result set_dce_clock_v2_1( 862 struct bios_parser *bp, 863 struct bp_set_dce_clock_parameters *bp_params); 864 865 static void init_set_dce_clock(struct bios_parser *bp) 866 { 867 switch (BIOS_CMD_TABLE_PARA_REVISION(setdceclock)) { 868 case 1: 869 bp->cmd_tbl.set_dce_clock = set_dce_clock_v2_1; 870 break; 871 default: 872 dm_output_to_console("Don't have set_dce_clock for v%d\n", 873 BIOS_CMD_TABLE_PARA_REVISION(setdceclock)); 874 bp->cmd_tbl.set_dce_clock = NULL; 875 break; 876 } 877 } 878 879 static enum bp_result set_dce_clock_v2_1( 880 struct bios_parser *bp, 881 struct bp_set_dce_clock_parameters *bp_params) 882 { 883 enum bp_result result = BP_RESULT_FAILURE; 884 885 struct set_dce_clock_ps_allocation_v2_1 params; 886 uint32_t atom_pll_id; 887 uint32_t atom_clock_type; 888 const struct command_table_helper *cmd = bp->cmd_helper; 889 890 memset(¶ms, 0, sizeof(params)); 891 892 if (!cmd->clock_source_id_to_atom(bp_params->pll_id, &atom_pll_id) || 893 !cmd->dc_clock_type_to_atom(bp_params->clock_type, 894 &atom_clock_type)) 895 return BP_RESULT_BADINPUT; 896 897 params.param.dceclksrc = atom_pll_id; 898 params.param.dceclktype = atom_clock_type; 899 900 if (bp_params->clock_type == DCECLOCK_TYPE_DPREFCLK) { 901 if (bp_params->flags.USE_GENLOCK_AS_SOURCE_FOR_DPREFCLK) 902 params.param.dceclkflag |= 903 DCE_CLOCK_FLAG_PLL_REFCLK_SRC_GENLK; 904 905 if (bp_params->flags.USE_PCIE_AS_SOURCE_FOR_DPREFCLK) 906 params.param.dceclkflag |= 907 DCE_CLOCK_FLAG_PLL_REFCLK_SRC_PCIE; 908 909 if (bp_params->flags.USE_XTALIN_AS_SOURCE_FOR_DPREFCLK) 910 params.param.dceclkflag |= 911 DCE_CLOCK_FLAG_PLL_REFCLK_SRC_XTALIN; 912 913 if (bp_params->flags.USE_GENERICA_AS_SOURCE_FOR_DPREFCLK) 914 params.param.dceclkflag |= 915 DCE_CLOCK_FLAG_PLL_REFCLK_SRC_GENERICA; 916 } else 917 /* only program clock frequency if display clock is used; 918 * VBIOS will program DPREFCLK 919 * We need to convert from KHz units into 10KHz units 920 */ 921 params.param.dceclk_10khz = cpu_to_le32( 922 bp_params->target_clock_frequency / 10); 923 DC_LOG_BIOS("%s:target_clock_frequency = %d"\ 924 "clock_type = %d \n", __func__,\ 925 bp_params->target_clock_frequency,\ 926 bp_params->clock_type); 927 928 if (EXEC_BIOS_CMD_TABLE(setdceclock, params)) { 929 /* Convert from 10KHz units back to KHz */ 930 bp_params->target_clock_frequency = le32_to_cpu( 931 params.param.dceclk_10khz) * 10; 932 result = BP_RESULT_OK; 933 } 934 935 return result; 936 } 937 938 939 /****************************************************************************** 940 ****************************************************************************** 941 ** 942 ** GET SMU CLOCK INFO 943 ** 944 ****************************************************************************** 945 *****************************************************************************/ 946 947 static unsigned int get_smu_clock_info_v3_1(struct bios_parser *bp, uint8_t id); 948 949 static void init_get_smu_clock_info(struct bios_parser *bp) 950 { 951 /* TODO add switch for table vrsion */ 952 bp->cmd_tbl.get_smu_clock_info = get_smu_clock_info_v3_1; 953 954 } 955 956 static unsigned int get_smu_clock_info_v3_1(struct bios_parser *bp, uint8_t id) 957 { 958 struct atom_get_smu_clock_info_parameters_v3_1 smu_input = {0}; 959 struct atom_get_smu_clock_info_output_parameters_v3_1 smu_output; 960 961 smu_input.command = GET_SMU_CLOCK_INFO_V3_1_GET_PLLVCO_FREQ; 962 smu_input.syspll_id = id; 963 964 /* Get Specific Clock */ 965 if (EXEC_BIOS_CMD_TABLE(getsmuclockinfo, smu_input)) { 966 memmove(&smu_output, &smu_input, sizeof( 967 struct atom_get_smu_clock_info_parameters_v3_1)); 968 return smu_output.atom_smu_outputclkfreq.syspllvcofreq_10khz; 969 } 970 971 return 0; 972 } 973 974 /****************************************************************************** 975 ****************************************************************************** 976 ** 977 ** LVTMA CONTROL 978 ** 979 ****************************************************************************** 980 *****************************************************************************/ 981 982 static enum bp_result enable_lvtma_control( 983 struct bios_parser *bp, 984 uint8_t uc_pwr_on, 985 uint8_t panel_instance); 986 987 static void init_enable_lvtma_control(struct bios_parser *bp) 988 { 989 /* TODO add switch for table vrsion */ 990 bp->cmd_tbl.enable_lvtma_control = enable_lvtma_control; 991 992 } 993 994 static void enable_lvtma_control_dmcub( 995 struct dc_dmub_srv *dmcub, 996 uint8_t uc_pwr_on, 997 uint8_t panel_instance) 998 { 999 1000 union dmub_rb_cmd cmd; 1001 1002 memset(&cmd, 0, sizeof(cmd)); 1003 1004 cmd.lvtma_control.header.type = DMUB_CMD__VBIOS; 1005 cmd.lvtma_control.header.sub_type = 1006 DMUB_CMD__VBIOS_LVTMA_CONTROL; 1007 cmd.lvtma_control.data.uc_pwr_action = 1008 uc_pwr_on; 1009 cmd.lvtma_control.data.panel_inst = 1010 panel_instance; 1011 dc_dmub_srv_cmd_queue(dmcub, &cmd); 1012 dc_dmub_srv_cmd_execute(dmcub); 1013 dc_dmub_srv_wait_idle(dmcub); 1014 1015 } 1016 1017 static enum bp_result enable_lvtma_control( 1018 struct bios_parser *bp, 1019 uint8_t uc_pwr_on, 1020 uint8_t panel_instance) 1021 { 1022 enum bp_result result = BP_RESULT_FAILURE; 1023 1024 if (bp->base.ctx->dc->ctx->dmub_srv && 1025 bp->base.ctx->dc->debug.dmub_command_table) { 1026 enable_lvtma_control_dmcub(bp->base.ctx->dmub_srv, 1027 uc_pwr_on, 1028 panel_instance); 1029 return BP_RESULT_OK; 1030 } 1031 return result; 1032 } 1033 1034 void dal_firmware_parser_init_cmd_tbl(struct bios_parser *bp) 1035 { 1036 init_dig_encoder_control(bp); 1037 init_transmitter_control(bp); 1038 init_set_pixel_clock(bp); 1039 1040 init_set_crtc_timing(bp); 1041 1042 init_enable_crtc(bp); 1043 1044 init_external_encoder_control(bp); 1045 init_enable_disp_power_gating(bp); 1046 init_set_dce_clock(bp); 1047 init_get_smu_clock_info(bp); 1048 1049 init_enable_lvtma_control(bp); 1050 } 1051