Loading drivers/gpu/msm/a6xx_reg.h +2 −0 Original line number Diff line number Diff line Loading @@ -537,6 +537,8 @@ #define A6XX_UCHE_GMEM_RANGE_MAX_HI 0xE0E #define A6XX_UCHE_CACHE_WAYS 0xE17 #define A6XX_UCHE_FILTER_CNTL 0xE18 #define A6XX_UCHE_CLIENT_PF 0xE19 #define A6XX_UCHE_CLIENT_PF_CLIENT_ID_MASK 0x7 #define A6XX_UCHE_PERFCTR_UCHE_SEL_0 0xE1C #define A6XX_UCHE_PERFCTR_UCHE_SEL_1 0xE1D #define A6XX_UCHE_PERFCTR_UCHE_SEL_2 0xE1E Loading drivers/gpu/msm/adreno.h +2 −0 Original line number Diff line number Diff line Loading @@ -856,6 +856,8 @@ struct adreno_gpudev { unsigned int arg1, unsigned int arg2); bool (*hw_isidle)(struct adreno_device *); int (*wait_for_gmu_idle)(struct adreno_device *); const char *(*iommu_fault_block)(struct adreno_device *adreno_dev, unsigned int fsynr1); }; /** Loading drivers/gpu/msm/adreno_a6xx.c +44 −1 Original line number Diff line number Diff line Loading @@ -285,6 +285,8 @@ static void a6xx_start(struct adreno_device *adreno_dev) kgsl_regwrite(device, A6XX_RBBM_INTERFACE_HANG_INT_CNTL, (1 << 30) | 0x4000); kgsl_regwrite(device, A6XX_UCHE_CLIENT_PF, 1); /* Set TWOPASSUSEWFI in A6XX_PC_DBG_ECO_CNTL if requested */ if (ADRENO_QUIRK(adreno_dev, ADRENO_QUIRK_TWO_PASS_USE_WFI)) kgsl_regrmw(device, A6XX_PC_DBG_ECO_CNTL, 0, (1 << 8)); Loading Loading @@ -1522,6 +1524,46 @@ static void a6xx_llc_enable_overrides(struct adreno_device *adreno_dev) iounmap(gpu_cx_reg); } static const char *fault_block[8] = { [0] = "CP", [1] = "UCHE", [2] = "VFD", [3] = "UCHE", [4] = "CCU", [5] = "unknown", [6] = "CDP Prefetch", [7] = "GPMU", }; static const char *uche_client[8] = { [0] = "VFD", [1] = "SP", [2] = "VSC", [3] = "VPC", [4] = "HLSQ", [5] = "PC", [6] = "LRZ", [7] = "unknown", }; static const char *a6xx_iommu_fault_block(struct adreno_device *adreno_dev, unsigned int fsynr1) { struct kgsl_device *device = KGSL_DEVICE(adreno_dev); unsigned int client_id; unsigned int uche_client_id; client_id = fsynr1 & 0xff; if (client_id >= ARRAY_SIZE(fault_block)) return "unknown"; else if (client_id != 3) return fault_block[client_id]; kgsl_regread(device, A6XX_UCHE_CLIENT_PF, &uche_client_id); return uche_client[uche_client_id & A6XX_UCHE_CLIENT_PF_CLIENT_ID_MASK]; } #define A6XX_INT_MASK \ ((1 << A6XX_INT_CP_AHB_ERROR) | \ (1 << A6XX_INT_ATB_ASYNCFIFO_OVERFLOW) | \ Loading Loading @@ -2078,5 +2120,6 @@ struct adreno_gpudev adreno_a6xx_gpudev = { .oob_clear = a6xx_oob_clear, .rpmh_gpu_pwrctrl = a6xx_rpmh_gpu_pwrctrl, .hw_isidle = a6xx_hw_isidle, /* Replaced by NULL if GMU is disabled */ .wait_for_gmu_idle = a6xx_wait_for_gmu_idle .wait_for_gmu_idle = a6xx_wait_for_gmu_idle, .iommu_fault_block = a6xx_iommu_fault_block, }; drivers/gpu/msm/kgsl_iommu.c +12 −0 Original line number Diff line number Diff line Loading @@ -797,6 +797,7 @@ static int kgsl_iommu_fault_handler(struct iommu_domain *domain, int write; struct kgsl_device *device; struct adreno_device *adreno_dev; struct adreno_gpudev *gpudev; unsigned int no_page_fault_log = 0; unsigned int curr_context_id = 0; struct kgsl_context *context; Loading @@ -813,6 +814,7 @@ static int kgsl_iommu_fault_handler(struct iommu_domain *domain, ctx = &iommu->ctx[KGSL_IOMMU_CONTEXT_USER]; device = KGSL_MMU_DEVICE(mmu); adreno_dev = ADRENO_DEVICE(device); gpudev = ADRENO_GPU_DEVICE(adreno_dev); if (pt->name == KGSL_MMU_SECURE_PT) ctx = &iommu->ctx[KGSL_IOMMU_CONTEXT_SECURE]; Loading Loading @@ -886,6 +888,16 @@ static int kgsl_iommu_fault_handler(struct iommu_domain *domain, ctx->name, ptbase, contextidr, write ? "write" : "read", fault_type); if (gpudev->iommu_fault_block) { unsigned int fsynr1; fsynr1 = KGSL_IOMMU_GET_CTX_REG(ctx, FSYNR1); KGSL_MEM_CRIT(ctx->kgsldev, "FAULTING BLOCK: %s\n", gpudev->iommu_fault_block(adreno_dev, fsynr1)); } /* Don't print the debug if this is a permissions fault */ if (!(flags & IOMMU_FAULT_PERMISSION)) { _check_if_freed(ctx, addr, ptname); Loading Loading
drivers/gpu/msm/a6xx_reg.h +2 −0 Original line number Diff line number Diff line Loading @@ -537,6 +537,8 @@ #define A6XX_UCHE_GMEM_RANGE_MAX_HI 0xE0E #define A6XX_UCHE_CACHE_WAYS 0xE17 #define A6XX_UCHE_FILTER_CNTL 0xE18 #define A6XX_UCHE_CLIENT_PF 0xE19 #define A6XX_UCHE_CLIENT_PF_CLIENT_ID_MASK 0x7 #define A6XX_UCHE_PERFCTR_UCHE_SEL_0 0xE1C #define A6XX_UCHE_PERFCTR_UCHE_SEL_1 0xE1D #define A6XX_UCHE_PERFCTR_UCHE_SEL_2 0xE1E Loading
drivers/gpu/msm/adreno.h +2 −0 Original line number Diff line number Diff line Loading @@ -856,6 +856,8 @@ struct adreno_gpudev { unsigned int arg1, unsigned int arg2); bool (*hw_isidle)(struct adreno_device *); int (*wait_for_gmu_idle)(struct adreno_device *); const char *(*iommu_fault_block)(struct adreno_device *adreno_dev, unsigned int fsynr1); }; /** Loading
drivers/gpu/msm/adreno_a6xx.c +44 −1 Original line number Diff line number Diff line Loading @@ -285,6 +285,8 @@ static void a6xx_start(struct adreno_device *adreno_dev) kgsl_regwrite(device, A6XX_RBBM_INTERFACE_HANG_INT_CNTL, (1 << 30) | 0x4000); kgsl_regwrite(device, A6XX_UCHE_CLIENT_PF, 1); /* Set TWOPASSUSEWFI in A6XX_PC_DBG_ECO_CNTL if requested */ if (ADRENO_QUIRK(adreno_dev, ADRENO_QUIRK_TWO_PASS_USE_WFI)) kgsl_regrmw(device, A6XX_PC_DBG_ECO_CNTL, 0, (1 << 8)); Loading Loading @@ -1522,6 +1524,46 @@ static void a6xx_llc_enable_overrides(struct adreno_device *adreno_dev) iounmap(gpu_cx_reg); } static const char *fault_block[8] = { [0] = "CP", [1] = "UCHE", [2] = "VFD", [3] = "UCHE", [4] = "CCU", [5] = "unknown", [6] = "CDP Prefetch", [7] = "GPMU", }; static const char *uche_client[8] = { [0] = "VFD", [1] = "SP", [2] = "VSC", [3] = "VPC", [4] = "HLSQ", [5] = "PC", [6] = "LRZ", [7] = "unknown", }; static const char *a6xx_iommu_fault_block(struct adreno_device *adreno_dev, unsigned int fsynr1) { struct kgsl_device *device = KGSL_DEVICE(adreno_dev); unsigned int client_id; unsigned int uche_client_id; client_id = fsynr1 & 0xff; if (client_id >= ARRAY_SIZE(fault_block)) return "unknown"; else if (client_id != 3) return fault_block[client_id]; kgsl_regread(device, A6XX_UCHE_CLIENT_PF, &uche_client_id); return uche_client[uche_client_id & A6XX_UCHE_CLIENT_PF_CLIENT_ID_MASK]; } #define A6XX_INT_MASK \ ((1 << A6XX_INT_CP_AHB_ERROR) | \ (1 << A6XX_INT_ATB_ASYNCFIFO_OVERFLOW) | \ Loading Loading @@ -2078,5 +2120,6 @@ struct adreno_gpudev adreno_a6xx_gpudev = { .oob_clear = a6xx_oob_clear, .rpmh_gpu_pwrctrl = a6xx_rpmh_gpu_pwrctrl, .hw_isidle = a6xx_hw_isidle, /* Replaced by NULL if GMU is disabled */ .wait_for_gmu_idle = a6xx_wait_for_gmu_idle .wait_for_gmu_idle = a6xx_wait_for_gmu_idle, .iommu_fault_block = a6xx_iommu_fault_block, };
drivers/gpu/msm/kgsl_iommu.c +12 −0 Original line number Diff line number Diff line Loading @@ -797,6 +797,7 @@ static int kgsl_iommu_fault_handler(struct iommu_domain *domain, int write; struct kgsl_device *device; struct adreno_device *adreno_dev; struct adreno_gpudev *gpudev; unsigned int no_page_fault_log = 0; unsigned int curr_context_id = 0; struct kgsl_context *context; Loading @@ -813,6 +814,7 @@ static int kgsl_iommu_fault_handler(struct iommu_domain *domain, ctx = &iommu->ctx[KGSL_IOMMU_CONTEXT_USER]; device = KGSL_MMU_DEVICE(mmu); adreno_dev = ADRENO_DEVICE(device); gpudev = ADRENO_GPU_DEVICE(adreno_dev); if (pt->name == KGSL_MMU_SECURE_PT) ctx = &iommu->ctx[KGSL_IOMMU_CONTEXT_SECURE]; Loading Loading @@ -886,6 +888,16 @@ static int kgsl_iommu_fault_handler(struct iommu_domain *domain, ctx->name, ptbase, contextidr, write ? "write" : "read", fault_type); if (gpudev->iommu_fault_block) { unsigned int fsynr1; fsynr1 = KGSL_IOMMU_GET_CTX_REG(ctx, FSYNR1); KGSL_MEM_CRIT(ctx->kgsldev, "FAULTING BLOCK: %s\n", gpudev->iommu_fault_block(adreno_dev, fsynr1)); } /* Don't print the debug if this is a permissions fault */ if (!(flags & IOMMU_FAULT_PERMISSION)) { _check_if_freed(ctx, addr, ptname); Loading