0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
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 *)¶ms) == 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
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, ¶ms);
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
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
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
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
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
0458
0459
0460
0461
0462
0463
0464
0465
0466
0467
0468
0469
0470
0471
0472
0473
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
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
0583 params.h_size = cpu_to_le16((uint16_t)bp_params->h_addressable);
0584
0585 params.h_blanking_time =
0586 cpu_to_le16((uint16_t)(bp_params->h_total -
0587 bp_params->h_addressable));
0588
0589 params.v_size = cpu_to_le16((uint16_t)bp_params->v_addressable);
0590
0591 params.v_blanking_time =
0592 cpu_to_le16((uint16_t)(bp_params->v_total -
0593 bp_params->v_addressable));
0594
0595
0596
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
0603
0604
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
0612
0613
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
0632
0633
0634
0635
0636
0637
0638 {
0639
0640
0641
0642
0643
0644
0645
0646 le16_add_cpu(¶ms.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);
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
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
0717
0718
0719
0720
0721
0722
0723
0724
0725
0726
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
0754 return BP_RESULT_OK;
0755 }
0756
0757
0758
0759
0760
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
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(¶ms, 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
0922
0923
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
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
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
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
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
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
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 }