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

Commit f151f57b authored by Greg Kroah-Hartman's avatar Greg Kroah-Hartman
Browse files

Merge tag 'drm-fixes-2018-09-28' of git://anongit.freedesktop.org/drm/drm

Dave writes:
  "drm fixes for 4.19-rc6

   Looks like a pretty normal week for graphics,

   core: syncobj fix, panel link regression revert
   amd: suspend/resume fixes, EDID emulation fix
   mali-dp: NV12 writeback and vblank reset fixes
   etnaviv: DMA setup fix"

* tag 'drm-fixes-2018-09-28' of git://anongit.freedesktop.org/drm/drm:
  drm/amd/display: Fix Edid emulation for linux
  drm/amd/display: Fix Vega10 lightup on S3 resume
  drm/amdgpu: Fix vce work queue was not cancelled when suspend
  Revert "drm/panel: Add device_link from panel device to DRM device"
  drm/syncobj: Don't leak fences when WAIT_FOR_SUBMIT is set
  drm/malidp: Fix writeback in NV12
  drm: mali-dp: Call drm_crtc_vblank_reset on device init
  drm/etnaviv: add DMA configuration for etnaviv platform device
parents ed1b3f4c fcb1349a
Loading
Loading
Loading
Loading
+2 −1
Original line number Original line Diff line number Diff line
@@ -258,6 +258,8 @@ int amdgpu_vce_suspend(struct amdgpu_device *adev)
{
{
	int i;
	int i;


	cancel_delayed_work_sync(&adev->vce.idle_work);

	if (adev->vce.vcpu_bo == NULL)
	if (adev->vce.vcpu_bo == NULL)
		return 0;
		return 0;


@@ -268,7 +270,6 @@ int amdgpu_vce_suspend(struct amdgpu_device *adev)
	if (i == AMDGPU_MAX_VCE_HANDLES)
	if (i == AMDGPU_MAX_VCE_HANDLES)
		return 0;
		return 0;


	cancel_delayed_work_sync(&adev->vce.idle_work);
	/* TODO: suspending running encoding sessions isn't supported */
	/* TODO: suspending running encoding sessions isn't supported */
	return -EINVAL;
	return -EINVAL;
}
}
+2 −2
Original line number Original line Diff line number Diff line
@@ -153,11 +153,11 @@ int amdgpu_vcn_suspend(struct amdgpu_device *adev)
	unsigned size;
	unsigned size;
	void *ptr;
	void *ptr;


	cancel_delayed_work_sync(&adev->vcn.idle_work);

	if (adev->vcn.vcpu_bo == NULL)
	if (adev->vcn.vcpu_bo == NULL)
		return 0;
		return 0;


	cancel_delayed_work_sync(&adev->vcn.idle_work);

	size = amdgpu_bo_size(adev->vcn.vcpu_bo);
	size = amdgpu_bo_size(adev->vcn.vcpu_bo);
	ptr = adev->vcn.cpu_addr;
	ptr = adev->vcn.cpu_addr;


+134 −5
Original line number Original line Diff line number Diff line
@@ -641,6 +641,87 @@ amdgpu_dm_find_first_crtc_matching_connector(struct drm_atomic_state *state,
	return NULL;
	return NULL;
}
}


static void emulated_link_detect(struct dc_link *link)
{
	struct dc_sink_init_data sink_init_data = { 0 };
	struct display_sink_capability sink_caps = { 0 };
	enum dc_edid_status edid_status;
	struct dc_context *dc_ctx = link->ctx;
	struct dc_sink *sink = NULL;
	struct dc_sink *prev_sink = NULL;

	link->type = dc_connection_none;
	prev_sink = link->local_sink;

	if (prev_sink != NULL)
		dc_sink_retain(prev_sink);

	switch (link->connector_signal) {
	case SIGNAL_TYPE_HDMI_TYPE_A: {
		sink_caps.transaction_type = DDC_TRANSACTION_TYPE_I2C;
		sink_caps.signal = SIGNAL_TYPE_HDMI_TYPE_A;
		break;
	}

	case SIGNAL_TYPE_DVI_SINGLE_LINK: {
		sink_caps.transaction_type = DDC_TRANSACTION_TYPE_I2C;
		sink_caps.signal = SIGNAL_TYPE_DVI_SINGLE_LINK;
		break;
	}

	case SIGNAL_TYPE_DVI_DUAL_LINK: {
		sink_caps.transaction_type = DDC_TRANSACTION_TYPE_I2C;
		sink_caps.signal = SIGNAL_TYPE_DVI_DUAL_LINK;
		break;
	}

	case SIGNAL_TYPE_LVDS: {
		sink_caps.transaction_type = DDC_TRANSACTION_TYPE_I2C;
		sink_caps.signal = SIGNAL_TYPE_LVDS;
		break;
	}

	case SIGNAL_TYPE_EDP: {
		sink_caps.transaction_type =
			DDC_TRANSACTION_TYPE_I2C_OVER_AUX;
		sink_caps.signal = SIGNAL_TYPE_EDP;
		break;
	}

	case SIGNAL_TYPE_DISPLAY_PORT: {
		sink_caps.transaction_type =
			DDC_TRANSACTION_TYPE_I2C_OVER_AUX;
		sink_caps.signal = SIGNAL_TYPE_VIRTUAL;
		break;
	}

	default:
		DC_ERROR("Invalid connector type! signal:%d\n",
			link->connector_signal);
		return;
	}

	sink_init_data.link = link;
	sink_init_data.sink_signal = sink_caps.signal;

	sink = dc_sink_create(&sink_init_data);
	if (!sink) {
		DC_ERROR("Failed to create sink!\n");
		return;
	}

	link->local_sink = sink;

	edid_status = dm_helpers_read_local_edid(
			link->ctx,
			link,
			sink);

	if (edid_status != EDID_OK)
		DC_ERROR("Failed to read EDID");

}

static int dm_resume(void *handle)
static int dm_resume(void *handle)
{
{
	struct amdgpu_device *adev = handle;
	struct amdgpu_device *adev = handle;
@@ -654,6 +735,7 @@ static int dm_resume(void *handle)
	struct drm_plane *plane;
	struct drm_plane *plane;
	struct drm_plane_state *new_plane_state;
	struct drm_plane_state *new_plane_state;
	struct dm_plane_state *dm_new_plane_state;
	struct dm_plane_state *dm_new_plane_state;
	enum dc_connection_type new_connection_type = dc_connection_none;
	int ret;
	int ret;
	int i;
	int i;


@@ -684,6 +766,12 @@ static int dm_resume(void *handle)
			continue;
			continue;


		mutex_lock(&aconnector->hpd_lock);
		mutex_lock(&aconnector->hpd_lock);
		if (!dc_link_detect_sink(aconnector->dc_link, &new_connection_type))
			DRM_ERROR("KMS: Failed to detect connector\n");

		if (aconnector->base.force && new_connection_type == dc_connection_none)
			emulated_link_detect(aconnector->dc_link);
		else
			dc_link_detect(aconnector->dc_link, DETECT_REASON_HPD);
			dc_link_detect(aconnector->dc_link, DETECT_REASON_HPD);


		if (aconnector->fake_enable && aconnector->dc_link->local_sink)
		if (aconnector->fake_enable && aconnector->dc_link->local_sink)
@@ -922,6 +1010,7 @@ static void handle_hpd_irq(void *param)
	struct amdgpu_dm_connector *aconnector = (struct amdgpu_dm_connector *)param;
	struct amdgpu_dm_connector *aconnector = (struct amdgpu_dm_connector *)param;
	struct drm_connector *connector = &aconnector->base;
	struct drm_connector *connector = &aconnector->base;
	struct drm_device *dev = connector->dev;
	struct drm_device *dev = connector->dev;
	enum dc_connection_type new_connection_type = dc_connection_none;


	/* In case of failure or MST no need to update connector status or notify the OS
	/* In case of failure or MST no need to update connector status or notify the OS
	 * since (for MST case) MST does this in it's own context.
	 * since (for MST case) MST does this in it's own context.
@@ -931,7 +1020,21 @@ static void handle_hpd_irq(void *param)
	if (aconnector->fake_enable)
	if (aconnector->fake_enable)
		aconnector->fake_enable = false;
		aconnector->fake_enable = false;


	if (dc_link_detect(aconnector->dc_link, DETECT_REASON_HPD)) {
	if (!dc_link_detect_sink(aconnector->dc_link, &new_connection_type))
		DRM_ERROR("KMS: Failed to detect connector\n");

	if (aconnector->base.force && new_connection_type == dc_connection_none) {
		emulated_link_detect(aconnector->dc_link);


		drm_modeset_lock_all(dev);
		dm_restore_drm_connector_state(dev, connector);
		drm_modeset_unlock_all(dev);

		if (aconnector->base.force == DRM_FORCE_UNSPECIFIED)
			drm_kms_helper_hotplug_event(dev);

	} else if (dc_link_detect(aconnector->dc_link, DETECT_REASON_HPD)) {
		amdgpu_dm_update_connector_after_detect(aconnector);
		amdgpu_dm_update_connector_after_detect(aconnector);




@@ -1031,6 +1134,7 @@ static void handle_hpd_rx_irq(void *param)
	struct drm_device *dev = connector->dev;
	struct drm_device *dev = connector->dev;
	struct dc_link *dc_link = aconnector->dc_link;
	struct dc_link *dc_link = aconnector->dc_link;
	bool is_mst_root_connector = aconnector->mst_mgr.mst_state;
	bool is_mst_root_connector = aconnector->mst_mgr.mst_state;
	enum dc_connection_type new_connection_type = dc_connection_none;


	/* TODO:Temporary add mutex to protect hpd interrupt not have a gpio
	/* TODO:Temporary add mutex to protect hpd interrupt not have a gpio
	 * conflict, after implement i2c helper, this mutex should be
	 * conflict, after implement i2c helper, this mutex should be
@@ -1042,7 +1146,24 @@ static void handle_hpd_rx_irq(void *param)
	if (dc_link_handle_hpd_rx_irq(dc_link, NULL, NULL) &&
	if (dc_link_handle_hpd_rx_irq(dc_link, NULL, NULL) &&
			!is_mst_root_connector) {
			!is_mst_root_connector) {
		/* Downstream Port status changed. */
		/* Downstream Port status changed. */
		if (dc_link_detect(dc_link, DETECT_REASON_HPDRX)) {
		if (!dc_link_detect_sink(dc_link, &new_connection_type))
			DRM_ERROR("KMS: Failed to detect connector\n");

		if (aconnector->base.force && new_connection_type == dc_connection_none) {
			emulated_link_detect(dc_link);

			if (aconnector->fake_enable)
				aconnector->fake_enable = false;

			amdgpu_dm_update_connector_after_detect(aconnector);


			drm_modeset_lock_all(dev);
			dm_restore_drm_connector_state(dev, connector);
			drm_modeset_unlock_all(dev);

			drm_kms_helper_hotplug_event(dev);
		} else if (dc_link_detect(dc_link, DETECT_REASON_HPDRX)) {


			if (aconnector->fake_enable)
			if (aconnector->fake_enable)
				aconnector->fake_enable = false;
				aconnector->fake_enable = false;
@@ -1433,6 +1554,7 @@ static int amdgpu_dm_initialize_drm_device(struct amdgpu_device *adev)
	struct amdgpu_mode_info *mode_info = &adev->mode_info;
	struct amdgpu_mode_info *mode_info = &adev->mode_info;
	uint32_t link_cnt;
	uint32_t link_cnt;
	int32_t total_overlay_planes, total_primary_planes;
	int32_t total_overlay_planes, total_primary_planes;
	enum dc_connection_type new_connection_type = dc_connection_none;


	link_cnt = dm->dc->caps.max_links;
	link_cnt = dm->dc->caps.max_links;
	if (amdgpu_dm_mode_config_init(dm->adev)) {
	if (amdgpu_dm_mode_config_init(dm->adev)) {
@@ -1499,7 +1621,14 @@ static int amdgpu_dm_initialize_drm_device(struct amdgpu_device *adev)


		link = dc_get_link_at_index(dm->dc, i);
		link = dc_get_link_at_index(dm->dc, i);


		if (dc_link_detect(link, DETECT_REASON_BOOT)) {
		if (!dc_link_detect_sink(link, &new_connection_type))
			DRM_ERROR("KMS: Failed to detect connector\n");

		if (aconnector->base.force && new_connection_type == dc_connection_none) {
			emulated_link_detect(link);
			amdgpu_dm_update_connector_after_detect(aconnector);

		} else if (dc_link_detect(link, DETECT_REASON_BOOT)) {
			amdgpu_dm_update_connector_after_detect(aconnector);
			amdgpu_dm_update_connector_after_detect(aconnector);
			register_backlight_device(dm, link);
			register_backlight_device(dm, link);
		}
		}
@@ -2494,7 +2623,7 @@ create_stream_for_sink(struct amdgpu_dm_connector *aconnector,
	if (dm_state && dm_state->freesync_capable)
	if (dm_state && dm_state->freesync_capable)
		stream->ignore_msa_timing_param = true;
		stream->ignore_msa_timing_param = true;
finish:
finish:
	if (sink && sink->sink_signal == SIGNAL_TYPE_VIRTUAL)
	if (sink && sink->sink_signal == SIGNAL_TYPE_VIRTUAL && aconnector->base.force != DRM_FORCE_ON)
		dc_sink_release(sink);
		dc_sink_release(sink);


	return stream;
	return stream;
+2 −2
Original line number Original line Diff line number Diff line
@@ -195,7 +195,7 @@ static bool program_hpd_filter(
	return result;
	return result;
}
}


static bool detect_sink(struct dc_link *link, enum dc_connection_type *type)
bool dc_link_detect_sink(struct dc_link *link, enum dc_connection_type *type)
{
{
	uint32_t is_hpd_high = 0;
	uint32_t is_hpd_high = 0;
	struct gpio *hpd_pin;
	struct gpio *hpd_pin;
@@ -604,7 +604,7 @@ bool dc_link_detect(struct dc_link *link, enum dc_detect_reason reason)
	if (link->connector_signal == SIGNAL_TYPE_VIRTUAL)
	if (link->connector_signal == SIGNAL_TYPE_VIRTUAL)
		return false;
		return false;


	if (false == detect_sink(link, &new_connection_type)) {
	if (false == dc_link_detect_sink(link, &new_connection_type)) {
		BREAK_TO_DEBUGGER();
		BREAK_TO_DEBUGGER();
		return false;
		return false;
	}
	}
+1 −0
Original line number Original line Diff line number Diff line
@@ -215,6 +215,7 @@ void dc_link_enable_hpd_filter(struct dc_link *link, bool enable);


bool dc_link_is_dp_sink_present(struct dc_link *link);
bool dc_link_is_dp_sink_present(struct dc_link *link);


bool dc_link_detect_sink(struct dc_link *link, enum dc_connection_type *type);
/*
/*
 * DPCD access interfaces
 * DPCD access interfaces
 */
 */
Loading