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

Commit df78b6d5 authored by Harshdeep Dhatt's avatar Harshdeep Dhatt Committed by Gerrit - the friendly Code Review server
Browse files

msm: kgsl: Remove the preemption oob



This oob is needed in a corner case of preemption
state machine, where we need to read the wptr to
see if it needs to be updated. But in cases where it
doesn't need to be updated, we have forcibly brought
gpu out of ifpc for nothing. Instead, use a flag to
figure the corner case, and then use a fenced write
only when wptr needs update.

Change-Id: I1b111d187c982fd2102c1e1c4d2b8f93bd7d18eb
Signed-off-by: default avatarHarshdeep Dhatt <hdhatt@codeaurora.org>
parent be72cb4a
Loading
Loading
Loading
Loading
+28 −27
Original line number Original line Diff line number Diff line
@@ -26,40 +26,36 @@ enum {


static void _update_wptr(struct adreno_device *adreno_dev, bool reset_timer)
static void _update_wptr(struct adreno_device *adreno_dev, bool reset_timer)
{
{
	struct kgsl_device *device = KGSL_DEVICE(adreno_dev);
	struct adreno_ringbuffer *rb = adreno_dev->cur_rb;
	struct adreno_ringbuffer *rb = adreno_dev->cur_rb;
	unsigned int wptr;
	unsigned long flags;
	unsigned long flags;
	int ret = 0;

	spin_lock_irqsave(&rb->preempt_lock, flags);


	if (in_interrupt() == 0) {
		/*
		/*
	 * Need to make sure GPU is up before we read the
		 * We might have skipped updating the wptr in case we are in
	 * WPTR as fence doesn't wake GPU on read operation.
		 * dispatcher context. Do it now.
		 */
		 */
	if (in_interrupt() == 0) {
		if (rb->skip_inline_wptr) {
		int status;


		status = gmu_core_dev_oob_set(device, oob_preempt);
			ret = adreno_gmu_fenced_write(adreno_dev,
				ADRENO_REG_CP_RB_WPTR, rb->wptr,
				FENCE_STATUS_WRITEDROPPED0_MASK);


		if (status) {
			reset_timer = true;
			adreno_set_gpu_fault(adreno_dev, ADRENO_GMU_FAULT);
			rb->skip_inline_wptr = false;
			adreno_dispatcher_schedule(device);
			return;
		}
		}
		}

	} else {
	spin_lock_irqsave(&rb->preempt_lock, flags);
		unsigned int wptr;


		adreno_readreg(adreno_dev, ADRENO_REG_CP_RB_WPTR, &wptr);
		adreno_readreg(adreno_dev, ADRENO_REG_CP_RB_WPTR, &wptr);

		if (wptr != rb->wptr) {
		if (wptr != rb->wptr) {
			adreno_writereg(adreno_dev, ADRENO_REG_CP_RB_WPTR,
			adreno_writereg(adreno_dev, ADRENO_REG_CP_RB_WPTR,
				rb->wptr);
				rb->wptr);
		/*
		 * In case something got submitted while preemption was on
		 * going, reset the timer.
		 */
			reset_timer = true;
			reset_timer = true;
		}
		}
	}


	if (reset_timer)
	if (reset_timer)
		rb->dispatch_q.expires = jiffies +
		rb->dispatch_q.expires = jiffies +
@@ -67,8 +63,13 @@ static void _update_wptr(struct adreno_device *adreno_dev, bool reset_timer)


	spin_unlock_irqrestore(&rb->preempt_lock, flags);
	spin_unlock_irqrestore(&rb->preempt_lock, flags);


	if (in_interrupt() == 0)
	if (in_interrupt() == 0) {
		gmu_core_dev_oob_clear(device, oob_preempt);
		/* If WPTR update fails, set the fault and trigger recovery */
		if (ret) {
			adreno_set_gpu_fault(adreno_dev, ADRENO_GMU_FAULT);
			adreno_dispatcher_schedule(KGSL_DEVICE(adreno_dev));
		}
	}
}
}


static inline bool adreno_move_preempt_state(struct adreno_device *adreno_dev,
static inline bool adreno_move_preempt_state(struct adreno_device *adreno_dev,
+9 −2
Original line number Original line Diff line number Diff line
@@ -101,8 +101,16 @@ static void adreno_ringbuffer_wptr(struct adreno_device *adreno_dev,
			ret = adreno_gmu_fenced_write(adreno_dev,
			ret = adreno_gmu_fenced_write(adreno_dev,
				ADRENO_REG_CP_RB_WPTR, rb->_wptr,
				ADRENO_REG_CP_RB_WPTR, rb->_wptr,
				FENCE_STATUS_WRITEDROPPED0_MASK);
				FENCE_STATUS_WRITEDROPPED0_MASK);

			rb->skip_inline_wptr = false;
		}
		}
	} else {
		/*
		 * We skipped inline submission because of preemption state
		 * machine. Set things up so that we write the wptr to the
		 * hardware eventually.
		 */
		if (adreno_dev->cur_rb == rb)
			rb->skip_inline_wptr = true;
	}
	}


	rb->wptr = rb->_wptr;
	rb->wptr = rb->_wptr;
@@ -113,7 +121,6 @@ static void adreno_ringbuffer_wptr(struct adreno_device *adreno_dev,
		adreno_set_gpu_fault(adreno_dev, ADRENO_GMU_FAULT);
		adreno_set_gpu_fault(adreno_dev, ADRENO_GMU_FAULT);
		adreno_dispatcher_schedule(KGSL_DEVICE(adreno_dev));
		adreno_dispatcher_schedule(KGSL_DEVICE(adreno_dev));
	}
	}

}
}


static void adreno_profile_submit_time(struct adreno_submit_time *time)
static void adreno_profile_submit_time(struct adreno_submit_time *time)
+3 −0
Original line number Original line Diff line number Diff line
@@ -100,6 +100,8 @@ struct adreno_ringbuffer_pagetable_info {
 * @gpr11: The gpr11 value of this RB
 * @gpr11: The gpr11 value of this RB
 * @preempted_midway: Indicates that the RB was preempted before rptr = wptr
 * @preempted_midway: Indicates that the RB was preempted before rptr = wptr
 * @preempt_lock: Lock to protect the wptr pointer while it is being updated
 * @preempt_lock: Lock to protect the wptr pointer while it is being updated
 * @skip_inline_wptr: Used during preemption to make sure wptr is updated in
 * hardware
 */
 */
struct adreno_ringbuffer {
struct adreno_ringbuffer {
	uint32_t flags;
	uint32_t flags;
@@ -122,6 +124,7 @@ struct adreno_ringbuffer {
	unsigned int gpr11;
	unsigned int gpr11;
	int preempted_midway;
	int preempted_midway;
	spinlock_t preempt_lock;
	spinlock_t preempt_lock;
	bool skip_inline_wptr;
};
};


/* Returns the current ringbuffer */
/* Returns the current ringbuffer */
+0 −1
Original line number Original line Diff line number Diff line
@@ -33,7 +33,6 @@ const char *gmu_core_oob_type_str(enum oob_request req)
	struct oob_entry table[] =  {
	struct oob_entry table[] =  {
			{ oob_gpu, "oob_gpu"},
			{ oob_gpu, "oob_gpu"},
			{ oob_perfcntr, "oob_perfcntr"},
			{ oob_perfcntr, "oob_perfcntr"},
			{ oob_preempt, "oob_preempt"},
			{ oob_boot_slumber, "oob_boot_slumber"},
			{ oob_boot_slumber, "oob_boot_slumber"},
			{ oob_dcvs, "oob_dcvs"},
			{ oob_dcvs, "oob_dcvs"},
	};
	};
+0 −1
Original line number Original line Diff line number Diff line
@@ -64,7 +64,6 @@ enum gmu_coretype {
enum oob_request {
enum oob_request {
	oob_gpu = 0,
	oob_gpu = 0,
	oob_perfcntr = 1,
	oob_perfcntr = 1,
	oob_preempt = 2,
	oob_boot_slumber = 6, /* reserved special case */
	oob_boot_slumber = 6, /* reserved special case */
	oob_dcvs = 7, /* reserved special case */
	oob_dcvs = 7, /* reserved special case */
};
};