[PATCH 4/6] drm/msm: Create a child device for the zap shader

Jordan Crouse jcrouse at codeaurora.org
Wed Apr 12 21:15:16 UTC 2017


Currently we abuse the platform device engine to create a platform
device for the zap shader subnode so that we can isolate the
reserved memory away from the parent GPU device.

It is much safer to create and register a simple child device and use
that instead.

Signed-off-by: Jordan Crouse <jcrouse at codeaurora.org>
---
 drivers/gpu/drm/msm/adreno/a5xx_gpu.c | 77 ++++++++++++++++++++---------------
 drivers/gpu/drm/msm/adreno/a5xx_gpu.h |  2 +
 2 files changed, 46 insertions(+), 33 deletions(-)

diff --git a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c
index 0a096f8..8678bce 100644
--- a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c
+++ b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c
@@ -31,7 +31,7 @@ static inline bool _check_segment(const struct elf32_phdr *phdr)
 		phdr->p_memsz);
 }
 
-static int zap_load_segments(struct platform_device *pdev,
+static int zap_load_segments(struct device *dev,
 		const struct firmware *mdt, const char *fwname,
 		void *fwptr, size_t fw_size, unsigned long fw_min_addr)
 {
@@ -55,15 +55,15 @@ static int zap_load_segments(struct platform_device *pdev,
 		/* Request the file containing the segment */
 		snprintf(filename, sizeof(filename), "%s.b%02d", fwname, i);
 
-		ret = request_firmware(&fw, filename, &pdev->dev);
+		ret = request_firmware(&fw, filename, dev);
 		if (ret) {
-			DRM_DEV_ERROR(&pdev->dev, "Failed to load segment %s\n",
+			DRM_DEV_ERROR(dev, "Failed to load segment %s\n",
 				filename);
 			break;
 		}
 
 		if (offset + fw->size > fw_size) {
-			DRM_DEV_ERROR(&pdev->dev, "Segment %s is too big\n",
+			DRM_DEV_ERROR(dev, "Segment %s is too big\n",
 				filename);
 			ret = -EINVAL;
 			release_firmware(fw);
@@ -82,7 +82,7 @@ static int zap_load_segments(struct platform_device *pdev,
 	return ret;
 }
 
-static int zap_load_mdt(struct platform_device *pdev)
+static int zap_load_mdt(struct device *dev)
 {
 	char filename[64];
 	const char *fwname;
@@ -92,37 +92,29 @@ static int zap_load_mdt(struct platform_device *pdev)
 	phys_addr_t fw_min_addr, fw_max_addr;
 	dma_addr_t fw_phys;
 	size_t fw_size;
-	void *ptr;
+	void *ptr = NULL;
 	int i, ret;
 
-	if (pdev == NULL)
-		return -ENODEV;
-
-	if (!qcom_scm_is_available()) {
-		DRM_DEV_ERROR(&pdev->dev, "SCM is not available\n");
-		return -EPROBE_DEFER;
-	}
-
-	ret = of_reserved_mem_device_init(&pdev->dev);
+	ret = of_reserved_mem_device_init(dev);
 	if (ret) {
-		DRM_DEV_ERROR(&pdev->dev, "Unable to set up the reserved memory\n");
+		DRM_DEV_ERROR(dev, "Unable to set up the reserved memory\n");
 		return ret;
 	}
 
 	/* Get the firmware and PAS id from the device node */
-	if (of_property_read_string(pdev->dev.of_node, "qcom,firmware",
+	if (of_property_read_string(dev->of_node, "qcom,firmware",
 		&fwname)) {
-		DRM_DEV_ERROR(&pdev->dev, "Could not read a firmware name\n");
+		DRM_DEV_ERROR(dev, "Could not read a firmware name\n");
 		return -EINVAL;
 	}
 
 	snprintf(filename, sizeof(filename), "%s.mdt", fwname);
 
 	/* Request the MDT file for the firmware */
-	ret = request_firmware(&mdt, filename, &pdev->dev);
+	ret = request_firmware(&mdt, filename, dev);
 	if (ret) {
-		DRM_DEV_ERROR(&pdev->dev, "Unable to load %s\n", filename);
-		return ret;
+		DRM_DEV_ERROR(dev, "Unable to load %s\n", filename);
+		goto out;
 	}
 
 	ehdr = (struct elf32_hdr *) mdt->data;
@@ -152,35 +144,36 @@ static int zap_load_mdt(struct platform_device *pdev)
 	/* Verify the MDT header */
 	ret = qcom_scm_pas_init_image(13, mdt->data, mdt->size);
 	if (ret) {
-		DRM_DEV_ERROR(&pdev->dev, "Invalid firmware metadata\n");
+		DRM_DEV_ERROR(dev, "Invalid firmware metadata\n");
 		goto out;
 	}
 
 	/* allocate some memory */
-	ptr = dma_alloc_coherent(&pdev->dev, fw_size, &fw_phys, GFP_KERNEL);
+	ptr = dma_alloc_coherent(dev, fw_size, &fw_phys, GFP_KERNEL);
 	if (ptr == NULL)
 		goto out;
 
 	/* Set up the newly allocated memory region */
 	ret = qcom_scm_pas_mem_setup(13, fw_phys, fw_size);
 	if (ret) {
-		DRM_DEV_ERROR(&pdev->dev, "Unable to set up firmware memory\n");
+		DRM_DEV_ERROR(dev, "Unable to set up firmware memory\n");
 		goto out;
 	}
 
-	ret = zap_load_segments(pdev, mdt, fwname, ptr, fw_size, fw_min_addr);
+	ret = zap_load_segments(dev, mdt, fwname, ptr, fw_size, fw_min_addr);
 	if (ret)
 		goto out;
 
 	ret = qcom_scm_pas_auth_and_reset(13);
 	if (ret)
-		DRM_DEV_ERROR(&pdev->dev, "Unable to authorize the image\n");
+		DRM_DEV_ERROR(dev, "Unable to authorize the image\n");
 
 out:
 	if (ret && ptr)
-		dma_free_coherent(&pdev->dev, fw_size, ptr, fw_phys);
+		dma_free_coherent(dev, fw_size, ptr, fw_phys);
 
 	release_firmware(mdt);
+
 	return ret;
 }
 
@@ -498,8 +491,10 @@ static int a5xx_zap_shader_init(struct msm_gpu *gpu)
 	if (loaded)
 		return a5xx_zap_shader_resume(gpu);
 
-	/* Populate the sub-nodes if they haven't already been done */
-	of_platform_populate(pdev->dev.of_node, NULL, NULL, &pdev->dev);
+	if (!qcom_scm_is_available()) {
+		DRM_DEV_ERROR(&pdev->dev, "SCM is not available\n");
+		return -EPROBE_DEFER;
+	}
 
 	/* Find the sub-node for the zap shader */
 	node = of_get_child_by_name(pdev->dev.of_node, "zap-shader");
@@ -509,10 +504,23 @@ static int a5xx_zap_shader_init(struct msm_gpu *gpu)
 		return -ENODEV;
 	}
 
-	ret = zap_load_mdt(of_find_device_by_node(node));
-	if (ret)
-		DRM_ERROR("%s: Unable to load the zap shader\n",
-			gpu->name);
+	/* Set up the child device to "own" the zap shader */
+	if (!a5xx_gpu->zap_dev.parent) {
+		a5xx_gpu->zap_dev.parent = &pdev->dev;
+		a5xx_gpu->zap_dev.of_node = node;
+		dev_set_name(&a5xx_gpu->zap_dev, "adreno_zap_shader");
+
+		ret = device_register(&a5xx_gpu->zap_dev);
+		if (ret) {
+			DRM_DEV_ERROR(&pdev->dev,
+				"Couldn't register the zap shader device\n");
+
+			a5xx_gpu->zap_dev.parent = NULL;
+			return ret;
+		}
+	}
+
+	ret = zap_load_mdt(&a5xx_gpu->zap_dev);
 
 	loaded = !ret;
 
@@ -755,6 +763,9 @@ static void a5xx_destroy(struct msm_gpu *gpu)
 
 	DBG("%s", gpu->name);
 
+	if (a5xx_gpu->zap_dev.parent)
+		device_unregister(&a5xx_gpu->zap_dev);
+
 	if (a5xx_gpu->pm4_bo) {
 		if (a5xx_gpu->pm4_iova)
 			msm_gem_put_iova(a5xx_gpu->pm4_bo, gpu->id);
diff --git a/drivers/gpu/drm/msm/adreno/a5xx_gpu.h b/drivers/gpu/drm/msm/adreno/a5xx_gpu.h
index 1590f84..78408f5 100644
--- a/drivers/gpu/drm/msm/adreno/a5xx_gpu.h
+++ b/drivers/gpu/drm/msm/adreno/a5xx_gpu.h
@@ -36,6 +36,8 @@ struct a5xx_gpu {
 	uint32_t gpmu_dwords;
 
 	uint32_t lm_leakage;
+
+	struct device zap_dev;
 };
 
 #define to_a5xx_gpu(x) container_of(x, struct a5xx_gpu, base)
-- 
1.9.1



More information about the dri-devel mailing list