Skip to content

Commit

Permalink
msm: kgsl: Map sync lock variables to every pagetable
Browse files Browse the repository at this point in the history
Map sync lock variables to every pagetable since we don't
use TTBR1 anymore.

Change-Id: If2d43c4c57d0cdcf6076229dfad32c0375e74df4
Signed-off-by: Rajesh Kemisetti <rajeshk@codeaurora.org>
  • Loading branch information
Rajesh Kemisetti authored and hellsgod committed Sep 4, 2013
1 parent 747a87f commit f3a29d7
Show file tree
Hide file tree
Showing 2 changed files with 70 additions and 34 deletions.
101 changes: 67 additions & 34 deletions drivers/gpu/msm/kgsl_iommu.c
Original file line number Diff line number Diff line change
Expand Up @@ -779,6 +779,46 @@ static int _get_iommu_ctxs(struct kgsl_mmu *mmu,

return 0;
}
/*
* kgsl_iommu_start_sync_lock - Initialize some variables during MMU start up
* for GPU CPU synchronization
* @mmu - Pointer to mmu device
*
* Return - 0 on success else error code
*/
static int kgsl_iommu_start_sync_lock(struct kgsl_mmu *mmu)
{
struct kgsl_iommu *iommu = mmu->priv;
uint32_t lock_gpu_addr = 0;

if (KGSL_DEVICE_3D0 != mmu->device->id ||
!msm_soc_version_supports_iommu_v1() ||
!kgsl_mmu_is_perprocess() ||
iommu->sync_lock_vars)
return 0;

if (!(mmu->flags & KGSL_MMU_FLAGS_IOMMU_SYNC)) {
KGSL_DRV_ERR(mmu->device,
"The GPU microcode does not support IOMMUv1 sync opcodes\n");
return -ENXIO;
}
/* Store Lock variables GPU address */
lock_gpu_addr = (iommu->sync_lock_desc.gpuaddr +
iommu->sync_lock_offset);

kgsl_iommu_sync_lock_vars.flag[PROC_APPS] = (lock_gpu_addr +
(offsetof(struct remote_iommu_petersons_spinlock,
flag[PROC_APPS])));
kgsl_iommu_sync_lock_vars.flag[PROC_GPU] = (lock_gpu_addr +
(offsetof(struct remote_iommu_petersons_spinlock,
flag[PROC_GPU])));
kgsl_iommu_sync_lock_vars.turn = (lock_gpu_addr +
(offsetof(struct remote_iommu_petersons_spinlock, turn)));

iommu->sync_lock_vars = &kgsl_iommu_sync_lock_vars;

return 0;
}

/*
* kgsl_get_sync_lock - Init Sync Lock between GPU and CPU
Expand All @@ -790,12 +830,11 @@ static int kgsl_iommu_init_sync_lock(struct kgsl_mmu *mmu)
{
struct kgsl_iommu *iommu = mmu->priv;
int status = 0;
struct kgsl_pagetable *pagetable = NULL;
uint32_t lock_gpu_addr = 0;
uint32_t lock_phy_addr = 0;
uint32_t page_offset = 0;

if (!msm_soc_version_supports_iommu_v1() ||
if (KGSL_DEVICE_3D0 != mmu->device->id ||
!msm_soc_version_supports_iommu_v1() ||
!kgsl_mmu_is_perprocess())
return status;

Expand Down Expand Up @@ -828,6 +867,7 @@ static int kgsl_iommu_init_sync_lock(struct kgsl_mmu *mmu)
page_offset = (lock_phy_addr & (PAGE_SIZE - 1));
lock_phy_addr = (lock_phy_addr & ~(PAGE_SIZE - 1));
iommu->sync_lock_desc.physaddr = (unsigned int)lock_phy_addr;
iommu->sync_lock_offset = page_offset;

iommu->sync_lock_desc.size =
PAGE_ALIGN(sizeof(kgsl_iommu_sync_lock_vars));
Expand All @@ -838,31 +878,6 @@ static int kgsl_iommu_init_sync_lock(struct kgsl_mmu *mmu)
if (status)
return status;

/* Map Lock variables to GPU pagetable */
pagetable = mmu->priv_bank_table ? mmu->priv_bank_table :
mmu->defaultpagetable;

status = kgsl_mmu_map_global(pagetable, &iommu->sync_lock_desc);

if (status) {
kgsl_mmu_unmap(pagetable, &iommu->sync_lock_desc);
iommu->sync_lock_desc.priv &= ~KGSL_MEMDESC_GLOBAL;
return status;
}

/* Store Lock variables GPU address */
lock_gpu_addr = (iommu->sync_lock_desc.gpuaddr + page_offset);

kgsl_iommu_sync_lock_vars.flag[PROC_APPS] = (lock_gpu_addr +
(offsetof(struct remote_iommu_petersons_spinlock,
flag[PROC_APPS])));
kgsl_iommu_sync_lock_vars.flag[PROC_GPU] = (lock_gpu_addr +
(offsetof(struct remote_iommu_petersons_spinlock,
flag[PROC_GPU])));
kgsl_iommu_sync_lock_vars.turn = (lock_gpu_addr +
(offsetof(struct remote_iommu_petersons_spinlock, turn)));

iommu->sync_lock_vars = &kgsl_iommu_sync_lock_vars;

/* Flag Sync Lock is Initialized */
iommu->sync_lock_initialized = 1;
Expand Down Expand Up @@ -1157,6 +1172,14 @@ static int kgsl_iommu_setup_regs(struct kgsl_mmu *mmu,
goto err;
}

/* Map Lock variables to GPU pagetable */
if (iommu->sync_lock_initialized) {
status = kgsl_mmu_map_global(pt,
&iommu->sync_lock_desc);
if (status)
goto err;
}

return 0;
err:
for (i--; i >= 0; i--)
Expand All @@ -1182,6 +1205,9 @@ static void kgsl_iommu_cleanup_regs(struct kgsl_mmu *mmu,
int i;
for (i = 0; i < iommu->unit_count; i++)
kgsl_mmu_unmap(pt, &(iommu->iommu_units[i].reg_map));

if (iommu->sync_lock_desc.gpuaddr)
kgsl_mmu_unmap(pt, &iommu->sync_lock_desc);
}


Expand Down Expand Up @@ -1210,6 +1236,10 @@ static int kgsl_iommu_init(struct kgsl_mmu *mmu)
if (status)
goto done;

status = kgsl_iommu_init_sync_lock(mmu);
if (status)
goto done;

iommu->iommu_reg_list = kgsl_iommuv1_reg;
iommu->ctx_offset = KGSL_IOMMU_CTX_OFFSET_V1;

Expand Down Expand Up @@ -1408,7 +1438,6 @@ static void kgsl_iommu_lock_rb_in_tlb(struct kgsl_mmu *mmu)

static int kgsl_iommu_start(struct kgsl_mmu *mmu)
{
struct kgsl_device *device = mmu->device;
int status;
struct kgsl_iommu *iommu = mmu->priv;
int i, j;
Expand All @@ -1420,13 +1449,12 @@ static int kgsl_iommu_start(struct kgsl_mmu *mmu)
status = kgsl_iommu_setup_defaultpagetable(mmu);
if (status)
return -ENOMEM;

/* Initialize the sync lock between GPU and CPU */
if (msm_soc_version_supports_iommu_v1() &&
(device->id == KGSL_DEVICE_3D0))
kgsl_iommu_init_sync_lock(mmu);
}

status = kgsl_iommu_start_sync_lock(mmu);
if (status)
return status;

/* We use the GPU MMU to control access to IOMMU registers on 8960 with
* a225, hence we still keep the MMU active on 8960 */
if (cpu_is_msm8960() && KGSL_DEVICE_3D0 == mmu->device->id) {
Expand Down Expand Up @@ -1629,7 +1657,12 @@ static int kgsl_iommu_close(struct kgsl_mmu *mmu)
if (reg_map->hostptr)
iounmap(reg_map->hostptr);
kgsl_sg_free(reg_map->sg, reg_map->sglen);
reg_map->priv &= ~KGSL_MEMDESC_GLOBAL;
}
/* clear IOMMU GPU CPU sync structures */
kgsl_sg_free(iommu->sync_lock_desc.sg, iommu->sync_lock_desc.sglen);
memset(&iommu->sync_lock_desc, 0, sizeof(iommu->sync_lock_desc));
iommu->sync_lock_vars = NULL;

kfree(iommu);

Expand Down
3 changes: 3 additions & 0 deletions drivers/gpu/msm/kgsl_iommu.h
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,8 @@ struct kgsl_iommu_unit {
* IOMMU registers
* @sync_lock_desc: GPU Memory descriptor for the memory containing the
* spinlocks
* @sync_lock_offset: The page offset within a page at which the sync
* variables are located
* @sync_lock_initialized: True if the sync_lock feature is enabled
*/
struct kgsl_iommu {
Expand All @@ -167,6 +169,7 @@ struct kgsl_iommu {
struct kgsl_iommu_register_list *iommu_reg_list;
struct remote_iommu_petersons_spinlock *sync_lock_vars;
struct kgsl_memdesc sync_lock_desc;
unsigned int sync_lock_offset;
bool sync_lock_initialized;
};

Expand Down

0 comments on commit f3a29d7

Please sign in to comment.