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

Commit 4df11675 authored by Chintan Pandya's avatar Chintan Pandya
Browse files

iommu: msm: Re-enable Context caching for MMU-500



Original intent:

MMU-500 implements context caching in TLBs and prefetch
buffers of IOMMU. Enabling them would boost performance.
But this implementation is different from what present
SMMU driver expects. So, configure auxiliary registers
for MMU-500.

Reason for re-enable:

Context caching was reverted due to strange issues of
Permission faults at SMMU when this was enabled. Now,
that issue is fixed. Re-enable this feature for
performance needs.

Change-Id: I63829358e501d4c6f7526d5b59a31ab23b1cd0d8
Signed-off-by: default avatarChintan Pandya <cpandya@codeaurora.org>
parent 236cef42
Loading
Loading
Loading
Loading
+45 −16
Original line number Diff line number Diff line
@@ -408,10 +408,15 @@ fail:
/*
 * May only be called for non-secure iommus
 */
static void __reset_iommu(void __iomem *base)
static void __reset_iommu(struct msm_iommu_drvdata *iommu_drvdata)
{
	int i, smt_size;
	void __iomem *base = iommu_drvdata->base;

	/* SMMU_ACR is an implementation defined register.
	 * Resetting is not required for some implementation.
	 */
	if (iommu_drvdata->model != MMU_500)
		SET_ACR(base, 0);
	SET_CR2(base, 0);
	SET_GFAR(base, 0);
@@ -425,8 +430,11 @@ static void __reset_iommu(void __iomem *base)
	mb();
}

static void __reset_iommu_secure(void __iomem *base)
static void __reset_iommu_secure(struct msm_iommu_drvdata *iommu_drvdata)
{
	void __iomem *base = iommu_drvdata->base;

	if (iommu_drvdata->model != MMU_500)
		SET_NSACR(base, 0);
	SET_NSCR2(base, 0);
	SET_NSGFAR(base, 0);
@@ -434,8 +442,15 @@ static void __reset_iommu_secure(void __iomem *base)
	mb();
}

static void __program_iommu_secure(void __iomem *base)
static void __program_iommu_secure(struct msm_iommu_drvdata *iommu_drvdata)
{
	void __iomem *base = iommu_drvdata->base;

	if (iommu_drvdata->model == MMU_500) {
		SET_NSACR_SMTNMC_BPTLBEN(base, 1);
		SET_NSACR_MMUDIS_BPTLBEN(base, 1);
		SET_NSACR_S2CR_BPTLBEN(base, 1);
	}
	SET_NSCR0_SMCFCFG(base, 1);
	SET_NSCR0_USFCFG(base, 1);
	SET_NSCR0_STALLD(base, 1);
@@ -451,11 +466,16 @@ static void __program_iommu_secure(void __iomem *base)
 */
static void __program_iommu(struct msm_iommu_drvdata *drvdata)
{
	__reset_iommu(drvdata->base);
	__reset_iommu(drvdata);

	if (!msm_iommu_get_scm_call_avail())
		__reset_iommu_secure(drvdata->base);
		__reset_iommu_secure(drvdata);

	if (drvdata->model == MMU_500) {
		SET_ACR_SMTNMC_BPTLBEN(drvdata->base, 1);
		SET_ACR_MMUDIS_BPTLBEN(drvdata->base, 1);
		SET_ACR_S2CR_BPTLBEN(drvdata->base, 1);
	}
	SET_CR0_SMCFCFG(drvdata->base, 1);
	SET_CR0_USFCFG(drvdata->base, 1);
	SET_CR0_STALLD(drvdata->base, 1);
@@ -466,7 +486,7 @@ static void __program_iommu(struct msm_iommu_drvdata *drvdata)
	SET_CR0_CLIENTPD(drvdata->base, 0);

	if (!msm_iommu_get_scm_call_avail())
		__program_iommu_secure(drvdata->base);
		__program_iommu_secure(drvdata);

	if (drvdata->smmu_local_base)
		writel_relaxed(0xFFFFFFFF, drvdata->smmu_local_base +
@@ -487,8 +507,15 @@ void program_iommu_bfb_settings(void __iomem *base,
	mb(); /* Make sure writes complete before returning */
}

static void __reset_context(void __iomem *base, int ctx)
static void __reset_context(struct msm_iommu_drvdata *iommu_drvdata, int ctx)
{
	void __iomem *base = iommu_drvdata->cb_base;

	/* Don't set ACTLR to zero because if context bank is in
	 * bypass mode (say after iommu_detach), still this ACTLR
	 * value matters for micro-TLB caching.
	 */
	if (iommu_drvdata->model != MMU_500)
		SET_ACTLR(base, ctx, 0);
	SET_FAR(base, ctx, 0);
	SET_FSRRESTORE(base, ctx, 0);
@@ -669,7 +696,7 @@ static void __program_context(struct msm_iommu_drvdata *iommu_drvdata,
	unsigned int ctx = ctx_drvdata->num;
	phys_addr_t pgtable = __pa(priv->pt.fl_table);

	__reset_context(cb_base, ctx);
	__reset_context(iommu_drvdata, ctx);
	msm_iommu_setup_ctx(cb_base, ctx);

	if (priv->pt.redirect)
@@ -683,10 +710,12 @@ static void __program_context(struct msm_iommu_drvdata *iommu_drvdata,
	/* Enable context fault interrupt */
	SET_CB_SCTLR_CFIE(cb_base, ctx, 1);

	if (iommu_drvdata->model != MMU_500) {
		/* Redirect all cacheable requests to L2 slave port. */
		SET_CB_ACTLR_BPRCISH(cb_base, ctx, 1);
		SET_CB_ACTLR_BPRCOSH(cb_base, ctx, 1);
		SET_CB_ACTLR_BPRCNSH(cb_base, ctx, 1);
	}

	/* Enable private ASID namespace */
	SET_CB_SCTLR_ASIDPNE(cb_base, ctx, 1);
@@ -899,7 +928,7 @@ static void msm_iommu_detach_dev(struct iommu_domain *domain,
	iommu_drvdata->asid[ctx_drvdata->asid - 1]--;
	ctx_drvdata->asid = -1;

	__reset_context(iommu_drvdata->cb_base, ctx_drvdata->num);
	__reset_context(iommu_drvdata, ctx_drvdata->num);

	/*
	 * Only reset the M2V tables on the very last detach */
+34 −0
Original line number Diff line number Diff line
@@ -277,6 +277,20 @@ do { \
#define SET_CR0_CLIENTPD(b, v)     SET_GLOBAL_FIELD(b, CR0, CLIENTPD, v)
#define SET_NSCR0_CLIENTPD(b, v)   SET_GLOBAL_FIELD(b, NSCR0, CLIENTPD, v)

#define SET_ACR_SMTNMC_BPTLBEN(b, v)\
	SET_GLOBAL_FIELD(b, ACR, SMTNMC_BPTLBEN, v)
#define SET_ACR_MMUDIS_BPTLBEN(b, v)\
	SET_GLOBAL_FIELD(b, ACR, MMUDIS_BPTLBEN, v)
#define SET_ACR_S2CR_BPTLBEN(b, v)\
	SET_GLOBAL_FIELD(b, ACR, S2CR_BPTLBEN, v)

#define SET_NSACR_SMTNMC_BPTLBEN(b, v)\
	SET_GLOBAL_FIELD(b, NSACR, SMTNMC_BPTLBEN, v)
#define SET_NSACR_MMUDIS_BPTLBEN(b, v)\
	SET_GLOBAL_FIELD(b, NSACR, MMUDIS_BPTLBEN, v)
#define SET_NSACR_S2CR_BPTLBEN(b, v)\
	SET_GLOBAL_FIELD(b, NSACR, S2CR_BPTLBEN, v)

#define GET_CR0_NSCFG(b)           GET_GLOBAL_FIELD(b, CR0, NSCFG)
#define GET_CR0_WACFG(b)           GET_GLOBAL_FIELD(b, CR0, WACFG)
#define GET_CR0_RACFG(b)           GET_GLOBAL_FIELD(b, CR0, RACFG)
@@ -1541,6 +1555,16 @@ do { \
#define CR0_CLIENTPD_MASK       0x01
#define NSCR0_CLIENTPD_MASK     0x01

/* ACR */
#define ACR_SMTNMC_BPTLBEN_MASK   0x01
#define ACR_MMUDIS_BPTLBEN_MASK   0x01
#define ACR_S2CR_BPTLBEN_MASK     0x01

/* NSACR */
#define NSACR_SMTNMC_BPTLBEN_MASK   0x01
#define NSACR_MMUDIS_BPTLBEN_MASK   0x01
#define NSACR_S2CR_BPTLBEN_MASK     0x01

/* Configuration Register 2 */
#define CR2_BPVMID_MASK         0xFF

@@ -1928,6 +1952,16 @@ do { \
#define CR0_CLIENTPD_SHIFT         0
#define NSCR0_CLIENTPD_SHIFT       0

/* ACR */
#define ACR_SMTNMC_BPTLBEN_SHIFT   8
#define ACR_MMUDIS_BPTLBEN_SHIFT   9
#define ACR_S2CR_BPTLBEN_SHIFT     10

/* NSACR */
#define NSACR_SMTNMC_BPTLBEN_SHIFT   8
#define NSACR_MMUDIS_BPTLBEN_SHIFT   9
#define NSACR_S2CR_BPTLBEN_SHIFT     10

/* Configuration Register: CR2 */
#define CR2_BPVMID_SHIFT           0