Patch "drm/rockchip: dsi: Hold pm-runtime across bind/unbind" has been added to the 5.10-stable tree

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This is a note to let you know that I've just added the patch titled

    drm/rockchip: dsi: Hold pm-runtime across bind/unbind

to the 5.10-stable tree which can be found at:
    http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
     drm-rockchip-dsi-hold-pm-runtime-across-bind-unbind.patch
and it can be found in the queue-5.10 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree,
please let <stable@xxxxxxxxxxxxxxx> know about it.



commit 0422e05fc6079a26361d71532e0b59a21130f7c9
Author: Brian Norris <briannorris@xxxxxxxxxxxx>
Date:   Tue Sep 28 14:35:49 2021 -0700

    drm/rockchip: dsi: Hold pm-runtime across bind/unbind
    
    [ Upstream commit 514db871922f103886ad4d221cf406b4fcc5e74a ]
    
    In commit 43c2de1002d2 ("drm/rockchip: dsi: move all lane config except
    LCDC mux to bind()"), we moved most HW configuration to bind(), but we
    didn't move the runtime PM management. Therefore, depending on initial
    boot state, runtime-PM workqueue delays, and other timing factors, we
    may disable our power domain in between the hardware configuration
    (bind()) and when we enable the display. This can cause us to lose
    hardware state and fail to configure our display. For example:
    
      dw-mipi-dsi-rockchip ff968000.mipi: failed to write command FIFO
      panel-innolux-p079zca ff960000.mipi.0: failed to write command 0
    
    or:
    
      dw-mipi-dsi-rockchip ff968000.mipi: failed to write command FIFO
      panel-kingdisplay-kd097d04 ff960000.mipi.0: failed write init cmds: -110
    
    We should match the runtime PM to the lifetime of the bind()/unbind()
    cycle.
    
    Tested on Acer Chrometab 10 (RK3399 Gru-Scarlet), with panel drivers
    built either as modules or built-in.
    
    Side notes: it seems one is more likely to see this problem when the
    panel driver is built into the kernel. I've also seen this problem
    bisect down to commits that simply changed Kconfig dependencies, because
    it changed the order in which driver init functions were compiled into
    the kernel, and therefore the ordering and timing of built-in device
    probe.
    
    Fixes: 43c2de1002d2 ("drm/rockchip: dsi: move all lane config except LCDC mux to bind()")
    Link: https://lore.kernel.org/linux-rockchip/9aedfb528600ecf871885f7293ca4207c84d16c1.camel@xxxxxxxxx/
    Reported-by: <aleksandr.o.makarov@xxxxxxxxx>
    Cc: <stable@xxxxxxxxxxxxxxx>
    Signed-off-by: Brian Norris <briannorris@xxxxxxxxxxxx>
    Tested-by: Nícolas F. R. A. Prado <nfraprado@xxxxxxxxxxxxx>
    Reviewed-by: Chen-Yu Tsai <wenst@xxxxxxxxxxxx>
    Signed-off-by: Heiko Stuebner <heiko@xxxxxxxxx>
    Link: https://patchwork.freedesktop.org/patch/msgid/20210928143413.v3.1.Ic2904d37f30013a7f3d8476203ad3733c186827e@changeid
    Signed-off-by: Sasha Levin <sashal@xxxxxxxxxx>

diff --git a/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c b/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c
index 433b2f459a7d9..d3cea42dde436 100644
--- a/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c
+++ b/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c
@@ -753,10 +753,6 @@ static void dw_mipi_dsi_encoder_enable(struct drm_encoder *encoder)
 	if (mux < 0)
 		return;
 
-	pm_runtime_get_sync(dsi->dev);
-	if (dsi->slave)
-		pm_runtime_get_sync(dsi->slave->dev);
-
 	/*
 	 * For the RK3399, the clk of grf must be enabled before writing grf
 	 * register. And for RK3288 or other soc, this grf_clk must be NULL,
@@ -775,20 +771,10 @@ static void dw_mipi_dsi_encoder_enable(struct drm_encoder *encoder)
 	clk_disable_unprepare(dsi->grf_clk);
 }
 
-static void dw_mipi_dsi_encoder_disable(struct drm_encoder *encoder)
-{
-	struct dw_mipi_dsi_rockchip *dsi = to_dsi(encoder);
-
-	if (dsi->slave)
-		pm_runtime_put(dsi->slave->dev);
-	pm_runtime_put(dsi->dev);
-}
-
 static const struct drm_encoder_helper_funcs
 dw_mipi_dsi_encoder_helper_funcs = {
 	.atomic_check = dw_mipi_dsi_encoder_atomic_check,
 	.enable = dw_mipi_dsi_encoder_enable,
-	.disable = dw_mipi_dsi_encoder_disable,
 };
 
 static int rockchip_dsi_drm_create_encoder(struct dw_mipi_dsi_rockchip *dsi,
@@ -918,10 +904,14 @@ static int dw_mipi_dsi_rockchip_bind(struct device *dev,
 		put_device(second);
 	}
 
+	pm_runtime_get_sync(dsi->dev);
+	if (dsi->slave)
+		pm_runtime_get_sync(dsi->slave->dev);
+
 	ret = clk_prepare_enable(dsi->pllref_clk);
 	if (ret) {
 		DRM_DEV_ERROR(dev, "Failed to enable pllref_clk: %d\n", ret);
-		return ret;
+		goto out_pm_runtime;
 	}
 
 	/*
@@ -933,7 +923,7 @@ static int dw_mipi_dsi_rockchip_bind(struct device *dev,
 	ret = clk_prepare_enable(dsi->grf_clk);
 	if (ret) {
 		DRM_DEV_ERROR(dsi->dev, "Failed to enable grf_clk: %d\n", ret);
-		return ret;
+		goto out_pm_runtime;
 	}
 
 	dw_mipi_dsi_rockchip_config(dsi);
@@ -945,16 +935,23 @@ static int dw_mipi_dsi_rockchip_bind(struct device *dev,
 	ret = rockchip_dsi_drm_create_encoder(dsi, drm_dev);
 	if (ret) {
 		DRM_DEV_ERROR(dev, "Failed to create drm encoder\n");
-		return ret;
+		goto out_pm_runtime;
 	}
 
 	ret = dw_mipi_dsi_bind(dsi->dmd, &dsi->encoder);
 	if (ret) {
 		DRM_DEV_ERROR(dev, "Failed to bind: %d\n", ret);
-		return ret;
+		goto out_pm_runtime;
 	}
 
 	return 0;
+
+out_pm_runtime:
+	pm_runtime_put(dsi->dev);
+	if (dsi->slave)
+		pm_runtime_put(dsi->slave->dev);
+
+	return ret;
 }
 
 static void dw_mipi_dsi_rockchip_unbind(struct device *dev,
@@ -969,6 +966,10 @@ static void dw_mipi_dsi_rockchip_unbind(struct device *dev,
 	dw_mipi_dsi_unbind(dsi->dmd);
 
 	clk_disable_unprepare(dsi->pllref_clk);
+
+	pm_runtime_put(dsi->dev);
+	if (dsi->slave)
+		pm_runtime_put(dsi->slave->dev);
 }
 
 static const struct component_ops dw_mipi_dsi_rockchip_ops = {



[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux