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

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

Merge "msm: kgsl: Dump always ON counter in adreno_irq_handler()"

parents db4c3fb3 9f5edacc
Loading
Loading
Loading
Loading
+10 −2
Original line number Diff line number Diff line
@@ -586,6 +586,9 @@ static irqreturn_t adreno_irq_handler(struct kgsl_device *device)
	unsigned int status = 0, fence = 0, fence_retries = 0, tmp, int_bit;
	unsigned int shadow_status = 0;
	int i;
	u64 ts, ts1, ts2;

	ts = gmu_core_dev_read_ao_counter(device);

	atomic_inc(&adreno_dev->pending_irq_refcnt);
	/* Ensure this increment is done before the IRQ status is updated */
@@ -612,6 +615,8 @@ static irqreturn_t adreno_irq_handler(struct kgsl_device *device)
				&fence);

		while (fence != 0) {
			ts1 =  gmu_core_dev_read_ao_counter(device);

			/* Wait for small time before trying again */
			udelay(1);
			adreno_readreg(adreno_dev,
@@ -619,14 +624,17 @@ static irqreturn_t adreno_irq_handler(struct kgsl_device *device)
					&fence);

			if (fence_retries == FENCE_RETRY_MAX && fence != 0) {
				ts2 =  gmu_core_dev_read_ao_counter(device);

				adreno_readreg(adreno_dev,
					ADRENO_REG_GMU_RBBM_INT_UNMASKED_STATUS,
					&shadow_status);

				dev_crit_ratelimited(device->dev,
					"Status=0x%x Unmasked status=0x%x Mask=0x%x\n",
					"Status=0x%x Unmasked status=0x%x Timestamps:%llx %llx %llx\n",
					shadow_status & irq_params->mask,
					shadow_status, irq_params->mask);
					shadow_status, ts, ts1, ts2);

				adreno_set_gpu_fault(adreno_dev,
						ADRENO_GMU_FAULT);
				adreno_dispatcher_schedule(KGSL_DEVICE
+1 −25
Original line number Diff line number Diff line
@@ -244,31 +244,6 @@ static inline int timed_poll_check_rscc(struct kgsl_device *device,
	return -ETIMEDOUT;
}

/*
 * read_AO_counter() - Returns the 64bit always on counter value
 *
 * @device: Pointer to KGSL device
 */
static inline uint64_t read_AO_counter(struct kgsl_device *device)
{
	unsigned int l, h, h1;

	gmu_core_regread(device, A6XX_GMU_CX_GMU_ALWAYS_ON_COUNTER_H, &h);
	gmu_core_regread(device, A6XX_GMU_CX_GMU_ALWAYS_ON_COUNTER_L, &l);
	gmu_core_regread(device, A6XX_GMU_CX_GMU_ALWAYS_ON_COUNTER_H, &h1);

	/*
	 * If there's no change in COUNTER_H we have no overflow so return,
	 * otherwise read COUNTER_L again
	 */

	if (h == h1)
		return (uint64_t) l | ((uint64_t) h << 32);

	gmu_core_regread(device, A6XX_GMU_CX_GMU_ALWAYS_ON_COUNTER_L, &l);
	return (uint64_t) l | ((uint64_t) h1 << 32);
}

/* Preemption functions */
void a6xx_preemption_trigger(struct adreno_device *adreno_dev);
void a6xx_preemption_schedule(struct adreno_device *adreno_dev);
@@ -297,4 +272,5 @@ void a6xx_crashdump_init(struct adreno_device *adreno_dev);
int a6xx_gmu_sptprac_enable(struct adreno_device *adreno_dev);
void a6xx_gmu_sptprac_disable(struct adreno_device *adreno_dev);
bool a6xx_gmu_sptprac_is_on(struct adreno_device *adreno_dev);
u64 a6xx_gmu_read_ao_counter(struct kgsl_device *device);
#endif
+31 −5
Original line number Diff line number Diff line
@@ -886,7 +886,7 @@ static int a6xx_gmu_wait_for_lowest_idle(struct kgsl_device *device)
	unsigned long t;
	uint64_t ts1, ts2, ts3;

	ts1 = read_AO_counter(device);
	ts1 = a6xx_gmu_read_ao_counter(device);

	t = jiffies + msecs_to_jiffies(GMU_IDLE_TIMEOUT);
	do {
@@ -901,7 +901,7 @@ static int a6xx_gmu_wait_for_lowest_idle(struct kgsl_device *device)
		usleep_range(10, 100);
	} while (!time_after(jiffies, t));

	ts2 = read_AO_counter(device);
	ts2 = a6xx_gmu_read_ao_counter(device);
	/* Check one last time */

	gmu_core_regread(device, A6XX_GPU_GMU_CX_GMU_RPMH_POWER_STATE, &reg);
@@ -910,7 +910,7 @@ static int a6xx_gmu_wait_for_lowest_idle(struct kgsl_device *device)
	if (idle_trandition_complete(gmu->idle_level, reg, reg1))
		return 0;

	ts3 = read_AO_counter(device);
	ts3 = a6xx_gmu_read_ao_counter(device);

	/* Collect abort data to help with debugging */
	gmu_core_regread(device, A6XX_GPU_GMU_AO_GPU_CX_BUSY_STATUS, &reg2);
@@ -954,14 +954,14 @@ static int a6xx_gmu_wait_for_idle(struct kgsl_device *device)
	unsigned int status2;
	uint64_t ts1;

	ts1 = read_AO_counter(device);
	ts1 = a6xx_gmu_read_ao_counter(device);
	if (timed_poll_check(device, A6XX_GPU_GMU_AO_GPU_CX_BUSY_STATUS,
			0, GMU_START_TIMEOUT, CXGXCPUBUSYIGNAHB)) {
		gmu_core_regread(device,
				A6XX_GPU_GMU_AO_GPU_CX_BUSY_STATUS2, &status2);
		dev_err(&gmu->pdev->dev,
				"GMU not idling: status2=0x%x %llx %llx\n",
				status2, ts1, read_AO_counter(device));
				status2, ts1, a6xx_gmu_read_ao_counter(device));
		return -ETIMEDOUT;
	}

@@ -1722,6 +1722,31 @@ static int a6xx_gmu_wait_for_active_transition(
	return -ETIMEDOUT;
}

/*
 * a6xx_gmu_read_ao_counter() - Returns the 64bit always on counter value
 *
 * @device: Pointer to KGSL device
 */
u64 a6xx_gmu_read_ao_counter(struct kgsl_device *device)
{
	unsigned int l, h, h1;

	gmu_core_regread(device, A6XX_GMU_CX_GMU_ALWAYS_ON_COUNTER_H, &h);
	gmu_core_regread(device, A6XX_GMU_CX_GMU_ALWAYS_ON_COUNTER_L, &l);
	gmu_core_regread(device, A6XX_GMU_CX_GMU_ALWAYS_ON_COUNTER_H, &h1);

	/*
	 * If there's no change in COUNTER_H we have no overflow so return,
	 * otherwise read COUNTER_L again
	 */

	if (h == h1)
		return (uint64_t) l | ((uint64_t) h << 32);

	gmu_core_regread(device, A6XX_GMU_CX_GMU_ALWAYS_ON_COUNTER_L, &l);
	return (uint64_t) l | ((uint64_t) h1 << 32);
}

struct gmu_dev_ops adreno_a6xx_gmudev = {
	.load_firmware = a6xx_gmu_load_firmware,
	.oob_set = a6xx_gmu_oob_set,
@@ -1739,6 +1764,7 @@ struct gmu_dev_ops adreno_a6xx_gmudev = {
	.snapshot = a6xx_gmu_snapshot,
	.cooperative_reset = a6xx_gmu_cooperative_reset,
	.wait_for_active_transition = a6xx_gmu_wait_for_active_transition,
	.read_ao_counter = a6xx_gmu_read_ao_counter,
	.gmu2host_intr_mask = HFI_IRQ_MASK,
	.gmu_ao_intr_mask = GMU_AO_INT_MASK,
};
+4 −3
Original line number Diff line number Diff line
@@ -259,7 +259,7 @@ static int a6xx_rgmu_wait_for_lowest_idle(struct kgsl_device *device)
	if (rgmu->idle_level != GPU_HW_IFPC)
		return 0;

	ts1 = read_AO_counter(device);
	ts1 = a6xx_gmu_read_ao_counter(device);

	t = jiffies + msecs_to_jiffies(RGMU_IDLE_TIMEOUT);
	do {
@@ -273,7 +273,7 @@ static int a6xx_rgmu_wait_for_lowest_idle(struct kgsl_device *device)
		usleep_range(10, 100);
	} while (!time_after(jiffies, t));

	ts2 = read_AO_counter(device);
	ts2 = a6xx_gmu_read_ao_counter(device);

	/* Do one last read incase it succeeds */
	gmu_core_regread(device,
@@ -282,7 +282,7 @@ static int a6xx_rgmu_wait_for_lowest_idle(struct kgsl_device *device)
	if (reg[0] & GX_GDSC_POWER_OFF)
		return 0;

	ts3 = read_AO_counter(device);
	ts3 = a6xx_gmu_read_ao_counter(device);

	/* Collect abort data to help with debugging */
	gmu_core_regread(device, A6XX_RGMU_CX_PCC_DEBUG, &reg[1]);
@@ -573,6 +573,7 @@ struct gmu_dev_ops adreno_a6xx_rgmudev = {
	.ifpc_show = a6xx_rgmu_ifpc_show,
	.snapshot = a6xx_rgmu_snapshot,
	.halt_execution = a6xx_rgmu_halt_execution,
	.read_ao_counter = a6xx_gmu_read_ao_counter,
	.gmu2host_intr_mask = RGMU_OOB_IRQ_MASK,
	.gmu_ao_intr_mask = RGMU_AO_IRQ_MASK,
};
+10 −0
Original line number Diff line number Diff line
@@ -380,3 +380,13 @@ int gmu_core_dev_wait_for_active_transition(struct kgsl_device *device)

	return 0;
}

u64 gmu_core_dev_read_ao_counter(struct kgsl_device *device)
{
	struct gmu_dev_ops *ops = GMU_DEVICE_OPS(device);

	if (ops && ops->read_ao_counter)
		return ops->read_ao_counter(device);

	return 0;
}
Loading