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