The common connector setup in msm_kms_init_connectors() calls the type-specific msm_dsi_modeset_init(), msm_dp_modeset_init() and msm_hdmi_modeset_init() functions, so it has to know about each concrete sub-block type.
Introduce a small struct msm_display interface with a modeset_init() callback, embedded in struct hdmi, struct msm_dsi and struct msm_dp. Each sub-block registers its ops and provides a msm_*_get_display() accessor; the common code then dispatches through display->funcs->modeset_init() without knowing the concrete type. Further per-sub-block operations will be folded into this interface in following patches. No functional change intended. Assisted-by: Claude:claude-opus-4-8 Signed-off-by: Dmitry Baryshkov <[email protected]> --- drivers/gpu/drm/msm/dp/dp_display.c | 17 ++++++++-- drivers/gpu/drm/msm/dp/dp_display.h | 2 ++ drivers/gpu/drm/msm/dsi/dsi.c | 18 ++++++++-- drivers/gpu/drm/msm/dsi/dsi.h | 2 ++ drivers/gpu/drm/msm/hdmi/hdmi.c | 13 +++++++- drivers/gpu/drm/msm/hdmi/hdmi.h | 2 ++ drivers/gpu/drm/msm/msm_drv.h | 50 ++++++++++++++++++---------- drivers/gpu/drm/msm/msm_kms.c | 66 ++++++++++++++++++------------------- 8 files changed, 115 insertions(+), 55 deletions(-) diff --git a/drivers/gpu/drm/msm/dp/dp_display.c b/drivers/gpu/drm/msm/dp/dp_display.c index 5ae5eed7e010..79dd556e96c2 100644 --- a/drivers/gpu/drm/msm/dp/dp_display.c +++ b/drivers/gpu/drm/msm/dp/dp_display.c @@ -203,6 +203,8 @@ void msm_dp_display_signal_audio_complete(struct msm_dp *msm_dp_display) complete_all(&dp->audio_comp); } +static const struct msm_display_funcs msm_dp_display_funcs; + static int msm_dp_display_bind(struct device *dev, struct device *master, void *data) { @@ -212,6 +214,7 @@ static int msm_dp_display_bind(struct device *dev, struct device *master, struct drm_device *drm = priv->dev; dp->msm_dp_display.drm_dev = drm; + dp->msm_dp_display.display.funcs = &msm_dp_display_funcs; priv->kms->dp[dp->id] = &dp->msm_dp_display; dp->drm_dev = drm; @@ -1317,9 +1320,10 @@ void msm_dp_display_debugfs_init(struct msm_dp *msm_dp_display, struct dentry *r DRM_ERROR("failed to initialize debug, rc = %d\n", rc); } -int msm_dp_modeset_init(struct msm_dp *msm_dp_display, struct drm_device *dev, - struct drm_encoder *encoder) +static int msm_dp_modeset_init(struct msm_display *display, + struct drm_device *dev, struct drm_encoder *encoder) { + struct msm_dp *msm_dp_display = container_of(display, struct msm_dp, display); struct msm_dp_display_private *msm_dp_priv; int ret; @@ -1348,6 +1352,15 @@ int msm_dp_modeset_init(struct msm_dp *msm_dp_display, struct drm_device *dev, return 0; } +static const struct msm_display_funcs msm_dp_display_funcs = { + .modeset_init = msm_dp_modeset_init, +}; + +struct msm_display *msm_dp_get_display(struct msm_dp *msm_dp_display) +{ + return msm_dp_display ? &msm_dp_display->display : NULL; +} + void msm_dp_bridge_atomic_enable(struct drm_bridge *drm_bridge, struct drm_atomic_commit *state) { diff --git a/drivers/gpu/drm/msm/dp/dp_display.h b/drivers/gpu/drm/msm/dp/dp_display.h index 0b65e16c790d..20a71afb1f90 100644 --- a/drivers/gpu/drm/msm/dp/dp_display.h +++ b/drivers/gpu/drm/msm/dp/dp_display.h @@ -12,6 +12,8 @@ #define DP_MAX_PIXEL_CLK_KHZ 675000 struct msm_dp { + struct msm_display display; + struct drm_device *drm_dev; struct platform_device *pdev; struct drm_connector *connector; diff --git a/drivers/gpu/drm/msm/dsi/dsi.c b/drivers/gpu/drm/msm/dsi/dsi.c index 3c9f01ed6271..6cd844d08733 100644 --- a/drivers/gpu/drm/msm/dsi/dsi.c +++ b/drivers/gpu/drm/msm/dsi/dsi.c @@ -115,6 +115,8 @@ static struct msm_dsi *dsi_init(struct platform_device *pdev) return ERR_PTR(ret); } +static const struct msm_display_funcs msm_dsi_display_funcs; + static int dsi_bind(struct device *dev, struct device *master, void *data) { struct msm_drm_private *priv = dev_get_drvdata(master); @@ -136,6 +138,7 @@ static int dsi_bind(struct device *dev, struct device *master, void *data) msm_dsi->next_bridge = ext_bridge; } + msm_dsi->display.funcs = &msm_dsi_display_funcs; priv->kms->dsi[msm_dsi->id] = msm_dsi; return 0; @@ -230,9 +233,11 @@ void __exit msm_dsi_unregister(void) platform_driver_unregister(&dsi_driver); } -int msm_dsi_modeset_init(struct msm_dsi *msm_dsi, struct drm_device *dev, - struct drm_encoder *encoder) +static int msm_dsi_modeset_init(struct msm_display *display, + struct drm_device *dev, + struct drm_encoder *encoder) { + struct msm_dsi *msm_dsi = container_of(display, struct msm_dsi, display); int ret; msm_dsi->dev = dev; @@ -262,6 +267,15 @@ int msm_dsi_modeset_init(struct msm_dsi *msm_dsi, struct drm_device *dev, return 0; } +static const struct msm_display_funcs msm_dsi_display_funcs = { + .modeset_init = msm_dsi_modeset_init, +}; + +struct msm_display *msm_dsi_get_display(struct msm_dsi *msm_dsi) +{ + return msm_dsi ? &msm_dsi->display : NULL; +} + void msm_dsi_snapshot(struct msm_disp_state *disp_state, struct msm_dsi *msm_dsi) { msm_dsi_host_snapshot(disp_state, msm_dsi->host); diff --git a/drivers/gpu/drm/msm/dsi/dsi.h b/drivers/gpu/drm/msm/dsi/dsi.h index 93c028a122f3..1d1bda0682db 100644 --- a/drivers/gpu/drm/msm/dsi/dsi.h +++ b/drivers/gpu/drm/msm/dsi/dsi.h @@ -32,6 +32,8 @@ enum msm_dsi_phy_usecase { #define DSI_BUS_CLK_MAX 4 struct msm_dsi { + struct msm_display display; + struct drm_device *dev; struct platform_device *pdev; diff --git a/drivers/gpu/drm/msm/hdmi/hdmi.c b/drivers/gpu/drm/msm/hdmi/hdmi.c index 474006084633..03367c6ba428 100644 --- a/drivers/gpu/drm/msm/hdmi/hdmi.c +++ b/drivers/gpu/drm/msm/hdmi/hdmi.c @@ -159,9 +159,10 @@ static int msm_hdmi_init(struct hdmi *hdmi) * should be handled in msm_hdmi_init() so that failure happens from * hdmi sub-device's probe. */ -int msm_hdmi_modeset_init(struct hdmi *hdmi, +static int msm_hdmi_modeset_init(struct msm_display *display, struct drm_device *dev, struct drm_encoder *encoder) { + struct hdmi *hdmi = container_of(display, struct hdmi, display); int ret; hdmi->dev = dev; @@ -210,6 +211,15 @@ int msm_hdmi_modeset_init(struct hdmi *hdmi, return ret; } +static const struct msm_display_funcs msm_hdmi_display_funcs = { + .modeset_init = msm_hdmi_modeset_init, +}; + +struct msm_display *msm_hdmi_get_display(struct hdmi *hdmi) +{ + return hdmi ? &hdmi->display : NULL; +} + /* * The hdmi device: */ @@ -243,6 +253,7 @@ static int msm_hdmi_bind(struct device *dev, struct device *master, void *data) err = msm_hdmi_init(hdmi); if (err) return err; + hdmi->display.funcs = &msm_hdmi_display_funcs; priv->kms->hdmi = hdmi; return 0; diff --git a/drivers/gpu/drm/msm/hdmi/hdmi.h b/drivers/gpu/drm/msm/hdmi/hdmi.h index 49433f7727c3..f24444610fe1 100644 --- a/drivers/gpu/drm/msm/hdmi/hdmi.h +++ b/drivers/gpu/drm/msm/hdmi/hdmi.h @@ -31,6 +31,8 @@ struct hdmi_audio { struct hdmi_hdcp_ctrl; struct hdmi { + struct msm_display display; + struct drm_device *dev; struct platform_device *pdev; diff --git a/drivers/gpu/drm/msm/msm_drv.h b/drivers/gpu/drm/msm/msm_drv.h index 0ec0622d9217..dbd955091ce7 100644 --- a/drivers/gpu/drm/msm/msm_drv.h +++ b/drivers/gpu/drm/msm/msm_drv.h @@ -274,17 +274,39 @@ int msm_fbdev_driver_fbdev_probe(struct drm_fb_helper *helper, .fbdev_probe = NULL #endif +struct msm_display; + +/** + * struct msm_display_funcs - ops provided by a display sub-block (DSI/DP/HDMI) + * @modeset_init: create the bridge and connector for the sub-block, attaching + * to @encoder. + */ +struct msm_display_funcs { + int (*modeset_init)(struct msm_display *display, struct drm_device *dev, + struct drm_encoder *encoder); +}; + +/** + * struct msm_display - common interface to a display sub-block + * @funcs: sub-block provided ops + * + * Embedded in each sub-block (&struct hdmi, &struct msm_dsi, &struct msm_dp) + * so that common KMS code can set up their connectors without knowing the + * concrete type. + */ +struct msm_display { + const struct msm_display_funcs *funcs; +}; + struct hdmi; #ifdef CONFIG_DRM_MSM_HDMI -int msm_hdmi_modeset_init(struct hdmi *hdmi, struct drm_device *dev, - struct drm_encoder *encoder); +struct msm_display *msm_hdmi_get_display(struct hdmi *hdmi); void __init msm_hdmi_register(void); void __exit msm_hdmi_unregister(void); #else -static inline int msm_hdmi_modeset_init(struct hdmi *hdmi, struct drm_device *dev, - struct drm_encoder *encoder) +static inline struct msm_display *msm_hdmi_get_display(struct hdmi *hdmi) { - return -EINVAL; + return NULL; } static inline void __init msm_hdmi_register(void) {} static inline void __exit msm_hdmi_unregister(void) {} @@ -296,8 +318,7 @@ int dsi_dev_attach(struct platform_device *pdev); void dsi_dev_detach(struct platform_device *pdev); void __init msm_dsi_register(void); void __exit msm_dsi_unregister(void); -int msm_dsi_modeset_init(struct msm_dsi *msm_dsi, struct drm_device *dev, - struct drm_encoder *encoder); +struct msm_display *msm_dsi_get_display(struct msm_dsi *msm_dsi); void msm_dsi_snapshot(struct msm_disp_state *disp_state, struct msm_dsi *msm_dsi); bool msm_dsi_is_cmd_mode(struct msm_dsi *msm_dsi); bool msm_dsi_is_bonded_dsi(struct msm_dsi *msm_dsi); @@ -312,11 +333,9 @@ static inline void __init msm_dsi_register(void) static inline void __exit msm_dsi_unregister(void) { } -static inline int msm_dsi_modeset_init(struct msm_dsi *msm_dsi, - struct drm_device *dev, - struct drm_encoder *encoder) +static inline struct msm_display *msm_dsi_get_display(struct msm_dsi *msm_dsi) { - return -EINVAL; + return NULL; } static inline void msm_dsi_snapshot(struct msm_disp_state *disp_state, struct msm_dsi *msm_dsi) { @@ -353,8 +372,7 @@ struct msm_dp; #ifdef CONFIG_DRM_MSM_DP int __init msm_dp_register(void); void __exit msm_dp_unregister(void); -int msm_dp_modeset_init(struct msm_dp *dp_display, struct drm_device *dev, - struct drm_encoder *encoder); +struct msm_display *msm_dp_get_display(struct msm_dp *dp_display); void msm_dp_snapshot(struct msm_disp_state *disp_state, struct msm_dp *dp_display); bool msm_dp_needs_periph_flush(const struct msm_dp *dp_display, const struct drm_display_mode *mode); @@ -368,11 +386,9 @@ static inline int __init msm_dp_register(void) static inline void __exit msm_dp_unregister(void) { } -static inline int msm_dp_modeset_init(struct msm_dp *dp_display, - struct drm_device *dev, - struct drm_encoder *encoder) +static inline struct msm_display *msm_dp_get_display(struct msm_dp *dp_display) { - return -EINVAL; + return NULL; } static inline void msm_dp_snapshot(struct msm_disp_state *disp_state, struct msm_dp *dp_display) diff --git a/drivers/gpu/drm/msm/msm_kms.c b/drivers/gpu/drm/msm/msm_kms.c index 87530145e82b..3f855f9b3d06 100644 --- a/drivers/gpu/drm/msm/msm_kms.c +++ b/drivers/gpu/drm/msm/msm_kms.c @@ -260,9 +260,24 @@ void msm_drm_kms_uninit(struct device *dev) kms->funcs->destroy(kms); } +static int msm_display_modeset_init(struct msm_display *display, + struct drm_device *ddev, + struct drm_encoder *encoder) +{ + if (!display) + return 0; + + return display->funcs->modeset_init(display, ddev, encoder); +} + /* - * Set up the bridges and connectors for the display sub-blocks, using the - * encoders the backend created in ->kms_init(). + * Set up the bridges and connectors for the display sub-blocks, dispatching + * through the common display interface using the encoders the backend created + * in ->kms_init(). + * + * The slave link of a bonded DSI pair shares its master's encoder and creates + * no connector of its own; its ->modeset_init() handles that internally, so it + * needs no special-casing here. */ static int msm_kms_init_connectors(struct drm_device *ddev) { @@ -270,45 +285,30 @@ static int msm_kms_init_connectors(struct drm_device *ddev) struct msm_kms *kms = priv->kms; int i, ret; - /* - * The slave link of a bonded DSI pair shares its master's encoder and - * creates no connector of its own; msm_dsi_modeset_init() handles that - * internally, so it needs no special-casing here. - */ for (i = 0; i < ARRAY_SIZE(kms->dsi); i++) { - if (!kms->dsi[i]) - continue; - - ret = msm_dsi_modeset_init(kms->dsi[i], ddev, kms->dsi_encoder[i]); - if (ret) { - DRM_DEV_ERROR(ddev->dev, - "modeset_init failed for dsi[%d]: %d\n", i, ret); - return ret; - } + ret = msm_display_modeset_init(msm_dsi_get_display(kms->dsi[i]), + ddev, kms->dsi_encoder[i]); + if (ret) + goto fail; } for (i = 0; i < ARRAY_SIZE(kms->dp); i++) { - if (!kms->dp[i]) - continue; - - ret = msm_dp_modeset_init(kms->dp[i], ddev, kms->dp_encoder[i]); - if (ret) { - DRM_DEV_ERROR(ddev->dev, - "modeset_init failed for dp[%d]: %d\n", i, ret); - return ret; - } + ret = msm_display_modeset_init(msm_dp_get_display(kms->dp[i]), + ddev, kms->dp_encoder[i]); + if (ret) + goto fail; } - if (kms->hdmi) { - ret = msm_hdmi_modeset_init(kms->hdmi, ddev, kms->hdmi_encoder); - if (ret) { - DRM_DEV_ERROR(ddev->dev, - "modeset_init failed for HDMI: %d\n", ret); - return ret; - } - } + ret = msm_display_modeset_init(msm_hdmi_get_display(kms->hdmi), + ddev, kms->hdmi_encoder); + if (ret) + goto fail; return 0; + +fail: + DRM_DEV_ERROR(ddev->dev, "modeset_init failed: %d\n", ret); + return ret; } int msm_drm_kms_init(struct device *dev, const struct drm_driver *drv) -- 2.47.3
