aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/amd/display/dc/bios/command_table2.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/amd/display/dc/bios/command_table2.c')
-rw-r--r--drivers/gpu/drm/amd/display/dc/bios/command_table2.c159
1 files changed, 155 insertions, 4 deletions
diff --git a/drivers/gpu/drm/amd/display/dc/bios/command_table2.c b/drivers/gpu/drm/amd/display/dc/bios/command_table2.c
index bb2e8105e6ab..c4ba6e84db65 100644
--- a/drivers/gpu/drm/amd/display/dc/bios/command_table2.c
+++ b/drivers/gpu/drm/amd/display/dc/bios/command_table2.c
@@ -37,6 +37,8 @@
#include "bios_parser_types_internal2.h"
#include "amdgpu.h"
+#include "dc_dmub_srv.h"
+#include "dc.h"
#define DC_LOGGER \
bp->base.ctx->logger
@@ -87,6 +89,10 @@ static enum bp_result encoder_control_digx_v1_5(
struct bios_parser *bp,
struct bp_encoder_control *cntl);
+static enum bp_result encoder_control_fallback(
+ struct bios_parser *bp,
+ struct bp_encoder_control *cntl);
+
static void init_dig_encoder_control(struct bios_parser *bp)
{
uint32_t version =
@@ -98,11 +104,26 @@ static void init_dig_encoder_control(struct bios_parser *bp)
break;
default:
dm_output_to_console("Don't have dig_encoder_control for v%d\n", version);
- bp->cmd_tbl.dig_encoder_control = NULL;
+ bp->cmd_tbl.dig_encoder_control = encoder_control_fallback;
break;
}
}
+static void encoder_control_dmcub(
+ struct dc_dmub_srv *dmcub,
+ struct dig_encoder_stream_setup_parameters_v1_5 *dig)
+{
+ struct dmub_rb_cmd_digx_encoder_control encoder_control = { 0 };
+
+ encoder_control.header.type = DMUB_CMD__VBIOS;
+ encoder_control.header.sub_type = DMUB_CMD__VBIOS_DIGX_ENCODER_CONTROL;
+ encoder_control.encoder_control.dig.stream_param = *dig;
+
+ dc_dmub_srv_cmd_queue(dmcub, &encoder_control.header);
+ dc_dmub_srv_cmd_execute(dmcub);
+ dc_dmub_srv_wait_idle(dmcub);
+}
+
static enum bp_result encoder_control_digx_v1_5(
struct bios_parser *bp,
struct bp_encoder_control *cntl)
@@ -155,12 +176,30 @@ static enum bp_result encoder_control_digx_v1_5(
break;
}
+ if (bp->base.ctx->dc->ctx->dmub_srv &&
+ bp->base.ctx->dc->debug.dmub_command_table) {
+ encoder_control_dmcub(bp->base.ctx->dmub_srv, &params);
+ return BP_RESULT_OK;
+ }
+
if (EXEC_BIOS_CMD_TABLE(digxencodercontrol, params))
result = BP_RESULT_OK;
return result;
}
+static enum bp_result encoder_control_fallback(
+ struct bios_parser *bp,
+ struct bp_encoder_control *cntl)
+{
+ if (bp->base.ctx->dc->ctx->dmub_srv &&
+ bp->base.ctx->dc->debug.dmub_command_table) {
+ return encoder_control_digx_v1_5(bp, cntl);
+ }
+
+ return BP_RESULT_FAILURE;
+}
+
/*****************************************************************************
******************************************************************************
**
@@ -173,6 +212,10 @@ static enum bp_result transmitter_control_v1_6(
struct bios_parser *bp,
struct bp_transmitter_control *cntl);
+static enum bp_result transmitter_control_fallback(
+ struct bios_parser *bp,
+ struct bp_transmitter_control *cntl);
+
static void init_transmitter_control(struct bios_parser *bp)
{
uint8_t frev;
@@ -186,11 +229,27 @@ static void init_transmitter_control(struct bios_parser *bp)
break;
default:
dm_output_to_console("Don't have transmitter_control for v%d\n", crev);
- bp->cmd_tbl.transmitter_control = NULL;
+ bp->cmd_tbl.transmitter_control = transmitter_control_fallback;
break;
}
}
+static void transmitter_control_dmcub(
+ struct dc_dmub_srv *dmcub,
+ struct dig_transmitter_control_parameters_v1_6 *dig)
+{
+ struct dmub_rb_cmd_dig1_transmitter_control transmitter_control;
+
+ transmitter_control.header.type = DMUB_CMD__VBIOS;
+ transmitter_control.header.sub_type =
+ DMUB_CMD__VBIOS_DIG1_TRANSMITTER_CONTROL;
+ transmitter_control.transmitter_control.dig = *dig;
+
+ dc_dmub_srv_cmd_queue(dmcub, &transmitter_control.header);
+ dc_dmub_srv_cmd_execute(dmcub);
+ dc_dmub_srv_wait_idle(dmcub);
+}
+
static enum bp_result transmitter_control_v1_6(
struct bios_parser *bp,
struct bp_transmitter_control *cntl)
@@ -222,6 +281,11 @@ static enum bp_result transmitter_control_v1_6(
__func__, ps.param.symclk_10khz);
}
+ if (bp->base.ctx->dc->ctx->dmub_srv &&
+ bp->base.ctx->dc->debug.dmub_command_table) {
+ transmitter_control_dmcub(bp->base.ctx->dmub_srv, &ps.param);
+ return BP_RESULT_OK;
+ }
/*color_depth not used any more, driver has deep color factor in the Phyclk*/
if (EXEC_BIOS_CMD_TABLE(dig1transmittercontrol, ps))
@@ -229,6 +293,18 @@ static enum bp_result transmitter_control_v1_6(
return result;
}
+static enum bp_result transmitter_control_fallback(
+ struct bios_parser *bp,
+ struct bp_transmitter_control *cntl)
+{
+ if (bp->base.ctx->dc->ctx->dmub_srv &&
+ bp->base.ctx->dc->debug.dmub_command_table) {
+ return transmitter_control_v1_6(bp, cntl);
+ }
+
+ return BP_RESULT_FAILURE;
+}
+
/******************************************************************************
******************************************************************************
**
@@ -241,6 +317,10 @@ static enum bp_result set_pixel_clock_v7(
struct bios_parser *bp,
struct bp_pixel_clock_parameters *bp_params);
+static enum bp_result set_pixel_clock_fallback(
+ struct bios_parser *bp,
+ struct bp_pixel_clock_parameters *bp_params);
+
static void init_set_pixel_clock(struct bios_parser *bp)
{
switch (BIOS_CMD_TABLE_PARA_REVISION(setpixelclock)) {
@@ -250,12 +330,25 @@ static void init_set_pixel_clock(struct bios_parser *bp)
default:
dm_output_to_console("Don't have set_pixel_clock for v%d\n",
BIOS_CMD_TABLE_PARA_REVISION(setpixelclock));
- bp->cmd_tbl.set_pixel_clock = NULL;
+ bp->cmd_tbl.set_pixel_clock = set_pixel_clock_fallback;
break;
}
}
+static void set_pixel_clock_dmcub(
+ struct dc_dmub_srv *dmcub,
+ struct set_pixel_clock_parameter_v1_7 *clk)
+{
+ struct dmub_rb_cmd_set_pixel_clock pixel_clock = { 0 };
+ pixel_clock.header.type = DMUB_CMD__VBIOS;
+ pixel_clock.header.sub_type = DMUB_CMD__VBIOS_SET_PIXEL_CLOCK;
+ pixel_clock.pixel_clock.clk = *clk;
+
+ dc_dmub_srv_cmd_queue(dmcub, &pixel_clock.header);
+ dc_dmub_srv_cmd_execute(dmcub);
+ dc_dmub_srv_wait_idle(dmcub);
+}
static enum bp_result set_pixel_clock_v7(
struct bios_parser *bp,
@@ -331,12 +424,30 @@ static enum bp_result set_pixel_clock_v7(
if (bp_params->signal_type == SIGNAL_TYPE_DVI_DUAL_LINK)
clk.miscinfo |= PIXEL_CLOCK_V7_MISC_DVI_DUALLINK_EN;
+ if (bp->base.ctx->dc->ctx->dmub_srv &&
+ bp->base.ctx->dc->debug.dmub_command_table) {
+ set_pixel_clock_dmcub(bp->base.ctx->dmub_srv, &clk);
+ return BP_RESULT_OK;
+ }
+
if (EXEC_BIOS_CMD_TABLE(setpixelclock, clk))
result = BP_RESULT_OK;
}
return result;
}
+static enum bp_result set_pixel_clock_fallback(
+ struct bios_parser *bp,
+ struct bp_pixel_clock_parameters *bp_params)
+{
+ if (bp->base.ctx->dc->ctx->dmub_srv &&
+ bp->base.ctx->dc->debug.dmub_command_table) {
+ return set_pixel_clock_v7(bp, bp_params);
+ }
+
+ return BP_RESULT_FAILURE;
+}
+
/******************************************************************************
******************************************************************************
**
@@ -569,6 +680,11 @@ static enum bp_result enable_disp_power_gating_v2_1(
enum controller_id crtc_id,
enum bp_pipe_control_action action);
+static enum bp_result enable_disp_power_gating_fallback(
+ struct bios_parser *bp,
+ enum controller_id crtc_id,
+ enum bp_pipe_control_action action);
+
static void init_enable_disp_power_gating(
struct bios_parser *bp)
{
@@ -580,11 +696,26 @@ static void init_enable_disp_power_gating(
default:
dm_output_to_console("Don't enable_disp_power_gating enable_crtc for v%d\n",
BIOS_CMD_TABLE_PARA_REVISION(enabledisppowergating));
- bp->cmd_tbl.enable_disp_power_gating = NULL;
+ bp->cmd_tbl.enable_disp_power_gating = enable_disp_power_gating_fallback;
break;
}
}
+static void enable_disp_power_gating_dmcub(
+ struct dc_dmub_srv *dmcub,
+ struct enable_disp_power_gating_parameters_v2_1 *pwr)
+{
+ struct dmub_rb_cmd_enable_disp_power_gating power_gating;
+
+ power_gating.header.type = DMUB_CMD__VBIOS;
+ power_gating.header.sub_type = DMUB_CMD__VBIOS_ENABLE_DISP_POWER_GATING;
+ power_gating.power_gating.pwr = *pwr;
+
+ dc_dmub_srv_cmd_queue(dmcub, &power_gating.header);
+ dc_dmub_srv_cmd_execute(dmcub);
+ dc_dmub_srv_wait_idle(dmcub);
+}
+
static enum bp_result enable_disp_power_gating_v2_1(
struct bios_parser *bp,
enum controller_id crtc_id,
@@ -604,12 +735,32 @@ static enum bp_result enable_disp_power_gating_v2_1(
ps.param.enable =
bp->cmd_helper->disp_power_gating_action_to_atom(action);
+ if (bp->base.ctx->dc->ctx->dmub_srv &&
+ bp->base.ctx->dc->debug.dmub_command_table) {
+ enable_disp_power_gating_dmcub(bp->base.ctx->dmub_srv,
+ &ps.param);
+ return BP_RESULT_OK;
+ }
+
if (EXEC_BIOS_CMD_TABLE(enabledisppowergating, ps.param))
result = BP_RESULT_OK;
return result;
}
+static enum bp_result enable_disp_power_gating_fallback(
+ struct bios_parser *bp,
+ enum controller_id crtc_id,
+ enum bp_pipe_control_action action)
+{
+ if (bp->base.ctx->dc->ctx->dmub_srv &&
+ bp->base.ctx->dc->debug.dmub_command_table) {
+ return enable_disp_power_gating_v2_1(bp, crtc_id, action);
+ }
+
+ return BP_RESULT_FAILURE;
+}
+
/******************************************************************************
*******************************************************************************
**