drm/etnaviv: add flushing logic for MMUv2
authorLucas Stach <l.stach@pengutronix.de>
Fri, 19 Aug 2016 22:01:24 +0000 (00:01 +0200)
committerLucas Stach <l.stach@pengutronix.de>
Thu, 15 Sep 2016 13:29:41 +0000 (15:29 +0200)
Flushing works differently on MMUv2, in that it's only necessary
to set a single bit in the control register to flush all translation
units. A semaphore stall then makes sure that the flush has propagated
properly.

Signed-off-by: Lucas Stach <l.stach@pengutronix.de>
drivers/gpu/drm/etnaviv/etnaviv_buffer.c

index 47b93427fecb524c798cbbab9472ab8efa52b53a..cb86c7e5495c58b5a855cede81f20e387d5d6ec0 100644 (file)
@@ -276,8 +276,12 @@ void etnaviv_buffer_queue(struct etnaviv_gpu *gpu, unsigned int event,
                extra_dwords = 1;
 
                /* flush command */
-               if (gpu->mmu->need_flush)
-                       extra_dwords += 1;
+               if (gpu->mmu->need_flush) {
+                       if (gpu->mmu->version == ETNAVIV_IOMMU_V1)
+                               extra_dwords += 1;
+                       else
+                               extra_dwords += 3;
+               }
 
                /* pipe switch commands */
                if (gpu->switch_context)
@@ -287,12 +291,23 @@ void etnaviv_buffer_queue(struct etnaviv_gpu *gpu, unsigned int event,
 
                if (gpu->mmu->need_flush) {
                        /* Add the MMU flush */
-                       CMD_LOAD_STATE(buffer, VIVS_GL_FLUSH_MMU,
-                                      VIVS_GL_FLUSH_MMU_FLUSH_FEMMU |
-                                      VIVS_GL_FLUSH_MMU_FLUSH_UNK1 |
-                                      VIVS_GL_FLUSH_MMU_FLUSH_UNK2 |
-                                      VIVS_GL_FLUSH_MMU_FLUSH_PEMMU |
-                                      VIVS_GL_FLUSH_MMU_FLUSH_UNK4);
+                       if (gpu->mmu->version == ETNAVIV_IOMMU_V1) {
+                               CMD_LOAD_STATE(buffer, VIVS_GL_FLUSH_MMU,
+                                              VIVS_GL_FLUSH_MMU_FLUSH_FEMMU |
+                                              VIVS_GL_FLUSH_MMU_FLUSH_UNK1 |
+                                              VIVS_GL_FLUSH_MMU_FLUSH_UNK2 |
+                                              VIVS_GL_FLUSH_MMU_FLUSH_PEMMU |
+                                              VIVS_GL_FLUSH_MMU_FLUSH_UNK4);
+                       } else {
+                               CMD_LOAD_STATE(buffer, VIVS_MMUv2_CONFIGURATION,
+                                       VIVS_MMUv2_CONFIGURATION_MODE_MASK |
+                                       VIVS_MMUv2_CONFIGURATION_ADDRESS_MASK |
+                                       VIVS_MMUv2_CONFIGURATION_FLUSH_FLUSH);
+                               CMD_SEM(buffer, SYNC_RECIPIENT_FE,
+                                       SYNC_RECIPIENT_PE);
+                               CMD_STALL(buffer, SYNC_RECIPIENT_FE,
+                                       SYNC_RECIPIENT_PE);
+                       }
 
                        gpu->mmu->need_flush = false;
                }