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

Commit 8eb8ad52 authored by Dave Airlie's avatar Dave Airlie
Browse files

Merge branch 'drm-fixes-4.17' of git://people.freedesktop.org/~agd5f/linux into drm-fixes

- Fix a hang on CZ boards with EDC enabled
- Fix hangs related to DP MST handling
- Fix a deadlock in irq handling in DC

* 'drm-fixes-4.17' of git://people.freedesktop.org/~agd5f/linux:
  drm/amd/display: Check dc_sink every time in MST hotplug
  drm/amd/display: Update MST edid property every time
  drm/amd/display: Don't read EDID in atomic_check
  drm/amd/display: Disallow enabling CRTC without primary plane with FB
  drm/amd/display: Fix deadlock when flushing irq
  drm/amdgpu: set COMPUTE_PGM_RSRC1 for SGPR/VGPR clearing shaders
parents d736aa62 7ad35721
Loading
Loading
Loading
Loading
+5 −2
Original line number Original line Diff line number Diff line
@@ -1459,10 +1459,11 @@ static const u32 sgpr_init_compute_shader[] =
static const u32 vgpr_init_regs[] =
static const u32 vgpr_init_regs[] =
{
{
	mmCOMPUTE_STATIC_THREAD_MGMT_SE0, 0xffffffff,
	mmCOMPUTE_STATIC_THREAD_MGMT_SE0, 0xffffffff,
	mmCOMPUTE_RESOURCE_LIMITS, 0,
	mmCOMPUTE_RESOURCE_LIMITS, 0x1000000, /* CU_GROUP_COUNT=1 */
	mmCOMPUTE_NUM_THREAD_X, 256*4,
	mmCOMPUTE_NUM_THREAD_X, 256*4,
	mmCOMPUTE_NUM_THREAD_Y, 1,
	mmCOMPUTE_NUM_THREAD_Y, 1,
	mmCOMPUTE_NUM_THREAD_Z, 1,
	mmCOMPUTE_NUM_THREAD_Z, 1,
	mmCOMPUTE_PGM_RSRC1, 0x100004f, /* VGPRS=15 (64 logical VGPRs), SGPRS=1 (16 SGPRs), BULKY=1 */
	mmCOMPUTE_PGM_RSRC2, 20,
	mmCOMPUTE_PGM_RSRC2, 20,
	mmCOMPUTE_USER_DATA_0, 0xedcedc00,
	mmCOMPUTE_USER_DATA_0, 0xedcedc00,
	mmCOMPUTE_USER_DATA_1, 0xedcedc01,
	mmCOMPUTE_USER_DATA_1, 0xedcedc01,
@@ -1479,10 +1480,11 @@ static const u32 vgpr_init_regs[] =
static const u32 sgpr1_init_regs[] =
static const u32 sgpr1_init_regs[] =
{
{
	mmCOMPUTE_STATIC_THREAD_MGMT_SE0, 0x0f,
	mmCOMPUTE_STATIC_THREAD_MGMT_SE0, 0x0f,
	mmCOMPUTE_RESOURCE_LIMITS, 0x1000000,
	mmCOMPUTE_RESOURCE_LIMITS, 0x1000000, /* CU_GROUP_COUNT=1 */
	mmCOMPUTE_NUM_THREAD_X, 256*5,
	mmCOMPUTE_NUM_THREAD_X, 256*5,
	mmCOMPUTE_NUM_THREAD_Y, 1,
	mmCOMPUTE_NUM_THREAD_Y, 1,
	mmCOMPUTE_NUM_THREAD_Z, 1,
	mmCOMPUTE_NUM_THREAD_Z, 1,
	mmCOMPUTE_PGM_RSRC1, 0x240, /* SGPRS=9 (80 GPRS) */
	mmCOMPUTE_PGM_RSRC2, 20,
	mmCOMPUTE_PGM_RSRC2, 20,
	mmCOMPUTE_USER_DATA_0, 0xedcedc00,
	mmCOMPUTE_USER_DATA_0, 0xedcedc00,
	mmCOMPUTE_USER_DATA_1, 0xedcedc01,
	mmCOMPUTE_USER_DATA_1, 0xedcedc01,
@@ -1503,6 +1505,7 @@ static const u32 sgpr2_init_regs[] =
	mmCOMPUTE_NUM_THREAD_X, 256*5,
	mmCOMPUTE_NUM_THREAD_X, 256*5,
	mmCOMPUTE_NUM_THREAD_Y, 1,
	mmCOMPUTE_NUM_THREAD_Y, 1,
	mmCOMPUTE_NUM_THREAD_Z, 1,
	mmCOMPUTE_NUM_THREAD_Z, 1,
	mmCOMPUTE_PGM_RSRC1, 0x240, /* SGPRS=9 (80 GPRS) */
	mmCOMPUTE_PGM_RSRC2, 20,
	mmCOMPUTE_PGM_RSRC2, 20,
	mmCOMPUTE_USER_DATA_0, 0xedcedc00,
	mmCOMPUTE_USER_DATA_0, 0xedcedc00,
	mmCOMPUTE_USER_DATA_1, 0xedcedc01,
	mmCOMPUTE_USER_DATA_1, 0xedcedc01,
+9 −1
Original line number Original line Diff line number Diff line
@@ -4557,6 +4557,7 @@ static int dm_update_crtcs_state(struct dc *dc,
		struct amdgpu_dm_connector *aconnector = NULL;
		struct amdgpu_dm_connector *aconnector = NULL;
		struct drm_connector_state *new_con_state = NULL;
		struct drm_connector_state *new_con_state = NULL;
		struct dm_connector_state *dm_conn_state = NULL;
		struct dm_connector_state *dm_conn_state = NULL;
		struct drm_plane_state *new_plane_state = NULL;


		new_stream = NULL;
		new_stream = NULL;


@@ -4564,6 +4565,13 @@ static int dm_update_crtcs_state(struct dc *dc,
		dm_new_crtc_state = to_dm_crtc_state(new_crtc_state);
		dm_new_crtc_state = to_dm_crtc_state(new_crtc_state);
		acrtc = to_amdgpu_crtc(crtc);
		acrtc = to_amdgpu_crtc(crtc);


		new_plane_state = drm_atomic_get_new_plane_state(state, new_crtc_state->crtc->primary);

		if (new_crtc_state->enable && new_plane_state && !new_plane_state->fb) {
			ret = -EINVAL;
			goto fail;
		}

		aconnector = amdgpu_dm_find_first_crtc_matching_connector(state, crtc);
		aconnector = amdgpu_dm_find_first_crtc_matching_connector(state, crtc);


		/* TODO This hack should go away */
		/* TODO This hack should go away */
@@ -4760,7 +4768,7 @@ static int dm_update_planes_state(struct dc *dc,
			if (!dm_old_crtc_state->stream)
			if (!dm_old_crtc_state->stream)
				continue;
				continue;


			DRM_DEBUG_DRIVER("Disabling DRM plane: %d on DRM crtc %d\n",
			DRM_DEBUG_ATOMIC("Disabling DRM plane: %d on DRM crtc %d\n",
					plane->base.id, old_plane_crtc->base.id);
					plane->base.id, old_plane_crtc->base.id);


			if (!dc_remove_plane_from_context(
			if (!dc_remove_plane_from_context(
+3 −2
Original line number Original line Diff line number Diff line
@@ -329,14 +329,15 @@ void amdgpu_dm_irq_fini(struct amdgpu_device *adev)
{
{
	int src;
	int src;
	struct irq_list_head *lh;
	struct irq_list_head *lh;
	unsigned long irq_table_flags;
	DRM_DEBUG_KMS("DM_IRQ: releasing resources.\n");
	DRM_DEBUG_KMS("DM_IRQ: releasing resources.\n");

	for (src = 0; src < DAL_IRQ_SOURCES_NUMBER; src++) {
	for (src = 0; src < DAL_IRQ_SOURCES_NUMBER; src++) {

		DM_IRQ_TABLE_LOCK(adev, irq_table_flags);
		/* The handler was removed from the table,
		/* The handler was removed from the table,
		 * it means it is safe to flush all the 'work'
		 * it means it is safe to flush all the 'work'
		 * (because no code can schedule a new one). */
		 * (because no code can schedule a new one). */
		lh = &adev->dm.irq_handler_list_low_tab[src];
		lh = &adev->dm.irq_handler_list_low_tab[src];
		DM_IRQ_TABLE_UNLOCK(adev, irq_table_flags);
		flush_work(&lh->work);
		flush_work(&lh->work);
	}
	}
}
}
+22 −32
Original line number Original line Diff line number Diff line
@@ -161,6 +161,11 @@ dm_dp_mst_connector_destroy(struct drm_connector *connector)
	struct amdgpu_dm_connector *amdgpu_dm_connector = to_amdgpu_dm_connector(connector);
	struct amdgpu_dm_connector *amdgpu_dm_connector = to_amdgpu_dm_connector(connector);
	struct amdgpu_encoder *amdgpu_encoder = amdgpu_dm_connector->mst_encoder;
	struct amdgpu_encoder *amdgpu_encoder = amdgpu_dm_connector->mst_encoder;


	if (amdgpu_dm_connector->edid) {
		kfree(amdgpu_dm_connector->edid);
		amdgpu_dm_connector->edid = NULL;
	}

	drm_encoder_cleanup(&amdgpu_encoder->base);
	drm_encoder_cleanup(&amdgpu_encoder->base);
	kfree(amdgpu_encoder);
	kfree(amdgpu_encoder);
	drm_connector_cleanup(connector);
	drm_connector_cleanup(connector);
@@ -181,28 +186,22 @@ static const struct drm_connector_funcs dm_dp_mst_connector_funcs = {
void dm_dp_mst_dc_sink_create(struct drm_connector *connector)
void dm_dp_mst_dc_sink_create(struct drm_connector *connector)
{
{
	struct amdgpu_dm_connector *aconnector = to_amdgpu_dm_connector(connector);
	struct amdgpu_dm_connector *aconnector = to_amdgpu_dm_connector(connector);
	struct edid *edid;
	struct dc_sink *dc_sink;
	struct dc_sink *dc_sink;
	struct dc_sink_init_data init_params = {
	struct dc_sink_init_data init_params = {
			.link = aconnector->dc_link,
			.link = aconnector->dc_link,
			.sink_signal = SIGNAL_TYPE_DISPLAY_PORT_MST };
			.sink_signal = SIGNAL_TYPE_DISPLAY_PORT_MST };


	/* FIXME none of this is safe. we shouldn't touch aconnector here in
	 * atomic_check
	 */

	/*
	/*
	 * TODO: Need to further figure out why ddc.algo is NULL while MST port exists
	 * TODO: Need to further figure out why ddc.algo is NULL while MST port exists
	 */
	 */
	if (!aconnector->port || !aconnector->port->aux.ddc.algo)
	if (!aconnector->port || !aconnector->port->aux.ddc.algo)
		return;
		return;


	edid = drm_dp_mst_get_edid(connector, &aconnector->mst_port->mst_mgr, aconnector->port);
	ASSERT(aconnector->edid);

	if (!edid) {
		drm_mode_connector_update_edid_property(
			&aconnector->base,
			NULL);
		return;
	}

	aconnector->edid = edid;


	dc_sink = dc_link_add_remote_sink(
	dc_sink = dc_link_add_remote_sink(
		aconnector->dc_link,
		aconnector->dc_link,
@@ -215,9 +214,6 @@ void dm_dp_mst_dc_sink_create(struct drm_connector *connector)


	amdgpu_dm_add_sink_to_freesync_module(
	amdgpu_dm_add_sink_to_freesync_module(
			connector, aconnector->edid);
			connector, aconnector->edid);

	drm_mode_connector_update_edid_property(
					&aconnector->base, aconnector->edid);
}
}


static int dm_dp_mst_get_modes(struct drm_connector *connector)
static int dm_dp_mst_get_modes(struct drm_connector *connector)
@@ -230,10 +226,6 @@ static int dm_dp_mst_get_modes(struct drm_connector *connector)


	if (!aconnector->edid) {
	if (!aconnector->edid) {
		struct edid *edid;
		struct edid *edid;
		struct dc_sink *dc_sink;
		struct dc_sink_init_data init_params = {
				.link = aconnector->dc_link,
				.sink_signal = SIGNAL_TYPE_DISPLAY_PORT_MST };
		edid = drm_dp_mst_get_edid(connector, &aconnector->mst_port->mst_mgr, aconnector->port);
		edid = drm_dp_mst_get_edid(connector, &aconnector->mst_port->mst_mgr, aconnector->port);


		if (!edid) {
		if (!edid) {
@@ -244,11 +236,17 @@ static int dm_dp_mst_get_modes(struct drm_connector *connector)
		}
		}


		aconnector->edid = edid;
		aconnector->edid = edid;
	}


	if (!aconnector->dc_sink) {
		struct dc_sink *dc_sink;
		struct dc_sink_init_data init_params = {
				.link = aconnector->dc_link,
				.sink_signal = SIGNAL_TYPE_DISPLAY_PORT_MST };
		dc_sink = dc_link_add_remote_sink(
		dc_sink = dc_link_add_remote_sink(
			aconnector->dc_link,
			aconnector->dc_link,
			(uint8_t *)edid,
			(uint8_t *)aconnector->edid,
			(edid->extensions + 1) * EDID_LENGTH,
			(aconnector->edid->extensions + 1) * EDID_LENGTH,
			&init_params);
			&init_params);


		dc_sink->priv = aconnector;
		dc_sink->priv = aconnector;
@@ -256,11 +254,11 @@ static int dm_dp_mst_get_modes(struct drm_connector *connector)


		if (aconnector->dc_sink)
		if (aconnector->dc_sink)
			amdgpu_dm_add_sink_to_freesync_module(
			amdgpu_dm_add_sink_to_freesync_module(
					connector, edid);
					connector, aconnector->edid);
	}


	drm_mode_connector_update_edid_property(
	drm_mode_connector_update_edid_property(
						&aconnector->base, edid);
					&aconnector->base, aconnector->edid);
	}


	ret = drm_add_edid_modes(connector, aconnector->edid);
	ret = drm_add_edid_modes(connector, aconnector->edid);


@@ -424,14 +422,6 @@ static void dm_dp_destroy_mst_connector(struct drm_dp_mst_topology_mgr *mgr,
		dc_sink_release(aconnector->dc_sink);
		dc_sink_release(aconnector->dc_sink);
		aconnector->dc_sink = NULL;
		aconnector->dc_sink = NULL;
	}
	}
	if (aconnector->edid) {
		kfree(aconnector->edid);
		aconnector->edid = NULL;
	}

	drm_mode_connector_update_edid_property(
			&aconnector->base,
			NULL);


	aconnector->mst_connected = false;
	aconnector->mst_connected = false;
}
}