Skip to content

Commit 819683a

Browse files
committed
Merge branch 'etnaviv/next' of https://git.pengutronix.de/git/lst/linux into drm-next
please pull the following etnaviv changes for the next merge window. Mostly some small workarounds to get new hardware support going. But also more fixes to the softpin MMU handling and a nice addition from Christian to make the kernel logs on hang detection more useful. Signed-off-by: Dave Airlie <[email protected]> From: Lucas Stach <[email protected]> Link: https://patchwork.freedesktop.org/patch/msgid/[email protected]
2 parents 4302423 + a3b4c2f commit 819683a

File tree

10 files changed

+138
-37
lines changed

10 files changed

+138
-37
lines changed

drivers/gpu/drm/etnaviv/etnaviv_dump.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,10 +83,15 @@ static void etnaviv_core_dump_registers(struct core_dump_iterator *iter,
8383
{
8484
struct etnaviv_dump_registers *reg = iter->data;
8585
unsigned int i;
86+
u32 read_addr;
8687

8788
for (i = 0; i < ARRAY_SIZE(etnaviv_dump_registers); i++, reg++) {
89+
read_addr = etnaviv_dump_registers[i];
90+
if (read_addr >= VIVS_PM_POWER_CONTROLS &&
91+
read_addr <= VIVS_PM_PULSE_EATER)
92+
read_addr = gpu_fix_power_address(gpu, read_addr);
8893
reg->reg = cpu_to_le32(etnaviv_dump_registers[i]);
89-
reg->value = cpu_to_le32(gpu_read(gpu, etnaviv_dump_registers[i]));
94+
reg->value = cpu_to_le32(gpu_read(gpu, read_addr));
9095
}
9196

9297
etnaviv_core_dump_header(iter, ETDUMP_BUF_REG, reg);

drivers/gpu/drm/etnaviv/etnaviv_gem.c

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,7 @@ static int etnaviv_gem_mmap_obj(struct etnaviv_gem_object *etnaviv_obj,
130130
{
131131
pgprot_t vm_page_prot;
132132

133-
vma->vm_flags |= VM_IO | VM_MIXEDMAP | VM_DONTEXPAND | VM_DONTDUMP;
133+
vma->vm_flags |= VM_PFNMAP | VM_DONTEXPAND | VM_DONTDUMP;
134134

135135
vm_page_prot = vm_get_page_prot(vma->vm_flags);
136136

@@ -165,7 +165,8 @@ static vm_fault_t etnaviv_gem_fault(struct vm_fault *vmf)
165165
struct vm_area_struct *vma = vmf->vma;
166166
struct drm_gem_object *obj = vma->vm_private_data;
167167
struct etnaviv_gem_object *etnaviv_obj = to_etnaviv_bo(obj);
168-
struct page **pages, *page;
168+
struct page **pages;
169+
unsigned long pfn;
169170
pgoff_t pgoff;
170171
int err;
171172

@@ -189,12 +190,12 @@ static vm_fault_t etnaviv_gem_fault(struct vm_fault *vmf)
189190
/* We don't use vmf->pgoff since that has the fake offset: */
190191
pgoff = (vmf->address - vma->vm_start) >> PAGE_SHIFT;
191192

192-
page = pages[pgoff];
193+
pfn = page_to_pfn(pages[pgoff]);
193194

194195
VERB("Inserting %p pfn %lx, pa %lx", (void *)vmf->address,
195-
page_to_pfn(page), page_to_pfn(page) << PAGE_SHIFT);
196+
pfn, pfn << PAGE_SHIFT);
196197

197-
return vmf_insert_page(vma, vmf->address, page);
198+
return vmf_insert_pfn(vma, vmf->address, pfn);
198199
}
199200

200201
int etnaviv_gem_mmap_offset(struct drm_gem_object *obj, u64 *offset)
@@ -258,7 +259,12 @@ struct etnaviv_vram_mapping *etnaviv_gem_mapping_get(
258259
if (mapping->use == 0) {
259260
mutex_lock(&mmu_context->lock);
260261
if (mapping->context == mmu_context)
261-
mapping->use += 1;
262+
if (va && mapping->iova != va) {
263+
etnaviv_iommu_reap_mapping(mapping);
264+
mapping = NULL;
265+
} else {
266+
mapping->use += 1;
267+
}
262268
else
263269
mapping = NULL;
264270
mutex_unlock(&mmu_context->lock);
@@ -504,7 +510,6 @@ void etnaviv_gem_free_object(struct drm_gem_object *obj)
504510
kfree(mapping);
505511
}
506512

507-
drm_gem_free_mmap_offset(obj);
508513
etnaviv_obj->ops->release(etnaviv_obj);
509514
drm_gem_object_release(obj);
510515

drivers/gpu/drm/etnaviv/etnaviv_gem.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@ struct etnaviv_gem_submit {
9696
int out_fence_id;
9797
struct list_head node; /* GPU active submit list */
9898
struct etnaviv_cmdbuf cmdbuf;
99+
struct pid *pid; /* submitting process */
99100
bool runtime_resumed;
100101
u32 exec_state;
101102
u32 flags;

drivers/gpu/drm/etnaviv/etnaviv_gem_submit.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -399,6 +399,9 @@ static void submit_cleanup(struct kref *kref)
399399
mutex_unlock(&submit->gpu->fence_lock);
400400
dma_fence_put(submit->out_fence);
401401
}
402+
403+
put_pid(submit->pid);
404+
402405
kfree(submit->pmrs);
403406
kfree(submit);
404407
}
@@ -422,6 +425,7 @@ int etnaviv_ioctl_gem_submit(struct drm_device *dev, void *data,
422425
struct sync_file *sync_file = NULL;
423426
struct ww_acquire_ctx ticket;
424427
int out_fence_fd = -1;
428+
struct pid *pid = get_pid(task_pid(current));
425429
void *stream;
426430
int ret;
427431

@@ -519,6 +523,8 @@ int etnaviv_ioctl_gem_submit(struct drm_device *dev, void *data,
519523
goto err_submit_ww_acquire;
520524
}
521525

526+
submit->pid = pid;
527+
522528
ret = etnaviv_cmdbuf_init(priv->cmdbuf_suballoc, &submit->cmdbuf,
523529
ALIGN(args->stream_size, 8) + 8);
524530
if (ret)

drivers/gpu/drm/etnaviv/etnaviv_gpu.c

Lines changed: 41 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -416,6 +416,12 @@ static void etnaviv_hw_identify(struct etnaviv_gpu *gpu)
416416
if (gpu->identity.model == chipModel_GC700)
417417
gpu->identity.features &= ~chipFeatures_FAST_CLEAR;
418418

419+
/* These models/revisions don't have the 2D pipe bit */
420+
if ((gpu->identity.model == chipModel_GC500 &&
421+
gpu->identity.revision <= 2) ||
422+
gpu->identity.model == chipModel_GC300)
423+
gpu->identity.features |= chipFeatures_PIPE_2D;
424+
419425
if ((gpu->identity.model == chipModel_GC500 &&
420426
gpu->identity.revision < 2) ||
421427
(gpu->identity.model == chipModel_GC300 &&
@@ -449,8 +455,9 @@ static void etnaviv_hw_identify(struct etnaviv_gpu *gpu)
449455
gpu_read(gpu, VIVS_HI_CHIP_MINOR_FEATURE_5);
450456
}
451457

452-
/* GC600 idle register reports zero bits where modules aren't present */
453-
if (gpu->identity.model == chipModel_GC600)
458+
/* GC600/300 idle register reports zero bits where modules aren't present */
459+
if (gpu->identity.model == chipModel_GC600 ||
460+
gpu->identity.model == chipModel_GC300)
454461
gpu->idle_mask = VIVS_HI_IDLE_STATE_TX |
455462
VIVS_HI_IDLE_STATE_RA |
456463
VIVS_HI_IDLE_STATE_SE |
@@ -583,17 +590,17 @@ static void etnaviv_gpu_enable_mlcg(struct etnaviv_gpu *gpu)
583590
u32 pmc, ppc;
584591

585592
/* enable clock gating */
586-
ppc = gpu_read(gpu, VIVS_PM_POWER_CONTROLS);
593+
ppc = gpu_read_power(gpu, VIVS_PM_POWER_CONTROLS);
587594
ppc |= VIVS_PM_POWER_CONTROLS_ENABLE_MODULE_CLOCK_GATING;
588595

589596
/* Disable stall module clock gating for 4.3.0.1 and 4.3.0.2 revs */
590597
if (gpu->identity.revision == 0x4301 ||
591598
gpu->identity.revision == 0x4302)
592599
ppc |= VIVS_PM_POWER_CONTROLS_DISABLE_STALL_MODULE_CLOCK_GATING;
593600

594-
gpu_write(gpu, VIVS_PM_POWER_CONTROLS, ppc);
601+
gpu_write_power(gpu, VIVS_PM_POWER_CONTROLS, ppc);
595602

596-
pmc = gpu_read(gpu, VIVS_PM_MODULE_CONTROLS);
603+
pmc = gpu_read_power(gpu, VIVS_PM_MODULE_CONTROLS);
597604

598605
/* Disable PA clock gating for GC400+ without bugfix except for GC420 */
599606
if (gpu->identity.model >= chipModel_GC400 &&
@@ -616,19 +623,20 @@ static void etnaviv_gpu_enable_mlcg(struct etnaviv_gpu *gpu)
616623

617624
/* Disable TX clock gating on affected core revisions. */
618625
if (etnaviv_is_model_rev(gpu, GC4000, 0x5222) ||
619-
etnaviv_is_model_rev(gpu, GC2000, 0x5108))
626+
etnaviv_is_model_rev(gpu, GC2000, 0x5108) ||
627+
etnaviv_is_model_rev(gpu, GC2000, 0x6202) ||
628+
etnaviv_is_model_rev(gpu, GC2000, 0x6203))
620629
pmc |= VIVS_PM_MODULE_CONTROLS_DISABLE_MODULE_CLOCK_GATING_TX;
621630

622-
/* Disable SE, RA and TX clock gating on affected core revisions. */
631+
/* Disable SE and RA clock gating on affected core revisions. */
623632
if (etnaviv_is_model_rev(gpu, GC7000, 0x6202))
624633
pmc |= VIVS_PM_MODULE_CONTROLS_DISABLE_MODULE_CLOCK_GATING_SE |
625-
VIVS_PM_MODULE_CONTROLS_DISABLE_MODULE_CLOCK_GATING_RA |
626-
VIVS_PM_MODULE_CONTROLS_DISABLE_MODULE_CLOCK_GATING_TX;
634+
VIVS_PM_MODULE_CONTROLS_DISABLE_MODULE_CLOCK_GATING_RA;
627635

628636
pmc |= VIVS_PM_MODULE_CONTROLS_DISABLE_MODULE_CLOCK_GATING_RA_HZ;
629637
pmc |= VIVS_PM_MODULE_CONTROLS_DISABLE_MODULE_CLOCK_GATING_RA_EZ;
630638

631-
gpu_write(gpu, VIVS_PM_MODULE_CONTROLS, pmc);
639+
gpu_write_power(gpu, VIVS_PM_MODULE_CONTROLS, pmc);
632640
}
633641

634642
void etnaviv_gpu_start_fe(struct etnaviv_gpu *gpu, u32 address, u16 prefetch)
@@ -688,11 +696,11 @@ static void etnaviv_gpu_setup_pulse_eater(struct etnaviv_gpu *gpu)
688696
(gpu->identity.features & chipFeatures_PIPE_3D))
689697
{
690698
/* Performance fix: disable internal DFS */
691-
pulse_eater = gpu_read(gpu, VIVS_PM_PULSE_EATER);
699+
pulse_eater = gpu_read_power(gpu, VIVS_PM_PULSE_EATER);
692700
pulse_eater |= BIT(18);
693701
}
694702

695-
gpu_write(gpu, VIVS_PM_PULSE_EATER, pulse_eater);
703+
gpu_write_power(gpu, VIVS_PM_PULSE_EATER, pulse_eater);
696704
}
697705

698706
static void etnaviv_gpu_hw_init(struct etnaviv_gpu *gpu)
@@ -1045,12 +1053,28 @@ int etnaviv_gpu_debugfs(struct etnaviv_gpu *gpu, struct seq_file *m)
10451053
}
10461054
#endif
10471055

1048-
void etnaviv_gpu_recover_hang(struct etnaviv_gpu *gpu)
1056+
void etnaviv_gpu_recover_hang(struct etnaviv_gem_submit *submit)
10491057
{
1058+
struct etnaviv_gpu *gpu = submit->gpu;
1059+
char *comm = NULL, *cmd = NULL;
1060+
struct task_struct *task;
10501061
unsigned int i;
10511062

10521063
dev_err(gpu->dev, "recover hung GPU!\n");
10531064

1065+
task = get_pid_task(submit->pid, PIDTYPE_PID);
1066+
if (task) {
1067+
comm = kstrdup(task->comm, GFP_KERNEL);
1068+
cmd = kstrdup_quotable_cmdline(task, GFP_KERNEL);
1069+
put_task_struct(task);
1070+
}
1071+
1072+
if (comm && cmd)
1073+
dev_err(gpu->dev, "offending task: %s (%s)\n", comm, cmd);
1074+
1075+
kfree(cmd);
1076+
kfree(comm);
1077+
10541078
if (pm_runtime_get_sync(gpu->dev) < 0)
10551079
goto pm_put;
10561080

@@ -1294,9 +1318,9 @@ static void sync_point_perfmon_sample_pre(struct etnaviv_gpu *gpu,
12941318
u32 val;
12951319

12961320
/* disable clock gating */
1297-
val = gpu_read(gpu, VIVS_PM_POWER_CONTROLS);
1321+
val = gpu_read_power(gpu, VIVS_PM_POWER_CONTROLS);
12981322
val &= ~VIVS_PM_POWER_CONTROLS_ENABLE_MODULE_CLOCK_GATING;
1299-
gpu_write(gpu, VIVS_PM_POWER_CONTROLS, val);
1323+
gpu_write_power(gpu, VIVS_PM_POWER_CONTROLS, val);
13001324

13011325
/* enable debug register */
13021326
val = gpu_read(gpu, VIVS_HI_CLOCK_CONTROL);
@@ -1327,9 +1351,9 @@ static void sync_point_perfmon_sample_post(struct etnaviv_gpu *gpu,
13271351
gpu_write(gpu, VIVS_HI_CLOCK_CONTROL, val);
13281352

13291353
/* enable clock gating */
1330-
val = gpu_read(gpu, VIVS_PM_POWER_CONTROLS);
1354+
val = gpu_read_power(gpu, VIVS_PM_POWER_CONTROLS);
13311355
val |= VIVS_PM_POWER_CONTROLS_ENABLE_MODULE_CLOCK_GATING;
1332-
gpu_write(gpu, VIVS_PM_POWER_CONTROLS, val);
1356+
gpu_write_power(gpu, VIVS_PM_POWER_CONTROLS, val);
13331357
}
13341358

13351359

drivers/gpu/drm/etnaviv/etnaviv_gpu.h

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include "etnaviv_gem.h"
1111
#include "etnaviv_mmu.h"
1212
#include "etnaviv_drv.h"
13+
#include "common.xml.h"
1314

1415
struct etnaviv_gem_submit;
1516
struct etnaviv_vram_mapping;
@@ -159,6 +160,26 @@ static inline u32 gpu_read(struct etnaviv_gpu *gpu, u32 reg)
159160
return readl(gpu->mmio + reg);
160161
}
161162

163+
static inline u32 gpu_fix_power_address(struct etnaviv_gpu *gpu, u32 reg)
164+
{
165+
/* Power registers in GC300 < 2.0 are offset by 0x100 */
166+
if (gpu->identity.model == chipModel_GC300 &&
167+
gpu->identity.revision < 0x2000)
168+
reg += 0x100;
169+
170+
return reg;
171+
}
172+
173+
static inline void gpu_write_power(struct etnaviv_gpu *gpu, u32 reg, u32 data)
174+
{
175+
writel(data, gpu->mmio + gpu_fix_power_address(gpu, reg));
176+
}
177+
178+
static inline u32 gpu_read_power(struct etnaviv_gpu *gpu, u32 reg)
179+
{
180+
return readl(gpu->mmio + gpu_fix_power_address(gpu, reg));
181+
}
182+
162183
int etnaviv_gpu_get_param(struct etnaviv_gpu *gpu, u32 param, u64 *value);
163184

164185
int etnaviv_gpu_init(struct etnaviv_gpu *gpu);
@@ -168,7 +189,7 @@ bool etnaviv_fill_identity_from_hwdb(struct etnaviv_gpu *gpu);
168189
int etnaviv_gpu_debugfs(struct etnaviv_gpu *gpu, struct seq_file *m);
169190
#endif
170191

171-
void etnaviv_gpu_recover_hang(struct etnaviv_gpu *gpu);
192+
void etnaviv_gpu_recover_hang(struct etnaviv_gem_submit *submit);
172193
void etnaviv_gpu_retire(struct etnaviv_gpu *gpu);
173194
int etnaviv_gpu_wait_fence_interruptible(struct etnaviv_gpu *gpu,
174195
u32 fence, struct drm_etnaviv_timespec *timeout);

drivers/gpu/drm/etnaviv/etnaviv_hwdb.c

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,37 @@ static const struct etnaviv_chip_identity etnaviv_chip_identities[] = {
6868
.minor_features10 = 0x00004040,
6969
.minor_features11 = 0x00000024,
7070
},
71+
{
72+
.model = 0x7000,
73+
.revision = 0x6203,
74+
.product_id = 0x70003,
75+
.customer_id = 0x4,
76+
.eco_id = 0,
77+
.stream_count = 16,
78+
.register_max = 64,
79+
.thread_count = 512,
80+
.shader_core_count = 2,
81+
.vertex_cache_size = 16,
82+
.vertex_output_buffer_size = 1024,
83+
.pixel_pipes = 1,
84+
.instruction_count = 512,
85+
.num_constants = 320,
86+
.buffer_size = 0,
87+
.varyings_count = 16,
88+
.features = 0xe0287c8d,
89+
.minor_features0 = 0xc1589eff,
90+
.minor_features1 = 0xfefbfad9,
91+
.minor_features2 = 0xeb9d4fbf,
92+
.minor_features3 = 0xedfffced,
93+
.minor_features4 = 0xdb0dafc7,
94+
.minor_features5 = 0x3b5ac333,
95+
.minor_features6 = 0xfcce6000,
96+
.minor_features7 = 0xfffbfa6f,
97+
.minor_features8 = 0x00e10ef3,
98+
.minor_features9 = 0x00c8003c,
99+
.minor_features10 = 0x00004040,
100+
.minor_features11 = 0x00000024,
101+
},
71102
{
72103
.model = 0x7000,
73104
.revision = 0x6204,

drivers/gpu/drm/etnaviv/etnaviv_mmu.c

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -80,10 +80,10 @@ static int etnaviv_iommu_map(struct etnaviv_iommu_context *context, u32 iova,
8080
return -EINVAL;
8181

8282
for_each_sgtable_dma_sg(sgt, sg, i) {
83-
u32 pa = sg_dma_address(sg) - sg->offset;
83+
phys_addr_t pa = sg_dma_address(sg) - sg->offset;
8484
size_t bytes = sg_dma_len(sg) + sg->offset;
8585

86-
VERB("map[%d]: %08x %08x(%zx)", i, iova, pa, bytes);
86+
VERB("map[%d]: %08x %pap(%zx)", i, iova, &pa, bytes);
8787

8888
ret = etnaviv_context_map(context, da, pa, bytes, prot);
8989
if (ret)
@@ -135,6 +135,19 @@ static void etnaviv_iommu_remove_mapping(struct etnaviv_iommu_context *context,
135135
drm_mm_remove_node(&mapping->vram_node);
136136
}
137137

138+
void etnaviv_iommu_reap_mapping(struct etnaviv_vram_mapping *mapping)
139+
{
140+
struct etnaviv_iommu_context *context = mapping->context;
141+
142+
lockdep_assert_held(&context->lock);
143+
WARN_ON(mapping->use);
144+
145+
etnaviv_iommu_remove_mapping(context, mapping);
146+
etnaviv_iommu_context_put(mapping->context);
147+
mapping->context = NULL;
148+
list_del_init(&mapping->mmu_node);
149+
}
150+
138151
static int etnaviv_iommu_find_iova(struct etnaviv_iommu_context *context,
139152
struct drm_mm_node *node, size_t size)
140153
{
@@ -202,10 +215,7 @@ static int etnaviv_iommu_find_iova(struct etnaviv_iommu_context *context,
202215
* this mapping.
203216
*/
204217
list_for_each_entry_safe(m, n, &list, scan_node) {
205-
etnaviv_iommu_remove_mapping(context, m);
206-
etnaviv_iommu_context_put(m->context);
207-
m->context = NULL;
208-
list_del_init(&m->mmu_node);
218+
etnaviv_iommu_reap_mapping(m);
209219
list_del_init(&m->scan_node);
210220
}
211221

@@ -257,10 +267,7 @@ static int etnaviv_iommu_insert_exact(struct etnaviv_iommu_context *context,
257267
}
258268

259269
list_for_each_entry_safe(m, n, &scan_list, scan_node) {
260-
etnaviv_iommu_remove_mapping(context, m);
261-
etnaviv_iommu_context_put(m->context);
262-
m->context = NULL;
263-
list_del_init(&m->mmu_node);
270+
etnaviv_iommu_reap_mapping(m);
264271
list_del_init(&m->scan_node);
265272
}
266273

drivers/gpu/drm/etnaviv/etnaviv_mmu.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ int etnaviv_iommu_map_gem(struct etnaviv_iommu_context *context,
9191
struct etnaviv_vram_mapping *mapping, u64 va);
9292
void etnaviv_iommu_unmap_gem(struct etnaviv_iommu_context *context,
9393
struct etnaviv_vram_mapping *mapping);
94+
void etnaviv_iommu_reap_mapping(struct etnaviv_vram_mapping *mapping);
9495

9596
int etnaviv_iommu_get_suballoc_va(struct etnaviv_iommu_context *ctx,
9697
struct etnaviv_vram_mapping *mapping,

0 commit comments

Comments
 (0)