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

Commit 8fcf414c 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: Change the pagefault policy immediately"

parents d5ab942b 61a88945
Loading
Loading
Loading
Loading
+20 −3
Original line number Diff line number Diff line
@@ -2079,15 +2079,32 @@ static ssize_t _ft_pagefault_policy_store(struct device *dev,
				     const char *buf, size_t count)
{
	struct adreno_device *adreno_dev = _get_adreno_dev(dev);
	int ret;
	int ret = 0;
	unsigned int policy = 0;
	if (adreno_dev == NULL)
		return 0;

	mutex_lock(&adreno_dev->dev.mutex);
	ret = kgsl_sysfs_store(buf, count, &adreno_dev->ft_pf_policy);
	/* MMU option changed call function to reset MMU options */
	if (count != kgsl_sysfs_store(buf, count, &policy))
		ret = -EINVAL;

	if (!ret) {
		policy &= (KGSL_FT_PAGEFAULT_INT_ENABLE |
				KGSL_FT_PAGEFAULT_GPUHALT_ENABLE |
				KGSL_FT_PAGEFAULT_LOG_ONE_PER_PAGE |
				KGSL_FT_PAGEFAULT_LOG_ONE_PER_INT);
		ret = kgsl_mmu_set_pagefault_policy(&(adreno_dev->dev.mmu),
				adreno_dev->ft_pf_policy);
		if (!ret)
			adreno_dev->ft_pf_policy = policy;
	}
	mutex_unlock(&adreno_dev->dev.mutex);

	return ret;
	if (!ret)
		return count;
	else
		return 0;
}

/**
+67 −0
Original line number Diff line number Diff line
@@ -2039,6 +2039,72 @@ static int kgsl_iommu_get_num_iommu_units(struct kgsl_mmu *mmu)
	return iommu->unit_count;
}

/*
 * kgsl_iommu_set_pf_policy() - Set the pagefault policy for IOMMU
 * @mmu: Pointer to mmu structure
 * @pf_policy: The pagefault polict to set
 *
 * Check if the new policy indicated by pf_policy is same as current
 * policy, if same then return else set the policy
 */
static int kgsl_iommu_set_pf_policy(struct kgsl_mmu *mmu,
				unsigned int pf_policy)
{
	int i, j;
	struct kgsl_iommu *iommu = mmu->priv;
	struct adreno_device *adreno_dev = ADRENO_DEVICE(mmu->device);
	int ret = 0;
	unsigned int sctlr_val;

	if ((adreno_dev->ft_pf_policy & KGSL_FT_PAGEFAULT_GPUHALT_ENABLE) ==
		(pf_policy & KGSL_FT_PAGEFAULT_GPUHALT_ENABLE))
		return ret;
	if (msm_soc_version_supports_iommu_v0())
		return ret;

	ret = kgsl_iommu_enable_clk(mmu, KGSL_IOMMU_CONTEXT_USER);

	if (ret) {
		KGSL_DRV_ERR(mmu->device, "Failed to enable iommu clocks\n");
		return ret;
	}
	ret = kgsl_iommu_enable_clk(mmu, KGSL_IOMMU_CONTEXT_PRIV);

	if (ret) {
		KGSL_DRV_ERR(mmu->device, "Failed to enable iommu clocks\n");
		kgsl_iommu_disable_clk_on_ts(mmu, 0, false);
		return ret;
	}
	/* Need to idle device before changing options */
	ret = mmu->device->ftbl->idle(mmu->device);
	if (ret) {
		kgsl_iommu_disable_clk_on_ts(mmu, 0, false);
		return ret;
	}

	for (i = 0; i < iommu->unit_count; i++) {
		struct kgsl_iommu_unit *iommu_unit = &iommu->iommu_units[i];
		for (j = 0; j < iommu_unit->dev_count; j++) {
			sctlr_val = KGSL_IOMMU_GET_CTX_REG(iommu,
					iommu_unit,
					iommu_unit->dev[j].ctx_id,
					SCTLR);
			if (pf_policy & KGSL_FT_PAGEFAULT_GPUHALT_ENABLE)
				sctlr_val &= ~(0x1 <<
					KGSL_IOMMU_SCTLR_HUPCF_SHIFT);
			else
				sctlr_val |= (0x1 <<
					KGSL_IOMMU_SCTLR_HUPCF_SHIFT);
			KGSL_IOMMU_SET_CTX_REG(iommu,
					iommu_unit,
					iommu_unit->dev[j].ctx_id,
					SCTLR, sctlr_val);
		}
	}
	kgsl_iommu_disable_clk_on_ts(mmu, 0, false);
	return ret;
}

struct kgsl_mmu_ops iommu_ops = {
	.mmu_init = kgsl_iommu_init,
	.mmu_close = kgsl_iommu_close,
@@ -2064,6 +2130,7 @@ struct kgsl_mmu_ops iommu_ops = {
	.mmu_cleanup_pt = NULL,
	.mmu_sync_lock = kgsl_iommu_sync_lock,
	.mmu_sync_unlock = kgsl_iommu_sync_unlock,
	.mmu_set_pf_policy = kgsl_iommu_set_pf_policy,
};

struct kgsl_mmu_pt_ops iommu_pt_ops = {
+11 −1
Original line number Diff line number Diff line
/* Copyright (c) 2002,2007-2013, The Linux Foundation. All rights reserved.
/* Copyright (c) 2002,2007-2014, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
@@ -128,6 +128,7 @@ struct kgsl_mmu_ops {
	unsigned int (*mmu_sync_unlock)
			(struct kgsl_mmu *mmu, unsigned int *cmds);
	int (*mmu_hw_halt_supported)(struct kgsl_mmu *mmu, int iommu_unit_num);
	int (*mmu_set_pf_policy)(struct kgsl_mmu *mmu, unsigned int pf_policy);
};

struct kgsl_mmu_pt_ops {
@@ -415,4 +416,13 @@ static inline int kgsl_mmu_sync_unlock(struct kgsl_mmu *mmu,
		return 0;
}

static inline int kgsl_mmu_set_pagefault_policy(struct kgsl_mmu *mmu,
						unsigned int pf_policy)
{
	if (mmu->mmu_ops && mmu->mmu_ops->mmu_set_pf_policy)
		return mmu->mmu_ops->mmu_set_pf_policy(mmu, pf_policy);
	else
		return 0;
}

#endif /* __KGSL_MMU_H */