MLK-16918-17: drm/imx: Add support for suspend/resume in nwl_dsi-imx
authorRobert Chiras <robert.chiras@nxp.com>
Wed, 22 Nov 2017 09:47:48 +0000 (11:47 +0200)
committerNitin Garg <nitin.garg@nxp.com>
Mon, 19 Mar 2018 20:55:35 +0000 (15:55 -0500)
Update the IMX_NWL_DSI DRM driver to support the PM Runtime and
System Sleep suspend/resume routines.

Signed-off-by: Robert Chiras <robert.chiras@nxp.com>
arch/arm64/boot/dts/freescale/fsl-imx8mq.dtsi
drivers/gpu/drm/imx/nwl_dsi-imx.c

index 571225b..eada06c 100644 (file)
                #size-cells = <0>;
                compatible = "mixel,imx8mq-mipi-dsi-phy";
                reg = <0x0 0x30A00300 0x0 0x100>;
-               power-domains = <&mipi_pd>;
                #phy-cells = <0>;
                status = "disabled";
        };
                assigned-clocks = <&clk IMX8MQ_CLK_DSI_AHB_SRC>;
                assigned-clock-parents = <&clk IMX8MQ_SYS1_PLL_80M>;
                assigned-clock-rates = <80000000>;
-               power-domains = <&mipi_pd>;
                phys = <&mipi_dsi_phy_drm>;
                phy-names = "dphy";
                status = "disabled";
index 7443167..d2069d1 100644 (file)
@@ -18,6 +18,7 @@
 #include <drm/drm_atomic_helper.h>
 #include <drm/drm_crtc_helper.h>
 #include <drm/drm_of.h>
+#include <linux/busfreq-imx.h>
 #include <linux/clk.h>
 #include <linux/component.h>
 #include <linux/err.h>
@@ -555,6 +556,7 @@ static void imx_nwl_dsi_encoder_enable(struct drm_encoder *encoder)
 {
        struct imx_mipi_dsi *dsi = encoder_to_dsi(encoder);
 
+       pm_runtime_get_sync(dsi->dev);
        imx_nwl_dsi_enable(dsi);
 }
 
@@ -563,6 +565,7 @@ static void imx_nwl_dsi_encoder_disable(struct drm_encoder *encoder)
        struct imx_mipi_dsi *dsi = encoder_to_dsi(encoder);
 
        imx_nwl_dsi_disable(dsi);
+       pm_runtime_put_sync(dsi->dev);
 }
 
 static int imx_nwl_dsi_encoder_atomic_check(struct drm_encoder *encoder,
@@ -600,6 +603,7 @@ static void imx_nwl_dsi_bridge_enable(struct drm_bridge *bridge)
        struct imx_mipi_dsi *dsi = bridge->driver_private;
 
        imx_nwl_dsi_enable(dsi);
+       pm_runtime_get_sync(dsi->dev);
 }
 
 static void imx_nwl_dsi_bridge_disable(struct drm_bridge *bridge)
@@ -607,6 +611,7 @@ static void imx_nwl_dsi_bridge_disable(struct drm_bridge *bridge)
        struct imx_mipi_dsi *dsi = bridge->driver_private;
 
        imx_nwl_dsi_disable(dsi);
+       pm_runtime_put_sync(dsi->dev);
 }
 
 static bool imx_nwl_dsi_bridge_mode_fixup(struct drm_bridge *bridge,
@@ -856,6 +861,8 @@ static int imx_nwl_dsi_probe(struct platform_device *pdev)
        dsi->dev = dev;
        dev_set_drvdata(dev, dsi);
 
+       pm_runtime_enable(dev);
+
        if (of_property_read_bool(dev->of_node, "as_bridge")) {
                ret = imx_nwl_dsi_parse_of(dev, true);
                if (ret)
@@ -885,12 +892,47 @@ static int imx_nwl_dsi_remove(struct platform_device *pdev)
        return 0;
 }
 
+#ifdef CONFIG_PM
+static int imx_nwl_suspend(struct device *dev)
+{
+       struct imx_mipi_dsi *dsi = dev_get_drvdata(dev);
+       bool enabled = dsi->enabled;
+
+       if (enabled && dsi->next_bridge)
+               drm_bridge_disable(dsi->next_bridge);
+       imx_nwl_dsi_disable(dsi);
+       release_bus_freq(BUS_FREQ_HIGH);
+
+       return 0;
+}
+
+static int imx_nwl_resume(struct device *dev)
+{
+       struct imx_mipi_dsi *dsi = dev_get_drvdata(dev);
+       bool enabled = dsi->enabled;
+
+       request_bus_freq(BUS_FREQ_HIGH);
+       imx_nwl_dsi_enable(dsi);
+       if (!enabled && dsi->next_bridge)
+               drm_bridge_enable(dsi->next_bridge);
+
+       return 0;
+}
+
+#endif
+
+static const struct dev_pm_ops imx_nwl_pm_ops = {
+       SET_RUNTIME_PM_OPS(imx_nwl_suspend, imx_nwl_resume, NULL)
+       SET_SYSTEM_SLEEP_PM_OPS(imx_nwl_suspend, imx_nwl_resume)
+};
+
 static struct platform_driver imx_nwl_dsi_driver = {
        .probe          = imx_nwl_dsi_probe,
        .remove         = imx_nwl_dsi_remove,
        .driver         = {
                .of_match_table = imx_nwl_dsi_dt_ids,
                .name   = DRIVER_NAME,
+               .pm     = &imx_nwl_pm_ops,
        },
 };