From: Krunoslav Kovac <krunoslav.ko...@amd.com>

[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: Krunoslav Kovac <krunoslav.ko...@amd.com>
Reviewed-by: Aric Cyr <aric....@amd.com>
Acked-by: Anthony Koo <anthony....@amd.com>
Acked-by: Aurabindo Pillai <aurabindo.pil...@amd.com>
---
 .../amd/display/amdgpu_dm/amdgpu_dm_color.c   |  7 +--
 drivers/gpu/drm/amd/display/dc/dc.h           | 45 ++++++++++++++++++-
 .../drm/amd/display/dc/dcn10/dcn10_resource.c | 34 ++++++++++++++
 .../drm/amd/display/dc/dcn20/dcn20_resource.c | 35 ++++++++++++++-
 .../drm/amd/display/dc/dcn21/dcn21_resource.c | 35 ++++++++++++++-
 .../amd/display/modules/color/color_gamma.c   | 31 ++++++++++---
 .../amd/display/modules/color/color_gamma.h   |  4 +-
 7 files changed, 178 insertions(+), 13 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
index 838f35668f12..4dfb6b55bb2e 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
@@ -239,7 +239,8 @@ static int __set_output_tf(struct dc_transfer_func *func,
                 * instead to simulate this.
                 */
                gamma->type = GAMMA_CUSTOM;
-               res = mod_color_calculate_degamma_params(func, gamma, true);
+               res = mod_color_calculate_degamma_params(NULL, func,
+                                                       gamma, true);
        } else {
                /*
                 * Assume sRGB. The actual mapping will depend on whether the
@@ -271,7 +272,7 @@ static int __set_input_tf(struct dc_transfer_func *func,
 
        __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);
 
        return res ? 0 : -ENOMEM;
@@ -485,7 +486,7 @@ int amdgpu_dm_update_plane_color_mgmt(struct dm_crtc_state 
*crtc,
                dc_plane_state->in_transfer_func->tf = tf;
 
                if (tf != TRANSFER_FUNCTION_SRGB &&
-                   !mod_color_calculate_degamma_params(
+                   !mod_color_calculate_degamma_params(NULL,
                            dc_plane_state->in_transfer_func, NULL, false))
                        return -ENOMEM;
        } else {
diff --git a/drivers/gpu/drm/amd/display/dc/dc.h 
b/drivers/gpu/drm/amd/display/dc/dc.h
index 99c8e40049e6..b4aeb5d8a818 100644
--- a/drivers/gpu/drm/amd/display/dc/dc.h
+++ b/drivers/gpu/drm/amd/display/dc/dc.h
@@ -98,6 +98,49 @@ struct dc_plane_cap {
        } 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 {
        uint32_t max_streams;
        uint32_t max_links;
@@ -120,9 +163,9 @@ struct dc_caps {
        bool psp_setup_panel_mode;
        bool extended_aux_timeout_support;
        bool dmcub_support;
-       bool hw_3d_lut;
        enum dp_protocol_version max_dp_protocol_version;
        struct dc_plane_cap planes[MAX_PLANES];
+       struct dc_color_caps color;
 };
 
 struct dc_bug_wa {
diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c 
b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c
index 43116749af9f..6d506c37fc71 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c
@@ -1384,6 +1384,40 @@ static bool dcn10_resource_construct(
        /* Raven DP PHY HBR2 eye diagram pattern is not stable. Use TP4 */
        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)
                dc->debug = debug_defaults_drv;
        else
diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c 
b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c
index b7e4d0c2432c..f04d0872a8ed 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c
@@ -3709,9 +3709,42 @@ static bool dcn20_resource_construct(
        dc->caps.max_slave_planes = 1;
        dc->caps.post_blend_color_processing = true;
        dc->caps.force_dp_tps4_for_cp2520 = true;
-       dc->caps.hw_3d_lut = 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) {
                dc->debug = debug_defaults_drv;
        } else if (dc->ctx->dce_environment == DCE_ENV_FPGA_MAXIMUS) {
diff --git a/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_resource.c 
b/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_resource.c
index 802372f09dc7..d771fe1e2c4e 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_resource.c
@@ -1798,7 +1798,6 @@ static bool dcn21_resource_construct(
        dc->caps.i2c_speed_in_khz = 100;
        dc->caps.max_cursor_size = 256;
        dc->caps.dmdata_alloc_size = 2048;
-       dc->caps.hw_3d_lut = true;
 
        dc->caps.max_slave_planes = 1;
        dc->caps.post_blend_color_processing = true;
@@ -1807,6 +1806,40 @@ static bool dcn21_resource_construct(
        dc->caps.dmcub_support = 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)
                dc->debug = debug_defaults_drv;
        else if (dc->ctx->dce_environment == DCE_ENV_FPGA_MAXIMUS) {
diff --git a/drivers/gpu/drm/amd/display/modules/color/color_gamma.c 
b/drivers/gpu/drm/amd/display/modules/color/color_gamma.c
index d47253cdcc4e..9431b48aecb4 100644
--- a/drivers/gpu/drm/amd/display/modules/color/color_gamma.c
+++ b/drivers/gpu/drm/amd/display/modules/color/color_gamma.c
@@ -1782,7 +1782,8 @@ bool calculate_user_regamma_ramp(struct dc_transfer_func 
*output_tf,
        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)
 {
        struct dc_transfer_func_distributed_points *tf_pts = &input_tf->tf_pts;
@@ -1801,11 +1802,29 @@ bool mod_color_calculate_degamma_params(struct 
dc_transfer_func *input_tf,
        /* we can use hardcoded curve for plain SRGB TF
         * If linear, it's bypass if on user ramp
         */
-       if (input_tf->type == TF_TYPE_PREDEFINED &&
-                       (input_tf->tf == TRANSFER_FUNCTION_SRGB ||
-                                       input_tf->tf == 
TRANSFER_FUNCTION_LINEAR) &&
-                                       !mapUserRamp)
-               return true;
+       if (input_tf->type == TF_TYPE_PREDEFINED) {
+               if ((input_tf->tf == TRANSFER_FUNCTION_SRGB ||
+                               input_tf->tf == TRANSFER_FUNCTION_LINEAR) &&
+                               !mapUserRamp)
+                       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;
 
diff --git a/drivers/gpu/drm/amd/display/modules/color/color_gamma.h 
b/drivers/gpu/drm/amd/display/modules/color/color_gamma.h
index 9994817a9a03..7f56226ba77a 100644
--- a/drivers/gpu/drm/amd/display/modules/color/color_gamma.h
+++ b/drivers/gpu/drm/amd/display/modules/color/color_gamma.h
@@ -30,6 +30,7 @@ struct dc_transfer_func;
 struct dc_gamma;
 struct dc_transfer_func_distributed_points;
 struct dc_rgb_fixed;
+struct dc_color_caps;
 enum dc_transfer_func_predefined;
 
 /* For SetRegamma ADL interface support
@@ -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 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);
 
 bool mod_color_calculate_degamma_curve(enum dc_transfer_func_predefined trans,
-- 
2.17.1

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

Reply via email to