Skip to content

Commit de487e4

Browse files
committed
Merge branch 'etnaviv/next' of https://git.pengutronix.de/git/lst/linux into drm-next
- fix for potential out-of-bounds reads in the perfmon ioctl implementation from Christian - override to expose proper feature flags for the GC400 found on the STM32MP1 SoC, also from Christian - Guido fixed an issue where we would spuriously fail to enter runtime suspend due to a new GPU engine status bit on GC7000 - tree-wide change from Gustavo to get rid of zero-length arrays - fix for missed TS cache flush on GC7000, leading to spurious MMU faults from me - request pages from DMA32 zone on systems where we can't address all present memory from me Signed-off-by: Dave Airlie <[email protected]> From: Lucas Stach <[email protected]> Link: https://patchwork.freedesktop.org/patch/msgid/[email protected]
2 parents cb7adfd + f232d9e commit de487e4

File tree

11 files changed

+230
-35
lines changed

11 files changed

+230
-35
lines changed

drivers/gpu/drm/etnaviv/etnaviv_buffer.c

Lines changed: 55 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212

1313
#include "common.xml.h"
1414
#include "state.xml.h"
15+
#include "state_blt.xml.h"
1516
#include "state_hi.xml.h"
1617
#include "state_3d.xml.h"
1718
#include "cmdstream.xml.h"
@@ -233,6 +234,8 @@ void etnaviv_buffer_end(struct etnaviv_gpu *gpu)
233234
struct etnaviv_cmdbuf *buffer = &gpu->buffer;
234235
unsigned int waitlink_offset = buffer->user_size - 16;
235236
u32 link_target, flush = 0;
237+
bool has_blt = !!(gpu->identity.minor_features5 &
238+
chipMinorFeatures5_BLT_ENGINE);
236239

237240
lockdep_assert_held(&gpu->lock);
238241

@@ -248,16 +251,38 @@ void etnaviv_buffer_end(struct etnaviv_gpu *gpu)
248251
if (flush) {
249252
unsigned int dwords = 7;
250253

254+
if (has_blt)
255+
dwords += 10;
256+
251257
link_target = etnaviv_buffer_reserve(gpu, buffer, dwords);
252258

253259
CMD_SEM(buffer, SYNC_RECIPIENT_FE, SYNC_RECIPIENT_PE);
254260
CMD_STALL(buffer, SYNC_RECIPIENT_FE, SYNC_RECIPIENT_PE);
261+
if (has_blt) {
262+
CMD_LOAD_STATE(buffer, VIVS_BLT_ENABLE, 0x1);
263+
CMD_SEM(buffer, SYNC_RECIPIENT_FE, SYNC_RECIPIENT_BLT);
264+
CMD_STALL(buffer, SYNC_RECIPIENT_FE, SYNC_RECIPIENT_BLT);
265+
CMD_LOAD_STATE(buffer, VIVS_BLT_ENABLE, 0x0);
266+
}
255267
CMD_LOAD_STATE(buffer, VIVS_GL_FLUSH_CACHE, flush);
256-
if (gpu->exec_state == ETNA_PIPE_3D)
257-
CMD_LOAD_STATE(buffer, VIVS_TS_FLUSH_CACHE,
258-
VIVS_TS_FLUSH_CACHE_FLUSH);
268+
if (gpu->exec_state == ETNA_PIPE_3D) {
269+
if (has_blt) {
270+
CMD_LOAD_STATE(buffer, VIVS_BLT_ENABLE, 0x1);
271+
CMD_LOAD_STATE(buffer, VIVS_BLT_SET_COMMAND, 0x1);
272+
CMD_LOAD_STATE(buffer, VIVS_BLT_ENABLE, 0x0);
273+
} else {
274+
CMD_LOAD_STATE(buffer, VIVS_TS_FLUSH_CACHE,
275+
VIVS_TS_FLUSH_CACHE_FLUSH);
276+
}
277+
}
259278
CMD_SEM(buffer, SYNC_RECIPIENT_FE, SYNC_RECIPIENT_PE);
260279
CMD_STALL(buffer, SYNC_RECIPIENT_FE, SYNC_RECIPIENT_PE);
280+
if (has_blt) {
281+
CMD_LOAD_STATE(buffer, VIVS_BLT_ENABLE, 0x1);
282+
CMD_SEM(buffer, SYNC_RECIPIENT_FE, SYNC_RECIPIENT_BLT);
283+
CMD_STALL(buffer, SYNC_RECIPIENT_FE, SYNC_RECIPIENT_BLT);
284+
CMD_LOAD_STATE(buffer, VIVS_BLT_ENABLE, 0x0);
285+
}
261286
CMD_END(buffer);
262287

263288
etnaviv_buffer_replace_wait(buffer, waitlink_offset,
@@ -323,6 +348,8 @@ void etnaviv_buffer_queue(struct etnaviv_gpu *gpu, u32 exec_state,
323348
bool switch_mmu_context = gpu->mmu_context != mmu_context;
324349
unsigned int new_flush_seq = READ_ONCE(gpu->mmu_context->flush_seq);
325350
bool need_flush = switch_mmu_context || gpu->flush_seq != new_flush_seq;
351+
bool has_blt = !!(gpu->identity.minor_features5 &
352+
chipMinorFeatures5_BLT_ENGINE);
326353

327354
lockdep_assert_held(&gpu->lock);
328355

@@ -433,6 +460,15 @@ void etnaviv_buffer_queue(struct etnaviv_gpu *gpu, u32 exec_state,
433460
* 2 semaphore stall + 1 event + 1 wait + 1 link.
434461
*/
435462
return_dwords = 7;
463+
464+
/*
465+
* When the BLT engine is present we need 6 more dwords in the return
466+
* target: 3 enable/flush/disable + 4 enable/semaphore stall/disable,
467+
* but we don't need the normal TS flush state.
468+
*/
469+
if (has_blt)
470+
return_dwords += 6;
471+
436472
return_target = etnaviv_buffer_reserve(gpu, buffer, return_dwords);
437473
CMD_LINK(cmdbuf, return_dwords, return_target);
438474

@@ -447,11 +483,25 @@ void etnaviv_buffer_queue(struct etnaviv_gpu *gpu, u32 exec_state,
447483
CMD_LOAD_STATE(buffer, VIVS_GL_FLUSH_CACHE,
448484
VIVS_GL_FLUSH_CACHE_DEPTH |
449485
VIVS_GL_FLUSH_CACHE_COLOR);
450-
CMD_LOAD_STATE(buffer, VIVS_TS_FLUSH_CACHE,
451-
VIVS_TS_FLUSH_CACHE_FLUSH);
486+
if (has_blt) {
487+
CMD_LOAD_STATE(buffer, VIVS_BLT_ENABLE, 0x1);
488+
CMD_LOAD_STATE(buffer, VIVS_BLT_SET_COMMAND, 0x1);
489+
CMD_LOAD_STATE(buffer, VIVS_BLT_ENABLE, 0x0);
490+
} else {
491+
CMD_LOAD_STATE(buffer, VIVS_TS_FLUSH_CACHE,
492+
VIVS_TS_FLUSH_CACHE_FLUSH);
493+
}
452494
}
453495
CMD_SEM(buffer, SYNC_RECIPIENT_FE, SYNC_RECIPIENT_PE);
454496
CMD_STALL(buffer, SYNC_RECIPIENT_FE, SYNC_RECIPIENT_PE);
497+
498+
if (has_blt) {
499+
CMD_LOAD_STATE(buffer, VIVS_BLT_ENABLE, 0x1);
500+
CMD_SEM(buffer, SYNC_RECIPIENT_FE, SYNC_RECIPIENT_BLT);
501+
CMD_STALL(buffer, SYNC_RECIPIENT_FE, SYNC_RECIPIENT_BLT);
502+
CMD_LOAD_STATE(buffer, VIVS_BLT_ENABLE, 0x0);
503+
}
504+
455505
CMD_LOAD_STATE(buffer, VIVS_GL_EVENT, VIVS_GL_EVENT_EVENT_ID(event) |
456506
VIVS_GL_EVENT_FROM_PE);
457507
CMD_WAIT(buffer);

drivers/gpu/drm/etnaviv/etnaviv_drv.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -551,6 +551,7 @@ static int etnaviv_bind(struct device *dev)
551551
mutex_init(&priv->gem_lock);
552552
INIT_LIST_HEAD(&priv->gem_list);
553553
priv->num_gpus = 0;
554+
priv->shm_gfp_mask = GFP_HIGHUSER | __GFP_RETRY_MAYFAIL | __GFP_NOWARN;
554555

555556
priv->cmdbuf_suballoc = etnaviv_cmdbuf_suballoc_new(drm->dev);
556557
if (IS_ERR(priv->cmdbuf_suballoc)) {

drivers/gpu/drm/etnaviv/etnaviv_drv.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ struct etnaviv_drm_private {
3535
int num_gpus;
3636
struct device_dma_parameters dma_parms;
3737
struct etnaviv_gpu *gpu[ETNA_MAX_PIPES];
38+
gfp_t shm_gfp_mask;
3839

3940
struct etnaviv_cmdbuf_suballoc *cmdbuf_suballoc;
4041
struct etnaviv_iommu_global *mmu_global;

drivers/gpu/drm/etnaviv/etnaviv_gem.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -602,6 +602,7 @@ static int etnaviv_gem_new_impl(struct drm_device *dev, u32 size, u32 flags,
602602
int etnaviv_gem_new_handle(struct drm_device *dev, struct drm_file *file,
603603
u32 size, u32 flags, u32 *handle)
604604
{
605+
struct etnaviv_drm_private *priv = dev->dev_private;
605606
struct drm_gem_object *obj = NULL;
606607
int ret;
607608

@@ -624,8 +625,7 @@ int etnaviv_gem_new_handle(struct drm_device *dev, struct drm_file *file,
624625
* above new_inode() why this is required _and_ expected if you're
625626
* going to pin these pages.
626627
*/
627-
mapping_set_gfp_mask(obj->filp->f_mapping, GFP_HIGHUSER |
628-
__GFP_RETRY_MAYFAIL | __GFP_NOWARN);
628+
mapping_set_gfp_mask(obj->filp->f_mapping, priv->shm_gfp_mask);
629629

630630
etnaviv_gem_obj_add(dev, obj);
631631

drivers/gpu/drm/etnaviv/etnaviv_gem.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ struct etnaviv_gem_submit {
105105
unsigned int nr_pmrs;
106106
struct etnaviv_perfmon_request *pmrs;
107107
unsigned int nr_bos;
108-
struct etnaviv_gem_submit_bo bos[0];
108+
struct etnaviv_gem_submit_bo bos[];
109109
/* No new members here, the previous one is variable-length! */
110110
};
111111

drivers/gpu/drm/etnaviv/etnaviv_gpu.c

Lines changed: 47 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -333,9 +333,13 @@ static void etnaviv_hw_identify(struct etnaviv_gpu *gpu)
333333
gpu->identity.revision = etnaviv_field(chipIdentity,
334334
VIVS_HI_CHIP_IDENTITY_REVISION);
335335
} else {
336+
u32 chipDate = gpu_read(gpu, VIVS_HI_CHIP_DATE);
336337

337338
gpu->identity.model = gpu_read(gpu, VIVS_HI_CHIP_MODEL);
338339
gpu->identity.revision = gpu_read(gpu, VIVS_HI_CHIP_REV);
340+
gpu->identity.product_id = gpu_read(gpu, VIVS_HI_CHIP_PRODUCT_ID);
341+
gpu->identity.customer_id = gpu_read(gpu, VIVS_HI_CHIP_CUSTOMER_ID);
342+
gpu->identity.eco_id = gpu_read(gpu, VIVS_HI_CHIP_ECO_ID);
339343

340344
/*
341345
* !!!! HACK ALERT !!!!
@@ -350,7 +354,6 @@ static void etnaviv_hw_identify(struct etnaviv_gpu *gpu)
350354

351355
/* Another special case */
352356
if (etnaviv_is_model_rev(gpu, GC300, 0x2201)) {
353-
u32 chipDate = gpu_read(gpu, VIVS_HI_CHIP_DATE);
354357
u32 chipTime = gpu_read(gpu, VIVS_HI_CHIP_TIME);
355358

356359
if (chipDate == 0x20080814 && chipTime == 0x12051100) {
@@ -373,6 +376,12 @@ static void etnaviv_hw_identify(struct etnaviv_gpu *gpu)
373376
gpu->identity.model = chipModel_GC3000;
374377
gpu->identity.revision &= 0xffff;
375378
}
379+
380+
if (etnaviv_is_model_rev(gpu, GC1000, 0x5037) && (chipDate == 0x20120617))
381+
gpu->identity.eco_id = 1;
382+
383+
if (etnaviv_is_model_rev(gpu, GC320, 0x5303) && (chipDate == 0x20140511))
384+
gpu->identity.eco_id = 1;
376385
}
377386

378387
dev_info(gpu->dev, "model: GC%x, revision: %x\n",
@@ -506,7 +515,7 @@ static int etnaviv_hw_reset(struct etnaviv_gpu *gpu)
506515
/* read idle register. */
507516
idle = gpu_read(gpu, VIVS_HI_IDLE_STATE);
508517

509-
/* try reseting again if FE it not idle */
518+
/* try resetting again if FE is not idle */
510519
if ((idle & VIVS_HI_IDLE_STATE_FE) == 0) {
511520
dev_dbg(gpu->dev, "FE is not idle\n");
512521
continue;
@@ -772,6 +781,14 @@ int etnaviv_gpu_init(struct etnaviv_gpu *gpu)
772781
gpu->identity.features &= ~chipFeatures_FAST_CLEAR;
773782
}
774783

784+
/*
785+
* If the GPU is part of a system with DMA addressing limitations,
786+
* request pages for our SHM backend buffers from the DMA32 zone to
787+
* hopefully avoid performance killing SWIOTLB bounce buffering.
788+
*/
789+
if (dma_addressing_limited(gpu->dev))
790+
priv->shm_gfp_mask |= GFP_DMA32;
791+
775792
/* Create buffer: */
776793
ret = etnaviv_cmdbuf_init(priv->cmdbuf_suballoc, &gpu->buffer,
777794
PAGE_SIZE);
@@ -851,6 +868,13 @@ int etnaviv_gpu_debugfs(struct etnaviv_gpu *gpu, struct seq_file *m)
851868

852869
verify_dma(gpu, &debug);
853870

871+
seq_puts(m, "\tidentity\n");
872+
seq_printf(m, "\t model: 0x%x\n", gpu->identity.model);
873+
seq_printf(m, "\t revision: 0x%x\n", gpu->identity.revision);
874+
seq_printf(m, "\t product_id: 0x%x\n", gpu->identity.product_id);
875+
seq_printf(m, "\t customer_id: 0x%x\n", gpu->identity.customer_id);
876+
seq_printf(m, "\t eco_id: 0x%x\n", gpu->identity.eco_id);
877+
854878
seq_puts(m, "\tfeatures\n");
855879
seq_printf(m, "\t major_features: 0x%08x\n",
856880
gpu->identity.features);
@@ -930,6 +954,20 @@ int etnaviv_gpu_debugfs(struct etnaviv_gpu *gpu, struct seq_file *m)
930954
seq_puts(m, "\t FP is not idle\n");
931955
if ((idle & VIVS_HI_IDLE_STATE_TS) == 0)
932956
seq_puts(m, "\t TS is not idle\n");
957+
if ((idle & VIVS_HI_IDLE_STATE_BL) == 0)
958+
seq_puts(m, "\t BL is not idle\n");
959+
if ((idle & VIVS_HI_IDLE_STATE_ASYNCFE) == 0)
960+
seq_puts(m, "\t ASYNCFE is not idle\n");
961+
if ((idle & VIVS_HI_IDLE_STATE_MC) == 0)
962+
seq_puts(m, "\t MC is not idle\n");
963+
if ((idle & VIVS_HI_IDLE_STATE_PPA) == 0)
964+
seq_puts(m, "\t PPA is not idle\n");
965+
if ((idle & VIVS_HI_IDLE_STATE_WD) == 0)
966+
seq_puts(m, "\t WD is not idle\n");
967+
if ((idle & VIVS_HI_IDLE_STATE_NN) == 0)
968+
seq_puts(m, "\t NN is not idle\n");
969+
if ((idle & VIVS_HI_IDLE_STATE_TP) == 0)
970+
seq_puts(m, "\t TP is not idle\n");
933971
if (idle & VIVS_HI_IDLE_STATE_AXI_LP)
934972
seq_puts(m, "\t AXI low power mode\n");
935973

@@ -1805,11 +1843,15 @@ static int etnaviv_gpu_rpm_suspend(struct device *dev)
18051843
if (atomic_read(&gpu->sched.hw_rq_count))
18061844
return -EBUSY;
18071845

1808-
/* Check whether the hardware (except FE) is idle */
1809-
mask = gpu->idle_mask & ~VIVS_HI_IDLE_STATE_FE;
1846+
/* Check whether the hardware (except FE and MC) is idle */
1847+
mask = gpu->idle_mask & ~(VIVS_HI_IDLE_STATE_FE |
1848+
VIVS_HI_IDLE_STATE_MC);
18101849
idle = gpu_read(gpu, VIVS_HI_IDLE_STATE) & mask;
1811-
if (idle != mask)
1850+
if (idle != mask) {
1851+
dev_warn_ratelimited(dev, "GPU not yet idle, mask: 0x%08x\n",
1852+
idle);
18121853
return -EBUSY;
1854+
}
18131855

18141856
return etnaviv_gpu_hw_suspend(gpu);
18151857
}

drivers/gpu/drm/etnaviv/etnaviv_gpu.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,11 @@ struct etnaviv_gem_submit;
1515
struct etnaviv_vram_mapping;
1616

1717
struct etnaviv_chip_identity {
18-
/* Chip model. */
1918
u32 model;
20-
21-
/* Revision value.*/
2219
u32 revision;
20+
u32 product_id;
21+
u32 customer_id;
22+
u32 eco_id;
2323

2424
/* Supported feature fields. */
2525
u32 features;

drivers/gpu/drm/etnaviv/etnaviv_hwdb.c

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,43 @@
66
#include "etnaviv_gpu.h"
77

88
static const struct etnaviv_chip_identity etnaviv_chip_identities[] = {
9+
{
10+
.model = 0x400,
11+
.revision = 0x4652,
12+
.product_id = 0x70001,
13+
.customer_id = 0x100,
14+
.eco_id = 0,
15+
.stream_count = 4,
16+
.register_max = 64,
17+
.thread_count = 128,
18+
.shader_core_count = 1,
19+
.vertex_cache_size = 8,
20+
.vertex_output_buffer_size = 1024,
21+
.pixel_pipes = 1,
22+
.instruction_count = 256,
23+
.num_constants = 320,
24+
.buffer_size = 0,
25+
.varyings_count = 8,
26+
.features = 0xa0e9e004,
27+
.minor_features0 = 0xe1299fff,
28+
.minor_features1 = 0xbe13b219,
29+
.minor_features2 = 0xce110010,
30+
.minor_features3 = 0x8000001,
31+
.minor_features4 = 0x20102,
32+
.minor_features5 = 0x120000,
33+
.minor_features6 = 0x0,
34+
.minor_features7 = 0x0,
35+
.minor_features8 = 0x0,
36+
.minor_features9 = 0x0,
37+
.minor_features10 = 0x0,
38+
.minor_features11 = 0x0,
39+
},
940
{
1041
.model = 0x7000,
1142
.revision = 0x6214,
43+
.product_id = ~0U,
44+
.customer_id = ~0U,
45+
.eco_id = ~0U,
1246
.stream_count = 16,
1347
.register_max = 64,
1448
.thread_count = 1024,
@@ -43,7 +77,13 @@ bool etnaviv_fill_identity_from_hwdb(struct etnaviv_gpu *gpu)
4377

4478
for (i = 0; i < ARRAY_SIZE(etnaviv_chip_identities); i++) {
4579
if (etnaviv_chip_identities[i].model == ident->model &&
46-
etnaviv_chip_identities[i].revision == ident->revision) {
80+
etnaviv_chip_identities[i].revision == ident->revision &&
81+
(etnaviv_chip_identities[i].product_id == ident->product_id ||
82+
etnaviv_chip_identities[i].product_id == ~0U) &&
83+
(etnaviv_chip_identities[i].customer_id == ident->customer_id ||
84+
etnaviv_chip_identities[i].customer_id == ~0U) &&
85+
(etnaviv_chip_identities[i].eco_id == ident->eco_id ||
86+
etnaviv_chip_identities[i].eco_id == ~0U)) {
4787
memcpy(ident, &etnaviv_chip_identities[i],
4888
sizeof(*ident));
4989
return true;

0 commit comments

Comments
 (0)