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

Commit 09bc7dfa authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "msm: kgsl: Print out the GPU block causing a pagefault" into msm-4.9

parents 1dc5ec74 1fde74d4
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -537,6 +537,8 @@
#define A6XX_UCHE_GMEM_RANGE_MAX_HI         0xE0E
#define A6XX_UCHE_CACHE_WAYS                0xE17
#define A6XX_UCHE_FILTER_CNTL               0xE18
#define A6XX_UCHE_CLIENT_PF                 0xE19
#define A6XX_UCHE_CLIENT_PF_CLIENT_ID_MASK  0x7
#define A6XX_UCHE_PERFCTR_UCHE_SEL_0        0xE1C
#define A6XX_UCHE_PERFCTR_UCHE_SEL_1        0xE1D
#define A6XX_UCHE_PERFCTR_UCHE_SEL_2        0xE1E
+2 −0
Original line number Diff line number Diff line
@@ -856,6 +856,8 @@ struct adreno_gpudev {
				unsigned int arg1, unsigned int arg2);
	bool (*hw_isidle)(struct adreno_device *);
	int (*wait_for_gmu_idle)(struct adreno_device *);
	const char *(*iommu_fault_block)(struct adreno_device *adreno_dev,
				unsigned int fsynr1);
};

/**
+44 −1
Original line number Diff line number Diff line
@@ -285,6 +285,8 @@ static void a6xx_start(struct adreno_device *adreno_dev)
	kgsl_regwrite(device, A6XX_RBBM_INTERFACE_HANG_INT_CNTL,
					  (1 << 30) | 0x4000);

	kgsl_regwrite(device, A6XX_UCHE_CLIENT_PF, 1);

	/* Set TWOPASSUSEWFI in A6XX_PC_DBG_ECO_CNTL if requested */
	if (ADRENO_QUIRK(adreno_dev, ADRENO_QUIRK_TWO_PASS_USE_WFI))
		kgsl_regrmw(device, A6XX_PC_DBG_ECO_CNTL, 0, (1 << 8));
@@ -1522,6 +1524,46 @@ static void a6xx_llc_enable_overrides(struct adreno_device *adreno_dev)
	iounmap(gpu_cx_reg);
}

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[8] = {
	[0] = "VFD",
	[1] = "SP",
	[2] = "VSC",
	[3] = "VPC",
	[4] = "HLSQ",
	[5] = "PC",
	[6] = "LRZ",
	[7] = "unknown",
};

static const char *a6xx_iommu_fault_block(struct adreno_device *adreno_dev,
						unsigned int fsynr1)
{
	struct kgsl_device *device = KGSL_DEVICE(adreno_dev);
	unsigned int client_id;
	unsigned int uche_client_id;

	client_id = fsynr1 & 0xff;

	if (client_id >= ARRAY_SIZE(fault_block))
		return "unknown";
	else if (client_id != 3)
		return fault_block[client_id];

	kgsl_regread(device, A6XX_UCHE_CLIENT_PF, &uche_client_id);
	return uche_client[uche_client_id & A6XX_UCHE_CLIENT_PF_CLIENT_ID_MASK];
}

#define A6XX_INT_MASK \
	((1 << A6XX_INT_CP_AHB_ERROR) |			\
	 (1 << A6XX_INT_ATB_ASYNCFIFO_OVERFLOW) |	\
@@ -2078,5 +2120,6 @@ struct adreno_gpudev adreno_a6xx_gpudev = {
	.oob_clear = a6xx_oob_clear,
	.rpmh_gpu_pwrctrl = a6xx_rpmh_gpu_pwrctrl,
	.hw_isidle = a6xx_hw_isidle, /* Replaced by NULL if GMU is disabled */
	.wait_for_gmu_idle = a6xx_wait_for_gmu_idle
	.wait_for_gmu_idle = a6xx_wait_for_gmu_idle,
	.iommu_fault_block = a6xx_iommu_fault_block,
};
+12 −0
Original line number Diff line number Diff line
@@ -797,6 +797,7 @@ static int kgsl_iommu_fault_handler(struct iommu_domain *domain,
	int write;
	struct kgsl_device *device;
	struct adreno_device *adreno_dev;
	struct adreno_gpudev *gpudev;
	unsigned int no_page_fault_log = 0;
	unsigned int curr_context_id = 0;
	struct kgsl_context *context;
@@ -813,6 +814,7 @@ static int kgsl_iommu_fault_handler(struct iommu_domain *domain,
	ctx = &iommu->ctx[KGSL_IOMMU_CONTEXT_USER];
	device = KGSL_MMU_DEVICE(mmu);
	adreno_dev = ADRENO_DEVICE(device);
	gpudev = ADRENO_GPU_DEVICE(adreno_dev);

	if (pt->name == KGSL_MMU_SECURE_PT)
		ctx = &iommu->ctx[KGSL_IOMMU_CONTEXT_SECURE];
@@ -886,6 +888,16 @@ static int kgsl_iommu_fault_handler(struct iommu_domain *domain,
			ctx->name, ptbase, contextidr,
			write ? "write" : "read", fault_type);

		if (gpudev->iommu_fault_block) {
			unsigned int fsynr1;

			fsynr1 = KGSL_IOMMU_GET_CTX_REG(ctx, FSYNR1);
			KGSL_MEM_CRIT(ctx->kgsldev,
				"FAULTING BLOCK: %s\n",
				gpudev->iommu_fault_block(adreno_dev,
								fsynr1));
		}

		/* Don't print the debug if this is a permissions fault */
		if (!(flags & IOMMU_FAULT_PERMISSION)) {
			_check_if_freed(ctx, addr, ptname);