OSDN Git Service

Merge tag 'drm/tegra/for-5.6-rc1' of git://anongit.freedesktop.org/tegra/linux into...
[tomoyo/tomoyo-test1.git] / drivers / gpu / drm / tegra / sor.c
index 1b8087d..41d2494 100644 (file)
@@ -2255,7 +2255,7 @@ static void tegra_sor_hdmi_disable(struct drm_encoder *encoder)
        if (err < 0)
                dev_err(sor->dev, "failed to power off I/O pad: %d\n", err);
 
-       pm_runtime_put(sor->dev);
+       host1x_client_suspend(&sor->client);
 }
 
 static void tegra_sor_hdmi_enable(struct drm_encoder *encoder)
@@ -2276,7 +2276,11 @@ static void tegra_sor_hdmi_enable(struct drm_encoder *encoder)
        mode = &encoder->crtc->state->adjusted_mode;
        pclk = mode->clock * 1000;
 
-       pm_runtime_get_sync(sor->dev);
+       err = host1x_client_resume(&sor->client);
+       if (err < 0) {
+               dev_err(sor->dev, "failed to resume: %d\n", err);
+               return;
+       }
 
        /* switch to safe parent clock */
        err = tegra_sor_set_parent_clock(sor, sor->clk_safe);
@@ -2722,7 +2726,7 @@ static void tegra_sor_dp_disable(struct drm_encoder *encoder)
        if (output->panel)
                drm_panel_unprepare(output->panel);
 
-       pm_runtime_put(sor->dev);
+       host1x_client_suspend(&sor->client);
 }
 
 static void tegra_sor_dp_enable(struct drm_encoder *encoder)
@@ -2742,7 +2746,11 @@ static void tegra_sor_dp_enable(struct drm_encoder *encoder)
        mode = &encoder->crtc->state->adjusted_mode;
        info = &output->connector.display_info;
 
-       pm_runtime_get_sync(sor->dev);
+       err = host1x_client_resume(&sor->client);
+       if (err < 0) {
+               dev_err(sor->dev, "failed to resume: %d\n", err);
+               return;
+       }
 
        /* switch to safe parent clock */
        err = tegra_sor_set_parent_clock(sor, sor->clk_safe);
@@ -3053,7 +3061,7 @@ static const struct tegra_sor_ops tegra_sor_dp_ops = {
 
 static int tegra_sor_init(struct host1x_client *client)
 {
-       struct drm_device *drm = dev_get_drvdata(client->parent);
+       struct drm_device *drm = dev_get_drvdata(client->host);
        const struct drm_encoder_helper_funcs *helpers = NULL;
        struct tegra_sor *sor = host1x_client_to_sor(client);
        int connector = DRM_MODE_CONNECTOR_Unknown;
@@ -3190,9 +3198,80 @@ static int tegra_sor_exit(struct host1x_client *client)
        return 0;
 }
 
+static int tegra_sor_runtime_suspend(struct host1x_client *client)
+{
+       struct tegra_sor *sor = host1x_client_to_sor(client);
+       struct device *dev = client->dev;
+       int err;
+
+       if (sor->rst) {
+               err = reset_control_assert(sor->rst);
+               if (err < 0) {
+                       dev_err(dev, "failed to assert reset: %d\n", err);
+                       return err;
+               }
+
+               reset_control_release(sor->rst);
+       }
+
+       usleep_range(1000, 2000);
+
+       clk_disable_unprepare(sor->clk);
+       pm_runtime_put_sync(dev);
+
+       return 0;
+}
+
+static int tegra_sor_runtime_resume(struct host1x_client *client)
+{
+       struct tegra_sor *sor = host1x_client_to_sor(client);
+       struct device *dev = client->dev;
+       int err;
+
+       err = pm_runtime_get_sync(dev);
+       if (err < 0) {
+               dev_err(dev, "failed to get runtime PM: %d\n", err);
+               return err;
+       }
+
+       err = clk_prepare_enable(sor->clk);
+       if (err < 0) {
+               dev_err(dev, "failed to enable clock: %d\n", err);
+               goto put_rpm;
+       }
+
+       usleep_range(1000, 2000);
+
+       if (sor->rst) {
+               err = reset_control_acquire(sor->rst);
+               if (err < 0) {
+                       dev_err(dev, "failed to acquire reset: %d\n", err);
+                       goto disable_clk;
+               }
+
+               err = reset_control_deassert(sor->rst);
+               if (err < 0) {
+                       dev_err(dev, "failed to deassert reset: %d\n", err);
+                       goto release_reset;
+               }
+       }
+
+       return 0;
+
+release_reset:
+       reset_control_release(sor->rst);
+disable_clk:
+       clk_disable_unprepare(sor->clk);
+put_rpm:
+       pm_runtime_put_sync(dev);
+       return err;
+}
+
 static const struct host1x_client_ops sor_client_ops = {
        .init = tegra_sor_init,
        .exit = tegra_sor_exit,
+       .suspend = tegra_sor_runtime_suspend,
+       .resume = tegra_sor_runtime_resume,
 };
 
 static const u8 tegra124_sor_xbar_cfg[5] = {
@@ -3843,10 +3922,9 @@ static int tegra_sor_probe(struct platform_device *pdev)
        if (!sor->clk_pad) {
                char *name;
 
-               err = pm_runtime_get_sync(&pdev->dev);
+               err = host1x_client_resume(&sor->client);
                if (err < 0) {
-                       dev_err(&pdev->dev, "failed to get runtime PM: %d\n",
-                               err);
+                       dev_err(sor->dev, "failed to resume: %d\n", err);
                        goto remove;
                }
 
@@ -3857,7 +3935,7 @@ static int tegra_sor_probe(struct platform_device *pdev)
                }
 
                sor->clk_pad = tegra_clk_sor_pad_register(sor, name);
-               pm_runtime_put(&pdev->dev);
+               host1x_client_suspend(&sor->client);
        }
 
        if (IS_ERR(sor->clk_pad)) {
@@ -3913,54 +3991,21 @@ static int tegra_sor_remove(struct platform_device *pdev)
        return 0;
 }
 
-static int tegra_sor_runtime_suspend(struct device *dev)
-{
-       struct tegra_sor *sor = dev_get_drvdata(dev);
-       int err;
-
-       if (sor->rst) {
-               err = reset_control_assert(sor->rst);
-               if (err < 0) {
-                       dev_err(dev, "failed to assert reset: %d\n", err);
-                       return err;
-               }
-
-               reset_control_release(sor->rst);
-       }
-
-       usleep_range(1000, 2000);
-
-       clk_disable_unprepare(sor->clk);
-
-       return 0;
-}
-
-static int tegra_sor_runtime_resume(struct device *dev)
+static int __maybe_unused tegra_sor_suspend(struct device *dev)
 {
        struct tegra_sor *sor = dev_get_drvdata(dev);
        int err;
 
-       err = clk_prepare_enable(sor->clk);
+       err = tegra_output_suspend(&sor->output);
        if (err < 0) {
-               dev_err(dev, "failed to enable clock: %d\n", err);
+               dev_err(dev, "failed to suspend output: %d\n", err);
                return err;
        }
 
-       usleep_range(1000, 2000);
-
-       if (sor->rst) {
-               err = reset_control_acquire(sor->rst);
-               if (err < 0) {
-                       dev_err(dev, "failed to acquire reset: %d\n", err);
-                       clk_disable_unprepare(sor->clk);
-                       return err;
-               }
-
-               err = reset_control_deassert(sor->rst);
+       if (sor->hdmi_supply) {
+               err = regulator_disable(sor->hdmi_supply);
                if (err < 0) {
-                       dev_err(dev, "failed to deassert reset: %d\n", err);
-                       reset_control_release(sor->rst);
-                       clk_disable_unprepare(sor->clk);
+                       tegra_output_resume(&sor->output);
                        return err;
                }
        }
@@ -3968,37 +4013,31 @@ static int tegra_sor_runtime_resume(struct device *dev)
        return 0;
 }
 
-static int tegra_sor_suspend(struct device *dev)
+static int __maybe_unused tegra_sor_resume(struct device *dev)
 {
        struct tegra_sor *sor = dev_get_drvdata(dev);
        int err;
 
        if (sor->hdmi_supply) {
-               err = regulator_disable(sor->hdmi_supply);
+               err = regulator_enable(sor->hdmi_supply);
                if (err < 0)
                        return err;
        }
 
-       return 0;
-}
+       err = tegra_output_resume(&sor->output);
+       if (err < 0) {
+               dev_err(dev, "failed to resume output: %d\n", err);
 
-static int tegra_sor_resume(struct device *dev)
-{
-       struct tegra_sor *sor = dev_get_drvdata(dev);
-       int err;
+               if (sor->hdmi_supply)
+                       regulator_disable(sor->hdmi_supply);
 
-       if (sor->hdmi_supply) {
-               err = regulator_enable(sor->hdmi_supply);
-               if (err < 0)
-                       return err;
+               return err;
        }
 
        return 0;
 }
 
 static const struct dev_pm_ops tegra_sor_pm_ops = {
-       SET_RUNTIME_PM_OPS(tegra_sor_runtime_suspend, tegra_sor_runtime_resume,
-                          NULL)
        SET_SYSTEM_SLEEP_PM_OPS(tegra_sor_suspend, tegra_sor_resume)
 };