summaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorMahantesh Kumbar <mkumbar@nvidia.com>2017-07-04 14:06:55 -0400
committermobile promotions <svcmobile_promotions@nvidia.com>2017-07-05 13:39:44 -0400
commita3802a2ae9d5ffeaec038a9ce7fc9fa333f1a68c (patch)
treef6d7ff8b6912a503f2f193ed73415d2479914aa9 /drivers
parente768e74df8be8abe8442d958bde7a4a2886694ba (diff)
gpu: nvgpu: falcon copy to IMEM support
- Added falcon interface/HAL copy to IMEM method - Deleted copy to IMEM code & then replaced with nvgpu_flcn_copy_to_imem() in multiple files - Code cleanup JIRA NVGPU-117 Change-Id: Ic47197ef7dc449e5bf1f418ac02598500c96da21 Signed-off-by: Mahantesh Kumbar <mkumbar@nvidia.com> Reviewed-on: https://git-master/r/1513273 Reviewed-by: Automatic_Commit_Validation_User GVS: Gerrit_Virtual_Submit Reviewed-by: Terje Bergstrom <tbergstrom@nvidia.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/gpu/nvgpu/common/falcon/falcon.c16
-rw-r--r--drivers/gpu/nvgpu/gk20a/flcn_gk20a.c55
-rw-r--r--drivers/gpu/nvgpu/gm206/bios_gm206.c37
-rw-r--r--drivers/gpu/nvgpu/gm20b/acr_gm20b.c45
-rw-r--r--drivers/gpu/nvgpu/gp106/sec2_gp106.c54
-rw-r--r--drivers/gpu/nvgpu/include/nvgpu/falcon.h4
6 files changed, 99 insertions, 112 deletions
diff --git a/drivers/gpu/nvgpu/common/falcon/falcon.c b/drivers/gpu/nvgpu/common/falcon/falcon.c
index 3795dd09..74d78e86 100644
--- a/drivers/gpu/nvgpu/common/falcon/falcon.c
+++ b/drivers/gpu/nvgpu/common/falcon/falcon.c
@@ -180,6 +180,22 @@ int nvgpu_flcn_copy_to_dmem(struct nvgpu_falcon *flcn,
180 return flcn_ops->copy_to_dmem(flcn, dst, src, size, port); 180 return flcn_ops->copy_to_dmem(flcn, dst, src, size, port);
181} 181}
182 182
183int nvgpu_flcn_copy_to_imem(struct nvgpu_falcon *flcn,
184 u32 dst, u8 *src, u32 size, u8 port, bool sec, u32 tag)
185{
186 struct nvgpu_falcon_ops *flcn_ops = &flcn->flcn_ops;
187 int status = -EINVAL;
188
189 if (flcn_ops->copy_to_imem)
190 status = flcn_ops->copy_to_imem(flcn, dst, src, size, port,
191 sec, tag);
192 else
193 nvgpu_warn(flcn->g, "Invalid op on falcon 0x%x ",
194 flcn->flcn_id);
195
196 return status;
197}
198
183void nvgpu_flcn_sw_init(struct gk20a *g, u32 flcn_id) 199void nvgpu_flcn_sw_init(struct gk20a *g, u32 flcn_id)
184{ 200{
185 struct nvgpu_falcon *flcn = NULL; 201 struct nvgpu_falcon *flcn = NULL;
diff --git a/drivers/gpu/nvgpu/gk20a/flcn_gk20a.c b/drivers/gpu/nvgpu/gk20a/flcn_gk20a.c
index b52652e2..158f4d8b 100644
--- a/drivers/gpu/nvgpu/gk20a/flcn_gk20a.c
+++ b/drivers/gpu/nvgpu/gk20a/flcn_gk20a.c
@@ -269,6 +269,60 @@ static int gk20a_flcn_copy_to_dmem(struct nvgpu_falcon *flcn,
269 return 0; 269 return 0;
270} 270}
271 271
272static int gk20a_flcn_copy_to_imem(struct nvgpu_falcon *flcn, u32 dst,
273 u8 *src, u32 size, u8 port, bool sec, u32 tag)
274{
275 struct gk20a *g = flcn->g;
276 u32 base_addr = flcn->flcn_base;
277 u32 *src_u32 = (u32 *)src;
278 u32 words = 0;
279 u32 blk = 0;
280 u32 i = 0;
281
282 nvgpu_log_info(g, "upload %d bytes to 0x%x", size, dst);
283
284 if (flcn_mem_overflow_check(flcn, dst, size, MEM_IMEM)) {
285 nvgpu_err(g, "incorrect parameters");
286 return -EINVAL;
287 }
288
289 nvgpu_mutex_acquire(&flcn->copy_lock);
290
291 words = size >> 2;
292 blk = dst >> 8;
293
294 nvgpu_log_info(g, "upload %d words to 0x%x block %d, tag 0x%x",
295 words, dst, blk, tag);
296
297 gk20a_writel(g, base_addr + falcon_falcon_imemc_r(port),
298 falcon_falcon_imemc_offs_f(dst >> 2) |
299 falcon_falcon_imemc_blk_f(blk) |
300 /* Set Auto-Increment on write */
301 falcon_falcon_imemc_aincw_f(1) |
302 sec << 28);
303
304 for (i = 0; i < words; i++) {
305 if (i % 64 == 0) {
306 /* tag is always 256B aligned */
307 gk20a_writel(g, base_addr + falcon_falcon_imemt_r(0),
308 tag);
309 tag++;
310 }
311
312 gk20a_writel(g, base_addr + falcon_falcon_imemd_r(port),
313 src_u32[i]);
314 }
315
316 /* WARNING : setting remaining bytes in block to 0x0 */
317 while (i % 64) {
318 gk20a_writel(g, base_addr + falcon_falcon_imemd_r(port), 0);
319 i++;
320 }
321
322 nvgpu_mutex_release(&flcn->copy_lock);
323
324 return 0;
325}
272 326
273static void gk20a_falcon_engine_dependency_ops(struct nvgpu_falcon *flcn) 327static void gk20a_falcon_engine_dependency_ops(struct nvgpu_falcon *flcn)
274{ 328{
@@ -302,6 +356,7 @@ void gk20a_falcon_ops(struct nvgpu_falcon *flcn)
302 flcn_ops->is_falcon_scrubbing_done = gk20a_is_falcon_scrubbing_done; 356 flcn_ops->is_falcon_scrubbing_done = gk20a_is_falcon_scrubbing_done;
303 flcn_ops->copy_from_dmem = gk20a_flcn_copy_from_dmem; 357 flcn_ops->copy_from_dmem = gk20a_flcn_copy_from_dmem;
304 flcn_ops->copy_to_dmem = gk20a_flcn_copy_to_dmem; 358 flcn_ops->copy_to_dmem = gk20a_flcn_copy_to_dmem;
359 flcn_ops->copy_to_imem = gk20a_flcn_copy_to_imem;
305 360
306 gk20a_falcon_engine_dependency_ops(flcn); 361 gk20a_falcon_engine_dependency_ops(flcn);
307} 362}
diff --git a/drivers/gpu/nvgpu/gm206/bios_gm206.c b/drivers/gpu/nvgpu/gm206/bios_gm206.c
index be089f2f..14610120 100644
--- a/drivers/gpu/nvgpu/gm206/bios_gm206.c
+++ b/drivers/gpu/nvgpu/gm206/bios_gm206.c
@@ -18,6 +18,7 @@
18#include <nvgpu/nvgpu_common.h> 18#include <nvgpu/nvgpu_common.h>
19#include <nvgpu/timers.h> 19#include <nvgpu/timers.h>
20#include <nvgpu/firmware.h> 20#include <nvgpu/firmware.h>
21#include <nvgpu/falcon.h>
21 22
22#include "gk20a/gk20a.h" 23#include "gk20a/gk20a.h"
23#include "gk20a/platform_gk20a.h" 24#include "gk20a/platform_gk20a.h"
@@ -39,40 +40,8 @@
39static void upload_code(struct gk20a *g, u32 dst, 40static void upload_code(struct gk20a *g, u32 dst,
40 u8 *src, u32 size, u8 port, bool sec) 41 u8 *src, u32 size, u8 port, bool sec)
41{ 42{
42 u32 i, words; 43 nvgpu_flcn_copy_to_imem(g->pmu.flcn, dst, src, size, port, sec,
43 u32 *src_u32 = (u32 *)src; 44 dst >> 8);
44 u32 blk;
45 u32 tag = 0;
46
47 gk20a_dbg_info("upload %d bytes to %x", size, dst);
48
49 words = size >> 2;
50
51 blk = dst >> 8;
52 tag = blk;
53
54 gk20a_dbg_info("upload %d words to %x block %d",
55 words, dst, blk);
56
57 gk20a_writel(g, pwr_falcon_imemc_r(port),
58 pwr_falcon_imemc_offs_f(dst >> 2) |
59 pwr_falcon_imemc_blk_f(blk) |
60 pwr_falcon_imemc_aincw_f(1) |
61 sec << 28);
62
63 for (i = 0; i < words; i++) {
64 if (i % 64 == 0) {
65 gk20a_writel(g, 0x10a188, tag);
66 tag++;
67 }
68
69 gk20a_writel(g, pwr_falcon_imemd_r(port), src_u32[i]);
70 }
71
72 while (i % 64) {
73 gk20a_writel(g, pwr_falcon_imemd_r(port), 0);
74 i++;
75 }
76} 45}
77 46
78static void upload_data(struct gk20a *g, u32 dst, u8 *src, u32 size, u8 port) 47static void upload_data(struct gk20a *g, u32 dst, u8 *src, u32 size, u8 port)
diff --git a/drivers/gpu/nvgpu/gm20b/acr_gm20b.c b/drivers/gpu/nvgpu/gm20b/acr_gm20b.c
index ee861933..3a638373 100644
--- a/drivers/gpu/nvgpu/gm20b/acr_gm20b.c
+++ b/drivers/gpu/nvgpu/gm20b/acr_gm20b.c
@@ -27,6 +27,7 @@
27#include <nvgpu/acr/nvgpu_acr.h> 27#include <nvgpu/acr/nvgpu_acr.h>
28#include <nvgpu/firmware.h> 28#include <nvgpu/firmware.h>
29#include <nvgpu/pmu.h> 29#include <nvgpu/pmu.h>
30#include <nvgpu/falcon.h>
30 31
31#include <nvgpu/linux/dma.h> 32#include <nvgpu/linux/dma.h>
32 33
@@ -1221,12 +1222,9 @@ static int bl_bootstrap(struct nvgpu_pmu *pmu,
1221 struct gk20a *g = gk20a_from_pmu(pmu); 1222 struct gk20a *g = gk20a_from_pmu(pmu);
1222 struct acr_desc *acr = &g->acr; 1223 struct acr_desc *acr = &g->acr;
1223 struct mm_gk20a *mm = &g->mm; 1224 struct mm_gk20a *mm = &g->mm;
1224 u32 imem_dst_blk = 0;
1225 u32 virt_addr = 0; 1225 u32 virt_addr = 0;
1226 u32 tag = 0;
1227 u32 index = 0;
1228 struct hsflcn_bl_desc *pmu_bl_gm10x_desc = g->acr.pmu_hsbl_desc; 1226 struct hsflcn_bl_desc *pmu_bl_gm10x_desc = g->acr.pmu_hsbl_desc;
1229 u32 *bl_ucode; 1227 u32 dst;
1230 1228
1231 gk20a_dbg_fn(""); 1229 gk20a_dbg_fn("");
1232 gk20a_writel(g, pwr_falcon_itfen_r(), 1230 gk20a_writel(g, pwr_falcon_itfen_r(),
@@ -1238,42 +1236,21 @@ static int bl_bootstrap(struct nvgpu_pmu *pmu,
1238 pwr_pmu_new_instblk_valid_f(1) | 1236 pwr_pmu_new_instblk_valid_f(1) |
1239 pwr_pmu_new_instblk_target_sys_coh_f()); 1237 pwr_pmu_new_instblk_target_sys_coh_f());
1240 1238
1241 /* TBD: load all other surfaces */
1242 /*copy bootloader interface structure to dmem*/ 1239 /*copy bootloader interface structure to dmem*/
1243 gk20a_writel(g, pwr_falcon_dmemc_r(0),
1244 pwr_falcon_dmemc_offs_f(0) |
1245 pwr_falcon_dmemc_blk_f(0) |
1246 pwr_falcon_dmemc_aincw_f(1));
1247 nvgpu_flcn_copy_to_dmem(pmu->flcn, 0, (u8 *)pbl_desc, 1240 nvgpu_flcn_copy_to_dmem(pmu->flcn, 0, (u8 *)pbl_desc,
1248 sizeof(struct flcn_bl_dmem_desc), 0); 1241 sizeof(struct flcn_bl_dmem_desc), 0);
1249 /*TODO This had to be copied to bl_desc_dmem_load_off, but since
1250 * this is 0, so ok for now*/
1251
1252 /* Now copy bootloader to TOP of IMEM */
1253 imem_dst_blk = (pwr_falcon_hwcfg_imem_size_v(
1254 gk20a_readl(g, pwr_falcon_hwcfg_r()))) - bl_sz/256;
1255
1256 /* Set Auto-Increment on write */
1257 gk20a_writel(g, pwr_falcon_imemc_r(0),
1258 pwr_falcon_imemc_offs_f(0) |
1259 pwr_falcon_imemc_blk_f(imem_dst_blk) |
1260 pwr_falcon_imemc_aincw_f(1));
1261 virt_addr = pmu_bl_gm10x_desc->bl_start_tag << 8;
1262 tag = virt_addr >> 8; /* tag is always 256B aligned */
1263 bl_ucode = (u32 *)(acr->hsbl_ucode.cpu_va);
1264 for (index = 0; index < bl_sz/4; index++) {
1265 if ((index % 64) == 0) {
1266 gk20a_writel(g, pwr_falcon_imemt_r(0),
1267 (tag & 0xffff) << 0);
1268 tag++;
1269 }
1270 gk20a_writel(g, pwr_falcon_imemd_r(0),
1271 bl_ucode[index] & 0xffffffff);
1272 }
1273 1242
1274 gk20a_writel(g, pwr_falcon_imemt_r(0), (0 & 0xffff) << 0); 1243 /* copy bootloader to TOP of IMEM */
1244 dst = (pwr_falcon_hwcfg_imem_size_v(
1245 gk20a_readl(g, pwr_falcon_hwcfg_r())) << 8) - bl_sz;
1246
1247 nvgpu_flcn_copy_to_imem(pmu->flcn, dst,
1248 (u8 *)(acr->hsbl_ucode.cpu_va), bl_sz, 0, 0,
1249 pmu_bl_gm10x_desc->bl_start_tag);
1250
1275 gm20b_dbg_pmu("Before starting falcon with BL\n"); 1251 gm20b_dbg_pmu("Before starting falcon with BL\n");
1276 1252
1253 virt_addr = pmu_bl_gm10x_desc->bl_start_tag << 8;
1277 gk20a_writel(g, pwr_falcon_bootvec_r(), 1254 gk20a_writel(g, pwr_falcon_bootvec_r(),
1278 pwr_falcon_bootvec_vec_f(virt_addr)); 1255 pwr_falcon_bootvec_vec_f(virt_addr));
1279 1256
diff --git a/drivers/gpu/nvgpu/gp106/sec2_gp106.c b/drivers/gpu/nvgpu/gp106/sec2_gp106.c
index 0f265710..ccd1b3ad 100644
--- a/drivers/gpu/nvgpu/gp106/sec2_gp106.c
+++ b/drivers/gpu/nvgpu/gp106/sec2_gp106.c
@@ -12,19 +12,11 @@
12 */ 12 */
13 13
14#include <nvgpu/pmu.h> 14#include <nvgpu/pmu.h>
15#include <nvgpu/falcon.h>
15 16
16#include "gk20a/gk20a.h" 17#include "gk20a/gk20a.h"
17#include "gk20a/pmu_gk20a.h"
18
19#include "gm20b/pmu_gm20b.h"
20
21#include "gp10b/pmu_gp10b.h"
22
23#include "gp106/pmu_gp106.h"
24
25#include "sec2_gp106.h" 18#include "sec2_gp106.h"
26 19
27#include <nvgpu/hw/gp106/hw_mc_gp106.h>
28#include <nvgpu/hw/gp106/hw_pwr_gp106.h> 20#include <nvgpu/hw/gp106/hw_pwr_gp106.h>
29#include <nvgpu/hw/gp106/hw_psec_gp106.h> 21#include <nvgpu/hw/gp106/hw_psec_gp106.h>
30 22
@@ -73,13 +65,10 @@ int bl_bootstrap_sec2(struct nvgpu_pmu *pmu,
73 struct gk20a *g = gk20a_from_pmu(pmu); 65 struct gk20a *g = gk20a_from_pmu(pmu);
74 struct acr_desc *acr = &g->acr; 66 struct acr_desc *acr = &g->acr;
75 struct mm_gk20a *mm = &g->mm; 67 struct mm_gk20a *mm = &g->mm;
76 u32 imem_dst_blk = 0;
77 u32 virt_addr = 0; 68 u32 virt_addr = 0;
78 u32 tag = 0;
79 u32 index = 0;
80 struct hsflcn_bl_desc *pmu_bl_gm10x_desc = g->acr.pmu_hsbl_desc; 69 struct hsflcn_bl_desc *pmu_bl_gm10x_desc = g->acr.pmu_hsbl_desc;
81 u32 *bl_ucode;
82 u32 data = 0; 70 u32 data = 0;
71 u32 dst;
83 72
84 gk20a_dbg_fn(""); 73 gk20a_dbg_fn("");
85 74
@@ -104,44 +93,23 @@ int bl_bootstrap_sec2(struct nvgpu_pmu *pmu,
104 data |= (1 << 3); 93 data |= (1 << 3);
105 gk20a_writel(g, psec_falcon_engctl_r(), data); 94 gk20a_writel(g, psec_falcon_engctl_r(), data);
106 95
107 /* TBD: load all other surfaces */
108 /*copy bootloader interface structure to dmem*/ 96 /*copy bootloader interface structure to dmem*/
109 gk20a_writel(g, psec_falcon_dmemc_r(0),
110 psec_falcon_dmemc_offs_f(0) |
111 psec_falcon_dmemc_blk_f(0) |
112 psec_falcon_dmemc_aincw_f(1));
113 nvgpu_flcn_copy_to_dmem(&g->sec2_flcn, 0, (u8 *)desc, 97 nvgpu_flcn_copy_to_dmem(&g->sec2_flcn, 0, (u8 *)desc,
114 sizeof(struct flcn_bl_dmem_desc), 0); 98 sizeof(struct flcn_bl_dmem_desc), 0);
115 /*TODO This had to be copied to bl_desc_dmem_load_off, but since 99
116 * this is 0, so ok for now*/ 100 /* copy bootloader to TOP of IMEM */
117 101 dst = (psec_falcon_hwcfg_imem_size_v(
118 /* Now copy bootloader to TOP of IMEM */ 102 gk20a_readl(g, psec_falcon_hwcfg_r())) << 8) - bl_sz;
119 imem_dst_blk = (psec_falcon_hwcfg_imem_size_v( 103
120 gk20a_readl(g, psec_falcon_hwcfg_r()))) - bl_sz/256; 104 nvgpu_flcn_copy_to_imem(&g->sec2_flcn, dst,
121 105 (u8 *)(acr->hsbl_ucode.cpu_va), bl_sz, 0, 0,
122 /* Set Auto-Increment on write */ 106 pmu_bl_gm10x_desc->bl_start_tag);
123 gk20a_writel(g, psec_falcon_imemc_r(0),
124 psec_falcon_imemc_offs_f(0) |
125 psec_falcon_imemc_blk_f(imem_dst_blk) |
126 psec_falcon_imemc_aincw_f(1));
127 virt_addr = pmu_bl_gm10x_desc->bl_start_tag << 8;
128 tag = virt_addr >> 8; /* tag is always 256B aligned */
129 bl_ucode = (u32 *)(acr->hsbl_ucode.cpu_va);
130 for (index = 0; index < bl_sz/4; index++) {
131 if ((index % 64) == 0) {
132 gk20a_writel(g, psec_falcon_imemt_r(0),
133 (tag & 0xffff) << 0);
134 tag++;
135 }
136 gk20a_writel(g, psec_falcon_imemd_r(0),
137 bl_ucode[index] & 0xffffffff);
138 }
139 gk20a_writel(g, psec_falcon_imemt_r(0), (0 & 0xffff) << 0);
140 107
141 gm20b_dbg_pmu("Before starting falcon with BL\n"); 108 gm20b_dbg_pmu("Before starting falcon with BL\n");
142 109
143 gk20a_writel(g, psec_falcon_mailbox0_r(), 0xDEADA5A5); 110 gk20a_writel(g, psec_falcon_mailbox0_r(), 0xDEADA5A5);
144 111
112 virt_addr = pmu_bl_gm10x_desc->bl_start_tag << 8;
145 gk20a_writel(g, psec_falcon_bootvec_r(), 113 gk20a_writel(g, psec_falcon_bootvec_r(),
146 psec_falcon_bootvec_vec_f(virt_addr)); 114 psec_falcon_bootvec_vec_f(virt_addr));
147 115
diff --git a/drivers/gpu/nvgpu/include/nvgpu/falcon.h b/drivers/gpu/nvgpu/include/nvgpu/falcon.h
index ca61ae46..36e9ffb1 100644
--- a/drivers/gpu/nvgpu/include/nvgpu/falcon.h
+++ b/drivers/gpu/nvgpu/include/nvgpu/falcon.h
@@ -140,7 +140,7 @@ struct nvgpu_falcon_ops {
140 int (*copy_from_imem)(struct nvgpu_falcon *flcn, u32 src, u8 *dst, 140 int (*copy_from_imem)(struct nvgpu_falcon *flcn, u32 src, u8 *dst,
141 u32 size, u8 port); 141 u32 size, u8 port);
142 int (*copy_to_imem)(struct nvgpu_falcon *flcn, u32 dst, u8 *src, 142 int (*copy_to_imem)(struct nvgpu_falcon *flcn, u32 dst, u8 *src,
143 u32 size, u8 port); 143 u32 size, u8 port, bool sec, u32 tag);
144 int (*dma_copy)(struct nvgpu_falcon *flcn, 144 int (*dma_copy)(struct nvgpu_falcon *flcn,
145 struct nvgpu_falcon_dma_info *dma_info); 145 struct nvgpu_falcon_dma_info *dma_info);
146 u32 (*mailbox_read)(struct nvgpu_falcon *flcn, u32 mailbox_index); 146 u32 (*mailbox_read)(struct nvgpu_falcon *flcn, u32 mailbox_index);
@@ -180,6 +180,8 @@ int nvgpu_flcn_copy_from_dmem(struct nvgpu_falcon *flcn,
180 u32 src, u8 *dst, u32 size, u8 port); 180 u32 src, u8 *dst, u32 size, u8 port);
181int nvgpu_flcn_copy_to_dmem(struct nvgpu_falcon *flcn, 181int nvgpu_flcn_copy_to_dmem(struct nvgpu_falcon *flcn,
182 u32 dst, u8 *src, u32 size, u8 port); 182 u32 dst, u8 *src, u32 size, u8 port);
183int nvgpu_flcn_copy_to_imem(struct nvgpu_falcon *flcn,
184 u32 dst, u8 *src, u32 size, u8 port, bool sec, u32 tag);
183int nvgpu_flcn_dma_copy(struct nvgpu_falcon *flcn, 185int nvgpu_flcn_dma_copy(struct nvgpu_falcon *flcn,
184 struct nvgpu_falcon_dma_info *dma_info); 186 struct nvgpu_falcon_dma_info *dma_info);
185u32 nvgpu_flcn_mailbox_read(struct nvgpu_falcon *flcn, u32 mailbox_index); 187u32 nvgpu_flcn_mailbox_read(struct nvgpu_falcon *flcn, u32 mailbox_index);