aboutsummaryrefslogtreecommitdiffstats
path: root/common/recipes-kernel/linux/linux-yocto-4.14.71/0070-drm-amd-display-Refactor-output-transfer-function-to.patch
diff options
context:
space:
mode:
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.patch308
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
+