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@xxxxxxxxxx> --- 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@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/dri-devel