drm: rcar-du: lvds: Add reset control
authorTomi Valkeinen <tomi.valkeinen+renesas@ideasonboard.com>
Mon, 23 Jan 2023 10:47:38 +0000 (12:47 +0200)
committerLaurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
Mon, 23 Jan 2023 15:56:51 +0000 (17:56 +0200)
Reset LVDS using the reset control as CPG reset/release is required in
the hardware manual sequence.

Based on a BSP patch from Koji Matsuoka <koji.matsuoka.xm@renesas.com>.

Signed-off-by: Tomi Valkeinen <tomi.valkeinen+renesas@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
drivers/gpu/drm/rcar-du/Kconfig
drivers/gpu/drm/rcar-du/rcar_lvds.c

index dc5d663ed88450dbb12a430548c1aca976d76b73..53c356aed5d52070e5de13355305bf5aefaa4d44 100644 (file)
@@ -44,6 +44,7 @@ config DRM_RCAR_LVDS
        depends on PM
        select DRM_KMS_HELPER
        select DRM_PANEL
+       select RESET_CONTROLLER
 
 config DRM_RCAR_USE_MIPI_DSI
        bool "R-Car DU MIPI DSI Encoder Support"
index 7cf515e4307908e96f0e0b8d42876107ff563f10..a11201e4d31b360eefd5934e72f265e76cbb33c6 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/of_graph.h>
 #include <linux/platform_device.h>
 #include <linux/pm_runtime.h>
+#include <linux/reset.h>
 #include <linux/slab.h>
 #include <linux/sys_soc.h>
 
@@ -61,6 +62,7 @@ struct rcar_lvds_device_info {
 struct rcar_lvds {
        struct device *dev;
        const struct rcar_lvds_device_info *info;
+       struct reset_control *rstc;
 
        struct drm_bridge bridge;
 
@@ -845,6 +847,11 @@ static int rcar_lvds_probe(struct platform_device *pdev)
        if (ret < 0)
                return ret;
 
+       lvds->rstc = devm_reset_control_get_exclusive(&pdev->dev, NULL);
+       if (IS_ERR(lvds->rstc))
+               return dev_err_probe(&pdev->dev, PTR_ERR(lvds->rstc),
+                                    "failed to get cpg reset\n");
+
        pm_runtime_enable(&pdev->dev);
 
        drm_bridge_add(&lvds->bridge);
@@ -924,6 +931,8 @@ static int rcar_lvds_runtime_suspend(struct device *dev)
 
        clk_disable_unprepare(lvds->clocks.mod);
 
+       reset_control_assert(lvds->rstc);
+
        return 0;
 }
 
@@ -932,11 +941,20 @@ static int rcar_lvds_runtime_resume(struct device *dev)
        struct rcar_lvds *lvds = dev_get_drvdata(dev);
        int ret;
 
+       ret = reset_control_deassert(lvds->rstc);
+       if (ret)
+               return ret;
+
        ret = clk_prepare_enable(lvds->clocks.mod);
        if (ret < 0)
-               return ret;
+               goto err_reset_assert;
 
        return 0;
+
+err_reset_assert:
+       reset_control_assert(lvds->rstc);
+
+       return ret;
 }
 
 static const struct dev_pm_ops rcar_lvds_pm_ops = {