With the new UAPI implementation, engines are powered on and off
when there are active jobs, and the core code handles channel
allocation. To accommodate that, add the power_on and power_off
callbacks. The open_channel and close_channel callbacks are now only
used for the staging path.

Signed-off-by: Mikko Perttunen <mperttu...@nvidia.com>
---
 drivers/gpu/drm/tegra/drm.h |  11 +++-
 drivers/gpu/drm/tegra/vic.c | 127 ++++++++++++++++++++----------------
 2 files changed, 78 insertions(+), 60 deletions(-)

diff --git a/drivers/gpu/drm/tegra/drm.h b/drivers/gpu/drm/tegra/drm.h
index b25443255be6..b915a3946ad4 100644
--- a/drivers/gpu/drm/tegra/drm.h
+++ b/drivers/gpu/drm/tegra/drm.h
@@ -67,14 +67,19 @@ struct tegra_drm_context {
 };
 
 struct tegra_drm_client_ops {
-       int (*open_channel)(struct tegra_drm_client *client,
-                           struct tegra_drm_context *context);
-       void (*close_channel)(struct tegra_drm_context *context);
+       int (*power_on)(struct tegra_drm_client *client);
+       void (*power_off)(struct tegra_drm_client *client);
+
        int (*is_addr_reg)(struct device *dev, u32 class, u32 offset);
        int (*is_valid_class)(u32 class);
        int (*submit)(struct tegra_drm_context *context,
                      struct drm_tegra_submit *args, struct drm_device *drm,
                      struct drm_file *file);
+
+       /* Legacy UAPI callbacks */
+       int (*open_channel)(struct tegra_drm_client *client,
+                           struct tegra_drm_context *context);
+       void (*close_channel)(struct tegra_drm_context *context);
 };
 
 int tegra_drm_submit(struct tegra_drm_context *context,
diff --git a/drivers/gpu/drm/tegra/vic.c b/drivers/gpu/drm/tegra/vic.c
index cb476da59adc..4783c7254de9 100644
--- a/drivers/gpu/drm/tegra/vic.c
+++ b/drivers/gpu/drm/tegra/vic.c
@@ -52,48 +52,6 @@ static void vic_writel(struct vic *vic, u32 value, unsigned 
int offset)
        writel(value, vic->regs + offset);
 }
 
-static int vic_runtime_resume(struct device *dev)
-{
-       struct vic *vic = dev_get_drvdata(dev);
-       int err;
-
-       err = clk_prepare_enable(vic->clk);
-       if (err < 0)
-               return err;
-
-       usleep_range(10, 20);
-
-       err = reset_control_deassert(vic->rst);
-       if (err < 0)
-               goto disable;
-
-       usleep_range(10, 20);
-
-       return 0;
-
-disable:
-       clk_disable_unprepare(vic->clk);
-       return err;
-}
-
-static int vic_runtime_suspend(struct device *dev)
-{
-       struct vic *vic = dev_get_drvdata(dev);
-       int err;
-
-       err = reset_control_assert(vic->rst);
-       if (err < 0)
-               return err;
-
-       usleep_range(2000, 4000);
-
-       clk_disable_unprepare(vic->clk);
-
-       vic->booted = false;
-
-       return 0;
-}
-
 static int vic_boot(struct vic *vic)
 {
 #ifdef CONFIG_IOMMU_API
@@ -308,47 +266,102 @@ static int vic_load_firmware(struct vic *vic)
        return err;
 }
 
-static int vic_open_channel(struct tegra_drm_client *client,
-                           struct tegra_drm_context *context)
+
+static int vic_runtime_resume(struct device *dev)
 {
-       struct vic *vic = to_vic(client);
+       struct vic *vic = dev_get_drvdata(dev);
        int err;
 
-       err = pm_runtime_get_sync(vic->dev);
+       err = clk_prepare_enable(vic->clk);
        if (err < 0)
                return err;
 
+       usleep_range(10, 20);
+
+       err = reset_control_deassert(vic->rst);
+       if (err < 0)
+               goto disable;
+
+       usleep_range(10, 20);
+
        err = vic_load_firmware(vic);
        if (err < 0)
-               goto rpm_put;
+               goto assert;
 
        err = vic_boot(vic);
        if (err < 0)
-               goto rpm_put;
+               goto assert;
+
+       return 0;
+
+assert:
+       reset_control_assert(vic->rst);
+disable:
+       clk_disable_unprepare(vic->clk);
+       return err;
+}
+
+static int vic_runtime_suspend(struct device *dev)
+{
+       struct vic *vic = dev_get_drvdata(dev);
+       int err;
+
+       err = reset_control_assert(vic->rst);
+       if (err < 0)
+               return err;
+
+       usleep_range(2000, 4000);
+
+       clk_disable_unprepare(vic->clk);
+
+       vic->booted = false;
+
+       return 0;
+}
+
+static int vic_power_on(struct tegra_drm_client *client)
+{
+       struct vic *vic = to_vic(client);
+
+       return pm_runtime_get_sync(vic->dev);
+}
+
+static void vic_power_off(struct tegra_drm_client *client)
+{
+       struct vic *vic = to_vic(client);
+
+       pm_runtime_put(vic->dev);
+}
+
+static int vic_open_channel(struct tegra_drm_client *client,
+                           struct tegra_drm_context *context)
+{
+       struct vic *vic = to_vic(client);
+       int err;
+
+       err = vic_power_on(client);
+       if (err < 0)
+               return err;
 
        context->channel = host1x_channel_get(vic->channel);
        if (!context->channel) {
-               err = -ENOMEM;
-               goto rpm_put;
+               vic_power_off(client);
+               return -ENOMEM;
        }
 
        return 0;
-
-rpm_put:
-       pm_runtime_put(vic->dev);
-       return err;
 }
 
 static void vic_close_channel(struct tegra_drm_context *context)
 {
-       struct vic *vic = to_vic(context->client);
-
        host1x_channel_put(context->channel);
 
-       pm_runtime_put(vic->dev);
+       vic_power_off(context->client);
 }
 
 static const struct tegra_drm_client_ops vic_ops = {
+       .power_on = vic_power_on,
+       .power_off = vic_power_off,
        .open_channel = vic_open_channel,
        .close_channel = vic_close_channel,
        .submit = tegra_drm_submit,
-- 
2.28.0

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

Reply via email to