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

Commit 05fb6786 authored by Jordan Crouse's avatar Jordan Crouse
Browse files

msm: kgsl: Move hw_isidle to target specific code



Currently, there is a custom hw_isidle function defined for a6xx but the
function pointer is removed in a6xx_start for non GMU/RGMU a6xx targets
which has the effect of falling back to the generic adreno_hw_isidle
function which confused at least two of us before we figured out what
was happening.

Instead of having a generic adreno_hw_isidle function except for a6xx, add
a hw_isidle function hook for all targets and do the GMU check in the
a6xx specific function. This also has the advantage of moving a a540
specific hack into the a5xx code and removes one of two usages of the
gpucore specific busy mask and the other is in soft fault detect.
Arguably we should get rid that too but for now we can just hardcode
the mask in there and remove the busy mask from the gpucore struct.

And finally it looks like adreno_isidle isn't used as a function hook,
so remove it from the device function tables and mark it static.

Change-Id: Ic0dedbad47fa5dee0e5d903a8f9dd9bf7230b759
Signed-off-by: default avatarJordan Crouse <jcrouse@codeaurora.org>
parent c744ab5d
Loading
Loading
Loading
Loading
+0 −23
Original line number Diff line number Diff line
@@ -28,7 +28,6 @@ static const struct adreno_a3xx_core adreno_gpu_core_a306 = {
		.gpudev = &adreno_a3xx_gpudev,
		.gmem_base = 0,
		.gmem_size = SZ_128K,
		.busy_mask = 0x7ffffffe,
		.bus_width = 0,
		.snapshot_size = 600 * SZ_1K,
	},
@@ -51,7 +50,6 @@ static const struct adreno_a3xx_core adreno_gpu_core_a306a = {
		.gpudev = &adreno_a3xx_gpudev,
		.gmem_base = 0,
		.gmem_size = SZ_128K,
		.busy_mask = 0x7ffffffe,
		.bus_width = 16,
		.snapshot_size = 600 * SZ_1K,
	},
@@ -72,7 +70,6 @@ static const struct adreno_a3xx_core adreno_gpu_core_a304 = {
		.gpudev = &adreno_a3xx_gpudev,
		.gmem_base = 0,
		.gmem_size = (SZ_64K + SZ_32K),
		.busy_mask = 0x7ffffffe,
		.bus_width = 0,
		.snapshot_size = 600 * SZ_1K,
	},
@@ -197,7 +194,6 @@ static const struct adreno_a5xx_core adreno_gpu_core_a530v2 = {
		.gpudev = &adreno_a5xx_gpudev,
		.gmem_base = 0x100000,
		.gmem_size = SZ_1M,
		.busy_mask = 0xfffffffe,
		.bus_width = 32,
		.snapshot_size = SZ_1M,
	},
@@ -224,7 +220,6 @@ static const struct adreno_a5xx_core adreno_gpu_core_a530v3 = {
		.gpudev = &adreno_a5xx_gpudev,
		.gmem_base = 0x100000,
		.gmem_size = SZ_1M,
		.busy_mask = 0xfffffffe,
		.bus_width = 32,
		.snapshot_size = SZ_1M,
	},
@@ -291,7 +286,6 @@ static const struct adreno_a5xx_core adreno_gpu_core_a505 = {
		.gpudev = &adreno_a5xx_gpudev,
		.gmem_base = 0x100000,
		.gmem_size = (SZ_128K + SZ_8K),
		.busy_mask = 0xfffffffe,
		.bus_width = 16,
		.snapshot_size = SZ_1M,
	},
@@ -311,7 +305,6 @@ static const struct adreno_a5xx_core adreno_gpu_core_a506 = {
		.gpudev = &adreno_a5xx_gpudev,
		.gmem_base = 0x100000,
		.gmem_size = (SZ_128K + SZ_8K),
		.busy_mask = 0xfffffffe,
		.bus_width = 16,
		.snapshot_size = SZ_1M,
	},
@@ -390,7 +383,6 @@ static const struct adreno_a5xx_core adreno_gpu_core_a510 = {
		.gpudev = &adreno_a5xx_gpudev,
		.gmem_base = 0x100000,
		.gmem_size = SZ_256K,
		.busy_mask = 0xfffffffe,
		.bus_width = 16,
		.snapshot_size = SZ_1M,
	},
@@ -516,7 +508,6 @@ static const struct adreno_a5xx_core adreno_gpu_core_a540v2 = {
		.gpudev = &adreno_a5xx_gpudev,
		.gmem_base = 0x100000,
		.gmem_size = SZ_1M,
		.busy_mask = 0xfffffffe,
		.bus_width = 32,
		.snapshot_size = SZ_1M,
	},
@@ -600,7 +591,6 @@ static const struct adreno_a5xx_core adreno_gpu_core_a512 = {
		.gpudev = &adreno_a5xx_gpudev,
		.gmem_base = 0x100000,
		.gmem_size = (SZ_256K + SZ_16K),
		.busy_mask = 0xfffffffe,
		.bus_width = 32,
		.snapshot_size = SZ_1M,
	},
@@ -620,7 +610,6 @@ static const struct adreno_a5xx_core adreno_gpu_core_a508 = {
		.gpudev = &adreno_a5xx_gpudev,
		.gmem_base = 0x100000,
		.gmem_size = (SZ_128K + SZ_8K),
		.busy_mask = 0xfffffffe,
		.bus_width = 32,
		.snapshot_size = SZ_1M,
	},
@@ -796,7 +785,6 @@ static const struct adreno_a6xx_core adreno_gpu_core_a630v2 = {
		.gpudev = &adreno_a6xx_gpudev,
		.gmem_base = 0x100000,
		.gmem_size = SZ_1M,
		.busy_mask = 0xfffffffe,
		.bus_width = 32,
		.snapshot_size = SZ_1M,
	},
@@ -897,7 +885,6 @@ static const struct adreno_a6xx_core adreno_gpu_core_a615 = {
		.gpudev = &adreno_a6xx_gpudev,
		.gmem_base = 0x100000,
		.gmem_size = SZ_512K,
		.busy_mask = 0xfffffffe,
		.bus_width = 32,
		.snapshot_size = 600 * SZ_1K,
	},
@@ -926,7 +913,6 @@ static const struct adreno_a6xx_core adreno_gpu_core_a618 = {
		.gpudev = &adreno_a6xx_gpudev,
		.gmem_base = 0x100000,
		.gmem_size = SZ_512K,
		.busy_mask = 0xfffffffe,
		.bus_width = 32,
		.snapshot_size = SZ_1M,
	},
@@ -1056,7 +1042,6 @@ static const struct adreno_a6xx_core adreno_gpu_core_a620 = {
		.gpudev = &adreno_a6xx_gpudev,
		.gmem_base = 0,
		.gmem_size = SZ_512K,
		.busy_mask = 0xfffffffe,
		.bus_width = 32,
		.snapshot_size = 2 * SZ_1M,
	},
@@ -1148,7 +1133,6 @@ static const struct adreno_a6xx_core adreno_gpu_core_a640 = {
		.gpudev = &adreno_a6xx_gpudev,
		.gmem_base = 0x100000,
		.gmem_size = SZ_1M, //Verified 1MB
		.busy_mask = 0xfffffffe,
		.bus_width = 32,
		.snapshot_size = 2 * SZ_1M,
	},
@@ -1230,7 +1214,6 @@ static const struct adreno_a6xx_core adreno_gpu_core_a650 = {
		.gpudev = &adreno_a6xx_gpudev,
		.gmem_base = 0,
		.gmem_size = SZ_1M + SZ_128K, /* verified 1152kB */
		.busy_mask = 0xfffffffe,
		.bus_width = 32,
		.snapshot_size = 2 * SZ_1M,
	},
@@ -1261,7 +1244,6 @@ static const struct adreno_a6xx_core adreno_gpu_core_a650v2 = {
		.gpudev = &adreno_a6xx_gpudev,
		.gmem_base = 0,
		.gmem_size = SZ_1M + SZ_128K, /* verified 1152kB */
		.busy_mask = 0xfffffffe,
		.bus_width = 32,
		.snapshot_size = 2 * SZ_1M,
	},
@@ -1289,7 +1271,6 @@ static const struct adreno_a6xx_core adreno_gpu_core_a680 = {
		.gpudev = &adreno_a6xx_gpudev,
		.gmem_base = 0x100000,
		.gmem_size = SZ_2M,
		.busy_mask = 0xfffffffe,
		.bus_width = 32,
		.snapshot_size = SZ_1M,
	},
@@ -1368,7 +1349,6 @@ static const struct adreno_a6xx_core adreno_gpu_core_a612 = {
		.gpudev = &adreno_a6xx_gpudev,
		.gmem_base = 0x100000,
		.gmem_size = (SZ_128K + SZ_4K),
		.busy_mask = 0xfffffffe,
		.bus_width = 32,
		.snapshot_size = SZ_1M,
	},
@@ -1395,7 +1375,6 @@ static const struct adreno_a6xx_core adreno_gpu_core_a616 = {
		.gpudev = &adreno_a6xx_gpudev,
		.gmem_base = 0x100000,
		.gmem_size = SZ_512K,
		.busy_mask = 0xfffffffe,
		.bus_width = 32,
		.snapshot_size = SZ_1M,
	},
@@ -1423,7 +1402,6 @@ static const struct adreno_a6xx_core adreno_gpu_core_a610 = {
		.gpudev = &adreno_a6xx_gpudev,
		.gmem_base = 0x100000,
		.gmem_size = (SZ_128K + SZ_4K),
		.busy_mask = 0xfffffffe,
		.bus_width = 32,
	},
	.prim_fifo_threshold = 0x00080000,
@@ -1537,7 +1515,6 @@ static const struct adreno_a6xx_core adreno_gpu_core_a660 = {
		.gpudev = &adreno_a6xx_gpudev,
		.gmem_base = 0,
		.gmem_size = SZ_1M + SZ_512K,
		.busy_mask = 0xfffffffe,
		.bus_width = 32,
		.snapshot_size = SZ_1M,
	},
+11 −58
Original line number Diff line number Diff line
@@ -2740,7 +2740,7 @@ static int adreno_setproperty(struct kgsl_device_private *dev_priv,
 *
 * Returns true if interrupts are pending from device else 0.
 */
inline unsigned int adreno_irq_pending(struct adreno_device *adreno_dev)
bool adreno_irq_pending(struct adreno_device *adreno_dev)
{
	unsigned int status;

@@ -2755,48 +2755,9 @@ inline unsigned int adreno_irq_pending(struct adreno_device *adreno_dev)
	 */
	if ((status & adreno_dev->irq_mask) ||
		atomic_read(&adreno_dev->pending_irq_refcnt))
		return 1;
	else
		return 0;
}


/**
 * adreno_hw_isidle() - Check if the GPU core is idle
 * @adreno_dev: Pointer to the Adreno device structure for the GPU
 *
 * Return true if the RBBM status register for the GPU type indicates that the
 * hardware is idle
 */
bool adreno_hw_isidle(struct adreno_device *adreno_dev)
{
	const struct adreno_gpu_core *gpucore = adreno_dev->gpucore;
	unsigned int reg_rbbm_status;
	struct adreno_gpudev *gpudev  = ADRENO_GPU_DEVICE(adreno_dev);

	/* if hw driver implements idle check - use it */
	if (gpudev->hw_isidle)
		return gpudev->hw_isidle(adreno_dev);

	if (adreno_is_a540(adreno_dev))
		/**
		 * Due to CRC idle throttling GPU
		 * idle hysteresys can take up to
		 * 3usec for expire - account for it
		 */
		udelay(5);

	adreno_readreg(adreno_dev, ADRENO_REG_RBBM_STATUS,
		&reg_rbbm_status);

	if (reg_rbbm_status & gpucore->busy_mask)
		return false;
		return true;

	/* Don't consider ourselves idle if there is an IRQ pending */
	if (adreno_irq_pending(adreno_dev))
	return false;

	return true;
}

/*
@@ -2884,20 +2845,13 @@ static int adreno_soft_reset(struct kgsl_device *device)
	return ret;
}

/*
 * adreno_isidle() - return true if the GPU hardware is idle
 * @device: Pointer to the KGSL device structure for the GPU
 *
 * Return true if the GPU hardware is idle and there are no commands pending in
 * the ringbuffer
 */
bool adreno_isidle(struct kgsl_device *device)
static bool adreno_isidle(struct adreno_device *adreno_dev)
{
	struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
	struct adreno_gpudev *gpudev  = ADRENO_GPU_DEVICE(adreno_dev);
	struct adreno_ringbuffer *rb;
	int i;

	if (!kgsl_state_is_awake(device))
	if (!kgsl_state_is_awake(KGSL_DEVICE(adreno_dev)))
		return true;

	/*
@@ -2916,7 +2870,7 @@ bool adreno_isidle(struct kgsl_device *device)
			return false;
	}

	return adreno_hw_isidle(adreno_dev);
	return gpudev->hw_isidle(adreno_dev);
}

/* Print some key registers if a spin-for-idle times out */
@@ -2977,7 +2931,7 @@ int adreno_spin_idle(struct adreno_device *adreno_dev, unsigned int timeout)
		if (adreno_gpu_fault(adreno_dev) != 0)
			return -EDEADLK;

		if (adreno_isidle(KGSL_DEVICE(adreno_dev)))
		if (adreno_isidle(adreno_dev))
			return 0;

	} while (time_before(jiffies, wait));
@@ -2990,7 +2944,7 @@ int adreno_spin_idle(struct adreno_device *adreno_dev, unsigned int timeout)
	if (adreno_gpu_fault(adreno_dev) != 0)
		return -EDEADLK;

	if (adreno_isidle(KGSL_DEVICE(adreno_dev)))
	if (adreno_isidle(adreno_dev))
		return 0;

	return -ETIMEDOUT;
@@ -3018,7 +2972,7 @@ int adreno_idle(struct kgsl_device *device)
		return -EDEADLK;

	/* Check if we are already idle before idling dispatcher */
	if (adreno_isidle(device))
	if (adreno_isidle(adreno_dev))
		return 0;
	/*
	 * Wait for dispatcher to finish completing commands
@@ -3715,7 +3669,7 @@ static bool adreno_is_hw_collapsible(struct kgsl_device *device)
			device->pwrctrl.ctrl_flags)
		return false;

	return adreno_isidle(device) && (gpudev->is_sptp_idle ?
	return adreno_isidle(adreno_dev) && (gpudev->is_sptp_idle ?
				gpudev->is_sptp_idle(adreno_dev) : true);
}

@@ -3801,7 +3755,6 @@ static const struct kgsl_functable adreno_functable = {
	.regread = adreno_regread,
	.regwrite = adreno_regwrite,
	.idle = adreno_idle,
	.isidle = adreno_isidle,
	.suspend_context = adreno_suspend_context,
	.first_open = adreno_first_open,
	.start = adreno_start,
+7 −5
Original line number Diff line number Diff line
@@ -340,7 +340,6 @@ struct adreno_reglist {
 * @gpudev: Pointer to the GPU family specific functions for this core
 * @gmem_base: Base address of binning memory (GMEM/OCMEM)
 * @gmem_size: Amount of binning memory (GMEM/OCMEM) to reserve for the core
 * @busy_mask: mask to check if GPU is busy in RBBM_STATUS
 * @bus_width: Bytes transferred in 1 cycle
 */
struct adreno_gpu_core {
@@ -350,7 +349,6 @@ struct adreno_gpu_core {
	struct adreno_gpudev *gpudev;
	unsigned long gmem_base;
	size_t gmem_size;
	unsigned int busy_mask;
	u32 bus_width;
	/** @snapshot_size: Size of the static snapshot region in bytes */
	u32 snapshot_size;
@@ -889,7 +887,6 @@ int adreno_switch_to_unsecure_mode(struct adreno_device *adreno_dev,
void adreno_spin_idle_debug(struct adreno_device *adreno_dev, const char *str);
int adreno_spin_idle(struct adreno_device *device, unsigned int timeout);
int adreno_idle(struct kgsl_device *device);
bool adreno_isidle(struct kgsl_device *device);

int adreno_set_constraint(struct kgsl_device *device,
				struct kgsl_context *context,
@@ -905,8 +902,6 @@ void adreno_fault_skipcmd_detached(struct adreno_device *adreno_dev,
					 struct adreno_context *drawctxt,
					 struct kgsl_drawobj *drawobj);

bool adreno_hw_isidle(struct adreno_device *adreno_dev);

void adreno_fault_detect_start(struct adreno_device *adreno_dev);
void adreno_fault_detect_stop(struct adreno_device *adreno_dev);

@@ -946,6 +941,13 @@ void adreno_rscc_regread(struct adreno_device *adreno_dev,
void adreno_isense_regread(struct adreno_device *adreno_dev,
		unsigned int offsetwords, unsigned int *value);

/**
 * adreno_irq_pending - Return true if an interrupt is pending
 * @adreno_dev: An Adreno GPU device handle
 *
 * Returns: true if interrupts are pending on the device
 */
bool adreno_irq_pending(struct adreno_device *adreno_dev);

#define ADRENO_TARGET(_name, _id) \
static inline int adreno_is_##_name(struct adreno_device *adreno_dev) \
+14 −0
Original line number Diff line number Diff line
@@ -1381,6 +1381,19 @@ static irqreturn_t a3xx_irq_handler(struct adreno_device *adreno_dev)
	return ret;
}

static bool a3xx_hw_isidle(struct adreno_device *adreno_dev)
{
	struct kgsl_device *device = KGSL_DEVICE(adreno_dev);
	u32 status;

	kgsl_regread(device, A3XX_RBBM_STATUS, &status);

	if (status & 0x7ffffffe)
		return false;

	return adreno_irq_pending(adreno_dev) ? false : true;
}

struct adreno_gpudev adreno_a3xx_gpudev = {
	.reg_offsets = a3xx_register_offsets,
	.ft_perf_counters = a3xx_ft_perf_counters,
@@ -1399,4 +1412,5 @@ struct adreno_gpudev adreno_a3xx_gpudev = {
#endif
	.clk_set_options = a3xx_clk_set_options,
	.read_alwayson = a3xx_read_alwayson,
	.hw_isidle = a3xx_hw_isidle,
};
+21 −0
Original line number Diff line number Diff line
@@ -2752,6 +2752,26 @@ static irqreturn_t a5xx_irq_handler(struct adreno_device *adreno_dev)
	return ret;
}

static bool a5xx_hw_isidle(struct adreno_device *adreno_dev)
{
	struct kgsl_device *device = KGSL_DEVICE(adreno_dev);
	u32 status;

	/*
	 * Due to CRC idle throttling the GPU idle hysteresis on a540 can take
	 * up to 5uS to expire
	 */
	if (adreno_is_a540(adreno_dev))
		udelay(5);

	kgsl_regread(device, A5XX_RBBM_STATUS, &status);

	if (status & 0xfffffffe)
		return false;

	return adreno_irq_pending(adreno_dev) ? false : true;
}

#ifdef CONFIG_QCOM_KGSL_CORESIGHT
static struct adreno_coresight_register a5xx_coresight_registers[] = {
	{ A5XX_RBBM_CFG_DBGBUS_SEL_A },
@@ -2978,4 +2998,5 @@ struct adreno_gpudev adreno_a5xx_gpudev = {
	.preemption_schedule = a5xx_preemption_schedule,
	.clk_set_options = a5xx_clk_set_options,
	.read_alwayson = a5xx_read_alwayson,
	.hw_isidle = a5xx_hw_isidle,
};
Loading