@@ -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,
@@ -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,
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 <mperttunen@nvidia.com> --- drivers/gpu/drm/tegra/drm.h | 11 +++- drivers/gpu/drm/tegra/vic.c | 127 ++++++++++++++++++++---------------- 2 files changed, 78 insertions(+), 60 deletions(-)