diff mbox series

[v4,24/24] drm/exynos: dsi: Adjust probe order

Message ID 20210910101218.1632297-25-maxime@cerno.tech (mailing list archive)
State Superseded
Headers show
Series drm/bridge: Make panel and bridge probe order consistent | expand

Commit Message

Maxime Ripard Sept. 10, 2021, 10:12 a.m. UTC
Without proper care and an agreement between how DSI hosts and devices
drivers register their MIPI-DSI entities and potential components, we can
end up in a situation where the drivers can never probe.

Most drivers were taking evasive maneuvers to try to workaround this,
but not all of them were following the same conventions, resulting in
various incompatibilities between DSI hosts and devices.

Now that we have a sequence agreed upon and documented, let's convert
exynos to it.

Signed-off-by: Maxime Ripard <maxime@cerno.tech>
---
 drivers/gpu/drm/exynos/exynos_drm_dsi.c | 19 ++++++++++++-------
 1 file changed, 12 insertions(+), 7 deletions(-)

Comments

Andrzej Hajda Sept. 13, 2021, 10:30 a.m. UTC | #1
W dniu 10.09.2021 o 12:12, Maxime Ripard pisze:
> Without proper care and an agreement between how DSI hosts and devices
> drivers register their MIPI-DSI entities and potential components, we can
> end up in a situation where the drivers can never probe.
>
> Most drivers were taking evasive maneuvers to try to workaround this,
> but not all of them were following the same conventions, resulting in
> various incompatibilities between DSI hosts and devices.
>
> Now that we have a sequence agreed upon and documented, let's convert
> exynos to it.
>
> Signed-off-by: Maxime Ripard <maxime@cerno.tech>

This patch should be dropped, as it will probably break the driver.

Exynos is already compatible with the pattern 
register-bus-then-get-sink, but it adds/removes panel/bridge 
dynamically, so it creates drm_device without waiting for downstream sink.


Regards

Andrzej


> ---
>   drivers/gpu/drm/exynos/exynos_drm_dsi.c | 19 ++++++++++++-------
>   1 file changed, 12 insertions(+), 7 deletions(-)
>
> diff --git a/drivers/gpu/drm/exynos/exynos_drm_dsi.c b/drivers/gpu/drm/exynos/exynos_drm_dsi.c
> index e39fac889edc..dfda2b259c44 100644
> --- a/drivers/gpu/drm/exynos/exynos_drm_dsi.c
> +++ b/drivers/gpu/drm/exynos/exynos_drm_dsi.c
> @@ -1529,6 +1529,7 @@ static const struct drm_encoder_helper_funcs exynos_dsi_encoder_helper_funcs = {
>   
>   MODULE_DEVICE_TABLE(of, exynos_dsi_of_match);
>   
> +static const struct component_ops exynos_dsi_component_ops;
>   static int exynos_dsi_host_attach(struct mipi_dsi_host *host,
>   				  struct mipi_dsi_device *device)
>   {
> @@ -1536,6 +1537,7 @@ static int exynos_dsi_host_attach(struct mipi_dsi_host *host,
>   	struct drm_encoder *encoder = &dsi->encoder;
>   	struct drm_device *drm = encoder->dev;
>   	struct drm_bridge *out_bridge;
> +	struct device *dev = host->dev;
>   
>   	out_bridge  = of_drm_find_bridge(device->dev.of_node);
>   	if (out_bridge) {
> @@ -1585,7 +1587,7 @@ static int exynos_dsi_host_attach(struct mipi_dsi_host *host,
>   	if (drm->mode_config.poll_enabled)
>   		drm_kms_helper_hotplug_event(drm);
>   
> -	return 0;
> +	return component_add(dev, &exynos_dsi_component_ops);
>   }
>   
>   static int exynos_dsi_host_detach(struct mipi_dsi_host *host,
> @@ -1593,6 +1595,9 @@ static int exynos_dsi_host_detach(struct mipi_dsi_host *host,
>   {
>   	struct exynos_dsi *dsi = host_to_dsi(host);
>   	struct drm_device *drm = dsi->encoder.dev;
> +	struct device *dev = host->dev;
> +
> +	component_del(dev, &exynos_dsi_component_ops);
>   
>   	if (dsi->panel) {
>   		mutex_lock(&drm->mode_config.mutex);
> @@ -1716,7 +1721,7 @@ static int exynos_dsi_bind(struct device *dev, struct device *master,
>   		of_node_put(in_bridge_node);
>   	}
>   
> -	return mipi_dsi_host_register(&dsi->dsi_host);
> +	return 0;
>   }
>   
>   static void exynos_dsi_unbind(struct device *dev, struct device *master,
> @@ -1726,8 +1731,6 @@ static void exynos_dsi_unbind(struct device *dev, struct device *master,
>   	struct drm_encoder *encoder = &dsi->encoder;
>   
>   	exynos_dsi_disable(encoder);
> -
> -	mipi_dsi_host_unregister(&dsi->dsi_host);
>   }
>   
>   static const struct component_ops exynos_dsi_component_ops = {
> @@ -1821,7 +1824,7 @@ static int exynos_dsi_probe(struct platform_device *pdev)
>   
>   	pm_runtime_enable(dev);
>   
> -	ret = component_add(dev, &exynos_dsi_component_ops);
> +	ret = mipi_dsi_host_register(&dsi->dsi_host);
>   	if (ret)
>   		goto err_disable_runtime;
>   
> @@ -1835,10 +1838,12 @@ static int exynos_dsi_probe(struct platform_device *pdev)
>   
>   static int exynos_dsi_remove(struct platform_device *pdev)
>   {
> +	struct exynos_dsi *dsi = platform_get_drvdata(pdev);
> +
> +	mipi_dsi_host_unregister(&dsi->dsi_host);
> +
>   	pm_runtime_disable(&pdev->dev);
>   
> -	component_del(&pdev->dev, &exynos_dsi_component_ops);
> -
>   	return 0;
>   }
>
Marek Szyprowski Sept. 17, 2021, 12:35 p.m. UTC | #2
Hi,

On 13.09.2021 12:30, Andrzej Hajda wrote:
> W dniu 10.09.2021 o 12:12, Maxime Ripard pisze:
>> Without proper care and an agreement between how DSI hosts and devices
>> drivers register their MIPI-DSI entities and potential components, we can
>> end up in a situation where the drivers can never probe.
>>
>> Most drivers were taking evasive maneuvers to try to workaround this,
>> but not all of them were following the same conventions, resulting in
>> various incompatibilities between DSI hosts and devices.
>>
>> Now that we have a sequence agreed upon and documented, let's convert
>> exynos to it.
>>
>> Signed-off-by: Maxime Ripard <maxime@cerno.tech>
> This patch should be dropped, as it will probably break the driver.
>
> Exynos is already compatible with the pattern
> register-bus-then-get-sink, but it adds/removes panel/bridge
> dynamically, so it creates drm_device without waiting for downstream sink.

Right, this patch breaks Exynos DSI driver operation. Without it, the 
whole series works fine on all Exynos based test boards.

Best regards
Maxime Ripard Sept. 22, 2021, 8:53 a.m. UTC | #3
Hi Marek,

On Fri, Sep 17, 2021 at 02:35:05PM +0200, Marek Szyprowski wrote:
> Hi,
> 
> On 13.09.2021 12:30, Andrzej Hajda wrote:
> > W dniu 10.09.2021 o 12:12, Maxime Ripard pisze:
> >> Without proper care and an agreement between how DSI hosts and devices
> >> drivers register their MIPI-DSI entities and potential components, we can
> >> end up in a situation where the drivers can never probe.
> >>
> >> Most drivers were taking evasive maneuvers to try to workaround this,
> >> but not all of them were following the same conventions, resulting in
> >> various incompatibilities between DSI hosts and devices.
> >>
> >> Now that we have a sequence agreed upon and documented, let's convert
> >> exynos to it.
> >>
> >> Signed-off-by: Maxime Ripard <maxime@cerno.tech>
> > This patch should be dropped, as it will probably break the driver.
> >
> > Exynos is already compatible with the pattern
> > register-bus-then-get-sink, but it adds/removes panel/bridge
> > dynamically, so it creates drm_device without waiting for downstream sink.
> 
> Right, this patch breaks Exynos DSI driver operation. Without it, the 
> whole series works fine on all Exynos based test boards.

Thanks for testing. Did you have any board using one of those bridges in
your test sample?

Thanks!
Maxime
Marek Szyprowski Sept. 23, 2021, 8:14 a.m. UTC | #4
Hi Maxime,

On 22.09.2021 10:53, Maxime Ripard wrote:
> On Fri, Sep 17, 2021 at 02:35:05PM +0200, Marek Szyprowski wrote:
>> On 13.09.2021 12:30, Andrzej Hajda wrote:
>>> W dniu 10.09.2021 o 12:12, Maxime Ripard pisze:
>>>> Without proper care and an agreement between how DSI hosts and devices
>>>> drivers register their MIPI-DSI entities and potential components, we can
>>>> end up in a situation where the drivers can never probe.
>>>>
>>>> Most drivers were taking evasive maneuvers to try to workaround this,
>>>> but not all of them were following the same conventions, resulting in
>>>> various incompatibilities between DSI hosts and devices.
>>>>
>>>> Now that we have a sequence agreed upon and documented, let's convert
>>>> exynos to it.
>>>>
>>>> Signed-off-by: Maxime Ripard <maxime@cerno.tech>
>>> This patch should be dropped, as it will probably break the driver.
>>>
>>> Exynos is already compatible with the pattern
>>> register-bus-then-get-sink, but it adds/removes panel/bridge
>>> dynamically, so it creates drm_device without waiting for downstream sink.
>> Right, this patch breaks Exynos DSI driver operation. Without it, the
>> whole series works fine on all Exynos based test boards.
> Thanks for testing. Did you have any board using one of those bridges in
> your test sample?

Nope, the only bridges I've tested are tc358764 and exynos-mic. However, 
both are used in a bit special way. The rest of my test boards just have 
a dsi panel.

Best regards
diff mbox series

Patch

diff --git a/drivers/gpu/drm/exynos/exynos_drm_dsi.c b/drivers/gpu/drm/exynos/exynos_drm_dsi.c
index e39fac889edc..dfda2b259c44 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_dsi.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_dsi.c
@@ -1529,6 +1529,7 @@  static const struct drm_encoder_helper_funcs exynos_dsi_encoder_helper_funcs = {
 
 MODULE_DEVICE_TABLE(of, exynos_dsi_of_match);
 
+static const struct component_ops exynos_dsi_component_ops;
 static int exynos_dsi_host_attach(struct mipi_dsi_host *host,
 				  struct mipi_dsi_device *device)
 {
@@ -1536,6 +1537,7 @@  static int exynos_dsi_host_attach(struct mipi_dsi_host *host,
 	struct drm_encoder *encoder = &dsi->encoder;
 	struct drm_device *drm = encoder->dev;
 	struct drm_bridge *out_bridge;
+	struct device *dev = host->dev;
 
 	out_bridge  = of_drm_find_bridge(device->dev.of_node);
 	if (out_bridge) {
@@ -1585,7 +1587,7 @@  static int exynos_dsi_host_attach(struct mipi_dsi_host *host,
 	if (drm->mode_config.poll_enabled)
 		drm_kms_helper_hotplug_event(drm);
 
-	return 0;
+	return component_add(dev, &exynos_dsi_component_ops);
 }
 
 static int exynos_dsi_host_detach(struct mipi_dsi_host *host,
@@ -1593,6 +1595,9 @@  static int exynos_dsi_host_detach(struct mipi_dsi_host *host,
 {
 	struct exynos_dsi *dsi = host_to_dsi(host);
 	struct drm_device *drm = dsi->encoder.dev;
+	struct device *dev = host->dev;
+
+	component_del(dev, &exynos_dsi_component_ops);
 
 	if (dsi->panel) {
 		mutex_lock(&drm->mode_config.mutex);
@@ -1716,7 +1721,7 @@  static int exynos_dsi_bind(struct device *dev, struct device *master,
 		of_node_put(in_bridge_node);
 	}
 
-	return mipi_dsi_host_register(&dsi->dsi_host);
+	return 0;
 }
 
 static void exynos_dsi_unbind(struct device *dev, struct device *master,
@@ -1726,8 +1731,6 @@  static void exynos_dsi_unbind(struct device *dev, struct device *master,
 	struct drm_encoder *encoder = &dsi->encoder;
 
 	exynos_dsi_disable(encoder);
-
-	mipi_dsi_host_unregister(&dsi->dsi_host);
 }
 
 static const struct component_ops exynos_dsi_component_ops = {
@@ -1821,7 +1824,7 @@  static int exynos_dsi_probe(struct platform_device *pdev)
 
 	pm_runtime_enable(dev);
 
-	ret = component_add(dev, &exynos_dsi_component_ops);
+	ret = mipi_dsi_host_register(&dsi->dsi_host);
 	if (ret)
 		goto err_disable_runtime;
 
@@ -1835,10 +1838,12 @@  static int exynos_dsi_probe(struct platform_device *pdev)
 
 static int exynos_dsi_remove(struct platform_device *pdev)
 {
+	struct exynos_dsi *dsi = platform_get_drvdata(pdev);
+
+	mipi_dsi_host_unregister(&dsi->dsi_host);
+
 	pm_runtime_disable(&pdev->dev);
 
-	component_del(&pdev->dev, &exynos_dsi_component_ops);
-
 	return 0;
 }