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

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
...@@ -405,31 +405,45 @@ static void hdmi_disconnect(struct omap_dss_device *src, ...@@ -405,31 +405,45 @@ static void hdmi_disconnect(struct omap_dss_device *src,
omapdss_device_disconnect(dst, dst->next); omapdss_device_disconnect(dst, dst->next);
} }
static int hdmi_read_edid(struct omap_dss_device *dssdev, #define MAX_EDID 512
u8 *edid, int len)
static struct edid *hdmi_read_edid(struct omap_dss_device *dssdev)
{ {
struct omap_hdmi *hdmi = dssdev_to_hdmi(dssdev); struct omap_hdmi *hdmi = dssdev_to_hdmi(dssdev);
bool need_enable; bool need_enable;
u8 *edid;
int r; int r;
edid = kzalloc(MAX_EDID, GFP_KERNEL);
if (!edid)
return NULL;
need_enable = hdmi->core_enabled == false; need_enable = hdmi->core_enabled == false;
if (need_enable) { if (need_enable) {
r = hdmi4_core_enable(&hdmi->core); r = hdmi4_core_enable(&hdmi->core);
if (r) if (r) {
return 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) if (need_enable)
hdmi4_core_disable(&hdmi->core); hdmi4_core_disable(&hdmi->core);
return r; return (struct edid *)edid;
} }
static void hdmi_lost_hotplug(struct omap_dss_device *dssdev) static void hdmi_lost_hotplug(struct omap_dss_device *dssdev)
......
...@@ -410,27 +410,39 @@ static void hdmi_disconnect(struct omap_dss_device *src, ...@@ -410,27 +410,39 @@ static void hdmi_disconnect(struct omap_dss_device *src,
omapdss_device_disconnect(dst, dst->next); omapdss_device_disconnect(dst, dst->next);
} }
static int hdmi_read_edid(struct omap_dss_device *dssdev, #define MAX_EDID 512
u8 *edid, int len)
static struct edid *hdmi_read_edid(struct omap_dss_device *dssdev)
{ {
struct omap_hdmi *hdmi = dssdev_to_hdmi(dssdev); struct omap_hdmi *hdmi = dssdev_to_hdmi(dssdev);
bool need_enable; bool need_enable;
u8 *edid;
int r; int r;
edid = kzalloc(MAX_EDID, GFP_KERNEL);
if (!edid)
return NULL;
need_enable = hdmi->core_enabled == false; need_enable = hdmi->core_enabled == false;
if (need_enable) { if (need_enable) {
r = hdmi_core_enable(hdmi); r = hdmi_core_enable(hdmi);
if (r) if (r) {
return 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) if (need_enable)
hdmi_core_disable(hdmi); hdmi_core_disable(hdmi);
return r; return (struct edid *)edid;
} }
static int hdmi_set_infoframe(struct omap_dss_device *dssdev, static int hdmi_set_infoframe(struct omap_dss_device *dssdev,
......
...@@ -367,7 +367,7 @@ struct omap_dss_device_ops { ...@@ -367,7 +367,7 @@ struct omap_dss_device_ops {
void *cb_data); void *cb_data);
void (*unregister_hpd_cb)(struct omap_dss_device *dssdev); 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, int (*get_modes)(struct omap_dss_device *dssdev,
struct drm_connector *connector); struct drm_connector *connector);
......
...@@ -153,25 +153,19 @@ static void omap_connector_destroy(struct drm_connector *connector) ...@@ -153,25 +153,19 @@ static void omap_connector_destroy(struct drm_connector *connector)
kfree(omap_connector); kfree(omap_connector);
} }
#define MAX_EDID 512
static int omap_connector_get_modes_edid(struct drm_connector *connector, static int omap_connector_get_modes_edid(struct drm_connector *connector,
struct omap_dss_device *dssdev) struct omap_dss_device *dssdev)
{ {
enum drm_connector_status status; enum drm_connector_status status;
void *edid; struct edid *edid;
int n; int n;
status = omap_connector_detect(connector, false); status = omap_connector_detect(connector, false);
if (status != connector_status_connected) if (status != connector_status_connected)
goto no_edid; goto no_edid;
edid = kzalloc(MAX_EDID, GFP_KERNEL); edid = dssdev->ops->read_edid(dssdev);
if (!edid) if (!edid || !drm_edid_is_valid(edid)) {
goto no_edid;
if (dssdev->ops->read_edid(dssdev, edid, MAX_EDID) <= 0 ||
!drm_edid_is_valid(edid)) {
kfree(edid); kfree(edid);
goto no_edid; goto no_edid;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment