Merge "msm: kgsl: Map GPU QTimer through GPU IOMMU"
This commit is contained in:
commit
8a259eb1ca
7 changed files with 126 additions and 3 deletions
|
@ -150,6 +150,11 @@ Optional Properties:
|
||||||
baseAddr - base address of the gpu channels in the qdss stm memory region
|
baseAddr - base address of the gpu channels in the qdss stm memory region
|
||||||
size - size of the gpu stm region
|
size - size of the gpu stm region
|
||||||
|
|
||||||
|
- qcom,gpu-qtimer:
|
||||||
|
<baseAddr size>
|
||||||
|
baseAddr - base address of the qtimer memory region
|
||||||
|
size - size of the qtimer region
|
||||||
|
|
||||||
- qcom,tsens-name:
|
- qcom,tsens-name:
|
||||||
Specify the name of GPU temperature sensor. This name will be used
|
Specify the name of GPU temperature sensor. This name will be used
|
||||||
to get the temperature from the thermal driver API.
|
to get the temperature from the thermal driver API.
|
||||||
|
|
|
@ -1720,6 +1720,30 @@ static int adreno_getproperty(struct kgsl_device *device,
|
||||||
status = 0;
|
status = 0;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case KGSL_PROP_DEVICE_QTIMER:
|
||||||
|
{
|
||||||
|
struct kgsl_qtimer_prop qtimerprop = {0};
|
||||||
|
struct kgsl_memdesc *qtimer_desc =
|
||||||
|
kgsl_mmu_get_qtimer_global_entry(device);
|
||||||
|
|
||||||
|
if (sizebytes != sizeof(qtimerprop)) {
|
||||||
|
status = -EINVAL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (qtimer_desc) {
|
||||||
|
qtimerprop.gpuaddr = qtimer_desc->gpuaddr;
|
||||||
|
qtimerprop.size = qtimer_desc->size;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (copy_to_user(value, &qtimerprop,
|
||||||
|
sizeof(qtimerprop))) {
|
||||||
|
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 */
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* Copyright (c) 2013-2016, The Linux Foundation. All rights reserved.
|
/* Copyright (c) 2013-2017, The Linux Foundation. All rights reserved.
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License version 2 and
|
* it under the terms of the GNU General Public License version 2 and
|
||||||
|
@ -113,6 +113,30 @@ int adreno_getproperty_compat(struct kgsl_device *device,
|
||||||
status = 0;
|
status = 0;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case KGSL_PROP_DEVICE_QTIMER:
|
||||||
|
{
|
||||||
|
struct kgsl_qtimer_prop qtimerprop = {0};
|
||||||
|
struct kgsl_memdesc *qtimer_desc =
|
||||||
|
kgsl_mmu_get_qtimer_global_entry(device);
|
||||||
|
|
||||||
|
if (sizebytes != sizeof(qtimerprop)) {
|
||||||
|
status = -EINVAL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (qtimer_desc) {
|
||||||
|
qtimerprop.gpuaddr = qtimer_desc->gpuaddr;
|
||||||
|
qtimerprop.size = qtimer_desc->size;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (copy_to_user(value, &qtimerprop,
|
||||||
|
sizeof(qtimerprop))) {
|
||||||
|
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
|
||||||
|
|
|
@ -106,6 +106,7 @@ 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 struct kgsl_memdesc gpu_qdss_desc;
|
||||||
|
static struct kgsl_memdesc gpu_qtimer_desc;
|
||||||
|
|
||||||
void kgsl_print_global_pt_entries(struct seq_file *s)
|
void kgsl_print_global_pt_entries(struct seq_file *s)
|
||||||
{
|
{
|
||||||
|
@ -261,6 +262,50 @@ static inline void kgsl_cleanup_qdss_desc(struct kgsl_mmu *mmu)
|
||||||
kgsl_sharedmem_free(&gpu_qdss_desc);
|
kgsl_sharedmem_free(&gpu_qdss_desc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct kgsl_memdesc *kgsl_iommu_get_qtimer_global_entry(void)
|
||||||
|
{
|
||||||
|
return &gpu_qtimer_desc;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void kgsl_setup_qtimer_desc(struct kgsl_device *device)
|
||||||
|
{
|
||||||
|
int result = 0;
|
||||||
|
uint32_t gpu_qtimer_entry[2];
|
||||||
|
|
||||||
|
if (!of_find_property(device->pdev->dev.of_node,
|
||||||
|
"qcom,gpu-qtimer", NULL))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (of_property_read_u32_array(device->pdev->dev.of_node,
|
||||||
|
"qcom,gpu-qtimer", gpu_qtimer_entry, 2)) {
|
||||||
|
KGSL_CORE_ERR("Failed to read gpu qtimer dts entry\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
gpu_qtimer_desc.flags = 0;
|
||||||
|
gpu_qtimer_desc.priv = 0;
|
||||||
|
gpu_qtimer_desc.physaddr = gpu_qtimer_entry[0];
|
||||||
|
gpu_qtimer_desc.size = gpu_qtimer_entry[1];
|
||||||
|
gpu_qtimer_desc.pagetable = NULL;
|
||||||
|
gpu_qtimer_desc.ops = NULL;
|
||||||
|
gpu_qtimer_desc.dev = device->dev->parent;
|
||||||
|
gpu_qtimer_desc.hostptr = NULL;
|
||||||
|
|
||||||
|
result = memdesc_sg_dma(&gpu_qtimer_desc, gpu_qtimer_desc.physaddr,
|
||||||
|
gpu_qtimer_desc.size);
|
||||||
|
if (result) {
|
||||||
|
KGSL_CORE_ERR("memdesc_sg_dma failed: %d\n", result);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
kgsl_mmu_add_global(device, &gpu_qtimer_desc, "gpu-qtimer");
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void kgsl_cleanup_qtimer_desc(struct kgsl_mmu *mmu)
|
||||||
|
{
|
||||||
|
kgsl_iommu_remove_global(mmu, &gpu_qtimer_desc);
|
||||||
|
kgsl_sharedmem_free(&gpu_qtimer_desc);
|
||||||
|
}
|
||||||
|
|
||||||
static inline void _iommu_sync_mmu_pc(bool lock)
|
static inline void _iommu_sync_mmu_pc(bool lock)
|
||||||
{
|
{
|
||||||
|
@ -1403,6 +1448,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);
|
kgsl_cleanup_qdss_desc(mmu);
|
||||||
|
kgsl_cleanup_qtimer_desc(mmu);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int _setstate_alloc(struct kgsl_device *device,
|
static int _setstate_alloc(struct kgsl_device *device,
|
||||||
|
@ -1474,6 +1520,7 @@ static int kgsl_iommu_init(struct kgsl_mmu *mmu)
|
||||||
|
|
||||||
kgsl_iommu_add_global(mmu, &iommu->setstate, "setstate");
|
kgsl_iommu_add_global(mmu, &iommu->setstate, "setstate");
|
||||||
kgsl_setup_qdss_desc(device);
|
kgsl_setup_qdss_desc(device);
|
||||||
|
kgsl_setup_qtimer_desc(device);
|
||||||
|
|
||||||
done:
|
done:
|
||||||
if (status)
|
if (status)
|
||||||
|
@ -2616,6 +2663,7 @@ struct kgsl_mmu_ops kgsl_iommu_ops = {
|
||||||
.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,
|
.mmu_get_qdss_global_entry = kgsl_iommu_get_qdss_global_entry,
|
||||||
|
.mmu_get_qtimer_global_entry = kgsl_iommu_get_qtimer_global_entry,
|
||||||
.probe = kgsl_iommu_probe,
|
.probe = kgsl_iommu_probe,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* Copyright (c) 2002,2007-2016, The Linux Foundation. All rights reserved.
|
/* Copyright (c) 2002,2007-2017, The Linux Foundation. All rights reserved.
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License version 2 and
|
* it under the terms of the GNU General Public License version 2 and
|
||||||
|
@ -619,6 +619,18 @@ struct kgsl_memdesc *kgsl_mmu_get_qdss_global_entry(struct kgsl_device *device)
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(kgsl_mmu_get_qdss_global_entry);
|
EXPORT_SYMBOL(kgsl_mmu_get_qdss_global_entry);
|
||||||
|
|
||||||
|
struct kgsl_memdesc *kgsl_mmu_get_qtimer_global_entry(
|
||||||
|
struct kgsl_device *device)
|
||||||
|
{
|
||||||
|
struct kgsl_mmu *mmu = &device->mmu;
|
||||||
|
|
||||||
|
if (MMU_OP_VALID(mmu, mmu_get_qtimer_global_entry))
|
||||||
|
return mmu->mmu_ops->mmu_get_qtimer_global_entry();
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(kgsl_mmu_get_qtimer_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
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* Copyright (c) 2002,2007-2016, The Linux Foundation. All rights reserved.
|
/* Copyright (c) 2002,2007-2017, The Linux Foundation. All rights reserved.
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License version 2 and
|
* it under the terms of the GNU General Public License version 2 and
|
||||||
|
@ -81,6 +81,7 @@ struct kgsl_mmu_ops {
|
||||||
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_memdesc* (*mmu_get_qdss_global_entry)(void);
|
||||||
|
struct kgsl_memdesc* (*mmu_get_qtimer_global_entry)(void);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct kgsl_mmu_pt_ops {
|
struct kgsl_mmu_pt_ops {
|
||||||
|
@ -231,6 +232,9 @@ int kgsl_mmu_unmap_offset(struct kgsl_pagetable *pagetable,
|
||||||
|
|
||||||
struct kgsl_memdesc *kgsl_mmu_get_qdss_global_entry(struct kgsl_device *device);
|
struct kgsl_memdesc *kgsl_mmu_get_qdss_global_entry(struct kgsl_device *device);
|
||||||
|
|
||||||
|
struct kgsl_memdesc *kgsl_mmu_get_qtimer_global_entry(
|
||||||
|
struct kgsl_device *device);
|
||||||
|
|
||||||
int kgsl_mmu_sparse_dummy_map(struct kgsl_pagetable *pagetable,
|
int kgsl_mmu_sparse_dummy_map(struct kgsl_pagetable *pagetable,
|
||||||
struct kgsl_memdesc *memdesc, uint64_t offset, uint64_t size);
|
struct kgsl_memdesc *memdesc, uint64_t offset, uint64_t size);
|
||||||
|
|
||||||
|
|
|
@ -318,6 +318,7 @@ enum kgsl_timestamp_type {
|
||||||
#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
|
#define KGSL_PROP_DEVICE_QDSS_STM 0x19
|
||||||
|
#define KGSL_PROP_DEVICE_QTIMER 0x20
|
||||||
|
|
||||||
struct kgsl_shadowprop {
|
struct kgsl_shadowprop {
|
||||||
unsigned long gpuaddr;
|
unsigned long gpuaddr;
|
||||||
|
@ -330,6 +331,11 @@ struct kgsl_qdss_stm_prop {
|
||||||
uint64_t size;
|
uint64_t size;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct kgsl_qtimer_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;
|
||||||
|
|
Loading…
Add table
Reference in a new issue