From b837708dfc9c28464cd124531f33375c7bc81b54 Mon Sep 17 00:00:00 2001 From: Carter Cooper Date: Thu, 20 Jun 2013 12:39:28 -0700 Subject: [PATCH] msm: kgsl: Option to not stall IOMMU V1 on pagefault based on FT policy There are cases where GPU has a pagefault and executes fine after pagefault without GPU stall. init.qcom.graphics.sh script can be used to change FT pagefault policy to not stall IOMMU V1 on pagefault and check if pagefault is harmless. Change-Id: If061230b66181bfd94c697ea106e7bf4de352e91 Signed-off-by: Tarun Karra Signed-off-by: Carter Cooper --- drivers/gpu/msm/kgsl_iommu.c | 23 +++++++++++++++++++++++ drivers/gpu/msm/kgsl_iommu.h | 4 ++++ 2 files changed, 27 insertions(+) diff --git a/drivers/gpu/msm/kgsl_iommu.c b/drivers/gpu/msm/kgsl_iommu.c index 091e3e53622c..b30ab0224939 100644 --- a/drivers/gpu/msm/kgsl_iommu.c +++ b/drivers/gpu/msm/kgsl_iommu.c @@ -38,6 +38,7 @@ static struct kgsl_iommu_register_list kgsl_iommuv0_reg[KGSL_IOMMU_REG_MAX] = { { 0, 0 }, /* GLOBAL_BASE */ + { 0x0, 1 }, /* SCTLR */ { 0x10, 1 }, /* TTBR0 */ { 0x14, 1 }, /* TTBR1 */ { 0x20, 1 }, /* FSR */ @@ -54,6 +55,7 @@ static struct kgsl_iommu_register_list kgsl_iommuv0_reg[KGSL_IOMMU_REG_MAX] = { static struct kgsl_iommu_register_list kgsl_iommuv1_reg[KGSL_IOMMU_REG_MAX] = { { 0, 0 }, /* GLOBAL_BASE */ + { 0x0, 1 }, /* SCTLR */ { 0x20, 1 }, /* TTBR0 */ { 0x28, 1 }, /* TTBR1 */ { 0x58, 1 }, /* FSR */ @@ -1558,6 +1560,8 @@ static int kgsl_iommu_start(struct kgsl_mmu *mmu) int status; struct kgsl_iommu *iommu = mmu->priv; int i, j; + int sctlr_val = 0; + struct adreno_device *adreno_dev = ADRENO_DEVICE(mmu->device); if (mmu->flags & KGSL_FLAGS_STARTED) return 0; @@ -1614,6 +1618,25 @@ static int kgsl_iommu_start(struct kgsl_mmu *mmu) 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++) { + + /* + * For IOMMU V1 do not halt IOMMU on pagefault if + * FT pagefault policy is set accordingly + */ + if ((!msm_soc_version_supports_iommu_v1()) && + (!(adreno_dev->ft_pf_policy & + KGSL_FT_PAGEFAULT_GPUHALT_ENABLE))) { + sctlr_val = KGSL_IOMMU_GET_CTX_REG(iommu, + iommu_unit, + iommu_unit->dev[j].ctx_id, + SCTLR); + 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); + } if (sizeof(phys_addr_t) > sizeof(unsigned long)) { iommu_unit->dev[j].default_ttbr0 = KGSL_IOMMU_GET_CTX_REG_LL(iommu, diff --git a/drivers/gpu/msm/kgsl_iommu.h b/drivers/gpu/msm/kgsl_iommu.h index 5c4b17ebdad8..7dca40e2c986 100644 --- a/drivers/gpu/msm/kgsl_iommu.h +++ b/drivers/gpu/msm/kgsl_iommu.h @@ -61,8 +61,12 @@ #define KGSL_IOMMU_IMPLDEF_MICRO_MMU_CTRL_HALT BIT(2) #define KGSL_IOMMU_IMPLDEF_MICRO_MMU_CTRL_IDLE BIT(3) +/* SCTLR fields */ +#define KGSL_IOMMU_SCTLR_HUPCF_SHIFT 8 + enum kgsl_iommu_reg_map { KGSL_IOMMU_GLOBAL_BASE = 0, + KGSL_IOMMU_CTX_SCTLR, KGSL_IOMMU_CTX_TTBR0, KGSL_IOMMU_CTX_TTBR1, KGSL_IOMMU_CTX_FSR,