diff --git a/drivers/gpu/msm/adreno.h b/drivers/gpu/msm/adreno.h index 67a5b57d1490b..89ddfbea4a0d7 100644 --- a/drivers/gpu/msm/adreno.h +++ b/drivers/gpu/msm/adreno.h @@ -605,7 +605,6 @@ enum adreno_regs { ADRENO_REG_CP_RB_RPTR_ADDR_HI, ADRENO_REG_CP_RB_RPTR, ADRENO_REG_CP_RB_WPTR, - ADRENO_REG_CP_CNTL, ADRENO_REG_CP_ME_CNTL, ADRENO_REG_CP_RB_CNTL, ADRENO_REG_CP_IB1_BASE, diff --git a/drivers/gpu/msm/adreno_a3xx.c b/drivers/gpu/msm/adreno_a3xx.c index 858520271d422..a1574f4c70826 100644 --- a/drivers/gpu/msm/adreno_a3xx.c +++ b/drivers/gpu/msm/adreno_a3xx.c @@ -1198,7 +1198,6 @@ static unsigned int a3xx_register_offsets[ADRENO_REG_REGISTER_MAX] = { ADRENO_REG_DEFINE(ADRENO_REG_CP_RB_BASE_HI, ADRENO_REG_SKIP), ADRENO_REG_DEFINE(ADRENO_REG_CP_RB_RPTR, A3XX_CP_RB_RPTR), ADRENO_REG_DEFINE(ADRENO_REG_CP_RB_WPTR, A3XX_CP_RB_WPTR), - ADRENO_REG_DEFINE(ADRENO_REG_CP_CNTL, A3XX_CP_CNTL), ADRENO_REG_DEFINE(ADRENO_REG_CP_ME_CNTL, A3XX_CP_ME_CNTL), ADRENO_REG_DEFINE(ADRENO_REG_CP_RB_CNTL, A3XX_CP_RB_CNTL), ADRENO_REG_DEFINE(ADRENO_REG_CP_IB1_BASE, A3XX_CP_IB1_BASE), diff --git a/drivers/gpu/msm/adreno_a5xx.c b/drivers/gpu/msm/adreno_a5xx.c index 30febffd8859b..88819e06d8868 100644 --- a/drivers/gpu/msm/adreno_a5xx.c +++ b/drivers/gpu/msm/adreno_a5xx.c @@ -2393,7 +2393,6 @@ static unsigned int a5xx_register_offsets[ADRENO_REG_REGISTER_MAX] = { A5XX_CP_RB_RPTR_ADDR_HI), ADRENO_REG_DEFINE(ADRENO_REG_CP_RB_RPTR, A5XX_CP_RB_RPTR), ADRENO_REG_DEFINE(ADRENO_REG_CP_RB_WPTR, A5XX_CP_RB_WPTR), - ADRENO_REG_DEFINE(ADRENO_REG_CP_CNTL, A5XX_CP_CNTL), ADRENO_REG_DEFINE(ADRENO_REG_CP_ME_CNTL, A5XX_CP_ME_CNTL), ADRENO_REG_DEFINE(ADRENO_REG_CP_RB_CNTL, A5XX_CP_RB_CNTL), ADRENO_REG_DEFINE(ADRENO_REG_CP_IB1_BASE, A5XX_CP_IB1_BASE), diff --git a/drivers/gpu/msm/adreno_a6xx.c b/drivers/gpu/msm/adreno_a6xx.c index 58f383c345afb..03eaf8d59416f 100644 --- a/drivers/gpu/msm/adreno_a6xx.c +++ b/drivers/gpu/msm/adreno_a6xx.c @@ -2264,7 +2264,6 @@ static unsigned int a6xx_register_offsets[ADRENO_REG_REGISTER_MAX] = { ADRENO_REG_DEFINE(ADRENO_REG_CP_RB_WPTR, A6XX_CP_RB_WPTR), ADRENO_REG_DEFINE(ADRENO_REG_CP_RB_CNTL, A6XX_CP_RB_CNTL), ADRENO_REG_DEFINE(ADRENO_REG_CP_ME_CNTL, A6XX_CP_SQE_CNTL), - ADRENO_REG_DEFINE(ADRENO_REG_CP_CNTL, A6XX_CP_MISC_CNTL), ADRENO_REG_DEFINE(ADRENO_REG_CP_HW_FAULT, A6XX_CP_HW_FAULT), ADRENO_REG_DEFINE(ADRENO_REG_CP_IB1_BASE, A6XX_CP_IB1_BASE), ADRENO_REG_DEFINE(ADRENO_REG_CP_IB1_BASE_HI, A6XX_CP_IB1_BASE_HI), diff --git a/drivers/gpu/msm/adreno_iommu.c b/drivers/gpu/msm/adreno_iommu.c index 9f5a50a16a667..f92f6b65e17f8 100644 --- a/drivers/gpu/msm/adreno_iommu.c +++ b/drivers/gpu/msm/adreno_iommu.c @@ -116,66 +116,36 @@ static unsigned int a3xx_tlbiall(struct adreno_device *adreno_dev, return cmds - start; } - -/** - * _adreno_iommu_add_idle_cmds - Add pm4 packets for GPU idle - * @adreno_dev - Pointer to device structure - * @cmds - Pointer to memory where idle commands need to be added - */ -static inline int _adreno_iommu_add_idle_cmds(struct adreno_device *adreno_dev, - unsigned int *cmds) -{ - unsigned int *start = cmds; - - cmds += cp_wait_for_idle(adreno_dev, cmds); - - if (adreno_is_a3xx(adreno_dev)) - cmds += cp_wait_for_me(adreno_dev, cmds); - - return cmds - start; -} - -/** - * adreno_iommu_set_apriv() - Generate commands to set/reset the APRIV - * @adreno_dev: Device on which the commands will execute - * @cmds: The memory pointer where commands are generated - * @set: If set then APRIV is set else reset - * - * Returns the number of commands generated - */ -static unsigned int adreno_iommu_set_apriv(struct adreno_device *adreno_dev, - unsigned int *cmds, int set) -{ - unsigned int *cmds_orig = cmds; - - /* adreno 3xx doesn't have the CP_CNTL.APRIV field */ - if (adreno_is_a3xx(adreno_dev)) - return 0; - - /* Targets with apriv control do not need to explicitly set the bit */ - if (ADRENO_FEATURE(adreno_dev, ADRENO_APRIV)) - return 0; - - cmds += cp_wait_for_idle(adreno_dev, cmds); - cmds += cp_wait_for_me(adreno_dev, cmds); - *cmds++ = cp_register(adreno_dev, adreno_getreg(adreno_dev, - ADRENO_REG_CP_CNTL), 1); - if (set) - *cmds++ = 1; - else - *cmds++ = 0; - - return cmds - cmds_orig; -} +/* offset at which a nop command is placed in setstate */ +#define KGSL_IOMMU_SETSTATE_NOP_OFFSET 1024 static unsigned int _adreno_iommu_set_pt_v2_a3xx(struct kgsl_device *device, unsigned int *cmds_orig, u64 ttbr0, u32 contextidr) { + struct kgsl_iommu *iommu = KGSL_IOMMU_PRIV(device); struct adreno_device *adreno_dev = ADRENO_DEVICE(device); unsigned int *cmds = cmds_orig; - cmds += _adreno_iommu_add_idle_cmds(adreno_dev, cmds); + /* + * Adding an indirect buffer ensures that the prefetch stalls until + * the commands in indirect buffer have completed. We need to stall + * prefetch with a nop indirect buffer when updating pagetables + * because it provides stabler synchronization. + */ + cmds += cp_wait_for_me(adreno_dev, cmds); + + if (!IS_ERR_OR_NULL(iommu->setstate)) { + *cmds++ = cp_mem_packet(adreno_dev, + CP_INDIRECT_BUFFER_PFE, 2, 1); + cmds += cp_gpuaddr(adreno_dev, cmds, iommu->setstate->gpuaddr + + KGSL_IOMMU_SETSTATE_NOP_OFFSET); + *cmds++ = 2; + } + + cmds += cp_wait_for_idle(adreno_dev, cmds); + + cmds += cp_wait_for_me(adreno_dev, cmds); cmds += a3xx_vbif_lock(adreno_dev, cmds); @@ -192,8 +162,11 @@ static unsigned int _adreno_iommu_set_pt_v2_a3xx(struct kgsl_device *device, /* wait for me to finish the TLBI */ cmds += cp_wait_for_me(adreno_dev, cmds); + cmds += cp_wait_for_idle(adreno_dev, cmds); - cmds += _adreno_iommu_add_idle_cmds(adreno_dev, cmds); + /* Invalidate the state */ + *cmds++ = cp_type3_packet(CP_INVALIDATE_STATE, 1); + *cmds++ = 0x7ffff; return cmds - cmds_orig; } @@ -206,9 +179,6 @@ static unsigned int _adreno_iommu_set_pt_v2_a5xx(struct kgsl_device *device, struct adreno_device *adreno_dev = ADRENO_DEVICE(device); unsigned int *cmds = cmds_orig; - cmds += _adreno_iommu_add_idle_cmds(adreno_dev, cmds); - cmds += cp_wait_for_me(adreno_dev, cmds); - /* CP switches the pagetable and flushes the Caches */ *cmds++ = cp_packet(adreno_dev, CP_SMMU_TABLE_UPDATE, 3); *cmds++ = lower_32_bits(ttbr0); @@ -222,11 +192,6 @@ static unsigned int _adreno_iommu_set_pt_v2_a5xx(struct kgsl_device *device, *cmds++ = upper_32_bits(ttbr0); *cmds++ = contextidr; - /* release all commands with wait_for_me */ - cmds += cp_wait_for_me(adreno_dev, cmds); - - cmds += _adreno_iommu_add_idle_cmds(adreno_dev, cmds); - return cmds - cmds_orig; } @@ -239,9 +204,6 @@ static unsigned int _adreno_iommu_set_pt_v2_a6xx(struct kgsl_device *device, struct adreno_device *adreno_dev = ADRENO_DEVICE(device); unsigned int *cmds = cmds_orig; - cmds += _adreno_iommu_add_idle_cmds(adreno_dev, cmds); - cmds += cp_wait_for_me(adreno_dev, cmds); - /* CP switches the pagetable and flushes the Caches */ *cmds++ = cp_packet(adreno_dev, CP_SMMU_TABLE_UPDATE, 4); *cmds++ = lower_32_bits(ttbr0); @@ -256,11 +218,6 @@ static unsigned int _adreno_iommu_set_pt_v2_a6xx(struct kgsl_device *device, *cmds++ = upper_32_bits(ttbr0); *cmds++ = contextidr; - /* release all commands with wait_for_me */ - cmds += cp_wait_for_me(adreno_dev, cmds); - - cmds += _adreno_iommu_add_idle_cmds(adreno_dev, cmds); - return cmds - cmds_orig; } @@ -281,42 +238,22 @@ unsigned int adreno_iommu_set_pt_generate_cmds( struct kgsl_iommu_context *ctx = &iommu->ctx[KGSL_IOMMU_CONTEXT_USER]; u64 ttbr0; u32 contextidr; - unsigned int *cmds_orig = cmds; ttbr0 = kgsl_mmu_pagetable_get_ttbr0(pt); contextidr = kgsl_mmu_pagetable_get_contextidr(pt); - cmds += adreno_iommu_set_apriv(adreno_dev, cmds, 1); - /* - * Adding an indirect buffer ensures that the prefetch stalls until - * the commands in indirect buffer have completed. We need to stall - * prefetch with a nop indirect buffer when updating pagetables - * because it provides stabler synchronization. - */ - cmds += cp_wait_for_me(adreno_dev, cmds); - *cmds++ = cp_mem_packet(adreno_dev, CP_INDIRECT_BUFFER_PFE, 2, 1); - cmds += cp_gpuaddr(adreno_dev, cmds, - iommu->setstate->gpuaddr + KGSL_IOMMU_SETSTATE_NOP_OFFSET); - *cmds++ = 2; - cmds += cp_wait_for_idle(adreno_dev, cmds); - if (adreno_is_a6xx(adreno_dev)) - cmds += _adreno_iommu_set_pt_v2_a6xx(device, cmds, + return _adreno_iommu_set_pt_v2_a6xx(device, cmds, ttbr0, contextidr, rb, ctx->cb_num); else if (adreno_is_a5xx(adreno_dev)) - cmds += _adreno_iommu_set_pt_v2_a5xx(device, cmds, + return _adreno_iommu_set_pt_v2_a5xx(device, cmds, ttbr0, contextidr, rb); else if (adreno_is_a3xx(adreno_dev)) - cmds += _adreno_iommu_set_pt_v2_a3xx(device, cmds, + return _adreno_iommu_set_pt_v2_a3xx(device, cmds, ttbr0, contextidr); - /* invalidate all base pointers */ - cmds += cp_invalidate_state(adreno_dev, cmds); - - cmds += adreno_iommu_set_apriv(adreno_dev, cmds, 0); - - return cmds - cmds_orig; + return 0; } /** @@ -440,18 +377,23 @@ void adreno_iommu_init(struct adreno_device *adreno_dev) if (kgsl_mmu_get_mmutype(device) == KGSL_MMU_TYPE_NONE) return; + if (!adreno_is_a3xx(adreno_dev)) + return; + /* - * A nop is required in an indirect buffer when switching + * 3xx requres a nop in an indirect buffer when switching * pagetables in-stream */ + if (IS_ERR_OR_NULL(iommu->setstate)) { + iommu->setstate = kgsl_allocate_global(device, PAGE_SIZE, + KGSL_MEMFLAGS_GPUREADONLY, 0, "setstate"); - kgsl_sharedmem_writel(device, iommu->setstate, - KGSL_IOMMU_SETSTATE_NOP_OFFSET, - cp_packet(adreno_dev, CP_NOP, 1)); + kgsl_sharedmem_writel(device, iommu->setstate, + KGSL_IOMMU_SETSTATE_NOP_OFFSET, + cp_type3_packet(CP_NOP, 1)); + } - /* Enable guard page MMU feature for A3xx and A4xx targets only */ - if (adreno_is_a3xx(adreno_dev)) - device->mmu.features |= KGSL_MMU_NEED_GUARD_PAGE; + device->mmu.features |= KGSL_MMU_NEED_GUARD_PAGE; } /** diff --git a/drivers/gpu/msm/adreno_pm4types.h b/drivers/gpu/msm/adreno_pm4types.h index 03d22029b18b8..55c586860f8e0 100644 --- a/drivers/gpu/msm/adreno_pm4types.h +++ b/drivers/gpu/msm/adreno_pm4types.h @@ -360,30 +360,6 @@ static inline uint cp_wait_for_idle(struct adreno_device *adreno_dev, return cmds - start; } -/** - * cp_invalidate_state - common function for invalidating cp - * state - * @adreno_dev: The adreno device - * @cmds: command pointer to add gpuaddr - */ -static inline uint cp_invalidate_state(struct adreno_device *adreno_dev, - uint *cmds) -{ - uint *start = cmds; - - if (ADRENO_GPUREV(adreno_dev) < 500) { - *cmds++ = cp_type3_packet(CP_INVALIDATE_STATE, 1); - *cmds++ = 0x7fff; - } else { - *cmds++ = cp_type7_packet(CP_SET_DRAW_STATE, 3); - *cmds++ = 0x40000; - *cmds++ = 0; - *cmds++ = 0; - } - - return cmds - start; -} - static inline u32 cp_protected_mode(struct adreno_device *adreno_dev, u32 *cmds, int on) { diff --git a/drivers/gpu/msm/adreno_snapshot.c b/drivers/gpu/msm/adreno_snapshot.c index d0f1c06bbd677..67165ec937648 100644 --- a/drivers/gpu/msm/adreno_snapshot.c +++ b/drivers/gpu/msm/adreno_snapshot.c @@ -208,18 +208,6 @@ static inline void parse_ib(struct kgsl_device *device, } -static inline bool iommu_is_setstate_addr(struct kgsl_device *device, - uint64_t gpuaddr, uint64_t size) -{ - struct kgsl_iommu *iommu = KGSL_IOMMU_PRIV(device); - - if (kgsl_mmu_get_mmutype(device) != KGSL_MMU_TYPE_IOMMU) - return false; - - return kgsl_gpuaddr_in_memdesc(iommu->setstate, gpuaddr, - size); -} - static void dump_all_ibs(struct kgsl_device *device, struct adreno_ringbuffer *rb, struct kgsl_snapshot *snapshot) @@ -227,6 +215,7 @@ static void dump_all_ibs(struct kgsl_device *device, int index = 0; unsigned int *rbptr; struct adreno_device *adreno_dev = ADRENO_DEVICE(device); + struct kgsl_iommu *iommu = KGSL_IOMMU_PRIV(device); rbptr = rb->buffer_desc->hostptr; @@ -248,7 +237,8 @@ static void dump_all_ibs(struct kgsl_device *device, } /* Don't parse known global IBs */ - if (iommu_is_setstate_addr(device, ibaddr, ibsize)) + if (kgsl_gpuaddr_in_memdesc(iommu->setstate, + ibaddr, ibsize)) continue; if (kgsl_gpuaddr_in_memdesc(adreno_dev->pwron_fixup, @@ -384,6 +374,7 @@ static void snapshot_rb_ibs(struct kgsl_device *device, parse_ibs = 0; if (parse_ibs && adreno_cmd_is_ib(adreno_dev, rbptr[index])) { + struct kgsl_iommu *iommu = KGSL_IOMMU_PRIV(device); uint64_t ibaddr; uint64_t ibsize; @@ -399,7 +390,8 @@ static void snapshot_rb_ibs(struct kgsl_device *device, index = (index + 1) % KGSL_RB_DWORDS; /* Don't parse known global IBs */ - if (iommu_is_setstate_addr(device, ibaddr, ibsize)) + if (kgsl_gpuaddr_in_memdesc(iommu->setstate, + ibaddr, ibsize)) continue; if (kgsl_gpuaddr_in_memdesc(adreno_dev->pwron_fixup, diff --git a/drivers/gpu/msm/kgsl_iommu.c b/drivers/gpu/msm/kgsl_iommu.c index 62b8e7cbaad4d..d615ebcae95d1 100644 --- a/drivers/gpu/msm/kgsl_iommu.c +++ b/drivers/gpu/msm/kgsl_iommu.c @@ -1209,7 +1209,7 @@ static int kgsl_iommu_init(struct kgsl_mmu *mmu) struct kgsl_device *device = KGSL_MMU_DEVICE(mmu); struct kgsl_iommu *iommu = _IOMMU_PRIV(mmu); struct kgsl_iommu_context *ctx = &iommu->ctx[KGSL_IOMMU_CONTEXT_USER]; - int status; + int status = 0; mmu->features |= KGSL_MMU_PAGED; @@ -1236,13 +1236,6 @@ static int kgsl_iommu_init(struct kgsl_mmu *mmu) } } - iommu->setstate = kgsl_allocate_global(device, PAGE_SIZE, - KGSL_MEMFLAGS_GPUREADONLY, 0, "setstate"); - - status = PTR_ERR_OR_ZERO(iommu->setstate); - if (status) - goto done; - device->qdss_desc = kgsl_allocate_global_fixed(device, "qcom,gpu-qdss-stm", "gpu-qdss"); diff --git a/drivers/gpu/msm/kgsl_sharedmem.c b/drivers/gpu/msm/kgsl_sharedmem.c index 0c997ad96d009..35b635260c105 100644 --- a/drivers/gpu/msm/kgsl_sharedmem.c +++ b/drivers/gpu/msm/kgsl_sharedmem.c @@ -812,7 +812,11 @@ kgsl_sharedmem_writel(struct kgsl_device *device, { uint32_t *dst; - if (WARN_ON(memdesc == NULL || memdesc->hostptr == NULL)) + /* Quietly return if the memdesc isn't valid */ + if (IS_ERR_OR_NULL(memdesc)) + return -EINVAL; + + if (WARN_ON(memdesc->hostptr == NULL)) return -EINVAL; WARN_ON(offsetbytes % sizeof(uint32_t) != 0);