Hi, On Wed, Jun 06, 2018 at 12:36:46PM +0300, Laurent Pinchart wrote: > On HDMI outputs, CEC support requires notification of HPD signal > deassertion. The HPD signal can be handled by various omap_dss_device > instances in the pipeline, and all of them forward HPD events to the > OMAP4 internal HDMI encoder. > > Knowledge of the DSS internals need to be removed from the > omap_dss_device instances in order to migrate to drm_bridge. To do so, > move HPD handling for CEC to the omap_connector. > > Signed-off-by: Laurent Pinchart > --- Reviewed-by: Sebastian Reichel -- Sebastian > drivers/gpu/drm/omapdrm/displays/connector-hdmi.c | 7 +---- > .../gpu/drm/omapdrm/displays/encoder-tpd12s015.c | 7 +---- > drivers/gpu/drm/omapdrm/omap_connector.c | 33 ++++++++++++++++++---- > 3 files changed, 29 insertions(+), 18 deletions(-) > > diff --git a/drivers/gpu/drm/omapdrm/displays/connector-hdmi.c b/drivers/gpu/drm/omapdrm/displays/connector-hdmi.c > index 84cc68388940..6f2364afb14a 100644 > --- a/drivers/gpu/drm/omapdrm/displays/connector-hdmi.c > +++ b/drivers/gpu/drm/omapdrm/displays/connector-hdmi.c > @@ -137,13 +137,8 @@ static int hdmic_read_edid(struct omap_dss_device *dssdev, > static bool hdmic_detect(struct omap_dss_device *dssdev) > { > struct panel_drv_data *ddata = to_panel_data(dssdev); > - struct omap_dss_device *src = dssdev->src; > - bool connected; > > - connected = gpiod_get_value_cansleep(ddata->hpd_gpio); > - if (!connected && src->ops->hdmi.lost_hotplug) > - src->ops->hdmi.lost_hotplug(src); > - return connected; > + return gpiod_get_value_cansleep(ddata->hpd_gpio); > } > > static void hdmic_register_hpd_cb(struct omap_dss_device *dssdev, > diff --git a/drivers/gpu/drm/omapdrm/displays/encoder-tpd12s015.c b/drivers/gpu/drm/omapdrm/displays/encoder-tpd12s015.c > index 1fa1d332dbc4..2772af84531a 100644 > --- a/drivers/gpu/drm/omapdrm/displays/encoder-tpd12s015.c > +++ b/drivers/gpu/drm/omapdrm/displays/encoder-tpd12s015.c > @@ -130,13 +130,8 @@ static int tpd_read_edid(struct omap_dss_device *dssdev, > static bool tpd_detect(struct omap_dss_device *dssdev) > { > struct panel_drv_data *ddata = to_panel_data(dssdev); > - struct omap_dss_device *src = dssdev->src; > - bool connected; > > - connected = gpiod_get_value_cansleep(ddata->hpd_gpio); > - if (!connected && src->ops->hdmi.lost_hotplug) > - src->ops->hdmi.lost_hotplug(src); > - return connected; > + return gpiod_get_value_cansleep(ddata->hpd_gpio); > } > > static void tpd_register_hpd_cb(struct omap_dss_device *dssdev, > diff --git a/drivers/gpu/drm/omapdrm/omap_connector.c b/drivers/gpu/drm/omapdrm/omap_connector.c > index 56985c191740..1b3f85a02c85 100644 > --- a/drivers/gpu/drm/omapdrm/omap_connector.c > +++ b/drivers/gpu/drm/omapdrm/omap_connector.c > @@ -34,6 +34,22 @@ struct omap_connector { > bool hdmi_mode; > }; > > +static void omap_connector_hpd_notify(struct drm_connector *connector, > + struct omap_dss_device *src, > + enum drm_connector_status status) > +{ > + if (status == connector_status_disconnected) { > + /* > + * If the source is an HDMI encoder, notify it of disconnection. > + * This is required to let the HDMI encoder reset any internal > + * state related to connection status, such as the CEC address. > + */ > + if (src && src->type == OMAP_DISPLAY_TYPE_HDMI && > + src->ops->hdmi.lost_hotplug) > + src->ops->hdmi.lost_hotplug(src); > + } > +} > + > static void omap_connector_hpd_cb(void *cb_data, > enum drm_connector_status status) > { > @@ -47,8 +63,12 @@ static void omap_connector_hpd_cb(void *cb_data, > connector->status = status; > mutex_unlock(&dev->mode_config.mutex); > > - if (old_status != status) > - drm_kms_helper_hotplug_event(dev); > + if (old_status == status) > + return; > + > + omap_connector_hpd_notify(connector, omap_connector->hpd, status); > + > + drm_kms_helper_hotplug_event(dev); > } > > void omap_connector_enable_hpd(struct drm_connector *connector) > @@ -103,10 +123,11 @@ static enum drm_connector_status omap_connector_detect( > OMAP_DSS_DEVICE_OP_DETECT); > > if (dssdev) { > - if (dssdev->ops->detect(dssdev)) > - status = connector_status_connected; > - else > - status = connector_status_disconnected; > + status = dssdev->ops->detect(dssdev) > + ? connector_status_connected > + : connector_status_disconnected; > + > + omap_connector_hpd_notify(connector, dssdev->src, status); > } else { > switch (omap_connector->dssdev->type) { > case OMAP_DISPLAY_TYPE_DPI: > -- > Regards, > > Laurent Pinchart > > _______________________________________________ > dri-devel mailing list > dri-devel@lists.freedesktop.org > https://lists.freedesktop.org/mailman/listinfo/dri-devel