aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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