gpu: host1x: Add option to skip firewall for a job
authorMikko Perttunen <mperttunen@nvidia.com>
Thu, 10 Jun 2021 11:04:46 +0000 (14:04 +0300)
committerThierry Reding <treding@nvidia.com>
Tue, 10 Aug 2021 12:42:49 +0000 (14:42 +0200)
The new UAPI will have its own firewall, and we don't want to run
the firewall in the Host1x driver for those jobs. As such, add a
parameter to host1x_job_alloc to specify if we want to skip the
firewall in the Host1x driver.

Signed-off-by: Mikko Perttunen <mperttunen@nvidia.com>
Signed-off-by: Thierry Reding <treding@nvidia.com>
drivers/gpu/drm/tegra/drm.c
drivers/gpu/host1x/job.c
include/linux/host1x.h

index 739250a..0e2a6f2 100644 (file)
@@ -193,7 +193,7 @@ int tegra_drm_submit(struct tegra_drm_context *context,
                return -EINVAL;
 
        job = host1x_job_alloc(context->channel, args->num_cmdbufs,
-                              args->num_relocs);
+                              args->num_relocs, false);
        if (!job)
                return -ENOMEM;
 
index 32619b7..0eef6df 100644 (file)
 #define HOST1X_WAIT_SYNCPT_OFFSET 0x8
 
 struct host1x_job *host1x_job_alloc(struct host1x_channel *ch,
-                                   u32 num_cmdbufs, u32 num_relocs)
+                                   u32 num_cmdbufs, u32 num_relocs,
+                                   bool skip_firewall)
 {
        struct host1x_job *job = NULL;
        unsigned int num_unpins = num_relocs;
+       bool enable_firewall;
        u64 total;
        void *mem;
 
-       if (!IS_ENABLED(CONFIG_TEGRA_HOST1X_FIREWALL))
+       enable_firewall = IS_ENABLED(CONFIG_TEGRA_HOST1X_FIREWALL) && !skip_firewall;
+
+       if (!enable_firewall)
                num_unpins += num_cmdbufs;
 
        /* Check that we're not going to overflow */
@@ -48,6 +52,8 @@ struct host1x_job *host1x_job_alloc(struct host1x_channel *ch,
        if (!job)
                return NULL;
 
+       job->enable_firewall = enable_firewall;
+
        kref_init(&job->ref);
        job->channel = ch;
 
@@ -214,7 +220,7 @@ static unsigned int pin_job(struct host1x *host, struct host1x_job *job)
         * We will copy gathers BO content later, so there is no need to
         * hold and pin them.
         */
-       if (IS_ENABLED(CONFIG_TEGRA_HOST1X_FIREWALL))
+       if (job->enable_firewall)
                return 0;
 
        for (i = 0; i < job->num_cmds; i++) {
@@ -321,7 +327,7 @@ static int do_relocs(struct host1x_job *job, struct host1x_job_gather *g)
                if (cmdbuf != reloc->cmdbuf.bo)
                        continue;
 
-               if (IS_ENABLED(CONFIG_TEGRA_HOST1X_FIREWALL)) {
+               if (job->enable_firewall) {
                        target = (u32 *)job->gather_copy_mapped +
                                        reloc->cmdbuf.offset / sizeof(u32) +
                                                g->offset / sizeof(u32);
@@ -634,7 +640,7 @@ int host1x_job_pin(struct host1x_job *job, struct device *dev)
        if (err)
                goto out;
 
-       if (IS_ENABLED(CONFIG_TEGRA_HOST1X_FIREWALL)) {
+       if (job->enable_firewall) {
                err = copy_gathers(host->dev, job, dev);
                if (err)
                        goto out;
@@ -653,7 +659,7 @@ int host1x_job_pin(struct host1x_job *job, struct device *dev)
                        continue;
 
                /* copy_gathers() sets gathers base if firewall is enabled */
-               if (!IS_ENABLED(CONFIG_TEGRA_HOST1X_FIREWALL))
+               if (!job->enable_firewall)
                        g->base = job->gather_addr_phys[i];
 
                for (j = i + 1; j < job->num_cmds; j++) {
@@ -688,8 +694,7 @@ void host1x_job_unpin(struct host1x_job *job)
                struct device *dev = unpin->dev ?: host->dev;
                struct sg_table *sgt = unpin->sgt;
 
-               if (!IS_ENABLED(CONFIG_TEGRA_HOST1X_FIREWALL) &&
-                   unpin->size && host->domain) {
+               if (!job->enable_firewall && unpin->size && host->domain) {
                        iommu_unmap(host->domain, job->addr_phys[i],
                                    unpin->size);
                        free_iova(&host->iova,
index 2127762..7bccf58 100644 (file)
@@ -272,10 +272,14 @@ struct host1x_job {
        /* Callback called when job is freed */
        void (*release)(struct host1x_job *job);
        void *user_data;
+
+       /* Whether host1x-side firewall should be ran for this job or not */
+       bool enable_firewall;
 };
 
 struct host1x_job *host1x_job_alloc(struct host1x_channel *ch,
-                                   u32 num_cmdbufs, u32 num_relocs);
+                                   u32 num_cmdbufs, u32 num_relocs,
+                                   bool skip_firewall);
 void host1x_job_add_gather(struct host1x_job *job, struct host1x_bo *bo,
                           unsigned int words, unsigned int offset);
 void host1x_job_add_wait(struct host1x_job *job, u32 id, u32 thresh,