diff options
author | Mikko Perttunen <mperttunen@nvidia.com> | 2021-06-10 14:04:46 +0300 |
---|---|---|
committer | Thierry Reding <treding@nvidia.com> | 2021-08-10 15:42:49 +0300 |
commit | 0fddaa85d66140466df8e848afcda452b7d7b416 (patch) | |
tree | 1a720d5474e9f42c831dca98637f613d709a1709 | |
parent | e902585fc8b639f1a1258eaa6265e98994e34ef8 (diff) | |
download | linux-0fddaa85d66140466df8e848afcda452b7d7b416.tar.xz |
gpu: host1x: Add option to skip firewall for a job
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>
-rw-r--r-- | drivers/gpu/drm/tegra/drm.c | 2 | ||||
-rw-r--r-- | drivers/gpu/host1x/job.c | 21 | ||||
-rw-r--r-- | include/linux/host1x.h | 6 |
3 files changed, 19 insertions, 10 deletions
diff --git a/drivers/gpu/drm/tegra/drm.c b/drivers/gpu/drm/tegra/drm.c index 739250acd498..0e2a6f24c4f6 100644 --- a/drivers/gpu/drm/tegra/drm.c +++ b/drivers/gpu/drm/tegra/drm.c @@ -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; diff --git a/drivers/gpu/host1x/job.c b/drivers/gpu/host1x/job.c index 32619b73a2fc..0eef6df7c89e 100644 --- a/drivers/gpu/host1x/job.c +++ b/drivers/gpu/host1x/job.c @@ -24,14 +24,18 @@ #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, diff --git a/include/linux/host1x.h b/include/linux/host1x.h index 2127762fc63d..7bccf589aba7 100644 --- a/include/linux/host1x.h +++ b/include/linux/host1x.h @@ -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, |