diff options
Diffstat (limited to 'drivers/gpu/nvgpu/gm20b/acr_gm20b.c')
-rw-r--r-- | drivers/gpu/nvgpu/gm20b/acr_gm20b.c | 112 |
1 files changed, 102 insertions, 10 deletions
diff --git a/drivers/gpu/nvgpu/gm20b/acr_gm20b.c b/drivers/gpu/nvgpu/gm20b/acr_gm20b.c index 2e33c3f0..ba47d235 100644 --- a/drivers/gpu/nvgpu/gm20b/acr_gm20b.c +++ b/drivers/gpu/nvgpu/gm20b/acr_gm20b.c | |||
@@ -57,6 +57,7 @@ static void free_acr_resources(struct gk20a *g, struct ls_flcn_mgr *plsfm); | |||
57 | static get_ucode_details pmu_acr_supp_ucode_list[] = { | 57 | static get_ucode_details pmu_acr_supp_ucode_list[] = { |
58 | pmu_ucode_details, | 58 | pmu_ucode_details, |
59 | fecs_ucode_details, | 59 | fecs_ucode_details, |
60 | gpccs_ucode_details, | ||
60 | }; | 61 | }; |
61 | 62 | ||
62 | /*Once is LS mode, cpuctl_alias is only accessible*/ | 63 | /*Once is LS mode, cpuctl_alias is only accessible*/ |
@@ -209,6 +210,77 @@ rel_sig: | |||
209 | release_firmware(fecs_sig); | 210 | release_firmware(fecs_sig); |
210 | return err; | 211 | return err; |
211 | } | 212 | } |
213 | int gpccs_ucode_details(struct gk20a *g, struct flcn_ucode_img *p_img) | ||
214 | { | ||
215 | struct lsf_ucode_desc *lsf_desc; | ||
216 | const struct firmware *gpccs_sig; | ||
217 | int err; | ||
218 | |||
219 | if (g->ops.securegpccs == false) | ||
220 | return -ENOENT; | ||
221 | |||
222 | gpccs_sig = gk20a_request_firmware(g, GM20B_FECS_UCODE_SIG); | ||
223 | if (!gpccs_sig) { | ||
224 | gk20a_err(dev_from_gk20a(g), "failed to load gpccs sig"); | ||
225 | return -ENOENT; | ||
226 | } | ||
227 | lsf_desc = kzalloc(sizeof(struct lsf_ucode_desc), GFP_KERNEL); | ||
228 | if (!lsf_desc) { | ||
229 | err = -ENOMEM; | ||
230 | goto rel_sig; | ||
231 | } | ||
232 | memcpy(lsf_desc, (void *)gpccs_sig->data, | ||
233 | sizeof(struct lsf_ucode_desc)); | ||
234 | lsf_desc->falcon_id = LSF_FALCON_ID_GPCCS; | ||
235 | |||
236 | p_img->desc = kzalloc(sizeof(struct pmu_ucode_desc), GFP_KERNEL); | ||
237 | if (p_img->desc == NULL) { | ||
238 | err = -ENOMEM; | ||
239 | goto free_lsf_desc; | ||
240 | } | ||
241 | |||
242 | p_img->desc->bootloader_start_offset = | ||
243 | 0; | ||
244 | p_img->desc->bootloader_size = | ||
245 | ALIGN(g->ctxsw_ucode_info.gpccs.boot.size, 256); | ||
246 | p_img->desc->bootloader_imem_offset = | ||
247 | g->ctxsw_ucode_info.gpccs.boot_imem_offset; | ||
248 | p_img->desc->bootloader_entry_point = | ||
249 | g->ctxsw_ucode_info.gpccs.boot_entry; | ||
250 | |||
251 | p_img->desc->image_size = | ||
252 | ALIGN(g->ctxsw_ucode_info.gpccs.boot.size, 256) + | ||
253 | ALIGN(g->ctxsw_ucode_info.gpccs.code.size, 256) + | ||
254 | ALIGN(g->ctxsw_ucode_info.gpccs.data.size, 256); | ||
255 | p_img->desc->app_size = ALIGN(g->ctxsw_ucode_info.gpccs.code.size, 256) | ||
256 | + ALIGN(g->ctxsw_ucode_info.gpccs.data.size, 256); | ||
257 | p_img->desc->app_start_offset = p_img->desc->bootloader_size; | ||
258 | p_img->desc->app_imem_offset = 0; | ||
259 | p_img->desc->app_imem_entry = 0; | ||
260 | p_img->desc->app_dmem_offset = 0; | ||
261 | p_img->desc->app_resident_code_offset = 0; | ||
262 | p_img->desc->app_resident_code_size = | ||
263 | ALIGN(g->ctxsw_ucode_info.gpccs.code.size, 256); | ||
264 | p_img->desc->app_resident_data_offset = | ||
265 | ALIGN(g->ctxsw_ucode_info.gpccs.data.offset, 256) - | ||
266 | ALIGN(g->ctxsw_ucode_info.gpccs.code.offset, 256); | ||
267 | p_img->desc->app_resident_data_size = | ||
268 | ALIGN(g->ctxsw_ucode_info.gpccs.data.size, 256); | ||
269 | p_img->data = (u32 *)((u8 *)g->ctxsw_ucode_info.surface_desc.cpu_va + | ||
270 | g->ctxsw_ucode_info.gpccs.boot.offset); | ||
271 | p_img->data_size = ALIGN(p_img->desc->image_size, 256); | ||
272 | p_img->fw_ver = NULL; | ||
273 | p_img->header = NULL; | ||
274 | p_img->lsf_desc = (struct lsf_ucode_desc *)lsf_desc; | ||
275 | gm20b_dbg_pmu("gpccs fw loaded\n"); | ||
276 | release_firmware(gpccs_sig); | ||
277 | return 0; | ||
278 | free_lsf_desc: | ||
279 | kfree(lsf_desc); | ||
280 | rel_sig: | ||
281 | release_firmware(gpccs_sig); | ||
282 | return err; | ||
283 | } | ||
212 | 284 | ||
213 | int prepare_ucode_blob(struct gk20a *g) | 285 | int prepare_ucode_blob(struct gk20a *g) |
214 | { | 286 | { |
@@ -571,6 +643,18 @@ static int lsfm_init_wpr_contents(struct gk20a *g, struct ls_flcn_mgr *plsfm, | |||
571 | gm20b_dbg_pmu("bl_data_size :%x %x\n", | 643 | gm20b_dbg_pmu("bl_data_size :%x %x\n", |
572 | pnode->lsb_header.bl_data_size, | 644 | pnode->lsb_header.bl_data_size, |
573 | lsb_hdr->bl_data_size); | 645 | lsb_hdr->bl_data_size); |
646 | gm20b_dbg_pmu("app_code_off :%x %x\n", | ||
647 | pnode->lsb_header.app_code_off, | ||
648 | lsb_hdr->app_code_off); | ||
649 | gm20b_dbg_pmu("app_code_size :%x %x\n", | ||
650 | pnode->lsb_header.app_code_size, | ||
651 | lsb_hdr->app_code_size); | ||
652 | gm20b_dbg_pmu("app_data_off :%x %x\n", | ||
653 | pnode->lsb_header.app_data_off, | ||
654 | lsb_hdr->app_data_off); | ||
655 | gm20b_dbg_pmu("app_data_size :%x %x\n", | ||
656 | pnode->lsb_header.app_data_size, | ||
657 | lsb_hdr->app_data_size); | ||
574 | gm20b_dbg_pmu("flags :%x %x\n", | 658 | gm20b_dbg_pmu("flags :%x %x\n", |
575 | pnode->lsb_header.flags, lsb_hdr->flags); | 659 | pnode->lsb_header.flags, lsb_hdr->flags); |
576 | 660 | ||
@@ -702,16 +786,6 @@ static void lsfm_fill_static_lsb_hdr_info(struct gk20a *g, | |||
702 | VA range */ | 786 | VA range */ |
703 | pnode->lsb_header.bl_imem_off = | 787 | pnode->lsb_header.bl_imem_off = |
704 | pnode->ucode_img.desc->bootloader_imem_offset; | 788 | pnode->ucode_img.desc->bootloader_imem_offset; |
705 | pnode->lsb_header.app_code_off = | ||
706 | pnode->ucode_img.desc->app_start_offset + | ||
707 | pnode->ucode_img.desc->app_resident_code_offset; | ||
708 | pnode->lsb_header.app_code_size = | ||
709 | pnode->ucode_img.desc->app_resident_code_size; | ||
710 | pnode->lsb_header.app_data_off = | ||
711 | pnode->ucode_img.desc->app_start_offset + | ||
712 | pnode->ucode_img.desc->app_resident_data_offset; | ||
713 | pnode->lsb_header.app_data_size = | ||
714 | pnode->ucode_img.desc->app_resident_data_size; | ||
715 | 789 | ||
716 | /* TODO: OBJFLCN should export properties using which the below | 790 | /* TODO: OBJFLCN should export properties using which the below |
717 | flags should be populated.*/ | 791 | flags should be populated.*/ |
@@ -721,6 +795,10 @@ static void lsfm_fill_static_lsb_hdr_info(struct gk20a *g, | |||
721 | data = NV_FLCN_ACR_LSF_FLAG_DMACTL_REQ_CTX_TRUE; | 795 | data = NV_FLCN_ACR_LSF_FLAG_DMACTL_REQ_CTX_TRUE; |
722 | pnode->lsb_header.flags = data; | 796 | pnode->lsb_header.flags = data; |
723 | } | 797 | } |
798 | if (falcon_id == LSF_FALCON_ID_GPCCS) { | ||
799 | pnode->lsb_header.flags |= | ||
800 | NV_FLCN_ACR_LSF_FLAG_FORCE_PRIV_LOAD_TRUE; | ||
801 | } | ||
724 | } | 802 | } |
725 | } | 803 | } |
726 | 804 | ||
@@ -742,6 +820,9 @@ static int lsfm_add_ucode_img(struct gk20a *g, struct ls_flcn_mgr *plsfm, | |||
742 | pnode->wpr_header.bootstrap_owner = LSF_BOOTSTRAP_OWNER_DEFAULT; | 820 | pnode->wpr_header.bootstrap_owner = LSF_BOOTSTRAP_OWNER_DEFAULT; |
743 | pnode->wpr_header.status = LSF_IMAGE_STATUS_COPY; | 821 | pnode->wpr_header.status = LSF_IMAGE_STATUS_COPY; |
744 | 822 | ||
823 | if (falcon_id == LSF_FALCON_ID_GPCCS) | ||
824 | pnode->wpr_header.lazy_bootstrap = 1; | ||
825 | |||
745 | /*TODO to check if PDB_PROP_FLCN_LAZY_BOOTSTRAP is to be supported by | 826 | /*TODO to check if PDB_PROP_FLCN_LAZY_BOOTSTRAP is to be supported by |
746 | Android */ | 827 | Android */ |
747 | /* Fill in static LSB header info elsewhere */ | 828 | /* Fill in static LSB header info elsewhere */ |
@@ -854,6 +935,17 @@ static int lsf_gen_wpr_requirements(struct gk20a *g, struct ls_flcn_mgr *plsfm) | |||
854 | /* Finally, update ucode surface size to include updates */ | 935 | /* Finally, update ucode surface size to include updates */ |
855 | pnode->full_ucode_size = wpr_offset - | 936 | pnode->full_ucode_size = wpr_offset - |
856 | pnode->lsb_header.ucode_off; | 937 | pnode->lsb_header.ucode_off; |
938 | if (pnode->wpr_header.falcon_id != LSF_FALCON_ID_PMU) { | ||
939 | pnode->lsb_header.app_code_off = | ||
940 | pnode->lsb_header.bl_code_size; | ||
941 | pnode->lsb_header.app_code_size = | ||
942 | pnode->lsb_header.ucode_size - | ||
943 | pnode->lsb_header.bl_code_size; | ||
944 | pnode->lsb_header.app_data_off = | ||
945 | pnode->lsb_header.ucode_size; | ||
946 | pnode->lsb_header.app_data_size = | ||
947 | pnode->lsb_header.data_size; | ||
948 | } | ||
857 | pnode = pnode->next; | 949 | pnode = pnode->next; |
858 | } | 950 | } |
859 | plsfm->wpr_size = wpr_offset; | 951 | plsfm->wpr_size = wpr_offset; |