drm/amd/display: Add DMUB support to DC

DC will use DMUB for command submission and flow control during
initialization.

Register offloading as well as submitting some BIOS commands are part
of the DC internal interface but are guarded behind debug options.

It won't be functional in amdgpu_dm yet since we don't pass the
DMUB service to DC for use.

Signed-off-by: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com>
Reviewed-by: Hersen Wu <hersenxs.wu@amd.com>
Acked-by: Harry Wentland <harry.wentland@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
Nicholas Kazlauskas
2019-10-25 15:03:58 -04:00
committed by Alex Deucher
parent 976e51a7c0
commit 3a1627b073
15 changed files with 640 additions and 1 deletions

View File

@@ -37,6 +37,10 @@
#include "bios_parser_types_internal2.h"
#include "amdgpu.h"
#ifdef CONFIG_DRM_AMD_DC_DMUB
#include "dc_dmub_srv.h"
#include "dc.h"
#endif
#define DC_LOGGER \
bp->base.ctx->logger
@@ -103,6 +107,21 @@ static void init_dig_encoder_control(struct bios_parser *bp)
}
}
#ifdef CONFIG_DRM_AMD_DC_DMUB
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__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);
}
#endif
static enum bp_result encoder_control_digx_v1_5(
struct bios_parser *bp,
struct bp_encoder_control *cntl)
@@ -154,6 +173,13 @@ static enum bp_result encoder_control_digx_v1_5(
default:
break;
}
#ifdef CONFIG_DRM_AMD_DC_DMUB
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;
}
#endif
if (EXEC_BIOS_CMD_TABLE(digxencodercontrol, params))
result = BP_RESULT_OK;
@@ -190,7 +216,21 @@ static void init_transmitter_control(struct bios_parser *bp)
break;
}
}
#ifdef CONFIG_DRM_AMD_DC_DMUB
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__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);
}
#endif
static enum bp_result transmitter_control_v1_6(
struct bios_parser *bp,
struct bp_transmitter_control *cntl)
@@ -223,6 +263,14 @@ static enum bp_result transmitter_control_v1_6(
}
#ifdef CONFIG_DRM_AMD_DC_DMUB
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;
}
#endif
/*color_depth not used any more, driver has deep color factor in the Phyclk*/
if (EXEC_BIOS_CMD_TABLE(dig1transmittercontrol, ps))
result = BP_RESULT_OK;
@@ -255,7 +303,21 @@ static void init_set_pixel_clock(struct bios_parser *bp)
}
}
#ifdef CONFIG_DRM_AMD_DC_DMUB
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__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);
}
#endif
static enum bp_result set_pixel_clock_v7(
struct bios_parser *bp,
@@ -331,6 +393,13 @@ 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;
#ifdef CONFIG_DRM_AMD_DC_DMUB
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;
}
#endif
if (EXEC_BIOS_CMD_TABLE(setpixelclock, clk))
result = BP_RESULT_OK;
}
@@ -584,7 +653,21 @@ static void init_enable_disp_power_gating(
break;
}
}
#ifdef CONFIG_DRM_AMD_DC_DMUB
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__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);
}
#endif
static enum bp_result enable_disp_power_gating_v2_1(
struct bios_parser *bp,
enum controller_id crtc_id,
@@ -604,6 +687,14 @@ static enum bp_result enable_disp_power_gating_v2_1(
ps.param.enable =
bp->cmd_helper->disp_power_gating_action_to_atom(action);
#ifdef CONFIG_DRM_AMD_DC_DMUB
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;
}
#endif
if (EXEC_BIOS_CMD_TABLE(enabledisppowergating, ps.param))
result = BP_RESULT_OK;