Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

drm/exynos: mic: Rework initialization

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@samsung.com>
Fixed merge conflict.
Signed-off-by: Inki Dae <inki.dae@samsung.com>

authored by

Marek Szyprowski and committed by
Inki Dae
7d787184 5c2b7451

+15 -33
+3 -3
drivers/gpu/drm/exynos/exynos_drm_drv.c
··· 177 177 DRV_PTR(mixer_driver, CONFIG_DRM_EXYNOS_MIXER), 178 178 DRM_COMPONENT_DRIVER 179 179 }, { 180 - DRV_PTR(mic_driver, CONFIG_DRM_EXYNOS_MIC), 181 - DRM_COMPONENT_DRIVER 182 - }, { 183 180 DRV_PTR(dp_driver, CONFIG_DRM_EXYNOS_DP), 184 181 DRM_COMPONENT_DRIVER 185 182 }, { 186 183 DRV_PTR(dsi_driver, CONFIG_DRM_EXYNOS_DSI), 184 + DRM_COMPONENT_DRIVER 185 + }, { 186 + DRV_PTR(mic_driver, CONFIG_DRM_EXYNOS_MIC), 187 187 DRM_COMPONENT_DRIVER 188 188 }, { 189 189 DRV_PTR(hdmi_driver, CONFIG_DRM_EXYNOS_HDMI),
+12 -30
drivers/gpu/drm/exynos/exynos_drm_mic.c
··· 26 26 #include <drm/drm_print.h> 27 27 28 28 #include "exynos_drm_drv.h" 29 + #include "exynos_drm_crtc.h" 29 30 30 31 /* Sysreg registers for MIC */ 31 32 #define DSD_CFG_MUX 0x1004 ··· 101 100 102 101 bool i80_mode; 103 102 struct videomode vm; 104 - struct drm_encoder *encoder; 105 103 struct drm_bridge bridge; 106 - struct drm_bridge *next_bridge; 107 104 108 105 bool enabled; 109 106 }; ··· 228 229 writel(reg, mic->reg + MIC_OP); 229 230 } 230 231 231 - static void mic_disable(struct drm_bridge *bridge) { } 232 - 233 232 static void mic_post_disable(struct drm_bridge *bridge) 234 233 { 235 234 struct exynos_mic *mic = bridge->driver_private; ··· 294 297 mutex_unlock(&mic_mutex); 295 298 } 296 299 297 - static void mic_enable(struct drm_bridge *bridge) { } 298 - 299 - static int mic_attach(struct drm_bridge *bridge, 300 - enum drm_bridge_attach_flags flags) 301 - { 302 - struct exynos_mic *mic = bridge->driver_private; 303 - 304 - return drm_bridge_attach(bridge->encoder, mic->next_bridge, 305 - &mic->bridge, flags); 306 - } 307 - 308 300 static const struct drm_bridge_funcs mic_bridge_funcs = { 309 - .disable = mic_disable, 310 301 .post_disable = mic_post_disable, 311 302 .mode_set = mic_mode_set, 312 303 .pre_enable = mic_pre_enable, 313 - .enable = mic_enable, 314 - .attach = mic_attach, 315 304 }; 316 305 317 306 static int exynos_mic_bind(struct device *dev, struct device *master, 318 307 void *data) 319 308 { 320 309 struct exynos_mic *mic = dev_get_drvdata(dev); 310 + struct drm_device *drm_dev = data; 311 + struct exynos_drm_crtc *crtc = exynos_drm_crtc_get_by_type(drm_dev, 312 + EXYNOS_DISPLAY_TYPE_LCD); 313 + struct drm_encoder *e, *encoder = NULL; 314 + 315 + drm_for_each_encoder(e, drm_dev) 316 + if (e->possible_crtcs == drm_crtc_mask(&crtc->base)) 317 + encoder = e; 318 + if (!encoder) 319 + return -ENODEV; 321 320 322 321 mic->bridge.driver_private = mic; 323 322 324 - return 0; 323 + return drm_bridge_attach(encoder, &mic->bridge, NULL, 0); 325 324 } 326 325 327 326 static void exynos_mic_unbind(struct device *dev, struct device *master, ··· 381 388 { 382 389 struct device *dev = &pdev->dev; 383 390 struct exynos_mic *mic; 384 - struct device_node *remote; 385 391 struct resource res; 386 392 int ret, i; 387 393 ··· 423 431 goto err; 424 432 } 425 433 } 426 - 427 - remote = of_graph_get_remote_node(dev->of_node, 1, 0); 428 - mic->next_bridge = of_drm_find_bridge(remote); 429 - if (!mic->next_bridge) { 430 - DRM_DEV_ERROR(dev, "mic: Failed to find next bridge\n"); 431 - ret = -EPROBE_DEFER; 432 - goto err; 433 - } 434 - 435 - of_node_put(remote); 436 434 437 435 platform_set_drvdata(pdev, mic); 438 436