Merge "msm: kgsl: Map GPU QDSS STM through GPU IOMMU"

This commit is contained in:
Linux Build Service Account 2016-07-27 19:27:07 -07:00 committed by Gerrit - the friendly Code Review server
commit 608c991c8e
7 changed files with 122 additions and 0 deletions

View file

@ -138,6 +138,11 @@ Optional Properties:
Specify the size of snapshot in bytes. This will override Specify the size of snapshot in bytes. This will override
snapshot size defined in the driver code. snapshot size defined in the driver code.
- qcom,gpu-qdss-stm:
<baseAddr size>
baseAddr - base address of the gpu channels in the qdss stm memory region
size - size of the gpu stm region
GPU Quirks: GPU Quirks:
- qcom,gpu-quirk-two-pass-use-wfi: - qcom,gpu-quirk-two-pass-use-wfi:
Signal the GPU to set Set TWOPASSUSEWFI bit in Signal the GPU to set Set TWOPASSUSEWFI bit in

View file

@ -1760,6 +1760,30 @@ static int adreno_getproperty(struct kgsl_device *device,
status = 0; status = 0;
} }
break; break;
case KGSL_PROP_DEVICE_QDSS_STM:
{
struct kgsl_qdss_stm_prop qdssprop = {0};
struct kgsl_memdesc *qdss_desc =
kgsl_mmu_get_qdss_global_entry(device);
if (sizebytes != sizeof(qdssprop)) {
status = -EINVAL;
break;
}
if (qdss_desc) {
qdssprop.gpuaddr = qdss_desc->gpuaddr;
qdssprop.size = qdss_desc->size;
}
if (copy_to_user(value, &qdssprop,
sizeof(qdssprop))) {
status = -EFAULT;
break;
}
status = 0;
}
break;
case KGSL_PROP_MMU_ENABLE: case KGSL_PROP_MMU_ENABLE:
{ {
/* Report MMU only if we can handle paged memory */ /* Report MMU only if we can handle paged memory */

View file

@ -89,6 +89,30 @@ int adreno_getproperty_compat(struct kgsl_device *device,
status = 0; status = 0;
} }
break; break;
case KGSL_PROP_DEVICE_QDSS_STM:
{
struct kgsl_qdss_stm_prop qdssprop = {0};
struct kgsl_memdesc *qdss_desc =
kgsl_mmu_get_qdss_global_entry(device);
if (sizebytes != sizeof(qdssprop)) {
status = -EINVAL;
break;
}
if (qdss_desc) {
qdssprop.gpuaddr = qdss_desc->gpuaddr;
qdssprop.size = qdss_desc->size;
}
if (copy_to_user(value, &qdssprop,
sizeof(qdssprop))) {
status = -EFAULT;
break;
}
status = 0;
}
break;
default: default:
/* /*
* Call the adreno_getproperty to check if the property type * Call the adreno_getproperty to check if the property type

View file

@ -96,6 +96,7 @@ static struct kgsl_memdesc *global_pt_entries[GLOBAL_PT_ENTRIES];
static struct kgsl_memdesc *kgsl_global_secure_pt_entry; static struct kgsl_memdesc *kgsl_global_secure_pt_entry;
static int global_pt_count; static int global_pt_count;
uint64_t global_pt_alloc; uint64_t global_pt_alloc;
static struct kgsl_memdesc gpu_qdss_desc;
static void kgsl_iommu_unmap_globals(struct kgsl_pagetable *pagetable) static void kgsl_iommu_unmap_globals(struct kgsl_pagetable *pagetable)
{ {
@ -183,6 +184,51 @@ void kgsl_add_global_secure_entry(struct kgsl_device *device,
kgsl_global_secure_pt_entry = memdesc; kgsl_global_secure_pt_entry = memdesc;
} }
struct kgsl_memdesc *kgsl_iommu_get_qdss_global_entry(void)
{
return &gpu_qdss_desc;
}
static void kgsl_setup_qdss_desc(struct kgsl_device *device)
{
int result = 0;
uint32_t gpu_qdss_entry[2];
if (!of_find_property(device->pdev->dev.of_node,
"qcom,gpu-qdss-stm", NULL))
return;
if (of_property_read_u32_array(device->pdev->dev.of_node,
"qcom,gpu-qdss-stm", gpu_qdss_entry, 2)) {
KGSL_CORE_ERR("Failed to read gpu qdss dts entry\n");
return;
}
gpu_qdss_desc.flags = 0;
gpu_qdss_desc.priv = 0;
gpu_qdss_desc.physaddr = gpu_qdss_entry[0];
gpu_qdss_desc.size = gpu_qdss_entry[1];
gpu_qdss_desc.pagetable = NULL;
gpu_qdss_desc.ops = NULL;
gpu_qdss_desc.dev = device->dev->parent;
gpu_qdss_desc.hostptr = NULL;
result = memdesc_sg_dma(&gpu_qdss_desc, gpu_qdss_desc.physaddr,
gpu_qdss_desc.size);
if (result) {
KGSL_CORE_ERR("memdesc_sg_dma failed: %d\n", result);
return;
}
kgsl_mmu_add_global(device, &gpu_qdss_desc);
}
static inline void kgsl_cleanup_qdss_desc(struct kgsl_mmu *mmu)
{
kgsl_iommu_remove_global(mmu, &gpu_qdss_desc);
kgsl_sharedmem_free(&gpu_qdss_desc);
}
static inline void _iommu_sync_mmu_pc(bool lock) static inline void _iommu_sync_mmu_pc(bool lock)
{ {
@ -1265,6 +1311,7 @@ static void kgsl_iommu_close(struct kgsl_mmu *mmu)
kgsl_iommu_remove_global(mmu, &iommu->setstate); kgsl_iommu_remove_global(mmu, &iommu->setstate);
kgsl_sharedmem_free(&iommu->setstate); kgsl_sharedmem_free(&iommu->setstate);
kgsl_cleanup_qdss_desc(mmu);
} }
static int _setstate_alloc(struct kgsl_device *device, static int _setstate_alloc(struct kgsl_device *device,
@ -1336,6 +1383,7 @@ static int kgsl_iommu_init(struct kgsl_mmu *mmu)
} }
kgsl_iommu_add_global(mmu, &iommu->setstate); kgsl_iommu_add_global(mmu, &iommu->setstate);
kgsl_setup_qdss_desc(device);
done: done:
if (status) if (status)
@ -2341,6 +2389,7 @@ struct kgsl_mmu_ops kgsl_iommu_ops = {
.mmu_add_global = kgsl_iommu_add_global, .mmu_add_global = kgsl_iommu_add_global,
.mmu_remove_global = kgsl_iommu_remove_global, .mmu_remove_global = kgsl_iommu_remove_global,
.mmu_getpagetable = kgsl_iommu_getpagetable, .mmu_getpagetable = kgsl_iommu_getpagetable,
.mmu_get_qdss_global_entry = kgsl_iommu_get_qdss_global_entry,
.probe = kgsl_iommu_probe, .probe = kgsl_iommu_probe,
}; };

View file

@ -546,6 +546,17 @@ bool kgsl_mmu_gpuaddr_in_range(struct kgsl_pagetable *pagetable,
} }
EXPORT_SYMBOL(kgsl_mmu_gpuaddr_in_range); EXPORT_SYMBOL(kgsl_mmu_gpuaddr_in_range);
struct kgsl_memdesc *kgsl_mmu_get_qdss_global_entry(struct kgsl_device *device)
{
struct kgsl_mmu *mmu = &device->mmu;
if (MMU_OP_VALID(mmu, mmu_get_qdss_global_entry))
return mmu->mmu_ops->mmu_get_qdss_global_entry();
return NULL;
}
EXPORT_SYMBOL(kgsl_mmu_get_qdss_global_entry);
/* /*
* NOMMU defintions - NOMMU really just means that the MMU is kept in pass * NOMMU defintions - NOMMU really just means that the MMU is kept in pass
* through and the GPU directly accesses physical memory. Used in debug mode and * through and the GPU directly accesses physical memory. Used in debug mode and

View file

@ -80,6 +80,7 @@ struct kgsl_mmu_ops {
struct kgsl_memdesc *memdesc); struct kgsl_memdesc *memdesc);
struct kgsl_pagetable * (*mmu_getpagetable)(struct kgsl_mmu *mmu, struct kgsl_pagetable * (*mmu_getpagetable)(struct kgsl_mmu *mmu,
unsigned long name); unsigned long name);
struct kgsl_memdesc* (*mmu_get_qdss_global_entry)(void);
}; };
struct kgsl_mmu_pt_ops { struct kgsl_mmu_pt_ops {
@ -227,6 +228,8 @@ int kgsl_mmu_unmap_offset(struct kgsl_pagetable *pagetable,
struct kgsl_memdesc *memdesc, uint64_t addr, uint64_t offset, struct kgsl_memdesc *memdesc, uint64_t addr, uint64_t offset,
uint64_t size); uint64_t size);
struct kgsl_memdesc *kgsl_mmu_get_qdss_global_entry(struct kgsl_device *device);
/* /*
* Static inline functions of MMU that simply call the SMMU specific * Static inline functions of MMU that simply call the SMMU specific
* function using a function pointer. These functions can be thought * function using a function pointer. These functions can be thought

View file

@ -308,6 +308,7 @@ enum kgsl_timestamp_type {
#define KGSL_PROP_GPMU_VERSION 0x16 #define KGSL_PROP_GPMU_VERSION 0x16
#define KGSL_PROP_HIGHEST_BANK_BIT 0x17 #define KGSL_PROP_HIGHEST_BANK_BIT 0x17
#define KGSL_PROP_DEVICE_BITNESS 0x18 #define KGSL_PROP_DEVICE_BITNESS 0x18
#define KGSL_PROP_DEVICE_QDSS_STM 0x19
struct kgsl_shadowprop { struct kgsl_shadowprop {
unsigned long gpuaddr; unsigned long gpuaddr;
@ -315,6 +316,11 @@ struct kgsl_shadowprop {
unsigned int flags; /* contains KGSL_FLAGS_ values */ unsigned int flags; /* contains KGSL_FLAGS_ values */
}; };
struct kgsl_qdss_stm_prop {
uint64_t gpuaddr;
uint64_t size;
};
struct kgsl_version { struct kgsl_version {
unsigned int drv_major; unsigned int drv_major;
unsigned int drv_minor; unsigned int drv_minor;