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

Commit 0f221139 authored by Chintan Pandya's avatar Chintan Pandya
Browse files

iommu: msm: Enable Context caching for MMU-500



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.

Change-Id: Ife23428315ccec01cf40d4d2409b3640a38c20bb
Signed-off-by: default avatarChintan Pandya <cpandya@codeaurora.org>
parent 80e9f3e9
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