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

Commit 7db14e4a authored by qctecmdr's avatar qctecmdr Committed by Gerrit - the friendly Code Review server
Browse files

Merge "msm: kgsl: Put a keep alive vote before updating CP_RB_WPTR"

parents 16a70b4b 98bf61e5
Loading
Loading
Loading
Loading
+20 −0
Original line number Diff line number Diff line
@@ -36,6 +36,7 @@ static void _update_wptr(struct adreno_device *adreno_dev, bool reset_timer)
	struct adreno_ringbuffer *rb = adreno_dev->cur_rb;
	unsigned long flags;
	int ret = 0;
	struct kgsl_device *device = KGSL_DEVICE(adreno_dev);

	spin_lock_irqsave(&rb->preempt_lock, flags);

@@ -45,11 +46,30 @@ static void _update_wptr(struct adreno_device *adreno_dev, bool reset_timer)
		 * dispatcher context. Do it now.
		 */
		if (rb->skip_inline_wptr) {
			/*
			 * There could be a situation where GPU comes out of
			 * ifpc after a fenced write transaction but before
			 * reading AHB_FENCE_STATUS from KMD, it goes back to
			 * ifpc due to inactivity (kernel scheduler plays a
			 * role here). Thus, the GPU could technically be
			 * re-collapsed between subsequent register writes
			 * leading to a prolonged preemption sequence. The
			 * keepalive bit prevents any further power collapse
			 * while it is set.
			 */
			if (gmu_core_isenabled(device))
				gmu_core_regrmw(device, A6XX_GMU_AO_SPARE_CNTL,
					0x0, 0x2);

			ret = adreno_gmu_fenced_write(adreno_dev,
				ADRENO_REG_CP_RB_WPTR, rb->wptr,
				FENCE_STATUS_WRITEDROPPED0_MASK);

			/* Clear the keep alive */
			if (gmu_core_isenabled(device))
				gmu_core_regrmw(device, A6XX_GMU_AO_SPARE_CNTL,
					0x2, 0x0);

			reset_timer = true;
			rb->skip_inline_wptr = false;
		}
+16 −1
Original line number Diff line number Diff line
/* Copyright (c) 2002,2007-2019, The Linux Foundation. All rights reserved.
/* Copyright (c) 2002,2007-2020, 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
@@ -89,6 +89,7 @@ static void adreno_get_submit_time(struct adreno_device *adreno_dev,
static void adreno_ringbuffer_wptr(struct adreno_device *adreno_dev,
		struct adreno_ringbuffer *rb)
{
	struct adreno_gpudev *gpudev = ADRENO_GPU_DEVICE(adreno_dev);
	unsigned long flags;
	int ret = 0;

@@ -102,6 +103,17 @@ static void adreno_ringbuffer_wptr(struct adreno_device *adreno_dev,
			 */
			kgsl_pwrscale_busy(KGSL_DEVICE(adreno_dev));

			/*
			 * There could be a situation where GPU comes out of
			 * ifpc after a fenced write transaction but before
			 * reading AHB_FENCE_STATUS from KMD, it goes back to
			 * ifpc due to inactivity (kernel scheduler plays a
			 * role here). Put a keep alive vote to avoid such
			 * unlikely scenario.
			 */
			if (gpudev->gpu_keepalive)
				gpudev->gpu_keepalive(adreno_dev, true);

			/*
			 * Ensure the write posted after a possible
			 * GMU wakeup (write could have dropped during wakeup)
@@ -110,6 +122,9 @@ static void adreno_ringbuffer_wptr(struct adreno_device *adreno_dev,
				ADRENO_REG_CP_RB_WPTR, rb->_wptr,
				FENCE_STATUS_WRITEDROPPED0_MASK);
			rb->skip_inline_wptr = false;
			if (gpudev->gpu_keepalive)
				gpudev->gpu_keepalive(adreno_dev, false);

		}
	} else {
		/*