Hi Marek, 22. 5. 13. 17:31에 Marek Szyprowski 이(가) 쓴 글: > Commit dd8b6803bc49 ("exynos: drm: dsi: Attach in_bridge in MIC driver") > moved Exynos MIC attaching from DSI to MIC driver. However the method > proposed there is incomplete and cannot really work. To properly attach > it to the bridge chain, access to the respective encoder is needed. The > Exynos MIC driver always attaches to the encoder created by the Exynos > DSI driver, so grab it via available helpers for getting access to the > CRTC and encoders. This also requires to change the order of driver > component binding to let DSI to be bound before MIC. > > Fixes: dd8b6803bc49 ("exynos: drm: dsi: Attach in_bridge in MIC driver") > Signed-off-by: Marek Szyprowski <m.szyprowski@xxxxxxxxxxx> > --- > A few words of comment. The mentioned commit has my Tested-by tag and > indeed I gave it. However that time due to remote work and incorrect > camera configuration in the office I was not able to check if the board > really produces valid display, I only checked if it boots and reports > valid DRM structures to the userspace. > > If possible, please merge this to the drm-misc-next together with the > rest of Exynos DSI to drm bridge rework patches. The commit-id, dd8b6803bc49, has already been merged to drm-next. Seems no need to go drm-misc-next. So I will merge it as a regression fix after the review, which will be merged to 5.19-rc series. Please let me know if there is my missing something. Thanks, Inki Dae > --- > drivers/gpu/drm/exynos/exynos_drm_drv.c | 6 ++-- > drivers/gpu/drm/exynos/exynos_drm_mic.c | 42 +++++++------------------ > 2 files changed, 15 insertions(+), 33 deletions(-) > > diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.c b/drivers/gpu/drm/exynos/exynos_drm_drv.c > index 424ea23eec32..16c539657f73 100644 > --- a/drivers/gpu/drm/exynos/exynos_drm_drv.c > +++ b/drivers/gpu/drm/exynos/exynos_drm_drv.c > @@ -176,15 +176,15 @@ static struct exynos_drm_driver_info exynos_drm_drivers[] = { > }, { > DRV_PTR(mixer_driver, CONFIG_DRM_EXYNOS_MIXER), > DRM_COMPONENT_DRIVER > - }, { > - DRV_PTR(mic_driver, CONFIG_DRM_EXYNOS_MIC), > - DRM_COMPONENT_DRIVER > }, { > DRV_PTR(dp_driver, CONFIG_DRM_EXYNOS_DP), > DRM_COMPONENT_DRIVER > }, { > DRV_PTR(dsi_driver, CONFIG_DRM_EXYNOS_DSI), > DRM_COMPONENT_DRIVER > + }, { > + DRV_PTR(mic_driver, CONFIG_DRM_EXYNOS_MIC), > + DRM_COMPONENT_DRIVER > }, { > DRV_PTR(hdmi_driver, CONFIG_DRM_EXYNOS_HDMI), > DRM_COMPONENT_DRIVER > diff --git a/drivers/gpu/drm/exynos/exynos_drm_mic.c b/drivers/gpu/drm/exynos/exynos_drm_mic.c > index 9e06f8e2a863..09ce28ee08d9 100644 > --- a/drivers/gpu/drm/exynos/exynos_drm_mic.c > +++ b/drivers/gpu/drm/exynos/exynos_drm_mic.c > @@ -26,6 +26,7 @@ > #include <drm/drm_print.h> > > #include "exynos_drm_drv.h" > +#include "exynos_drm_crtc.h" > > /* Sysreg registers for MIC */ > #define DSD_CFG_MUX 0x1004 > @@ -100,9 +101,7 @@ struct exynos_mic { > > bool i80_mode; > struct videomode vm; > - struct drm_encoder *encoder; > struct drm_bridge bridge; > - struct drm_bridge *next_bridge; > > bool enabled; > }; > @@ -229,8 +228,6 @@ static void mic_set_reg_on(struct exynos_mic *mic, bool enable) > writel(reg, mic->reg + MIC_OP); > } > > -static void mic_disable(struct drm_bridge *bridge) { } > - > static void mic_post_disable(struct drm_bridge *bridge) > { > struct exynos_mic *mic = bridge->driver_private; > @@ -297,34 +294,30 @@ static void mic_pre_enable(struct drm_bridge *bridge) > mutex_unlock(&mic_mutex); > } > > -static void mic_enable(struct drm_bridge *bridge) { } > - > -static int mic_attach(struct drm_bridge *bridge, > - enum drm_bridge_attach_flags flags) > -{ > - struct exynos_mic *mic = bridge->driver_private; > - > - return drm_bridge_attach(bridge->encoder, mic->next_bridge, > - &mic->bridge, flags); > -} > - > static const struct drm_bridge_funcs mic_bridge_funcs = { > - .disable = mic_disable, > .post_disable = mic_post_disable, > .mode_set = mic_mode_set, > .pre_enable = mic_pre_enable, > - .enable = mic_enable, > - .attach = mic_attach, > }; > > static int exynos_mic_bind(struct device *dev, struct device *master, > void *data) > { > struct exynos_mic *mic = dev_get_drvdata(dev); > + struct drm_device *drm_dev = data; > + struct exynos_drm_crtc *crtc = exynos_drm_crtc_get_by_type(drm_dev, > + EXYNOS_DISPLAY_TYPE_LCD); > + struct drm_encoder *e, *encoder = NULL; > + > + drm_for_each_encoder(e, drm_dev) > + if (e->possible_crtcs == drm_crtc_mask(&crtc->base)) > + encoder = e; > + if (!encoder) > + return -ENODEV; > > mic->bridge.driver_private = mic; > > - return 0; > + return drm_bridge_attach(encoder, &mic->bridge, NULL, 0); > } > > static void exynos_mic_unbind(struct device *dev, struct device *master, > @@ -388,7 +381,6 @@ static int exynos_mic_probe(struct platform_device *pdev) > { > struct device *dev = &pdev->dev; > struct exynos_mic *mic; > - struct device_node *remote; > struct resource res; > int ret, i; > > @@ -432,16 +424,6 @@ static int exynos_mic_probe(struct platform_device *pdev) > } > } > > - remote = of_graph_get_remote_node(dev->of_node, 1, 0); > - mic->next_bridge = of_drm_find_bridge(remote); > - if (IS_ERR(mic->next_bridge)) { > - DRM_DEV_ERROR(dev, "mic: Failed to find next bridge\n"); > - ret = PTR_ERR(mic->next_bridge); > - goto err; > - } > - > - of_node_put(remote); > - > platform_set_drvdata(pdev, mic); > > mic->bridge.funcs = &mic_bridge_funcs;