root/drivers/gpu/drm/amd/display/dc/bios/command_table.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. dal_bios_parser_init_cmd_tbl
  2. bios_cmd_table_para_revision
  3. init_dig_encoder_control
  4. init_encoder_control_dig_v1
  5. encoder_control_dig_v1
  6. encoder_control_dig1_v1
  7. encoder_control_dig2_v1
  8. encoder_control_digx_v3
  9. encoder_control_digx_v4
  10. encoder_control_digx_v5
  11. init_transmitter_control
  12. transmitter_control_v2
  13. transmitter_control_v3
  14. transmitter_control_v4
  15. transmitter_control_v1_5
  16. transmitter_control_v1_6
  17. init_set_pixel_clock
  18. set_pixel_clock_v3
  19. set_pixel_clock_v5
  20. set_pixel_clock_v6
  21. set_pixel_clock_v7
  22. init_enable_spread_spectrum_on_ppll
  23. enable_spread_spectrum_on_ppll_v1
  24. enable_spread_spectrum_on_ppll_v2
  25. enable_spread_spectrum_on_ppll_v3
  26. init_adjust_display_pll
  27. adjust_display_pll_v2
  28. adjust_display_pll_v3
  29. init_dac_encoder_control
  30. dac_encoder_control_prepare_params
  31. dac1_encoder_control_v1
  32. dac2_encoder_control_v1
  33. init_dac_output_control
  34. dac1_output_control_v1
  35. dac2_output_control_v1
  36. init_set_crtc_timing
  37. set_crtc_timing_v1
  38. set_crtc_using_dtd_timing_v3
  39. init_enable_crtc
  40. enable_crtc_v1
  41. init_enable_crtc_mem_req
  42. enable_crtc_mem_req_v1
  43. init_program_clock
  44. program_clock_v5
  45. program_clock_v6
  46. init_external_encoder_control
  47. external_encoder_control_v3
  48. init_enable_disp_power_gating
  49. enable_disp_power_gating_v2_1
  50. init_set_dce_clock
  51. set_dce_clock_v2_1

   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 #include "amdgpu.h"
  28 #include "atom.h"
  29 
  30 #include "include/bios_parser_interface.h"
  31 
  32 #include "command_table.h"
  33 #include "command_table_helper.h"
  34 #include "bios_parser_helper.h"
  35 #include "bios_parser_types_internal.h"
  36 
  37 #define EXEC_BIOS_CMD_TABLE(command, params)\
  38         (amdgpu_atom_execute_table(((struct amdgpu_device *)bp->base.ctx->driver_context)->mode_info.atom_context, \
  39                 GetIndexIntoMasterTable(COMMAND, command), \
  40                 (uint32_t *)&params) == 0)
  41 
  42 #define BIOS_CMD_TABLE_REVISION(command, frev, crev)\
  43         amdgpu_atom_parse_cmd_header(((struct amdgpu_device *)bp->base.ctx->driver_context)->mode_info.atom_context, \
  44                 GetIndexIntoMasterTable(COMMAND, command), &frev, &crev)
  45 
  46 #define BIOS_CMD_TABLE_PARA_REVISION(command)\
  47         bios_cmd_table_para_revision(bp->base.ctx->driver_context, \
  48                 GetIndexIntoMasterTable(COMMAND, command))
  49 
  50 static void init_dig_encoder_control(struct bios_parser *bp);
  51 static void init_transmitter_control(struct bios_parser *bp);
  52 static void init_set_pixel_clock(struct bios_parser *bp);
  53 static void init_enable_spread_spectrum_on_ppll(struct bios_parser *bp);
  54 static void init_adjust_display_pll(struct bios_parser *bp);
  55 static void init_dac_encoder_control(struct bios_parser *bp);
  56 static void init_dac_output_control(struct bios_parser *bp);
  57 static void init_set_crtc_timing(struct bios_parser *bp);
  58 static void init_enable_crtc(struct bios_parser *bp);
  59 static void init_enable_crtc_mem_req(struct bios_parser *bp);
  60 static void init_external_encoder_control(struct bios_parser *bp);
  61 static void init_enable_disp_power_gating(struct bios_parser *bp);
  62 static void init_program_clock(struct bios_parser *bp);
  63 static void init_set_dce_clock(struct bios_parser *bp);
  64 
  65 void dal_bios_parser_init_cmd_tbl(struct bios_parser *bp)
  66 {
  67         init_dig_encoder_control(bp);
  68         init_transmitter_control(bp);
  69         init_set_pixel_clock(bp);
  70         init_enable_spread_spectrum_on_ppll(bp);
  71         init_adjust_display_pll(bp);
  72         init_dac_encoder_control(bp);
  73         init_dac_output_control(bp);
  74         init_set_crtc_timing(bp);
  75         init_enable_crtc(bp);
  76         init_enable_crtc_mem_req(bp);
  77         init_program_clock(bp);
  78         init_external_encoder_control(bp);
  79         init_enable_disp_power_gating(bp);
  80         init_set_dce_clock(bp);
  81 }
  82 
  83 static uint32_t bios_cmd_table_para_revision(void *dev,
  84                                              uint32_t index)
  85 {
  86         struct amdgpu_device *adev = dev;
  87         uint8_t frev, crev;
  88 
  89         if (amdgpu_atom_parse_cmd_header(adev->mode_info.atom_context,
  90                                         index,
  91                                         &frev, &crev))
  92                 return crev;
  93         else
  94                 return 0;
  95 }
  96 
  97 /*******************************************************************************
  98  ********************************************************************************
  99  **
 100  **                  D I G E N C O D E R C O N T R O L
 101  **
 102  ********************************************************************************
 103  *******************************************************************************/
 104 static enum bp_result encoder_control_digx_v3(
 105         struct bios_parser *bp,
 106         struct bp_encoder_control *cntl);
 107 
 108 static enum bp_result encoder_control_digx_v4(
 109         struct bios_parser *bp,
 110         struct bp_encoder_control *cntl);
 111 
 112 static enum bp_result encoder_control_digx_v5(
 113         struct bios_parser *bp,
 114         struct bp_encoder_control *cntl);
 115 
 116 static void init_encoder_control_dig_v1(struct bios_parser *bp);
 117 
 118 static void init_dig_encoder_control(struct bios_parser *bp)
 119 {
 120         uint32_t version =
 121                 BIOS_CMD_TABLE_PARA_REVISION(DIGxEncoderControl);
 122 
 123         switch (version) {
 124         case 2:
 125                 bp->cmd_tbl.dig_encoder_control = encoder_control_digx_v3;
 126                 break;
 127         case 4:
 128                 bp->cmd_tbl.dig_encoder_control = encoder_control_digx_v4;
 129                 break;
 130 
 131         case 5:
 132                 bp->cmd_tbl.dig_encoder_control = encoder_control_digx_v5;
 133                 break;
 134 
 135         default:
 136                 init_encoder_control_dig_v1(bp);
 137                 break;
 138         }
 139 }
 140 
 141 static enum bp_result encoder_control_dig_v1(
 142         struct bios_parser *bp,
 143         struct bp_encoder_control *cntl);
 144 static enum bp_result encoder_control_dig1_v1(
 145         struct bios_parser *bp,
 146         struct bp_encoder_control *cntl);
 147 static enum bp_result encoder_control_dig2_v1(
 148         struct bios_parser *bp,
 149         struct bp_encoder_control *cntl);
 150 
 151 static void init_encoder_control_dig_v1(struct bios_parser *bp)
 152 {
 153         struct cmd_tbl *cmd_tbl = &bp->cmd_tbl;
 154 
 155         if (1 == BIOS_CMD_TABLE_PARA_REVISION(DIG1EncoderControl))
 156                 cmd_tbl->encoder_control_dig1 = encoder_control_dig1_v1;
 157         else
 158                 cmd_tbl->encoder_control_dig1 = NULL;
 159 
 160         if (1 == BIOS_CMD_TABLE_PARA_REVISION(DIG2EncoderControl))
 161                 cmd_tbl->encoder_control_dig2 = encoder_control_dig2_v1;
 162         else
 163                 cmd_tbl->encoder_control_dig2 = NULL;
 164 
 165         cmd_tbl->dig_encoder_control = encoder_control_dig_v1;
 166 }
 167 
 168 static enum bp_result encoder_control_dig_v1(
 169         struct bios_parser *bp,
 170         struct bp_encoder_control *cntl)
 171 {
 172         enum bp_result result = BP_RESULT_FAILURE;
 173         struct cmd_tbl *cmd_tbl = &bp->cmd_tbl;
 174 
 175         if (cntl != NULL)
 176                 switch (cntl->engine_id) {
 177                 case ENGINE_ID_DIGA:
 178                         if (cmd_tbl->encoder_control_dig1 != NULL)
 179                                 result =
 180                                         cmd_tbl->encoder_control_dig1(bp, cntl);
 181                         break;
 182                 case ENGINE_ID_DIGB:
 183                         if (cmd_tbl->encoder_control_dig2 != NULL)
 184                                 result =
 185                                         cmd_tbl->encoder_control_dig2(bp, cntl);
 186                         break;
 187 
 188                 default:
 189                         break;
 190                 }
 191 
 192         return result;
 193 }
 194 
 195 static enum bp_result encoder_control_dig1_v1(
 196         struct bios_parser *bp,
 197         struct bp_encoder_control *cntl)
 198 {
 199         enum bp_result result = BP_RESULT_FAILURE;
 200         DIG_ENCODER_CONTROL_PARAMETERS_V2 params = {0};
 201 
 202         bp->cmd_helper->assign_control_parameter(bp->cmd_helper, cntl, &params);
 203 
 204         if (EXEC_BIOS_CMD_TABLE(DIG1EncoderControl, params))
 205                 result = BP_RESULT_OK;
 206 
 207         return result;
 208 }
 209 
 210 static enum bp_result encoder_control_dig2_v1(
 211         struct bios_parser *bp,
 212         struct bp_encoder_control *cntl)
 213 {
 214         enum bp_result result = BP_RESULT_FAILURE;
 215         DIG_ENCODER_CONTROL_PARAMETERS_V2 params = {0};
 216 
 217         bp->cmd_helper->assign_control_parameter(bp->cmd_helper, cntl, &params);
 218 
 219         if (EXEC_BIOS_CMD_TABLE(DIG2EncoderControl, params))
 220                 result = BP_RESULT_OK;
 221 
 222         return result;
 223 }
 224 
 225 static enum bp_result encoder_control_digx_v3(
 226         struct bios_parser *bp,
 227         struct bp_encoder_control *cntl)
 228 {
 229         enum bp_result result = BP_RESULT_FAILURE;
 230         DIG_ENCODER_CONTROL_PARAMETERS_V3 params = {0};
 231 
 232         if (LANE_COUNT_FOUR < cntl->lanes_number)
 233                 params.acConfig.ucDPLinkRate = 1; /* dual link 2.7GHz */
 234         else
 235                 params.acConfig.ucDPLinkRate = 0; /* single link 1.62GHz */
 236 
 237         params.acConfig.ucDigSel = (uint8_t)(cntl->engine_id);
 238 
 239         /* We need to convert from KHz units into 10KHz units */
 240         params.ucAction = bp->cmd_helper->encoder_action_to_atom(cntl->action);
 241         params.usPixelClock = cpu_to_le16((uint16_t)(cntl->pixel_clock / 10));
 242         params.ucEncoderMode =
 243                         (uint8_t)bp->cmd_helper->encoder_mode_bp_to_atom(
 244                                         cntl->signal,
 245                                         cntl->enable_dp_audio);
 246         params.ucLaneNum = (uint8_t)(cntl->lanes_number);
 247 
 248         if (EXEC_BIOS_CMD_TABLE(DIGxEncoderControl, params))
 249                 result = BP_RESULT_OK;
 250 
 251         return result;
 252 }
 253 
 254 static enum bp_result encoder_control_digx_v4(
 255         struct bios_parser *bp,
 256         struct bp_encoder_control *cntl)
 257 {
 258         enum bp_result result = BP_RESULT_FAILURE;
 259         DIG_ENCODER_CONTROL_PARAMETERS_V4 params = {0};
 260 
 261         if (LANE_COUNT_FOUR < cntl->lanes_number)
 262                 params.acConfig.ucDPLinkRate = 1; /* dual link 2.7GHz */
 263         else
 264                 params.acConfig.ucDPLinkRate = 0; /* single link 1.62GHz */
 265 
 266         params.acConfig.ucDigSel = (uint8_t)(cntl->engine_id);
 267 
 268         /* We need to convert from KHz units into 10KHz units */
 269         params.ucAction = bp->cmd_helper->encoder_action_to_atom(cntl->action);
 270         params.usPixelClock = cpu_to_le16((uint16_t)(cntl->pixel_clock / 10));
 271         params.ucEncoderMode =
 272                         (uint8_t)(bp->cmd_helper->encoder_mode_bp_to_atom(
 273                                         cntl->signal,
 274                                         cntl->enable_dp_audio));
 275         params.ucLaneNum = (uint8_t)(cntl->lanes_number);
 276 
 277         if (EXEC_BIOS_CMD_TABLE(DIGxEncoderControl, params))
 278                 result = BP_RESULT_OK;
 279 
 280         return result;
 281 }
 282 
 283 static enum bp_result encoder_control_digx_v5(
 284         struct bios_parser *bp,
 285         struct bp_encoder_control *cntl)
 286 {
 287         enum bp_result result = BP_RESULT_FAILURE;
 288         ENCODER_STREAM_SETUP_PARAMETERS_V5 params = {0};
 289 
 290         params.ucDigId = (uint8_t)(cntl->engine_id);
 291         params.ucAction = bp->cmd_helper->encoder_action_to_atom(cntl->action);
 292 
 293         params.ulPixelClock = cntl->pixel_clock / 10;
 294         params.ucDigMode =
 295                         (uint8_t)(bp->cmd_helper->encoder_mode_bp_to_atom(
 296                                         cntl->signal,
 297                                         cntl->enable_dp_audio));
 298         params.ucLaneNum = (uint8_t)(cntl->lanes_number);
 299 
 300         switch (cntl->color_depth) {
 301         case COLOR_DEPTH_888:
 302                 params.ucBitPerColor = PANEL_8BIT_PER_COLOR;
 303                 break;
 304         case COLOR_DEPTH_101010:
 305                 params.ucBitPerColor = PANEL_10BIT_PER_COLOR;
 306                 break;
 307         case COLOR_DEPTH_121212:
 308                 params.ucBitPerColor = PANEL_12BIT_PER_COLOR;
 309                 break;
 310         case COLOR_DEPTH_161616:
 311                 params.ucBitPerColor = PANEL_16BIT_PER_COLOR;
 312                 break;
 313         default:
 314                 break;
 315         }
 316 
 317         if (cntl->signal == SIGNAL_TYPE_HDMI_TYPE_A)
 318                 switch (cntl->color_depth) {
 319                 case COLOR_DEPTH_101010:
 320                         params.ulPixelClock =
 321                                 (params.ulPixelClock * 30) / 24;
 322                         break;
 323                 case COLOR_DEPTH_121212:
 324                         params.ulPixelClock =
 325                                 (params.ulPixelClock * 36) / 24;
 326                         break;
 327                 case COLOR_DEPTH_161616:
 328                         params.ulPixelClock =
 329                                 (params.ulPixelClock * 48) / 24;
 330                         break;
 331                 default:
 332                         break;
 333                 }
 334 
 335         if (EXEC_BIOS_CMD_TABLE(DIGxEncoderControl, params))
 336                 result = BP_RESULT_OK;
 337 
 338         return result;
 339 }
 340 
 341 /*******************************************************************************
 342  ********************************************************************************
 343  **
 344  **                  TRANSMITTER CONTROL
 345  **
 346  ********************************************************************************
 347  *******************************************************************************/
 348 
 349 static enum bp_result transmitter_control_v2(
 350         struct bios_parser *bp,
 351         struct bp_transmitter_control *cntl);
 352 static enum bp_result transmitter_control_v3(
 353         struct bios_parser *bp,
 354         struct bp_transmitter_control *cntl);
 355 static enum bp_result transmitter_control_v4(
 356         struct bios_parser *bp,
 357         struct bp_transmitter_control *cntl);
 358 static enum bp_result transmitter_control_v1_5(
 359         struct bios_parser *bp,
 360         struct bp_transmitter_control *cntl);
 361 static enum bp_result transmitter_control_v1_6(
 362         struct bios_parser *bp,
 363         struct bp_transmitter_control *cntl);
 364 
 365 static void init_transmitter_control(struct bios_parser *bp)
 366 {
 367         uint8_t frev;
 368         uint8_t crev;
 369 
 370         if (BIOS_CMD_TABLE_REVISION(UNIPHYTransmitterControl,
 371                         frev, crev) == false)
 372                 BREAK_TO_DEBUGGER();
 373         switch (crev) {
 374         case 2:
 375                 bp->cmd_tbl.transmitter_control = transmitter_control_v2;
 376                 break;
 377         case 3:
 378                 bp->cmd_tbl.transmitter_control = transmitter_control_v3;
 379                 break;
 380         case 4:
 381                 bp->cmd_tbl.transmitter_control = transmitter_control_v4;
 382                 break;
 383         case 5:
 384                 bp->cmd_tbl.transmitter_control = transmitter_control_v1_5;
 385                 break;
 386         case 6:
 387                 bp->cmd_tbl.transmitter_control = transmitter_control_v1_6;
 388                 break;
 389         default:
 390                 dm_output_to_console("Don't have transmitter_control for v%d\n", crev);
 391                 bp->cmd_tbl.transmitter_control = NULL;
 392                 break;
 393         }
 394 }
 395 
 396 static enum bp_result transmitter_control_v2(
 397         struct bios_parser *bp,
 398         struct bp_transmitter_control *cntl)
 399 {
 400         enum bp_result result = BP_RESULT_FAILURE;
 401         DIG_TRANSMITTER_CONTROL_PARAMETERS_V2 params;
 402         enum connector_id connector_id =
 403                 dal_graphics_object_id_get_connector_id(cntl->connector_obj_id);
 404 
 405         memset(&params, 0, sizeof(params));
 406 
 407         switch (cntl->transmitter) {
 408         case TRANSMITTER_UNIPHY_A:
 409         case TRANSMITTER_UNIPHY_B:
 410         case TRANSMITTER_UNIPHY_C:
 411         case TRANSMITTER_UNIPHY_D:
 412         case TRANSMITTER_UNIPHY_E:
 413         case TRANSMITTER_UNIPHY_F:
 414         case TRANSMITTER_TRAVIS_LCD:
 415                 break;
 416         default:
 417                 return BP_RESULT_BADINPUT;
 418         }
 419 
 420         switch (cntl->action) {
 421         case TRANSMITTER_CONTROL_INIT:
 422                 if ((CONNECTOR_ID_DUAL_LINK_DVII == connector_id) ||
 423                                 (CONNECTOR_ID_DUAL_LINK_DVID == connector_id))
 424                         /* on INIT this bit should be set according to the
 425                          * phisycal connector
 426                          * Bit0: dual link connector flag
 427                          * =0 connector is single link connector
 428                          * =1 connector is dual link connector
 429                          */
 430                         params.acConfig.fDualLinkConnector = 1;
 431 
 432                 /* connector object id */
 433                 params.usInitInfo =
 434                                 cpu_to_le16((uint8_t)cntl->connector_obj_id.id);
 435                 break;
 436         case TRANSMITTER_CONTROL_SET_VOLTAGE_AND_PREEMPASIS:
 437                 /* votage swing and pre-emphsis */
 438                 params.asMode.ucLaneSel = (uint8_t)cntl->lane_select;
 439                 params.asMode.ucLaneSet = (uint8_t)cntl->lane_settings;
 440                 break;
 441         default:
 442                 /* if dual-link */
 443                 if (LANE_COUNT_FOUR < cntl->lanes_number) {
 444                         /* on ENABLE/DISABLE this bit should be set according to
 445                          * actual timing (number of lanes)
 446                          * Bit0: dual link connector flag
 447                          * =0 connector is single link connector
 448                          * =1 connector is dual link connector
 449                          */
 450                         params.acConfig.fDualLinkConnector = 1;
 451 
 452                         /* link rate, half for dual link
 453                          * We need to convert from KHz units into 20KHz units
 454                          */
 455                         params.usPixelClock =
 456                                         cpu_to_le16((uint16_t)(cntl->pixel_clock / 20));
 457                 } else
 458                         /* link rate, half for dual link
 459                          * We need to convert from KHz units into 10KHz units
 460                          */
 461                         params.usPixelClock =
 462                                         cpu_to_le16((uint16_t)(cntl->pixel_clock / 10));
 463                 break;
 464         }
 465 
 466         /* 00 - coherent mode
 467          * 01 - incoherent mode
 468          */
 469 
 470         params.acConfig.fCoherentMode = cntl->coherent;
 471 
 472         if ((TRANSMITTER_UNIPHY_B == cntl->transmitter)
 473                         || (TRANSMITTER_UNIPHY_D == cntl->transmitter)
 474                         || (TRANSMITTER_UNIPHY_F == cntl->transmitter))
 475                 /* Bit2: Transmitter Link selection
 476                  * =0 when bit0=0, single link A/C/E, when bit0=1,
 477                  * master link A/C/E
 478                  * =1 when bit0=0, single link B/D/F, when bit0=1,
 479                  * master link B/D/F
 480                  */
 481                 params.acConfig.ucLinkSel = 1;
 482 
 483         if (ENGINE_ID_DIGB == cntl->engine_id)
 484                 /* Bit3: Transmitter data source selection
 485                  * =0 DIGA is data source.
 486                  * =1 DIGB is data source.
 487                  * This bit is only useful when ucAction= ATOM_ENABLE
 488                  */
 489                 params.acConfig.ucEncoderSel = 1;
 490 
 491         if (CONNECTOR_ID_DISPLAY_PORT == connector_id)
 492                 /* Bit4: DP connector flag
 493                  * =0 connector is none-DP connector
 494                  * =1 connector is DP connector
 495                  */
 496                 params.acConfig.fDPConnector = 1;
 497 
 498         /* Bit[7:6]: Transmitter selection
 499          * =0 UNIPHY_ENCODER: UNIPHYA/B
 500          * =1 UNIPHY1_ENCODER: UNIPHYC/D
 501          * =2 UNIPHY2_ENCODER: UNIPHYE/F
 502          * =3 reserved
 503          */
 504         params.acConfig.ucTransmitterSel =
 505                         (uint8_t)bp->cmd_helper->transmitter_bp_to_atom(
 506                                         cntl->transmitter);
 507 
 508         params.ucAction = (uint8_t)cntl->action;
 509 
 510         if (EXEC_BIOS_CMD_TABLE(UNIPHYTransmitterControl, params))
 511                 result = BP_RESULT_OK;
 512 
 513         return result;
 514 }
 515 
 516 static enum bp_result transmitter_control_v3(
 517         struct bios_parser *bp,
 518         struct bp_transmitter_control *cntl)
 519 {
 520         enum bp_result result = BP_RESULT_FAILURE;
 521         DIG_TRANSMITTER_CONTROL_PARAMETERS_V3 params;
 522         uint32_t pll_id;
 523         enum connector_id conn_id =
 524                         dal_graphics_object_id_get_connector_id(cntl->connector_obj_id);
 525         const struct command_table_helper *cmd = bp->cmd_helper;
 526         bool dual_link_conn = (CONNECTOR_ID_DUAL_LINK_DVII == conn_id)
 527                                         || (CONNECTOR_ID_DUAL_LINK_DVID == conn_id);
 528 
 529         memset(&params, 0, sizeof(params));
 530 
 531         switch (cntl->transmitter) {
 532         case TRANSMITTER_UNIPHY_A:
 533         case TRANSMITTER_UNIPHY_B:
 534         case TRANSMITTER_UNIPHY_C:
 535         case TRANSMITTER_UNIPHY_D:
 536         case TRANSMITTER_UNIPHY_E:
 537         case TRANSMITTER_UNIPHY_F:
 538         case TRANSMITTER_TRAVIS_LCD:
 539                 break;
 540         default:
 541                 return BP_RESULT_BADINPUT;
 542         }
 543 
 544         if (!cmd->clock_source_id_to_atom(cntl->pll_id, &pll_id))
 545                 return BP_RESULT_BADINPUT;
 546 
 547         /* fill information based on the action */
 548         switch (cntl->action) {
 549         case TRANSMITTER_CONTROL_INIT:
 550                 if (dual_link_conn) {
 551                         /* on INIT this bit should be set according to the
 552                          * phisycal connector
 553                          * Bit0: dual link connector flag
 554                          * =0 connector is single link connector
 555                          * =1 connector is dual link connector
 556                          */
 557                         params.acConfig.fDualLinkConnector = 1;
 558                 }
 559 
 560                 /* connector object id */
 561                 params.usInitInfo =
 562                                 cpu_to_le16((uint8_t)(cntl->connector_obj_id.id));
 563                 break;
 564         case TRANSMITTER_CONTROL_SET_VOLTAGE_AND_PREEMPASIS:
 565                 /* votage swing and pre-emphsis */
 566                 params.asMode.ucLaneSel = (uint8_t)cntl->lane_select;
 567                 params.asMode.ucLaneSet = (uint8_t)cntl->lane_settings;
 568                 break;
 569         default:
 570                 if (dual_link_conn && cntl->multi_path)
 571                         /* on ENABLE/DISABLE this bit should be set according to
 572                          * actual timing (number of lanes)
 573                          * Bit0: dual link connector flag
 574                          * =0 connector is single link connector
 575                          * =1 connector is dual link connector
 576                          */
 577                         params.acConfig.fDualLinkConnector = 1;
 578 
 579                 /* if dual-link */
 580                 if (LANE_COUNT_FOUR < cntl->lanes_number) {
 581                         /* on ENABLE/DISABLE this bit should be set according to
 582                          * actual timing (number of lanes)
 583                          * Bit0: dual link connector flag
 584                          * =0 connector is single link connector
 585                          * =1 connector is dual link connector
 586                          */
 587                         params.acConfig.fDualLinkConnector = 1;
 588 
 589                         /* link rate, half for dual link
 590                          * We need to convert from KHz units into 20KHz units
 591                          */
 592                         params.usPixelClock =
 593                                         cpu_to_le16((uint16_t)(cntl->pixel_clock / 20));
 594                 } else {
 595                         /* link rate, half for dual link
 596                          * We need to convert from KHz units into 10KHz units
 597                          */
 598                         params.usPixelClock =
 599                                         cpu_to_le16((uint16_t)(cntl->pixel_clock / 10));
 600                 }
 601                 break;
 602         }
 603 
 604         /* 00 - coherent mode
 605          * 01 - incoherent mode
 606          */
 607 
 608         params.acConfig.fCoherentMode = cntl->coherent;
 609 
 610         if ((TRANSMITTER_UNIPHY_B == cntl->transmitter)
 611                 || (TRANSMITTER_UNIPHY_D == cntl->transmitter)
 612                 || (TRANSMITTER_UNIPHY_F == cntl->transmitter))
 613                 /* Bit2: Transmitter Link selection
 614                  * =0 when bit0=0, single link A/C/E, when bit0=1,
 615                  * master link A/C/E
 616                  * =1 when bit0=0, single link B/D/F, when bit0=1,
 617                  * master link B/D/F
 618                  */
 619                 params.acConfig.ucLinkSel = 1;
 620 
 621         if (ENGINE_ID_DIGB == cntl->engine_id)
 622                 /* Bit3: Transmitter data source selection
 623                  * =0 DIGA is data source.
 624                  * =1 DIGB is data source.
 625                  * This bit is only useful when ucAction= ATOM_ENABLE
 626                  */
 627                 params.acConfig.ucEncoderSel = 1;
 628 
 629         /* Bit[7:6]: Transmitter selection
 630          * =0 UNIPHY_ENCODER: UNIPHYA/B
 631          * =1 UNIPHY1_ENCODER: UNIPHYC/D
 632          * =2 UNIPHY2_ENCODER: UNIPHYE/F
 633          * =3 reserved
 634          */
 635         params.acConfig.ucTransmitterSel =
 636                         (uint8_t)cmd->transmitter_bp_to_atom(cntl->transmitter);
 637 
 638         params.ucLaneNum = (uint8_t)cntl->lanes_number;
 639 
 640         params.acConfig.ucRefClkSource = (uint8_t)pll_id;
 641 
 642         params.ucAction = (uint8_t)cntl->action;
 643 
 644         if (EXEC_BIOS_CMD_TABLE(UNIPHYTransmitterControl, params))
 645                 result = BP_RESULT_OK;
 646 
 647         return result;
 648 }
 649 
 650 static enum bp_result transmitter_control_v4(
 651         struct bios_parser *bp,
 652         struct bp_transmitter_control *cntl)
 653 {
 654         enum bp_result result = BP_RESULT_FAILURE;
 655         DIG_TRANSMITTER_CONTROL_PARAMETERS_V4 params;
 656         uint32_t ref_clk_src_id;
 657         enum connector_id conn_id =
 658                         dal_graphics_object_id_get_connector_id(cntl->connector_obj_id);
 659         const struct command_table_helper *cmd = bp->cmd_helper;
 660 
 661         memset(&params, 0, sizeof(params));
 662 
 663         switch (cntl->transmitter) {
 664         case TRANSMITTER_UNIPHY_A:
 665         case TRANSMITTER_UNIPHY_B:
 666         case TRANSMITTER_UNIPHY_C:
 667         case TRANSMITTER_UNIPHY_D:
 668         case TRANSMITTER_UNIPHY_E:
 669         case TRANSMITTER_UNIPHY_F:
 670         case TRANSMITTER_TRAVIS_LCD:
 671                 break;
 672         default:
 673                 return BP_RESULT_BADINPUT;
 674         }
 675 
 676         if (!cmd->clock_source_id_to_ref_clk_src(cntl->pll_id, &ref_clk_src_id))
 677                 return BP_RESULT_BADINPUT;
 678 
 679         switch (cntl->action) {
 680         case TRANSMITTER_CONTROL_INIT:
 681         {
 682                 if ((CONNECTOR_ID_DUAL_LINK_DVII == conn_id) ||
 683                                 (CONNECTOR_ID_DUAL_LINK_DVID == conn_id))
 684                         /* on INIT this bit should be set according to the
 685                          * phisycal connector
 686                          * Bit0: dual link connector flag
 687                          * =0 connector is single link connector
 688                          * =1 connector is dual link connector
 689                          */
 690                         params.acConfig.fDualLinkConnector = 1;
 691 
 692                 /* connector object id */
 693                 params.usInitInfo =
 694                                 cpu_to_le16((uint8_t)(cntl->connector_obj_id.id));
 695         }
 696         break;
 697         case TRANSMITTER_CONTROL_SET_VOLTAGE_AND_PREEMPASIS:
 698                 /* votage swing and pre-emphsis */
 699                 params.asMode.ucLaneSel = (uint8_t)(cntl->lane_select);
 700                 params.asMode.ucLaneSet = (uint8_t)(cntl->lane_settings);
 701                 break;
 702         default:
 703                 if ((CONNECTOR_ID_DUAL_LINK_DVII == conn_id) ||
 704                                 (CONNECTOR_ID_DUAL_LINK_DVID == conn_id))
 705                         /* on ENABLE/DISABLE this bit should be set according to
 706                          * actual timing (number of lanes)
 707                          * Bit0: dual link connector flag
 708                          * =0 connector is single link connector
 709                          * =1 connector is dual link connector
 710                          */
 711                         params.acConfig.fDualLinkConnector = 1;
 712 
 713                 /* if dual-link */
 714                 if (LANE_COUNT_FOUR < cntl->lanes_number)
 715                         /* link rate, half for dual link
 716                          * We need to convert from KHz units into 20KHz units
 717                          */
 718                         params.usPixelClock =
 719                                         cpu_to_le16((uint16_t)(cntl->pixel_clock / 20));
 720                 else {
 721                         /* link rate, half for dual link
 722                          * We need to convert from KHz units into 10KHz units
 723                          */
 724                         params.usPixelClock =
 725                                         cpu_to_le16((uint16_t)(cntl->pixel_clock / 10));
 726                 }
 727                 break;
 728         }
 729 
 730         /* 00 - coherent mode
 731          * 01 - incoherent mode
 732          */
 733 
 734         params.acConfig.fCoherentMode = cntl->coherent;
 735 
 736         if ((TRANSMITTER_UNIPHY_B == cntl->transmitter)
 737                 || (TRANSMITTER_UNIPHY_D == cntl->transmitter)
 738                 || (TRANSMITTER_UNIPHY_F == cntl->transmitter))
 739                 /* Bit2: Transmitter Link selection
 740                  * =0 when bit0=0, single link A/C/E, when bit0=1,
 741                  * master link A/C/E
 742                  * =1 when bit0=0, single link B/D/F, when bit0=1,
 743                  * master link B/D/F
 744                  */
 745                 params.acConfig.ucLinkSel = 1;
 746 
 747         if (ENGINE_ID_DIGB == cntl->engine_id)
 748                 /* Bit3: Transmitter data source selection
 749                  * =0 DIGA is data source.
 750                  * =1 DIGB is data source.
 751                  * This bit is only useful when ucAction= ATOM_ENABLE
 752                  */
 753                 params.acConfig.ucEncoderSel = 1;
 754 
 755         /* Bit[7:6]: Transmitter selection
 756          * =0 UNIPHY_ENCODER: UNIPHYA/B
 757          * =1 UNIPHY1_ENCODER: UNIPHYC/D
 758          * =2 UNIPHY2_ENCODER: UNIPHYE/F
 759          * =3 reserved
 760          */
 761         params.acConfig.ucTransmitterSel =
 762                 (uint8_t)(cmd->transmitter_bp_to_atom(cntl->transmitter));
 763         params.ucLaneNum = (uint8_t)(cntl->lanes_number);
 764         params.acConfig.ucRefClkSource = (uint8_t)(ref_clk_src_id);
 765         params.ucAction = (uint8_t)(cntl->action);
 766 
 767         if (EXEC_BIOS_CMD_TABLE(UNIPHYTransmitterControl, params))
 768                 result = BP_RESULT_OK;
 769 
 770         return result;
 771 }
 772 
 773 static enum bp_result transmitter_control_v1_5(
 774         struct bios_parser *bp,
 775         struct bp_transmitter_control *cntl)
 776 {
 777         enum bp_result result = BP_RESULT_FAILURE;
 778         const struct command_table_helper *cmd = bp->cmd_helper;
 779         DIG_TRANSMITTER_CONTROL_PARAMETERS_V1_5 params;
 780 
 781         memset(&params, 0, sizeof(params));
 782         params.ucPhyId = cmd->phy_id_to_atom(cntl->transmitter);
 783         params.ucAction = (uint8_t)cntl->action;
 784         params.ucLaneNum = (uint8_t)cntl->lanes_number;
 785         params.ucConnObjId = (uint8_t)cntl->connector_obj_id.id;
 786 
 787         params.ucDigMode =
 788                 cmd->signal_type_to_atom_dig_mode(cntl->signal);
 789         params.asConfig.ucPhyClkSrcId =
 790                 cmd->clock_source_id_to_atom_phy_clk_src_id(cntl->pll_id);
 791         /* 00 - coherent mode */
 792         params.asConfig.ucCoherentMode = cntl->coherent;
 793         params.asConfig.ucHPDSel =
 794                 cmd->hpd_sel_to_atom(cntl->hpd_sel);
 795         params.ucDigEncoderSel =
 796                 cmd->dig_encoder_sel_to_atom(cntl->engine_id);
 797         params.ucDPLaneSet = (uint8_t) cntl->lane_settings;
 798         params.usSymClock = cpu_to_le16((uint16_t) (cntl->pixel_clock / 10));
 799         /*
 800          * In SI/TN case, caller have to set usPixelClock as following:
 801          * DP mode: usPixelClock = DP_LINK_CLOCK/10
 802          * (DP_LINK_CLOCK = 1.62GHz, 2.7GHz, 5.4GHz)
 803          * DVI single link mode: usPixelClock = pixel clock
 804          * DVI dual link mode: usPixelClock = pixel clock
 805          * HDMI mode: usPixelClock = pixel clock * deep_color_ratio
 806          * (=1: 8bpp, =1.25: 10bpp, =1.5:12bpp, =2: 16bpp)
 807          * LVDS mode: usPixelClock = pixel clock
 808          */
 809         if  (cntl->signal == SIGNAL_TYPE_HDMI_TYPE_A) {
 810                 switch (cntl->color_depth) {
 811                 case COLOR_DEPTH_101010:
 812                         params.usSymClock =
 813                                 cpu_to_le16((le16_to_cpu(params.usSymClock) * 30) / 24);
 814                         break;
 815                 case COLOR_DEPTH_121212:
 816                         params.usSymClock =
 817                                 cpu_to_le16((le16_to_cpu(params.usSymClock) * 36) / 24);
 818                         break;
 819                 case COLOR_DEPTH_161616:
 820                         params.usSymClock =
 821                                 cpu_to_le16((le16_to_cpu(params.usSymClock) * 48) / 24);
 822                         break;
 823                 default:
 824                         break;
 825                 }
 826         }
 827 
 828         if (EXEC_BIOS_CMD_TABLE(UNIPHYTransmitterControl, params))
 829                 result = BP_RESULT_OK;
 830 
 831         return result;
 832 }
 833 
 834 static enum bp_result transmitter_control_v1_6(
 835         struct bios_parser *bp,
 836         struct bp_transmitter_control *cntl)
 837 {
 838         enum bp_result result = BP_RESULT_FAILURE;
 839         const struct command_table_helper *cmd = bp->cmd_helper;
 840         DIG_TRANSMITTER_CONTROL_PARAMETERS_V1_6 params;
 841 
 842         memset(&params, 0, sizeof(params));
 843         params.ucPhyId = cmd->phy_id_to_atom(cntl->transmitter);
 844         params.ucAction = (uint8_t)cntl->action;
 845 
 846         if (cntl->action == TRANSMITTER_CONTROL_SET_VOLTAGE_AND_PREEMPASIS)
 847                 params.ucDPLaneSet = (uint8_t)cntl->lane_settings;
 848         else
 849                 params.ucDigMode = cmd->signal_type_to_atom_dig_mode(cntl->signal);
 850 
 851         params.ucLaneNum = (uint8_t)cntl->lanes_number;
 852         params.ucHPDSel = cmd->hpd_sel_to_atom(cntl->hpd_sel);
 853         params.ucDigEncoderSel = cmd->dig_encoder_sel_to_atom(cntl->engine_id);
 854         params.ucConnObjId = (uint8_t)cntl->connector_obj_id.id;
 855         params.ulSymClock = cntl->pixel_clock/10;
 856 
 857         /*
 858          * In SI/TN case, caller have to set usPixelClock as following:
 859          * DP mode: usPixelClock = DP_LINK_CLOCK/10
 860          * (DP_LINK_CLOCK = 1.62GHz, 2.7GHz, 5.4GHz)
 861          * DVI single link mode: usPixelClock = pixel clock
 862          * DVI dual link mode: usPixelClock = pixel clock
 863          * HDMI mode: usPixelClock = pixel clock * deep_color_ratio
 864          * (=1: 8bpp, =1.25: 10bpp, =1.5:12bpp, =2: 16bpp)
 865          * LVDS mode: usPixelClock = pixel clock
 866          */
 867         switch (cntl->signal) {
 868         case SIGNAL_TYPE_HDMI_TYPE_A:
 869                 switch (cntl->color_depth) {
 870                 case COLOR_DEPTH_101010:
 871                         params.ulSymClock =
 872                                 cpu_to_le16((le16_to_cpu(params.ulSymClock) * 30) / 24);
 873                         break;
 874                 case COLOR_DEPTH_121212:
 875                         params.ulSymClock =
 876                                 cpu_to_le16((le16_to_cpu(params.ulSymClock) * 36) / 24);
 877                         break;
 878                 case COLOR_DEPTH_161616:
 879                         params.ulSymClock =
 880                                 cpu_to_le16((le16_to_cpu(params.ulSymClock) * 48) / 24);
 881                         break;
 882                 default:
 883                         break;
 884                 }
 885                 break;
 886                 default:
 887                         break;
 888         }
 889 
 890         if (EXEC_BIOS_CMD_TABLE(UNIPHYTransmitterControl, params))
 891                 result = BP_RESULT_OK;
 892         return result;
 893 }
 894 
 895 /*******************************************************************************
 896  ********************************************************************************
 897  **
 898  **                  SET PIXEL CLOCK
 899  **
 900  ********************************************************************************
 901  *******************************************************************************/
 902 
 903 static enum bp_result set_pixel_clock_v3(
 904         struct bios_parser *bp,
 905         struct bp_pixel_clock_parameters *bp_params);
 906 static enum bp_result set_pixel_clock_v5(
 907         struct bios_parser *bp,
 908         struct bp_pixel_clock_parameters *bp_params);
 909 static enum bp_result set_pixel_clock_v6(
 910         struct bios_parser *bp,
 911         struct bp_pixel_clock_parameters *bp_params);
 912 static enum bp_result set_pixel_clock_v7(
 913         struct bios_parser *bp,
 914         struct bp_pixel_clock_parameters *bp_params);
 915 
 916 static void init_set_pixel_clock(struct bios_parser *bp)
 917 {
 918         switch (BIOS_CMD_TABLE_PARA_REVISION(SetPixelClock)) {
 919         case 3:
 920                 bp->cmd_tbl.set_pixel_clock = set_pixel_clock_v3;
 921                 break;
 922         case 5:
 923                 bp->cmd_tbl.set_pixel_clock = set_pixel_clock_v5;
 924                 break;
 925         case 6:
 926                 bp->cmd_tbl.set_pixel_clock = set_pixel_clock_v6;
 927                 break;
 928         case 7:
 929                 bp->cmd_tbl.set_pixel_clock = set_pixel_clock_v7;
 930                 break;
 931         default:
 932                 dm_output_to_console("Don't have set_pixel_clock for v%d\n",
 933                          BIOS_CMD_TABLE_PARA_REVISION(SetPixelClock));
 934                 bp->cmd_tbl.set_pixel_clock = NULL;
 935                 break;
 936         }
 937 }
 938 
 939 static enum bp_result set_pixel_clock_v3(
 940         struct bios_parser *bp,
 941         struct bp_pixel_clock_parameters *bp_params)
 942 {
 943         enum bp_result result = BP_RESULT_FAILURE;
 944         PIXEL_CLOCK_PARAMETERS_V3 *params;
 945         SET_PIXEL_CLOCK_PS_ALLOCATION allocation;
 946 
 947         memset(&allocation, 0, sizeof(allocation));
 948 
 949         if (CLOCK_SOURCE_ID_PLL1 == bp_params->pll_id)
 950                 allocation.sPCLKInput.ucPpll = ATOM_PPLL1;
 951         else if (CLOCK_SOURCE_ID_PLL2 == bp_params->pll_id)
 952                 allocation.sPCLKInput.ucPpll = ATOM_PPLL2;
 953         else
 954                 return BP_RESULT_BADINPUT;
 955 
 956         allocation.sPCLKInput.usRefDiv =
 957                         cpu_to_le16((uint16_t)bp_params->reference_divider);
 958         allocation.sPCLKInput.usFbDiv =
 959                         cpu_to_le16((uint16_t)bp_params->feedback_divider);
 960         allocation.sPCLKInput.ucFracFbDiv =
 961                         (uint8_t)bp_params->fractional_feedback_divider;
 962         allocation.sPCLKInput.ucPostDiv =
 963                         (uint8_t)bp_params->pixel_clock_post_divider;
 964 
 965         /* We need to convert from 100Hz units into 10KHz units */
 966         allocation.sPCLKInput.usPixelClock =
 967                         cpu_to_le16((uint16_t)(bp_params->target_pixel_clock_100hz / 100));
 968 
 969         params = (PIXEL_CLOCK_PARAMETERS_V3 *)&allocation.sPCLKInput;
 970         params->ucTransmitterId =
 971                         bp->cmd_helper->encoder_id_to_atom(
 972                                         dal_graphics_object_id_get_encoder_id(
 973                                                         bp_params->encoder_object_id));
 974         params->ucEncoderMode =
 975                         (uint8_t)(bp->cmd_helper->encoder_mode_bp_to_atom(
 976                                         bp_params->signal_type, false));
 977 
 978         if (bp_params->flags.FORCE_PROGRAMMING_OF_PLL)
 979                 params->ucMiscInfo |= PIXEL_CLOCK_MISC_FORCE_PROG_PPLL;
 980 
 981         if (bp_params->flags.USE_E_CLOCK_AS_SOURCE_FOR_D_CLOCK)
 982                 params->ucMiscInfo |= PIXEL_CLOCK_MISC_USE_ENGINE_FOR_DISPCLK;
 983 
 984         if (CONTROLLER_ID_D1 != bp_params->controller_id)
 985                 params->ucMiscInfo |= PIXEL_CLOCK_MISC_CRTC_SEL_CRTC2;
 986 
 987         if (EXEC_BIOS_CMD_TABLE(SetPixelClock, allocation))
 988                 result = BP_RESULT_OK;
 989 
 990         return result;
 991 }
 992 
 993 #ifndef SET_PIXEL_CLOCK_PS_ALLOCATION_V5
 994 /* video bios did not define this: */
 995 typedef struct _SET_PIXEL_CLOCK_PS_ALLOCATION_V5 {
 996         PIXEL_CLOCK_PARAMETERS_V5 sPCLKInput;
 997         /* Caller doesn't need to init this portion */
 998         ENABLE_SPREAD_SPECTRUM_ON_PPLL sReserved;
 999 } SET_PIXEL_CLOCK_PS_ALLOCATION_V5;
1000 #endif
1001 
1002 #ifndef SET_PIXEL_CLOCK_PS_ALLOCATION_V6
1003 /* video bios did not define this: */
1004 typedef struct _SET_PIXEL_CLOCK_PS_ALLOCATION_V6 {
1005         PIXEL_CLOCK_PARAMETERS_V6 sPCLKInput;
1006         /* Caller doesn't need to init this portion */
1007         ENABLE_SPREAD_SPECTRUM_ON_PPLL sReserved;
1008 } SET_PIXEL_CLOCK_PS_ALLOCATION_V6;
1009 #endif
1010 
1011 static enum bp_result set_pixel_clock_v5(
1012         struct bios_parser *bp,
1013         struct bp_pixel_clock_parameters *bp_params)
1014 {
1015         enum bp_result result = BP_RESULT_FAILURE;
1016         SET_PIXEL_CLOCK_PS_ALLOCATION_V5 clk;
1017         uint8_t controller_id;
1018         uint32_t pll_id;
1019 
1020         memset(&clk, 0, sizeof(clk));
1021 
1022         if (bp->cmd_helper->clock_source_id_to_atom(bp_params->pll_id, &pll_id)
1023                         && bp->cmd_helper->controller_id_to_atom(
1024                                         bp_params->controller_id, &controller_id)) {
1025                 clk.sPCLKInput.ucCRTC = controller_id;
1026                 clk.sPCLKInput.ucPpll = (uint8_t)pll_id;
1027                 clk.sPCLKInput.ucRefDiv =
1028                                 (uint8_t)(bp_params->reference_divider);
1029                 clk.sPCLKInput.usFbDiv =
1030                                 cpu_to_le16((uint16_t)(bp_params->feedback_divider));
1031                 clk.sPCLKInput.ulFbDivDecFrac =
1032                                 cpu_to_le32(bp_params->fractional_feedback_divider);
1033                 clk.sPCLKInput.ucPostDiv =
1034                                 (uint8_t)(bp_params->pixel_clock_post_divider);
1035                 clk.sPCLKInput.ucTransmitterID =
1036                                 bp->cmd_helper->encoder_id_to_atom(
1037                                                 dal_graphics_object_id_get_encoder_id(
1038                                                                 bp_params->encoder_object_id));
1039                 clk.sPCLKInput.ucEncoderMode =
1040                                 (uint8_t)bp->cmd_helper->encoder_mode_bp_to_atom(
1041                                                 bp_params->signal_type, false);
1042 
1043                 /* We need to convert from 100Hz units into 10KHz units */
1044                 clk.sPCLKInput.usPixelClock =
1045                                 cpu_to_le16((uint16_t)(bp_params->target_pixel_clock_100hz / 100));
1046 
1047                 if (bp_params->flags.FORCE_PROGRAMMING_OF_PLL)
1048                         clk.sPCLKInput.ucMiscInfo |=
1049                                         PIXEL_CLOCK_MISC_FORCE_PROG_PPLL;
1050 
1051                 if (bp_params->flags.SET_EXTERNAL_REF_DIV_SRC)
1052                         clk.sPCLKInput.ucMiscInfo |=
1053                                         PIXEL_CLOCK_MISC_REF_DIV_SRC;
1054 
1055                 /* clkV5.ucMiscInfo bit[3:2]= HDMI panel bit depth: =0: 24bpp
1056                  * =1:30bpp, =2:32bpp
1057                  * driver choose program it itself, i.e. here we program it
1058                  * to 888 by default.
1059                  */
1060 
1061                 if (EXEC_BIOS_CMD_TABLE(SetPixelClock, clk))
1062                         result = BP_RESULT_OK;
1063         }
1064 
1065         return result;
1066 }
1067 
1068 static enum bp_result set_pixel_clock_v6(
1069         struct bios_parser *bp,
1070         struct bp_pixel_clock_parameters *bp_params)
1071 {
1072         enum bp_result result = BP_RESULT_FAILURE;
1073         SET_PIXEL_CLOCK_PS_ALLOCATION_V6 clk;
1074         uint8_t controller_id;
1075         uint32_t pll_id;
1076 
1077         memset(&clk, 0, sizeof(clk));
1078 
1079         if (bp->cmd_helper->clock_source_id_to_atom(bp_params->pll_id, &pll_id)
1080                         && bp->cmd_helper->controller_id_to_atom(
1081                                         bp_params->controller_id, &controller_id)) {
1082                 /* Note: VBIOS still wants to use ucCRTC name which is now
1083                  * 1 byte in ULONG
1084                  *typedef struct _CRTC_PIXEL_CLOCK_FREQ
1085                  *{
1086                  * target the pixel clock to drive the CRTC timing.
1087                  * ULONG ulPixelClock:24;
1088                  * 0 means disable PPLL/DCPLL. Expanded to 24 bits comparing to
1089                  * previous version.
1090                  * ATOM_CRTC1~6, indicate the CRTC controller to
1091                  * ULONG ucCRTC:8;
1092                  * drive the pixel clock. not used for DCPLL case.
1093                  *}CRTC_PIXEL_CLOCK_FREQ;
1094                  *union
1095                  *{
1096                  * pixel clock and CRTC id frequency
1097                  * CRTC_PIXEL_CLOCK_FREQ ulCrtcPclkFreq;
1098                  * ULONG ulDispEngClkFreq; dispclk frequency
1099                  *};
1100                  */
1101                 clk.sPCLKInput.ulCrtcPclkFreq.ucCRTC = controller_id;
1102                 clk.sPCLKInput.ucPpll = (uint8_t) pll_id;
1103                 clk.sPCLKInput.ucRefDiv =
1104                                 (uint8_t) bp_params->reference_divider;
1105                 clk.sPCLKInput.usFbDiv =
1106                                 cpu_to_le16((uint16_t) bp_params->feedback_divider);
1107                 clk.sPCLKInput.ulFbDivDecFrac =
1108                                 cpu_to_le32(bp_params->fractional_feedback_divider);
1109                 clk.sPCLKInput.ucPostDiv =
1110                                 (uint8_t) bp_params->pixel_clock_post_divider;
1111                 clk.sPCLKInput.ucTransmitterID =
1112                                 bp->cmd_helper->encoder_id_to_atom(
1113                                                 dal_graphics_object_id_get_encoder_id(
1114                                                                 bp_params->encoder_object_id));
1115                 clk.sPCLKInput.ucEncoderMode =
1116                                 (uint8_t) bp->cmd_helper->encoder_mode_bp_to_atom(
1117                                                 bp_params->signal_type, false);
1118 
1119                 /* We need to convert from 100 Hz units into 10KHz units */
1120                 clk.sPCLKInput.ulCrtcPclkFreq.ulPixelClock =
1121                                 cpu_to_le32(bp_params->target_pixel_clock_100hz / 100);
1122 
1123                 if (bp_params->flags.FORCE_PROGRAMMING_OF_PLL) {
1124                         clk.sPCLKInput.ucMiscInfo |=
1125                                         PIXEL_CLOCK_V6_MISC_FORCE_PROG_PPLL;
1126                 }
1127 
1128                 if (bp_params->flags.SET_EXTERNAL_REF_DIV_SRC) {
1129                         clk.sPCLKInput.ucMiscInfo |=
1130                                         PIXEL_CLOCK_V6_MISC_REF_DIV_SRC;
1131                 }
1132 
1133                 /* clkV6.ucMiscInfo bit[3:2]= HDMI panel bit depth: =0:
1134                  * 24bpp =1:30bpp, =2:32bpp
1135                  * driver choose program it itself, i.e. here we pass required
1136                  * target rate that includes deep color.
1137                  */
1138 
1139                 if (EXEC_BIOS_CMD_TABLE(SetPixelClock, clk))
1140                         result = BP_RESULT_OK;
1141         }
1142 
1143         return result;
1144 }
1145 
1146 static enum bp_result set_pixel_clock_v7(
1147         struct bios_parser *bp,
1148         struct bp_pixel_clock_parameters *bp_params)
1149 {
1150         enum bp_result result = BP_RESULT_FAILURE;
1151         PIXEL_CLOCK_PARAMETERS_V7 clk;
1152         uint8_t controller_id;
1153         uint32_t pll_id;
1154 
1155         memset(&clk, 0, sizeof(clk));
1156 
1157         if (bp->cmd_helper->clock_source_id_to_atom(bp_params->pll_id, &pll_id)
1158                         && bp->cmd_helper->controller_id_to_atom(bp_params->controller_id, &controller_id)) {
1159                 /* Note: VBIOS still wants to use ucCRTC name which is now
1160                  * 1 byte in ULONG
1161                  *typedef struct _CRTC_PIXEL_CLOCK_FREQ
1162                  *{
1163                  * target the pixel clock to drive the CRTC timing.
1164                  * ULONG ulPixelClock:24;
1165                  * 0 means disable PPLL/DCPLL. Expanded to 24 bits comparing to
1166                  * previous version.
1167                  * ATOM_CRTC1~6, indicate the CRTC controller to
1168                  * ULONG ucCRTC:8;
1169                  * drive the pixel clock. not used for DCPLL case.
1170                  *}CRTC_PIXEL_CLOCK_FREQ;
1171                  *union
1172                  *{
1173                  * pixel clock and CRTC id frequency
1174                  * CRTC_PIXEL_CLOCK_FREQ ulCrtcPclkFreq;
1175                  * ULONG ulDispEngClkFreq; dispclk frequency
1176                  *};
1177                  */
1178                 clk.ucCRTC = controller_id;
1179                 clk.ucPpll = (uint8_t) pll_id;
1180                 clk.ucTransmitterID = bp->cmd_helper->encoder_id_to_atom(dal_graphics_object_id_get_encoder_id(bp_params->encoder_object_id));
1181                 clk.ucEncoderMode = (uint8_t) bp->cmd_helper->encoder_mode_bp_to_atom(bp_params->signal_type, false);
1182 
1183                 clk.ulPixelClock = cpu_to_le32(bp_params->target_pixel_clock_100hz);
1184 
1185                 clk.ucDeepColorRatio = (uint8_t) bp->cmd_helper->transmitter_color_depth_to_atom(bp_params->color_depth);
1186 
1187                 if (bp_params->flags.FORCE_PROGRAMMING_OF_PLL)
1188                         clk.ucMiscInfo |= PIXEL_CLOCK_V7_MISC_FORCE_PROG_PPLL;
1189 
1190                 if (bp_params->flags.SET_EXTERNAL_REF_DIV_SRC)
1191                         clk.ucMiscInfo |= PIXEL_CLOCK_V7_MISC_REF_DIV_SRC;
1192 
1193                 if (bp_params->flags.PROGRAM_PHY_PLL_ONLY)
1194                         clk.ucMiscInfo |= PIXEL_CLOCK_V7_MISC_PROG_PHYPLL;
1195 
1196                 if (bp_params->flags.SUPPORT_YUV_420)
1197                         clk.ucMiscInfo |= PIXEL_CLOCK_V7_MISC_YUV420_MODE;
1198 
1199                 if (bp_params->flags.SET_XTALIN_REF_SRC)
1200                         clk.ucMiscInfo |= PIXEL_CLOCK_V7_MISC_REF_DIV_SRC_XTALIN;
1201 
1202                 if (bp_params->flags.SET_GENLOCK_REF_DIV_SRC)
1203                         clk.ucMiscInfo |= PIXEL_CLOCK_V7_MISC_REF_DIV_SRC_GENLK;
1204 
1205                 if (bp_params->signal_type == SIGNAL_TYPE_DVI_DUAL_LINK)
1206                         clk.ucMiscInfo |= PIXEL_CLOCK_V7_MISC_DVI_DUALLINK_EN;
1207 
1208                 if (EXEC_BIOS_CMD_TABLE(SetPixelClock, clk))
1209                         result = BP_RESULT_OK;
1210         }
1211         return result;
1212 }
1213 
1214 /*******************************************************************************
1215  ********************************************************************************
1216  **
1217  **                  ENABLE PIXEL CLOCK SS
1218  **
1219  ********************************************************************************
1220  *******************************************************************************/
1221 static enum bp_result enable_spread_spectrum_on_ppll_v1(
1222         struct bios_parser *bp,
1223         struct bp_spread_spectrum_parameters *bp_params,
1224         bool enable);
1225 static enum bp_result enable_spread_spectrum_on_ppll_v2(
1226         struct bios_parser *bp,
1227         struct bp_spread_spectrum_parameters *bp_params,
1228         bool enable);
1229 static enum bp_result enable_spread_spectrum_on_ppll_v3(
1230         struct bios_parser *bp,
1231         struct bp_spread_spectrum_parameters *bp_params,
1232         bool enable);
1233 
1234 static void init_enable_spread_spectrum_on_ppll(struct bios_parser *bp)
1235 {
1236         switch (BIOS_CMD_TABLE_PARA_REVISION(EnableSpreadSpectrumOnPPLL)) {
1237         case 1:
1238                 bp->cmd_tbl.enable_spread_spectrum_on_ppll =
1239                                 enable_spread_spectrum_on_ppll_v1;
1240                 break;
1241         case 2:
1242                 bp->cmd_tbl.enable_spread_spectrum_on_ppll =
1243                                 enable_spread_spectrum_on_ppll_v2;
1244                 break;
1245         case 3:
1246                 bp->cmd_tbl.enable_spread_spectrum_on_ppll =
1247                                 enable_spread_spectrum_on_ppll_v3;
1248                 break;
1249         default:
1250                 dm_output_to_console("Don't have enable_spread_spectrum_on_ppll for v%d\n",
1251                          BIOS_CMD_TABLE_PARA_REVISION(EnableSpreadSpectrumOnPPLL));
1252                 bp->cmd_tbl.enable_spread_spectrum_on_ppll = NULL;
1253                 break;
1254         }
1255 }
1256 
1257 static enum bp_result enable_spread_spectrum_on_ppll_v1(
1258         struct bios_parser *bp,
1259         struct bp_spread_spectrum_parameters *bp_params,
1260         bool enable)
1261 {
1262         enum bp_result result = BP_RESULT_FAILURE;
1263         ENABLE_SPREAD_SPECTRUM_ON_PPLL params;
1264 
1265         memset(&params, 0, sizeof(params));
1266 
1267         if ((enable == true) && (bp_params->percentage > 0))
1268                 params.ucEnable = ATOM_ENABLE;
1269         else
1270                 params.ucEnable = ATOM_DISABLE;
1271 
1272         params.usSpreadSpectrumPercentage =
1273                         cpu_to_le16((uint16_t)bp_params->percentage);
1274         params.ucSpreadSpectrumStep =
1275                         (uint8_t)bp_params->ver1.step;
1276         params.ucSpreadSpectrumDelay =
1277                         (uint8_t)bp_params->ver1.delay;
1278         /* convert back to unit of 10KHz */
1279         params.ucSpreadSpectrumRange =
1280                         (uint8_t)(bp_params->ver1.range / 10000);
1281 
1282         if (bp_params->flags.EXTERNAL_SS)
1283                 params.ucSpreadSpectrumType |= ATOM_EXTERNAL_SS_MASK;
1284 
1285         if (bp_params->flags.CENTER_SPREAD)
1286                 params.ucSpreadSpectrumType |= ATOM_SS_CENTRE_SPREAD_MODE;
1287 
1288         if (bp_params->pll_id == CLOCK_SOURCE_ID_PLL1)
1289                 params.ucPpll = ATOM_PPLL1;
1290         else if (bp_params->pll_id == CLOCK_SOURCE_ID_PLL2)
1291                 params.ucPpll = ATOM_PPLL2;
1292         else
1293                 BREAK_TO_DEBUGGER(); /* Unexpected PLL value!! */
1294 
1295         if (EXEC_BIOS_CMD_TABLE(EnableSpreadSpectrumOnPPLL, params))
1296                 result = BP_RESULT_OK;
1297 
1298         return result;
1299 }
1300 
1301 static enum bp_result enable_spread_spectrum_on_ppll_v2(
1302         struct bios_parser *bp,
1303         struct bp_spread_spectrum_parameters *bp_params,
1304         bool enable)
1305 {
1306         enum bp_result result = BP_RESULT_FAILURE;
1307         ENABLE_SPREAD_SPECTRUM_ON_PPLL_V2 params;
1308 
1309         memset(&params, 0, sizeof(params));
1310 
1311         if (bp_params->pll_id == CLOCK_SOURCE_ID_PLL1)
1312                 params.ucSpreadSpectrumType = ATOM_PPLL_SS_TYPE_V2_P1PLL;
1313         else if (bp_params->pll_id == CLOCK_SOURCE_ID_PLL2)
1314                 params.ucSpreadSpectrumType = ATOM_PPLL_SS_TYPE_V2_P2PLL;
1315         else
1316                 BREAK_TO_DEBUGGER(); /* Unexpected PLL value!! */
1317 
1318         if ((enable == true) && (bp_params->percentage > 0)) {
1319                 params.ucEnable = ATOM_ENABLE;
1320 
1321                 params.usSpreadSpectrumPercentage =
1322                                 cpu_to_le16((uint16_t)(bp_params->percentage));
1323                 params.usSpreadSpectrumStep =
1324                                 cpu_to_le16((uint16_t)(bp_params->ds.ds_frac_size));
1325 
1326                 if (bp_params->flags.EXTERNAL_SS)
1327                         params.ucSpreadSpectrumType |=
1328                                         ATOM_PPLL_SS_TYPE_V2_EXT_SPREAD;
1329 
1330                 if (bp_params->flags.CENTER_SPREAD)
1331                         params.ucSpreadSpectrumType |=
1332                                         ATOM_PPLL_SS_TYPE_V2_CENTRE_SPREAD;
1333 
1334                 /* Both amounts need to be left shifted first before bit
1335                  * comparison. Otherwise, the result will always be zero here
1336                  */
1337                 params.usSpreadSpectrumAmount = cpu_to_le16((uint16_t)(
1338                                 ((bp_params->ds.feedback_amount <<
1339                                                 ATOM_PPLL_SS_AMOUNT_V2_FBDIV_SHIFT) &
1340                                                 ATOM_PPLL_SS_AMOUNT_V2_FBDIV_MASK) |
1341                                                 ((bp_params->ds.nfrac_amount <<
1342                                                                 ATOM_PPLL_SS_AMOUNT_V2_NFRAC_SHIFT) &
1343                                                                 ATOM_PPLL_SS_AMOUNT_V2_NFRAC_MASK)));
1344         } else
1345                 params.ucEnable = ATOM_DISABLE;
1346 
1347         if (EXEC_BIOS_CMD_TABLE(EnableSpreadSpectrumOnPPLL, params))
1348                 result = BP_RESULT_OK;
1349 
1350         return result;
1351 }
1352 
1353 static enum bp_result enable_spread_spectrum_on_ppll_v3(
1354         struct bios_parser *bp,
1355         struct bp_spread_spectrum_parameters *bp_params,
1356         bool enable)
1357 {
1358         enum bp_result result = BP_RESULT_FAILURE;
1359         ENABLE_SPREAD_SPECTRUM_ON_PPLL_V3 params;
1360 
1361         memset(&params, 0, sizeof(params));
1362 
1363         switch (bp_params->pll_id) {
1364         case CLOCK_SOURCE_ID_PLL0:
1365                 /* ATOM_PPLL_SS_TYPE_V3_P0PLL; this is pixel clock only,
1366                  * not for SI display clock.
1367                  */
1368                 params.ucSpreadSpectrumType = ATOM_PPLL_SS_TYPE_V3_DCPLL;
1369                 break;
1370         case CLOCK_SOURCE_ID_PLL1:
1371                 params.ucSpreadSpectrumType = ATOM_PPLL_SS_TYPE_V3_P1PLL;
1372                 break;
1373 
1374         case CLOCK_SOURCE_ID_PLL2:
1375                 params.ucSpreadSpectrumType = ATOM_PPLL_SS_TYPE_V3_P2PLL;
1376                 break;
1377 
1378         case CLOCK_SOURCE_ID_DCPLL:
1379                 params.ucSpreadSpectrumType = ATOM_PPLL_SS_TYPE_V3_DCPLL;
1380                 break;
1381 
1382         default:
1383                 BREAK_TO_DEBUGGER();
1384                 /* Unexpected PLL value!! */
1385                 return result;
1386         }
1387 
1388         if (enable == true) {
1389                 params.ucEnable = ATOM_ENABLE;
1390 
1391                 params.usSpreadSpectrumAmountFrac =
1392                                 cpu_to_le16((uint16_t)(bp_params->ds_frac_amount));
1393                 params.usSpreadSpectrumStep =
1394                                 cpu_to_le16((uint16_t)(bp_params->ds.ds_frac_size));
1395 
1396                 if (bp_params->flags.EXTERNAL_SS)
1397                         params.ucSpreadSpectrumType |=
1398                                         ATOM_PPLL_SS_TYPE_V3_EXT_SPREAD;
1399                 if (bp_params->flags.CENTER_SPREAD)
1400                         params.ucSpreadSpectrumType |=
1401                                         ATOM_PPLL_SS_TYPE_V3_CENTRE_SPREAD;
1402 
1403                 /* Both amounts need to be left shifted first before bit
1404                  * comparison. Otherwise, the result will always be zero here
1405                  */
1406                 params.usSpreadSpectrumAmount = cpu_to_le16((uint16_t)(
1407                                 ((bp_params->ds.feedback_amount <<
1408                                                 ATOM_PPLL_SS_AMOUNT_V3_FBDIV_SHIFT) &
1409                                                 ATOM_PPLL_SS_AMOUNT_V3_FBDIV_MASK) |
1410                                                 ((bp_params->ds.nfrac_amount <<
1411                                                                 ATOM_PPLL_SS_AMOUNT_V3_NFRAC_SHIFT) &
1412                                                                 ATOM_PPLL_SS_AMOUNT_V3_NFRAC_MASK)));
1413         } else
1414                 params.ucEnable = ATOM_DISABLE;
1415 
1416         if (EXEC_BIOS_CMD_TABLE(EnableSpreadSpectrumOnPPLL, params))
1417                 result = BP_RESULT_OK;
1418 
1419         return result;
1420 }
1421 
1422 /*******************************************************************************
1423  ********************************************************************************
1424  **
1425  **                  ADJUST DISPLAY PLL
1426  **
1427  ********************************************************************************
1428  *******************************************************************************/
1429 
1430 static enum bp_result adjust_display_pll_v2(
1431         struct bios_parser *bp,
1432         struct bp_adjust_pixel_clock_parameters *bp_params);
1433 static enum bp_result adjust_display_pll_v3(
1434         struct bios_parser *bp,
1435         struct bp_adjust_pixel_clock_parameters *bp_params);
1436 
1437 static void init_adjust_display_pll(struct bios_parser *bp)
1438 {
1439         switch (BIOS_CMD_TABLE_PARA_REVISION(AdjustDisplayPll)) {
1440         case 2:
1441                 bp->cmd_tbl.adjust_display_pll = adjust_display_pll_v2;
1442                 break;
1443         case 3:
1444                 bp->cmd_tbl.adjust_display_pll = adjust_display_pll_v3;
1445                 break;
1446         default:
1447                 dm_output_to_console("Don't have adjust_display_pll for v%d\n",
1448                          BIOS_CMD_TABLE_PARA_REVISION(AdjustDisplayPll));
1449                 bp->cmd_tbl.adjust_display_pll = NULL;
1450                 break;
1451         }
1452 }
1453 
1454 static enum bp_result adjust_display_pll_v2(
1455         struct bios_parser *bp,
1456         struct bp_adjust_pixel_clock_parameters *bp_params)
1457 {
1458         enum bp_result result = BP_RESULT_FAILURE;
1459         ADJUST_DISPLAY_PLL_PS_ALLOCATION params = { 0 };
1460 
1461         /* We need to convert from KHz units into 10KHz units and then convert
1462          * output pixel clock back 10KHz-->KHz */
1463         uint32_t pixel_clock_10KHz_in = bp_params->pixel_clock / 10;
1464 
1465         params.usPixelClock = cpu_to_le16((uint16_t)(pixel_clock_10KHz_in));
1466         params.ucTransmitterID =
1467                         bp->cmd_helper->encoder_id_to_atom(
1468                                         dal_graphics_object_id_get_encoder_id(
1469                                                         bp_params->encoder_object_id));
1470         params.ucEncodeMode =
1471                         (uint8_t)bp->cmd_helper->encoder_mode_bp_to_atom(
1472                                         bp_params->signal_type, false);
1473         return result;
1474 }
1475 
1476 static enum bp_result adjust_display_pll_v3(
1477         struct bios_parser *bp,
1478         struct bp_adjust_pixel_clock_parameters *bp_params)
1479 {
1480         enum bp_result result = BP_RESULT_FAILURE;
1481         ADJUST_DISPLAY_PLL_PS_ALLOCATION_V3 params;
1482         uint32_t pixel_clk_10_kHz_in = bp_params->pixel_clock / 10;
1483 
1484         memset(&params, 0, sizeof(params));
1485 
1486         /* We need to convert from KHz units into 10KHz units and then convert
1487          * output pixel clock back 10KHz-->KHz */
1488         params.sInput.usPixelClock = cpu_to_le16((uint16_t)pixel_clk_10_kHz_in);
1489         params.sInput.ucTransmitterID =
1490                         bp->cmd_helper->encoder_id_to_atom(
1491                                         dal_graphics_object_id_get_encoder_id(
1492                                                         bp_params->encoder_object_id));
1493         params.sInput.ucEncodeMode =
1494                         (uint8_t)bp->cmd_helper->encoder_mode_bp_to_atom(
1495                                         bp_params->signal_type, false);
1496 
1497         if (bp_params->ss_enable == true)
1498                 params.sInput.ucDispPllConfig |= DISPPLL_CONFIG_SS_ENABLE;
1499 
1500         if (bp_params->signal_type == SIGNAL_TYPE_DVI_DUAL_LINK)
1501                 params.sInput.ucDispPllConfig |= DISPPLL_CONFIG_DUAL_LINK;
1502 
1503         if (EXEC_BIOS_CMD_TABLE(AdjustDisplayPll, params)) {
1504                 /* Convert output pixel clock back 10KHz-->KHz: multiply
1505                  * original pixel clock in KHz by ratio
1506                  * [output pxlClk/input pxlClk] */
1507                 uint64_t pixel_clk_10_khz_out =
1508                                 (uint64_t)le32_to_cpu(params.sOutput.ulDispPllFreq);
1509                 uint64_t pixel_clk = (uint64_t)bp_params->pixel_clock;
1510 
1511                 if (pixel_clk_10_kHz_in != 0) {
1512                         bp_params->adjusted_pixel_clock =
1513                                         div_u64(pixel_clk * pixel_clk_10_khz_out,
1514                                                         pixel_clk_10_kHz_in);
1515                 } else {
1516                         bp_params->adjusted_pixel_clock = 0;
1517                         BREAK_TO_DEBUGGER();
1518                 }
1519 
1520                 bp_params->reference_divider = params.sOutput.ucRefDiv;
1521                 bp_params->pixel_clock_post_divider = params.sOutput.ucPostDiv;
1522 
1523                 result = BP_RESULT_OK;
1524         }
1525 
1526         return result;
1527 }
1528 
1529 /*******************************************************************************
1530  ********************************************************************************
1531  **
1532  **                  DAC ENCODER CONTROL
1533  **
1534  ********************************************************************************
1535  *******************************************************************************/
1536 
1537 static enum bp_result dac1_encoder_control_v1(
1538         struct bios_parser *bp,
1539         bool enable,
1540         uint32_t pixel_clock,
1541         uint8_t dac_standard);
1542 static enum bp_result dac2_encoder_control_v1(
1543         struct bios_parser *bp,
1544         bool enable,
1545         uint32_t pixel_clock,
1546         uint8_t dac_standard);
1547 
1548 static void init_dac_encoder_control(struct bios_parser *bp)
1549 {
1550         switch (BIOS_CMD_TABLE_PARA_REVISION(DAC1EncoderControl)) {
1551         case 1:
1552                 bp->cmd_tbl.dac1_encoder_control = dac1_encoder_control_v1;
1553                 break;
1554         default:
1555                 bp->cmd_tbl.dac1_encoder_control = NULL;
1556                 break;
1557         }
1558         switch (BIOS_CMD_TABLE_PARA_REVISION(DAC2EncoderControl)) {
1559         case 1:
1560                 bp->cmd_tbl.dac2_encoder_control = dac2_encoder_control_v1;
1561                 break;
1562         default:
1563                 bp->cmd_tbl.dac2_encoder_control = NULL;
1564                 break;
1565         }
1566 }
1567 
1568 static void dac_encoder_control_prepare_params(
1569         DAC_ENCODER_CONTROL_PS_ALLOCATION *params,
1570         bool enable,
1571         uint32_t pixel_clock,
1572         uint8_t dac_standard)
1573 {
1574         params->ucDacStandard = dac_standard;
1575         if (enable)
1576                 params->ucAction = ATOM_ENABLE;
1577         else
1578                 params->ucAction = ATOM_DISABLE;
1579 
1580         /* We need to convert from KHz units into 10KHz units
1581          * it looks as if the TvControl do not care about pixel clock
1582          */
1583         params->usPixelClock = cpu_to_le16((uint16_t)(pixel_clock / 10));
1584 }
1585 
1586 static enum bp_result dac1_encoder_control_v1(
1587         struct bios_parser *bp,
1588         bool enable,
1589         uint32_t pixel_clock,
1590         uint8_t dac_standard)
1591 {
1592         enum bp_result result = BP_RESULT_FAILURE;
1593         DAC_ENCODER_CONTROL_PS_ALLOCATION params;
1594 
1595         dac_encoder_control_prepare_params(
1596                 &params,
1597                 enable,
1598                 pixel_clock,
1599                 dac_standard);
1600 
1601         if (EXEC_BIOS_CMD_TABLE(DAC1EncoderControl, params))
1602                 result = BP_RESULT_OK;
1603 
1604         return result;
1605 }
1606 
1607 static enum bp_result dac2_encoder_control_v1(
1608         struct bios_parser *bp,
1609         bool enable,
1610         uint32_t pixel_clock,
1611         uint8_t dac_standard)
1612 {
1613         enum bp_result result = BP_RESULT_FAILURE;
1614         DAC_ENCODER_CONTROL_PS_ALLOCATION params;
1615 
1616         dac_encoder_control_prepare_params(
1617                 &params,
1618                 enable,
1619                 pixel_clock,
1620                 dac_standard);
1621 
1622         if (EXEC_BIOS_CMD_TABLE(DAC2EncoderControl, params))
1623                 result = BP_RESULT_OK;
1624 
1625         return result;
1626 }
1627 
1628 /*******************************************************************************
1629  ********************************************************************************
1630  **
1631  **                  DAC OUTPUT CONTROL
1632  **
1633  ********************************************************************************
1634  *******************************************************************************/
1635 static enum bp_result dac1_output_control_v1(
1636         struct bios_parser *bp,
1637         bool enable);
1638 static enum bp_result dac2_output_control_v1(
1639         struct bios_parser *bp,
1640         bool enable);
1641 
1642 static void init_dac_output_control(struct bios_parser *bp)
1643 {
1644         switch (BIOS_CMD_TABLE_PARA_REVISION(DAC1OutputControl)) {
1645         case 1:
1646                 bp->cmd_tbl.dac1_output_control = dac1_output_control_v1;
1647                 break;
1648         default:
1649                 bp->cmd_tbl.dac1_output_control = NULL;
1650                 break;
1651         }
1652         switch (BIOS_CMD_TABLE_PARA_REVISION(DAC2OutputControl)) {
1653         case 1:
1654                 bp->cmd_tbl.dac2_output_control = dac2_output_control_v1;
1655                 break;
1656         default:
1657                 bp->cmd_tbl.dac2_output_control = NULL;
1658                 break;
1659         }
1660 }
1661 
1662 static enum bp_result dac1_output_control_v1(
1663         struct bios_parser *bp, bool enable)
1664 {
1665         enum bp_result result = BP_RESULT_FAILURE;
1666         DISPLAY_DEVICE_OUTPUT_CONTROL_PS_ALLOCATION params;
1667 
1668         if (enable)
1669                 params.ucAction = ATOM_ENABLE;
1670         else
1671                 params.ucAction = ATOM_DISABLE;
1672 
1673         if (EXEC_BIOS_CMD_TABLE(DAC1OutputControl, params))
1674                 result = BP_RESULT_OK;
1675 
1676         return result;
1677 }
1678 
1679 static enum bp_result dac2_output_control_v1(
1680         struct bios_parser *bp, bool enable)
1681 {
1682         enum bp_result result = BP_RESULT_FAILURE;
1683         DISPLAY_DEVICE_OUTPUT_CONTROL_PS_ALLOCATION params;
1684 
1685         if (enable)
1686                 params.ucAction = ATOM_ENABLE;
1687         else
1688                 params.ucAction = ATOM_DISABLE;
1689 
1690         if (EXEC_BIOS_CMD_TABLE(DAC2OutputControl, params))
1691                 result = BP_RESULT_OK;
1692 
1693         return result;
1694 }
1695 
1696 /*******************************************************************************
1697  ********************************************************************************
1698  **
1699  **                  SET CRTC TIMING
1700  **
1701  ********************************************************************************
1702  *******************************************************************************/
1703 
1704 static enum bp_result set_crtc_using_dtd_timing_v3(
1705         struct bios_parser *bp,
1706         struct bp_hw_crtc_timing_parameters *bp_params);
1707 static enum bp_result set_crtc_timing_v1(
1708         struct bios_parser *bp,
1709         struct bp_hw_crtc_timing_parameters *bp_params);
1710 
1711 static void init_set_crtc_timing(struct bios_parser *bp)
1712 {
1713         uint32_t dtd_version =
1714                         BIOS_CMD_TABLE_PARA_REVISION(SetCRTC_UsingDTDTiming);
1715         if (dtd_version > 2)
1716                 switch (dtd_version) {
1717                 case 3:
1718                         bp->cmd_tbl.set_crtc_timing =
1719                                         set_crtc_using_dtd_timing_v3;
1720                         break;
1721                 default:
1722                         dm_output_to_console("Don't have set_crtc_timing for dtd v%d\n",
1723                                  dtd_version);
1724                         bp->cmd_tbl.set_crtc_timing = NULL;
1725                         break;
1726                 }
1727         else
1728                 switch (BIOS_CMD_TABLE_PARA_REVISION(SetCRTC_Timing)) {
1729                 case 1:
1730                         bp->cmd_tbl.set_crtc_timing = set_crtc_timing_v1;
1731                         break;
1732                 default:
1733                         dm_output_to_console("Don't have set_crtc_timing for v%d\n",
1734                                  BIOS_CMD_TABLE_PARA_REVISION(SetCRTC_Timing));
1735                         bp->cmd_tbl.set_crtc_timing = NULL;
1736                         break;
1737                 }
1738 }
1739 
1740 static enum bp_result set_crtc_timing_v1(
1741         struct bios_parser *bp,
1742         struct bp_hw_crtc_timing_parameters *bp_params)
1743 {
1744         enum bp_result result = BP_RESULT_FAILURE;
1745         SET_CRTC_TIMING_PARAMETERS_PS_ALLOCATION params = {0};
1746         uint8_t atom_controller_id;
1747 
1748         if (bp->cmd_helper->controller_id_to_atom(
1749                         bp_params->controller_id, &atom_controller_id))
1750                 params.ucCRTC = atom_controller_id;
1751 
1752         params.usH_Total = cpu_to_le16((uint16_t)(bp_params->h_total));
1753         params.usH_Disp = cpu_to_le16((uint16_t)(bp_params->h_addressable));
1754         params.usH_SyncStart = cpu_to_le16((uint16_t)(bp_params->h_sync_start));
1755         params.usH_SyncWidth = cpu_to_le16((uint16_t)(bp_params->h_sync_width));
1756         params.usV_Total = cpu_to_le16((uint16_t)(bp_params->v_total));
1757         params.usV_Disp = cpu_to_le16((uint16_t)(bp_params->v_addressable));
1758         params.usV_SyncStart =
1759                         cpu_to_le16((uint16_t)(bp_params->v_sync_start));
1760         params.usV_SyncWidth =
1761                         cpu_to_le16((uint16_t)(bp_params->v_sync_width));
1762 
1763         /* VBIOS does not expect any value except zero into this call, for
1764          * underscan use another entry ProgramOverscan call but when mode
1765          * 1776x1000 with the overscan 72x44 .e.i. 1920x1080 @30 DAL2 is ok,
1766          * but when same ,but 60 Hz there is corruption
1767          * DAL1 does not allow the mode 1776x1000@60
1768          */
1769         params.ucOverscanRight = (uint8_t)bp_params->h_overscan_right;
1770         params.ucOverscanLeft = (uint8_t)bp_params->h_overscan_left;
1771         params.ucOverscanBottom = (uint8_t)bp_params->v_overscan_bottom;
1772         params.ucOverscanTop = (uint8_t)bp_params->v_overscan_top;
1773 
1774         if (0 == bp_params->flags.HSYNC_POSITIVE_POLARITY)
1775                 params.susModeMiscInfo.usAccess =
1776                                 cpu_to_le16(le16_to_cpu(params.susModeMiscInfo.usAccess) | ATOM_HSYNC_POLARITY);
1777 
1778         if (0 == bp_params->flags.VSYNC_POSITIVE_POLARITY)
1779                 params.susModeMiscInfo.usAccess =
1780                                 cpu_to_le16(le16_to_cpu(params.susModeMiscInfo.usAccess) | ATOM_VSYNC_POLARITY);
1781 
1782         if (bp_params->flags.INTERLACE) {
1783                 params.susModeMiscInfo.usAccess =
1784                                 cpu_to_le16(le16_to_cpu(params.susModeMiscInfo.usAccess) | ATOM_INTERLACE);
1785 
1786                 /* original DAL code has this condition to apply tis for
1787                  * non-TV/CV only due to complex MV testing for possible
1788                  * impact
1789                  * if (pACParameters->signal != SignalType_YPbPr &&
1790                  *  pACParameters->signal != SignalType_Composite &&
1791                  *  pACParameters->signal != SignalType_SVideo)
1792                  */
1793                 /* HW will deduct 0.5 line from 2nd feild.
1794                  * i.e. for 1080i, it is 2 lines for 1st field, 2.5
1795                  * lines for the 2nd feild. we need input as 5 instead
1796                  * of 4, but it is 4 either from Edid data
1797                  * (spec CEA 861) or CEA timing table.
1798                  */
1799                 params.usV_SyncStart =
1800                                 cpu_to_le16((uint16_t)(bp_params->v_sync_start + 1));
1801         }
1802 
1803         if (bp_params->flags.HORZ_COUNT_BY_TWO)
1804                 params.susModeMiscInfo.usAccess =
1805                                 cpu_to_le16(le16_to_cpu(params.susModeMiscInfo.usAccess) | ATOM_DOUBLE_CLOCK_MODE);
1806 
1807         if (EXEC_BIOS_CMD_TABLE(SetCRTC_Timing, params))
1808                 result = BP_RESULT_OK;
1809 
1810         return result;
1811 }
1812 
1813 static enum bp_result set_crtc_using_dtd_timing_v3(
1814         struct bios_parser *bp,
1815         struct bp_hw_crtc_timing_parameters *bp_params)
1816 {
1817         enum bp_result result = BP_RESULT_FAILURE;
1818         SET_CRTC_USING_DTD_TIMING_PARAMETERS params = {0};
1819         uint8_t atom_controller_id;
1820 
1821         if (bp->cmd_helper->controller_id_to_atom(
1822                         bp_params->controller_id, &atom_controller_id))
1823                 params.ucCRTC = atom_controller_id;
1824 
1825         /* bios usH_Size wants h addressable size */
1826         params.usH_Size = cpu_to_le16((uint16_t)bp_params->h_addressable);
1827         /* bios usH_Blanking_Time wants borders included in blanking */
1828         params.usH_Blanking_Time =
1829                         cpu_to_le16((uint16_t)(bp_params->h_total - bp_params->h_addressable));
1830         /* bios usV_Size wants v addressable size */
1831         params.usV_Size = cpu_to_le16((uint16_t)bp_params->v_addressable);
1832         /* bios usV_Blanking_Time wants borders included in blanking */
1833         params.usV_Blanking_Time =
1834                         cpu_to_le16((uint16_t)(bp_params->v_total - bp_params->v_addressable));
1835         /* bios usHSyncOffset is the offset from the end of h addressable,
1836          * our horizontalSyncStart is the offset from the beginning
1837          * of h addressable */
1838         params.usH_SyncOffset =
1839                         cpu_to_le16((uint16_t)(bp_params->h_sync_start - bp_params->h_addressable));
1840         params.usH_SyncWidth = cpu_to_le16((uint16_t)bp_params->h_sync_width);
1841         /* bios usHSyncOffset is the offset from the end of v addressable,
1842          * our verticalSyncStart is the offset from the beginning of
1843          * v addressable */
1844         params.usV_SyncOffset =
1845                         cpu_to_le16((uint16_t)(bp_params->v_sync_start - bp_params->v_addressable));
1846         params.usV_SyncWidth = cpu_to_le16((uint16_t)bp_params->v_sync_width);
1847 
1848         /* we assume that overscan from original timing does not get bigger
1849          * than 255
1850          * we will program all the borders in the Set CRTC Overscan call below
1851          */
1852 
1853         if (0 == bp_params->flags.HSYNC_POSITIVE_POLARITY)
1854                 params.susModeMiscInfo.usAccess =
1855                                 cpu_to_le16(le16_to_cpu(params.susModeMiscInfo.usAccess) | ATOM_HSYNC_POLARITY);
1856 
1857         if (0 == bp_params->flags.VSYNC_POSITIVE_POLARITY)
1858                 params.susModeMiscInfo.usAccess =
1859                                 cpu_to_le16(le16_to_cpu(params.susModeMiscInfo.usAccess) | ATOM_VSYNC_POLARITY);
1860 
1861         if (bp_params->flags.INTERLACE) {
1862                 params.susModeMiscInfo.usAccess =
1863                                 cpu_to_le16(le16_to_cpu(params.susModeMiscInfo.usAccess) | ATOM_INTERLACE);
1864 
1865                 /* original DAL code has this condition to apply this
1866                  * for non-TV/CV only
1867                  * due to complex MV testing for possible impact
1868                  * if ( pACParameters->signal != SignalType_YPbPr &&
1869                  *  pACParameters->signal != SignalType_Composite &&
1870                  *  pACParameters->signal != SignalType_SVideo)
1871                  */
1872                 {
1873                         /* HW will deduct 0.5 line from 2nd feild.
1874                          * i.e. for 1080i, it is 2 lines for 1st field,
1875                          * 2.5 lines for the 2nd feild. we need input as 5
1876                          * instead of 4.
1877                          * but it is 4 either from Edid data (spec CEA 861)
1878                          * or CEA timing table.
1879                          */
1880                         params.usV_SyncOffset =
1881                                         cpu_to_le16(le16_to_cpu(params.usV_SyncOffset) + 1);
1882 
1883                 }
1884         }
1885 
1886         if (bp_params->flags.HORZ_COUNT_BY_TWO)
1887                 params.susModeMiscInfo.usAccess =
1888                                 cpu_to_le16(le16_to_cpu(params.susModeMiscInfo.usAccess) | ATOM_DOUBLE_CLOCK_MODE);
1889 
1890         if (EXEC_BIOS_CMD_TABLE(SetCRTC_UsingDTDTiming, params))
1891                 result = BP_RESULT_OK;
1892 
1893         return result;
1894 }
1895 
1896 /*******************************************************************************
1897  ********************************************************************************
1898  **
1899  **                  ENABLE CRTC
1900  **
1901  ********************************************************************************
1902  *******************************************************************************/
1903 
1904 static enum bp_result enable_crtc_v1(
1905         struct bios_parser *bp,
1906         enum controller_id controller_id,
1907         bool enable);
1908 
1909 static void init_enable_crtc(struct bios_parser *bp)
1910 {
1911         switch (BIOS_CMD_TABLE_PARA_REVISION(EnableCRTC)) {
1912         case 1:
1913                 bp->cmd_tbl.enable_crtc = enable_crtc_v1;
1914                 break;
1915         default:
1916                 dm_output_to_console("Don't have enable_crtc for v%d\n",
1917                          BIOS_CMD_TABLE_PARA_REVISION(EnableCRTC));
1918                 bp->cmd_tbl.enable_crtc = NULL;
1919                 break;
1920         }
1921 }
1922 
1923 static enum bp_result enable_crtc_v1(
1924         struct bios_parser *bp,
1925         enum controller_id controller_id,
1926         bool enable)
1927 {
1928         bool result = BP_RESULT_FAILURE;
1929         ENABLE_CRTC_PARAMETERS params = {0};
1930         uint8_t id;
1931 
1932         if (bp->cmd_helper->controller_id_to_atom(controller_id, &id))
1933                 params.ucCRTC = id;
1934         else
1935                 return BP_RESULT_BADINPUT;
1936 
1937         if (enable)
1938                 params.ucEnable = ATOM_ENABLE;
1939         else
1940                 params.ucEnable = ATOM_DISABLE;
1941 
1942         if (EXEC_BIOS_CMD_TABLE(EnableCRTC, params))
1943                 result = BP_RESULT_OK;
1944 
1945         return result;
1946 }
1947 
1948 /*******************************************************************************
1949  ********************************************************************************
1950  **
1951  **                  ENABLE CRTC MEM REQ
1952  **
1953  ********************************************************************************
1954  *******************************************************************************/
1955 
1956 static enum bp_result enable_crtc_mem_req_v1(
1957         struct bios_parser *bp,
1958         enum controller_id controller_id,
1959         bool enable);
1960 
1961 static void init_enable_crtc_mem_req(struct bios_parser *bp)
1962 {
1963         switch (BIOS_CMD_TABLE_PARA_REVISION(EnableCRTCMemReq)) {
1964         case 1:
1965                 bp->cmd_tbl.enable_crtc_mem_req = enable_crtc_mem_req_v1;
1966                 break;
1967         default:
1968                 bp->cmd_tbl.enable_crtc_mem_req = NULL;
1969                 break;
1970         }
1971 }
1972 
1973 static enum bp_result enable_crtc_mem_req_v1(
1974         struct bios_parser *bp,
1975         enum controller_id controller_id,
1976         bool enable)
1977 {
1978         bool result = BP_RESULT_BADINPUT;
1979         ENABLE_CRTC_PARAMETERS params = {0};
1980         uint8_t id;
1981 
1982         if (bp->cmd_helper->controller_id_to_atom(controller_id, &id)) {
1983                 params.ucCRTC = id;
1984 
1985                 if (enable)
1986                         params.ucEnable = ATOM_ENABLE;
1987                 else
1988                         params.ucEnable = ATOM_DISABLE;
1989 
1990                 if (EXEC_BIOS_CMD_TABLE(EnableCRTCMemReq, params))
1991                         result = BP_RESULT_OK;
1992                 else
1993                         result = BP_RESULT_FAILURE;
1994         }
1995 
1996         return result;
1997 }
1998 
1999 /*******************************************************************************
2000  ********************************************************************************
2001  **
2002  **                  DISPLAY PLL
2003  **
2004  ********************************************************************************
2005  *******************************************************************************/
2006 
2007 static enum bp_result program_clock_v5(
2008         struct bios_parser *bp,
2009         struct bp_pixel_clock_parameters *bp_params);
2010 static enum bp_result program_clock_v6(
2011         struct bios_parser *bp,
2012         struct bp_pixel_clock_parameters *bp_params);
2013 
2014 static void init_program_clock(struct bios_parser *bp)
2015 {
2016         switch (BIOS_CMD_TABLE_PARA_REVISION(SetPixelClock)) {
2017         case 5:
2018                 bp->cmd_tbl.program_clock = program_clock_v5;
2019                 break;
2020         case 6:
2021                 bp->cmd_tbl.program_clock = program_clock_v6;
2022                 break;
2023         default:
2024                 dm_output_to_console("Don't have program_clock for v%d\n",
2025                          BIOS_CMD_TABLE_PARA_REVISION(SetPixelClock));
2026                 bp->cmd_tbl.program_clock = NULL;
2027                 break;
2028         }
2029 }
2030 
2031 static enum bp_result program_clock_v5(
2032         struct bios_parser *bp,
2033         struct bp_pixel_clock_parameters *bp_params)
2034 {
2035         enum bp_result result = BP_RESULT_FAILURE;
2036 
2037         SET_PIXEL_CLOCK_PS_ALLOCATION_V5 params;
2038         uint32_t atom_pll_id;
2039 
2040         memset(&params, 0, sizeof(params));
2041         if (!bp->cmd_helper->clock_source_id_to_atom(
2042                         bp_params->pll_id, &atom_pll_id)) {
2043                 BREAK_TO_DEBUGGER(); /* Invalid Inpute!! */
2044                 return BP_RESULT_BADINPUT;
2045         }
2046 
2047         /* We need to convert from KHz units into 10KHz units */
2048         params.sPCLKInput.ucPpll = (uint8_t) atom_pll_id;
2049         params.sPCLKInput.usPixelClock =
2050                         cpu_to_le16((uint16_t) (bp_params->target_pixel_clock_100hz / 100));
2051         params.sPCLKInput.ucCRTC = (uint8_t) ATOM_CRTC_INVALID;
2052 
2053         if (bp_params->flags.SET_EXTERNAL_REF_DIV_SRC)
2054                 params.sPCLKInput.ucMiscInfo |= PIXEL_CLOCK_MISC_REF_DIV_SRC;
2055 
2056         if (EXEC_BIOS_CMD_TABLE(SetPixelClock, params))
2057                 result = BP_RESULT_OK;
2058 
2059         return result;
2060 }
2061 
2062 static enum bp_result program_clock_v6(
2063         struct bios_parser *bp,
2064         struct bp_pixel_clock_parameters *bp_params)
2065 {
2066         enum bp_result result = BP_RESULT_FAILURE;
2067 
2068         SET_PIXEL_CLOCK_PS_ALLOCATION_V6 params;
2069         uint32_t atom_pll_id;
2070 
2071         memset(&params, 0, sizeof(params));
2072 
2073         if (!bp->cmd_helper->clock_source_id_to_atom(
2074                         bp_params->pll_id, &atom_pll_id)) {
2075                 BREAK_TO_DEBUGGER(); /*Invalid Input!!*/
2076                 return BP_RESULT_BADINPUT;
2077         }
2078 
2079         /* We need to convert from KHz units into 10KHz units */
2080         params.sPCLKInput.ucPpll = (uint8_t)atom_pll_id;
2081         params.sPCLKInput.ulDispEngClkFreq =
2082                         cpu_to_le32(bp_params->target_pixel_clock_100hz / 100);
2083 
2084         if (bp_params->flags.SET_EXTERNAL_REF_DIV_SRC)
2085                 params.sPCLKInput.ucMiscInfo |= PIXEL_CLOCK_MISC_REF_DIV_SRC;
2086 
2087         if (bp_params->flags.SET_DISPCLK_DFS_BYPASS)
2088                 params.sPCLKInput.ucMiscInfo |= PIXEL_CLOCK_V6_MISC_DPREFCLK_BYPASS;
2089 
2090         if (EXEC_BIOS_CMD_TABLE(SetPixelClock, params)) {
2091                 /* True display clock is returned by VBIOS if DFS bypass
2092                  * is enabled. */
2093                 bp_params->dfs_bypass_display_clock =
2094                                 (uint32_t)(le32_to_cpu(params.sPCLKInput.ulDispEngClkFreq) * 10);
2095                 result = BP_RESULT_OK;
2096         }
2097 
2098         return result;
2099 }
2100 
2101 /*******************************************************************************
2102  ********************************************************************************
2103  **
2104  **                  EXTERNAL ENCODER CONTROL
2105  **
2106  ********************************************************************************
2107  *******************************************************************************/
2108 
2109 static enum bp_result external_encoder_control_v3(
2110         struct bios_parser *bp,
2111         struct bp_external_encoder_control *cntl);
2112 
2113 static void init_external_encoder_control(
2114         struct bios_parser *bp)
2115 {
2116         switch (BIOS_CMD_TABLE_PARA_REVISION(ExternalEncoderControl)) {
2117         case 3:
2118                 bp->cmd_tbl.external_encoder_control =
2119                                 external_encoder_control_v3;
2120                 break;
2121         default:
2122                 bp->cmd_tbl.external_encoder_control = NULL;
2123                 break;
2124         }
2125 }
2126 
2127 static enum bp_result external_encoder_control_v3(
2128         struct bios_parser *bp,
2129         struct bp_external_encoder_control *cntl)
2130 {
2131         enum bp_result result = BP_RESULT_FAILURE;
2132 
2133         /* we need use _PS_Alloc struct */
2134         EXTERNAL_ENCODER_CONTROL_PS_ALLOCATION_V3 params;
2135         EXTERNAL_ENCODER_CONTROL_PARAMETERS_V3 *cntl_params;
2136         struct graphics_object_id encoder;
2137         bool is_input_signal_dp = false;
2138 
2139         memset(&params, 0, sizeof(params));
2140 
2141         cntl_params = &params.sExtEncoder;
2142 
2143         encoder = cntl->encoder_id;
2144 
2145         /* check if encoder supports external encoder control table */
2146         switch (dal_graphics_object_id_get_encoder_id(encoder)) {
2147         case ENCODER_ID_EXTERNAL_NUTMEG:
2148         case ENCODER_ID_EXTERNAL_TRAVIS:
2149                 is_input_signal_dp = true;
2150                 break;
2151 
2152         default:
2153                 BREAK_TO_DEBUGGER();
2154                 return BP_RESULT_BADINPUT;
2155         }
2156 
2157         /* Fill information based on the action
2158          *
2159          * Bit[6:4]: indicate external encoder, applied to all functions.
2160          * =0: external encoder1, mapped to external encoder enum id1
2161          * =1: external encoder2, mapped to external encoder enum id2
2162          *
2163          * enum ObjectEnumId
2164          * {
2165          *  EnumId_Unknown = 0,
2166          *  EnumId_1,
2167          *  EnumId_2,
2168          * };
2169          */
2170         cntl_params->ucConfig = (uint8_t)((encoder.enum_id - 1) << 4);
2171 
2172         switch (cntl->action) {
2173         case EXTERNAL_ENCODER_CONTROL_INIT:
2174                 /* output display connector type. Only valid in encoder
2175                  * initialization */
2176                 cntl_params->usConnectorId =
2177                                 cpu_to_le16((uint16_t)cntl->connector_obj_id.id);
2178                 break;
2179         case EXTERNAL_ENCODER_CONTROL_SETUP:
2180                 /* EXTERNAL_ENCODER_CONTROL_PARAMETERS_V3 pixel clock unit in
2181                  * 10KHz
2182                  * output display device pixel clock frequency in unit of 10KHz.
2183                  * Only valid in setup and enableoutput
2184                  */
2185                 cntl_params->usPixelClock =
2186                                 cpu_to_le16((uint16_t)(cntl->pixel_clock / 10));
2187                 /* Indicate display output signal type drive by external
2188                  * encoder, only valid in setup and enableoutput */
2189                 cntl_params->ucEncoderMode =
2190                                 (uint8_t)bp->cmd_helper->encoder_mode_bp_to_atom(
2191                                                 cntl->signal, false);
2192 
2193                 if (is_input_signal_dp) {
2194                         /* Bit[0]: indicate link rate, =1: 2.7Ghz, =0: 1.62Ghz,
2195                          * only valid in encoder setup with DP mode. */
2196                         if (LINK_RATE_HIGH == cntl->link_rate)
2197                                 cntl_params->ucConfig |= 1;
2198                         /* output color depth Indicate encoder data bpc format
2199                          * in DP mode, only valid in encoder setup in DP mode.
2200                          */
2201                         cntl_params->ucBitPerColor =
2202                                         (uint8_t)(cntl->color_depth);
2203                 }
2204                 /* Indicate how many lanes used by external encoder, only valid
2205                  * in encoder setup and enableoutput. */
2206                 cntl_params->ucLaneNum = (uint8_t)(cntl->lanes_number);
2207                 break;
2208         case EXTERNAL_ENCODER_CONTROL_ENABLE:
2209                 cntl_params->usPixelClock =
2210                                 cpu_to_le16((uint16_t)(cntl->pixel_clock / 10));
2211                 cntl_params->ucEncoderMode =
2212                                 (uint8_t)bp->cmd_helper->encoder_mode_bp_to_atom(
2213                                                 cntl->signal, false);
2214                 cntl_params->ucLaneNum = (uint8_t)cntl->lanes_number;
2215                 break;
2216         default:
2217                 break;
2218         }
2219 
2220         cntl_params->ucAction = (uint8_t)cntl->action;
2221 
2222         if (EXEC_BIOS_CMD_TABLE(ExternalEncoderControl, params))
2223                 result = BP_RESULT_OK;
2224 
2225         return result;
2226 }
2227 
2228 /*******************************************************************************
2229  ********************************************************************************
2230  **
2231  **                  ENABLE DISPLAY POWER GATING
2232  **
2233  ********************************************************************************
2234  *******************************************************************************/
2235 
2236 static enum bp_result enable_disp_power_gating_v2_1(
2237         struct bios_parser *bp,
2238         enum controller_id crtc_id,
2239         enum bp_pipe_control_action action);
2240 
2241 static void init_enable_disp_power_gating(
2242         struct bios_parser *bp)
2243 {
2244         switch (BIOS_CMD_TABLE_PARA_REVISION(EnableDispPowerGating)) {
2245         case 1:
2246                 bp->cmd_tbl.enable_disp_power_gating =
2247                                 enable_disp_power_gating_v2_1;
2248                 break;
2249         default:
2250                 dm_output_to_console("Don't enable_disp_power_gating enable_crtc for v%d\n",
2251                          BIOS_CMD_TABLE_PARA_REVISION(EnableDispPowerGating));
2252                 bp->cmd_tbl.enable_disp_power_gating = NULL;
2253                 break;
2254         }
2255 }
2256 
2257 static enum bp_result enable_disp_power_gating_v2_1(
2258         struct bios_parser *bp,
2259         enum controller_id crtc_id,
2260         enum bp_pipe_control_action action)
2261 {
2262         enum bp_result result = BP_RESULT_FAILURE;
2263 
2264         ENABLE_DISP_POWER_GATING_PS_ALLOCATION params = {0};
2265         uint8_t atom_crtc_id;
2266 
2267         if (bp->cmd_helper->controller_id_to_atom(crtc_id, &atom_crtc_id))
2268                 params.ucDispPipeId = atom_crtc_id;
2269         else
2270                 return BP_RESULT_BADINPUT;
2271 
2272         params.ucEnable =
2273                         bp->cmd_helper->disp_power_gating_action_to_atom(action);
2274 
2275         if (EXEC_BIOS_CMD_TABLE(EnableDispPowerGating, params))
2276                 result = BP_RESULT_OK;
2277 
2278         return result;
2279 }
2280 
2281 /*******************************************************************************
2282  ********************************************************************************
2283  **
2284  **                  SET DCE CLOCK
2285  **
2286  ********************************************************************************
2287  *******************************************************************************/
2288 static enum bp_result set_dce_clock_v2_1(
2289         struct bios_parser *bp,
2290         struct bp_set_dce_clock_parameters *bp_params);
2291 
2292 static void init_set_dce_clock(struct bios_parser *bp)
2293 {
2294         switch (BIOS_CMD_TABLE_PARA_REVISION(SetDCEClock)) {
2295         case 1:
2296                 bp->cmd_tbl.set_dce_clock = set_dce_clock_v2_1;
2297                 break;
2298         default:
2299                 dm_output_to_console("Don't have set_dce_clock for v%d\n",
2300                          BIOS_CMD_TABLE_PARA_REVISION(SetDCEClock));
2301                 bp->cmd_tbl.set_dce_clock = NULL;
2302                 break;
2303         }
2304 }
2305 
2306 static enum bp_result set_dce_clock_v2_1(
2307         struct bios_parser *bp,
2308         struct bp_set_dce_clock_parameters *bp_params)
2309 {
2310         enum bp_result result = BP_RESULT_FAILURE;
2311 
2312         SET_DCE_CLOCK_PS_ALLOCATION_V2_1 params;
2313         uint32_t atom_pll_id;
2314         uint32_t atom_clock_type;
2315         const struct command_table_helper *cmd = bp->cmd_helper;
2316 
2317         memset(&params, 0, sizeof(params));
2318 
2319         if (!cmd->clock_source_id_to_atom(bp_params->pll_id, &atom_pll_id) ||
2320                         !cmd->dc_clock_type_to_atom(bp_params->clock_type, &atom_clock_type))
2321                 return BP_RESULT_BADINPUT;
2322 
2323         params.asParam.ucDCEClkSrc  = atom_pll_id;
2324         params.asParam.ucDCEClkType = atom_clock_type;
2325 
2326         if (bp_params->clock_type == DCECLOCK_TYPE_DPREFCLK) {
2327                 if (bp_params->flags.USE_GENLOCK_AS_SOURCE_FOR_DPREFCLK)
2328                         params.asParam.ucDCEClkFlag |= DCE_CLOCK_FLAG_PLL_REFCLK_SRC_GENLK;
2329 
2330                 if (bp_params->flags.USE_PCIE_AS_SOURCE_FOR_DPREFCLK)
2331                         params.asParam.ucDCEClkFlag |= DCE_CLOCK_FLAG_PLL_REFCLK_SRC_PCIE;
2332 
2333                 if (bp_params->flags.USE_XTALIN_AS_SOURCE_FOR_DPREFCLK)
2334                         params.asParam.ucDCEClkFlag |= DCE_CLOCK_FLAG_PLL_REFCLK_SRC_XTALIN;
2335 
2336                 if (bp_params->flags.USE_GENERICA_AS_SOURCE_FOR_DPREFCLK)
2337                         params.asParam.ucDCEClkFlag |= DCE_CLOCK_FLAG_PLL_REFCLK_SRC_GENERICA;
2338         }
2339         else
2340                 /* only program clock frequency if display clock is used; VBIOS will program DPREFCLK */
2341                 /* We need to convert from KHz units into 10KHz units */
2342                 params.asParam.ulDCEClkFreq = cpu_to_le32(bp_params->target_clock_frequency / 10);
2343 
2344         if (EXEC_BIOS_CMD_TABLE(SetDCEClock, params)) {
2345                 /* Convert from 10KHz units back to KHz */
2346                 bp_params->target_clock_frequency = le32_to_cpu(params.asParam.ulDCEClkFreq) * 10;
2347                 result = BP_RESULT_OK;
2348         }
2349 
2350         return result;
2351 }

/* [<][>][^][v][top][bottom][index][help] */