1 From f232d9ec029ce3e2543b05213e2979e01e503408 Mon Sep 17 00:00:00 2001
2 From: Lucas Stach <l.stach@pengutronix.de>
3 Date: Wed, 26 Feb 2020 16:27:08 +0100
4 Subject: [PATCH] drm/etnaviv: fix TS cache flushing on GPUs with BLT engine
6 As seen in the Vivante kernel driver, most GPUs with the BLT engine have
7 a broken TS cache flush. The workaround is to temporarily set the BLT
8 command to CLEAR_IMAGE, without actually executing the clear. Apparently
9 this state change is enough to trigger the required TS cache flush. As
10 the BLT engine is completely asychronous, we also need a few more stall
11 states to synchronize the flush with the frontend.
13 Root-caused-by: Jonathan Marek <jonathan@marek.ca>
14 Signed-off-by: Lucas Stach <l.stach@pengutronix.de>
16 drivers/gpu/drm/etnaviv/etnaviv_buffer.c | 60 ++++++++++++++++++++++--
17 drivers/gpu/drm/etnaviv/state_blt.xml.h | 2 +
18 2 files changed, 57 insertions(+), 5 deletions(-)
20 diff --git a/drivers/gpu/drm/etnaviv/etnaviv_buffer.c b/drivers/gpu/drm/etnaviv/etnaviv_buffer.c
21 index 32d9fac587f9..76d38561c910 100644
22 --- a/drivers/gpu/drm/etnaviv/etnaviv_buffer.c
23 +++ b/drivers/gpu/drm/etnaviv/etnaviv_buffer.c
26 #include "common.xml.h"
27 #include "state.xml.h"
28 +#include "state_blt.xml.h"
29 #include "state_hi.xml.h"
30 #include "state_3d.xml.h"
31 #include "cmdstream.xml.h"
32 @@ -233,6 +234,8 @@ void etnaviv_buffer_end(struct etnaviv_gpu *gpu)
33 struct etnaviv_cmdbuf *buffer = &gpu->buffer;
34 unsigned int waitlink_offset = buffer->user_size - 16;
35 u32 link_target, flush = 0;
36 + bool has_blt = !!(gpu->identity.minor_features5 &
37 + chipMinorFeatures5_BLT_ENGINE);
39 lockdep_assert_held(&gpu->lock);
41 @@ -248,16 +251,38 @@ void etnaviv_buffer_end(struct etnaviv_gpu *gpu)
43 unsigned int dwords = 7;
48 link_target = etnaviv_buffer_reserve(gpu, buffer, dwords);
50 CMD_SEM(buffer, SYNC_RECIPIENT_FE, SYNC_RECIPIENT_PE);
51 CMD_STALL(buffer, SYNC_RECIPIENT_FE, SYNC_RECIPIENT_PE);
53 + CMD_LOAD_STATE(buffer, VIVS_BLT_ENABLE, 0x1);
54 + CMD_SEM(buffer, SYNC_RECIPIENT_FE, SYNC_RECIPIENT_BLT);
55 + CMD_STALL(buffer, SYNC_RECIPIENT_FE, SYNC_RECIPIENT_BLT);
56 + CMD_LOAD_STATE(buffer, VIVS_BLT_ENABLE, 0x0);
58 CMD_LOAD_STATE(buffer, VIVS_GL_FLUSH_CACHE, flush);
59 - if (gpu->exec_state == ETNA_PIPE_3D)
60 - CMD_LOAD_STATE(buffer, VIVS_TS_FLUSH_CACHE,
61 - VIVS_TS_FLUSH_CACHE_FLUSH);
62 + if (gpu->exec_state == ETNA_PIPE_3D) {
64 + CMD_LOAD_STATE(buffer, VIVS_BLT_ENABLE, 0x1);
65 + CMD_LOAD_STATE(buffer, VIVS_BLT_SET_COMMAND, 0x1);
66 + CMD_LOAD_STATE(buffer, VIVS_BLT_ENABLE, 0x0);
68 + CMD_LOAD_STATE(buffer, VIVS_TS_FLUSH_CACHE,
69 + VIVS_TS_FLUSH_CACHE_FLUSH);
72 CMD_SEM(buffer, SYNC_RECIPIENT_FE, SYNC_RECIPIENT_PE);
73 CMD_STALL(buffer, SYNC_RECIPIENT_FE, SYNC_RECIPIENT_PE);
75 + CMD_LOAD_STATE(buffer, VIVS_BLT_ENABLE, 0x1);
76 + CMD_SEM(buffer, SYNC_RECIPIENT_FE, SYNC_RECIPIENT_BLT);
77 + CMD_STALL(buffer, SYNC_RECIPIENT_FE, SYNC_RECIPIENT_BLT);
78 + CMD_LOAD_STATE(buffer, VIVS_BLT_ENABLE, 0x0);
82 etnaviv_buffer_replace_wait(buffer, waitlink_offset,
83 @@ -323,6 +348,8 @@ void etnaviv_buffer_queue(struct etnaviv_gpu *gpu, u32 exec_state,
84 bool switch_mmu_context = gpu->mmu_context != mmu_context;
85 unsigned int new_flush_seq = READ_ONCE(gpu->mmu_context->flush_seq);
86 bool need_flush = switch_mmu_context || gpu->flush_seq != new_flush_seq;
87 + bool has_blt = !!(gpu->identity.minor_features5 &
88 + chipMinorFeatures5_BLT_ENGINE);
90 lockdep_assert_held(&gpu->lock);
92 @@ -433,6 +460,15 @@ void etnaviv_buffer_queue(struct etnaviv_gpu *gpu, u32 exec_state,
93 * 2 semaphore stall + 1 event + 1 wait + 1 link.
98 + * When the BLT engine is present we need 6 more dwords in the return
99 + * target: 3 enable/flush/disable + 4 enable/semaphore stall/disable,
100 + * but we don't need the normal TS flush state.
103 + return_dwords += 6;
105 return_target = etnaviv_buffer_reserve(gpu, buffer, return_dwords);
106 CMD_LINK(cmdbuf, return_dwords, return_target);
108 @@ -447,11 +483,25 @@ void etnaviv_buffer_queue(struct etnaviv_gpu *gpu, u32 exec_state,
109 CMD_LOAD_STATE(buffer, VIVS_GL_FLUSH_CACHE,
110 VIVS_GL_FLUSH_CACHE_DEPTH |
111 VIVS_GL_FLUSH_CACHE_COLOR);
112 - CMD_LOAD_STATE(buffer, VIVS_TS_FLUSH_CACHE,
113 - VIVS_TS_FLUSH_CACHE_FLUSH);
115 + CMD_LOAD_STATE(buffer, VIVS_BLT_ENABLE, 0x1);
116 + CMD_LOAD_STATE(buffer, VIVS_BLT_SET_COMMAND, 0x1);
117 + CMD_LOAD_STATE(buffer, VIVS_BLT_ENABLE, 0x0);
119 + CMD_LOAD_STATE(buffer, VIVS_TS_FLUSH_CACHE,
120 + VIVS_TS_FLUSH_CACHE_FLUSH);
123 CMD_SEM(buffer, SYNC_RECIPIENT_FE, SYNC_RECIPIENT_PE);
124 CMD_STALL(buffer, SYNC_RECIPIENT_FE, SYNC_RECIPIENT_PE);
127 + CMD_LOAD_STATE(buffer, VIVS_BLT_ENABLE, 0x1);
128 + CMD_SEM(buffer, SYNC_RECIPIENT_FE, SYNC_RECIPIENT_BLT);
129 + CMD_STALL(buffer, SYNC_RECIPIENT_FE, SYNC_RECIPIENT_BLT);
130 + CMD_LOAD_STATE(buffer, VIVS_BLT_ENABLE, 0x0);
133 CMD_LOAD_STATE(buffer, VIVS_GL_EVENT, VIVS_GL_EVENT_EVENT_ID(event) |
134 VIVS_GL_EVENT_FROM_PE);
136 diff --git a/drivers/gpu/drm/etnaviv/state_blt.xml.h b/drivers/gpu/drm/etnaviv/state_blt.xml.h
137 index daae55995def..0e8bcf9dcc93 100644
138 --- a/drivers/gpu/drm/etnaviv/state_blt.xml.h
139 +++ b/drivers/gpu/drm/etnaviv/state_blt.xml.h
140 @@ -46,6 +46,8 @@ DEALINGS IN THE SOFTWARE.
142 /* This is a cut-down version of the state_blt.xml.h file */
144 +#define VIVS_BLT_SET_COMMAND 0x000140ac
146 #define VIVS_BLT_ENABLE 0x000140b8
147 #define VIVS_BLT_ENABLE_ENABLE 0x00000001