Commit 2b1966c6 authored by Dave Airlie's avatar Dave Airlie
Browse files

Merge tag 'drm-misc-next-2022-10-27' of git://anongit.freedesktop.org/drm/drm-misc into drm-next



drm-misc-next for 6.2:

UAPI Changes:

Cross-subsystem Changes:

Core Changes:
- connector: Send hotplug event on cleanup
- edid: logging/debug improvements
- plane_helper: Improve tests

Driver Changes:
- bridge:
  - it6505: Synchronization improvements
- panel:
  - panel-edp: Add INX N116BGE-EA2 C2 and C4 support.
- nouveau: Fix page-fault handling
- vmwgfx: fb and cursor refactoring, convert to generic hashtable

Signed-off-by: default avatarDave Airlie <airlied@redhat.com>

From: Maxime Ripard <maxime@cerno.tech>
Link: https://patchwork.freedesktop.org/patch/msgid/20221027073407.c2tlaczvzjrnzazi@houat
parents 7f7a942c e1e7bc48
Loading
Loading
Loading
Loading
+0 −11
Original line number Diff line number Diff line
@@ -651,17 +651,6 @@ See drivers/gpu/drm/amd/display/TODO for tasks.

Contact: Harry Wentland, Alex Deucher

vmwgfx: Replace hashtable with Linux' implementation
----------------------------------------------------

The vmwgfx driver uses its own hashtable implementation. Replace the
code with Linux' implementation and update the callers. It's mostly a
refactoring task, but the interfaces are different.

Contact: Zack Rusin, Thomas Zimmermann <tzimmermann@suse.de>

Level: Intermediate

Bootsplash
==========

+0 −3
Original line number Diff line number Diff line
@@ -6108,7 +6108,6 @@ static void create_eml_sink(struct amdgpu_dm_connector *aconnector)
				aconnector->base.name);

		aconnector->base.force = DRM_FORCE_OFF;
		aconnector->base.override_edid = false;
		return;
	}

@@ -6143,8 +6142,6 @@ static void handle_edid_mgmt(struct amdgpu_dm_connector *aconnector)
		link->verified_link_cap.link_rate = LINK_RATE_HIGH2;
	}


	aconnector->base.override_edid = true;
	create_eml_sink(aconnector);
}

+51 −55
Original line number Diff line number Diff line
@@ -412,6 +412,7 @@ struct it6505 {
	 * Mutex protects extcon and interrupt functions from interfering
	 * each other.
	 */
	struct mutex irq_lock;
	struct mutex extcon_lock;
	struct mutex mode_lock; /* used to bridge_detect */
	struct mutex aux_lock; /* used to aux data transfers */
@@ -440,7 +441,7 @@ struct it6505 {
	enum hdcp_state hdcp_status;
	struct delayed_work hdcp_work;
	struct work_struct hdcp_wait_ksv_list;
	struct completion wait_edid_complete;
	struct completion extcon_completion;
	u8 auto_train_retry;
	bool hdcp_desired;
	bool is_repeater;
@@ -725,28 +726,6 @@ static void it6505_calc_video_info(struct it6505 *it6505)
			     DRM_MODE_ARG(&it6505->video_info));
}

static int it6505_drm_dp_link_probe(struct drm_dp_aux *aux,
				    struct it6505_drm_dp_link *link)
{
	u8 values[3];
	int err;

	memset(link, 0, sizeof(*link));

	err = drm_dp_dpcd_read(aux, DP_DPCD_REV, values, sizeof(values));
	if (err < 0)
		return err;

	link->revision = values[0];
	link->rate = drm_dp_bw_code_to_link_rate(values[1]);
	link->num_lanes = values[2] & DP_MAX_LANE_COUNT_MASK;

	if (values[2] & DP_ENHANCED_FRAME_CAP)
		link->capabilities = DP_ENHANCED_FRAME_CAP;

	return 0;
}

static int it6505_drm_dp_link_set_power(struct drm_dp_aux *aux,
					struct it6505_drm_dp_link *link,
					u8 mode)
@@ -1456,11 +1435,19 @@ static void it6505_parse_link_capabilities(struct it6505 *it6505)
	int bcaps;

	if (it6505->dpcd[0] == 0) {
		it6505_aux_on(it6505);
		it6505_get_dpcd(it6505, DP_DPCD_REV, it6505->dpcd,
				ARRAY_SIZE(it6505->dpcd));
		dev_err(dev, "DPCD is not initialized");
		return;
	}

	memset(link, 0, sizeof(*link));

	link->revision = it6505->dpcd[0];
	link->rate = drm_dp_bw_code_to_link_rate(it6505->dpcd[1]);
	link->num_lanes = it6505->dpcd[2] & DP_MAX_LANE_COUNT_MASK;

	if (it6505->dpcd[2] & DP_ENHANCED_FRAME_CAP)
		link->capabilities = DP_ENHANCED_FRAME_CAP;

	DRM_DEV_DEBUG_DRIVER(dev, "DPCD Rev.: %d.%d",
			     link->revision >> 4, link->revision & 0x0F);

@@ -2323,19 +2310,32 @@ static int it6505_process_hpd_irq(struct it6505 *it6505)
static void it6505_irq_hpd(struct it6505 *it6505)
{
	struct device *dev = &it6505->client->dev;
	int dp_sink_count;

	it6505->hpd_state = it6505_get_sink_hpd_status(it6505);
	DRM_DEV_DEBUG_DRIVER(dev, "hpd change interrupt, change to %s",
			     it6505->hpd_state ? "high" : "low");

	if (it6505->bridge.dev)
		drm_helper_hpd_irq_event(it6505->bridge.dev);
	if (it6505->hpd_state) {
		wait_for_completion_timeout(&it6505->extcon_completion,
					    msecs_to_jiffies(1000));
		it6505_aux_on(it6505);
		if (it6505->dpcd[0] == 0) {
			it6505_get_dpcd(it6505, DP_DPCD_REV, it6505->dpcd,
					ARRAY_SIZE(it6505->dpcd));
			it6505_variable_config(it6505);
			it6505_parse_link_capabilities(it6505);
		}
		it6505->auto_train_retry = AUTO_TRAIN_RETRY;

		it6505_drm_dp_link_set_power(&it6505->aux, &it6505->link,
					     DP_SET_POWER_D0);
		dp_sink_count = it6505_dpcd_read(it6505, DP_SINK_COUNT);
		it6505->sink_count = DP_GET_SINK_COUNT(dp_sink_count);

		DRM_DEV_DEBUG_DRIVER(dev, "it6505->sink_count: %d",
				     it6505->sink_count);

	if (it6505->hpd_state) {
		wait_for_completion_timeout(&it6505->wait_edid_complete,
					    msecs_to_jiffies(6000));
		it6505_lane_termination_on(it6505);
		it6505_lane_power_on(it6505);

@@ -2363,6 +2363,9 @@ static void it6505_irq_hpd(struct it6505 *it6505)
		it6505_lane_off(it6505);
		it6505_link_reset_step_train(it6505);
	}

	if (it6505->bridge.dev)
		drm_helper_hpd_irq_event(it6505->bridge.dev);
}

static void it6505_irq_hpd_irq(struct it6505 *it6505)
@@ -2491,8 +2494,7 @@ static irqreturn_t it6505_int_threaded_handler(int unused, void *data)
	};
	int int_status[3], i;

	msleep(100);
	mutex_lock(&it6505->extcon_lock);
	mutex_lock(&it6505->irq_lock);

	if (it6505->enable_drv_hold || !it6505->powered)
		goto unlock;
@@ -2522,7 +2524,7 @@ static irqreturn_t it6505_int_threaded_handler(int unused, void *data)
	}

unlock:
	mutex_unlock(&it6505->extcon_lock);
	mutex_unlock(&it6505->irq_lock);

	return IRQ_HANDLED;
}
@@ -2625,26 +2627,14 @@ static enum drm_connector_status it6505_detect(struct it6505 *it6505)
		goto unlock;

	if (it6505->enable_drv_hold) {
		status = it6505_get_sink_hpd_status(it6505) ?
					connector_status_connected :
		status = it6505->hpd_state ? connector_status_connected :
					     connector_status_disconnected;
		goto unlock;
	}

	if (it6505_get_sink_hpd_status(it6505)) {
		it6505_aux_on(it6505);
		it6505_drm_dp_link_probe(&it6505->aux, &it6505->link);
	if (it6505->hpd_state) {
		it6505_drm_dp_link_set_power(&it6505->aux, &it6505->link,
					     DP_SET_POWER_D0);
		it6505->auto_train_retry = AUTO_TRAIN_RETRY;

		if (it6505->dpcd[0] == 0) {
			it6505_get_dpcd(it6505, DP_DPCD_REV, it6505->dpcd,
					ARRAY_SIZE(it6505->dpcd));
			it6505_variable_config(it6505);
			it6505_parse_link_capabilities(it6505);
		}

		dp_sink_count = it6505_dpcd_read(it6505, DP_SINK_COUNT);
		it6505->sink_count = DP_GET_SINK_COUNT(dp_sink_count);
		DRM_DEV_DEBUG_DRIVER(dev, "it6505->sink_count:%d branch:%d",
@@ -2711,9 +2701,12 @@ static void it6505_extcon_work(struct work_struct *work)
		 */
		if (ret)
			it6505_poweron(it6505);

		complete_all(&it6505->extcon_completion);
	} else {
		DRM_DEV_DEBUG_DRIVER(dev, "start to power off");
		pm_runtime_put_sync(dev);
		reinit_completion(&it6505->extcon_completion);

		drm_helper_hpd_irq_event(it6505->bridge.dev);
		memset(it6505->dpcd, 0, sizeof(it6505->dpcd));
@@ -2871,10 +2864,7 @@ static int it6505_bridge_attach(struct drm_bridge *bridge,
	}

	/* Register aux channel */
	it6505->aux.name = "DP-AUX";
	it6505->aux.dev = dev;
	it6505->aux.drm_dev = bridge->dev;
	it6505->aux.transfer = it6505_aux_transfer;

	ret = drm_dp_aux_register(&it6505->aux);

@@ -3287,6 +3277,7 @@ static int it6505_i2c_probe(struct i2c_client *client,
	if (!it6505)
		return -ENOMEM;

	mutex_init(&it6505->irq_lock);
	mutex_init(&it6505->extcon_lock);
	mutex_init(&it6505->mode_lock);
	mutex_init(&it6505->aux_lock);
@@ -3342,7 +3333,7 @@ static int it6505_i2c_probe(struct i2c_client *client,
	INIT_WORK(&it6505->link_works, it6505_link_training_work);
	INIT_WORK(&it6505->hdcp_wait_ksv_list, it6505_hdcp_wait_ksv_list);
	INIT_DELAYED_WORK(&it6505->hdcp_work, it6505_hdcp_work);
	init_completion(&it6505->wait_edid_complete);
	init_completion(&it6505->extcon_completion);
	memset(it6505->dpcd, 0, sizeof(it6505->dpcd));
	it6505->powered = false;
	it6505->enable_drv_hold = DEFAULT_DRV_HOLD;
@@ -3354,6 +3345,11 @@ static int it6505_i2c_probe(struct i2c_client *client,
	debugfs_init(it6505);
	pm_runtime_enable(dev);

	it6505->aux.name = "DP-AUX";
	it6505->aux.dev = dev;
	it6505->aux.transfer = it6505_aux_transfer;
	drm_dp_aux_init(&it6505->aux);

	it6505->bridge.funcs = &it6505_bridge_funcs;
	it6505->bridge.type = DRM_MODE_CONNECTOR_DisplayPort;
	it6505->bridge.ops = DRM_BRIDGE_OP_DETECT | DRM_BRIDGE_OP_EDID |
+1 −1
Original line number Diff line number Diff line
@@ -235,7 +235,7 @@ static void drm_client_buffer_delete(struct drm_client_buffer *buffer)
{
	struct drm_device *dev = buffer->client->dev;

	drm_gem_vunmap(buffer->gem, &buffer->map);
	drm_gem_vunmap_unlocked(buffer->gem, &buffer->map);

	if (buffer->gem)
		drm_gem_object_put(buffer->gem);
+4 −0
Original line number Diff line number Diff line
@@ -274,6 +274,7 @@ static int __drm_connector_init(struct drm_device *dev,
	INIT_LIST_HEAD(&connector->probed_modes);
	INIT_LIST_HEAD(&connector->modes);
	mutex_init(&connector->mutex);
	mutex_init(&connector->edid_override_mutex);
	connector->edid_blob_ptr = NULL;
	connector->epoch_counter = 0;
	connector->tile_blob_ptr = NULL;
@@ -582,6 +583,9 @@ void drm_connector_cleanup(struct drm_connector *connector)
	mutex_destroy(&connector->mutex);

	memset(connector, 0, sizeof(*connector));

	if (dev->registered)
		drm_sysfs_hotplug_event(dev);
}
EXPORT_SYMBOL(drm_connector_cleanup);

Loading