diff options
Diffstat (limited to 'common/recipes-kernel/linux/linux-yocto-4.14.71/0070-drm-amd-display-Refactor-output-transfer-function-to.patch')
-rw-r--r-- | common/recipes-kernel/linux/linux-yocto-4.14.71/0070-drm-amd-display-Refactor-output-transfer-function-to.patch | 308 |
1 files changed, 308 insertions, 0 deletions
diff --git a/common/recipes-kernel/linux/linux-yocto-4.14.71/0070-drm-amd-display-Refactor-output-transfer-function-to.patch b/common/recipes-kernel/linux/linux-yocto-4.14.71/0070-drm-amd-display-Refactor-output-transfer-function-to.patch new file mode 100644 index 00000000..65e44b58 --- /dev/null +++ b/common/recipes-kernel/linux/linux-yocto-4.14.71/0070-drm-amd-display-Refactor-output-transfer-function-to.patch @@ -0,0 +1,308 @@ +From 3c028814f813567158147857a73875adc4c0e711 Mon Sep 17 00:00:00 2001 +From: Anthony Koo <Anthony.Koo@amd.com> +Date: Thu, 15 Dec 2016 12:09:46 -0500 +Subject: [PATCH 0070/4131] drm/amd/display: Refactor output transfer function + to stream + +Refactor part 3 - Moving output transfer function from surface to stream + +Split HWSS to program degamma and regamma separately. +Degamma should be dependent on input transfer function. +And Regamma should depend on the desired output transfer function. + +Signed-off-by: Anthony Koo <anthony.koo@amd.com> +Reviewed-by: Aric Cyr <Aric.Cyr@amd.com> +Acked-by: Harry Wentland <Harry.Wentland@amd.com> +Signed-off-by: Alex Deucher <alexander.deucher@amd.com> +--- + .../drm/amd/display/amdgpu_dm/amdgpu_dm_types.c | 11 ++++ + drivers/gpu/drm/amd/display/dc/core/dc.c | 23 +++++--- + drivers/gpu/drm/amd/display/dc/core/dc_stream.c | 3 + + drivers/gpu/drm/amd/display/dc/core/dc_surface.c | 3 - + drivers/gpu/drm/amd/display/dc/dc.h | 7 ++- + .../amd/display/dc/dce110/dce110_hw_sequencer.c | 65 ++++++++++++++++++---- + drivers/gpu/drm/amd/display/dc/inc/core_types.h | 3 + + drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h | 7 ++- + 8 files changed, 95 insertions(+), 27 deletions(-) + +diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_types.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_types.c +index 0311090..6aede70 100644 +--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_types.c ++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_types.c +@@ -512,6 +512,7 @@ static void fill_gamma_from_crtc( + { + int i; + struct dc_gamma *gamma; ++ struct dc_transfer_func *input_tf; + uint16_t *red, *green, *blue; + int end = (crtc->gamma_size > NUM_OF_RAW_GAMMA_RAMP_RGB_256) ? + NUM_OF_RAW_GAMMA_RAMP_RGB_256 : crtc->gamma_size; +@@ -539,6 +540,16 @@ static void fill_gamma_from_crtc( + gamma->size = sizeof(gamma->gamma_ramp_rgb256x3x16); + + dc_surface->gamma_correction = gamma; ++ ++ input_tf = dc_create_transfer_func(adev->dm.dc); ++ ++ if (input_tf == NULL) ++ return; ++ ++ input_tf->type = TF_TYPE_PREDEFINED; ++ input_tf->tf = TRANSFER_FUNCTION_SRGB; ++ ++ dc_surface->in_transfer_func = input_tf; + } + + static void fill_plane_attributes( +diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c +index f20701a..df1bae8 100644 +--- a/drivers/gpu/drm/amd/display/dc/core/dc.c ++++ b/drivers/gpu/drm/amd/display/dc/core/dc.c +@@ -1394,6 +1394,7 @@ void dc_update_surfaces_for_target(struct dc *dc, struct dc_surface_update *upda + + for (j = 0; j < context->res_ctx.pool->pipe_count; j++) { + struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[j]; ++ struct core_stream *stream = pipe_ctx->stream; + + if (pipe_ctx->surface != surface) + continue; +@@ -1472,15 +1473,14 @@ void dc_update_surfaces_for_target(struct dc *dc, struct dc_surface_update *upda + + if (updates[i].out_transfer_func && + updates[i].out_transfer_func != +- surface->public.out_transfer_func) { +- if (surface->public.out_transfer_func != NULL) ++ stream->public.out_transfer_func) { ++ if (stream->public.out_transfer_func != NULL) + dc_transfer_func_release( +- surface->public. ++ stream->public. + out_transfer_func); +- + dc_transfer_func_retain( + updates[i].out_transfer_func); +- surface->public.out_transfer_func = ++ stream->public.out_transfer_func = + updates[i].out_transfer_func; + } + } +@@ -1517,11 +1517,18 @@ void dc_update_surfaces_for_target(struct dc *dc, struct dc_surface_update *upda + } + + if (is_new_pipe_surface[j] || ++ updates[i].in_transfer_func) ++ core_dc->hwss.set_input_transfer_func( ++ pipe_ctx, pipe_ctx->surface); ++ ++ if (is_new_pipe_surface[j] || + updates[i].gamma || +- updates[i].in_transfer_func || + updates[i].out_transfer_func) +- core_dc->hwss.set_gamma_correction( +- pipe_ctx, pipe_ctx->surface); ++ core_dc->hwss.set_output_transfer_func( ++ pipe_ctx, ++ pipe_ctx->surface, ++ pipe_ctx->stream); ++ + } + if (apply_ctx) { + core_dc->hwss.apply_ctx_for_surface(core_dc, surface, context); +diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_stream.c b/drivers/gpu/drm/amd/display/dc/core/dc_stream.c +index 8d6aa60..237436e 100644 +--- a/drivers/gpu/drm/amd/display/dc/core/dc_stream.c ++++ b/drivers/gpu/drm/amd/display/dc/core/dc_stream.c +@@ -89,6 +89,9 @@ static bool construct(struct core_stream *stream, + static void destruct(struct core_stream *stream) + { + dc_sink_release(&stream->sink->public); ++ if (stream->public.out_transfer_func != NULL) ++ dc_transfer_func_release( ++ stream->public.out_transfer_func); + } + + void dc_stream_retain(const struct dc_stream *dc_stream) +diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_surface.c b/drivers/gpu/drm/amd/display/dc/core/dc_surface.c +index 26f2f76..1ca40a2 100644 +--- a/drivers/gpu/drm/amd/display/dc/core/dc_surface.c ++++ b/drivers/gpu/drm/amd/display/dc/core/dc_surface.c +@@ -76,9 +76,6 @@ static void destruct(struct surface *surface) + if (surface->protected.public.in_transfer_func != NULL) + dc_transfer_func_release( + surface->protected.public.in_transfer_func); +- if (surface->protected.public.out_transfer_func != NULL) +- dc_transfer_func_release( +- surface->protected.public.out_transfer_func); + } + + /******************************************************************************* +diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h +index c7905b3..3f30afc 100644 +--- a/drivers/gpu/drm/amd/display/dc/dc.h ++++ b/drivers/gpu/drm/amd/display/dc/dc.h +@@ -254,6 +254,7 @@ struct dc_transfer_func_distributed_points { + enum dc_transfer_func_predefined { + TRANSFER_FUNCTION_SRGB, + TRANSFER_FUNCTION_BT709, ++ TRANSFER_FUNCTION_PQ, + TRANSFER_FUNCTION_LINEAR, + }; + +@@ -287,7 +288,6 @@ struct dc_surface { + const struct dc_gamma *gamma_correction; + + const struct dc_transfer_func *in_transfer_func; +- const struct dc_transfer_func *out_transfer_func; + }; + + struct dc_plane_info { +@@ -527,10 +527,11 @@ struct dc_stream { + + struct freesync_context freesync_ctx; + +- /* TODO: dithering */ +- /* TODO: transfer function (CSC/regamma/gamut remap) */ ++ const struct dc_transfer_func *out_transfer_func; + struct colorspace_transform gamut_remap_matrix; + struct csc_transform csc_color_matrix; ++ ++ /* TODO: dithering */ + /* TODO: custom INFO packets */ + /* TODO: ABM info (DMCU) */ + /* TODO: PSR info */ +diff --git a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c +index f6984e9..72017d5 100644 +--- a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c ++++ b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c +@@ -231,11 +231,61 @@ static void build_prescale_params(struct ipp_prescale_params *prescale_params, + } + } + +-static bool dce110_set_gamma_correction( ++static bool dce110_set_degamma( + struct pipe_ctx *pipe_ctx, + const struct core_surface *surface) + { + struct input_pixel_processor *ipp = pipe_ctx->ipp; ++ const struct core_transfer_func *tf = NULL; ++ struct ipp_prescale_params prescale_params = { 0 }; ++ bool result = true; ++ ++ if (ipp == NULL) ++ return false; ++ ++ if (surface->public.in_transfer_func) ++ tf = DC_TRANSFER_FUNC_TO_CORE(surface->public.in_transfer_func); ++ ++ build_prescale_params(&prescale_params, surface); ++ ipp->funcs->ipp_program_prescale(ipp, &prescale_params); ++ ++ if (tf == NULL) { ++ /* Default case if no input transfer function specified */ ++ ipp->funcs->ipp_set_degamma(ipp, ++ IPP_DEGAMMA_MODE_BYPASS); ++ } else if (tf->public.type == TF_TYPE_PREDEFINED) { ++ switch (tf->public.tf) { ++ case TRANSFER_FUNCTION_SRGB: ++ ipp->funcs->ipp_set_degamma(ipp, ++ IPP_DEGAMMA_MODE_HW_sRGB); ++ break; ++ case TRANSFER_FUNCTION_BT709: ++ ipp->funcs->ipp_set_degamma(ipp, ++ IPP_DEGAMMA_MODE_HW_xvYCC); ++ break; ++ case TRANSFER_FUNCTION_LINEAR: ++ ipp->funcs->ipp_set_degamma(ipp, ++ IPP_DEGAMMA_MODE_BYPASS); ++ break; ++ case TRANSFER_FUNCTION_PQ: ++ result = false; ++ break; ++ default: ++ result = false; ++ } ++ } else { ++ /*TF_TYPE_DISTRIBUTED_POINTS - Not supported in DCE 11*/ ++ result = false; ++ } ++ ++ return result; ++} ++ ++static bool dce110_set_output_transfer_func( ++ struct pipe_ctx *pipe_ctx, ++ const struct core_surface *surface, /* Surface - To be removed */ ++ const struct core_stream *stream) ++{ + struct output_pixel_processor *opp = pipe_ctx->opp; + const struct core_gamma *ramp = NULL; + struct ipp_prescale_params prescale_params = { 0 }; +@@ -253,20 +303,10 @@ static bool dce110_set_gamma_correction( + + opp->funcs->opp_power_on_regamma_lut(opp, true); + +- if (ipp) { +- build_prescale_params(&prescale_params, surface); +- ipp->funcs->ipp_program_prescale(ipp, &prescale_params); +- } +- + if (ramp && calculate_regamma_params(regamma_params, ramp, surface)) { +- + opp->funcs->opp_program_regamma_pwl(opp, regamma_params); +- if (ipp) +- ipp->funcs->ipp_set_degamma(ipp, IPP_DEGAMMA_MODE_HW_sRGB); + opp->funcs->opp_set_regamma_mode(opp, OPP_REGAMMA_USER); + } else { +- if (ipp) +- ipp->funcs->ipp_set_degamma(ipp, IPP_DEGAMMA_MODE_BYPASS); + opp->funcs->opp_set_regamma_mode(opp, OPP_REGAMMA_BYPASS); + } + +@@ -1904,7 +1944,8 @@ static const struct hw_sequencer_funcs dce110_funcs = { + .set_plane_config = set_plane_config, + .update_plane_addr = update_plane_addr, + .update_pending_status = dce110_update_pending_status, +- .set_gamma_correction = dce110_set_gamma_correction, ++ .set_input_transfer_func = dce110_set_degamma, ++ .set_output_transfer_func = dce110_set_output_transfer_func, + .power_down = dce110_power_down, + .enable_accelerated_mode = dce110_enable_accelerated_mode, + .enable_timing_synchronization = dce110_enable_timing_synchronization, +diff --git a/drivers/gpu/drm/amd/display/dc/inc/core_types.h b/drivers/gpu/drm/amd/display/dc/inc/core_types.h +index a67d675..c2d35c2 100644 +--- a/drivers/gpu/drm/amd/display/dc/inc/core_types.h ++++ b/drivers/gpu/drm/amd/display/dc/inc/core_types.h +@@ -55,6 +55,9 @@ struct core_target { + #define DC_GAMMA_TO_CORE(dc_gamma) \ + container_of(dc_gamma, struct core_gamma, public) + ++#define DC_TRANSFER_FUNC_TO_CORE(dc_transfer_func) \ ++ container_of(dc_transfer_func, struct core_transfer_func, public) ++ + struct core_surface { + struct dc_surface public; + struct dc_surface_status status; +diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h b/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h +index 89a0834..0e803ca 100644 +--- a/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h ++++ b/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h +@@ -77,10 +77,15 @@ struct hw_sequencer_funcs { + void (*update_pending_status)( + struct pipe_ctx *pipe_ctx); + +- bool (*set_gamma_correction)( ++ bool (*set_input_transfer_func)( + struct pipe_ctx *pipe_ctx, + const struct core_surface *surface); + ++ bool (*set_output_transfer_func)( ++ struct pipe_ctx *pipe_ctx, ++ const struct core_surface *surface, ++ const struct core_stream *stream); ++ + void (*power_down)(struct core_dc *dc); + + void (*enable_accelerated_mode)(struct core_dc *dc); +-- +2.7.4 + |