diff mbox series

drm/exynos: mic: Rework initialization

Message ID 20220513083105.9456-1-m.szyprowski@samsung.com
State New
Headers show
Series drm/exynos: mic: Rework initialization | expand

Commit Message

Marek Szyprowski May 13, 2022, 8:31 a.m. UTC
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>
---
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.
---
 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(-)

Comments

대인기/Tizen Platform Lab(SR)/삼성전자 May 16, 2022, 12:50 a.m. UTC | #1
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@samsung.com>
> ---
> 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;
diff mbox series

Patch

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;