Back to home page

OSCL-LXR

 
 

    


0001 /*
0002  * Copyright 2012-15 Advanced Micro Devices, Inc.
0003  *
0004  * Permission is hereby granted, free of charge, to any person obtaining a
0005  * copy of this software and associated documentation files (the "Software"),
0006  * to deal in the Software without restriction, including without limitation
0007  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
0008  * and/or sell copies of the Software, and to permit persons to whom the
0009  * Software is furnished to do so, subject to the following conditions:
0010  *
0011  * The above copyright notice and this permission notice shall be included in
0012  * all copies or substantial portions of the Software.
0013  *
0014  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
0015  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
0016  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
0017  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
0018  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
0019  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
0020  * OTHER DEALINGS IN THE SOFTWARE.
0021  *
0022  * Authors: AMD
0023  *
0024  */
0025 
0026 #include "dm_services.h"
0027 
0028 #include "ObjectID.h"
0029 
0030 #include "atomfirmware.h"
0031 #include "atom.h"
0032 #include "include/bios_parser_interface.h"
0033 
0034 #include "command_table2.h"
0035 #include "command_table_helper2.h"
0036 #include "bios_parser_helper.h"
0037 #include "bios_parser_types_internal2.h"
0038 #include "amdgpu.h"
0039 
0040 #include "dc_dmub_srv.h"
0041 #include "dc.h"
0042 
0043 #define DC_LOGGER \
0044     bp->base.ctx->logger
0045 
0046 #define GET_INDEX_INTO_MASTER_TABLE(MasterOrData, FieldName)\
0047     (offsetof(struct atom_master_list_of_##MasterOrData##_functions_v2_1, FieldName) / sizeof(uint16_t))
0048 
0049 #define EXEC_BIOS_CMD_TABLE(fname, params)\
0050     (amdgpu_atom_execute_table(((struct amdgpu_device *)bp->base.ctx->driver_context)->mode_info.atom_context, \
0051         GET_INDEX_INTO_MASTER_TABLE(command, fname), \
0052         (uint32_t *)&params) == 0)
0053 
0054 #define BIOS_CMD_TABLE_REVISION(fname, frev, crev)\
0055     amdgpu_atom_parse_cmd_header(((struct amdgpu_device *)bp->base.ctx->driver_context)->mode_info.atom_context, \
0056         GET_INDEX_INTO_MASTER_TABLE(command, fname), &frev, &crev)
0057 
0058 #define BIOS_CMD_TABLE_PARA_REVISION(fname)\
0059     bios_cmd_table_para_revision(bp->base.ctx->driver_context, \
0060             GET_INDEX_INTO_MASTER_TABLE(command, fname))
0061 
0062 
0063 
0064 static uint32_t bios_cmd_table_para_revision(void *dev,
0065                          uint32_t index)
0066 {
0067     struct amdgpu_device *adev = dev;
0068     uint8_t frev, crev;
0069 
0070     if (amdgpu_atom_parse_cmd_header(adev->mode_info.atom_context,
0071                     index,
0072                     &frev, &crev))
0073         return crev;
0074     else
0075         return 0;
0076 }
0077 
0078 /******************************************************************************
0079  ******************************************************************************
0080  **
0081  **                  D I G E N C O D E R C O N T R O L
0082  **
0083  ******************************************************************************
0084  *****************************************************************************/
0085 
0086 static enum bp_result encoder_control_digx_v1_5(
0087     struct bios_parser *bp,
0088     struct bp_encoder_control *cntl);
0089 
0090 static enum bp_result encoder_control_fallback(
0091     struct bios_parser *bp,
0092     struct bp_encoder_control *cntl);
0093 
0094 static void init_dig_encoder_control(struct bios_parser *bp)
0095 {
0096     uint32_t version =
0097         BIOS_CMD_TABLE_PARA_REVISION(digxencodercontrol);
0098 
0099     switch (version) {
0100     case 5:
0101         bp->cmd_tbl.dig_encoder_control = encoder_control_digx_v1_5;
0102         break;
0103     default:
0104         dm_output_to_console("Don't have dig_encoder_control for v%d\n", version);
0105         bp->cmd_tbl.dig_encoder_control = encoder_control_fallback;
0106         break;
0107     }
0108 }
0109 
0110 static void encoder_control_dmcub(
0111         struct dc_dmub_srv *dmcub,
0112         struct dig_encoder_stream_setup_parameters_v1_5 *dig)
0113 {
0114     union dmub_rb_cmd cmd;
0115 
0116     memset(&cmd, 0, sizeof(cmd));
0117 
0118     cmd.digx_encoder_control.header.type = DMUB_CMD__VBIOS;
0119     cmd.digx_encoder_control.header.sub_type =
0120         DMUB_CMD__VBIOS_DIGX_ENCODER_CONTROL;
0121     cmd.digx_encoder_control.header.payload_bytes =
0122         sizeof(cmd.digx_encoder_control) -
0123         sizeof(cmd.digx_encoder_control.header);
0124     cmd.digx_encoder_control.encoder_control.dig.stream_param = *dig;
0125 
0126     dc_dmub_srv_cmd_queue(dmcub, &cmd);
0127     dc_dmub_srv_cmd_execute(dmcub);
0128     dc_dmub_srv_wait_idle(dmcub);
0129 }
0130 
0131 static enum bp_result encoder_control_digx_v1_5(
0132     struct bios_parser *bp,
0133     struct bp_encoder_control *cntl)
0134 {
0135     enum bp_result result = BP_RESULT_FAILURE;
0136     struct dig_encoder_stream_setup_parameters_v1_5 params = {0};
0137 
0138     params.digid = (uint8_t)(cntl->engine_id);
0139     params.action = bp->cmd_helper->encoder_action_to_atom(cntl->action);
0140 
0141     params.pclk_10khz = cntl->pixel_clock / 10;
0142     params.digmode =
0143             (uint8_t)(bp->cmd_helper->encoder_mode_bp_to_atom(
0144                     cntl->signal,
0145                     cntl->enable_dp_audio));
0146     params.lanenum = (uint8_t)(cntl->lanes_number);
0147 
0148     switch (cntl->color_depth) {
0149     case COLOR_DEPTH_888:
0150         params.bitpercolor = PANEL_8BIT_PER_COLOR;
0151         break;
0152     case COLOR_DEPTH_101010:
0153         params.bitpercolor = PANEL_10BIT_PER_COLOR;
0154         break;
0155     case COLOR_DEPTH_121212:
0156         params.bitpercolor = PANEL_12BIT_PER_COLOR;
0157         break;
0158     case COLOR_DEPTH_161616:
0159         params.bitpercolor = PANEL_16BIT_PER_COLOR;
0160         break;
0161     default:
0162         break;
0163     }
0164 
0165     if (cntl->signal == SIGNAL_TYPE_HDMI_TYPE_A)
0166         switch (cntl->color_depth) {
0167         case COLOR_DEPTH_101010:
0168             params.pclk_10khz =
0169                 (params.pclk_10khz * 30) / 24;
0170             break;
0171         case COLOR_DEPTH_121212:
0172             params.pclk_10khz =
0173                 (params.pclk_10khz * 36) / 24;
0174             break;
0175         case COLOR_DEPTH_161616:
0176             params.pclk_10khz =
0177                 (params.pclk_10khz * 48) / 24;
0178             break;
0179         default:
0180             break;
0181         }
0182 
0183     if (bp->base.ctx->dc->ctx->dmub_srv &&
0184         bp->base.ctx->dc->debug.dmub_command_table) {
0185         encoder_control_dmcub(bp->base.ctx->dmub_srv, &params);
0186         return BP_RESULT_OK;
0187     }
0188 
0189     if (EXEC_BIOS_CMD_TABLE(digxencodercontrol, params))
0190         result = BP_RESULT_OK;
0191 
0192     return result;
0193 }
0194 
0195 static enum bp_result encoder_control_fallback(
0196     struct bios_parser *bp,
0197     struct bp_encoder_control *cntl)
0198 {
0199     if (bp->base.ctx->dc->ctx->dmub_srv &&
0200         bp->base.ctx->dc->debug.dmub_command_table) {
0201         return encoder_control_digx_v1_5(bp, cntl);
0202     }
0203 
0204     return BP_RESULT_FAILURE;
0205 }
0206 
0207 /*****************************************************************************
0208  ******************************************************************************
0209  **
0210  **                  TRANSMITTER CONTROL
0211  **
0212  ******************************************************************************
0213  *****************************************************************************/
0214 
0215 static enum bp_result transmitter_control_v1_6(
0216     struct bios_parser *bp,
0217     struct bp_transmitter_control *cntl);
0218 
0219 static enum bp_result transmitter_control_v1_7(
0220     struct bios_parser *bp,
0221     struct bp_transmitter_control *cntl);
0222 
0223 static enum bp_result transmitter_control_fallback(
0224     struct bios_parser *bp,
0225     struct bp_transmitter_control *cntl);
0226 
0227 static void init_transmitter_control(struct bios_parser *bp)
0228 {
0229     uint8_t frev;
0230     uint8_t crev;
0231 
0232     BIOS_CMD_TABLE_REVISION(dig1transmittercontrol, frev, crev);
0233 
0234     switch (crev) {
0235     case 6:
0236         bp->cmd_tbl.transmitter_control = transmitter_control_v1_6;
0237         break;
0238     case 7:
0239         bp->cmd_tbl.transmitter_control = transmitter_control_v1_7;
0240         break;
0241     default:
0242         dm_output_to_console("Don't have transmitter_control for v%d\n", crev);
0243         bp->cmd_tbl.transmitter_control = transmitter_control_fallback;
0244         break;
0245     }
0246 }
0247 
0248 static void transmitter_control_dmcub(
0249         struct dc_dmub_srv *dmcub,
0250         struct dig_transmitter_control_parameters_v1_6 *dig)
0251 {
0252     union dmub_rb_cmd cmd;
0253 
0254     memset(&cmd, 0, sizeof(cmd));
0255 
0256     cmd.dig1_transmitter_control.header.type = DMUB_CMD__VBIOS;
0257     cmd.dig1_transmitter_control.header.sub_type =
0258         DMUB_CMD__VBIOS_DIG1_TRANSMITTER_CONTROL;
0259     cmd.dig1_transmitter_control.header.payload_bytes =
0260         sizeof(cmd.dig1_transmitter_control) -
0261         sizeof(cmd.dig1_transmitter_control.header);
0262     cmd.dig1_transmitter_control.transmitter_control.dig = *dig;
0263 
0264     dc_dmub_srv_cmd_queue(dmcub, &cmd);
0265     dc_dmub_srv_cmd_execute(dmcub);
0266     dc_dmub_srv_wait_idle(dmcub);
0267 }
0268 
0269 static enum bp_result transmitter_control_v1_6(
0270     struct bios_parser *bp,
0271     struct bp_transmitter_control *cntl)
0272 {
0273     enum bp_result result = BP_RESULT_FAILURE;
0274     const struct command_table_helper *cmd = bp->cmd_helper;
0275     struct dig_transmitter_control_ps_allocation_v1_6 ps = { { 0 } };
0276 
0277     ps.param.phyid = cmd->phy_id_to_atom(cntl->transmitter);
0278     ps.param.action = (uint8_t)cntl->action;
0279 
0280     if (cntl->action == TRANSMITTER_CONTROL_SET_VOLTAGE_AND_PREEMPASIS)
0281         ps.param.mode_laneset.dplaneset = (uint8_t)cntl->lane_settings;
0282     else
0283         ps.param.mode_laneset.digmode =
0284                 cmd->signal_type_to_atom_dig_mode(cntl->signal);
0285 
0286     ps.param.lanenum = (uint8_t)cntl->lanes_number;
0287     ps.param.hpdsel = cmd->hpd_sel_to_atom(cntl->hpd_sel);
0288     ps.param.digfe_sel = cmd->dig_encoder_sel_to_atom(cntl->engine_id);
0289     ps.param.connobj_id = (uint8_t)cntl->connector_obj_id.id;
0290     ps.param.symclk_10khz = cntl->pixel_clock/10;
0291 
0292 
0293     if (cntl->action == TRANSMITTER_CONTROL_ENABLE ||
0294         cntl->action == TRANSMITTER_CONTROL_ACTIAVATE ||
0295         cntl->action == TRANSMITTER_CONTROL_DEACTIVATE) {
0296         DC_LOG_BIOS("%s:ps.param.symclk_10khz = %d\n",\
0297         __func__, ps.param.symclk_10khz);
0298     }
0299 
0300     if (bp->base.ctx->dc->ctx->dmub_srv &&
0301         bp->base.ctx->dc->debug.dmub_command_table) {
0302         transmitter_control_dmcub(bp->base.ctx->dmub_srv, &ps.param);
0303         return BP_RESULT_OK;
0304     }
0305 
0306 /*color_depth not used any more, driver has deep color factor in the Phyclk*/
0307     if (EXEC_BIOS_CMD_TABLE(dig1transmittercontrol, ps))
0308         result = BP_RESULT_OK;
0309     return result;
0310 }
0311 
0312 static void transmitter_control_dmcub_v1_7(
0313         struct dc_dmub_srv *dmcub,
0314         struct dmub_dig_transmitter_control_data_v1_7 *dig)
0315 {
0316     union dmub_rb_cmd cmd;
0317 
0318     memset(&cmd, 0, sizeof(cmd));
0319 
0320     cmd.dig1_transmitter_control.header.type = DMUB_CMD__VBIOS;
0321     cmd.dig1_transmitter_control.header.sub_type =
0322         DMUB_CMD__VBIOS_DIG1_TRANSMITTER_CONTROL;
0323     cmd.dig1_transmitter_control.header.payload_bytes =
0324         sizeof(cmd.dig1_transmitter_control) -
0325         sizeof(cmd.dig1_transmitter_control.header);
0326     cmd.dig1_transmitter_control.transmitter_control.dig_v1_7 = *dig;
0327 
0328     dc_dmub_srv_cmd_queue(dmcub, &cmd);
0329     dc_dmub_srv_cmd_execute(dmcub);
0330     dc_dmub_srv_wait_idle(dmcub);
0331 }
0332 
0333 static enum bp_result transmitter_control_v1_7(
0334     struct bios_parser *bp,
0335     struct bp_transmitter_control *cntl)
0336 {
0337     enum bp_result result = BP_RESULT_FAILURE;
0338     const struct command_table_helper *cmd = bp->cmd_helper;
0339     struct dmub_dig_transmitter_control_data_v1_7 dig_v1_7 = {0};
0340 
0341     uint8_t hpo_instance = (uint8_t)cntl->hpo_engine_id - ENGINE_ID_HPO_0;
0342 
0343     if (dc_is_dp_signal(cntl->signal))
0344         hpo_instance = (uint8_t)cntl->hpo_engine_id - ENGINE_ID_HPO_DP_0;
0345 
0346     dig_v1_7.phyid = cmd->phy_id_to_atom(cntl->transmitter);
0347     dig_v1_7.action = (uint8_t)cntl->action;
0348 
0349     if (cntl->action == TRANSMITTER_CONTROL_SET_VOLTAGE_AND_PREEMPASIS)
0350         dig_v1_7.mode_laneset.dplaneset = (uint8_t)cntl->lane_settings;
0351     else
0352         dig_v1_7.mode_laneset.digmode =
0353                 cmd->signal_type_to_atom_dig_mode(cntl->signal);
0354 
0355     dig_v1_7.lanenum = (uint8_t)cntl->lanes_number;
0356     dig_v1_7.hpdsel = cmd->hpd_sel_to_atom(cntl->hpd_sel);
0357     dig_v1_7.digfe_sel = cmd->dig_encoder_sel_to_atom(cntl->engine_id);
0358     dig_v1_7.connobj_id = (uint8_t)cntl->connector_obj_id.id;
0359     dig_v1_7.HPO_instance = hpo_instance;
0360     dig_v1_7.symclk_units.symclk_10khz = cntl->pixel_clock/10;
0361 
0362     if (cntl->action == TRANSMITTER_CONTROL_ENABLE ||
0363         cntl->action == TRANSMITTER_CONTROL_ACTIAVATE ||
0364         cntl->action == TRANSMITTER_CONTROL_DEACTIVATE) {
0365             DC_LOG_BIOS("%s:dig_v1_7.symclk_units.symclk_10khz = %d\n",
0366             __func__, dig_v1_7.symclk_units.symclk_10khz);
0367     }
0368 
0369     if (bp->base.ctx->dc->ctx->dmub_srv &&
0370         bp->base.ctx->dc->debug.dmub_command_table) {
0371         transmitter_control_dmcub_v1_7(bp->base.ctx->dmub_srv, &dig_v1_7);
0372         return BP_RESULT_OK;
0373     }
0374 
0375 /*color_depth not used any more, driver has deep color factor in the Phyclk*/
0376     if (EXEC_BIOS_CMD_TABLE(dig1transmittercontrol, dig_v1_7))
0377         result = BP_RESULT_OK;
0378     return result;
0379 }
0380 
0381 static enum bp_result transmitter_control_fallback(
0382     struct bios_parser *bp,
0383     struct bp_transmitter_control *cntl)
0384 {
0385     if (bp->base.ctx->dc->ctx->dmub_srv &&
0386         bp->base.ctx->dc->debug.dmub_command_table) {
0387         return transmitter_control_v1_7(bp, cntl);
0388     }
0389 
0390     return BP_RESULT_FAILURE;
0391 }
0392 
0393 /******************************************************************************
0394  ******************************************************************************
0395  **
0396  **                  SET PIXEL CLOCK
0397  **
0398  ******************************************************************************
0399  *****************************************************************************/
0400 
0401 static enum bp_result set_pixel_clock_v7(
0402     struct bios_parser *bp,
0403     struct bp_pixel_clock_parameters *bp_params);
0404 
0405 static enum bp_result set_pixel_clock_fallback(
0406     struct bios_parser *bp,
0407     struct bp_pixel_clock_parameters *bp_params);
0408 
0409 static void init_set_pixel_clock(struct bios_parser *bp)
0410 {
0411     switch (BIOS_CMD_TABLE_PARA_REVISION(setpixelclock)) {
0412     case 7:
0413         bp->cmd_tbl.set_pixel_clock = set_pixel_clock_v7;
0414         break;
0415     default:
0416         dm_output_to_console("Don't have set_pixel_clock for v%d\n",
0417              BIOS_CMD_TABLE_PARA_REVISION(setpixelclock));
0418         bp->cmd_tbl.set_pixel_clock = set_pixel_clock_fallback;
0419         break;
0420     }
0421 }
0422 
0423 static void set_pixel_clock_dmcub(
0424         struct dc_dmub_srv *dmcub,
0425         struct set_pixel_clock_parameter_v1_7 *clk)
0426 {
0427     union dmub_rb_cmd cmd;
0428 
0429     memset(&cmd, 0, sizeof(cmd));
0430 
0431     cmd.set_pixel_clock.header.type = DMUB_CMD__VBIOS;
0432     cmd.set_pixel_clock.header.sub_type = DMUB_CMD__VBIOS_SET_PIXEL_CLOCK;
0433     cmd.set_pixel_clock.header.payload_bytes =
0434         sizeof(cmd.set_pixel_clock) -
0435         sizeof(cmd.set_pixel_clock.header);
0436     cmd.set_pixel_clock.pixel_clock.clk = *clk;
0437 
0438     dc_dmub_srv_cmd_queue(dmcub, &cmd);
0439     dc_dmub_srv_cmd_execute(dmcub);
0440     dc_dmub_srv_wait_idle(dmcub);
0441 }
0442 
0443 static enum bp_result set_pixel_clock_v7(
0444     struct bios_parser *bp,
0445     struct bp_pixel_clock_parameters *bp_params)
0446 {
0447     enum bp_result result = BP_RESULT_FAILURE;
0448     struct set_pixel_clock_parameter_v1_7 clk;
0449     uint8_t controller_id;
0450     uint32_t pll_id;
0451 
0452     memset(&clk, 0, sizeof(clk));
0453 
0454     if (bp->cmd_helper->clock_source_id_to_atom(bp_params->pll_id, &pll_id)
0455             && bp->cmd_helper->controller_id_to_atom(bp_params->
0456                     controller_id, &controller_id)) {
0457         /* Note: VBIOS still wants to use ucCRTC name which is now
0458          * 1 byte in ULONG
0459          *typedef struct _CRTC_PIXEL_CLOCK_FREQ
0460          *{
0461          * target the pixel clock to drive the CRTC timing.
0462          * ULONG ulPixelClock:24;
0463          * 0 means disable PPLL/DCPLL. Expanded to 24 bits comparing to
0464          * previous version.
0465          * ATOM_CRTC1~6, indicate the CRTC controller to
0466          * ULONG ucCRTC:8;
0467          * drive the pixel clock. not used for DCPLL case.
0468          *}CRTC_PIXEL_CLOCK_FREQ;
0469          *union
0470          *{
0471          * pixel clock and CRTC id frequency
0472          * CRTC_PIXEL_CLOCK_FREQ ulCrtcPclkFreq;
0473          * ULONG ulDispEngClkFreq; dispclk frequency
0474          *};
0475          */
0476         clk.crtc_id = controller_id;
0477         clk.pll_id = (uint8_t) pll_id;
0478         clk.encoderobjid =
0479             bp->cmd_helper->encoder_id_to_atom(
0480                 dal_graphics_object_id_get_encoder_id(
0481                     bp_params->encoder_object_id));
0482 
0483         clk.encoder_mode = (uint8_t) bp->
0484             cmd_helper->encoder_mode_bp_to_atom(
0485                 bp_params->signal_type, false);
0486 
0487         clk.pixclk_100hz = cpu_to_le32(bp_params->target_pixel_clock_100hz);
0488 
0489         clk.deep_color_ratio =
0490             (uint8_t) bp->cmd_helper->
0491                 transmitter_color_depth_to_atom(
0492                     bp_params->color_depth);
0493 
0494         DC_LOG_BIOS("%s:program display clock = %d, tg = %d, pll = %d, "\
0495                 "colorDepth = %d\n", __func__,
0496                 bp_params->target_pixel_clock_100hz, (int)controller_id,
0497                 pll_id, bp_params->color_depth);
0498 
0499         if (bp_params->flags.FORCE_PROGRAMMING_OF_PLL)
0500             clk.miscinfo |= PIXEL_CLOCK_V7_MISC_FORCE_PROG_PPLL;
0501 
0502         if (bp_params->flags.PROGRAM_PHY_PLL_ONLY)
0503             clk.miscinfo |= PIXEL_CLOCK_V7_MISC_PROG_PHYPLL;
0504 
0505         if (bp_params->flags.SUPPORT_YUV_420)
0506             clk.miscinfo |= PIXEL_CLOCK_V7_MISC_YUV420_MODE;
0507 
0508         if (bp_params->flags.SET_XTALIN_REF_SRC)
0509             clk.miscinfo |= PIXEL_CLOCK_V7_MISC_REF_DIV_SRC_XTALIN;
0510 
0511         if (bp_params->flags.SET_GENLOCK_REF_DIV_SRC)
0512             clk.miscinfo |= PIXEL_CLOCK_V7_MISC_REF_DIV_SRC_GENLK;
0513 
0514         if (bp_params->signal_type == SIGNAL_TYPE_DVI_DUAL_LINK)
0515             clk.miscinfo |= PIXEL_CLOCK_V7_MISC_DVI_DUALLINK_EN;
0516 
0517         if (bp->base.ctx->dc->ctx->dmub_srv &&
0518             bp->base.ctx->dc->debug.dmub_command_table) {
0519             set_pixel_clock_dmcub(bp->base.ctx->dmub_srv, &clk);
0520             return BP_RESULT_OK;
0521         }
0522 
0523         if (EXEC_BIOS_CMD_TABLE(setpixelclock, clk))
0524             result = BP_RESULT_OK;
0525     }
0526     return result;
0527 }
0528 
0529 static enum bp_result set_pixel_clock_fallback(
0530     struct bios_parser *bp,
0531     struct bp_pixel_clock_parameters *bp_params)
0532 {
0533     if (bp->base.ctx->dc->ctx->dmub_srv &&
0534         bp->base.ctx->dc->debug.dmub_command_table) {
0535         return set_pixel_clock_v7(bp, bp_params);
0536     }
0537 
0538     return BP_RESULT_FAILURE;
0539 }
0540 
0541 /******************************************************************************
0542  ******************************************************************************
0543  **
0544  **                  SET CRTC TIMING
0545  **
0546  ******************************************************************************
0547  *****************************************************************************/
0548 
0549 static enum bp_result set_crtc_using_dtd_timing_v3(
0550     struct bios_parser *bp,
0551     struct bp_hw_crtc_timing_parameters *bp_params);
0552 
0553 static void init_set_crtc_timing(struct bios_parser *bp)
0554 {
0555     uint32_t dtd_version =
0556             BIOS_CMD_TABLE_PARA_REVISION(setcrtc_usingdtdtiming);
0557 
0558     switch (dtd_version) {
0559     case 3:
0560         bp->cmd_tbl.set_crtc_timing =
0561             set_crtc_using_dtd_timing_v3;
0562         break;
0563     default:
0564         dm_output_to_console("Don't have set_crtc_timing for v%d\n", dtd_version);
0565         bp->cmd_tbl.set_crtc_timing = NULL;
0566         break;
0567     }
0568 }
0569 
0570 static enum bp_result set_crtc_using_dtd_timing_v3(
0571     struct bios_parser *bp,
0572     struct bp_hw_crtc_timing_parameters *bp_params)
0573 {
0574     enum bp_result result = BP_RESULT_FAILURE;
0575     struct set_crtc_using_dtd_timing_parameters params = {0};
0576     uint8_t atom_controller_id;
0577 
0578     if (bp->cmd_helper->controller_id_to_atom(
0579             bp_params->controller_id, &atom_controller_id))
0580         params.crtc_id = atom_controller_id;
0581 
0582     /* bios usH_Size wants h addressable size */
0583     params.h_size = cpu_to_le16((uint16_t)bp_params->h_addressable);
0584     /* bios usH_Blanking_Time wants borders included in blanking */
0585     params.h_blanking_time =
0586             cpu_to_le16((uint16_t)(bp_params->h_total -
0587                     bp_params->h_addressable));
0588     /* bios usV_Size wants v addressable size */
0589     params.v_size = cpu_to_le16((uint16_t)bp_params->v_addressable);
0590     /* bios usV_Blanking_Time wants borders included in blanking */
0591     params.v_blanking_time =
0592             cpu_to_le16((uint16_t)(bp_params->v_total -
0593                     bp_params->v_addressable));
0594     /* bios usHSyncOffset is the offset from the end of h addressable,
0595      * our horizontalSyncStart is the offset from the beginning
0596      * of h addressable
0597      */
0598     params.h_syncoffset =
0599             cpu_to_le16((uint16_t)(bp_params->h_sync_start -
0600                     bp_params->h_addressable));
0601     params.h_syncwidth = cpu_to_le16((uint16_t)bp_params->h_sync_width);
0602     /* bios usHSyncOffset is the offset from the end of v addressable,
0603      * our verticalSyncStart is the offset from the beginning of
0604      * v addressable
0605      */
0606     params.v_syncoffset =
0607             cpu_to_le16((uint16_t)(bp_params->v_sync_start -
0608                     bp_params->v_addressable));
0609     params.v_syncwidth = cpu_to_le16((uint16_t)bp_params->v_sync_width);
0610 
0611     /* we assume that overscan from original timing does not get bigger
0612      * than 255
0613      * we will program all the borders in the Set CRTC Overscan call below
0614      */
0615 
0616     if (bp_params->flags.HSYNC_POSITIVE_POLARITY == 0)
0617         params.modemiscinfo =
0618                 cpu_to_le16(le16_to_cpu(params.modemiscinfo) |
0619                         ATOM_HSYNC_POLARITY);
0620 
0621     if (bp_params->flags.VSYNC_POSITIVE_POLARITY == 0)
0622         params.modemiscinfo =
0623                 cpu_to_le16(le16_to_cpu(params.modemiscinfo) |
0624                         ATOM_VSYNC_POLARITY);
0625 
0626     if (bp_params->flags.INTERLACE) {
0627         params.modemiscinfo =
0628                 cpu_to_le16(le16_to_cpu(params.modemiscinfo) |
0629                         ATOM_INTERLACE);
0630 
0631         /* original DAL code has this condition to apply this
0632          * for non-TV/CV only
0633          * due to complex MV testing for possible impact
0634          * if ( pACParameters->signal != SignalType_YPbPr &&
0635          *  pACParameters->signal != SignalType_Composite &&
0636          *  pACParameters->signal != SignalType_SVideo)
0637          */
0638         {
0639             /* HW will deduct 0.5 line from 2nd feild.
0640              * i.e. for 1080i, it is 2 lines for 1st field,
0641              * 2.5 lines for the 2nd feild. we need input as 5
0642              * instead of 4.
0643              * but it is 4 either from Edid data (spec CEA 861)
0644              * or CEA timing table.
0645              */
0646             le16_add_cpu(&params.v_syncoffset, 1);
0647         }
0648     }
0649 
0650     if (bp_params->flags.HORZ_COUNT_BY_TWO)
0651         params.modemiscinfo =
0652             cpu_to_le16(le16_to_cpu(params.modemiscinfo) |
0653                     0x100); /* ATOM_DOUBLE_CLOCK_MODE */
0654 
0655     if (EXEC_BIOS_CMD_TABLE(setcrtc_usingdtdtiming, params))
0656         result = BP_RESULT_OK;
0657 
0658     return result;
0659 }
0660 
0661 /******************************************************************************
0662  ******************************************************************************
0663  **
0664  **                  ENABLE CRTC
0665  **
0666  ******************************************************************************
0667  *****************************************************************************/
0668 
0669 static enum bp_result enable_crtc_v1(
0670     struct bios_parser *bp,
0671     enum controller_id controller_id,
0672     bool enable);
0673 
0674 static void init_enable_crtc(struct bios_parser *bp)
0675 {
0676     switch (BIOS_CMD_TABLE_PARA_REVISION(enablecrtc)) {
0677     case 1:
0678         bp->cmd_tbl.enable_crtc = enable_crtc_v1;
0679         break;
0680     default:
0681         dm_output_to_console("Don't have enable_crtc for v%d\n",
0682              BIOS_CMD_TABLE_PARA_REVISION(enablecrtc));
0683         bp->cmd_tbl.enable_crtc = NULL;
0684         break;
0685     }
0686 }
0687 
0688 static enum bp_result enable_crtc_v1(
0689     struct bios_parser *bp,
0690     enum controller_id controller_id,
0691     bool enable)
0692 {
0693     bool result = BP_RESULT_FAILURE;
0694     struct enable_crtc_parameters params = {0};
0695     uint8_t id;
0696 
0697     if (bp->cmd_helper->controller_id_to_atom(controller_id, &id))
0698         params.crtc_id = id;
0699     else
0700         return BP_RESULT_BADINPUT;
0701 
0702     if (enable)
0703         params.enable = ATOM_ENABLE;
0704     else
0705         params.enable = ATOM_DISABLE;
0706 
0707     if (EXEC_BIOS_CMD_TABLE(enablecrtc, params))
0708         result = BP_RESULT_OK;
0709 
0710     return result;
0711 }
0712 
0713 /******************************************************************************
0714  ******************************************************************************
0715  **
0716  **                  DISPLAY PLL
0717  **
0718  ******************************************************************************
0719  *****************************************************************************/
0720 
0721 
0722 
0723 /******************************************************************************
0724  ******************************************************************************
0725  **
0726  **                  EXTERNAL ENCODER CONTROL
0727  **
0728  ******************************************************************************
0729  *****************************************************************************/
0730 
0731 static enum bp_result external_encoder_control_v3(
0732     struct bios_parser *bp,
0733     struct bp_external_encoder_control *cntl);
0734 
0735 static void init_external_encoder_control(
0736     struct bios_parser *bp)
0737 {
0738     switch (BIOS_CMD_TABLE_PARA_REVISION(externalencodercontrol)) {
0739     case 3:
0740         bp->cmd_tbl.external_encoder_control =
0741                 external_encoder_control_v3;
0742         break;
0743     default:
0744         bp->cmd_tbl.external_encoder_control = NULL;
0745         break;
0746     }
0747 }
0748 
0749 static enum bp_result external_encoder_control_v3(
0750     struct bios_parser *bp,
0751     struct bp_external_encoder_control *cntl)
0752 {
0753     /* TODO */
0754     return BP_RESULT_OK;
0755 }
0756 
0757 /******************************************************************************
0758  ******************************************************************************
0759  **
0760  **                  ENABLE DISPLAY POWER GATING
0761  **
0762  ******************************************************************************
0763  *****************************************************************************/
0764 
0765 static enum bp_result enable_disp_power_gating_v2_1(
0766     struct bios_parser *bp,
0767     enum controller_id crtc_id,
0768     enum bp_pipe_control_action action);
0769 
0770 static enum bp_result enable_disp_power_gating_fallback(
0771     struct bios_parser *bp,
0772     enum controller_id crtc_id,
0773     enum bp_pipe_control_action action);
0774 
0775 static void init_enable_disp_power_gating(
0776     struct bios_parser *bp)
0777 {
0778     switch (BIOS_CMD_TABLE_PARA_REVISION(enabledisppowergating)) {
0779     case 1:
0780         bp->cmd_tbl.enable_disp_power_gating =
0781                 enable_disp_power_gating_v2_1;
0782         break;
0783     default:
0784         dm_output_to_console("Don't enable_disp_power_gating enable_crtc for v%d\n",
0785              BIOS_CMD_TABLE_PARA_REVISION(enabledisppowergating));
0786         bp->cmd_tbl.enable_disp_power_gating = enable_disp_power_gating_fallback;
0787         break;
0788     }
0789 }
0790 
0791 static void enable_disp_power_gating_dmcub(
0792     struct dc_dmub_srv *dmcub,
0793     struct enable_disp_power_gating_parameters_v2_1 *pwr)
0794 {
0795     union dmub_rb_cmd cmd;
0796 
0797     memset(&cmd, 0, sizeof(cmd));
0798 
0799     cmd.enable_disp_power_gating.header.type = DMUB_CMD__VBIOS;
0800     cmd.enable_disp_power_gating.header.sub_type =
0801         DMUB_CMD__VBIOS_ENABLE_DISP_POWER_GATING;
0802     cmd.enable_disp_power_gating.header.payload_bytes =
0803         sizeof(cmd.enable_disp_power_gating) -
0804         sizeof(cmd.enable_disp_power_gating.header);
0805     cmd.enable_disp_power_gating.power_gating.pwr = *pwr;
0806 
0807     dc_dmub_srv_cmd_queue(dmcub, &cmd);
0808     dc_dmub_srv_cmd_execute(dmcub);
0809     dc_dmub_srv_wait_idle(dmcub);
0810 }
0811 
0812 static enum bp_result enable_disp_power_gating_v2_1(
0813     struct bios_parser *bp,
0814     enum controller_id crtc_id,
0815     enum bp_pipe_control_action action)
0816 {
0817     enum bp_result result = BP_RESULT_FAILURE;
0818 
0819 
0820     struct enable_disp_power_gating_ps_allocation ps = { { 0 } };
0821     uint8_t atom_crtc_id;
0822 
0823     if (bp->cmd_helper->controller_id_to_atom(crtc_id, &atom_crtc_id))
0824         ps.param.disp_pipe_id = atom_crtc_id;
0825     else
0826         return BP_RESULT_BADINPUT;
0827 
0828     ps.param.enable =
0829         bp->cmd_helper->disp_power_gating_action_to_atom(action);
0830 
0831     if (bp->base.ctx->dc->ctx->dmub_srv &&
0832         bp->base.ctx->dc->debug.dmub_command_table) {
0833         enable_disp_power_gating_dmcub(bp->base.ctx->dmub_srv,
0834                            &ps.param);
0835         return BP_RESULT_OK;
0836     }
0837 
0838     if (EXEC_BIOS_CMD_TABLE(enabledisppowergating, ps.param))
0839         result = BP_RESULT_OK;
0840 
0841     return result;
0842 }
0843 
0844 static enum bp_result enable_disp_power_gating_fallback(
0845     struct bios_parser *bp,
0846     enum controller_id crtc_id,
0847     enum bp_pipe_control_action action)
0848 {
0849     if (bp->base.ctx->dc->ctx->dmub_srv &&
0850         bp->base.ctx->dc->debug.dmub_command_table) {
0851         return enable_disp_power_gating_v2_1(bp, crtc_id, action);
0852     }
0853 
0854     return BP_RESULT_FAILURE;
0855 }
0856 
0857 /******************************************************************************
0858 *******************************************************************************
0859  **
0860  **                  SET DCE CLOCK
0861  **
0862 *******************************************************************************
0863 *******************************************************************************/
0864 
0865 static enum bp_result set_dce_clock_v2_1(
0866     struct bios_parser *bp,
0867     struct bp_set_dce_clock_parameters *bp_params);
0868 
0869 static void init_set_dce_clock(struct bios_parser *bp)
0870 {
0871     switch (BIOS_CMD_TABLE_PARA_REVISION(setdceclock)) {
0872     case 1:
0873         bp->cmd_tbl.set_dce_clock = set_dce_clock_v2_1;
0874         break;
0875     default:
0876         dm_output_to_console("Don't have set_dce_clock for v%d\n",
0877              BIOS_CMD_TABLE_PARA_REVISION(setdceclock));
0878         bp->cmd_tbl.set_dce_clock = NULL;
0879         break;
0880     }
0881 }
0882 
0883 static enum bp_result set_dce_clock_v2_1(
0884     struct bios_parser *bp,
0885     struct bp_set_dce_clock_parameters *bp_params)
0886 {
0887     enum bp_result result = BP_RESULT_FAILURE;
0888 
0889     struct set_dce_clock_ps_allocation_v2_1 params;
0890     uint32_t atom_pll_id;
0891     uint32_t atom_clock_type;
0892     const struct command_table_helper *cmd = bp->cmd_helper;
0893 
0894     memset(&params, 0, sizeof(params));
0895 
0896     if (!cmd->clock_source_id_to_atom(bp_params->pll_id, &atom_pll_id) ||
0897             !cmd->dc_clock_type_to_atom(bp_params->clock_type,
0898                     &atom_clock_type))
0899         return BP_RESULT_BADINPUT;
0900 
0901     params.param.dceclksrc  = atom_pll_id;
0902     params.param.dceclktype = atom_clock_type;
0903 
0904     if (bp_params->clock_type == DCECLOCK_TYPE_DPREFCLK) {
0905         if (bp_params->flags.USE_GENLOCK_AS_SOURCE_FOR_DPREFCLK)
0906             params.param.dceclkflag |=
0907                     DCE_CLOCK_FLAG_PLL_REFCLK_SRC_GENLK;
0908 
0909         if (bp_params->flags.USE_PCIE_AS_SOURCE_FOR_DPREFCLK)
0910             params.param.dceclkflag |=
0911                     DCE_CLOCK_FLAG_PLL_REFCLK_SRC_PCIE;
0912 
0913         if (bp_params->flags.USE_XTALIN_AS_SOURCE_FOR_DPREFCLK)
0914             params.param.dceclkflag |=
0915                     DCE_CLOCK_FLAG_PLL_REFCLK_SRC_XTALIN;
0916 
0917         if (bp_params->flags.USE_GENERICA_AS_SOURCE_FOR_DPREFCLK)
0918             params.param.dceclkflag |=
0919                     DCE_CLOCK_FLAG_PLL_REFCLK_SRC_GENERICA;
0920     } else
0921         /* only program clock frequency if display clock is used;
0922          * VBIOS will program DPREFCLK
0923          * We need to convert from KHz units into 10KHz units
0924          */
0925         params.param.dceclk_10khz = cpu_to_le32(
0926                 bp_params->target_clock_frequency / 10);
0927     DC_LOG_BIOS("%s:target_clock_frequency = %d"\
0928             "clock_type = %d \n", __func__,\
0929             bp_params->target_clock_frequency,\
0930             bp_params->clock_type);
0931 
0932     if (EXEC_BIOS_CMD_TABLE(setdceclock, params)) {
0933         /* Convert from 10KHz units back to KHz */
0934         bp_params->target_clock_frequency = le32_to_cpu(
0935                 params.param.dceclk_10khz) * 10;
0936         result = BP_RESULT_OK;
0937     }
0938 
0939     return result;
0940 }
0941 
0942 
0943 /******************************************************************************
0944  ******************************************************************************
0945  **
0946  **                  GET SMU CLOCK INFO
0947  **
0948  ******************************************************************************
0949  *****************************************************************************/
0950 
0951 static unsigned int get_smu_clock_info_v3_1(struct bios_parser *bp, uint8_t id);
0952 
0953 static void init_get_smu_clock_info(struct bios_parser *bp)
0954 {
0955     /* TODO add switch for table vrsion */
0956     bp->cmd_tbl.get_smu_clock_info = get_smu_clock_info_v3_1;
0957 
0958 }
0959 
0960 static unsigned int get_smu_clock_info_v3_1(struct bios_parser *bp, uint8_t id)
0961 {
0962     struct atom_get_smu_clock_info_parameters_v3_1 smu_input = {0};
0963     struct atom_get_smu_clock_info_output_parameters_v3_1 smu_output;
0964 
0965     smu_input.command = GET_SMU_CLOCK_INFO_V3_1_GET_PLLVCO_FREQ;
0966     smu_input.syspll_id = id;
0967 
0968     /* Get Specific Clock */
0969     if (EXEC_BIOS_CMD_TABLE(getsmuclockinfo, smu_input)) {
0970         memmove(&smu_output, &smu_input, sizeof(
0971             struct atom_get_smu_clock_info_parameters_v3_1));
0972         return smu_output.atom_smu_outputclkfreq.syspllvcofreq_10khz;
0973     }
0974 
0975     return 0;
0976 }
0977 
0978 /******************************************************************************
0979  ******************************************************************************
0980  **
0981  **                  LVTMA CONTROL
0982  **
0983  ******************************************************************************
0984  *****************************************************************************/
0985 
0986 static enum bp_result enable_lvtma_control(
0987     struct bios_parser *bp,
0988     uint8_t uc_pwr_on,
0989     uint8_t panel_instance);
0990 
0991 static void init_enable_lvtma_control(struct bios_parser *bp)
0992 {
0993     /* TODO add switch for table vrsion */
0994     bp->cmd_tbl.enable_lvtma_control = enable_lvtma_control;
0995 
0996 }
0997 
0998 static void enable_lvtma_control_dmcub(
0999     struct dc_dmub_srv *dmcub,
1000     uint8_t uc_pwr_on,
1001     uint8_t panel_instance)
1002 {
1003 
1004     union dmub_rb_cmd cmd;
1005 
1006     memset(&cmd, 0, sizeof(cmd));
1007 
1008     cmd.lvtma_control.header.type = DMUB_CMD__VBIOS;
1009     cmd.lvtma_control.header.sub_type =
1010             DMUB_CMD__VBIOS_LVTMA_CONTROL;
1011     cmd.lvtma_control.data.uc_pwr_action =
1012             uc_pwr_on;
1013     cmd.lvtma_control.data.panel_inst =
1014             panel_instance;
1015     dc_dmub_srv_cmd_queue(dmcub, &cmd);
1016     dc_dmub_srv_cmd_execute(dmcub);
1017     dc_dmub_srv_wait_idle(dmcub);
1018 
1019 }
1020 
1021 static enum bp_result enable_lvtma_control(
1022     struct bios_parser *bp,
1023     uint8_t uc_pwr_on,
1024     uint8_t panel_instance)
1025 {
1026     enum bp_result result = BP_RESULT_FAILURE;
1027 
1028     if (bp->base.ctx->dc->ctx->dmub_srv &&
1029         bp->base.ctx->dc->debug.dmub_command_table) {
1030         enable_lvtma_control_dmcub(bp->base.ctx->dmub_srv,
1031                 uc_pwr_on,
1032                 panel_instance);
1033         return BP_RESULT_OK;
1034     }
1035     return result;
1036 }
1037 
1038 void dal_firmware_parser_init_cmd_tbl(struct bios_parser *bp)
1039 {
1040     init_dig_encoder_control(bp);
1041     init_transmitter_control(bp);
1042     init_set_pixel_clock(bp);
1043 
1044     init_set_crtc_timing(bp);
1045 
1046     init_enable_crtc(bp);
1047 
1048     init_external_encoder_control(bp);
1049     init_enable_disp_power_gating(bp);
1050     init_set_dce_clock(bp);
1051     init_get_smu_clock_info(bp);
1052 
1053     init_enable_lvtma_control(bp);
1054 }