Tegra DRM / Host1x drivers improvements and corrections
v2 cover Tegra DRM / Host1x drivers improvements and corrections
Hello!
This small series fixes a few minor long-standing problems of the Tegra DRM and Host1x drivers. It also adds a push buffer dumping support, which is a minor debugging feature.
Changelog:
v2: - The drm/tegra and host1x patches got aggregated into this common
series because I'm a bit worried that the standalone patches may become forgotten for a long time.
- In the patch "gpu: host1x: debug: Dump push buffer state" I fixed the printk formatting problem on ARM64 that was reported by kernel test robot for a previous version of this patch.
Dmitry Osipenko (6):
drm/tegra: gr3d: Assert reset before power-gating drm/tegra: gr2d: Add tiled PATBASE address register
gpu: host1x: Optimize BOs usage when firewall is enabled
gpu: host1x: Put gather's BO on pinning error
gpu: host1x: debug: Fix multiple channels emitting messages
simultaneously
gpu: host1x: debug: Dump push buffer state
drivers/gpu/drm/tegra/gr2d.c | 1 + drivers/gpu/drm/tegra/gr2d.h | 1 + drivers/gpu/drm/tegra/gr3d.c | 2 ++ drivers/gpu/host1x/debug.c | 4 ++++ drivers/gpu/host1x/hw/debug_hw.c | 6 ++++++ drivers/gpu/host1x/job.c | 27 ++++++++++++++++++++------- 6 files changed, 34 insertions(+), 7 deletions(-)
Signature · 1 line
2.26.0
PATCH v2 1/6 drm/tegra: gr3d: Assert reset before power-gating
Tegra TRM documentation states that hardware should be in a default state when power partition is turned off, i.e. reset should be asserted. This patch adds the missing reset assertions.
--- drivers/gpu/drm/tegra/gr3d.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/gpu/drm/tegra/gr3d.c +2 -0
@@ -381,10 +381,12 @@ static int gr3d_remove(struct platform_device *pdev) }if (gr3d->clk_secondary) { +reset_control_assert (gr3d->rst_secondary);tegra_powergate_power_off (TEGRA_POWERGATE_3D1 );clk_disable_unprepare (gr3d->clk_secondary); } +reset_control_assert (gr3d->rst);tegra_powergate_power_off (TEGRA_POWERGATE_3D );clk_disable_unprepare (gr3d->clk);
Signature · 1 line
2.26.0
PATCH v2 2/6 drm/tegra: gr2d: Add tiled PATBASE address register
In reply to Dmitry OsipenkoThere are two PATBASE address registers, one for linear layout and other for tiled. The driver's address registers list misses the tiled PATBASE register.
--- drivers/gpu/drm/tegra/gr2d.c | 1 + drivers/gpu/drm/tegra/gr2d.h | 1 + 2 files changed, 2 insertions(+)
drivers/gpu/drm/tegra/gr2d.c +1 -0
@@ -177,6 +177,7 @@ static const u32 gr2d_addr_regs[] = {GR2D_DSTC_BASE_ADDR ,GR2D_SRCA_BASE_ADDR ,GR2D_SRCB_BASE_ADDR , +GR2D_PATBASE_ADDR ,GR2D_SRC_BASE_ADDR_SB ,GR2D_DSTA_BASE_ADDR_SB , GR2D_DSTB_BASE_ADDR_SB,
drivers/gpu/drm/tegra/gr2d.h +1 -0
@@ -14,6 +14,7 @@#define GR2D_DSTC_BASE_ADDR 0x2d#define GR2D_SRCA_BASE_ADDR 0x31#define GR2D_SRCB_BASE_ADDR 0x32 +#define GR2D_PATBASE_ADDR 0x47#define GR2D_SRC_BASE_ADDR_SB 0x48#define GR2D_DSTA_BASE_ADDR_SB 0x49#define GR2D_DSTB_BASE_ADDR_SB 0x4a
Signature · 1 line
2.26.0
PATCH v2 3/6 gpu: host1x: Optimize BOs usage when firewall is enabled
In reply to Dmitry OsipenkoWe don't need to hold and pin original BOs of the gathers in a case of enabled firewall because in this case gather's content is copied and the copy is used by the executed job.
--- drivers/gpu/host1x/job.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-)
drivers/gpu/host1x/job.c +12 -2
@@ -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) +
@@ -183,6 +186,13 @@ 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 ;
@@ -216,7 +226,7 @@ static unsigned int pin_job(struct host1x *host, struct host1x_job *job) goto unpin; } -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);
Signature · 1 line
2.26.0
PATCH v2 4/6 gpu: host1x: Put gather's BO on pinning error
In reply to Dmitry OsipenkoThis patch fixes gather's BO refcounting on a pinning error. Gather's BO won't be leaked now if something goes wrong.
--- drivers/gpu/host1x/job.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-)
drivers/gpu/host1x/job.c +8 -5
@@ -105,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;
@@ -194,7 +195,6 @@ static unsigned int pin_job(struct host1x *host, struct host1x_job *job)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;
@@ -204,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 ;
@@ -223,7 +224,7 @@ 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 (host->domain) {
@@ -236,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,
@@ -245,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;
@@ -255,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 ;
@@ -273,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;
Signature · 1 line
2.26.0
PATCH v2 5/6 gpu: host1x: debug: Fix multiple channels emitting messages simultaneously
In reply to Dmitry OsipenkoOnce channel's job is hung, it dumps the channel's state into KMSG before tearing down the offending job. If multiple channels hang at once, then they dump messages simultaneously, making the debug info unreadable, and thus, useless. This patch adds mutex which allows only one channel to emit debug messages at a time.
--- drivers/gpu/host1x/debug.c | 4 ++++ 1 file changed, 4 insertions(+)
drivers/gpu/host1x/debug.c +4 -0
@@ -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 ;
Signature · 1 line
2.26.0
PATCH v2 6/6 gpu: host1x: debug: Dump push buffer state
In reply to Dmitry OsipenkoWhen job hangs and there is a memory error pointing at channel's push buffer, it is very handy to know the push buffer's state. This patch makes the push buffer's state to be dumped into KMSG in addition to the job's gathers.
--- drivers/gpu/host1x/hw/debug_hw.c | 6 ++++++ 1 file changed, 6 insertions(+)
drivers/gpu/host1x/hw/debug_hw.c +6 -0
@@ -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;
Signature · 1 line
2.26.0