Merge "msm: kgsl: Map GPU QDSS STM through GPU IOMMU"
This commit is contained in:
commit
608c991c8e
7 changed files with 122 additions and 0 deletions
|
@ -138,6 +138,11 @@ Optional Properties:
|
|||
Specify the size of snapshot in bytes. This will override
|
||||
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:
|
||||
- qcom,gpu-quirk-two-pass-use-wfi:
|
||||
Signal the GPU to set Set TWOPASSUSEWFI bit in
|
||||
|
|
|
@ -1760,6 +1760,30 @@ static int adreno_getproperty(struct kgsl_device *device,
|
|||
status = 0;
|
||||
}
|
||||
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:
|
||||
{
|
||||
/* Report MMU only if we can handle paged memory */
|
||||
|
|
|
@ -89,6 +89,30 @@ int adreno_getproperty_compat(struct kgsl_device *device,
|
|||
status = 0;
|
||||
}
|
||||
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:
|
||||
/*
|
||||
* Call the adreno_getproperty to check if the property type
|
||||
|
|
|
@ -96,6 +96,7 @@ static struct kgsl_memdesc *global_pt_entries[GLOBAL_PT_ENTRIES];
|
|||
static struct kgsl_memdesc *kgsl_global_secure_pt_entry;
|
||||
static int global_pt_count;
|
||||
uint64_t global_pt_alloc;
|
||||
static struct kgsl_memdesc gpu_qdss_desc;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
|
@ -1265,6 +1311,7 @@ static void kgsl_iommu_close(struct kgsl_mmu *mmu)
|
|||
|
||||
kgsl_iommu_remove_global(mmu, &iommu->setstate);
|
||||
kgsl_sharedmem_free(&iommu->setstate);
|
||||
kgsl_cleanup_qdss_desc(mmu);
|
||||
}
|
||||
|
||||
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_setup_qdss_desc(device);
|
||||
|
||||
done:
|
||||
if (status)
|
||||
|
@ -2341,6 +2389,7 @@ struct kgsl_mmu_ops kgsl_iommu_ops = {
|
|||
.mmu_add_global = kgsl_iommu_add_global,
|
||||
.mmu_remove_global = kgsl_iommu_remove_global,
|
||||
.mmu_getpagetable = kgsl_iommu_getpagetable,
|
||||
.mmu_get_qdss_global_entry = kgsl_iommu_get_qdss_global_entry,
|
||||
.probe = kgsl_iommu_probe,
|
||||
};
|
||||
|
||||
|
|
|
@ -546,6 +546,17 @@ bool kgsl_mmu_gpuaddr_in_range(struct kgsl_pagetable *pagetable,
|
|||
}
|
||||
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
|
||||
* through and the GPU directly accesses physical memory. Used in debug mode and
|
||||
|
|
|
@ -80,6 +80,7 @@ struct kgsl_mmu_ops {
|
|||
struct kgsl_memdesc *memdesc);
|
||||
struct kgsl_pagetable * (*mmu_getpagetable)(struct kgsl_mmu *mmu,
|
||||
unsigned long name);
|
||||
struct kgsl_memdesc* (*mmu_get_qdss_global_entry)(void);
|
||||
};
|
||||
|
||||
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,
|
||||
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
|
||||
* function using a function pointer. These functions can be thought
|
||||
|
|
|
@ -308,6 +308,7 @@ enum kgsl_timestamp_type {
|
|||
#define KGSL_PROP_GPMU_VERSION 0x16
|
||||
#define KGSL_PROP_HIGHEST_BANK_BIT 0x17
|
||||
#define KGSL_PROP_DEVICE_BITNESS 0x18
|
||||
#define KGSL_PROP_DEVICE_QDSS_STM 0x19
|
||||
|
||||
struct kgsl_shadowprop {
|
||||
unsigned long gpuaddr;
|
||||
|
@ -315,6 +316,11 @@ struct kgsl_shadowprop {
|
|||
unsigned int flags; /* contains KGSL_FLAGS_ values */
|
||||
};
|
||||
|
||||
struct kgsl_qdss_stm_prop {
|
||||
uint64_t gpuaddr;
|
||||
uint64_t size;
|
||||
};
|
||||
|
||||
struct kgsl_version {
|
||||
unsigned int drv_major;
|
||||
unsigned int drv_minor;
|
||||
|
|
Loading…
Add table
Reference in a new issue