summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/gpu/drm/amd/display/dc/core/dc.c38
-rw-r--r--drivers/gpu/drm/amd/display/dc/core/dc_surface.c64
-rw-r--r--drivers/gpu/drm/amd/display/dc/dc.h40
-rw-r--r--drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c36
-rw-r--r--drivers/gpu/drm/amd/display/dc/inc/core_types.h5
-rw-r--r--drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h4
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 06d8b32..8d26684 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 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()
@@ -198,17 +199,44 @@ struct dc_gamma *dc_create_gamma()
if (gamma == NULL)
goto alloc_fail;
- if (false == construct_gamma(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 7733292..aeb0c3be 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(void);
+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);
OpenPOWER on IntegriCloud