Commit 0fe37173 authored by Laurent Pinchart's avatar Laurent Pinchart Committed by Tomi Valkeinen
Browse files

drm/omap: hdmi: Allocate EDID in the .read_edid() operation



Bring the omapdss-specific .read_edid() operation in sync with the
drm_bridge .get_edid() operation to ease code reuse.

Signed-off-by: default avatarLaurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: default avatarTomi Valkeinen <tomi.valkeinen@ti.com>
Tested-by: default avatarSebastian Reichel <sebastian.reichel@collabora.com>
Reviewed-by: default avatarSebastian Reichel <sebastian.reichel@collabora.com>
Signed-off-by: default avatarTomi Valkeinen <tomi.valkeinen@ti.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20200226112514.12455-29-laurent.pinchart@ideasonboard.com
parent db0fefd1
Loading
Loading
Loading
Loading
+25 −11
Original line number Diff line number Diff line
@@ -405,31 +405,45 @@ static void hdmi_disconnect(struct omap_dss_device *src,
	omapdss_device_disconnect(dst, dst->next);
}

static int hdmi_read_edid(struct omap_dss_device *dssdev,
		u8 *edid, int len)
#define MAX_EDID	512

static struct edid *hdmi_read_edid(struct omap_dss_device *dssdev)
{
	struct omap_hdmi *hdmi = dssdev_to_hdmi(dssdev);
	bool need_enable;
	u8 *edid;
	int r;

	edid = kzalloc(MAX_EDID, GFP_KERNEL);
	if (!edid)
		return NULL;

	need_enable = hdmi->core_enabled == false;

	if (need_enable) {
		r = hdmi4_core_enable(&hdmi->core);
		if (r)
			return r;
		if (r) {
			kfree(edid);
			return NULL;
		}
	}

	r = read_edid(hdmi, edid, MAX_EDID);
	if (r < 0) {
		kfree(edid);
		edid = NULL;
	} else {
		unsigned int cec_addr;

		cec_addr = r >= 256 ? cec_get_edid_phys_addr(edid, r, NULL)
			 : CEC_PHYS_ADDR_INVALID;
		hdmi4_cec_set_phys_addr(&hdmi->core, cec_addr);
	}

	r = read_edid(hdmi, edid, len);
	if (r >= 256)
		hdmi4_cec_set_phys_addr(&hdmi->core,
					cec_get_edid_phys_addr(edid, r, NULL));
	else
		hdmi4_cec_set_phys_addr(&hdmi->core, CEC_PHYS_ADDR_INVALID);
	if (need_enable)
		hdmi4_core_disable(&hdmi->core);

	return r;
	return (struct edid *)edid;
}

static void hdmi_lost_hotplug(struct omap_dss_device *dssdev)
+18 −6
Original line number Diff line number Diff line
@@ -410,27 +410,39 @@ static void hdmi_disconnect(struct omap_dss_device *src,
	omapdss_device_disconnect(dst, dst->next);
}

static int hdmi_read_edid(struct omap_dss_device *dssdev,
		u8 *edid, int len)
#define MAX_EDID	512

static struct edid *hdmi_read_edid(struct omap_dss_device *dssdev)
{
	struct omap_hdmi *hdmi = dssdev_to_hdmi(dssdev);
	bool need_enable;
	u8 *edid;
	int r;

	edid = kzalloc(MAX_EDID, GFP_KERNEL);
	if (!edid)
		return NULL;

	need_enable = hdmi->core_enabled == false;

	if (need_enable) {
		r = hdmi_core_enable(hdmi);
		if (r)
			return r;
		if (r) {
			kfree(edid);
			return NULL;
		}
	}

	r = read_edid(hdmi, edid, len);
	r = read_edid(hdmi, edid, MAX_EDID);
	if (r < 0) {
		kfree(edid);
		edid = NULL;
	}

	if (need_enable)
		hdmi_core_disable(hdmi);

	return r;
	return (struct edid *)edid;
}

static int hdmi_set_infoframe(struct omap_dss_device *dssdev,
+1 −1
Original line number Diff line number Diff line
@@ -367,7 +367,7 @@ struct omap_dss_device_ops {
				void *cb_data);
	void (*unregister_hpd_cb)(struct omap_dss_device *dssdev);

	int (*read_edid)(struct omap_dss_device *dssdev, u8 *buf, int len);
	struct edid *(*read_edid)(struct omap_dss_device *dssdev);

	int (*get_modes)(struct omap_dss_device *dssdev,
			 struct drm_connector *connector);
+3 −9
Original line number Diff line number Diff line
@@ -153,25 +153,19 @@ static void omap_connector_destroy(struct drm_connector *connector)
	kfree(omap_connector);
}

#define MAX_EDID  512

static int omap_connector_get_modes_edid(struct drm_connector *connector,
					 struct omap_dss_device *dssdev)
{
	enum drm_connector_status status;
	void *edid;
	struct edid *edid;
	int n;

	status = omap_connector_detect(connector, false);
	if (status != connector_status_connected)
		goto no_edid;

	edid = kzalloc(MAX_EDID, GFP_KERNEL);
	if (!edid)
		goto no_edid;

	if (dssdev->ops->read_edid(dssdev, edid, MAX_EDID) <= 0 ||
	    !drm_edid_is_valid(edid)) {
	edid = dssdev->ops->read_edid(dssdev);
	if (!edid || !drm_edid_is_valid(edid)) {
		kfree(edid);
		goto no_edid;
	}