Loading drivers/gpu/msm/kgsl.h +2 −0 Original line number Diff line number Diff line Loading @@ -124,6 +124,8 @@ struct kgsl_memdesc_ops { #define KGSL_MEMDESC_SECURE BIT(5) /* Indicates gpuaddr is assigned via bimap */ #define KGSL_MEMDESC_BITMAP_ALLOC BIT(6) /* The memdesc is private for use during pagetable switch only */ #define KGSL_MEMDESC_PRIVATE BIT(7) /* shared memory allocation */ struct kgsl_memdesc { Loading drivers/gpu/msm/kgsl_iommu.c +17 −3 Original line number Diff line number Diff line Loading @@ -999,6 +999,7 @@ static int kgsl_iommu_init_sync_lock(struct kgsl_mmu *mmu) } /* Add the entry to the global PT list */ iommu->sync_lock_desc.priv |= KGSL_MEMDESC_PRIVATE; status = kgsl_add_global_pt_entry(mmu->device, &iommu->sync_lock_desc); if (status) { kgsl_sg_free(iommu->sync_lock_desc.sg, Loading Loading @@ -1189,6 +1190,7 @@ static int kgsl_set_register_map(struct kgsl_mmu *mmu) ret = -EINVAL; goto err; } /* this mapping is only for use during pagetable switch */ iommu_unit->reg_map.hostptr = ioremap(data.physstart, data.physend - data.physstart + 1); if (!iommu_unit->reg_map.hostptr) { Loading @@ -1206,9 +1208,22 @@ static int kgsl_set_register_map(struct kgsl_mmu *mmu) if (ret) goto err; /* Add the register map to the global PT list */ kgsl_add_global_pt_entry(mmu->device, &iommu_unit->reg_map); if (msm_soc_version_supports_iommu_v0()) { /* * Add the register map to the global PT list so that it * gets a GPU virtual address. This is needed for v0 * only, on later hardware the registers are in the * RBBM adress space. */ iommu_unit->reg_map.priv |= KGSL_MEMDESC_PRIVATE; kgsl_add_global_pt_entry(mmu->device, &iommu_unit->reg_map); } /* For v0, iommu_halt_enable is read from devtree * elsewhere, but force it on for v1 and later hardware. */ if (!msm_soc_version_supports_iommu_v0()) iommu_unit->iommu_halt_enable = 1; Loading Loading @@ -1865,7 +1880,6 @@ static int kgsl_iommu_close(struct kgsl_mmu *mmu) if (reg_map->hostptr) iounmap(reg_map->hostptr); kgsl_free(reg_map->sg); reg_map->priv &= ~KGSL_MEMDESC_GLOBAL; } /* clear IOMMU GPU CPU sync structures */ Loading drivers/gpu/msm/kgsl_mmu.c +40 −12 Original line number Diff line number Diff line Loading @@ -107,7 +107,20 @@ static void kgsl_unmap_global_pt_entries(struct kgsl_pagetable *pagetable) int i; for (i = 0; i < KGSL_MAX_GLOBAL_PT_ENTRIES; i++) { if (kgsl_global_pt_entries.entries[i]) struct kgsl_memdesc *entry = kgsl_global_pt_entries.entries[i]; /* entry was removed */ if (entry == NULL) continue; /* * Private entries are only in the private pagetable, * but they are in the global list so that they have a unique * address. */ if ((entry->priv & KGSL_MEMDESC_PRIVATE) && (pagetable->name != KGSL_MMU_PRIV_PT)) continue; kgsl_mmu_unmap(pagetable, kgsl_global_pt_entries.entries[i]); } Loading @@ -126,12 +139,24 @@ static int kgsl_map_global_pt_entries(struct kgsl_pagetable *pagetable) int i, ret = 0; for (i = 0; !ret && i < KGSL_MAX_GLOBAL_PT_ENTRIES; i++) { if (kgsl_global_pt_entries.entries[i]) { ret = kgsl_mmu_map(pagetable, kgsl_global_pt_entries.entries[i]); struct kgsl_memdesc *entry = kgsl_global_pt_entries.entries[i]; /* entry was removed */ if (entry == NULL) continue; /* * Private entries are only in the private pagetable, * but they are in the global list so that they have a unique * address. */ if ((entry->priv & KGSL_MEMDESC_PRIVATE) && (pagetable->name != KGSL_MMU_PRIV_PT)) continue; ret = kgsl_mmu_map(pagetable, entry); if (ret) break; } } if (ret) Loading @@ -152,11 +177,14 @@ void kgsl_remove_global_pt_entry(struct kgsl_memdesc *memdesc) { int i, j; if (!(memdesc->priv & KGSL_MEMDESC_GLOBAL)) if (memdesc->gpuaddr == 0) return; for (i = 0; i < kgsl_global_pt_entries.count; i++) { if (kgsl_global_pt_entries.entries[i] == memdesc) { memdesc->gpuaddr = 0; memdesc->priv &= ~(KGSL_MEMDESC_GLOBAL | KGSL_MEMDESC_PRIVATE); for (j = i; j < kgsl_global_pt_entries.count; j++) kgsl_global_pt_entries.entries[j] = kgsl_global_pt_entries.entries[j + 1]; Loading @@ -183,7 +211,8 @@ int kgsl_add_global_pt_entry(struct kgsl_device *device, unsigned int gaddr = KGSL_MMU_GLOBAL_MEM_BASE; unsigned int size = ALIGN(memdesc->size, PAGE_SIZE); if (memdesc->priv & KGSL_MEMDESC_GLOBAL) /* do we already have a mapping? */ if (memdesc->gpuaddr != 0) return 0; if (kgsl_global_pt_entries.count == KGSL_MAX_GLOBAL_PT_ENTRIES) Loading @@ -209,13 +238,12 @@ int kgsl_add_global_pt_entry(struct kgsl_device *device, KGSL_GLOBAL_PT_SIZE)) return -ENOMEM; memdesc->priv |= KGSL_MEMDESC_GLOBAL; if (kgsl_mmu_type == KGSL_MMU_TYPE_NONE) memdesc->gpuaddr = memdesc->physaddr; else memdesc->gpuaddr = gaddr; memdesc->priv |= KGSL_MEMDESC_GLOBAL; /* * Move the entries from index till the last entry 1 slot right leaving * the slot at index empty for the newcomer Loading Loading
drivers/gpu/msm/kgsl.h +2 −0 Original line number Diff line number Diff line Loading @@ -124,6 +124,8 @@ struct kgsl_memdesc_ops { #define KGSL_MEMDESC_SECURE BIT(5) /* Indicates gpuaddr is assigned via bimap */ #define KGSL_MEMDESC_BITMAP_ALLOC BIT(6) /* The memdesc is private for use during pagetable switch only */ #define KGSL_MEMDESC_PRIVATE BIT(7) /* shared memory allocation */ struct kgsl_memdesc { Loading
drivers/gpu/msm/kgsl_iommu.c +17 −3 Original line number Diff line number Diff line Loading @@ -999,6 +999,7 @@ static int kgsl_iommu_init_sync_lock(struct kgsl_mmu *mmu) } /* Add the entry to the global PT list */ iommu->sync_lock_desc.priv |= KGSL_MEMDESC_PRIVATE; status = kgsl_add_global_pt_entry(mmu->device, &iommu->sync_lock_desc); if (status) { kgsl_sg_free(iommu->sync_lock_desc.sg, Loading Loading @@ -1189,6 +1190,7 @@ static int kgsl_set_register_map(struct kgsl_mmu *mmu) ret = -EINVAL; goto err; } /* this mapping is only for use during pagetable switch */ iommu_unit->reg_map.hostptr = ioremap(data.physstart, data.physend - data.physstart + 1); if (!iommu_unit->reg_map.hostptr) { Loading @@ -1206,9 +1208,22 @@ static int kgsl_set_register_map(struct kgsl_mmu *mmu) if (ret) goto err; /* Add the register map to the global PT list */ kgsl_add_global_pt_entry(mmu->device, &iommu_unit->reg_map); if (msm_soc_version_supports_iommu_v0()) { /* * Add the register map to the global PT list so that it * gets a GPU virtual address. This is needed for v0 * only, on later hardware the registers are in the * RBBM adress space. */ iommu_unit->reg_map.priv |= KGSL_MEMDESC_PRIVATE; kgsl_add_global_pt_entry(mmu->device, &iommu_unit->reg_map); } /* For v0, iommu_halt_enable is read from devtree * elsewhere, but force it on for v1 and later hardware. */ if (!msm_soc_version_supports_iommu_v0()) iommu_unit->iommu_halt_enable = 1; Loading Loading @@ -1865,7 +1880,6 @@ static int kgsl_iommu_close(struct kgsl_mmu *mmu) if (reg_map->hostptr) iounmap(reg_map->hostptr); kgsl_free(reg_map->sg); reg_map->priv &= ~KGSL_MEMDESC_GLOBAL; } /* clear IOMMU GPU CPU sync structures */ Loading
drivers/gpu/msm/kgsl_mmu.c +40 −12 Original line number Diff line number Diff line Loading @@ -107,7 +107,20 @@ static void kgsl_unmap_global_pt_entries(struct kgsl_pagetable *pagetable) int i; for (i = 0; i < KGSL_MAX_GLOBAL_PT_ENTRIES; i++) { if (kgsl_global_pt_entries.entries[i]) struct kgsl_memdesc *entry = kgsl_global_pt_entries.entries[i]; /* entry was removed */ if (entry == NULL) continue; /* * Private entries are only in the private pagetable, * but they are in the global list so that they have a unique * address. */ if ((entry->priv & KGSL_MEMDESC_PRIVATE) && (pagetable->name != KGSL_MMU_PRIV_PT)) continue; kgsl_mmu_unmap(pagetable, kgsl_global_pt_entries.entries[i]); } Loading @@ -126,12 +139,24 @@ static int kgsl_map_global_pt_entries(struct kgsl_pagetable *pagetable) int i, ret = 0; for (i = 0; !ret && i < KGSL_MAX_GLOBAL_PT_ENTRIES; i++) { if (kgsl_global_pt_entries.entries[i]) { ret = kgsl_mmu_map(pagetable, kgsl_global_pt_entries.entries[i]); struct kgsl_memdesc *entry = kgsl_global_pt_entries.entries[i]; /* entry was removed */ if (entry == NULL) continue; /* * Private entries are only in the private pagetable, * but they are in the global list so that they have a unique * address. */ if ((entry->priv & KGSL_MEMDESC_PRIVATE) && (pagetable->name != KGSL_MMU_PRIV_PT)) continue; ret = kgsl_mmu_map(pagetable, entry); if (ret) break; } } if (ret) Loading @@ -152,11 +177,14 @@ void kgsl_remove_global_pt_entry(struct kgsl_memdesc *memdesc) { int i, j; if (!(memdesc->priv & KGSL_MEMDESC_GLOBAL)) if (memdesc->gpuaddr == 0) return; for (i = 0; i < kgsl_global_pt_entries.count; i++) { if (kgsl_global_pt_entries.entries[i] == memdesc) { memdesc->gpuaddr = 0; memdesc->priv &= ~(KGSL_MEMDESC_GLOBAL | KGSL_MEMDESC_PRIVATE); for (j = i; j < kgsl_global_pt_entries.count; j++) kgsl_global_pt_entries.entries[j] = kgsl_global_pt_entries.entries[j + 1]; Loading @@ -183,7 +211,8 @@ int kgsl_add_global_pt_entry(struct kgsl_device *device, unsigned int gaddr = KGSL_MMU_GLOBAL_MEM_BASE; unsigned int size = ALIGN(memdesc->size, PAGE_SIZE); if (memdesc->priv & KGSL_MEMDESC_GLOBAL) /* do we already have a mapping? */ if (memdesc->gpuaddr != 0) return 0; if (kgsl_global_pt_entries.count == KGSL_MAX_GLOBAL_PT_ENTRIES) Loading @@ -209,13 +238,12 @@ int kgsl_add_global_pt_entry(struct kgsl_device *device, KGSL_GLOBAL_PT_SIZE)) return -ENOMEM; memdesc->priv |= KGSL_MEMDESC_GLOBAL; if (kgsl_mmu_type == KGSL_MMU_TYPE_NONE) memdesc->gpuaddr = memdesc->physaddr; else memdesc->gpuaddr = gaddr; memdesc->priv |= KGSL_MEMDESC_GLOBAL; /* * Move the entries from index till the last entry 1 slot right leaving * the slot at index empty for the newcomer Loading