aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJordan Crouse <jcrouse@codeaurora.org>2019-04-19 15:46:14 -0400
committerRob Clark <robdclark@chromium.org>2019-04-21 10:37:16 -0400
commita9e2559c931d7c44ae7d677b12093956ffa864b9 (patch)
tree35d58a2afc0bdcb6198740809221e50615634e3c
parent026ef6354caa661ddd4c399590048e72a9d420bf (diff)
drm/msm/gpu: Move zap shader loading to adreno
a5xx and a6xx both share (mostly) the same code to load the zap shader and bring the GPU out of secure mode. Move the formerly 5xx specific code to adreno to make it available for a6xx too. Signed-off-by: Jordan Crouse <jcrouse@codeaurora.org> Signed-off-by: Rob Clark <robdclark@chromium.org>
-rw-r--r--drivers/gpu/drm/msm/adreno/a5xx_gpu.c111
-rw-r--r--drivers/gpu/drm/msm/adreno/adreno_gpu.c135
-rw-r--r--drivers/gpu/drm/msm/adreno/adreno_gpu.h6
3 files changed, 142 insertions, 110 deletions
diff --git a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c
index 270da14cba67..e5fcefa49f19 100644
--- a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c
+++ b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c
@@ -15,9 +15,6 @@
15#include <linux/types.h> 15#include <linux/types.h>
16#include <linux/cpumask.h> 16#include <linux/cpumask.h>
17#include <linux/qcom_scm.h> 17#include <linux/qcom_scm.h>
18#include <linux/dma-mapping.h>
19#include <linux/of_address.h>
20#include <linux/soc/qcom/mdt_loader.h>
21#include <linux/pm_opp.h> 18#include <linux/pm_opp.h>
22#include <linux/nvmem-consumer.h> 19#include <linux/nvmem-consumer.h>
23#include <linux/slab.h> 20#include <linux/slab.h>
@@ -30,96 +27,6 @@ static void a5xx_dump(struct msm_gpu *gpu);
30 27
31#define GPU_PAS_ID 13 28#define GPU_PAS_ID 13
32 29
33static int zap_shader_load_mdt(struct msm_gpu *gpu, const char *fwname)
34{
35 struct device *dev = &gpu->pdev->dev;
36 const struct firmware *fw;
37 struct device_node *np, *mem_np;
38 struct resource r;
39 phys_addr_t mem_phys;
40 ssize_t mem_size;
41 void *mem_region = NULL;
42 int ret;
43
44 if (!IS_ENABLED(CONFIG_ARCH_QCOM))
45 return -EINVAL;
46
47 np = of_get_child_by_name(dev->of_node, "zap-shader");
48 if (!np)
49 return -ENODEV;
50
51 mem_np = of_parse_phandle(np, "memory-region", 0);
52 of_node_put(np);
53 if (!mem_np)
54 return -EINVAL;
55
56 ret = of_address_to_resource(mem_np, 0, &r);
57 of_node_put(mem_np);
58 if (ret)
59 return ret;
60
61 mem_phys = r.start;
62 mem_size = resource_size(&r);
63
64 /* Request the MDT file for the firmware */
65 fw = adreno_request_fw(to_adreno_gpu(gpu), fwname);
66 if (IS_ERR(fw)) {
67 DRM_DEV_ERROR(dev, "Unable to load %s\n", fwname);
68 return PTR_ERR(fw);
69 }
70
71 /* Figure out how much memory we need */
72 mem_size = qcom_mdt_get_size(fw);
73 if (mem_size < 0) {
74 ret = mem_size;
75 goto out;
76 }
77
78 /* Allocate memory for the firmware image */
79 mem_region = memremap(mem_phys, mem_size, MEMREMAP_WC);
80 if (!mem_region) {
81 ret = -ENOMEM;
82 goto out;
83 }
84
85 /*
86 * Load the rest of the MDT
87 *
88 * Note that we could be dealing with two different paths, since
89 * with upstream linux-firmware it would be in a qcom/ subdir..
90 * adreno_request_fw() handles this, but qcom_mdt_load() does
91 * not. But since we've already gotten thru adreno_request_fw()
92 * we know which of the two cases it is:
93 */
94 if (to_adreno_gpu(gpu)->fwloc == FW_LOCATION_LEGACY) {
95 ret = qcom_mdt_load(dev, fw, fwname, GPU_PAS_ID,
96 mem_region, mem_phys, mem_size, NULL);
97 } else {
98 char *newname;
99
100 newname = kasprintf(GFP_KERNEL, "qcom/%s", fwname);
101
102 ret = qcom_mdt_load(dev, fw, newname, GPU_PAS_ID,
103 mem_region, mem_phys, mem_size, NULL);
104 kfree(newname);
105 }
106 if (ret)
107 goto out;
108
109 /* Send the image to the secure world */
110 ret = qcom_scm_pas_auth_and_reset(GPU_PAS_ID);
111 if (ret)
112 DRM_DEV_ERROR(dev, "Unable to authorize the image\n");
113
114out:
115 if (mem_region)
116 memunmap(mem_region);
117
118 release_firmware(fw);
119
120 return ret;
121}
122
123static void a5xx_flush(struct msm_gpu *gpu, struct msm_ringbuffer *ring) 30static void a5xx_flush(struct msm_gpu *gpu, struct msm_ringbuffer *ring)
124{ 31{
125 struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu); 32 struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
@@ -565,8 +472,6 @@ static int a5xx_zap_shader_resume(struct msm_gpu *gpu)
565static int a5xx_zap_shader_init(struct msm_gpu *gpu) 472static int a5xx_zap_shader_init(struct msm_gpu *gpu)
566{ 473{
567 static bool loaded; 474 static bool loaded;
568 struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
569 struct platform_device *pdev = gpu->pdev;
570 int ret; 475 int ret;
571 476
572 /* 477 /*
@@ -576,23 +481,9 @@ static int a5xx_zap_shader_init(struct msm_gpu *gpu)
576 if (loaded) 481 if (loaded)
577 return a5xx_zap_shader_resume(gpu); 482 return a5xx_zap_shader_resume(gpu);
578 483
579 /* We need SCM to be able to load the firmware */ 484 ret = adreno_zap_shader_load(gpu, GPU_PAS_ID);
580 if (!qcom_scm_is_available()) {
581 DRM_DEV_ERROR(&pdev->dev, "SCM is not available\n");
582 return -EPROBE_DEFER;
583 }
584
585 /* Each GPU has a target specific zap shader firmware name to use */
586 if (!adreno_gpu->info->zapfw) {
587 DRM_DEV_ERROR(&pdev->dev,
588 "Zap shader firmware file not specified for this target\n");
589 return -ENODEV;
590 }
591
592 ret = zap_shader_load_mdt(gpu, adreno_gpu->info->zapfw);
593 485
594 loaded = !ret; 486 loaded = !ret;
595
596 return ret; 487 return ret;
597} 488}
598 489
diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.c b/drivers/gpu/drm/msm/adreno/adreno_gpu.c
index 6de08cfc38aa..6f7f4114afcf 100644
--- a/drivers/gpu/drm/msm/adreno/adreno_gpu.c
+++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.c
@@ -19,13 +19,148 @@
19 19
20#include <linux/ascii85.h> 20#include <linux/ascii85.h>
21#include <linux/interconnect.h> 21#include <linux/interconnect.h>
22#include <linux/qcom_scm.h>
22#include <linux/kernel.h> 23#include <linux/kernel.h>
24#include <linux/of_address.h>
23#include <linux/pm_opp.h> 25#include <linux/pm_opp.h>
24#include <linux/slab.h> 26#include <linux/slab.h>
27#include <linux/soc/qcom/mdt_loader.h>
25#include "adreno_gpu.h" 28#include "adreno_gpu.h"
26#include "msm_gem.h" 29#include "msm_gem.h"
27#include "msm_mmu.h" 30#include "msm_mmu.h"
28 31
32static bool zap_available = true;
33
34static int zap_shader_load_mdt(struct msm_gpu *gpu, const char *fwname,
35 u32 pasid)
36{
37 struct device *dev = &gpu->pdev->dev;
38 const struct firmware *fw;
39 struct device_node *np, *mem_np;
40 struct resource r;
41 phys_addr_t mem_phys;
42 ssize_t mem_size;
43 void *mem_region = NULL;
44 int ret;
45
46 if (!IS_ENABLED(CONFIG_ARCH_QCOM)) {
47 zap_available = false;
48 return -EINVAL;
49 }
50
51 np = of_get_child_by_name(dev->of_node, "zap-shader");
52 if (!np) {
53 zap_available = false;
54 return -ENODEV;
55 }
56
57 mem_np = of_parse_phandle(np, "memory-region", 0);
58 of_node_put(np);
59 if (!mem_np) {
60 zap_available = false;
61 return -EINVAL;
62 }
63
64 ret = of_address_to_resource(mem_np, 0, &r);
65 of_node_put(mem_np);
66 if (ret)
67 return ret;
68
69 mem_phys = r.start;
70 mem_size = resource_size(&r);
71
72 /* Request the MDT file for the firmware */
73 fw = adreno_request_fw(to_adreno_gpu(gpu), fwname);
74 if (IS_ERR(fw)) {
75 DRM_DEV_ERROR(dev, "Unable to load %s\n", fwname);
76 return PTR_ERR(fw);
77 }
78
79 /* Figure out how much memory we need */
80 mem_size = qcom_mdt_get_size(fw);
81 if (mem_size < 0) {
82 ret = mem_size;
83 goto out;
84 }
85
86 /* Allocate memory for the firmware image */
87 mem_region = memremap(mem_phys, mem_size, MEMREMAP_WC);
88 if (!mem_region) {
89 ret = -ENOMEM;
90 goto out;
91 }
92
93 /*
94 * Load the rest of the MDT
95 *
96 * Note that we could be dealing with two different paths, since
97 * with upstream linux-firmware it would be in a qcom/ subdir..
98 * adreno_request_fw() handles this, but qcom_mdt_load() does
99 * not. But since we've already gotten through adreno_request_fw()
100 * we know which of the two cases it is:
101 */
102 if (to_adreno_gpu(gpu)->fwloc == FW_LOCATION_LEGACY) {
103 ret = qcom_mdt_load(dev, fw, fwname, pasid,
104 mem_region, mem_phys, mem_size, NULL);
105 } else {
106 char *newname;
107
108 newname = kasprintf(GFP_KERNEL, "qcom/%s", fwname);
109
110 ret = qcom_mdt_load(dev, fw, newname, pasid,
111 mem_region, mem_phys, mem_size, NULL);
112 kfree(newname);
113 }
114 if (ret)
115 goto out;
116
117 /* Send the image to the secure world */
118 ret = qcom_scm_pas_auth_and_reset(pasid);
119
120 /*
121 * If the scm call returns -EOPNOTSUPP we assume that this target
122 * doesn't need/support the zap shader so quietly fail
123 */
124 if (ret == -EOPNOTSUPP)
125 zap_available = false;
126 else if (ret)
127 DRM_DEV_ERROR(dev, "Unable to authorize the image\n");
128
129out:
130 if (mem_region)
131 memunmap(mem_region);
132
133 release_firmware(fw);
134
135 return ret;
136}
137
138int adreno_zap_shader_load(struct msm_gpu *gpu, u32 pasid)
139{
140 struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
141 struct platform_device *pdev = gpu->pdev;
142
143 /* Short cut if we determine the zap shader isn't available/needed */
144 if (!zap_available)
145 return -ENODEV;
146
147 /* We need SCM to be able to load the firmware */
148 if (!qcom_scm_is_available()) {
149 DRM_DEV_ERROR(&pdev->dev, "SCM is not available\n");
150 return -EPROBE_DEFER;
151 }
152
153 /* Each GPU has a target specific zap shader firmware name to use */
154 if (!adreno_gpu->info->zapfw) {
155 zap_available = false;
156 DRM_DEV_ERROR(&pdev->dev,
157 "Zap shader firmware file not specified for this target\n");
158 return -ENODEV;
159 }
160
161 return zap_shader_load_mdt(gpu, adreno_gpu->info->zapfw, pasid);
162}
163
29int adreno_get_param(struct msm_gpu *gpu, uint32_t param, uint64_t *value) 164int adreno_get_param(struct msm_gpu *gpu, uint32_t param, uint64_t *value)
30{ 165{
31 struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu); 166 struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.h b/drivers/gpu/drm/msm/adreno/adreno_gpu.h
index 5db459bc28a7..0925606ec9b5 100644
--- a/drivers/gpu/drm/msm/adreno/adreno_gpu.h
+++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.h
@@ -252,6 +252,12 @@ void adreno_gpu_state_destroy(struct msm_gpu_state *state);
252int adreno_gpu_state_get(struct msm_gpu *gpu, struct msm_gpu_state *state); 252int adreno_gpu_state_get(struct msm_gpu *gpu, struct msm_gpu_state *state);
253int adreno_gpu_state_put(struct msm_gpu_state *state); 253int adreno_gpu_state_put(struct msm_gpu_state *state);
254 254
255/*
256 * For a5xx and a6xx targets load the zap shader that is used to pull the GPU
257 * out of secure mode
258 */
259int adreno_zap_shader_load(struct msm_gpu *gpu, u32 pasid);
260
255/* ringbuffer helpers (the parts that are adreno specific) */ 261/* ringbuffer helpers (the parts that are adreno specific) */
256 262
257static inline void 263static inline void