diff options
| author | Jonathan Wicks <jwicks@codeaurora.org> | 2017-02-24 16:21:26 -0700 |
|---|---|---|
| committer | Jonathan Wicks <jwicks@codeaurora.org> | 2017-02-28 11:12:33 -0700 |
| commit | 2e560ec3d03229a6654843757207d0a070dfde68 (patch) | |
| tree | 9f6c5ae2c96fb75fe733c4b08d9ece16b8a24da2 /drivers/gpu/msm | |
| parent | 98094e2149dad0658346d504edde8aac9a921500 (diff) | |
msm: kgsl: Map GPU QTimer through GPU IOMMU
Map the GPU QTimer area as a global into the GPU
IOMMU so that the GPU can access the QTimer.
Change-Id: If50bd36681123adde7e3a37644c41316f101154c
Signed-off-by: Jonathan Wicks <jwicks@codeaurora.org>
Diffstat (limited to 'drivers/gpu/msm')
| -rw-r--r-- | drivers/gpu/msm/adreno.c | 24 | ||||
| -rw-r--r-- | drivers/gpu/msm/adreno_compat.c | 26 | ||||
| -rw-r--r-- | drivers/gpu/msm/kgsl_iommu.c | 48 | ||||
| -rw-r--r-- | drivers/gpu/msm/kgsl_mmu.c | 14 | ||||
| -rw-r--r-- | drivers/gpu/msm/kgsl_mmu.h | 6 |
5 files changed, 115 insertions, 3 deletions
diff --git a/drivers/gpu/msm/adreno.c b/drivers/gpu/msm/adreno.c index 0f582cf35e6b..f46402aae4f6 100644 --- a/drivers/gpu/msm/adreno.c +++ b/drivers/gpu/msm/adreno.c @@ -1720,6 +1720,30 @@ static int adreno_getproperty(struct kgsl_device *device, status = 0; } 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: { /* Report MMU only if we can handle paged memory */ diff --git a/drivers/gpu/msm/adreno_compat.c b/drivers/gpu/msm/adreno_compat.c index d86a0c60f0b4..5a8d587d4536 100644 --- a/drivers/gpu/msm/adreno_compat.c +++ b/drivers/gpu/msm/adreno_compat.c @@ -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 * 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; } 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: /* * Call the adreno_getproperty to check if the property type diff --git a/drivers/gpu/msm/kgsl_iommu.c b/drivers/gpu/msm/kgsl_iommu.c index 6c667cb62896..af9fc1c15236 100644 --- a/drivers/gpu/msm/kgsl_iommu.c +++ b/drivers/gpu/msm/kgsl_iommu.c @@ -106,6 +106,7 @@ 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 struct kgsl_memdesc gpu_qtimer_desc; 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); } +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) { @@ -1403,6 +1448,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); + kgsl_cleanup_qtimer_desc(mmu); } 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_setup_qdss_desc(device); + kgsl_setup_qtimer_desc(device); done: if (status) @@ -2616,6 +2663,7 @@ struct kgsl_mmu_ops kgsl_iommu_ops = { .mmu_remove_global = kgsl_iommu_remove_global, .mmu_getpagetable = kgsl_iommu_getpagetable, .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, }; diff --git a/drivers/gpu/msm/kgsl_mmu.c b/drivers/gpu/msm/kgsl_mmu.c index 46bb6f4656fb..aa7157e882ac 100644 --- a/drivers/gpu/msm/kgsl_mmu.c +++ b/drivers/gpu/msm/kgsl_mmu.c @@ -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 * 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); +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 * through and the GPU directly accesses physical memory. Used in debug mode and diff --git a/drivers/gpu/msm/kgsl_mmu.h b/drivers/gpu/msm/kgsl_mmu.h index bc448d424ccb..505fe591a53e 100644 --- a/drivers/gpu/msm/kgsl_mmu.h +++ b/drivers/gpu/msm/kgsl_mmu.h @@ -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 * 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, unsigned long name); struct kgsl_memdesc* (*mmu_get_qdss_global_entry)(void); + struct kgsl_memdesc* (*mmu_get_qtimer_global_entry)(void); }; 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_qtimer_global_entry( + struct kgsl_device *device); + int kgsl_mmu_sparse_dummy_map(struct kgsl_pagetable *pagetable, struct kgsl_memdesc *memdesc, uint64_t offset, uint64_t size); |
