diff options
author | Anthony Koo <Anthony.Koo@amd.com> | 2016-12-13 13:59:41 -0500 |
---|---|---|
committer | Alex Deucher <alexander.deucher@amd.com> | 2017-09-26 17:05:08 -0400 |
commit | fb735a9f29f94fcb29fee224b8da704a510a5a3a (patch) | |
tree | 3ba858eea98646e325647ce4703fe4ec55fdfb9a /drivers/gpu/drm/amd/display/dc/core | |
parent | 88499197de090c9bb391cc11bf9410b9f020092f (diff) | |
download | op-kernel-dev-fb735a9f29f94fcb29fee224b8da704a510a5a3a.zip op-kernel-dev-fb735a9f29f94fcb29fee224b8da704a510a5a3a.tar.gz |
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>
Diffstat (limited to 'drivers/gpu/drm/amd/display/dc/core')
-rw-r--r-- | drivers/gpu/drm/amd/display/dc/core/dc.c | 38 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/display/dc/core/dc_surface.c | 64 |
2 files changed, 80 insertions, 22 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; } + |