aboutsummaryrefslogtreecommitdiffstats
path: root/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/0063-drm-amd-display-Add-in-out-transfer-functions-to-DC.patch
diff options
context:
space:
mode:
Diffstat (limited to 'meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/0063-drm-amd-display-Add-in-out-transfer-functions-to-DC.patch')
-rw-r--r--meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/0063-drm-amd-display-Add-in-out-transfer-functions-to-DC.patch399
1 files changed, 399 insertions, 0 deletions
diff --git a/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/0063-drm-amd-display-Add-in-out-transfer-functions-to-DC.patch b/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/0063-drm-amd-display-Add-in-out-transfer-functions-to-DC.patch
new file mode 100644
index 00000000..60d5333a
--- /dev/null
+++ b/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/0063-drm-amd-display-Add-in-out-transfer-functions-to-DC.patch
@@ -0,0 +1,399 @@
+From 690487d6784b85f42f43f9d1a24fe35db2a32d65 Mon Sep 17 00:00:00 2001
+From: Anthony Koo <Anthony.Koo@amd.com>
+Date: Tue, 13 Dec 2016 13:59:41 -0500
+Subject: [PATCH 0063/4131] drm/amd/display: Add in/out transfer functions to
+ DC
+
+Refactor part 1 of degamma/regamma programming.
+
+End goal is to have source and output transfer function in
+which dc can use to decide how to program the degamma
+and regamma HW.
+
+Gamma will be explicitly applied through
+dc_update_surfaces_for_target.
+
+Color module should build the logical curve with all
+adjustments applied and pass enough information
+for dc to program HW PWL.
+
+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>
+---
+ drivers/gpu/drm/amd/display/dc/core/dc.c | 38 +++++++++++--
+ drivers/gpu/drm/amd/display/dc/core/dc_surface.c | 64 ++++++++++++++++------
+ drivers/gpu/drm/amd/display/dc/dc.h | 40 +++++++++++++-
+ .../amd/display/dc/dce110/dce110_hw_sequencer.c | 36 ++++--------
+ drivers/gpu/drm/amd/display/dc/inc/core_types.h | 5 ++
+ drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h | 4 +-
+ 6 files changed, 135 insertions(+), 52 deletions(-)
+
+diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c
+index 9a35e3b..f20701a 100644
+--- a/drivers/gpu/drm/amd/display/dc/core/dc.c
++++ b/drivers/gpu/drm/amd/display/dc/core/dc.c
+@@ -1455,6 +1455,34 @@ void dc_update_surfaces_for_target(struct dc *dc, struct dc_surface_update *upda
+ surface->public.gamma_correction =
+ updates[i].gamma;
+ }
++
++ if (updates[i].in_transfer_func &&
++ updates[i].in_transfer_func !=
++ surface->public.in_transfer_func) {
++ if (surface->public.in_transfer_func != NULL)
++ dc_transfer_func_release(
++ surface->public.
++ in_transfer_func);
++
++ dc_transfer_func_retain(
++ updates[i].in_transfer_func);
++ surface->public.in_transfer_func =
++ updates[i].in_transfer_func;
++ }
++
++ if (updates[i].out_transfer_func &&
++ updates[i].out_transfer_func !=
++ surface->public.out_transfer_func) {
++ if (surface->public.out_transfer_func != NULL)
++ dc_transfer_func_release(
++ surface->public.
++ out_transfer_func);
++
++ dc_transfer_func_retain(
++ updates[i].out_transfer_func);
++ surface->public.out_transfer_func =
++ updates[i].out_transfer_func;
++ }
+ }
+ }
+
+@@ -1474,7 +1502,6 @@ void dc_update_surfaces_for_target(struct dc *dc, struct dc_surface_update *upda
+
+ if (updates[i].plane_info || updates[i].scaling_info
+ || is_new_pipe_surface[j]) {
+-
+ apply_ctx = true;
+
+ if (!pipe_ctx->tg->funcs->is_blanked(pipe_ctx->tg)) {
+@@ -1489,9 +1516,12 @@ void dc_update_surfaces_for_target(struct dc *dc, struct dc_surface_update *upda
+ }
+ }
+
+- if (updates[i].gamma)
+- core_dc->hwss.prepare_pipe_for_context(
+- core_dc, pipe_ctx, context);
++ 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);
+ }
+ 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_surface.c b/drivers/gpu/drm/amd/display/dc/core/dc_surface.c
+index 813c37e..26f2f76 100644
+--- a/drivers/gpu/drm/amd/display/dc/core/dc_surface.c
++++ b/drivers/gpu/drm/amd/display/dc/core/dc_surface.c
+@@ -45,11 +45,18 @@ struct gamma {
+ int ref_count;
+ };
+
++struct transfer_func {
++ struct core_transfer_func protected;
++ int ref_count;
++};
++
+ #define DC_SURFACE_TO_SURFACE(dc_surface) container_of(dc_surface, struct surface, protected.public)
+ #define CORE_SURFACE_TO_SURFACE(core_surface) container_of(core_surface, struct surface, protected)
+
+ #define DC_GAMMA_TO_GAMMA(dc_gamma) \
+ container_of(dc_gamma, struct gamma, protected.public)
++#define DC_TRANSFER_FUNC_TO_TRANSFER_FUNC(dc_tf) \
++ container_of(dc_tf, struct transfer_func, protected.public)
+ #define CORE_GAMMA_TO_GAMMA(core_gamma) \
+ container_of(core_gamma, struct gamma, protected)
+
+@@ -66,6 +73,12 @@ static void destruct(struct surface *surface)
+ {
+ if (surface->protected.public.gamma_correction != NULL)
+ dc_gamma_release(surface->protected.public.gamma_correction);
++ 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);
+ }
+
+ /*******************************************************************************
+@@ -163,16 +176,6 @@ void dc_surface_release(const struct dc_surface *dc_surface)
+ }
+ }
+
+-static bool construct_gamma(struct dc_context *ctx, struct gamma *gamma)
+-{
+- return true;
+-}
+-
+-static void destruct_gamma(struct gamma *gamma)
+-{
+-
+-}
+-
+ void dc_gamma_retain(const struct dc_gamma *dc_gamma)
+ {
+ struct gamma *gamma = DC_GAMMA_TO_GAMMA(dc_gamma);
+@@ -185,10 +188,8 @@ void dc_gamma_release(const struct dc_gamma *dc_gamma)
+ struct gamma *gamma = DC_GAMMA_TO_GAMMA(dc_gamma);
+ --gamma->ref_count;
+
+- if (gamma->ref_count == 0) {
+- destruct_gamma(gamma);
++ if (gamma->ref_count == 0)
+ dm_free(gamma);
+- }
+ }
+
+ struct dc_gamma *dc_create_gamma(const struct dc *dc)
+@@ -199,17 +200,44 @@ struct dc_gamma *dc_create_gamma(const struct dc *dc)
+ if (gamma == NULL)
+ goto alloc_fail;
+
+- if (false == construct_gamma(core_dc->ctx, gamma))
+- goto construct_fail;
+-
+ dc_gamma_retain(&gamma->protected.public);
+
+ return &gamma->protected.public;
+
+-construct_fail:
+- dm_free(gamma);
++alloc_fail:
++ return NULL;
++}
++
++void dc_transfer_func_retain(const struct dc_transfer_func *dc_tf)
++{
++ struct transfer_func *tf = DC_TRANSFER_FUNC_TO_TRANSFER_FUNC(dc_tf);
++
++ ++tf->ref_count;
++}
++
++void dc_transfer_func_release(const struct dc_transfer_func *dc_tf)
++{
++ struct transfer_func *tf = DC_TRANSFER_FUNC_TO_TRANSFER_FUNC(dc_tf);
++ --tf->ref_count;
++
++ if (tf->ref_count == 0)
++ dm_free(tf);
++}
++
++struct dc_transfer_func *dc_create_transfer_func(const struct dc *dc)
++{
++ struct core_dc *core_dc = DC_TO_CORE(dc);
++ struct transfer_func *tf = dm_alloc(sizeof(*tf));
++
++ if (tf == NULL)
++ goto alloc_fail;
++
++ dc_transfer_func_retain(&tf->protected.public);
++
++ return &tf->protected.public;
+
+ alloc_fail:
+ return NULL;
+ }
+
++
+diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h
+index d9e2ed1..4cb1948 100644
+--- a/drivers/gpu/drm/amd/display/dc/dc.h
++++ b/drivers/gpu/drm/amd/display/dc/dc.h
+@@ -201,7 +201,8 @@ bool dc_init_dchub(struct dc *dc, struct dchub_init_data *dh_data);
+
+ enum {
+ RGB_256X3X16 = 256,
+- FLOAT_GAMMA_RAMP_MAX = 1025
++ FLOAT_GAMMA_RAMP_MAX = 1025,
++ TRANSFER_FUNC_POINTS = 1025
+ };
+
+ enum dc_gamma_ramp_type {
+@@ -236,6 +237,31 @@ struct dc_gamma {
+ uint32_t size;
+ };
+
++enum dc_transfer_func_type {
++ TF_TYPE_PREDEFINED,
++ TF_TYPE_DISTRIBUTED_POINTS,
++};
++
++struct dc_transfer_func_distributed_points {
++ uint16_t red[TRANSFER_FUNC_POINTS];
++ uint16_t green[TRANSFER_FUNC_POINTS];
++ uint16_t blue[TRANSFER_FUNC_POINTS];
++ uint16_t end_exponent;
++ uint16_t x_point_at_y1;
++};
++
++enum dc_transfer_func_predefined {
++ TRANSFER_FUNCTION_SRGB,
++ TRANSFER_FUNCTION_BT709,
++ TRANSFER_FUNCTION_LINEAR,
++};
++
++struct dc_transfer_func {
++ enum dc_transfer_func_type type;
++ enum dc_transfer_func_predefined tf;
++ struct dc_transfer_func_distributed_points tf_pts;
++};
++
+ struct dc_surface {
+ bool visible;
+ bool flip_immediate;
+@@ -256,7 +282,11 @@ struct dc_surface {
+ bool horizontal_mirror;
+ enum plane_stereo_format stereo_format;
+
++ /* TO BE REMOVED AFTER BELOW TRANSFER FUNCTIONS IMPLEMENTED */
+ 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 {
+@@ -287,8 +317,12 @@ struct dc_surface_update {
+ /* following updates require alloc/sleep/spin that is not isr safe,
+ * null means no updates
+ */
++ /* gamma TO BE REMOVED */
+ struct dc_gamma *gamma;
+
++ struct dc_transfer_func *in_transfer_func;
++ struct dc_transfer_func *out_transfer_func;
++
+
+ };
+ /*
+@@ -316,6 +350,10 @@ void dc_gamma_retain(const struct dc_gamma *dc_gamma);
+ void dc_gamma_release(const struct dc_gamma *dc_gamma);
+ struct dc_gamma *dc_create_gamma(const struct dc *dc);
+
++void dc_transfer_func_retain(const struct dc_transfer_func *dc_tf);
++void dc_transfer_func_release(const struct dc_transfer_func *dc_tf);
++struct dc_transfer_func *dc_create_transfer_func(const struct dc *dc);
++
+ /*
+ * This structure holds a surface address. There could be multiple addresses
+ * in cases such as Stereo 3D, Planar YUV, etc. Other per-flip attributes such
+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 99937fa..f6984e9 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,16 +231,20 @@ static void build_prescale_params(struct ipp_prescale_params *prescale_params,
+ }
+ }
+
+-static bool set_gamma_ramp(
+- struct input_pixel_processor *ipp,
+- struct output_pixel_processor *opp,
+- const struct core_gamma *ramp,
++static bool dce110_set_gamma_correction(
++ struct pipe_ctx *pipe_ctx,
+ const struct core_surface *surface)
+ {
++ struct input_pixel_processor *ipp = pipe_ctx->ipp;
++ struct output_pixel_processor *opp = pipe_ctx->opp;
++ const struct core_gamma *ramp = NULL;
+ struct ipp_prescale_params prescale_params = { 0 };
+ struct pwl_params *regamma_params;
+ bool result = false;
+
++ if (surface->public.gamma_correction)
++ ramp = DC_GAMMA_TO_CORE(surface->public.gamma_correction);
++
+ regamma_params = dm_alloc(sizeof(struct pwl_params));
+ if (regamma_params == NULL)
+ goto regamma_alloc_fail;
+@@ -1842,33 +1846,13 @@ static void dce110_program_front_end_for_pipe(
+ pipe_ctx->scl_data.recout.y);
+ }
+
+-
+-
+-static void dce110_prepare_pipe_for_surface_commit(
+- struct core_dc *dc,
+- struct pipe_ctx *pipe_ctx,
+- struct validate_context *context) {
+- struct core_gamma *gamma = NULL;
+-
+- dc->hwss.increase_watermarks_for_pipe(dc, pipe_ctx, context);
+-
+- if (pipe_ctx->surface->public.gamma_correction)
+- gamma = DC_GAMMA_TO_CORE(
+- pipe_ctx->surface->public.gamma_correction);
+-
+- dc->hwss.set_gamma_correction(
+- pipe_ctx->ipp,
+- pipe_ctx->opp,
+- gamma, pipe_ctx->surface);
+-}
+-
+ static void dce110_prepare_pipe_for_context(
+ struct core_dc *dc,
+ struct pipe_ctx *pipe_ctx,
+ struct validate_context *context)
+ {
+ dce110_power_on_pipe_if_needed(dc, pipe_ctx, context);
+- dce110_prepare_pipe_for_surface_commit(dc, pipe_ctx, context);
++ dc->hwss.increase_watermarks_for_pipe(dc, pipe_ctx, context);
+ }
+
+ static void dce110_apply_ctx_for_surface(
+@@ -1920,7 +1904,7 @@ 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 = set_gamma_ramp,
++ .set_gamma_correction = dce110_set_gamma_correction,
+ .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 3cf9bfb..a67d675 100644
+--- a/drivers/gpu/drm/amd/display/dc/inc/core_types.h
++++ b/drivers/gpu/drm/amd/display/dc/inc/core_types.h
+@@ -66,6 +66,11 @@ struct core_gamma {
+ struct dc_context *ctx;
+ };
+
++struct core_transfer_func {
++ struct dc_transfer_func public;
++ struct dc_context *ctx;
++};
++
+ void enable_surface_flip_reporting(struct dc_surface *dc_surface,
+ uint32_t controller_id);
+
+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 fcaf2c7..89a0834 100644
+--- a/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h
++++ b/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h
+@@ -78,9 +78,7 @@ struct hw_sequencer_funcs {
+ struct pipe_ctx *pipe_ctx);
+
+ bool (*set_gamma_correction)(
+- struct input_pixel_processor *ipp,
+- struct output_pixel_processor *opp,
+- const struct core_gamma *ramp,
++ struct pipe_ctx *pipe_ctx,
+ const struct core_surface *surface);
+
+ void (*power_down)(struct core_dc *dc);
+--
+2.7.4
+