diff options
Diffstat (limited to 'drivers/gpu/host1x')
-rw-r--r-- | drivers/gpu/host1x/debug.c | 4 | ||||
-rw-r--r-- | drivers/gpu/host1x/hw/debug_hw.c | 6 | ||||
-rw-r--r-- | drivers/gpu/host1x/job.c | 27 | ||||
-rw-r--r-- | drivers/gpu/host1x/mipi.c | 37 |
4 files changed, 51 insertions, 23 deletions
diff --git a/drivers/gpu/host1x/debug.c b/drivers/gpu/host1x/debug.c index c0392672a842..1b4997bda1c7 100644 --- a/drivers/gpu/host1x/debug.c +++ b/drivers/gpu/host1x/debug.c @@ -16,6 +16,8 @@ #include "debug.h" #include "channel.h" +static DEFINE_MUTEX(debug_lock); + unsigned int host1x_debug_trace_cmdbuf; static pid_t host1x_debug_force_timeout_pid; @@ -52,12 +54,14 @@ static int show_channel(struct host1x_channel *ch, void *data, bool show_fifo) struct output *o = data; mutex_lock(&ch->cdma.lock); + mutex_lock(&debug_lock); if (show_fifo) host1x_hw_show_channel_fifo(m, ch, o); host1x_hw_show_channel_cdma(m, ch, o); + mutex_unlock(&debug_lock); mutex_unlock(&ch->cdma.lock); return 0; diff --git a/drivers/gpu/host1x/hw/debug_hw.c b/drivers/gpu/host1x/hw/debug_hw.c index 02125842071c..f31bcfa1b837 100644 --- a/drivers/gpu/host1x/hw/debug_hw.c +++ b/drivers/gpu/host1x/hw/debug_hw.c @@ -192,8 +192,14 @@ static void show_gather(struct output *o, phys_addr_t phys_addr, static void show_channel_gathers(struct output *o, struct host1x_cdma *cdma) { + struct push_buffer *pb = &cdma->push_buffer; struct host1x_job *job; + host1x_debug_output(o, "PUSHBUF at %pad, %u words\n", + &pb->dma, pb->size / 4); + + show_gather(o, pb->dma, pb->size / 4, cdma, pb->dma, pb->mapped); + list_for_each_entry(job, &cdma->sync_queue, list) { unsigned int i; diff --git a/drivers/gpu/host1x/job.c b/drivers/gpu/host1x/job.c index a10643aa89aa..89b6c14b7392 100644 --- a/drivers/gpu/host1x/job.c +++ b/drivers/gpu/host1x/job.c @@ -27,10 +27,13 @@ struct host1x_job *host1x_job_alloc(struct host1x_channel *ch, u32 num_cmdbufs, u32 num_relocs) { struct host1x_job *job = NULL; - unsigned int num_unpins = num_cmdbufs + num_relocs; + unsigned int num_unpins = num_relocs; u64 total; void *mem; + if (!IS_ENABLED(CONFIG_TEGRA_HOST1X_FIREWALL)) + num_unpins += num_cmdbufs; + /* Check that we're not going to overflow */ total = sizeof(struct host1x_job) + (u64)num_relocs * sizeof(struct host1x_reloc) + @@ -102,6 +105,7 @@ static unsigned int pin_job(struct host1x *host, struct host1x_job *job) { struct host1x_client *client = job->client; struct device *dev = client->dev; + struct host1x_job_gather *g; struct iommu_domain *domain; unsigned int i; int err; @@ -183,8 +187,14 @@ static unsigned int pin_job(struct host1x *host, struct host1x_job *job) job->num_unpins++; } + /* + * We will copy gathers BO content later, so there is no need to + * hold and pin them. + */ + if (IS_ENABLED(CONFIG_TEGRA_HOST1X_FIREWALL)) + return 0; + for (i = 0; i < job->num_gathers; i++) { - struct host1x_job_gather *g = &job->gathers[i]; size_t gather_size = 0; struct scatterlist *sg; struct sg_table *sgt; @@ -194,6 +204,7 @@ static unsigned int pin_job(struct host1x *host, struct host1x_job *job) dma_addr_t *phys; unsigned int j; + g = &job->gathers[i]; g->bo = host1x_bo_get(g->bo); if (!g->bo) { err = -EINVAL; @@ -213,10 +224,10 @@ static unsigned int pin_job(struct host1x *host, struct host1x_job *job) sgt = host1x_bo_pin(host->dev, g->bo, phys); if (IS_ERR(sgt)) { err = PTR_ERR(sgt); - goto unpin; + goto put; } - if (!IS_ENABLED(CONFIG_TEGRA_HOST1X_FIREWALL) && host->domain) { + if (host->domain) { for_each_sg(sgt->sgl, sg, sgt->nents, j) gather_size += sg->length; gather_size = iova_align(&host->iova, gather_size); @@ -226,7 +237,7 @@ static unsigned int pin_job(struct host1x *host, struct host1x_job *job) host->iova_end >> shift, true); if (!alloc) { err = -ENOMEM; - goto unpin; + goto put; } err = iommu_map_sg(host->domain, @@ -235,7 +246,7 @@ static unsigned int pin_job(struct host1x *host, struct host1x_job *job) if (err == 0) { __free_iova(&host->iova, alloc); err = -EINVAL; - goto unpin; + goto put; } job->unpins[job->num_unpins].size = gather_size; @@ -245,7 +256,7 @@ static unsigned int pin_job(struct host1x *host, struct host1x_job *job) DMA_TO_DEVICE); if (!err) { err = -ENOMEM; - goto unpin; + goto put; } job->unpins[job->num_unpins].dir = DMA_TO_DEVICE; @@ -263,6 +274,8 @@ static unsigned int pin_job(struct host1x *host, struct host1x_job *job) return 0; +put: + host1x_bo_put(g->bo); unpin: host1x_job_unpin(job); return err; diff --git a/drivers/gpu/host1x/mipi.c b/drivers/gpu/host1x/mipi.c index e00809d996a2..e606464aa43c 100644 --- a/drivers/gpu/host1x/mipi.c +++ b/drivers/gpu/host1x/mipi.c @@ -21,9 +21,9 @@ */ #include <linux/clk.h> -#include <linux/delay.h> #include <linux/host1x.h> #include <linux/io.h> +#include <linux/iopoll.h> #include <linux/of_platform.h> #include <linux/platform_device.h> #include <linux/slab.h> @@ -206,9 +206,9 @@ static int tegra_mipi_power_down(struct tegra_mipi *mipi) return 0; } -struct tegra_mipi_device *tegra_mipi_request(struct device *device) +struct tegra_mipi_device *tegra_mipi_request(struct device *device, + struct device_node *np) { - struct device_node *np = device->of_node; struct tegra_mipi_device *dev; struct of_phandle_args args; int err; @@ -293,22 +293,29 @@ int tegra_mipi_disable(struct tegra_mipi_device *dev) } EXPORT_SYMBOL(tegra_mipi_disable); -static int tegra_mipi_wait(struct tegra_mipi *mipi) +int tegra_mipi_wait(struct tegra_mipi_device *device) { - unsigned long timeout = jiffies + msecs_to_jiffies(250); + struct tegra_mipi *mipi = device->mipi; + void __iomem *status_reg = mipi->regs + (MIPI_CAL_STATUS << 2); u32 value; + int err; - while (time_before(jiffies, timeout)) { - value = tegra_mipi_readl(mipi, MIPI_CAL_STATUS); - if ((value & MIPI_CAL_STATUS_ACTIVE) == 0 && - (value & MIPI_CAL_STATUS_DONE) != 0) - return 0; + err = clk_enable(device->mipi->clk); + if (err < 0) + return err; - usleep_range(10, 50); - } + mutex_lock(&device->mipi->lock); - return -ETIMEDOUT; + err = readl_relaxed_poll_timeout(status_reg, value, + !(value & MIPI_CAL_STATUS_ACTIVE) && + (value & MIPI_CAL_STATUS_DONE), 50, + 250000); + mutex_unlock(&device->mipi->lock); + clk_disable(device->mipi->clk); + + return err; } +EXPORT_SYMBOL(tegra_mipi_wait); int tegra_mipi_calibrate(struct tegra_mipi_device *device) { @@ -374,12 +381,10 @@ int tegra_mipi_calibrate(struct tegra_mipi_device *device) value |= MIPI_CAL_CTRL_START; tegra_mipi_writel(device->mipi, value, MIPI_CAL_CTRL); - err = tegra_mipi_wait(device->mipi); - mutex_unlock(&device->mipi->lock); clk_disable(device->mipi->clk); - return err; + return 0; } EXPORT_SYMBOL(tegra_mipi_calibrate); |