Thread (59 messages) 59 messages, 5 authors, 2020-09-01

Re: [PATCH 16/19] drm/msm/a6xx: Add support for per-instance pagetables

From: Rob Clark <hidden>
Date: 2020-08-17 18:55:23
Also in: dri-devel, linux-arm-msm, linux-iommu, lkml

On Mon, Aug 17, 2020 at 8:41 AM Akhil P Oommen [off-list ref] wrote:
On 8/14/2020 8:11 AM, Rob Clark wrote:
quoted
From: Jordan Crouse <redacted>

Add support for using per-instance pagetables if all the dependencies are
available.

Signed-off-by: Jordan Crouse <redacted>
Signed-off-by: Rob Clark <redacted>
---
  drivers/gpu/drm/msm/adreno/a6xx_gpu.c | 70 +++++++++++++++++++++++++++
  drivers/gpu/drm/msm/adreno/a6xx_gpu.h |  1 +
  drivers/gpu/drm/msm/msm_ringbuffer.h  |  1 +
  3 files changed, 72 insertions(+)
diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
index 5eabb0109577..9653ac9b3cb8 100644
--- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
+++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
@@ -81,6 +81,56 @@ static void get_stats_counter(struct msm_ringbuffer *ring, u32 counter,
      OUT_RING(ring, upper_32_bits(iova));
  }

+static void a6xx_set_pagetable(struct a6xx_gpu *a6xx_gpu,
+             struct msm_ringbuffer *ring, struct msm_file_private *ctx)
+{
+     phys_addr_t ttbr;
+     u32 asid;
+     u64 memptr = rbmemptr(ring, ttbr0);
+
+     if (ctx == a6xx_gpu->cur_ctx)
+             return;
+
+     if (msm_iommu_pagetable_params(ctx->aspace->mmu, &ttbr, &asid))
+             return;
+
+     /* Execute the table update */
+     OUT_PKT7(ring, CP_SMMU_TABLE_UPDATE, 4);
+     OUT_RING(ring, CP_SMMU_TABLE_UPDATE_0_TTBR0_LO(lower_32_bits(ttbr)));
+
+     /*
+      * For now ignore the asid since the smmu driver uses a TLBIASID to
+      * flush the TLB when we use iommu_flush_tlb_all() and the smmu driver
+      * isn't aware that the asid changed.  Instead, keep the default asid
+      * (0, same as the context bank) to make sure the TLB is properly
+      * flushed.
+      */
+     OUT_RING(ring,
+             CP_SMMU_TABLE_UPDATE_1_TTBR0_HI(upper_32_bits(ttbr)) |
+             CP_SMMU_TABLE_UPDATE_1_ASID(0));
+     OUT_RING(ring, CP_SMMU_TABLE_UPDATE_2_CONTEXTIDR(0));
+     OUT_RING(ring, CP_SMMU_TABLE_UPDATE_3_CONTEXTBANK(0));
+
+     /*
+      * Write the new TTBR0 to the memstore. This is good for debugging.
+      */
+     OUT_PKT7(ring, CP_MEM_WRITE, 4);
+     OUT_RING(ring, CP_MEM_WRITE_0_ADDR_LO(lower_32_bits(memptr)));
+     OUT_RING(ring, CP_MEM_WRITE_1_ADDR_HI(upper_32_bits(memptr)));
+     OUT_RING(ring, lower_32_bits(ttbr));
+     OUT_RING(ring, (0 << 16) | upper_32_bits(ttbr));
why (0 << 16) is required here?
That would normally be (asid << 16), except due to the way we
currently flush tlb, we need to use asid==0..

(Although msm_iommu_pagetable_params() should return asid==0, I fixed
that in msm_iommu_pagetable_create() and didn't notice that Jordan had
fixed that here instead)

BR,
-R
quoted
+
+     /*
+      * And finally, trigger a uche flush to be sure there isn't anything
+      * lingering in that part of the GPU
+      */
+
+     OUT_PKT7(ring, CP_EVENT_WRITE, 1);
+     OUT_RING(ring, 0x31);
This may be unnecessary, but no harm in keeping it. SMMU_TABLE_UPDATE is
supposed to do a UCHE flush.

-Akhil
quoted
+
+     a6xx_gpu->cur_ctx = ctx;
+}
+
  static void a6xx_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit)
  {
      unsigned int index = submit->seqno % MSM_GPU_SUBMIT_STATS_COUNT;
@@ -90,6 +140,8 @@ static void a6xx_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit)
      struct msm_ringbuffer *ring = submit->ring;
      unsigned int i;

+     a6xx_set_pagetable(a6xx_gpu, ring, submit->queue->ctx);
+
      get_stats_counter(ring, REG_A6XX_RBBM_PERFCTR_CP_0_LO,
              rbmemptr_stats(ring, index, cpcycles_start));
@@ -696,6 +748,8 @@ static int a6xx_hw_init(struct msm_gpu *gpu)
      /* Always come up on rb 0 */
      a6xx_gpu->cur_ring = gpu->rb[0];

+     a6xx_gpu->cur_ctx = NULL;
+
      /* Enable the SQE_to start the CP engine */
      gpu_write(gpu, REG_A6XX_CP_SQE_CNTL, 1);
@@ -1008,6 +1062,21 @@ static unsigned long a6xx_gpu_busy(struct msm_gpu *gpu)
      return (unsigned long)busy_time;
  }

+static struct msm_gem_address_space *
+a6xx_create_private_address_space(struct msm_gpu *gpu)
+{
+     struct msm_gem_address_space *aspace = NULL;
+     struct msm_mmu *mmu;
+
+     mmu = msm_iommu_pagetable_create(gpu->aspace->mmu);
+
+     if (!IS_ERR(mmu))
+             aspace = msm_gem_address_space_create(mmu,
+                     "gpu", 0x100000000ULL, 0x1ffffffffULL);
+
+     return aspace;
+}
+
  static const struct adreno_gpu_funcs funcs = {
      .base = {
              .get_param = adreno_get_param,
@@ -1031,6 +1100,7 @@ static const struct adreno_gpu_funcs funcs = {
              .gpu_state_put = a6xx_gpu_state_put,
  #endif
              .create_address_space = adreno_iommu_create_address_space,
+             .create_private_address_space = a6xx_create_private_address_space,
      },
      .get_timestamp = a6xx_get_timestamp,
  };
diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.h b/drivers/gpu/drm/msm/adreno/a6xx_gpu.h
index 03ba60d5b07f..da22d7549d9b 100644
--- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.h
+++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.h
@@ -19,6 +19,7 @@ struct a6xx_gpu {
      uint64_t sqe_iova;

      struct msm_ringbuffer *cur_ring;
+     struct msm_file_private *cur_ctx;

      struct a6xx_gmu gmu;
  };
diff --git a/drivers/gpu/drm/msm/msm_ringbuffer.h b/drivers/gpu/drm/msm/msm_ringbuffer.h
index 7764373d0ed2..0987d6bf848c 100644
--- a/drivers/gpu/drm/msm/msm_ringbuffer.h
+++ b/drivers/gpu/drm/msm/msm_ringbuffer.h
@@ -31,6 +31,7 @@ struct msm_rbmemptrs {
      volatile uint32_t fence;

      volatile struct msm_gpu_submit_stats stats[MSM_GPU_SUBMIT_STATS_COUNT];
+     volatile u64 ttbr0;
  };

  struct msm_ringbuffer {
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help