Commit 6aa145bc authored by Jani Nikula's avatar Jani Nikula
Browse files

drm/edid: abstract debugfs override EDID set/reset



Add functions drm_edid_override_set() and drm_edid_override_reset() to
support "edid_override" connector debugfs, and to hide the details about
it in drm_edid.c. No functional changes at this time.

Also note in the connector.override_edid flag kernel-doc that this is
only supposed to be modified by the code doing debugfs EDID override
handling. Currently, it is still being modified by amdgpu in
create_eml_sink() and handle_edid_mgmt() for reasons unknown. This was
added in commit 4562236b ("drm/amd/dc: Add dc display driver (v2)")
and later moved to amdgpu_dm.c in commit e7b07cee ("drm/amd/display:
Merge amdgpu_dm_types and amdgpu_dm").

Signed-off-by: default avatarJani Nikula <jani.nikula@intel.com>
Reviewed-by: default avatarVille Syrjälä <ville.syrjala@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/8f6b4001630cafac5f44aa5913429ac9979743d2.1656494768.git.jani.nikula@intel.com
parent f999b37e
Loading
Loading
Loading
Loading
+2 −0
Original line number Original line Diff line number Diff line
@@ -286,3 +286,5 @@ int drm_mode_page_flip_ioctl(struct drm_device *dev,


/* drm_edid.c */
/* drm_edid.c */
void drm_mode_fixup_1366x768(struct drm_display_mode *mode);
void drm_mode_fixup_1366x768(struct drm_display_mode *mode);
int drm_edid_override_set(struct drm_connector *connector, const void *edid, size_t size);
int drm_edid_override_reset(struct drm_connector *connector);
+5 −16
Original line number Original line Diff line number Diff line
@@ -350,31 +350,20 @@ static ssize_t edid_write(struct file *file, const char __user *ubuf,
	struct seq_file *m = file->private_data;
	struct seq_file *m = file->private_data;
	struct drm_connector *connector = m->private;
	struct drm_connector *connector = m->private;
	char *buf;
	char *buf;
	struct edid *edid;
	int ret;
	int ret;


	buf = memdup_user(ubuf, len);
	buf = memdup_user(ubuf, len);
	if (IS_ERR(buf))
	if (IS_ERR(buf))
		return PTR_ERR(buf);
		return PTR_ERR(buf);


	edid = (struct edid *) buf;
	if (len == 5 && !strncmp(buf, "reset", 5))

		ret = drm_edid_override_reset(connector);
	if (len == 5 && !strncmp(buf, "reset", 5)) {
	else
		connector->override_edid = false;
		ret = drm_edid_override_set(connector, buf, len);
		ret = drm_connector_update_edid_property(connector, NULL);
	} else if (len < EDID_LENGTH ||
		   EDID_LENGTH * (1 + edid->extensions) > len)
		ret = -EINVAL;
	else {
		connector->override_edid = false;
		ret = drm_connector_update_edid_property(connector, edid);
		if (!ret)
			connector->override_edid = true;
	}


	kfree(buf);
	kfree(buf);


	return (ret) ? ret : len;
	return ret ? ret : len;
}
}


/*
/*
+26 −0
Original line number Original line Diff line number Diff line
@@ -2161,6 +2161,32 @@ static struct edid *drm_get_override_edid(struct drm_connector *connector,
	return IS_ERR(override) ? NULL : override;
	return IS_ERR(override) ? NULL : override;
}
}


/* For debugfs edid_override implementation */
int drm_edid_override_set(struct drm_connector *connector, const void *edid,
			  size_t size)
{
	int ret;

	if (size < EDID_LENGTH || edid_size(edid) > size)
		return -EINVAL;

	connector->override_edid = false;

	ret = drm_connector_update_edid_property(connector, edid);
	if (!ret)
		connector->override_edid = true;

	return ret;
}

/* For debugfs edid_override implementation */
int drm_edid_override_reset(struct drm_connector *connector)
{
	connector->override_edid = false;

	return drm_connector_update_edid_property(connector, NULL);
}

/**
/**
 * drm_add_override_edid_modes - add modes from override/firmware EDID
 * drm_add_override_edid_modes - add modes from override/firmware EDID
 * @connector: connector we're probing
 * @connector: connector we're probing
+5 −1
Original line number Original line Diff line number Diff line
@@ -1527,7 +1527,11 @@ struct drm_connector {
	struct drm_cmdline_mode cmdline_mode;
	struct drm_cmdline_mode cmdline_mode;
	/** @force: a DRM_FORCE_<foo> state for forced mode sets */
	/** @force: a DRM_FORCE_<foo> state for forced mode sets */
	enum drm_connector_force force;
	enum drm_connector_force force;
	/** @override_edid: has the EDID been overwritten through debugfs for testing? */
	/**
	 * @override_edid: has the EDID been overwritten through debugfs for
	 * testing? Do not modify outside of drm_edid_override_set() and
	 * drm_edid_override_reset().
	 */
	bool override_edid;
	bool override_edid;
	/** @epoch_counter: used to detect any other changes in connector, besides status */
	/** @epoch_counter: used to detect any other changes in connector, besides status */
	u64 epoch_counter;
	u64 epoch_counter;