Commit 819683a1 authored by Dave Airlie's avatar Dave Airlie
Browse files

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: default avatarDave Airlie <airlied@redhat.com>
From: Lucas Stach <l.stach@pengutronix.de>
Link: https://patchwork.freedesktop.org/patch/msgid/adcb1b3dec89a18d6c3c4ee6e179b9b2c9f25046.camel@pengutronix.de
parents 4302423c a3b4c2f9
Loading
Loading
Loading
Loading
+6 −1
Original line number Diff line number Diff line
@@ -83,10 +83,15 @@ static void etnaviv_core_dump_registers(struct core_dump_iterator *iter,
{
	struct etnaviv_dump_registers *reg = iter->data;
	unsigned int i;
	u32 read_addr;

	for (i = 0; i < ARRAY_SIZE(etnaviv_dump_registers); i++, reg++) {
		read_addr = etnaviv_dump_registers[i];
		if (read_addr >= VIVS_PM_POWER_CONTROLS &&
		    read_addr <= VIVS_PM_PULSE_EATER)
			read_addr = gpu_fix_power_address(gpu, read_addr);
		reg->reg = cpu_to_le32(etnaviv_dump_registers[i]);
		reg->value = cpu_to_le32(gpu_read(gpu, etnaviv_dump_registers[i]));
		reg->value = cpu_to_le32(gpu_read(gpu, read_addr));
	}

	etnaviv_core_dump_header(iter, ETDUMP_BUF_REG, reg);
+12 −7
Original line number Diff line number Diff line
@@ -130,7 +130,7 @@ static int etnaviv_gem_mmap_obj(struct etnaviv_gem_object *etnaviv_obj,
{
	pgprot_t vm_page_prot;

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

	vm_page_prot = vm_get_page_prot(vma->vm_flags);

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

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

	page = pages[pgoff];
	pfn = page_to_pfn(pages[pgoff]);

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

	return vmf_insert_page(vma, vmf->address, page);
	return vmf_insert_pfn(vma, vmf->address, pfn);
}

int etnaviv_gem_mmap_offset(struct drm_gem_object *obj, u64 *offset)
@@ -258,7 +259,12 @@ struct etnaviv_vram_mapping *etnaviv_gem_mapping_get(
		if (mapping->use == 0) {
			mutex_lock(&mmu_context->lock);
			if (mapping->context == mmu_context)
				if (va && mapping->iova != va) {
					etnaviv_iommu_reap_mapping(mapping);
					mapping = NULL;
				} else {
					mapping->use += 1;
				}
			else
				mapping = NULL;
			mutex_unlock(&mmu_context->lock);
@@ -504,7 +510,6 @@ void etnaviv_gem_free_object(struct drm_gem_object *obj)
		kfree(mapping);
	}

	drm_gem_free_mmap_offset(obj);
	etnaviv_obj->ops->release(etnaviv_obj);
	drm_gem_object_release(obj);

+1 −0
Original line number Diff line number Diff line
@@ -96,6 +96,7 @@ struct etnaviv_gem_submit {
	int out_fence_id;
	struct list_head node; /* GPU active submit list */
	struct etnaviv_cmdbuf cmdbuf;
	struct pid *pid;       /* submitting process */
	bool runtime_resumed;
	u32 exec_state;
	u32 flags;
+6 −0
Original line number Diff line number Diff line
@@ -399,6 +399,9 @@ static void submit_cleanup(struct kref *kref)
		mutex_unlock(&submit->gpu->fence_lock);
		dma_fence_put(submit->out_fence);
	}

	put_pid(submit->pid);

	kfree(submit->pmrs);
	kfree(submit);
}
@@ -422,6 +425,7 @@ int etnaviv_ioctl_gem_submit(struct drm_device *dev, void *data,
	struct sync_file *sync_file = NULL;
	struct ww_acquire_ctx ticket;
	int out_fence_fd = -1;
	struct pid *pid = get_pid(task_pid(current));
	void *stream;
	int ret;

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

	submit->pid = pid;

	ret = etnaviv_cmdbuf_init(priv->cmdbuf_suballoc, &submit->cmdbuf,
				  ALIGN(args->stream_size, 8) + 8);
	if (ret)
+41 −17
Original line number Diff line number Diff line
@@ -416,6 +416,12 @@ static void etnaviv_hw_identify(struct etnaviv_gpu *gpu)
	if (gpu->identity.model == chipModel_GC700)
		gpu->identity.features &= ~chipFeatures_FAST_CLEAR;

	/* These models/revisions don't have the 2D pipe bit */
	if ((gpu->identity.model == chipModel_GC500 &&
	     gpu->identity.revision <= 2) ||
	    gpu->identity.model == chipModel_GC300)
		gpu->identity.features |= chipFeatures_PIPE_2D;

	if ((gpu->identity.model == chipModel_GC500 &&
	     gpu->identity.revision < 2) ||
	    (gpu->identity.model == chipModel_GC300 &&
@@ -449,8 +455,9 @@ static void etnaviv_hw_identify(struct etnaviv_gpu *gpu)
				gpu_read(gpu, VIVS_HI_CHIP_MINOR_FEATURE_5);
	}

	/* GC600 idle register reports zero bits where modules aren't present */
	if (gpu->identity.model == chipModel_GC600)
	/* GC600/300 idle register reports zero bits where modules aren't present */
	if (gpu->identity.model == chipModel_GC600 ||
	    gpu->identity.model == chipModel_GC300)
		gpu->idle_mask = VIVS_HI_IDLE_STATE_TX |
				 VIVS_HI_IDLE_STATE_RA |
				 VIVS_HI_IDLE_STATE_SE |
@@ -583,7 +590,7 @@ static void etnaviv_gpu_enable_mlcg(struct etnaviv_gpu *gpu)
	u32 pmc, ppc;

	/* enable clock gating */
	ppc = gpu_read(gpu, VIVS_PM_POWER_CONTROLS);
	ppc = gpu_read_power(gpu, VIVS_PM_POWER_CONTROLS);
	ppc |= VIVS_PM_POWER_CONTROLS_ENABLE_MODULE_CLOCK_GATING;

	/* Disable stall module clock gating for 4.3.0.1 and 4.3.0.2 revs */
@@ -591,9 +598,9 @@ static void etnaviv_gpu_enable_mlcg(struct etnaviv_gpu *gpu)
	    gpu->identity.revision == 0x4302)
		ppc |= VIVS_PM_POWER_CONTROLS_DISABLE_STALL_MODULE_CLOCK_GATING;

	gpu_write(gpu, VIVS_PM_POWER_CONTROLS, ppc);
	gpu_write_power(gpu, VIVS_PM_POWER_CONTROLS, ppc);

	pmc = gpu_read(gpu, VIVS_PM_MODULE_CONTROLS);
	pmc = gpu_read_power(gpu, VIVS_PM_MODULE_CONTROLS);

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

	/* Disable TX clock gating on affected core revisions. */
	if (etnaviv_is_model_rev(gpu, GC4000, 0x5222) ||
	    etnaviv_is_model_rev(gpu, GC2000, 0x5108))
	    etnaviv_is_model_rev(gpu, GC2000, 0x5108) ||
	    etnaviv_is_model_rev(gpu, GC2000, 0x6202) ||
	    etnaviv_is_model_rev(gpu, GC2000, 0x6203))
		pmc |= VIVS_PM_MODULE_CONTROLS_DISABLE_MODULE_CLOCK_GATING_TX;

	/* Disable SE, RA and TX clock gating on affected core revisions. */
	/* Disable SE and RA clock gating on affected core revisions. */
	if (etnaviv_is_model_rev(gpu, GC7000, 0x6202))
		pmc |= VIVS_PM_MODULE_CONTROLS_DISABLE_MODULE_CLOCK_GATING_SE |
		       VIVS_PM_MODULE_CONTROLS_DISABLE_MODULE_CLOCK_GATING_RA |
		       VIVS_PM_MODULE_CONTROLS_DISABLE_MODULE_CLOCK_GATING_TX;
		       VIVS_PM_MODULE_CONTROLS_DISABLE_MODULE_CLOCK_GATING_RA;

	pmc |= VIVS_PM_MODULE_CONTROLS_DISABLE_MODULE_CLOCK_GATING_RA_HZ;
	pmc |= VIVS_PM_MODULE_CONTROLS_DISABLE_MODULE_CLOCK_GATING_RA_EZ;

	gpu_write(gpu, VIVS_PM_MODULE_CONTROLS, pmc);
	gpu_write_power(gpu, VIVS_PM_MODULE_CONTROLS, pmc);
}

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)
	    (gpu->identity.features & chipFeatures_PIPE_3D))
	{
		/* Performance fix: disable internal DFS */
		pulse_eater = gpu_read(gpu, VIVS_PM_PULSE_EATER);
		pulse_eater = gpu_read_power(gpu, VIVS_PM_PULSE_EATER);
		pulse_eater |= BIT(18);
	}

	gpu_write(gpu, VIVS_PM_PULSE_EATER, pulse_eater);
	gpu_write_power(gpu, VIVS_PM_PULSE_EATER, pulse_eater);
}

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)
}
#endif

void etnaviv_gpu_recover_hang(struct etnaviv_gpu *gpu)
void etnaviv_gpu_recover_hang(struct etnaviv_gem_submit *submit)
{
	struct etnaviv_gpu *gpu = submit->gpu;
	char *comm = NULL, *cmd = NULL;
	struct task_struct *task;
	unsigned int i;

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

	task = get_pid_task(submit->pid, PIDTYPE_PID);
	if (task) {
		comm = kstrdup(task->comm, GFP_KERNEL);
		cmd = kstrdup_quotable_cmdline(task, GFP_KERNEL);
		put_task_struct(task);
	}

	if (comm && cmd)
		dev_err(gpu->dev, "offending task: %s (%s)\n", comm, cmd);

	kfree(cmd);
	kfree(comm);

	if (pm_runtime_get_sync(gpu->dev) < 0)
		goto pm_put;

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

	/* disable clock gating */
	val = gpu_read(gpu, VIVS_PM_POWER_CONTROLS);
	val = gpu_read_power(gpu, VIVS_PM_POWER_CONTROLS);
	val &= ~VIVS_PM_POWER_CONTROLS_ENABLE_MODULE_CLOCK_GATING;
	gpu_write(gpu, VIVS_PM_POWER_CONTROLS, val);
	gpu_write_power(gpu, VIVS_PM_POWER_CONTROLS, val);

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

	/* enable clock gating */
	val = gpu_read(gpu, VIVS_PM_POWER_CONTROLS);
	val = gpu_read_power(gpu, VIVS_PM_POWER_CONTROLS);
	val |= VIVS_PM_POWER_CONTROLS_ENABLE_MODULE_CLOCK_GATING;
	gpu_write(gpu, VIVS_PM_POWER_CONTROLS, val);
	gpu_write_power(gpu, VIVS_PM_POWER_CONTROLS, val);
}


Loading