From all the drivers using drm_bridge_connector only iMX/dcss and OMAP
DRM driver do a proper work of calling drm_bridge_connector_en/disable_hpd() in right places. Rather than teaching each and every driver how to properly handle drm_bridge_connector's HPD, make that automatic.
Add two additional drm_connector helper funcs: enable_hpd() and disable_hpd(). Make drm_kms_helper_poll_* functions call them (as this is the time where the drm_bridge_connector's functions are called by the drivers too).
Dmitry Baryshkov (7): drm/poll-helper: merge drm_kms_helper_poll_disable() and _fini() drm/probe-helper: enable and disable HPD on connectors drm/bridge_connector: rely on drm_kms_helper_poll_* for HPD enablement drm/imx/dcss: stop using drm_bridge_connector_en/disable_hpd() drm/msm/hdmi: stop using drm_bridge_connector_en/disable_hpd() drm/omap: stop using drm_bridge_connector_en/disable_hpd() drm/bridge_connector: drop drm_bridge_connector_en/disable_hpd()
drivers/gpu/drm/drm_bridge_connector.c | 23 +++---------- drivers/gpu/drm/drm_probe_helper.c | 40 ++++++++++++++++++----- drivers/gpu/drm/imx/dcss/dcss-dev.c | 4 --- drivers/gpu/drm/imx/dcss/dcss-kms.c | 4 --- drivers/gpu/drm/msm/hdmi/hdmi.c | 2 -- drivers/gpu/drm/omapdrm/omap_drv.c | 41 ------------------------ include/drm/drm_bridge_connector.h | 2 -- include/drm/drm_modeset_helper_vtables.h | 22 +++++++++++++ 8 files changed, 58 insertions(+), 80 deletions(-)
Merge drm_kms_helper_poll_disable() and drm_kms_helper_poll_fini() code into a common helper function.
Signed-off-by: Dmitry Baryshkov dmitry.baryshkov@linaro.org --- drivers/gpu/drm/drm_probe_helper.c | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-)
diff --git a/drivers/gpu/drm/drm_probe_helper.c b/drivers/gpu/drm/drm_probe_helper.c index 682359512996..204f6999113f 100644 --- a/drivers/gpu/drm/drm_probe_helper.c +++ b/drivers/gpu/drm/drm_probe_helper.c @@ -754,6 +754,17 @@ bool drm_kms_helper_is_poll_worker(void) } EXPORT_SYMBOL(drm_kms_helper_is_poll_worker);
+static void drm_kms_helper_poll_disable_fini(struct drm_device *dev, bool fini) +{ + if (!dev->mode_config.poll_enabled) + return; + + if (fini) + dev->mode_config.poll_enabled = false; + + cancel_delayed_work_sync(&dev->mode_config.output_poll_work); +} + /** * drm_kms_helper_poll_disable - disable output polling * @dev: drm_device @@ -770,9 +781,7 @@ EXPORT_SYMBOL(drm_kms_helper_is_poll_worker); */ void drm_kms_helper_poll_disable(struct drm_device *dev) { - if (!dev->mode_config.poll_enabled) - return; - cancel_delayed_work_sync(&dev->mode_config.output_poll_work); + drm_kms_helper_poll_disable_fini(dev, false); } EXPORT_SYMBOL(drm_kms_helper_poll_disable);
@@ -810,11 +819,7 @@ EXPORT_SYMBOL(drm_kms_helper_poll_init); */ void drm_kms_helper_poll_fini(struct drm_device *dev) { - if (!dev->mode_config.poll_enabled) - return; - - dev->mode_config.poll_enabled = false; - cancel_delayed_work_sync(&dev->mode_config.output_poll_work); + drm_kms_helper_poll_disable_fini(dev, true); } EXPORT_SYMBOL(drm_kms_helper_poll_fini);
Intruct two drm_connector_helper_funcs: enable_hpd() and disable_hpd(). They are called by drm_kms_helper_poll_enable() and drm_kms_helper_poll_disable() (and thus drm_kms_helper_poll_init() and drm_kms_helper_poll_fini()) respectively.
This allows drivers to rely on drm_kms_helper_poll for enabling and disabling HPD detection rather than doing that manually.
Signed-off-by: Dmitry Baryshkov dmitry.baryshkov@linaro.org --- drivers/gpu/drm/drm_probe_helper.c | 19 +++++++++++++++++++ include/drm/drm_modeset_helper_vtables.h | 22 ++++++++++++++++++++++ 2 files changed, 41 insertions(+)
diff --git a/drivers/gpu/drm/drm_probe_helper.c b/drivers/gpu/drm/drm_probe_helper.c index 204f6999113f..7fef16cd80ff 100644 --- a/drivers/gpu/drm/drm_probe_helper.c +++ b/drivers/gpu/drm/drm_probe_helper.c @@ -251,6 +251,12 @@ void drm_kms_helper_poll_enable(struct drm_device *dev)
drm_connector_list_iter_begin(dev, &conn_iter); drm_for_each_connector_iter(connector, &conn_iter) { + const struct drm_connector_helper_funcs *funcs = + connector->helper_private; + + if (funcs && funcs->enable_hpd) + funcs->enable_hpd(connector); + if (connector->polled & (DRM_CONNECTOR_POLL_CONNECT | DRM_CONNECTOR_POLL_DISCONNECT)) poll = true; @@ -756,12 +762,25 @@ EXPORT_SYMBOL(drm_kms_helper_is_poll_worker);
static void drm_kms_helper_poll_disable_fini(struct drm_device *dev, bool fini) { + struct drm_connector *connector; + struct drm_connector_list_iter conn_iter; + if (!dev->mode_config.poll_enabled) return;
if (fini) dev->mode_config.poll_enabled = false;
+ drm_connector_list_iter_begin(dev, &conn_iter); + drm_for_each_connector_iter(connector, &conn_iter) { + const struct drm_connector_helper_funcs *funcs = + connector->helper_private; + + if (funcs && funcs->disable_hpd) + funcs->disable_hpd(connector); + } + drm_connector_list_iter_end(&conn_iter); + cancel_delayed_work_sync(&dev->mode_config.output_poll_work); }
diff --git a/include/drm/drm_modeset_helper_vtables.h b/include/drm/drm_modeset_helper_vtables.h index fdfa9f37ce05..7fa67017d303 100644 --- a/include/drm/drm_modeset_helper_vtables.h +++ b/include/drm/drm_modeset_helper_vtables.h @@ -1143,6 +1143,28 @@ struct drm_connector_helper_funcs { */ void (*cleanup_writeback_job)(struct drm_writeback_connector *connector, struct drm_writeback_job *job); + + /** + * @enable_hpd: + * + * Enable hot-plug detection for the connector. + * + * This operation is optional. + * + * This callback is used by the drm_kms_helper_poll_enable() helpers. + */ + void (*enable_hpd)(struct drm_connector *connector); + + /** + * @disable_hpd: + * + * Disable hot-plug detection for the connector. + * + * This operation is optional. + * + * This callback is used by the drm_kms_helper_poll_disable() helpers. + */ + void (*disable_hpd)(struct drm_connector *connector); };
/**
Use drm_connector's helpers enable_hpd and disable_hpd to enable and disable HPD automatically by the means of drm_kms_helper_poll_* functions. As the drm_bridge_connector_enable_hpd() and drm_bridge_connector_disable_hpd() functions are now unused, replace them with stubs to ease driver migration.
Signed-off-by: Dmitry Baryshkov dmitry.baryshkov@linaro.org --- drivers/gpu/drm/drm_bridge_connector.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/drm_bridge_connector.c b/drivers/gpu/drm/drm_bridge_connector.c index 60923cdfe8e1..1592da3b9403 100644 --- a/drivers/gpu/drm/drm_bridge_connector.c +++ b/drivers/gpu/drm/drm_bridge_connector.c @@ -136,6 +136,11 @@ static void drm_bridge_connector_hpd_cb(void *cb_data, * This is typically used by display drivers in their resume handler. */ void drm_bridge_connector_enable_hpd(struct drm_connector *connector) +{ +} +EXPORT_SYMBOL_GPL(drm_bridge_connector_enable_hpd); + +static void _drm_bridge_connector_enable_hpd(struct drm_connector *connector) { struct drm_bridge_connector *bridge_connector = to_drm_bridge_connector(connector); @@ -145,7 +150,6 @@ void drm_bridge_connector_enable_hpd(struct drm_connector *connector) drm_bridge_hpd_enable(hpd, drm_bridge_connector_hpd_cb, bridge_connector); } -EXPORT_SYMBOL_GPL(drm_bridge_connector_enable_hpd);
/** * drm_bridge_connector_disable_hpd - Disable hot-plug detection for the @@ -156,6 +160,11 @@ EXPORT_SYMBOL_GPL(drm_bridge_connector_enable_hpd); * This is typically used by display drivers in their suspend handler. */ void drm_bridge_connector_disable_hpd(struct drm_connector *connector) +{ +} +EXPORT_SYMBOL_GPL(drm_bridge_connector_disable_hpd); + +static void _drm_bridge_connector_disable_hpd(struct drm_connector *connector) { struct drm_bridge_connector *bridge_connector = to_drm_bridge_connector(connector); @@ -164,7 +173,6 @@ void drm_bridge_connector_disable_hpd(struct drm_connector *connector) if (hpd) drm_bridge_hpd_disable(hpd); } -EXPORT_SYMBOL_GPL(drm_bridge_connector_disable_hpd);
/* ----------------------------------------------------------------------------- * Bridge Connector Functions @@ -305,6 +313,8 @@ static int drm_bridge_connector_get_modes(struct drm_connector *connector) static const struct drm_connector_helper_funcs drm_bridge_connector_helper_funcs = { .get_modes = drm_bridge_connector_get_modes, /* No need for .mode_valid(), the bridges are checked by the core. */ + .enable_hpd = _drm_bridge_connector_enable_hpd, + .disable_hpd = _drm_bridge_connector_disable_hpd, };
/* -----------------------------------------------------------------------------
The functionality of drm_bridge_connector_enable_hpd() and drm_bridge_connector_disable_hpd() is provided automatically by the drm_kms_poll helpers. Stop calling these functions manually.
Signed-off-by: Dmitry Baryshkov dmitry.baryshkov@linaro.org --- drivers/gpu/drm/imx/dcss/dcss-dev.c | 4 ---- drivers/gpu/drm/imx/dcss/dcss-kms.c | 4 ---- 2 files changed, 8 deletions(-)
diff --git a/drivers/gpu/drm/imx/dcss/dcss-dev.c b/drivers/gpu/drm/imx/dcss/dcss-dev.c index c849533ca83e..62c5f7cd5906 100644 --- a/drivers/gpu/drm/imx/dcss/dcss-dev.c +++ b/drivers/gpu/drm/imx/dcss/dcss-dev.c @@ -254,8 +254,6 @@ int dcss_dev_suspend(struct device *dev) struct dcss_kms_dev *kms = container_of(ddev, struct dcss_kms_dev, base); int ret;
- drm_bridge_connector_disable_hpd(kms->connector); - drm_mode_config_helper_suspend(ddev);
if (pm_runtime_suspended(dev)) @@ -289,8 +287,6 @@ int dcss_dev_resume(struct device *dev)
drm_mode_config_helper_resume(ddev);
- drm_bridge_connector_enable_hpd(kms->connector); - return 0; } #endif /* CONFIG_PM_SLEEP */ diff --git a/drivers/gpu/drm/imx/dcss/dcss-kms.c b/drivers/gpu/drm/imx/dcss/dcss-kms.c index 9b84df34a6a1..614073eb70b0 100644 --- a/drivers/gpu/drm/imx/dcss/dcss-kms.c +++ b/drivers/gpu/drm/imx/dcss/dcss-kms.c @@ -142,8 +142,6 @@ struct dcss_kms_dev *dcss_kms_attach(struct dcss_dev *dcss)
drm_kms_helper_poll_init(drm);
- drm_bridge_connector_enable_hpd(kms->connector); - ret = drm_dev_register(drm, 0); if (ret) goto cleanup_crtc; @@ -153,7 +151,6 @@ struct dcss_kms_dev *dcss_kms_attach(struct dcss_dev *dcss) return kms;
cleanup_crtc: - drm_bridge_connector_disable_hpd(kms->connector); drm_kms_helper_poll_fini(drm); dcss_crtc_deinit(crtc, drm);
@@ -169,7 +166,6 @@ void dcss_kms_detach(struct dcss_kms_dev *kms) struct drm_device *drm = &kms->base;
drm_dev_unregister(drm); - drm_bridge_connector_disable_hpd(kms->connector); drm_kms_helper_poll_fini(drm); drm_atomic_helper_shutdown(drm); drm_crtc_vblank_off(&kms->crtc.base);
The functionality of drm_bridge_connector_enable_hpd() and drm_bridge_connector_disable_hpd() is provided automatically by the drm_kms_poll helpers. Stop calling these functions manually.
Signed-off-by: Dmitry Baryshkov dmitry.baryshkov@linaro.org --- drivers/gpu/drm/msm/hdmi/hdmi.c | 2 -- 1 file changed, 2 deletions(-)
diff --git a/drivers/gpu/drm/msm/hdmi/hdmi.c b/drivers/gpu/drm/msm/hdmi/hdmi.c index cf24e68864ba..da889175dd86 100644 --- a/drivers/gpu/drm/msm/hdmi/hdmi.c +++ b/drivers/gpu/drm/msm/hdmi/hdmi.c @@ -317,8 +317,6 @@ int msm_hdmi_modeset_init(struct hdmi *hdmi, goto fail; }
- drm_bridge_connector_enable_hpd(hdmi->connector); - ret = msm_hdmi_hpd_enable(hdmi->bridge); if (ret < 0) { DRM_DEV_ERROR(&hdmi->pdev->dev, "failed to enable HPD: %d\n", ret);
The functionality of drm_bridge_connector_enable_hpd() and drm_bridge_connector_disable_hpd() is provided automatically by the drm_kms_poll helpers. Stop calling these functions manually.
Signed-off-by: Dmitry Baryshkov dmitry.baryshkov@linaro.org --- drivers/gpu/drm/omapdrm/omap_drv.c | 41 ------------------------------ 1 file changed, 41 deletions(-)
diff --git a/drivers/gpu/drm/omapdrm/omap_drv.c b/drivers/gpu/drm/omapdrm/omap_drv.c index eaf67b9e5f12..699ed814e021 100644 --- a/drivers/gpu/drm/omapdrm/omap_drv.c +++ b/drivers/gpu/drm/omapdrm/omap_drv.c @@ -545,44 +545,6 @@ static void omap_modeset_fini(struct drm_device *ddev) drm_mode_config_cleanup(ddev); }
-/* - * Enable the HPD in external components if supported - */ -static void omap_modeset_enable_external_hpd(struct drm_device *ddev) -{ - struct omap_drm_private *priv = ddev->dev_private; - unsigned int i; - - for (i = 0; i < priv->num_pipes; i++) { - struct drm_connector *connector = priv->pipes[i].connector; - - if (!connector) - continue; - - if (priv->pipes[i].output->bridge) - drm_bridge_connector_enable_hpd(connector); - } -} - -/* - * Disable the HPD in external components if supported - */ -static void omap_modeset_disable_external_hpd(struct drm_device *ddev) -{ - struct omap_drm_private *priv = ddev->dev_private; - unsigned int i; - - for (i = 0; i < priv->num_pipes; i++) { - struct drm_connector *connector = priv->pipes[i].connector; - - if (!connector) - continue; - - if (priv->pipes[i].output->bridge) - drm_bridge_connector_disable_hpd(connector); - } -} - /* * drm ioctl funcs */ @@ -782,7 +744,6 @@ static int omapdrm_init(struct omap_drm_private *priv, struct device *dev) omap_fbdev_init(ddev);
drm_kms_helper_poll_init(ddev); - omap_modeset_enable_external_hpd(ddev);
/* * Register the DRM device with the core and the connectors with @@ -795,7 +756,6 @@ static int omapdrm_init(struct omap_drm_private *priv, struct device *dev) return 0;
err_cleanup_helpers: - omap_modeset_disable_external_hpd(ddev); drm_kms_helper_poll_fini(ddev);
omap_fbdev_fini(ddev); @@ -822,7 +782,6 @@ static void omapdrm_cleanup(struct omap_drm_private *priv)
drm_dev_unregister(ddev);
- omap_modeset_disable_external_hpd(ddev); drm_kms_helper_poll_fini(ddev);
omap_fbdev_fini(ddev);
Now as all drivers stopped calling drm_bridge_connector_enable_hpd() and drm_bridge_connector_disable_hpd() it is safe to remove them complelely.
Signed-off-by: Dmitry Baryshkov dmitry.baryshkov@linaro.org --- drivers/gpu/drm/drm_bridge_connector.c | 25 ------------------------- include/drm/drm_bridge_connector.h | 2 -- 2 files changed, 27 deletions(-)
diff --git a/drivers/gpu/drm/drm_bridge_connector.c b/drivers/gpu/drm/drm_bridge_connector.c index 1592da3b9403..d9c1f61b6fb6 100644 --- a/drivers/gpu/drm/drm_bridge_connector.c +++ b/drivers/gpu/drm/drm_bridge_connector.c @@ -128,18 +128,6 @@ static void drm_bridge_connector_hpd_cb(void *cb_data, drm_kms_helper_hotplug_event(dev); }
-/** - * drm_bridge_connector_enable_hpd - Enable hot-plug detection for the connector - * @connector: The DRM bridge connector - * - * This function enables hot-plug detection for the given bridge connector. - * This is typically used by display drivers in their resume handler. - */ -void drm_bridge_connector_enable_hpd(struct drm_connector *connector) -{ -} -EXPORT_SYMBOL_GPL(drm_bridge_connector_enable_hpd); - static void _drm_bridge_connector_enable_hpd(struct drm_connector *connector) { struct drm_bridge_connector *bridge_connector = @@ -151,19 +139,6 @@ static void _drm_bridge_connector_enable_hpd(struct drm_connector *connector) bridge_connector); }
-/** - * drm_bridge_connector_disable_hpd - Disable hot-plug detection for the - * connector - * @connector: The DRM bridge connector - * - * This function disables hot-plug detection for the given bridge connector. - * This is typically used by display drivers in their suspend handler. - */ -void drm_bridge_connector_disable_hpd(struct drm_connector *connector) -{ -} -EXPORT_SYMBOL_GPL(drm_bridge_connector_disable_hpd); - static void _drm_bridge_connector_disable_hpd(struct drm_connector *connector) { struct drm_bridge_connector *bridge_connector = diff --git a/include/drm/drm_bridge_connector.h b/include/drm/drm_bridge_connector.h index 33f6c3bbdb4a..69630815fb09 100644 --- a/include/drm/drm_bridge_connector.h +++ b/include/drm/drm_bridge_connector.h @@ -10,8 +10,6 @@ struct drm_connector; struct drm_device; struct drm_encoder;
-void drm_bridge_connector_enable_hpd(struct drm_connector *connector); -void drm_bridge_connector_disable_hpd(struct drm_connector *connector); struct drm_connector *drm_bridge_connector_init(struct drm_device *drm, struct drm_encoder *encoder);
On 29/04/2022 21:51, Dmitry Baryshkov wrote:
From all the drivers using drm_bridge_connector only iMX/dcss and OMAP DRM driver do a proper work of calling drm_bridge_connector_en/disable_hpd() in right places. Rather than teaching each and every driver how to properly handle drm_bridge_connector's HPD, make that automatic.
Add two additional drm_connector helper funcs: enable_hpd() and disable_hpd(). Make drm_kms_helper_poll_* functions call them (as this is the time where the drm_bridge_connector's functions are called by the drivers too).
Gracious ping regarding this series. It went for two weeks w/o review.
Few additional points 'pro': - It makes it possible to handle hpd enablement in cases where the driver uses a mixture of drm_bridge_connector and old connectors (msm) - It makes it possible for other connectors to also implement dynamic hpd enablement/disablement in a standard way
Dmitry Baryshkov (7): drm/poll-helper: merge drm_kms_helper_poll_disable() and _fini() drm/probe-helper: enable and disable HPD on connectors drm/bridge_connector: rely on drm_kms_helper_poll_* for HPD enablement drm/imx/dcss: stop using drm_bridge_connector_en/disable_hpd() drm/msm/hdmi: stop using drm_bridge_connector_en/disable_hpd() drm/omap: stop using drm_bridge_connector_en/disable_hpd() drm/bridge_connector: drop drm_bridge_connector_en/disable_hpd()
drivers/gpu/drm/drm_bridge_connector.c | 23 +++---------- drivers/gpu/drm/drm_probe_helper.c | 40 ++++++++++++++++++----- drivers/gpu/drm/imx/dcss/dcss-dev.c | 4 --- drivers/gpu/drm/imx/dcss/dcss-kms.c | 4 --- drivers/gpu/drm/msm/hdmi/hdmi.c | 2 -- drivers/gpu/drm/omapdrm/omap_drv.c | 41 ------------------------ include/drm/drm_bridge_connector.h | 2 -- include/drm/drm_modeset_helper_vtables.h | 22 +++++++++++++ 8 files changed, 58 insertions(+), 80 deletions(-)
dri-devel@lists.freedesktop.org