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

Commit fd3cc445 authored by Akhil P Oommen's avatar Akhil P Oommen
Browse files

msm: kgsl: Correctly identify faulting UCHE client



Pagefault handler logs incorrect faulting block when the fauling
block is a UCHE client. Fix this by properly decoding the faulting
UCHE client from MID and UCHE_CLIENT_PF register value.

Change-Id: Ia936cb8badcd936eb58052cb1ef10bd57b74c3f6
Signed-off-by: default avatarAkhil P Oommen <akhilpo@codeaurora.org>
parent 364e8d57
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -925,7 +925,7 @@ struct adreno_gpudev {
	void (*gpu_keepalive)(struct adreno_device *adreno_dev,
			bool state);
	bool (*hw_isidle)(struct adreno_device *adreno_dev);
	const char *(*iommu_fault_block)(struct adreno_device *adreno_dev,
	const char *(*iommu_fault_block)(struct kgsl_device *device,
				unsigned int fsynr1);
	int (*reset)(struct kgsl_device *device, int fault);
	int (*soft_reset)(struct adreno_device *adreno_dev);
+50 −31
Original line number Diff line number Diff line
@@ -1309,47 +1309,66 @@ static void a6xx_llc_enable_overrides(struct adreno_device *adreno_dev)
			A6XX_GPU_CX_MISC_SYSTEM_CACHE_CNTL_0, 0x3);
}

static const char *fault_block[8] = {
	[0] = "CP",
	[1] = "UCHE",
	[2] = "VFD",
	[3] = "UCHE",
	[4] = "CCU",
	[5] = "unknown",
	[6] = "CDP Prefetch",
	[7] = "GPMU",
static const char *uche_client[7][3] = {
	{"SP | VSC | VPC | HLSQ | PC | LRZ", "TP", "VFD"},
	{"VSC | VPC | HLSQ | PC | LRZ", "TP | VFD", "SP"},
	{"SP | VPC | HLSQ | PC | LRZ", "TP | VFD", "VSC"},
	{"SP | VSC | HLSQ | PC | LRZ", "TP | VFD", "VPC"},
	{"SP | VSC | VPC | PC | LRZ", "TP | VFD", "HLSQ"},
	{"SP | VSC | VPC | HLSQ | LRZ", "TP | VFD", "PC"},
	{"SP | VSC | VPC | HLSQ | PC", "TP | VFD", "LRZ"},
};

static const char *uche_client[8] = {
	[0] = "VFD",
	[1] = "SP",
	[2] = "VSC",
	[3] = "VPC",
	[4] = "HLSQ",
	[5] = "PC",
	[6] = "LRZ",
	[7] = "unknown",
};
#define SCOOBYDOO 0x5c00bd00

static const char *a6xx_iommu_fault_block(struct adreno_device *adreno_dev,
						unsigned int fsynr1)
static const char *a6xx_fault_block_uche(struct kgsl_device *device,
		unsigned int mid)
{
	struct kgsl_device *device = KGSL_DEVICE(adreno_dev);
	unsigned int client_id;
	unsigned int uche_client_id;
	unsigned int uche_client_id = 0;
	static char str[40];

	client_id = fsynr1 & 0xff;
	mutex_lock(&device->mutex);

	if (client_id >= ARRAY_SIZE(fault_block))
		return "unknown";
	else if (client_id != 3)
		return fault_block[client_id];
	if (!kgsl_state_is_awake(device)) {
		mutex_unlock(&device->mutex);
		return "UCHE: unknown";
	}

	mutex_lock(&device->mutex);
	kgsl_regread(device, A6XX_UCHE_CLIENT_PF, &uche_client_id);
	mutex_unlock(&device->mutex);

	return uche_client[uche_client_id & A6XX_UCHE_CLIENT_PF_CLIENT_ID_MASK];
	/* Ignore the value if the gpu is in IFPC */
	if (uche_client_id == SCOOBYDOO)
		return "UCHE: unknown";

	uche_client_id &= A6XX_UCHE_CLIENT_PF_CLIENT_ID_MASK;
	snprintf(str, sizeof(str), "UCHE: %s",
			uche_client[uche_client_id][mid - 1]);

	return str;
}

static const char *a6xx_iommu_fault_block(struct kgsl_device *device,
		unsigned int fsynr1)
{
	unsigned int mid = fsynr1 & 0xff;

	switch (mid) {
	case 0:
		return "CP";
	case 1:
	case 2:
	case 3:
		return a6xx_fault_block_uche(device, mid);
	case 4:
		return "CCU";
	case 6:
		return "CDP Prefetch";
	case 7:
		return "GPMU";
	}

	return "Unknown";
}

static void a6xx_cp_callback(struct adreno_device *adreno_dev, int bit)
+2 −3
Original line number Diff line number Diff line
@@ -807,8 +807,7 @@ static int kgsl_iommu_fault_handler(struct iommu_domain *domain,
			fsynr1 = KGSL_IOMMU_GET_CTX_REG(ctx, FSYNR1);
			dev_crit(ctx->kgsldev->dev,
				"FAULTING BLOCK: %s\n",
				      gpudev->iommu_fault_block(adreno_dev,
								fsynr1));
				gpudev->iommu_fault_block(device, fsynr1));
		}

		/* Don't print the debug if this is a permissions fault */