diff --git a/drivers/gpu/msm/adreno.c b/drivers/gpu/msm/adreno.c index 70fc17e3321dfeb9aabeb9c2a47659b9fea734dc..110464d6ac7aef7e0c58a6d6625f12150955bcf1 100644 --- a/drivers/gpu/msm/adreno.c +++ b/drivers/gpu/msm/adreno.c @@ -884,9 +884,7 @@ static int adreno_iommu_setstate(struct kgsl_device *device, uint32_t flags) { phys_addr_t pt_val; - unsigned int link[230]; - unsigned int *cmds = &link[0]; - int sizedwords = 0; + unsigned int *link, *cmds; struct adreno_device *adreno_dev = ADRENO_DEVICE(device); int num_iommu_units; struct kgsl_context *context; @@ -901,11 +899,16 @@ static int adreno_iommu_setstate(struct kgsl_device *device, num_iommu_units = kgsl_mmu_get_num_iommu_units(&device->mmu); context = kgsl_context_get(device, context_id); - if (!context) { - kgsl_mmu_device_setstate(&device->mmu, flags); - return 0; + if (context) + adreno_ctx = ADRENO_CONTEXT(context); + + link = kmalloc(PAGE_SIZE, GFP_KERNEL); + if (link == NULL) { + result = -ENOMEM; + goto done; } - adreno_ctx = ADRENO_CONTEXT(context); + + cmds = link; kgsl_mmu_enable_clk(&device->mmu, KGSL_IOMMU_MAX_UNITS); @@ -924,17 +927,11 @@ static int adreno_iommu_setstate(struct kgsl_device *device, cmds += _adreno_iommu_setstate_v1(device, cmds, pt_val, num_iommu_units, flags); - sizedwords += (cmds - &link[0]); - if (sizedwords == 0) { - KGSL_DRV_ERR(device, "no commands generated\n"); - BUG(); - } /* invalidate all base pointers */ *cmds++ = cp_type3_packet(CP_INVALIDATE_STATE, 1); *cmds++ = 0x7fff; - sizedwords += 2; - if (sizedwords > (ARRAY_SIZE(link))) { + if ((unsigned int) (cmds - link) > (PAGE_SIZE / sizeof(unsigned int))) { KGSL_DRV_ERR(device, "Temp command buffer overflow\n"); BUG(); } @@ -943,7 +940,8 @@ static int adreno_iommu_setstate(struct kgsl_device *device, * use the global timestamp for iommu clock disablement */ result = adreno_ringbuffer_issuecmds(device, adreno_ctx, - KGSL_CMD_FLAGS_PMODE, &link[0], sizedwords); + KGSL_CMD_FLAGS_PMODE, link, + (unsigned int)(cmds - link)); /* * On error disable the IOMMU clock right away otherwise turn it off @@ -955,6 +953,8 @@ static int adreno_iommu_setstate(struct kgsl_device *device, kgsl_mmu_disable_clk_on_ts(&device->mmu, rb->global_ts, KGSL_IOMMU_MAX_UNITS); +done: + kfree(link); kgsl_context_put(context); return result; } diff --git a/drivers/gpu/msm/adreno.h b/drivers/gpu/msm/adreno.h index 4ab2880ff70b8f6740028119a48e54b377693916..23309a12815202c1904a15fbb9af1a1201e3b6a4 100644 --- a/drivers/gpu/msm/adreno.h +++ b/drivers/gpu/msm/adreno.h @@ -715,6 +715,11 @@ static inline int adreno_add_read_cmds(struct kgsl_device *device, *cmds++ = val; *cmds++ = 0xFFFFFFFF; *cmds++ = 0xFFFFFFFF; + + /* WAIT_REG_MEM turns back on protected mode - push it off */ + *cmds++ = cp_type3_packet(CP_SET_PROTECTED_MODE, 1); + *cmds++ = 0; + cmds += __adreno_add_idle_indirect_cmds(cmds, nop_gpuaddr); return cmds - start; } diff --git a/drivers/gpu/msm/adreno_a3xx.c b/drivers/gpu/msm/adreno_a3xx.c index ff1002c0b10f6e492c40474e1b738c06b679e542..26bdb4820ba767b601c94f04df27ae2384afc318 100644 --- a/drivers/gpu/msm/adreno_a3xx.c +++ b/drivers/gpu/msm/adreno_a3xx.c @@ -3970,6 +3970,7 @@ static void a3xx_protect_init(struct kgsl_device *device) /* CP registers */ adreno_set_protected_registers(device, &index, 0x1C0, 5); + adreno_set_protected_registers(device, &index, 0x1EC, 1); adreno_set_protected_registers(device, &index, 0x1F6, 1); adreno_set_protected_registers(device, &index, 0x1F8, 2); adreno_set_protected_registers(device, &index, 0x45E, 2); diff --git a/drivers/gpu/msm/kgsl_iommu.c b/drivers/gpu/msm/kgsl_iommu.c index 03a58e9ed1a23bb349eb33ea5987d6b1d5d3aed7..2d5c0b879943a8ab8de7f8503b402eea29c1c735 100644 --- a/drivers/gpu/msm/kgsl_iommu.c +++ b/drivers/gpu/msm/kgsl_iommu.c @@ -1021,6 +1021,10 @@ inline unsigned int kgsl_iommu_sync_lock(struct kgsl_mmu *mmu, *cmds++ = 0x1; *cmds++ = 0x1; + /* WAIT_REG_MEM turns back on protected mode - push it off */ + *cmds++ = cp_type3_packet(CP_SET_PROTECTED_MODE, 1); + *cmds++ = 0; + *cmds++ = cp_type3_packet(CP_MEM_WRITE, 2); *cmds++ = lock_vars->turn; *cmds++ = 0; @@ -1035,11 +1039,19 @@ inline unsigned int kgsl_iommu_sync_lock(struct kgsl_mmu *mmu, *cmds++ = 0x1; *cmds++ = 0x1; + /* WAIT_REG_MEM turns back on protected mode - push it off */ + *cmds++ = cp_type3_packet(CP_SET_PROTECTED_MODE, 1); + *cmds++ = 0; + *cmds++ = cp_type3_packet(CP_TEST_TWO_MEMS, 3); *cmds++ = lock_vars->flag[PROC_APPS]; *cmds++ = lock_vars->turn; *cmds++ = 0; + /* TEST_TWO_MEMS turns back on protected mode - push it off */ + *cmds++ = cp_type3_packet(CP_SET_PROTECTED_MODE, 1); + *cmds++ = 0; + cmds += adreno_add_idle_cmds(adreno_dev, cmds); return cmds - start; @@ -1077,6 +1089,10 @@ inline unsigned int kgsl_iommu_sync_unlock(struct kgsl_mmu *mmu, *cmds++ = 0x1; *cmds++ = 0x1; + /* WAIT_REG_MEM turns back on protected mode - push it off */ + *cmds++ = cp_type3_packet(CP_SET_PROTECTED_MODE, 1); + *cmds++ = 0; + cmds += adreno_add_idle_cmds(adreno_dev, cmds); return cmds - start;