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

drm/omap: Move HPD disconnection handling to omap_connector



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: default avatarLaurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: default avatarSebastian Reichel <sebastian.reichel@collabora.co.uk>
Signed-off-by: default avatarTomi Valkeinen <tomi.valkeinen@ti.com>
parent 18412b66
Loading
Loading
Loading
Loading
+1 −6
Original line number Diff line number Diff line
@@ -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,
+1 −6
Original line number Diff line number Diff line
@@ -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,
+27 −6
Original line number Diff line number Diff line
@@ -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,7 +63,11 @@ static void omap_connector_hpd_cb(void *cb_data,
	connector->status = status;
	mutex_unlock(&dev->mode_config.mutex);

	if (old_status != status)
	if (old_status == status)
		return;

	omap_connector_hpd_notify(connector, omap_connector->hpd, status);

	drm_kms_helper_hotplug_event(dev);
}

@@ -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: