Merge "msm: kgsl: Map GPU QTimer through GPU IOMMU"

This commit is contained in:
Linux Build Service Account 2017-03-10 02:07:12 -08:00 committed by Gerrit - the friendly Code Review server
commit 8a259eb1ca
7 changed files with 126 additions and 3 deletions

View file

@ -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.

View file

@ -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 */

View file

@ -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

View file

@ -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,
}; };

View file

@ -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

View file

@ -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);

View file

@ -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;