diff options
author | Dave Airlie <airlied@redhat.com> | 2020-02-28 16:21:14 +1000 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2020-02-28 16:22:41 +1000 |
commit | 60347451ddb0646c1a9cc5b9581e5bcf648ad1aa (patch) | |
tree | 73cd9298b66b4a84b0e3f02346202f905f5840bd /drivers/gpu/drm/omapdrm/omap_connector.c | |
parent | a2ae604da74dcf9ae674d3c03efad80574952800 (diff) | |
parent | 18b39fb975b79d6526449ca7c8ab504bc92e2825 (diff) | |
download | linux-60347451ddb0646c1a9cc5b9581e5bcf648ad1aa.tar.bz2 |
Merge tag 'drm-misc-next-2020-02-27' of git://anongit.freedesktop.org/drm/drm-misc into drm-next
drm-misc-next for 5.7
UAPI Changes:
Cross-subsystem Changes:
Core Changes:
- bridge: huge rework to get rid of omap_dss custom display drivers
Driver Changes:
- hisilicon: some fixes related to modes it can deal with / default to
- virtio: shmem and gpu context fixes and enhancements
- sun4i: Support for LVDS on the A33
Signed-off-by: Dave Airlie <airlied@redhat.com>
From: Maxime Ripard <maxime@cerno.tech>
Link: https://patchwork.freedesktop.org/patch/msgid/20200227113222.cdwzy4cvcqjtbmou@gilmour.lan
Diffstat (limited to 'drivers/gpu/drm/omapdrm/omap_connector.c')
-rw-r--r-- | drivers/gpu/drm/omapdrm/omap_connector.c | 247 |
1 files changed, 12 insertions, 235 deletions
diff --git a/drivers/gpu/drm/omapdrm/omap_connector.c b/drivers/gpu/drm/omapdrm/omap_connector.c index 94cded387174..528764566b17 100644 --- a/drivers/gpu/drm/omapdrm/omap_connector.c +++ b/drivers/gpu/drm/omapdrm/omap_connector.c @@ -6,7 +6,6 @@ #include <drm/drm_atomic_helper.h> #include <drm/drm_crtc.h> -#include <drm/drm_panel.h> #include <drm/drm_probe_helper.h> #include "omap_drv.h" @@ -20,124 +19,12 @@ struct omap_connector { struct drm_connector base; struct omap_dss_device *output; - struct omap_dss_device *hpd; - bool hdmi_mode; }; -static void omap_connector_hpd_notify(struct drm_connector *connector, - enum drm_connector_status status) -{ - struct omap_connector *omap_connector = to_omap_connector(connector); - struct omap_dss_device *dssdev; - - if (status != connector_status_disconnected) - return; - - /* - * Notify all devics in the pipeline of disconnection. This is required - * to let the HDMI encoders reset their internal state related to - * connection status, such as the CEC address. - */ - for (dssdev = omap_connector->output; dssdev; dssdev = dssdev->next) { - if (dssdev->ops && dssdev->ops->hdmi.lost_hotplug) - dssdev->ops->hdmi.lost_hotplug(dssdev); - } -} - -static void omap_connector_hpd_cb(void *cb_data, - enum drm_connector_status status) -{ - struct omap_connector *omap_connector = cb_data; - struct drm_connector *connector = &omap_connector->base; - struct drm_device *dev = connector->dev; - enum drm_connector_status old_status; - - mutex_lock(&dev->mode_config.mutex); - old_status = connector->status; - connector->status = status; - mutex_unlock(&dev->mode_config.mutex); - - if (old_status == status) - return; - - omap_connector_hpd_notify(connector, status); - - drm_kms_helper_hotplug_event(dev); -} - -void omap_connector_enable_hpd(struct drm_connector *connector) -{ - struct omap_connector *omap_connector = to_omap_connector(connector); - struct omap_dss_device *hpd = omap_connector->hpd; - - if (hpd) - hpd->ops->register_hpd_cb(hpd, omap_connector_hpd_cb, - omap_connector); -} - -void omap_connector_disable_hpd(struct drm_connector *connector) -{ - struct omap_connector *omap_connector = to_omap_connector(connector); - struct omap_dss_device *hpd = omap_connector->hpd; - - if (hpd) - hpd->ops->unregister_hpd_cb(hpd); -} - -bool omap_connector_get_hdmi_mode(struct drm_connector *connector) -{ - struct omap_connector *omap_connector = to_omap_connector(connector); - - return omap_connector->hdmi_mode; -} - -static struct omap_dss_device * -omap_connector_find_device(struct drm_connector *connector, - enum omap_dss_device_ops_flag op) -{ - struct omap_connector *omap_connector = to_omap_connector(connector); - struct omap_dss_device *dssdev = NULL; - struct omap_dss_device *d; - - for (d = omap_connector->output; d; d = d->next) { - if (d->ops_flags & op) - dssdev = d; - } - - return dssdev; -} - static enum drm_connector_status omap_connector_detect( struct drm_connector *connector, bool force) { - struct omap_dss_device *dssdev; - enum drm_connector_status status; - - dssdev = omap_connector_find_device(connector, - OMAP_DSS_DEVICE_OP_DETECT); - - if (dssdev) { - status = dssdev->ops->detect(dssdev) - ? connector_status_connected - : connector_status_disconnected; - - omap_connector_hpd_notify(connector, status); - } else { - switch (connector->connector_type) { - case DRM_MODE_CONNECTOR_DPI: - case DRM_MODE_CONNECTOR_LVDS: - case DRM_MODE_CONNECTOR_DSI: - status = connector_status_connected; - break; - default: - status = connector_status_unknown; - break; - } - } - - VERB("%s: %d (force=%d)", connector->name, status, force); - - return status; + return connector_status_connected; } static void omap_connector_destroy(struct drm_connector *connector) @@ -146,14 +33,6 @@ static void omap_connector_destroy(struct drm_connector *connector) DBG("%s", connector->name); - if (omap_connector->hpd) { - struct omap_dss_device *hpd = omap_connector->hpd; - - hpd->ops->unregister_hpd_cb(hpd); - omapdss_device_put(hpd); - omap_connector->hpd = NULL; - } - drm_connector_unregister(connector); drm_connector_cleanup(connector); @@ -162,81 +41,27 @@ 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) -{ - struct omap_connector *omap_connector = to_omap_connector(connector); - enum drm_connector_status status; - void *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)) { - kfree(edid); - goto no_edid; - } - - drm_connector_update_edid_property(connector, edid); - n = drm_add_edid_modes(connector, edid); - - omap_connector->hdmi_mode = drm_detect_hdmi_monitor(edid); - - kfree(edid); - return n; - -no_edid: - drm_connector_update_edid_property(connector, NULL); - return 0; -} - static int omap_connector_get_modes(struct drm_connector *connector) { struct omap_connector *omap_connector = to_omap_connector(connector); - struct omap_dss_device *dssdev; + struct omap_dss_device *dssdev = NULL; + struct omap_dss_device *d; DBG("%s", connector->name); /* - * If display exposes EDID, then we parse that in the normal way to - * build table of supported modes. + * If the display pipeline reports modes (e.g. with a fixed resolution + * panel or an analog TV output), query it. */ - dssdev = omap_connector_find_device(connector, - OMAP_DSS_DEVICE_OP_EDID); - if (dssdev) - return omap_connector_get_modes_edid(connector, dssdev); + for (d = omap_connector->output; d; d = d->next) { + if (d->ops_flags & OMAP_DSS_DEVICE_OP_MODES) + dssdev = d; + } - /* - * Otherwise if the display pipeline reports modes (e.g. with a fixed - * resolution panel or an analog TV output), query it. - */ - dssdev = omap_connector_find_device(connector, - OMAP_DSS_DEVICE_OP_MODES); if (dssdev) return dssdev->ops->get_modes(dssdev, connector); - /* - * Otherwise if the display pipeline uses a drm_panel, we delegate the - * operation to the panel API. - */ - if (omap_connector->output->panel) - return drm_panel_get_modes(omap_connector->output->panel, - connector); - - /* - * We can't retrieve modes, which can happen for instance for a DVI or - * VGA output with the DDC bus unconnected. The KMS core will add the - * default modes. - */ + /* We can't retrieve modes. The KMS core will add the default modes. */ return 0; } @@ -249,7 +74,7 @@ enum drm_mode_status omap_connector_mode_fixup(struct omap_dss_device *dssdev, drm_mode_copy(adjusted_mode, mode); for (; dssdev; dssdev = dssdev->next) { - if (!dssdev->ops->check_timings) + if (!dssdev->ops || !dssdev->ops->check_timings) continue; ret = dssdev->ops->check_timings(dssdev, adjusted_mode); @@ -298,35 +123,6 @@ static const struct drm_connector_helper_funcs omap_connector_helper_funcs = { .mode_valid = omap_connector_mode_valid, }; -static int omap_connector_get_type(struct omap_dss_device *output) -{ - struct omap_dss_device *display; - enum omap_display_type type; - - display = omapdss_display_get(output); - type = display->type; - omapdss_device_put(display); - - switch (type) { - case OMAP_DISPLAY_TYPE_HDMI: - return DRM_MODE_CONNECTOR_HDMIA; - case OMAP_DISPLAY_TYPE_DVI: - return DRM_MODE_CONNECTOR_DVID; - case OMAP_DISPLAY_TYPE_DSI: - return DRM_MODE_CONNECTOR_DSI; - case OMAP_DISPLAY_TYPE_DPI: - case OMAP_DISPLAY_TYPE_DBI: - return DRM_MODE_CONNECTOR_DPI; - case OMAP_DISPLAY_TYPE_VENC: - /* TODO: This could also be composite */ - return DRM_MODE_CONNECTOR_SVIDEO; - case OMAP_DISPLAY_TYPE_SDI: - return DRM_MODE_CONNECTOR_LVDS; - default: - return DRM_MODE_CONNECTOR_Unknown; - } -} - /* initialize connector */ struct drm_connector *omap_connector_init(struct drm_device *dev, struct omap_dss_device *output, @@ -334,7 +130,6 @@ struct drm_connector *omap_connector_init(struct drm_device *dev, { struct drm_connector *connector = NULL; struct omap_connector *omap_connector; - struct omap_dss_device *dssdev; DBG("%s", output->name); @@ -349,27 +144,9 @@ struct drm_connector *omap_connector_init(struct drm_device *dev, connector->doublescan_allowed = 0; drm_connector_init(dev, connector, &omap_connector_funcs, - omap_connector_get_type(output)); + DRM_MODE_CONNECTOR_DSI); drm_connector_helper_add(connector, &omap_connector_helper_funcs); - /* - * Initialize connector status handling. First try to find a device that - * supports hot-plug reporting. If it fails, fall back to a device that - * support polling. If that fails too, we don't support hot-plug - * detection at all. - */ - dssdev = omap_connector_find_device(connector, OMAP_DSS_DEVICE_OP_HPD); - if (dssdev) { - omap_connector->hpd = omapdss_device_get(dssdev); - connector->polled = DRM_CONNECTOR_POLL_HPD; - } else { - dssdev = omap_connector_find_device(connector, - OMAP_DSS_DEVICE_OP_DETECT); - if (dssdev) - connector->polled = DRM_CONNECTOR_POLL_CONNECT | - DRM_CONNECTOR_POLL_DISCONNECT; - } - return connector; fail: |