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

Commit 289a52c8 authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge changes I0d48316d,I8752ced6,I65c9d5c3 into msm-4.14

* changes:
  msm: kgsl: Initialize protect registers before powerup list
  msm: kgsl: Prevent race condition when freeing memory
  msm: kgsl: Write the profiling reference data before submission
parents 7bc7db4e 91a1a19b
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -872,13 +872,14 @@ static void a6xx_start(struct adreno_device *adreno_dev)
		kgsl_regwrite(device, A6XX_RB_CONTEXT_SWITCH_GMEM_SAVE_RESTORE,
			0x1);

	a6xx_protect_init(adreno_dev);

	if (!patch_reglist && (adreno_dev->pwrup_reglist.gpuaddr != 0)) {
		a6xx_patch_pwrup_reglist(adreno_dev);
		patch_reglist = true;
	}

	a6xx_preemption_start(adreno_dev);
	a6xx_protect_init(adreno_dev);

	/*
	 * We start LM here because we want all the following to be up
+2 −0
Original line number Diff line number Diff line
@@ -565,6 +565,8 @@ static int sendcmd(struct adreno_device *adreno_dev,
		return -EBUSY;
	}

	memset(&time, 0x0, sizeof(time));

	dispatcher->inflight++;
	dispatch_q->inflight++;

+53 −33
Original line number Diff line number Diff line
@@ -121,13 +121,60 @@ static void adreno_ringbuffer_wptr(struct adreno_device *adreno_dev,

}

static void adreno_profile_submit_time(struct adreno_submit_time *time)
{
	struct kgsl_drawobj *drawobj;
	struct kgsl_drawobj_cmd *cmdobj;
	struct kgsl_mem_entry *entry;

	if (time == NULL)
		return;

	drawobj = time->drawobj;

	if (drawobj == NULL)
		return;

	cmdobj = CMDOBJ(drawobj);
	entry = cmdobj->profiling_buf_entry;

	if (entry) {
		struct kgsl_drawobj_profiling_buffer *profile_buffer;

		profile_buffer = kgsl_gpuaddr_to_vaddr(&entry->memdesc,
					cmdobj->profiling_buffer_gpuaddr);

		if (profile_buffer == NULL)
			return;

		/* Return kernel clock time to the the client if requested */
		if (drawobj->flags & KGSL_DRAWOBJ_PROFILING_KTIME) {
			uint64_t secs = time->ktime;

			profile_buffer->wall_clock_ns =
				do_div(secs, NSEC_PER_SEC);
			profile_buffer->wall_clock_s = secs;
		} else {
			profile_buffer->wall_clock_s = time->utime.tv_sec;
			profile_buffer->wall_clock_ns = time->utime.tv_nsec;
		}

		profile_buffer->gpu_ticks_queued = time->ticks;

		kgsl_memdesc_unmap(&entry->memdesc);
	}
}

void adreno_ringbuffer_submit(struct adreno_ringbuffer *rb,
		struct adreno_submit_time *time)
{
	struct adreno_device *adreno_dev = ADRENO_RB_DEVICE(rb);

	if (time != NULL)
	if (time != NULL) {
		adreno_get_submit_time(adreno_dev, rb, time);
		/* Put the timevalues in the profiling buffer */
		adreno_profile_submit_time(time);
	}

	adreno_ringbuffer_wptr(adreno_dev, rb);
}
@@ -776,16 +823,12 @@ int adreno_ringbuffer_submitcmd(struct adreno_device *adreno_dev,
	int flags = KGSL_CMD_FLAGS_NONE;
	int ret;
	struct adreno_ringbuffer *rb;
	struct kgsl_drawobj_profiling_buffer *profile_buffer = NULL;
	unsigned int dwords = 0;
	struct adreno_submit_time local;
	struct kgsl_mem_entry *entry = cmdobj->profiling_buf_entry;
	struct adreno_firmware *fw = ADRENO_FW(adreno_dev, ADRENO_FW_SQE);
	bool set_ib1list_marker = false;

	if (entry)
		profile_buffer = kgsl_gpuaddr_to_vaddr(&entry->memdesc,
					cmdobj->profiling_buffer_gpuaddr);
	memset(&local, 0x0, sizeof(local));

	context = drawobj->context;
	drawctxt = ADRENO_CONTEXT(context);
@@ -857,7 +900,8 @@ int adreno_ringbuffer_submitcmd(struct adreno_device *adreno_dev,
	dwords += (numibs * 30);

	if (drawobj->flags & KGSL_DRAWOBJ_PROFILING &&
		!adreno_is_a3xx(adreno_dev) && profile_buffer) {
		!adreno_is_a3xx(adreno_dev) &&
		(cmdobj->profiling_buf_entry != NULL)) {
		user_profiling = true;
		dwords += 6;

@@ -877,6 +921,8 @@ int adreno_ringbuffer_submitcmd(struct adreno_device *adreno_dev,

		if (time == NULL)
			time = &local;

		time->drawobj = drawobj;
	}

	if (test_bit(CMDOBJ_PROFILE, &cmdobj->priv)) {
@@ -1029,35 +1075,9 @@ int adreno_ringbuffer_submitcmd(struct adreno_device *adreno_dev,
	if (!ret) {
		set_bit(KGSL_CONTEXT_PRIV_SUBMITTED, &context->priv);
		cmdobj->global_ts = drawctxt->internal_timestamp;

		/* Put the timevalues in the profiling buffer */
		if (user_profiling) {
			/*
			 * Return kernel clock time to the the client
			 * if requested
			 */
			if (drawobj->flags & KGSL_DRAWOBJ_PROFILING_KTIME) {
				uint64_t secs = time->ktime;

				profile_buffer->wall_clock_ns =
					do_div(secs, NSEC_PER_SEC);
				profile_buffer->wall_clock_s = secs;
			} else {
				profile_buffer->wall_clock_s =
					time->utime.tv_sec;
				profile_buffer->wall_clock_ns =
					time->utime.tv_nsec;
			}
			profile_buffer->gpu_ticks_queued = time->ticks;
		}
	}

done:
	/* Corresponding unmap to the memdesc map of profile_buffer */
	if (entry)
		kgsl_memdesc_unmap(&entry->memdesc);


	trace_kgsl_issueibcmds(device, context->id, numibs, drawobj->timestamp,
			drawobj->flags, ret, drawctxt->type);

+3 −1
Original line number Diff line number Diff line
/* Copyright (c) 2002,2007-2017, The Linux Foundation. All rights reserved.
/* Copyright (c) 2002,2007-2018, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
@@ -43,11 +43,13 @@ struct kgsl_device_private;
 * @ticks: GPU ticks at submit time (from the 19.2Mhz timer)
 * @ktime: local clock time (in nanoseconds)
 * @utime: Wall clock time
 * @drawobj: the object that we want to profile
 */
struct adreno_submit_time {
	uint64_t ticks;
	u64 ktime;
	struct timespec utime;
	struct kgsl_drawobj *drawobj;
};

/**
+12 −0
Original line number Diff line number Diff line
@@ -3424,7 +3424,13 @@ long kgsl_ioctl_sparse_phys_free(struct kgsl_device_private *dev_priv,
	if (entry == NULL)
		return -EINVAL;

	if (!kgsl_mem_entry_set_pend(entry)) {
		kgsl_mem_entry_put(entry);
		return -EBUSY;
	}

	if (entry->memdesc.cur_bindings != 0) {
		kgsl_mem_entry_unset_pend(entry);
		kgsl_mem_entry_put(entry);
		return -EINVAL;
	}
@@ -3493,7 +3499,13 @@ long kgsl_ioctl_sparse_virt_free(struct kgsl_device_private *dev_priv,
	if (entry == NULL)
		return -EINVAL;

	if (!kgsl_mem_entry_set_pend(entry)) {
		kgsl_mem_entry_put(entry);
		return -EBUSY;
	}

	if (entry->bind_tree.rb_node != NULL) {
		kgsl_mem_entry_unset_pend(entry);
		kgsl_mem_entry_put(entry);
		return -EINVAL;
	}