Commit a8bf7164 authored by Krunoslav Kovac's avatar Krunoslav Kovac Committed by Alex Deucher

drm/amd/display: Internal refactoring to abstract color caps

[Why&How]
modules/color calculates various colour operations which are translated
to abstracted HW. DCE 5-12 had almost no important changes, but
starting with DCN1, every new generation comes with fairly major
differences in color pipeline.
We would hack it with some DCN checks, but a better approach is to
abstract color pipe capabilities so modules/DM can decide mapping to
HW block based on logical capabilities,
Signed-off-by: default avatarKrunoslav Kovac <Krunoslav.Kovac@amd.com>
Reviewed-by: default avatarAric Cyr <Aric.Cyr@amd.com>
Acked-by: default avatarAnthony Koo <Anthony.Koo@amd.com>
Acked-by: default avatarAurabindo Pillai <aurabindo.pillai@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 4b0e95d1
...@@ -239,7 +239,8 @@ static int __set_output_tf(struct dc_transfer_func *func, ...@@ -239,7 +239,8 @@ static int __set_output_tf(struct dc_transfer_func *func,
* instead to simulate this. * instead to simulate this.
*/ */
gamma->type = GAMMA_CUSTOM; gamma->type = GAMMA_CUSTOM;
res = mod_color_calculate_degamma_params(func, gamma, true); res = mod_color_calculate_degamma_params(NULL, func,
gamma, true);
} else { } else {
/* /*
* Assume sRGB. The actual mapping will depend on whether the * Assume sRGB. The actual mapping will depend on whether the
...@@ -271,7 +272,7 @@ static int __set_input_tf(struct dc_transfer_func *func, ...@@ -271,7 +272,7 @@ static int __set_input_tf(struct dc_transfer_func *func,
__drm_lut_to_dc_gamma(lut, gamma, false); __drm_lut_to_dc_gamma(lut, gamma, false);
res = mod_color_calculate_degamma_params(func, gamma, true); res = mod_color_calculate_degamma_params(NULL, func, gamma, true);
dc_gamma_release(&gamma); dc_gamma_release(&gamma);
return res ? 0 : -ENOMEM; return res ? 0 : -ENOMEM;
...@@ -485,7 +486,7 @@ int amdgpu_dm_update_plane_color_mgmt(struct dm_crtc_state *crtc, ...@@ -485,7 +486,7 @@ int amdgpu_dm_update_plane_color_mgmt(struct dm_crtc_state *crtc,
dc_plane_state->in_transfer_func->tf = tf; dc_plane_state->in_transfer_func->tf = tf;
if (tf != TRANSFER_FUNCTION_SRGB && if (tf != TRANSFER_FUNCTION_SRGB &&
!mod_color_calculate_degamma_params( !mod_color_calculate_degamma_params(NULL,
dc_plane_state->in_transfer_func, NULL, false)) dc_plane_state->in_transfer_func, NULL, false))
return -ENOMEM; return -ENOMEM;
} else { } else {
......
...@@ -98,6 +98,49 @@ struct dc_plane_cap { ...@@ -98,6 +98,49 @@ struct dc_plane_cap {
} max_downscale_factor; } max_downscale_factor;
}; };
// Color management caps (DPP and MPC)
struct rom_curve_caps {
uint16_t srgb : 1;
uint16_t bt2020 : 1;
uint16_t gamma2_2 : 1;
uint16_t pq : 1;
uint16_t hlg : 1;
};
struct dpp_color_caps {
uint16_t dcn_arch : 1; // all DCE generations treated the same
// input lut is different than most LUTs, just plain 256-entry lookup
uint16_t input_lut_shared : 1; // shared with DGAM
uint16_t icsc : 1;
uint16_t dgam_ram : 1;
uint16_t post_csc : 1; // before gamut remap
uint16_t gamma_corr : 1;
// hdr_mult and gamut remap always available in DPP (in that order)
// 3d lut implies shaper LUT,
// it may be shared with MPC - check MPC:shared_3d_lut flag
uint16_t hw_3d_lut : 1;
uint16_t ogam_ram : 1; // blnd gam
uint16_t ocsc : 1;
struct rom_curve_caps dgam_rom_caps;
struct rom_curve_caps ogam_rom_caps;
};
struct mpc_color_caps {
uint16_t gamut_remap : 1;
uint16_t ogam_ram : 1;
uint16_t ocsc : 1;
uint16_t num_3dluts : 3; //3d lut always assumes a preceding shaper LUT
uint16_t shared_3d_lut:1; //can be in either DPP or MPC, but single instance
struct rom_curve_caps ogam_rom_caps;
};
struct dc_color_caps {
struct dpp_color_caps dpp;
struct mpc_color_caps mpc;
};
struct dc_caps { struct dc_caps {
uint32_t max_streams; uint32_t max_streams;
uint32_t max_links; uint32_t max_links;
...@@ -120,9 +163,9 @@ struct dc_caps { ...@@ -120,9 +163,9 @@ struct dc_caps {
bool psp_setup_panel_mode; bool psp_setup_panel_mode;
bool extended_aux_timeout_support; bool extended_aux_timeout_support;
bool dmcub_support; bool dmcub_support;
bool hw_3d_lut;
enum dp_protocol_version max_dp_protocol_version; enum dp_protocol_version max_dp_protocol_version;
struct dc_plane_cap planes[MAX_PLANES]; struct dc_plane_cap planes[MAX_PLANES];
struct dc_color_caps color;
}; };
struct dc_bug_wa { struct dc_bug_wa {
......
...@@ -1384,6 +1384,40 @@ static bool dcn10_resource_construct( ...@@ -1384,6 +1384,40 @@ static bool dcn10_resource_construct(
/* Raven DP PHY HBR2 eye diagram pattern is not stable. Use TP4 */ /* Raven DP PHY HBR2 eye diagram pattern is not stable. Use TP4 */
dc->caps.force_dp_tps4_for_cp2520 = true; dc->caps.force_dp_tps4_for_cp2520 = true;
/* Color pipeline capabilities */
dc->caps.color.dpp.dcn_arch = 1;
dc->caps.color.dpp.input_lut_shared = 1;
dc->caps.color.dpp.icsc = 1;
dc->caps.color.dpp.dgam_ram = 1;
dc->caps.color.dpp.dgam_rom_caps.srgb = 1;
dc->caps.color.dpp.dgam_rom_caps.bt2020 = 1;
dc->caps.color.dpp.dgam_rom_caps.gamma2_2 = 0;
dc->caps.color.dpp.dgam_rom_caps.pq = 0;
dc->caps.color.dpp.dgam_rom_caps.hlg = 0;
dc->caps.color.dpp.post_csc = 0;
dc->caps.color.dpp.gamma_corr = 0;
dc->caps.color.dpp.hw_3d_lut = 0;
dc->caps.color.dpp.ogam_ram = 1; // RGAM on DCN1
dc->caps.color.dpp.ogam_rom_caps.srgb = 1;
dc->caps.color.dpp.ogam_rom_caps.bt2020 = 1;
dc->caps.color.dpp.ogam_rom_caps.gamma2_2 = 0;
dc->caps.color.dpp.ogam_rom_caps.pq = 0;
dc->caps.color.dpp.ogam_rom_caps.hlg = 0;
dc->caps.color.dpp.ocsc = 1;
/* no post-blend color operations */
dc->caps.color.mpc.gamut_remap = 0;
dc->caps.color.mpc.num_3dluts = 0;
dc->caps.color.mpc.shared_3d_lut = 0;
dc->caps.color.mpc.ogam_ram = 0;
dc->caps.color.mpc.ogam_rom_caps.srgb = 0;
dc->caps.color.mpc.ogam_rom_caps.bt2020 = 0;
dc->caps.color.mpc.ogam_rom_caps.gamma2_2 = 0;
dc->caps.color.mpc.ogam_rom_caps.pq = 0;
dc->caps.color.mpc.ogam_rom_caps.hlg = 0;
dc->caps.color.mpc.ocsc = 0;
if (dc->ctx->dce_environment == DCE_ENV_PRODUCTION_DRV) if (dc->ctx->dce_environment == DCE_ENV_PRODUCTION_DRV)
dc->debug = debug_defaults_drv; dc->debug = debug_defaults_drv;
else else
......
...@@ -3709,9 +3709,42 @@ static bool dcn20_resource_construct( ...@@ -3709,9 +3709,42 @@ static bool dcn20_resource_construct(
dc->caps.max_slave_planes = 1; dc->caps.max_slave_planes = 1;
dc->caps.post_blend_color_processing = true; dc->caps.post_blend_color_processing = true;
dc->caps.force_dp_tps4_for_cp2520 = true; dc->caps.force_dp_tps4_for_cp2520 = true;
dc->caps.hw_3d_lut = true;
dc->caps.extended_aux_timeout_support = true; dc->caps.extended_aux_timeout_support = true;
/* Color pipeline capabilities */
dc->caps.color.dpp.dcn_arch = 1;
dc->caps.color.dpp.input_lut_shared = 0;
dc->caps.color.dpp.icsc = 1;
dc->caps.color.dpp.dgam_ram = 1;
dc->caps.color.dpp.dgam_rom_caps.srgb = 1;
dc->caps.color.dpp.dgam_rom_caps.bt2020 = 1;
dc->caps.color.dpp.dgam_rom_caps.gamma2_2 = 0;
dc->caps.color.dpp.dgam_rom_caps.pq = 0;
dc->caps.color.dpp.dgam_rom_caps.hlg = 0;
dc->caps.color.dpp.post_csc = 0;
dc->caps.color.dpp.gamma_corr = 0;
dc->caps.color.dpp.hw_3d_lut = 1;
dc->caps.color.dpp.ogam_ram = 1;
// no OGAM ROM on DCN2, only MPC ROM
dc->caps.color.dpp.ogam_rom_caps.srgb = 0;
dc->caps.color.dpp.ogam_rom_caps.bt2020 = 0;
dc->caps.color.dpp.ogam_rom_caps.gamma2_2 = 0;
dc->caps.color.dpp.ogam_rom_caps.pq = 0;
dc->caps.color.dpp.ogam_rom_caps.hlg = 0;
dc->caps.color.dpp.ocsc = 0;
dc->caps.color.mpc.gamut_remap = 0;
dc->caps.color.mpc.num_3dluts = 0;
dc->caps.color.mpc.shared_3d_lut = 0;
dc->caps.color.mpc.ogam_ram = 1;
dc->caps.color.mpc.ogam_rom_caps.srgb = 0;
dc->caps.color.mpc.ogam_rom_caps.bt2020 = 0;
dc->caps.color.mpc.ogam_rom_caps.gamma2_2 = 0;
dc->caps.color.mpc.ogam_rom_caps.pq = 0;
dc->caps.color.mpc.ogam_rom_caps.hlg = 0;
dc->caps.color.mpc.ocsc = 1;
if (dc->ctx->dce_environment == DCE_ENV_PRODUCTION_DRV) { if (dc->ctx->dce_environment == DCE_ENV_PRODUCTION_DRV) {
dc->debug = debug_defaults_drv; dc->debug = debug_defaults_drv;
} else if (dc->ctx->dce_environment == DCE_ENV_FPGA_MAXIMUS) { } else if (dc->ctx->dce_environment == DCE_ENV_FPGA_MAXIMUS) {
......
...@@ -1798,7 +1798,6 @@ static bool dcn21_resource_construct( ...@@ -1798,7 +1798,6 @@ static bool dcn21_resource_construct(
dc->caps.i2c_speed_in_khz = 100; dc->caps.i2c_speed_in_khz = 100;
dc->caps.max_cursor_size = 256; dc->caps.max_cursor_size = 256;
dc->caps.dmdata_alloc_size = 2048; dc->caps.dmdata_alloc_size = 2048;
dc->caps.hw_3d_lut = true;
dc->caps.max_slave_planes = 1; dc->caps.max_slave_planes = 1;
dc->caps.post_blend_color_processing = true; dc->caps.post_blend_color_processing = true;
...@@ -1807,6 +1806,40 @@ static bool dcn21_resource_construct( ...@@ -1807,6 +1806,40 @@ static bool dcn21_resource_construct(
dc->caps.dmcub_support = true; dc->caps.dmcub_support = true;
dc->caps.is_apu = true; dc->caps.is_apu = true;
/* Color pipeline capabilities */
dc->caps.color.dpp.dcn_arch = 1;
dc->caps.color.dpp.input_lut_shared = 0;
dc->caps.color.dpp.icsc = 1;
dc->caps.color.dpp.dgam_ram = 1;
dc->caps.color.dpp.dgam_rom_caps.srgb = 1;
dc->caps.color.dpp.dgam_rom_caps.bt2020 = 1;
dc->caps.color.dpp.dgam_rom_caps.gamma2_2 = 0;
dc->caps.color.dpp.dgam_rom_caps.pq = 0;
dc->caps.color.dpp.dgam_rom_caps.hlg = 0;
dc->caps.color.dpp.post_csc = 0;
dc->caps.color.dpp.gamma_corr = 0;
dc->caps.color.dpp.hw_3d_lut = 1;
dc->caps.color.dpp.ogam_ram = 1;
// no OGAM ROM on DCN2
dc->caps.color.dpp.ogam_rom_caps.srgb = 0;
dc->caps.color.dpp.ogam_rom_caps.bt2020 = 0;
dc->caps.color.dpp.ogam_rom_caps.gamma2_2 = 0;
dc->caps.color.dpp.ogam_rom_caps.pq = 0;
dc->caps.color.dpp.ogam_rom_caps.hlg = 0;
dc->caps.color.dpp.ocsc = 0;
dc->caps.color.mpc.gamut_remap = 0;
dc->caps.color.mpc.num_3dluts = 0;
dc->caps.color.mpc.shared_3d_lut = 0;
dc->caps.color.mpc.ogam_ram = 1;
dc->caps.color.mpc.ogam_rom_caps.srgb = 0;
dc->caps.color.mpc.ogam_rom_caps.bt2020 = 0;
dc->caps.color.mpc.ogam_rom_caps.gamma2_2 = 0;
dc->caps.color.mpc.ogam_rom_caps.pq = 0;
dc->caps.color.mpc.ogam_rom_caps.hlg = 0;
dc->caps.color.mpc.ocsc = 1;
if (dc->ctx->dce_environment == DCE_ENV_PRODUCTION_DRV) if (dc->ctx->dce_environment == DCE_ENV_PRODUCTION_DRV)
dc->debug = debug_defaults_drv; dc->debug = debug_defaults_drv;
else if (dc->ctx->dce_environment == DCE_ENV_FPGA_MAXIMUS) { else if (dc->ctx->dce_environment == DCE_ENV_FPGA_MAXIMUS) {
......
...@@ -1782,7 +1782,8 @@ bool calculate_user_regamma_ramp(struct dc_transfer_func *output_tf, ...@@ -1782,7 +1782,8 @@ bool calculate_user_regamma_ramp(struct dc_transfer_func *output_tf,
return ret; return ret;
} }
bool mod_color_calculate_degamma_params(struct dc_transfer_func *input_tf, bool mod_color_calculate_degamma_params(struct dc_color_caps *dc_caps,
struct dc_transfer_func *input_tf,
const struct dc_gamma *ramp, bool mapUserRamp) const struct dc_gamma *ramp, bool mapUserRamp)
{ {
struct dc_transfer_func_distributed_points *tf_pts = &input_tf->tf_pts; struct dc_transfer_func_distributed_points *tf_pts = &input_tf->tf_pts;
...@@ -1801,12 +1802,30 @@ bool mod_color_calculate_degamma_params(struct dc_transfer_func *input_tf, ...@@ -1801,12 +1802,30 @@ bool mod_color_calculate_degamma_params(struct dc_transfer_func *input_tf,
/* we can use hardcoded curve for plain SRGB TF /* we can use hardcoded curve for plain SRGB TF
* If linear, it's bypass if on user ramp * If linear, it's bypass if on user ramp
*/ */
if (input_tf->type == TF_TYPE_PREDEFINED && if (input_tf->type == TF_TYPE_PREDEFINED) {
(input_tf->tf == TRANSFER_FUNCTION_SRGB || if ((input_tf->tf == TRANSFER_FUNCTION_SRGB ||
input_tf->tf == TRANSFER_FUNCTION_LINEAR) && input_tf->tf == TRANSFER_FUNCTION_LINEAR) &&
!mapUserRamp) !mapUserRamp)
return true; return true;
if (dc_caps != NULL &&
dc_caps->dpp.dcn_arch == 1) {
if (input_tf->tf == TRANSFER_FUNCTION_PQ &&
dc_caps->dpp.dgam_rom_caps.pq == 1)
return true;
if (input_tf->tf == TRANSFER_FUNCTION_GAMMA22 &&
dc_caps->dpp.dgam_rom_caps.gamma2_2 == 1)
return true;
// HLG OOTF not accounted for
if (input_tf->tf == TRANSFER_FUNCTION_HLG &&
dc_caps->dpp.dgam_rom_caps.hlg == 1)
return true;
}
}
input_tf->type = TF_TYPE_DISTRIBUTED_POINTS; input_tf->type = TF_TYPE_DISTRIBUTED_POINTS;
if (mapUserRamp && ramp && ramp->type == GAMMA_RGB_256) { if (mapUserRamp && ramp && ramp->type == GAMMA_RGB_256) {
......
...@@ -30,6 +30,7 @@ struct dc_transfer_func; ...@@ -30,6 +30,7 @@ struct dc_transfer_func;
struct dc_gamma; struct dc_gamma;
struct dc_transfer_func_distributed_points; struct dc_transfer_func_distributed_points;
struct dc_rgb_fixed; struct dc_rgb_fixed;
struct dc_color_caps;
enum dc_transfer_func_predefined; enum dc_transfer_func_predefined;
/* For SetRegamma ADL interface support /* For SetRegamma ADL interface support
...@@ -100,7 +101,8 @@ bool mod_color_calculate_regamma_params(struct dc_transfer_func *output_tf, ...@@ -100,7 +101,8 @@ bool mod_color_calculate_regamma_params(struct dc_transfer_func *output_tf,
const struct dc_gamma *ramp, bool mapUserRamp, bool canRomBeUsed, const struct dc_gamma *ramp, bool mapUserRamp, bool canRomBeUsed,
const struct freesync_hdr_tf_params *fs_params); const struct freesync_hdr_tf_params *fs_params);
bool mod_color_calculate_degamma_params(struct dc_transfer_func *output_tf, bool mod_color_calculate_degamma_params(struct dc_color_caps *dc_caps,
struct dc_transfer_func *output_tf,
const struct dc_gamma *ramp, bool mapUserRamp); const struct dc_gamma *ramp, bool mapUserRamp);
bool mod_color_calculate_degamma_curve(enum dc_transfer_func_predefined trans, bool mod_color_calculate_degamma_curve(enum dc_transfer_func_predefined trans,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment