From 4b4e7a2a4c535de40ac850ef0245106c655eaa7a Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Thu, 4 Feb 2021 18:33:44 +0000 Subject: drm/bridge: make a const array static, makes object smaller Don't populate the const array frs_limits on the stack but instead make it static. Makes the object code smaller by 128 bytes: Before: text data bss dec hex filename 24845 7440 64 32349 7e5d ./drivers/gpu/drm/bridge/tc358768.o After: text data bss dec hex filename 24749 7408 64 32221 7ddd ./drivers/gpu/drm/bridge/tc358768.o (gcc version 10.2.0) Signed-off-by: Colin Ian King Reviewed-by: Laurent Pinchart Signed-off-by: Laurent Pinchart --- drivers/gpu/drm/bridge/tc358768.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/bridge/tc358768.c b/drivers/gpu/drm/bridge/tc358768.c index 8ed8302d6bbb..2495ea46b091 100644 --- a/drivers/gpu/drm/bridge/tc358768.c +++ b/drivers/gpu/drm/bridge/tc358768.c @@ -291,7 +291,7 @@ static int tc358768_calc_pll(struct tc358768_priv *priv, const struct drm_display_mode *mode, bool verify_only) { - const u32 frs_limits[] = { + static const u32 frs_limits[] = { 1000000000, 500000000, 250000000, -- cgit v1.2.3 From 015f2ebb93767d40c442e749642fffaf10316d78 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Tue, 23 Mar 2021 02:09:53 +0200 Subject: drm: rcar-du: Shutdown the display on system shutdown When the system shuts down or warm reboots, the display may be active, with the hardware accessing system memory. Upon reboot, the DDR will not be accessible, which may cause issues. Implement the platform_driver .shutdown() operation and shut down the display to fix this. Signed-off-by: Laurent Pinchart Reviewed-by: Kieran Bingham --- drivers/gpu/drm/rcar-du/rcar_du_drv.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/gpu/drm/rcar-du/rcar_du_drv.c b/drivers/gpu/drm/rcar-du/rcar_du_drv.c index e289a66594a7..978828681313 100644 --- a/drivers/gpu/drm/rcar-du/rcar_du_drv.c +++ b/drivers/gpu/drm/rcar-du/rcar_du_drv.c @@ -561,6 +561,13 @@ static int rcar_du_remove(struct platform_device *pdev) return 0; } +static void rcar_du_shutdown(struct platform_device *pdev) +{ + struct rcar_du_device *rcdu = platform_get_drvdata(pdev); + + drm_atomic_helper_shutdown(&rcdu->ddev); +} + static int rcar_du_probe(struct platform_device *pdev) { struct rcar_du_device *rcdu; @@ -615,6 +622,7 @@ error: static struct platform_driver rcar_du_platform_driver = { .probe = rcar_du_probe, .remove = rcar_du_remove, + .shutdown = rcar_du_shutdown, .driver = { .name = "rcar-du", .pm = &rcar_du_pm_ops, -- cgit v1.2.3 From c29b6b0b126e9ee69a5d6339475e831a149295bd Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Tue, 23 Mar 2021 02:09:53 +0200 Subject: drm: rcar-du: Don't put reference to drm_device in rcar_du_remove() The reference to the drm_device that was acquired by devm_drm_dev_alloc() is released automatically by the devres infrastructure. It must not be released manually, as that causes a reference underflow.. Fixes: ea6aae151887 ("drm: rcar-du: Embed drm_device in rcar_du_device") Signed-off-by: Laurent Pinchart Reviewed-by: Kieran Bingham --- drivers/gpu/drm/rcar-du/rcar_du_drv.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/gpu/drm/rcar-du/rcar_du_drv.c b/drivers/gpu/drm/rcar-du/rcar_du_drv.c index 978828681313..44b18fa525f0 100644 --- a/drivers/gpu/drm/rcar-du/rcar_du_drv.c +++ b/drivers/gpu/drm/rcar-du/rcar_du_drv.c @@ -556,8 +556,6 @@ static int rcar_du_remove(struct platform_device *pdev) drm_kms_helper_poll_fini(ddev); - drm_dev_put(ddev); - return 0; } -- cgit v1.2.3 From 5e7ef0b85c7718c10f6122caf7af9b2e70d53830 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Tue, 23 Mar 2021 02:09:53 +0200 Subject: drm: rcar-du: Shutdown the display on remove When the device is unbound from the driver (the DU being a platform device, this occurs either when removing the DU module, or when unbinding the device manually through sysfs), the display may be active. Make sure it gets shut down. Signed-off-by: Laurent Pinchart Reviewed-by: Kieran Bingham --- drivers/gpu/drm/rcar-du/rcar_du_drv.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/rcar-du/rcar_du_drv.c b/drivers/gpu/drm/rcar-du/rcar_du_drv.c index 44b18fa525f0..4ac26d08ebb4 100644 --- a/drivers/gpu/drm/rcar-du/rcar_du_drv.c +++ b/drivers/gpu/drm/rcar-du/rcar_du_drv.c @@ -553,6 +553,7 @@ static int rcar_du_remove(struct platform_device *pdev) struct drm_device *ddev = &rcdu->ddev; drm_dev_unregister(ddev); + drm_atomic_helper_shutdown(ddev); drm_kms_helper_poll_fini(ddev); -- cgit v1.2.3 From fb8d617f8fd64f52f62e4f782aed64d1754ed33b Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Tue, 23 Mar 2021 23:50:08 +0200 Subject: drm/bridge: Centralize error message when bridge attach fails Being informed of a failure to attach a bridge is useful, and many drivers prints an error message in that case. Move the message to drm_bridge_attach() to avoid code duplication. Suggested-by: Stephen Boyd Signed-off-by: Laurent Pinchart Reviewed-by: Tomi Valkeinen Reviewed-by: Jyri Sarha --- drivers/gpu/drm/bridge/analogix/analogix_dp_core.c | 9 +-------- drivers/gpu/drm/bridge/analogix/anx7625.c | 5 +---- drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 1 - drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c | 10 +--------- drivers/gpu/drm/drm_bridge.c | 10 ++++++++++ drivers/gpu/drm/exynos/exynos_dp.c | 5 +---- drivers/gpu/drm/exynos/exynos_hdmi.c | 5 +---- drivers/gpu/drm/hisilicon/kirin/dw_drm_dsi.c | 9 +-------- drivers/gpu/drm/imx/dcss/dcss-kms.c | 5 +---- drivers/gpu/drm/imx/imx-ldb.c | 4 +--- drivers/gpu/drm/imx/parallel-display.c | 5 +---- drivers/gpu/drm/ingenic/ingenic-drm-drv.c | 4 +--- drivers/gpu/drm/kmb/kmb_dsi.c | 1 - drivers/gpu/drm/mcde/mcde_dsi.c | 9 +-------- drivers/gpu/drm/mediatek/mtk_dpi.c | 4 +--- drivers/gpu/drm/mediatek/mtk_hdmi.c | 5 +---- drivers/gpu/drm/omapdrm/omap_drv.c | 6 +----- drivers/gpu/drm/rockchip/rockchip_lvds.c | 5 +---- drivers/gpu/drm/rockchip/rockchip_rgb.c | 5 +---- drivers/gpu/drm/sti/sti_dvo.c | 4 +--- drivers/gpu/drm/sun4i/sun4i_lvds.c | 4 +--- drivers/gpu/drm/sun4i/sun4i_rgb.c | 4 +--- drivers/gpu/drm/tegra/rgb.c | 5 +---- drivers/gpu/drm/tidss/tidss_kms.c | 4 +--- drivers/gpu/drm/tilcdc/tilcdc_external.c | 4 +--- drivers/gpu/drm/vc4/vc4_dsi.c | 4 +--- 26 files changed, 33 insertions(+), 103 deletions(-) diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c index 550814ca2139..b7d2e4449cfa 100644 --- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c +++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c @@ -1583,7 +1583,6 @@ static int analogix_dp_create_bridge(struct drm_device *drm_dev, struct analogix_dp_device *dp) { struct drm_bridge *bridge; - int ret; bridge = devm_kzalloc(drm_dev->dev, sizeof(*bridge), GFP_KERNEL); if (!bridge) { @@ -1596,13 +1595,7 @@ static int analogix_dp_create_bridge(struct drm_device *drm_dev, bridge->driver_private = dp; bridge->funcs = &analogix_dp_bridge_funcs; - ret = drm_bridge_attach(dp->encoder, bridge, NULL, 0); - if (ret) { - DRM_ERROR("failed to attach drm bridge\n"); - return -EINVAL; - } - - return 0; + return drm_bridge_attach(dp->encoder, bridge, NULL, 0); } static int analogix_dp_dt_parse_pdata(struct analogix_dp_device *dp) diff --git a/drivers/gpu/drm/bridge/analogix/anx7625.c b/drivers/gpu/drm/bridge/analogix/anx7625.c index a3d82377066b..ef29197fed50 100644 --- a/drivers/gpu/drm/bridge/analogix/anx7625.c +++ b/drivers/gpu/drm/bridge/analogix/anx7625.c @@ -1359,11 +1359,8 @@ static int anx7625_bridge_attach(struct drm_bridge *bridge, err = drm_bridge_attach(bridge->encoder, ctx->pdata.panel_bridge, &ctx->bridge, flags); - if (err) { - DRM_DEV_ERROR(dev, - "Fail to attach panel bridge: %d\n", err); + if (err) return err; - } } ctx->bridge_attached = 1; diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c index e7c7c9b9c646..77af49248069 100644 --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c @@ -3474,7 +3474,6 @@ struct dw_hdmi *dw_hdmi_bind(struct platform_device *pdev, ret = drm_bridge_attach(encoder, &hdmi->bridge, NULL, 0); if (ret) { dw_hdmi_remove(hdmi); - DRM_ERROR("Failed to initialize bridge with drm\n"); return ERR_PTR(ret); } diff --git a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c index 6b268f9445b3..7900da1d4325 100644 --- a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c +++ b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c @@ -1229,15 +1229,7 @@ EXPORT_SYMBOL_GPL(dw_mipi_dsi_remove); */ int dw_mipi_dsi_bind(struct dw_mipi_dsi *dsi, struct drm_encoder *encoder) { - int ret; - - ret = drm_bridge_attach(encoder, &dsi->bridge, NULL, 0); - if (ret) { - DRM_ERROR("Failed to initialize bridge with drm\n"); - return ret; - } - - return ret; + return drm_bridge_attach(encoder, &dsi->bridge, NULL, 0); } EXPORT_SYMBOL_GPL(dw_mipi_dsi_bind); diff --git a/drivers/gpu/drm/drm_bridge.c b/drivers/gpu/drm/drm_bridge.c index 044acd07c153..11ec2846addb 100644 --- a/drivers/gpu/drm/drm_bridge.c +++ b/drivers/gpu/drm/drm_bridge.c @@ -28,6 +28,7 @@ #include #include #include +#include #include "drm_crtc_internal.h" @@ -225,6 +226,15 @@ err_reset_bridge: bridge->dev = NULL; bridge->encoder = NULL; list_del(&bridge->chain_node); + +#ifdef CONFIG_OF + DRM_ERROR("failed to attach bridge %pOF to encoder %s: %d\n", + bridge->of_node, encoder->name, ret); +#else + DRM_ERROR("failed to attach bridge to encoder %s: %d\n", + encoder->name, ret); +#endif + return ret; } EXPORT_SYMBOL(drm_bridge_attach); diff --git a/drivers/gpu/drm/exynos/exynos_dp.c b/drivers/gpu/drm/exynos/exynos_dp.c index 9ac51b6ab34b..27664f663c5a 100644 --- a/drivers/gpu/drm/exynos/exynos_dp.c +++ b/drivers/gpu/drm/exynos/exynos_dp.c @@ -109,11 +109,8 @@ static int exynos_dp_bridge_attach(struct analogix_dp_plat_data *plat_data, if (dp->ptn_bridge) { ret = drm_bridge_attach(&dp->encoder, dp->ptn_bridge, bridge, 0); - if (ret) { - DRM_DEV_ERROR(dp->dev, - "Failed to attach bridge to drm\n"); + if (ret) return ret; - } } return 0; diff --git a/drivers/gpu/drm/exynos/exynos_hdmi.c b/drivers/gpu/drm/exynos/exynos_hdmi.c index f893731d6021..c769dec576de 100644 --- a/drivers/gpu/drm/exynos/exynos_hdmi.c +++ b/drivers/gpu/drm/exynos/exynos_hdmi.c @@ -970,11 +970,8 @@ static int hdmi_create_connector(struct drm_encoder *encoder) drm_connector_helper_add(connector, &hdmi_connector_helper_funcs); drm_connector_attach_encoder(connector, encoder); - if (hdata->bridge) { + if (hdata->bridge) ret = drm_bridge_attach(encoder, hdata->bridge, NULL, 0); - if (ret) - DRM_DEV_ERROR(hdata->dev, "Failed to attach bridge\n"); - } cec_fill_conn_info_from_drm(&conn_info, connector); diff --git a/drivers/gpu/drm/hisilicon/kirin/dw_drm_dsi.c b/drivers/gpu/drm/hisilicon/kirin/dw_drm_dsi.c index 9b565a057340..952cfdb1961d 100644 --- a/drivers/gpu/drm/hisilicon/kirin/dw_drm_dsi.c +++ b/drivers/gpu/drm/hisilicon/kirin/dw_drm_dsi.c @@ -769,16 +769,9 @@ static int dsi_bridge_init(struct drm_device *dev, struct dw_dsi *dsi) { struct drm_encoder *encoder = &dsi->encoder; struct drm_bridge *bridge = dsi->bridge; - int ret; /* associate the bridge to dsi encoder */ - ret = drm_bridge_attach(encoder, bridge, NULL, 0); - if (ret) { - DRM_ERROR("failed to attach external bridge\n"); - return ret; - } - - return 0; + return drm_bridge_attach(encoder, bridge, NULL, 0); } static int dsi_bind(struct device *dev, struct device *master, void *data) diff --git a/drivers/gpu/drm/imx/dcss/dcss-kms.c b/drivers/gpu/drm/imx/dcss/dcss-kms.c index 917834b1c80e..9b84df34a6a1 100644 --- a/drivers/gpu/drm/imx/dcss/dcss-kms.c +++ b/drivers/gpu/drm/imx/dcss/dcss-kms.c @@ -93,11 +93,8 @@ static int dcss_kms_bridge_connector_init(struct dcss_kms_dev *kms) ret = drm_bridge_attach(encoder, bridge, NULL, DRM_BRIDGE_ATTACH_NO_CONNECTOR); - if (ret < 0) { - dev_err(ddev->dev, "Unable to attach bridge %pOF\n", - bridge->of_node); + if (ret < 0) return ret; - } kms->connector = drm_bridge_connector_init(ddev, encoder); if (IS_ERR(kms->connector)) { diff --git a/drivers/gpu/drm/imx/imx-ldb.c b/drivers/gpu/drm/imx/imx-ldb.c index 53132ddf9587..e5078d03020d 100644 --- a/drivers/gpu/drm/imx/imx-ldb.c +++ b/drivers/gpu/drm/imx/imx-ldb.c @@ -465,10 +465,8 @@ static int imx_ldb_register(struct drm_device *drm, if (imx_ldb_ch->bridge) { ret = drm_bridge_attach(encoder, imx_ldb_ch->bridge, NULL, 0); - if (ret) { - DRM_ERROR("Failed to initialize bridge with drm\n"); + if (ret) return ret; - } } else { /* * We want to add the connector whenever there is no bridge diff --git a/drivers/gpu/drm/imx/parallel-display.c b/drivers/gpu/drm/imx/parallel-display.c index e0412e694fd9..a8aba0141ce7 100644 --- a/drivers/gpu/drm/imx/parallel-display.c +++ b/drivers/gpu/drm/imx/parallel-display.c @@ -294,11 +294,8 @@ static int imx_pd_bind(struct device *dev, struct device *master, void *data) if (imxpd->next_bridge) { ret = drm_bridge_attach(encoder, imxpd->next_bridge, bridge, 0); - if (ret < 0) { - dev_err(imxpd->dev, "failed to attach bridge: %d\n", - ret); + if (ret < 0) return ret; - } } else { drm_connector_helper_add(connector, &imx_pd_connector_helper_funcs); diff --git a/drivers/gpu/drm/ingenic/ingenic-drm-drv.c b/drivers/gpu/drm/ingenic/ingenic-drm-drv.c index 857ed070b21b..d261f7a03b18 100644 --- a/drivers/gpu/drm/ingenic/ingenic-drm-drv.c +++ b/drivers/gpu/drm/ingenic/ingenic-drm-drv.c @@ -1081,10 +1081,8 @@ static int ingenic_drm_bind(struct device *dev, bool has_components) drm_encoder_helper_add(encoder, &ingenic_drm_encoder_helper_funcs); ret = drm_bridge_attach(encoder, bridge, NULL, 0); - if (ret) { - dev_err(dev, "Unable to attach bridge\n"); + if (ret) return ret; - } } drm_for_each_encoder(encoder, drm) { diff --git a/drivers/gpu/drm/kmb/kmb_dsi.c b/drivers/gpu/drm/kmb/kmb_dsi.c index 231041b269f5..1793cd31b117 100644 --- a/drivers/gpu/drm/kmb/kmb_dsi.c +++ b/drivers/gpu/drm/kmb/kmb_dsi.c @@ -1441,7 +1441,6 @@ int kmb_dsi_encoder_init(struct drm_device *dev, struct kmb_dsi *kmb_dsi) ret = drm_bridge_attach(encoder, adv_bridge, NULL, DRM_BRIDGE_ATTACH_NO_CONNECTOR); if (ret) { - DRM_ERROR("failed to attach bridge to MIPI\n"); drm_encoder_cleanup(encoder); return ret; } diff --git a/drivers/gpu/drm/mcde/mcde_dsi.c b/drivers/gpu/drm/mcde/mcde_dsi.c index 34a00d7e9c38..f3644667e24f 100644 --- a/drivers/gpu/drm/mcde/mcde_dsi.c +++ b/drivers/gpu/drm/mcde/mcde_dsi.c @@ -1052,7 +1052,6 @@ static int mcde_dsi_bridge_attach(struct drm_bridge *bridge, { struct mcde_dsi *d = bridge_to_mcde_dsi(bridge); struct drm_device *drm = bridge->dev; - int ret; if (!drm_core_check_feature(drm, DRIVER_ATOMIC)) { dev_err(d->dev, "we need atomic updates\n"); @@ -1060,13 +1059,7 @@ static int mcde_dsi_bridge_attach(struct drm_bridge *bridge, } /* Attach the DSI bridge to the output (panel etc) bridge */ - ret = drm_bridge_attach(bridge->encoder, d->bridge_out, bridge, flags); - if (ret) { - dev_err(d->dev, "failed to attach the DSI bridge\n"); - return ret; - } - - return 0; + return drm_bridge_attach(bridge->encoder, d->bridge_out, bridge, flags); } static const struct drm_bridge_funcs mcde_dsi_bridge_funcs = { diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c b/drivers/gpu/drm/mediatek/mtk_dpi.c index bced555648b0..96d35770c844 100644 --- a/drivers/gpu/drm/mediatek/mtk_dpi.c +++ b/drivers/gpu/drm/mediatek/mtk_dpi.c @@ -714,10 +714,8 @@ static int mtk_dpi_bind(struct device *dev, struct device *master, void *data) ret = drm_bridge_attach(&dpi->encoder, &dpi->bridge, NULL, DRM_BRIDGE_ATTACH_NO_CONNECTOR); - if (ret) { - dev_err(dev, "Failed to attach bridge: %d\n", ret); + if (ret) goto err_cleanup; - } dpi->connector = drm_bridge_connector_init(drm_dev, &dpi->encoder); if (IS_ERR(dpi->connector)) { diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi.c b/drivers/gpu/drm/mediatek/mtk_hdmi.c index c1651a83700d..5838c44cbf6f 100644 --- a/drivers/gpu/drm/mediatek/mtk_hdmi.c +++ b/drivers/gpu/drm/mediatek/mtk_hdmi.c @@ -1293,11 +1293,8 @@ static int mtk_hdmi_bridge_attach(struct drm_bridge *bridge, if (hdmi->next_bridge) { ret = drm_bridge_attach(bridge->encoder, hdmi->next_bridge, bridge, flags); - if (ret) { - dev_err(hdmi->dev, - "Failed to attach external bridge: %d\n", ret); + if (ret) return ret; - } } mtk_cec_set_hpd_event(hdmi->cec_dev, mtk_hdmi_hpd_event, hdmi->dev); diff --git a/drivers/gpu/drm/omapdrm/omap_drv.c b/drivers/gpu/drm/omapdrm/omap_drv.c index 8632139e0f01..f86e20578143 100644 --- a/drivers/gpu/drm/omapdrm/omap_drv.c +++ b/drivers/gpu/drm/omapdrm/omap_drv.c @@ -290,12 +290,8 @@ static int omap_modeset_init(struct drm_device *dev) ret = drm_bridge_attach(pipe->encoder, pipe->output->bridge, NULL, DRM_BRIDGE_ATTACH_NO_CONNECTOR); - if (ret < 0) { - dev_err(priv->dev, - "unable to attach bridge %pOF\n", - pipe->output->bridge->of_node); + if (ret < 0) return ret; - } } id = omap_display_id(pipe->output); diff --git a/drivers/gpu/drm/rockchip/rockchip_lvds.c b/drivers/gpu/drm/rockchip/rockchip_lvds.c index 489d63c05c0d..551653940e39 100644 --- a/drivers/gpu/drm/rockchip/rockchip_lvds.c +++ b/drivers/gpu/drm/rockchip/rockchip_lvds.c @@ -636,11 +636,8 @@ static int rockchip_lvds_bind(struct device *dev, struct device *master, } } else { ret = drm_bridge_attach(encoder, lvds->bridge, NULL, 0); - if (ret) { - DRM_DEV_ERROR(drm_dev->dev, - "failed to attach bridge: %d\n", ret); + if (ret) goto err_free_encoder; - } } pm_runtime_enable(dev); diff --git a/drivers/gpu/drm/rockchip/rockchip_rgb.c b/drivers/gpu/drm/rockchip/rockchip_rgb.c index c079714477d8..d691d9bef8e7 100644 --- a/drivers/gpu/drm/rockchip/rockchip_rgb.c +++ b/drivers/gpu/drm/rockchip/rockchip_rgb.c @@ -143,11 +143,8 @@ struct rockchip_rgb *rockchip_rgb_init(struct device *dev, rgb->bridge = bridge; ret = drm_bridge_attach(encoder, rgb->bridge, NULL, 0); - if (ret) { - DRM_DEV_ERROR(drm_dev->dev, - "failed to attach bridge: %d\n", ret); + if (ret) goto err_free_encoder; - } return rgb; diff --git a/drivers/gpu/drm/sti/sti_dvo.c b/drivers/gpu/drm/sti/sti_dvo.c index ddb4184f0726..b6ee8a82e656 100644 --- a/drivers/gpu/drm/sti/sti_dvo.c +++ b/drivers/gpu/drm/sti/sti_dvo.c @@ -463,10 +463,8 @@ static int sti_dvo_bind(struct device *dev, struct device *master, void *data) drm_bridge_add(bridge); err = drm_bridge_attach(encoder, bridge, NULL, 0); - if (err) { - DRM_ERROR("Failed to attach bridge\n"); + if (err) return err; - } dvo->bridge = bridge; connector->encoder = encoder; diff --git a/drivers/gpu/drm/sun4i/sun4i_lvds.c b/drivers/gpu/drm/sun4i/sun4i_lvds.c index ac570437172e..6716e895ae8a 100644 --- a/drivers/gpu/drm/sun4i/sun4i_lvds.c +++ b/drivers/gpu/drm/sun4i/sun4i_lvds.c @@ -142,10 +142,8 @@ int sun4i_lvds_init(struct drm_device *drm, struct sun4i_tcon *tcon) if (bridge) { ret = drm_bridge_attach(encoder, bridge, NULL, 0); - if (ret) { - dev_err(drm->dev, "Couldn't attach our bridge\n"); + if (ret) goto err_cleanup_connector; - } } return 0; diff --git a/drivers/gpu/drm/sun4i/sun4i_rgb.c b/drivers/gpu/drm/sun4i/sun4i_rgb.c index e172426eb7e9..dfb6acc42f02 100644 --- a/drivers/gpu/drm/sun4i/sun4i_rgb.c +++ b/drivers/gpu/drm/sun4i/sun4i_rgb.c @@ -234,10 +234,8 @@ int sun4i_rgb_init(struct drm_device *drm, struct sun4i_tcon *tcon) if (rgb->bridge) { ret = drm_bridge_attach(encoder, rgb->bridge, NULL, 0); - if (ret) { - dev_err(drm->dev, "Couldn't attach our bridge\n"); + if (ret) goto err_cleanup_connector; - } } return 0; diff --git a/drivers/gpu/drm/tegra/rgb.c b/drivers/gpu/drm/tegra/rgb.c index 4142a56ca764..606c78a2b988 100644 --- a/drivers/gpu/drm/tegra/rgb.c +++ b/drivers/gpu/drm/tegra/rgb.c @@ -275,11 +275,8 @@ int tegra_dc_rgb_init(struct drm_device *drm, struct tegra_dc *dc) if (output->bridge) { err = drm_bridge_attach(&output->encoder, output->bridge, NULL, DRM_BRIDGE_ATTACH_NO_CONNECTOR); - if (err) { - dev_err(output->dev, "failed to attach bridge: %d\n", - err); + if (err) return err; - } connector = drm_bridge_connector_init(drm, &output->encoder); if (IS_ERR(connector)) { diff --git a/drivers/gpu/drm/tidss/tidss_kms.c b/drivers/gpu/drm/tidss/tidss_kms.c index 95f8e0f78e32..666e527a0acf 100644 --- a/drivers/gpu/drm/tidss/tidss_kms.c +++ b/drivers/gpu/drm/tidss/tidss_kms.c @@ -227,10 +227,8 @@ static int tidss_dispc_modeset_init(struct tidss_device *tidss) } ret = drm_bridge_attach(enc, pipes[i].bridge, NULL, 0); - if (ret) { - dev_err(tidss->dev, "bridge attach failed: %d\n", ret); + if (ret) return ret; - } } /* create overlay planes of the leftover planes */ diff --git a/drivers/gpu/drm/tilcdc/tilcdc_external.c b/drivers/gpu/drm/tilcdc/tilcdc_external.c index b177525588c1..7594cf6e186e 100644 --- a/drivers/gpu/drm/tilcdc/tilcdc_external.c +++ b/drivers/gpu/drm/tilcdc/tilcdc_external.c @@ -93,10 +93,8 @@ int tilcdc_attach_bridge(struct drm_device *ddev, struct drm_bridge *bridge) priv->external_encoder->possible_crtcs = BIT(0); ret = drm_bridge_attach(priv->external_encoder, bridge, NULL, 0); - if (ret) { - dev_err(ddev->dev, "drm_bridge_attach() failed %d\n", ret); + if (ret) return ret; - } tilcdc_crtc_set_panel_info(priv->crtc, &panel_info_default); diff --git a/drivers/gpu/drm/vc4/vc4_dsi.c b/drivers/gpu/drm/vc4/vc4_dsi.c index a55256ed0955..a185027911ce 100644 --- a/drivers/gpu/drm/vc4/vc4_dsi.c +++ b/drivers/gpu/drm/vc4/vc4_dsi.c @@ -1646,10 +1646,8 @@ static int vc4_dsi_bind(struct device *dev, struct device *master, void *data) drm_encoder_helper_add(dsi->encoder, &vc4_dsi_encoder_helper_funcs); ret = drm_bridge_attach(dsi->encoder, dsi->bridge, NULL, 0); - if (ret) { - dev_err(dev, "bridge attach failed: %d\n", ret); + if (ret) return ret; - } /* Disable the atomic helper calls into the bridge. We * manually call the bridge pre_enable / enable / etc. calls * from our driver, since we need to sequence them within the -- cgit v1.2.3 From 5bcc48395b9f35dace564de47fcf434cdb67a8e1 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Thu, 14 May 2020 04:03:07 +0300 Subject: drm: bridge: dw-hdmi: Attach to next bridge if available On all platforms except i.MX and Rockchip, the dw-hdmi DT bindings require a video output port connected to an HDMI sink (most likely an HDMI connector, in rare cases another bridges converting HDMI to another protocol). For those platforms, retrieve the next bridge and attach it from the dw-hdmi bridge attach handler. Signed-off-by: Laurent Pinchart Reviewed-by: Neil Armstrong Tested-by: Kieran Bingham # On V3U Reviewed-by: Kieran Bingham --- drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 54 ++++++++++++++++++++++++++++++- include/drm/bridge/dw_hdmi.h | 2 ++ 2 files changed, 55 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c index 77af49248069..f08d0fded61f 100644 --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c @@ -143,6 +143,7 @@ struct dw_hdmi_phy_data { struct dw_hdmi { struct drm_connector connector; struct drm_bridge bridge; + struct drm_bridge *next_bridge; unsigned int version; @@ -2775,7 +2776,8 @@ static int dw_hdmi_bridge_attach(struct drm_bridge *bridge, struct dw_hdmi *hdmi = bridge->driver_private; if (flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR) - return 0; + return drm_bridge_attach(bridge->encoder, hdmi->next_bridge, + bridge, flags); return dw_hdmi_connector_create(hdmi); } @@ -3160,6 +3162,52 @@ static void dw_hdmi_init_hw(struct dw_hdmi *hdmi) /* ----------------------------------------------------------------------------- * Probe/remove API, used from platforms based on the DRM bridge API. */ + +static int dw_hdmi_parse_dt(struct dw_hdmi *hdmi) +{ + struct device_node *endpoint; + struct device_node *remote; + + if (!hdmi->plat_data->output_port) + return 0; + + endpoint = of_graph_get_endpoint_by_regs(hdmi->dev->of_node, + hdmi->plat_data->output_port, + -1); + if (!endpoint) { + /* + * On platforms whose bindings don't make the output port + * mandatory (such as Rockchip) the plat_data->output_port + * field isn't set, so it's safe to make this a fatal error. + */ + dev_err(hdmi->dev, "Missing endpoint in port@%u\n", + hdmi->plat_data->output_port); + return -ENODEV; + } + + remote = of_graph_get_remote_port_parent(endpoint); + of_node_put(endpoint); + if (!remote) { + dev_err(hdmi->dev, "Endpoint in port@%u unconnected\n", + hdmi->plat_data->output_port); + return -ENODEV; + } + + if (!of_device_is_available(remote)) { + dev_err(hdmi->dev, "port@%u remote device is disabled\n", + hdmi->plat_data->output_port); + of_node_put(remote); + return -ENODEV; + } + + hdmi->next_bridge = of_drm_find_bridge(remote); + of_node_put(remote); + if (!hdmi->next_bridge) + return -EPROBE_DEFER; + + return 0; +} + struct dw_hdmi *dw_hdmi_probe(struct platform_device *pdev, const struct dw_hdmi_plat_data *plat_data) { @@ -3196,6 +3244,10 @@ struct dw_hdmi *dw_hdmi_probe(struct platform_device *pdev, mutex_init(&hdmi->cec_notifier_mutex); spin_lock_init(&hdmi->audio_lock); + ret = dw_hdmi_parse_dt(hdmi); + if (ret < 0) + return ERR_PTR(ret); + ddc_node = of_parse_phandle(np, "ddc-i2c-bus", 0); if (ddc_node) { hdmi->ddc = of_get_i2c_adapter_by_node(ddc_node); diff --git a/include/drm/bridge/dw_hdmi.h b/include/drm/bridge/dw_hdmi.h index 6a5716655619..2a1f85f9a8a3 100644 --- a/include/drm/bridge/dw_hdmi.h +++ b/include/drm/bridge/dw_hdmi.h @@ -126,6 +126,8 @@ struct dw_hdmi_phy_ops { struct dw_hdmi_plat_data { struct regmap *regm; + unsigned int output_port; + unsigned long input_bus_encoding; bool use_drm_infoframe; bool ycbcr_420_allowed; -- cgit v1.2.3 From e9e056949c927e5bdfd0ee172ad95658f6c3c198 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Thu, 16 Apr 2020 01:29:53 +0300 Subject: drm: rcar-du: lvds: Convert to DRM panel bridge helper Replace the manual panel handling with usage of the DRM panel bridge helper. This simplifies the driver, and brings support for DRM_BRIDGE_ATTACH_NO_CONNECTOR as an added bonus. Signed-off-by: Laurent Pinchart Tested-by: Kieran Bingham # On V3U Reviewed-by: Kieran Bingham --- drivers/gpu/drm/rcar-du/rcar_lvds.c | 120 ++++-------------------------------- 1 file changed, 12 insertions(+), 108 deletions(-) diff --git a/drivers/gpu/drm/rcar-du/rcar_lvds.c b/drivers/gpu/drm/rcar-du/rcar_lvds.c index 70dbbe44bb23..1b360e06658c 100644 --- a/drivers/gpu/drm/rcar-du/rcar_lvds.c +++ b/drivers/gpu/drm/rcar-du/rcar_lvds.c @@ -63,7 +63,6 @@ struct rcar_lvds { struct drm_bridge bridge; struct drm_bridge *next_bridge; - struct drm_connector connector; struct drm_panel *panel; void __iomem *mmio; @@ -80,73 +79,11 @@ struct rcar_lvds { #define bridge_to_rcar_lvds(b) \ container_of(b, struct rcar_lvds, bridge) -#define connector_to_rcar_lvds(c) \ - container_of(c, struct rcar_lvds, connector) - static void rcar_lvds_write(struct rcar_lvds *lvds, u32 reg, u32 data) { iowrite32(data, lvds->mmio + reg); } -/* ----------------------------------------------------------------------------- - * Connector & Panel - */ - -static int rcar_lvds_connector_get_modes(struct drm_connector *connector) -{ - struct rcar_lvds *lvds = connector_to_rcar_lvds(connector); - - return drm_panel_get_modes(lvds->panel, connector); -} - -static int rcar_lvds_connector_atomic_check(struct drm_connector *connector, - struct drm_atomic_state *state) -{ - struct rcar_lvds *lvds = connector_to_rcar_lvds(connector); - const struct drm_display_mode *panel_mode; - struct drm_connector_state *conn_state; - struct drm_crtc_state *crtc_state; - - conn_state = drm_atomic_get_new_connector_state(state, connector); - if (!conn_state->crtc) - return 0; - - if (list_empty(&connector->modes)) { - dev_dbg(lvds->dev, "connector: empty modes list\n"); - return -EINVAL; - } - - panel_mode = list_first_entry(&connector->modes, - struct drm_display_mode, head); - - /* We're not allowed to modify the resolution. */ - crtc_state = drm_atomic_get_crtc_state(state, conn_state->crtc); - if (IS_ERR(crtc_state)) - return PTR_ERR(crtc_state); - - if (crtc_state->mode.hdisplay != panel_mode->hdisplay || - crtc_state->mode.vdisplay != panel_mode->vdisplay) - return -EINVAL; - - /* The flat panel mode is fixed, just copy it to the adjusted mode. */ - drm_mode_copy(&crtc_state->adjusted_mode, panel_mode); - - return 0; -} - -static const struct drm_connector_helper_funcs rcar_lvds_conn_helper_funcs = { - .get_modes = rcar_lvds_connector_get_modes, - .atomic_check = rcar_lvds_connector_atomic_check, -}; - -static const struct drm_connector_funcs rcar_lvds_conn_funcs = { - .reset = drm_atomic_helper_connector_reset, - .fill_modes = drm_helper_probe_single_connector_modes, - .destroy = drm_connector_cleanup, - .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, - .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, -}; - /* ----------------------------------------------------------------------------- * PLL Setup */ @@ -583,11 +520,6 @@ static void __rcar_lvds_atomic_enable(struct drm_bridge *bridge, /* Turn the output on. */ lvdcr0 |= LVDCR0_LVRES; rcar_lvds_write(lvds, LVDCR0, lvdcr0); - - if (lvds->panel) { - drm_panel_prepare(lvds->panel); - drm_panel_enable(lvds->panel); - } } static void rcar_lvds_atomic_enable(struct drm_bridge *bridge, @@ -609,11 +541,6 @@ static void rcar_lvds_atomic_disable(struct drm_bridge *bridge, { struct rcar_lvds *lvds = bridge_to_rcar_lvds(bridge); - if (lvds->panel) { - drm_panel_disable(lvds->panel); - drm_panel_unprepare(lvds->panel); - } - rcar_lvds_write(lvds, LVDCR0, 0); rcar_lvds_write(lvds, LVDCR1, 0); rcar_lvds_write(lvds, LVDPLLCR, 0); @@ -648,45 +575,13 @@ static int rcar_lvds_attach(struct drm_bridge *bridge, enum drm_bridge_attach_flags flags) { struct rcar_lvds *lvds = bridge_to_rcar_lvds(bridge); - struct drm_connector *connector = &lvds->connector; - struct drm_encoder *encoder = bridge->encoder; - int ret; - - /* If we have a next bridge just attach it. */ - if (lvds->next_bridge) - return drm_bridge_attach(bridge->encoder, lvds->next_bridge, - bridge, flags); - - if (flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR) { - DRM_ERROR("Fix bridge driver to make connector optional!"); - return -EINVAL; - } - - /* Otherwise if we have a panel, create a connector. */ - if (!lvds->panel) - return 0; - - ret = drm_connector_init(bridge->dev, connector, &rcar_lvds_conn_funcs, - DRM_MODE_CONNECTOR_LVDS); - if (ret < 0) - return ret; - - drm_connector_helper_add(connector, &rcar_lvds_conn_helper_funcs); - - ret = drm_connector_attach_encoder(connector, encoder); - if (ret < 0) - return ret; - - return 0; -} -static void rcar_lvds_detach(struct drm_bridge *bridge) -{ + return drm_bridge_attach(bridge->encoder, lvds->next_bridge, bridge, + flags); } static const struct drm_bridge_funcs rcar_lvds_bridge_ops = { .attach = rcar_lvds_attach, - .detach = rcar_lvds_detach, .atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state, .atomic_destroy_state = drm_atomic_helper_bridge_destroy_state, .atomic_reset = drm_atomic_helper_bridge_reset, @@ -759,7 +654,7 @@ static int rcar_lvds_parse_dt_companion(struct rcar_lvds *lvds) * that we are expected to generate even pixels from the primary * encoder, and odd pixels from the companion encoder. */ - if (lvds->next_bridge && lvds->next_bridge->timings && + if (lvds->next_bridge->timings && lvds->next_bridge->timings->dual_link) lvds->link_type = RCAR_LVDS_DUAL_LINK_EVEN_ODD_PIXELS; else @@ -811,6 +706,15 @@ static int rcar_lvds_parse_dt(struct rcar_lvds *lvds) if (ret) goto done; + if (lvds->panel) { + lvds->next_bridge = devm_drm_panel_bridge_add(lvds->dev, + lvds->panel); + if (IS_ERR_OR_NULL(lvds->next_bridge)) { + ret = -EINVAL; + goto done; + } + } + if (lvds->info->quirks & RCAR_LVDS_QUIRK_DUAL_LINK) ret = rcar_lvds_parse_dt_companion(lvds); -- cgit v1.2.3 From d0f44e0dac29aca3f85d238dfbcd2e52450b38dc Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Mon, 25 May 2020 07:05:26 +0300 Subject: drm: rcar-du: dw-hdmi: Set output port number Report the DT output port number in dw_hdmi_plat_data to connect to the next bridge in the dw-hdmi driver. Signed-off-by: Laurent Pinchart Tested-by: Kieran Bingham # On V3U Reviewed-by: Kieran Bingham --- drivers/gpu/drm/rcar-du/rcar_dw_hdmi.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/rcar-du/rcar_dw_hdmi.c b/drivers/gpu/drm/rcar-du/rcar_dw_hdmi.c index 7b8ec8310699..18ed14911b98 100644 --- a/drivers/gpu/drm/rcar-du/rcar_dw_hdmi.c +++ b/drivers/gpu/drm/rcar-du/rcar_dw_hdmi.c @@ -75,6 +75,7 @@ static int rcar_hdmi_phy_configure(struct dw_hdmi *hdmi, void *data, } static const struct dw_hdmi_plat_data rcar_dw_hdmi_plat_data = { + .output_port = 1, .mode_valid = rcar_hdmi_mode_valid, .configure_phy = rcar_hdmi_phy_configure, }; -- cgit v1.2.3 From c24110a8fd09ac754df36feeece4b98d072f0f64 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Mon, 25 May 2020 06:18:01 +0300 Subject: drm: rcar-du: Use drm_bridge_connector_init() helper Use the drm_bridge_connector_init() helper to create a drm_connector for each output, instead of relying on the bridge drivers doing so. Attach the bridges with the DRM_BRIDGE_ATTACH_NO_CONNECTOR flag to instruct them not to create a connector. Signed-off-by: Laurent Pinchart Reviewed-by: Jacopo Mondi Tested-by: Kieran Bingham # On V3U Reviewed-by: Kieran Bingham --- drivers/gpu/drm/rcar-du/rcar_du_encoder.c | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/rcar-du/rcar_du_encoder.c b/drivers/gpu/drm/rcar-du/rcar_du_encoder.c index ca3761772211..0daa8bba50f5 100644 --- a/drivers/gpu/drm/rcar-du/rcar_du_encoder.c +++ b/drivers/gpu/drm/rcar-du/rcar_du_encoder.c @@ -11,6 +11,7 @@ #include #include +#include #include #include #include @@ -53,7 +54,9 @@ int rcar_du_encoder_init(struct rcar_du_device *rcdu, struct device_node *enc_node) { struct rcar_du_encoder *renc; + struct drm_connector *connector; struct drm_bridge *bridge; + int ret; /* * Locate the DRM bridge from the DT node. For the DPAD outputs, if the @@ -103,9 +106,22 @@ int rcar_du_encoder_init(struct rcar_du_device *rcdu, renc->output = output; - /* - * Attach the bridge to the encoder. The bridge will create the - * connector. - */ - return drm_bridge_attach(&renc->base, bridge, NULL, 0); + /* Attach the bridge to the encoder. */ + ret = drm_bridge_attach(&renc->base, bridge, NULL, + DRM_BRIDGE_ATTACH_NO_CONNECTOR); + if (ret) { + dev_err(rcdu->dev, "failed to attach bridge for output %u\n", + output); + return ret; + } + + /* Create the connector for the chain of bridges. */ + connector = drm_bridge_connector_init(&rcdu->ddev, &renc->base); + if (IS_ERR(connector)) { + dev_err(rcdu->dev, + "failed to created connector for output %u\n", output); + return PTR_ERR(connector); + } + + return drm_connector_attach_encoder(connector, &renc->base); } -- cgit v1.2.3 From 9b54182ce23946674231bbe3ee22f89dfe274cab Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Thu, 15 Apr 2021 05:16:42 +0300 Subject: drm: rcar-du: lvds: Don't set bridge driver_private field The drm_bridge.driver_private field is set but never used. Don't set it. Signed-off-by: Laurent Pinchart Reviewed-by: Kieran Bingham --- drivers/gpu/drm/rcar-du/rcar_lvds.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/gpu/drm/rcar-du/rcar_lvds.c b/drivers/gpu/drm/rcar-du/rcar_lvds.c index 1b360e06658c..0804a2773e56 100644 --- a/drivers/gpu/drm/rcar-du/rcar_lvds.c +++ b/drivers/gpu/drm/rcar-du/rcar_lvds.c @@ -823,7 +823,6 @@ static int rcar_lvds_probe(struct platform_device *pdev) if (ret < 0) return ret; - lvds->bridge.driver_private = lvds; lvds->bridge.funcs = &rcar_lvds_bridge_ops; lvds->bridge.of_node = pdev->dev.of_node; -- cgit v1.2.3 From 6571a76af380290dd9a003a3bc90d4779ec4f8f8 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Thu, 15 Apr 2021 05:23:15 +0300 Subject: drm: rcar-du: lvds: Use dev_err_probe() Simplify error handling by using the dev_err_probe() function. Signed-off-by: Laurent Pinchart Reviewed-by: Kieran Bingham --- drivers/gpu/drm/rcar-du/rcar_lvds.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/rcar-du/rcar_lvds.c b/drivers/gpu/drm/rcar-du/rcar_lvds.c index 0804a2773e56..d061b8de748f 100644 --- a/drivers/gpu/drm/rcar-du/rcar_lvds.c +++ b/drivers/gpu/drm/rcar-du/rcar_lvds.c @@ -743,9 +743,8 @@ static struct clk *rcar_lvds_get_clock(struct rcar_lvds *lvds, const char *name, if (PTR_ERR(clk) == -ENOENT && optional) return NULL; - if (PTR_ERR(clk) != -EPROBE_DEFER) - dev_err(lvds->dev, "failed to get %s clock\n", - name ? name : "module"); + dev_err_probe(lvds->dev, PTR_ERR(clk), "failed to get %s clock\n", + name ? name : "module"); return clk; } -- cgit v1.2.3