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

Commit bcc0dc37 authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "msm: kgsl: Map GPU QTimer through GPU IOMMU" into msm-4.9

parents deffc0a7 4892d8d2
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -152,6 +152,11 @@ Optional Properties:
				baseAddr - base address of the gpu channels in the qdss stm memory 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:
				Specify the name of GPU temperature sensor. This name will be used
				to get the temperature from the thermal driver API.
+24 −0
Original line number Diff line number Diff line
@@ -1854,6 +1854,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 */
+25 −1
Original line number 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
 * 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
+48 −0
Original line number Diff line number Diff line
@@ -113,6 +113,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)
{
@@ -272,6 +273,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)
{
@@ -1452,6 +1497,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,
@@ -1523,6 +1569,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)
@@ -2671,6 +2718,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,
};

+12 −0
Original line number 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);

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
 * through and the GPU directly accesses physical memory. Used in debug mode
Loading