summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarcel Ziswiler <marcel.ziswiler@toradex.com>2019-04-23 16:51:00 +0200
committerMarcel Ziswiler <marcel.ziswiler@toradex.com>2019-04-24 13:55:50 +0200
commitc97298b6d6390da9d8b9be68e65191332760d7e0 (patch)
tree8997e020dbb675bd7fa312a752c9e19c2f1af42a
parenta14005555c2da43f8094a6b317b8ec05653c0880 (diff)
drm/imx/hdp: implement optional regular ddc/edid i2c bus handling
Implement optional regular DDC/EDID I2C bus handling which may be enabled via ddc-i2c-bus device tree property. Signed-off-by: Marcel Ziswiler <marcel.ziswiler@toradex.com>
-rw-r--r--drivers/gpu/drm/imx/hdp/imx-hdp.c37
-rw-r--r--drivers/gpu/drm/imx/hdp/imx-hdp.h2
2 files changed, 34 insertions, 5 deletions
diff --git a/drivers/gpu/drm/imx/hdp/imx-hdp.c b/drivers/gpu/drm/imx/hdp/imx-hdp.c
index 1152c9aaff07..b126875fc09d 100644
--- a/drivers/gpu/drm/imx/hdp/imx-hdp.c
+++ b/drivers/gpu/drm/imx/hdp/imx-hdp.c
@@ -831,10 +831,17 @@ imx_hdp_connector_detect(struct drm_connector *connector, bool force)
struct imx_hdp, connector);
int ret;
u8 hpd = 0xf;
+ struct edid *edid;
ret = imx_hdp_call(hdp, get_hpd_state, &hdp->state, &hpd);
- if (ret > 0)
- return connector_status_unknown;
+ if (ret > 0) {
+ /* Check if optional regular DDC I2C bus should be used. */
+ if (hdp->ddc) {
+ edid = drm_get_edid(connector, hdp->ddc);
+ if (drm_edid_is_valid(edid))
+ hpd = 1;
+ }
+ }
if (hpd == 1)
/* Cable Connected */
@@ -844,7 +851,7 @@ imx_hdp_connector_detect(struct drm_connector *connector, bool force)
return connector_status_disconnected;
else {
/* Cable status unknown */
- DRM_INFO("Unknow cable status, hdp=%u\n", hpd);
+ DRM_INFO("Unknow cable status, hpd=%u\n", hpd);
return connector_status_unknown;
}
}
@@ -875,8 +882,16 @@ static int imx_hdp_connector_get_modes(struct drm_connector *connector)
int num_modes = 0;
if (!hdp->no_edid) {
- edid = drm_do_get_edid(connector, hdp->ops->get_edid_block,
- &hdp->state);
+ /*
+ * Check if optional regular DDC I2C bus should be used.
+ * Fall-back to using IP/firmware integrated one.
+ */
+ if (hdp->ddc)
+ edid = drm_get_edid(connector, hdp->ddc);
+ else
+ edid = drm_do_get_edid(connector,
+ hdp->ops->get_edid_block,
+ &hdp->state);
if (edid) {
dev_info(hdp->dev, "%x,%x,%x,%x,%x,%x,%x,%x\n",
edid->header[0], edid->header[1],
@@ -1396,6 +1411,7 @@ static int imx_hdp_imx_bind(struct device *dev, struct device *master,
struct platform_device *pdev = to_platform_device(dev);
struct drm_device *drm = data;
struct imx_hdp *hdp;
+ struct device_node *ddc_phandle;
const struct of_device_id *of_id =
of_match_device(imx_hdp_dt_ids, dev);
const struct hdp_devtype *devtype = of_id->data;
@@ -1462,6 +1478,17 @@ static int imx_hdp_imx_bind(struct device *dev, struct device *master,
if (cpu_is_imx8qm() && (imx8_get_soc_revision() < B0_SILICON_ID))
hdp->no_edid = true;
+ /* get optional regular DDC I2C bus */
+ ddc_phandle = of_parse_phandle(pdev->dev.of_node, "ddc-i2c-bus", 0);
+ if (ddc_phandle) {
+ hdp->ddc = of_get_i2c_adapter_by_node(ddc_phandle);
+ if (hdp->ddc)
+ dev_info(dev, "Connector's ddc i2c bus found\n");
+ else
+ ret = -EPROBE_DEFER;
+ of_node_put(ddc_phandle);
+ }
+
if (devtype->connector_type == DRM_MODE_CONNECTOR_DisplayPort) {
hdp->is_dp = true;
hdp->is_edp = of_property_read_bool(pdev->dev.of_node, "fsl,edp");
diff --git a/drivers/gpu/drm/imx/hdp/imx-hdp.h b/drivers/gpu/drm/imx/hdp/imx-hdp.h
index 41ea3b963aa8..dfa3cca06295 100644
--- a/drivers/gpu/drm/imx/hdp/imx-hdp.h
+++ b/drivers/gpu/drm/imx/hdp/imx-hdp.h
@@ -256,6 +256,8 @@ struct imx_hdp {
VIC_PXL_ENCODING_FORMAT format;
bool hdr_metadata_present;
bool hdr_mode;
+
+ struct i2c_adapter *ddc; /* optional regular DDC I2C bus */
};
void imx_hdp_register_audio_driver(struct device *dev);