Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 4892d8d2 authored by Jonathan Wicks's avatar Jonathan Wicks Committed by Lynus Vaz
Browse files

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: default avatarJonathan Wicks <jwicks@codeaurora.org>
parent 0f105b40
Loading
Loading
Loading
Loading
+5 −0
Original line number Original line Diff line number Diff line
@@ -152,6 +152,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.
+24 −0
Original line number Original line Diff line number Diff line
@@ -1854,6 +1854,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 */
+25 −1
Original line number Original line Diff line number Diff line
/* 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
+48 −0
Original line number Original line Diff line number Diff line
@@ -113,6 +113,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)
{
{
@@ -272,6 +273,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)
{
{
@@ -1452,6 +1497,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,
@@ -1523,6 +1569,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)
@@ -2671,6 +2718,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,
};
};


+12 −0
Original line number Original line Diff line number Diff line
@@ -617,6 +617,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 definitions - NOMMU really just means that the MMU is kept in pass
 * NOMMU definitions - NOMMU really just means that the MMU is kept in pass
 * through and the GPU directly accesses physical memory. Used in debug mode
 * through and the GPU directly accesses physical memory. Used in debug mode
Loading