[PATCH 014/103] drm/amd/display: Refactor dc_update_planes_and_stream.
Harry Wentland
harry.wentland at amd.com
Tue Oct 10 22:39:43 UTC 2017
From: Bhawanpreet Lakha <Bhawanpreet.Lakha at amd.com>
Split update_planes_and_stream_state (split Software and Hardware
programming) as the state is already build, so we only need to
program the hardware
Signed-off-by: Andrey Grodzovsky <Andrey.Grodzovsky at amd.com>
Signed-off-by: Bhawanpreet Lakha <Bhawanpreet.Lakha at amd.com>
Reviewed-by: Harry Wentland <Harry.Wentland at amd.com>
---
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 21 +-
drivers/gpu/drm/amd/display/dc/core/dc.c | 256 +++++-----------------
drivers/gpu/drm/amd/display/dc/dc.h | 36 +--
3 files changed, 87 insertions(+), 226 deletions(-)
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index fb80e22ae06f..af2c9d1289c0 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -3935,7 +3935,8 @@ static void prepare_flip_isr(struct amdgpu_crtc *acrtc)
static void amdgpu_dm_do_flip(
struct drm_crtc *crtc,
struct drm_framebuffer *fb,
- uint32_t target)
+ uint32_t target,
+ struct dc_state *state)
{
unsigned long flags;
uint32_t target_vblank;
@@ -4006,7 +4007,13 @@ static void amdgpu_dm_do_flip(
surface_updates->flip_addr = &addr;
- dc_update_planes_and_stream(adev->dm.dc, surface_updates, 1, acrtc_state->stream, NULL);
+ dc_commit_updates_for_stream(adev->dm.dc,
+ surface_updates,
+ 1,
+ acrtc_state->stream,
+ NULL,
+ &surface_updates->surface,
+ state);
DRM_DEBUG_DRIVER("%s Flipping to hi: 0x%x, low: 0x%x \n",
__func__,
@@ -4030,6 +4037,7 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state,
struct dc_plane_state *plane_states_constructed[MAX_SURFACES];
struct amdgpu_crtc *acrtc_attach = to_amdgpu_crtc(pcrtc);
struct dm_crtc_state *acrtc_state = to_dm_crtc_state(pcrtc->state);
+ struct dm_atomic_state *dm_state = to_dm_atomic_state(state);
int planes_count = 0;
unsigned long flags;
@@ -4086,7 +4094,8 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state,
amdgpu_dm_do_flip(
crtc,
fb,
- drm_crtc_vblank_count(crtc) + *wait_for_vblank);
+ drm_crtc_vblank_count(crtc) + *wait_for_vblank,
+ dm_state->context);
}
}
@@ -4106,7 +4115,8 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state,
if (false == dc_commit_planes_to_stream(dm->dc,
plane_states_constructed,
planes_count,
- dc_stream_attach))
+ dc_stream_attach,
+ dm_state->context))
dm_error("%s: Failed to attach plane!\n", __func__);
} else {
/*TODO BUG Here should go disable planes on CRTC. */
@@ -4329,7 +4339,8 @@ void amdgpu_dm_atomic_commit_tail(
dm->dc,
status->plane_states,
status->plane_count,
- new_acrtc_state->stream))
+ new_acrtc_state->stream,
+ dm_state->context))
dm_error("%s: Failed to update stream scaling!\n", __func__);
}
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c
index 47f16a4b9f27..1ec6df9870da 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc.c
@@ -869,7 +869,8 @@ bool dc_commit_planes_to_stream(
struct dc *dc,
struct dc_plane_state **plane_states,
uint8_t new_plane_count,
- struct dc_stream_state *dc_stream)
+ struct dc_stream_state *dc_stream,
+ struct dc_state *state)
{
struct dc_surface_update updates[MAX_SURFACES];
struct dc_flip_addrs flip_addr[MAX_SURFACES];
@@ -920,11 +921,11 @@ bool dc_commit_planes_to_stream(
updates[i].scaling_info = &scaling_info[i];
}
- dc_update_planes_and_stream(
+ dc_commit_updates_for_stream(
dc,
updates,
new_plane_count,
- dc_stream, stream_update);
+ dc_stream, stream_update, plane_states, state);
dc_post_update_surfaces_to_stream(dc);
@@ -1150,192 +1151,20 @@ static struct dc_stream_status *stream_get_status(
static const enum surface_update_type update_surface_trace_level = UPDATE_TYPE_FULL;
-void dc_update_planes_and_stream(struct dc *dc,
- struct dc_surface_update *srf_updates, int surface_count,
+
+static void commit_planes_for_stream(struct dc *dc,
+ struct dc_surface_update *srf_updates,
+ int surface_count,
struct dc_stream_state *stream,
- struct dc_stream_update *stream_update)
+ struct dc_stream_update *stream_update,
+ enum surface_update_type update_type,
+ struct dc_state *context)
{
- struct dc_state *context;
int i, j;
- enum surface_update_type update_type;
- const struct dc_stream_status *stream_status;
- struct dc_context *dc_ctx = dc->ctx;
-
- stream_status = dc_stream_get_status(stream);
-
- ASSERT(stream_status);
- if (!stream_status)
- return; /* Cannot commit surface to stream that is not committed */
-
-#ifdef ENABLE_FBC
- if (srf_updates->flip_addr) {
- if (srf_updates->flip_addr->address.grph.addr.low_part == 0)
- ASSERT(0);
- }
-#endif
- context = dc->current_state;
-
- /* update current stream with the new updates */
- if (stream_update) {
- if ((stream_update->src.height != 0) &&
- (stream_update->src.width != 0))
- stream->src = stream_update->src;
-
- if ((stream_update->dst.height != 0) &&
- (stream_update->dst.width != 0))
- stream->dst = stream_update->dst;
-
- if (stream_update->out_transfer_func &&
- stream_update->out_transfer_func !=
- stream->out_transfer_func) {
- if (stream->out_transfer_func != NULL)
- dc_transfer_func_release(stream->out_transfer_func);
- dc_transfer_func_retain(stream_update->out_transfer_func);
- stream->out_transfer_func =
- stream_update->out_transfer_func;
- }
- }
-
- /* do not perform surface update if surface has invalid dimensions
- * (all zero) and no scaling_info is provided
- */
- if (surface_count > 0 &&
- srf_updates->surface->src_rect.width == 0 &&
- srf_updates->surface->src_rect.height == 0 &&
- srf_updates->surface->dst_rect.width == 0 &&
- srf_updates->surface->dst_rect.height == 0 &&
- !srf_updates->scaling_info) {
- ASSERT(false);
- return;
- }
-
- update_type = dc_check_update_surfaces_for_stream(
- dc, srf_updates, surface_count, stream_update, stream_status);
-
- if (update_type >= update_surface_trace_level)
- update_surface_trace(dc, srf_updates, surface_count);
-
- if (update_type >= UPDATE_TYPE_FULL) {
- struct dc_plane_state *new_planes[MAX_SURFACES] = {0};
-
- for (i = 0; i < surface_count; i++)
- new_planes[i] = srf_updates[i].surface;
-
- /* initialize scratch memory for building context */
- context = dc_create_state();
- if (context == NULL) {
- DC_ERROR("Failed to allocate new validate context!\n");
- return;
- }
-
- dc_resource_state_copy_construct(
- dc->current_state, context);
-
- /*remove old surfaces from context */
- if (!dc_rem_all_planes_for_stream(dc, stream, context)) {
-
- BREAK_TO_DEBUGGER();
- goto fail;
- }
-
- /* add surface to context */
- if (!dc_add_all_planes_for_stream(dc, stream, new_planes, surface_count, context)) {
-
- BREAK_TO_DEBUGGER();
- goto fail;
- }
- }
-
- /* save update parameters into surface */
- for (i = 0; i < surface_count; i++) {
- struct dc_plane_state *surface = srf_updates[i].surface;
-
- if (srf_updates[i].flip_addr) {
- surface->address = srf_updates[i].flip_addr->address;
- surface->flip_immediate =
- srf_updates[i].flip_addr->flip_immediate;
- }
-
- if (srf_updates[i].scaling_info) {
- surface->scaling_quality =
- srf_updates[i].scaling_info->scaling_quality;
- surface->dst_rect =
- srf_updates[i].scaling_info->dst_rect;
- surface->src_rect =
- srf_updates[i].scaling_info->src_rect;
- surface->clip_rect =
- srf_updates[i].scaling_info->clip_rect;
- }
-
- if (srf_updates[i].plane_info) {
- surface->color_space =
- srf_updates[i].plane_info->color_space;
- surface->format =
- srf_updates[i].plane_info->format;
- surface->plane_size =
- srf_updates[i].plane_info->plane_size;
- surface->rotation =
- srf_updates[i].plane_info->rotation;
- surface->horizontal_mirror =
- srf_updates[i].plane_info->horizontal_mirror;
- surface->stereo_format =
- srf_updates[i].plane_info->stereo_format;
- surface->tiling_info =
- srf_updates[i].plane_info->tiling_info;
- surface->visible =
- srf_updates[i].plane_info->visible;
- surface->per_pixel_alpha =
- srf_updates[i].plane_info->per_pixel_alpha;
- surface->dcc =
- srf_updates[i].plane_info->dcc;
- }
-
- if (update_type >= UPDATE_TYPE_MED) {
- for (j = 0; j < dc->res_pool->pipe_count; j++) {
- struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[j];
-
- if (pipe_ctx->plane_state != surface)
- continue;
-
- resource_build_scaling_params(pipe_ctx);
- }
- }
-
- if (srf_updates[i].gamma &&
- srf_updates[i].gamma != surface->gamma_correction) {
- if (surface->gamma_correction != NULL)
- dc_gamma_release(&surface->gamma_correction);
-
- dc_gamma_retain(srf_updates[i].gamma);
- surface->gamma_correction = srf_updates[i].gamma;
- }
-
- if (srf_updates[i].in_transfer_func &&
- srf_updates[i].in_transfer_func != surface->in_transfer_func) {
- if (surface->in_transfer_func != NULL)
- dc_transfer_func_release(
- surface->
- in_transfer_func);
-
- dc_transfer_func_retain(
- srf_updates[i].in_transfer_func);
- surface->in_transfer_func =
- srf_updates[i].in_transfer_func;
- }
-
- if (srf_updates[i].hdr_static_metadata)
- surface->hdr_static_ctx =
- *(srf_updates[i].hdr_static_metadata);
- }
if (update_type == UPDATE_TYPE_FULL) {
- if (!dc->res_pool->funcs->validate_bandwidth(dc, context)) {
- BREAK_TO_DEBUGGER();
- goto fail;
- } else {
- dc->hwss.set_bandwidth(dc, context, false);
- context_clock_trace(dc, context);
- }
+ dc->hwss.set_bandwidth(dc, context, false);
+ context_clock_trace(dc, context);
}
if (update_type > UPDATE_TYPE_FAST) {
@@ -1459,27 +1288,60 @@ void dc_update_planes_and_stream(struct dc *dc,
break;
}
}
+}
+
+void dc_commit_updates_for_stream(struct dc *dc,
+ struct dc_surface_update *srf_updates,
+ int surface_count,
+ struct dc_stream_state *stream,
+ struct dc_stream_update *stream_update,
+ struct dc_plane_state **plane_states,
+ struct dc_state *state)
+{
+ const struct dc_stream_status *stream_status;
+ enum surface_update_type update_type;
+ struct dc_state *context;
+ int i;
- if (dc->current_state != context) {
+ stream_status = dc_stream_get_status(stream);
+ context = dc->current_state;
+
+ update_type = dc_check_update_surfaces_for_stream(
+ dc, srf_updates, surface_count, stream_update, stream_status);
+
+ if (update_type >= update_surface_trace_level)
+ update_surface_trace(dc, srf_updates, surface_count);
- /* Since memory free requires elevated IRQL, an interrupt
- * request is generated by mem free. If this happens
- * between freeing and reassigning the context, our vsync
- * interrupt will call into dc and cause a memory
- * corruption BSOD. Hence, we first reassign the context,
- * then free the old context.
- */
- struct dc_state *old = dc->current_state;
+ if (update_type >= UPDATE_TYPE_FULL)
+ dc_resource_state_copy_construct(state, context);
- dc->current_state = context;
- dc_release_state(old);
+
+ for (i = 0; i < surface_count; i++) {
+ struct dc_plane_state *surface = srf_updates[i].surface;
+
+ /* TODO: On flip we don't build the state, so it still has the
+ * old address. Which is why we are updating the address here
+ */
+ if (srf_updates[i].flip_addr)
+ surface->address = srf_updates[i].flip_addr->address;
}
+
+
+ commit_planes_for_stream(
+ dc,
+ srf_updates,
+ surface_count,
+ stream,
+ stream_update,
+ update_type,
+ context);
+
+ dc_post_update_surfaces_to_stream(dc);
+
return;
-fail:
- dc_release_state(context);
}
uint8_t dc_get_current_stream_count(struct dc *dc)
diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h
index 4ff543826476..50440731f83c 100644
--- a/drivers/gpu/drm/amd/display/dc/dc.h
+++ b/drivers/gpu/drm/amd/display/dc/dc.h
@@ -449,23 +449,6 @@ struct dc_flip_addrs {
/* TODO: add flip duration for FreeSync */
};
-/*
- * Set up surface attributes and associate to a stream
- * The surfaces parameter is an absolute set of all surface active for the stream.
- * If no surfaces are provided, the stream will be blanked; no memory read.
- * Any flip related attribute changes must be done through this interface.
- *
- * After this call:
- * Surfaces attributes are programmed and configured to be composed into stream.
- * This does not trigger a flip. No surface address is programmed.
- */
-
-bool dc_commit_planes_to_stream(
- struct dc *dc,
- struct dc_plane_state **plane_states,
- uint8_t new_plane_count,
- struct dc_stream_state *stream);
-
bool dc_post_update_surfaces_to_stream(
struct dc *dc);
@@ -571,9 +554,6 @@ bool dc_is_stream_unchanged(
struct dc_stream_state *old_stream, struct dc_stream_state *stream);
/*
- * Setup stream attributes if no stream updates are provided
- * there will be no impact on the stream parameters
- *
* Set up surface attributes and associate to a stream
* The surfaces parameter is an absolute set of all surface active for the stream.
* If no surfaces are provided, the stream will be blanked; no memory read.
@@ -582,14 +562,22 @@ bool dc_is_stream_unchanged(
* After this call:
* Surfaces attributes are programmed and configured to be composed into stream.
* This does not trigger a flip. No surface address is programmed.
- *
*/
-void dc_update_planes_and_stream(struct dc *dc,
- struct dc_surface_update *surface_updates, int surface_count,
+bool dc_commit_planes_to_stream(
+ struct dc *dc,
+ struct dc_plane_state **plane_states,
+ uint8_t new_plane_count,
struct dc_stream_state *dc_stream,
- struct dc_stream_update *stream_update);
+ struct dc_state *state);
+void dc_commit_updates_for_stream(struct dc *dc,
+ struct dc_surface_update *srf_updates,
+ int surface_count,
+ struct dc_stream_state *stream,
+ struct dc_stream_update *stream_update,
+ struct dc_plane_state **plane_states,
+ struct dc_state *state);
/*
* Log the current stream state.
*/
--
2.14.1
More information about the amd-gfx
mailing list