Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 066f9eb4 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

Highlights this time:
1. Fix for a nasty Kconfig dependency chain issue from Philipp.
2. Occlusion query buffer address added to the cmdstream validator by
Christian.
3. Fixes and cleanups to the job handling from me. This allows us to
turn on the GPU performance profiling added in the last cycle.
It is also prep work for hooking in the DRM GPU scheduler, which I hope
to land for the next cycle.

* 'etnaviv/next' of https://git.pengutronix.de/git/lst/linux: (32 commits)
  drm/etnaviv: use memset32 to init pagetable
  drm/etnaviv: move submit free out of critical section
  drm/etnaviv: re-enable perfmon support
  drm/etnaviv: couple runtime PM management to submit object lifetime
  drm/etnaviv: move GPU active handling to bo pin/unpin
  drm/etnaviv: move cmdbuf into submit object
  drm/etnaviv: use submit exec_state for perfmon sampling
  drm/etnaviv: move exec_state to submit object
  drm/etnaviv: move PMRs to submit object
  drm/etnaviv: refcount the submit object
  drm/etnaviv: move ww_acquire_ctx out of submit object
  drm/etnaviv: move object unpinning to submit cleanup
  drm/etnaviv: attach in fence to submit and move fence wait to fence_sync
  drm/etnaviv: rename submit fence to out_fence
  drm/etnaviv: move object fence attachment to gem_submit path
  drm/etnaviv: simplify submit_create
  drm/etnaviv: add lockdep annotations to buffer manipulation functions
  drm/etnaviv: hold GPU lock while inserting END command
  drm/etnaviv: move workqueue to be per GPU
  drm/etnaviv: remove switch_context member from etnaviv_gpu
  ...
parents 4ef0bef2 2f20fc4f
Loading
Loading
Loading
Loading
+9 −0
Original line number Diff line number Diff line
@@ -6,6 +6,7 @@ config DRM_ETNAVIV
	depends on MMU
	select SHMEM
	select SYNC_FILE
	select THERMAL if DRM_ETNAVIV_THERMAL
	select TMPFS
	select WANT_DEV_COREDUMP
	select CMA if HAVE_DMA_CONTIGUOUS
@@ -13,6 +14,14 @@ config DRM_ETNAVIV
	help
	  DRM driver for Vivante GPUs.

config DRM_ETNAVIV_THERMAL
	bool "enable ETNAVIV thermal throttling"
	depends on DRM_ETNAVIV
	default y
	help
	  Compile in support for thermal throttling.
	  Say Y unless you want to risk burning your SoC.

config DRM_ETNAVIV_REGISTER_LOGGING
	bool "enable ETNAVIV register logging"
	depends on DRM_ETNAVIV
+27 −13
Original line number Diff line number Diff line
@@ -100,6 +100,8 @@ static void etnaviv_cmd_select_pipe(struct etnaviv_gpu *gpu,
{
	u32 flush = 0;

	lockdep_assert_held(&gpu->lock);

	/*
	 * This assumes that if we're switching to 2D, we're switching
	 * away from 3D, and vice versa.  Hence, if we're switching to
@@ -164,7 +166,9 @@ static u32 etnaviv_buffer_reserve(struct etnaviv_gpu *gpu,

u16 etnaviv_buffer_init(struct etnaviv_gpu *gpu)
{
	struct etnaviv_cmdbuf *buffer = gpu->buffer;
	struct etnaviv_cmdbuf *buffer = &gpu->buffer;

	lockdep_assert_held(&gpu->lock);

	/* initialize buffer */
	buffer->user_size = 0;
@@ -178,7 +182,9 @@ u16 etnaviv_buffer_init(struct etnaviv_gpu *gpu)

u16 etnaviv_buffer_config_mmuv2(struct etnaviv_gpu *gpu, u32 mtlb_addr, u32 safe_addr)
{
	struct etnaviv_cmdbuf *buffer = gpu->buffer;
	struct etnaviv_cmdbuf *buffer = &gpu->buffer;

	lockdep_assert_held(&gpu->lock);

	buffer->user_size = 0;

@@ -211,10 +217,12 @@ u16 etnaviv_buffer_config_mmuv2(struct etnaviv_gpu *gpu, u32 mtlb_addr, u32 safe

void etnaviv_buffer_end(struct etnaviv_gpu *gpu)
{
	struct etnaviv_cmdbuf *buffer = gpu->buffer;
	struct etnaviv_cmdbuf *buffer = &gpu->buffer;
	unsigned int waitlink_offset = buffer->user_size - 16;
	u32 link_target, flush = 0;

	lockdep_assert_held(&gpu->lock);

	if (gpu->exec_state == ETNA_PIPE_2D)
		flush = VIVS_GL_FLUSH_CACHE_PE2D;
	else if (gpu->exec_state == ETNA_PIPE_3D)
@@ -253,10 +261,12 @@ void etnaviv_buffer_end(struct etnaviv_gpu *gpu)
/* Append a 'sync point' to the ring buffer. */
void etnaviv_sync_point_queue(struct etnaviv_gpu *gpu, unsigned int event)
{
	struct etnaviv_cmdbuf *buffer = gpu->buffer;
	struct etnaviv_cmdbuf *buffer = &gpu->buffer;
	unsigned int waitlink_offset = buffer->user_size - 16;
	u32 dwords, target;

	lockdep_assert_held(&gpu->lock);

	/*
	 * We need at most 3 dwords in the return target:
	 * 1 event + 1 end + 1 wait + 1 link.
@@ -287,13 +297,16 @@ void etnaviv_sync_point_queue(struct etnaviv_gpu *gpu, unsigned int event)
}

/* Append a command buffer to the ring buffer. */
void etnaviv_buffer_queue(struct etnaviv_gpu *gpu, unsigned int event,
	struct etnaviv_cmdbuf *cmdbuf)
void etnaviv_buffer_queue(struct etnaviv_gpu *gpu, u32 exec_state,
	unsigned int event, struct etnaviv_cmdbuf *cmdbuf)
{
	struct etnaviv_cmdbuf *buffer = gpu->buffer;
	struct etnaviv_cmdbuf *buffer = &gpu->buffer;
	unsigned int waitlink_offset = buffer->user_size - 16;
	u32 return_target, return_dwords;
	u32 link_target, link_dwords;
	bool switch_context = gpu->exec_state != exec_state;

	lockdep_assert_held(&gpu->lock);

	if (drm_debug & DRM_UT_DRIVER)
		etnaviv_buffer_dump(gpu, buffer, 0, 0x50);
@@ -306,7 +319,7 @@ void etnaviv_buffer_queue(struct etnaviv_gpu *gpu, unsigned int event,
	 * need to append a mmu flush load state, followed by a new
	 * link to this buffer - a total of four additional words.
	 */
	if (gpu->mmu->need_flush || gpu->switch_context) {
	if (gpu->mmu->need_flush || switch_context) {
		u32 target, extra_dwords;

		/* link command */
@@ -321,7 +334,7 @@ void etnaviv_buffer_queue(struct etnaviv_gpu *gpu, unsigned int event,
		}

		/* pipe switch commands */
		if (gpu->switch_context)
		if (switch_context)
			extra_dwords += 4;

		target = etnaviv_buffer_reserve(gpu, buffer, extra_dwords);
@@ -349,10 +362,9 @@ void etnaviv_buffer_queue(struct etnaviv_gpu *gpu, unsigned int event,
			gpu->mmu->need_flush = false;
		}

		if (gpu->switch_context) {
			etnaviv_cmd_select_pipe(gpu, buffer, cmdbuf->exec_state);
			gpu->exec_state = cmdbuf->exec_state;
			gpu->switch_context = false;
		if (switch_context) {
			etnaviv_cmd_select_pipe(gpu, buffer, exec_state);
			gpu->exec_state = exec_state;
		}

		/* And the link to the submitted buffer */
@@ -421,4 +433,6 @@ void etnaviv_buffer_queue(struct etnaviv_gpu *gpu, unsigned int event,

	if (drm_debug & DRM_UT_DRIVER)
		etnaviv_buffer_dump(gpu, buffer, 0, 0x50);

	gpu->lastctx = cmdbuf->ctx;
}
+1 −0
Original line number Diff line number Diff line
@@ -78,6 +78,7 @@ static const struct {
	ST(0x17c0, 8),
	ST(0x17e0, 8),
	ST(0x2400, 14 * 16),
	ST(0x3824, 1),
	ST(0x10800, 32 * 16),
	ST(0x14600, 16),
	ST(0x14800, 8 * 8),
+4 −25
Original line number Diff line number Diff line
@@ -86,26 +86,11 @@ void etnaviv_cmdbuf_suballoc_destroy(struct etnaviv_cmdbuf_suballoc *suballoc)
	kfree(suballoc);
}

struct etnaviv_cmdbuf *
etnaviv_cmdbuf_new(struct etnaviv_cmdbuf_suballoc *suballoc, u32 size,
		   size_t nr_bos, size_t nr_pmrs)
int etnaviv_cmdbuf_init(struct etnaviv_cmdbuf_suballoc *suballoc,
			struct etnaviv_cmdbuf *cmdbuf, u32 size)
{
	struct etnaviv_cmdbuf *cmdbuf;
	struct etnaviv_perfmon_request *pmrs;
	size_t sz = size_vstruct(nr_bos, sizeof(cmdbuf->bo_map[0]),
				 sizeof(*cmdbuf));
	int granule_offs, order, ret;

	cmdbuf = kzalloc(sz, GFP_KERNEL);
	if (!cmdbuf)
		return NULL;

	sz = sizeof(*pmrs) * nr_pmrs;
	pmrs = kzalloc(sz, GFP_KERNEL);
	if (!pmrs)
		goto out_free_cmdbuf;

	cmdbuf->pmrs = pmrs;
	cmdbuf->suballoc = suballoc;
	cmdbuf->size = size;

@@ -123,7 +108,7 @@ etnaviv_cmdbuf_new(struct etnaviv_cmdbuf_suballoc *suballoc, u32 size,
		if (!ret) {
			dev_err(suballoc->gpu->dev,
				"Timeout waiting for cmdbuf space\n");
			return NULL;
			return -ETIMEDOUT;
		}
		goto retry;
	}
@@ -131,11 +116,7 @@ etnaviv_cmdbuf_new(struct etnaviv_cmdbuf_suballoc *suballoc, u32 size,
	cmdbuf->suballoc_offset = granule_offs * SUBALLOC_GRANULE;
	cmdbuf->vaddr = suballoc->vaddr + cmdbuf->suballoc_offset;

	return cmdbuf;

out_free_cmdbuf:
	kfree(cmdbuf);
	return NULL;
	return 0;
}

void etnaviv_cmdbuf_free(struct etnaviv_cmdbuf *cmdbuf)
@@ -151,8 +132,6 @@ void etnaviv_cmdbuf_free(struct etnaviv_cmdbuf *cmdbuf)
	suballoc->free_space = 1;
	mutex_unlock(&suballoc->lock);
	wake_up_all(&suballoc->free_event);
	kfree(cmdbuf->pmrs);
	kfree(cmdbuf);
}

u32 etnaviv_cmdbuf_get_va(struct etnaviv_cmdbuf *buf)
+3 −15
Original line number Diff line number Diff line
@@ -33,27 +33,15 @@ struct etnaviv_cmdbuf {
	void *vaddr;
	u32 size;
	u32 user_size;
	/* fence after which this buffer is to be disposed */
	struct dma_fence *fence;
	/* target exec state */
	u32 exec_state;
	/* per GPU in-flight list */
	struct list_head node;
	/* perfmon requests */
	unsigned int nr_pmrs;
	struct etnaviv_perfmon_request *pmrs;
	/* BOs attached to this command buffer */
	unsigned int nr_bos;
	struct etnaviv_vram_mapping *bo_map[0];
};

struct etnaviv_cmdbuf_suballoc *
etnaviv_cmdbuf_suballoc_new(struct etnaviv_gpu * gpu);
void etnaviv_cmdbuf_suballoc_destroy(struct etnaviv_cmdbuf_suballoc *suballoc);

struct etnaviv_cmdbuf *
etnaviv_cmdbuf_new(struct etnaviv_cmdbuf_suballoc *suballoc, u32 size,
		   size_t nr_bos, size_t nr_pmrs);

int etnaviv_cmdbuf_init(struct etnaviv_cmdbuf_suballoc *suballoc,
		struct etnaviv_cmdbuf *cmdbuf, u32 size);
void etnaviv_cmdbuf_free(struct etnaviv_cmdbuf *cmdbuf);

u32 etnaviv_cmdbuf_get_va(struct etnaviv_cmdbuf *buf);
Loading