Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 49e37ba0 authored by Dave Airlie's avatar Dave Airlie
Browse files

Merge branch 'drm-next-4.15-dc' of git://people.freedesktop.org/~agd5f/linux into drm-next

Various fixes for DC for 4.15.

* 'drm-next-4.15-dc' of git://people.freedesktop.org/~agd5f/linux:
  drm/amd/display: fix MST link training fail division by 0
  drm/amd/display: Fix formatting for null pointer dereference fix
  drm/amd/display: Remove dangling planes on dc commit state
  drm/amd/display: add flip_immediate to commit update for stream
  drm/amd/display: Miss register MST encoder cbs
  drm/amd/display: Fix warnings on S3 resume
  drm/amd/display: use num_timing_generator instead of pipe_count
  drm/amd/display: use configurable FBC option in dm
  drm/amd/display: fix AZ clock not enabled before program AZ endpoint
  amdgpu/dm: Don't use DRM_ERROR in amdgpu_dm_atomic_check
parents 4479ed41 00f713c6
Loading
Loading
Loading
Loading
+35 −9
Original line number Diff line number Diff line
@@ -344,7 +344,7 @@ static void hotplug_notify_work_func(struct work_struct *work)
	drm_kms_helper_hotplug_event(dev);
}

#ifdef ENABLE_FBC
#if defined(CONFIG_DRM_AMD_DC_FBC)
#include "dal_asic_id.h"
/* Allocate memory for FBC compressed data  */
/* TODO: Dynamic allocation */
@@ -422,7 +422,7 @@ static int amdgpu_dm_init(struct amdgpu_device *adev)
	else
		init_data.log_mask = DC_MIN_LOG_MASK;

#ifdef ENABLE_FBC
#if defined(CONFIG_DRM_AMD_DC_FBC)
	if (adev->family == FAMILY_CZ)
		amdgpu_dm_initialize_fbc(adev);
	init_data.fbc_gpu_addr = adev->dm.compressor.gpu_addr;
@@ -643,6 +643,11 @@ int amdgpu_dm_display_resume(struct amdgpu_device *adev)
	struct drm_connector *connector;
	struct drm_crtc *crtc;
	struct drm_crtc_state *new_crtc_state;
	struct dm_crtc_state *dm_new_crtc_state;
	struct drm_plane *plane;
	struct drm_plane_state *new_plane_state;
	struct dm_plane_state *dm_new_plane_state;

	int ret = 0;
	int i;

@@ -681,6 +686,29 @@ int amdgpu_dm_display_resume(struct amdgpu_device *adev)
	for_each_new_crtc_in_state(adev->dm.cached_state, crtc, new_crtc_state, i)
		new_crtc_state->active_changed = true;

	/*
	 * atomic_check is expected to create the dc states. We need to release
	 * them here, since they were duplicated as part of the suspend
	 * procedure.
	 */
	for_each_new_crtc_in_state(adev->dm.cached_state, crtc, new_crtc_state, i) {
		dm_new_crtc_state = to_dm_crtc_state(new_crtc_state);
		if (dm_new_crtc_state->stream) {
			WARN_ON(kref_read(&dm_new_crtc_state->stream->refcount) > 1);
			dc_stream_release(dm_new_crtc_state->stream);
			dm_new_crtc_state->stream = NULL;
		}
	}

	for_each_new_plane_in_state(adev->dm.cached_state, plane, new_plane_state, i) {
		dm_new_plane_state = to_dm_plane_state(new_plane_state);
		if (dm_new_plane_state->dc_state) {
			WARN_ON(kref_read(&dm_new_plane_state->dc_state->refcount) > 1);
			dc_plane_state_release(dm_new_plane_state->dc_state);
			dm_new_plane_state->dc_state = NULL;
		}
	}

	ret = drm_atomic_helper_resume(ddev, adev->dm.cached_state);

	drm_atomic_state_put(adev->dm.cached_state);
@@ -4662,10 +4690,8 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev,
	bool lock_and_validation_needed = false;

	ret = drm_atomic_helper_check_modeset(dev, state);
	if (ret) {
		DRM_ERROR("Atomic state validation failed with error :%d !\n", ret);
		return ret;
	}
	if (ret)
		goto fail;

	/*
	 * legacy_cursor_update should be made false for SoC's having
@@ -4782,11 +4808,11 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev,

fail:
	if (ret == -EDEADLK)
		DRM_DEBUG_DRIVER("Atomic check stopped due to to deadlock.\n");
		DRM_DEBUG_DRIVER("Atomic check stopped to avoid deadlock.\n");
	else if (ret == -EINTR || ret == -EAGAIN || ret == -ERESTARTSYS)
		DRM_DEBUG_DRIVER("Atomic check stopped due to to signal.\n");
		DRM_DEBUG_DRIVER("Atomic check stopped due to signal.\n");
	else
		DRM_ERROR("Atomic check failed with err: %d \n", ret);
		DRM_DEBUG_DRIVER("Atomic check failed with err: %d \n", ret);

	return ret;
}
+2 −2
Original line number Diff line number Diff line
@@ -72,7 +72,7 @@ struct irq_list_head {
	struct work_struct work;
};

#ifdef ENABLE_FBC
#if defined(CONFIG_DRM_AMD_DC_FBC)
struct dm_comressor_info {
	void *cpu_addr;
	struct amdgpu_bo *bo_ptr;
@@ -142,7 +142,7 @@ struct amdgpu_display_manager {
	 * Caches device atomic state for suspend/resume
	 */
	struct drm_atomic_state *cached_state;
#ifdef ENABLE_FBC
#if defined(CONFIG_DRM_AMD_DC_FBC)
	struct dm_comressor_info compressor;
#endif
};
+11 −1
Original line number Diff line number Diff line
@@ -245,6 +245,16 @@ static const struct drm_connector_helper_funcs dm_dp_mst_connector_helper_funcs
	.best_encoder = dm_mst_best_encoder,
};

static void amdgpu_dm_encoder_destroy(struct drm_encoder *encoder)
{
	drm_encoder_cleanup(encoder);
	kfree(encoder);
}

static const struct drm_encoder_funcs amdgpu_dm_encoder_funcs = {
	.destroy = amdgpu_dm_encoder_destroy,
};

static struct amdgpu_encoder *
dm_dp_create_fake_mst_encoder(struct amdgpu_dm_connector *connector)
{
@@ -268,7 +278,7 @@ dm_dp_create_fake_mst_encoder(struct amdgpu_dm_connector *connector)
	drm_encoder_init(
		dev,
		&amdgpu_encoder->base,
		NULL,
		&amdgpu_dm_encoder_funcs,
		DRM_MODE_ENCODER_DPMST,
		NULL);

+39 −3
Original line number Diff line number Diff line
@@ -619,6 +619,39 @@ static bool construct(struct dc *dc,
	return false;
}

static void disable_dangling_plane(struct dc *dc, struct dc_state *context)
{
	int i, j;
	struct dc_state *dangling_context = dc_create_state();
	struct dc_state *current_ctx;

	if (dangling_context == NULL)
		return;

	dc_resource_state_copy_construct(dc->current_state, dangling_context);

	for (i = 0; i < dc->res_pool->pipe_count; i++) {
		struct dc_stream_state *old_stream =
				dc->current_state->res_ctx.pipe_ctx[i].stream;
		bool should_disable = true;

		for (j = 0; j < context->stream_count; j++) {
			if (old_stream == context->streams[j]) {
				should_disable = false;
				break;
			}
		}
		if (should_disable && old_stream) {
			dc_rem_all_planes_for_stream(dc, old_stream, dangling_context);
			dc->hwss.apply_ctx_for_surface(dc, old_stream, 0, dangling_context);
		}
	}

	current_ctx = dc->current_state;
	dc->current_state = dangling_context;
	dc_release_state(current_ctx);
}

/*******************************************************************************
 * Public functions
 ******************************************************************************/
@@ -801,6 +834,8 @@ static enum dc_status dc_commit_state_no_check(struct dc *dc, struct dc_state *c
	int i, j, k, l;
	struct dc_stream_state *dc_streams[MAX_STREAMS] = {0};

	disable_dangling_plane(dc, context);

	for (i = 0; i < context->stream_count; i++)
		dc_streams[i] =  context->streams[i];

@@ -830,8 +865,6 @@ static enum dc_status dc_commit_state_no_check(struct dc *dc, struct dc_state *c
			}
		}



		CONN_MSG_MODE(sink->link, "{%dx%d, %dx%d@%dKhz}",
				context->streams[i]->timing.h_addressable,
				context->streams[i]->timing.v_addressable,
@@ -1414,8 +1447,11 @@ void dc_commit_updates_for_stream(struct dc *dc,
		/* 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)
		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 (update_type >= UPDATE_TYPE_MED) {
			for (j = 0; j < dc->res_pool->pipe_count; j++) {
+4 −2
Original line number Diff line number Diff line
@@ -2318,9 +2318,11 @@ void core_link_enable_stream(

			/* Abort stream enable *unless* the failure was due to
			 * DP link training - some DP monitors will recover and
			 * show the stream anyway.
			 * show the stream anyway. But MST displays can't proceed
			 * without link training.
			 */
			if (status != DC_FAIL_DP_LINK_TRAINING) {
			if (status != DC_FAIL_DP_LINK_TRAINING ||
					pipe_ctx->stream->signal == SIGNAL_TYPE_DISPLAY_PORT_MST) {
				BREAK_TO_DEBUGGER();
				return;
			}
Loading