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

Commit 8e842076 authored by Jordan Crouse's avatar Jordan Crouse
Browse files

msm: kgsl: Detect missing per-process pagetable support and fallback



Per-process pagetable support might be disabled in the arm-smmu driver for
any number of reasons but we won't know it until we try to create our
first dynamic domain. If enabling the dynamic domain returns -EOPNOTSUPP
then disable per-process pagetables and fall back to global pagetables.

Also, demote a WARN to a log-once message when the arm-smmu driver doesn't
support the system cache no-write-allocate tag.

Change-Id: Ic0dedbadb66fc862eeb9cd585ade9edc1d178c77
Signed-off-by: default avatarJordan Crouse <jcrouse@codeaurora.org>
parent 87ff01a7
Loading
Loading
Loading
Loading
+29 −9
Original line number Diff line number Diff line
@@ -1059,6 +1059,7 @@ static void _free_pt(struct kgsl_iommu_context *ctx, struct kgsl_pagetable *pt)
static void _enable_gpuhtw_llc(struct kgsl_mmu *mmu,
		struct iommu_domain *domain)
{
	struct kgsl_device *device = KGSL_MMU_DEVICE(mmu);
	int attr, ret;
	u32 val = 1;

@@ -1072,12 +1073,10 @@ static void _enable_gpuhtw_llc(struct kgsl_mmu *mmu,

	ret = iommu_domain_set_attr(domain, attr, &val);

	/*
	 * Warn once if the system cache will not be used for GPU
	 * pagetable walks. This is not a fatal error.
	 */
	WARN_ONCE(ret, "System cache not enabled for GPU pagetable walks: %d\n",
		ret);
	/* Print a one time error message if system cache isn't enabled */
	if (ret)
		dev_err_once(device->dev,
			"System cache no-write-alloc is disabled for GPU pagetables\n");
}

static int set_smmu_aperture(struct kgsl_device *device, int cb_num)
@@ -1302,7 +1301,13 @@ static int _init_per_process_pt(struct kgsl_mmu *mmu, struct kgsl_pagetable *pt)

	ret = iommu_domain_set_attr(iommu_pt->domain,
				DOMAIN_ATTR_DYNAMIC, &dynamic);

	/*
	 * If -ENOTSUPP then dynamic pagetables aren't supported. Quietly
	 * return the error and the upper levels will handle it
	 */
	if (ret) {
		if (ret != -ENOTSUPP)
			dev_err(device->dev,
				"set DOMAIN_ATTR_DYNAMIC failed: %d\n", ret);
		goto done;
@@ -1383,6 +1388,7 @@ static int kgsl_iommu_init_pt(struct kgsl_mmu *mmu, struct kgsl_pagetable *pt)
static struct kgsl_pagetable *kgsl_iommu_getpagetable(struct kgsl_mmu *mmu,
		unsigned long name)
{
	struct kgsl_device *device = KGSL_MMU_DEVICE(mmu);
	struct kgsl_pagetable *pt;

	if (!kgsl_mmu_is_perprocess(mmu) && (name != KGSL_MMU_SECURE_PT) &&
@@ -1393,9 +1399,23 @@ static struct kgsl_pagetable *kgsl_iommu_getpagetable(struct kgsl_mmu *mmu,
	}

	pt = kgsl_get_pagetable(name);
	if (pt == NULL)
	if (pt == NULL) {
		pt = kgsl_mmu_createpagetableobject(mmu, name);

		/*
		 * Special fallback case -if we get ENOTSUPP that means that
		 * per-process pagetables are not supported by arm-smmu. This
		 * should happen on the first try so we safely set the global
		 * pagetable bit and avoid going down this path again
		 */
		if (PTR_ERR_OR_ZERO(pt) == -ENOTSUPP) {
			dev_err_once(device->dev,
				"Couldn't enable per-process pagetables. Default to global pagetables\n");
			set_bit(KGSL_MMU_GLOBAL_PAGETABLE, &mmu->features);
			return mmu->defaultpagetable;
		}
	}

	return pt;
}