From 20408d5b32e5564b2fb410bc5b0bb0a198629437 Mon Sep 17 00:00:00 2001 From: Terje Bergstrom Date: Mon, 23 Jun 2014 09:56:45 +0300 Subject: gpu: nvgpu: Boot FECS to secure mode Boot FECS to secure mode if ACR is enabled. Bug 200006956 Change-Id: Ifc107704a6456af837b7f6c513c04d152b2f4d3a Signed-off-by: Terje Bergstrom Reviewed-on: http://git-master/r/424251 --- drivers/gpu/nvgpu/gm20b/acr_gm20b.c | 55 ++++++++++++++++++++++++++++++++++++- drivers/gpu/nvgpu/gm20b/acr_gm20b.h | 2 +- drivers/gpu/nvgpu/gm20b/gr_gm20b.c | 55 +++++++++++++++++++++++++++++++++++++ 3 files changed, 110 insertions(+), 2 deletions(-) (limited to 'drivers/gpu/nvgpu/gm20b') diff --git a/drivers/gpu/nvgpu/gm20b/acr_gm20b.c b/drivers/gpu/nvgpu/gm20b/acr_gm20b.c index 2b7be4f7..c03629fc 100644 --- a/drivers/gpu/nvgpu/gm20b/acr_gm20b.c +++ b/drivers/gpu/nvgpu/gm20b/acr_gm20b.c @@ -55,8 +55,9 @@ static int acr_ucode_patch_sig(struct gk20a *g, /*Globals*/ static void __iomem *mc = IO_ADDRESS(TEGRA_MC_BASE); -get_ucode_details pmu_acr_supp_ucode_list[MAX_SUPPORTED_LSFM] = { +get_ucode_details pmu_acr_supp_ucode_list[] = { pmu_ucode_details, + fecs_ucode_details, }; /*Once is LS mode, cpuctl_alias is only accessible*/ @@ -116,6 +117,57 @@ int pmu_ucode_details(struct gk20a *g, struct flcn_ucode_img *p_img) return 0; } +int fecs_ucode_details(struct gk20a *g, struct flcn_ucode_img *p_img) +{ + int err = 0; + struct lsf_ucode_desc *lsf_desc; + + lsf_desc = kzalloc(sizeof(struct lsf_ucode_desc), GFP_KERNEL); + if (!lsf_desc) + return -ENOMEM; + lsf_desc->falcon_id = LSF_FALCON_ID_FECS; + + p_img->desc = kzalloc(sizeof(struct pmu_ucode_desc), GFP_KERNEL); + if (p_img->desc == NULL) { + kfree(lsf_desc); + return -ENOMEM; + } + + p_img->desc->bootloader_start_offset = + g->ctxsw_ucode_info.fecs.boot.offset; + p_img->desc->bootloader_size = + g->ctxsw_ucode_info.fecs.boot.size; + p_img->desc->bootloader_imem_offset = + g->ctxsw_ucode_info.fecs.boot_imem_offset; + p_img->desc->bootloader_entry_point = + g->ctxsw_ucode_info.fecs.boot_entry; + + p_img->desc->image_size = g->ctxsw_ucode_info.fecs.boot.size + + g->ctxsw_ucode_info.fecs.code.size + + g->ctxsw_ucode_info.fecs.data.size; + p_img->desc->app_size = 0; + p_img->desc->app_start_offset = 0; + p_img->desc->app_imem_offset = 0; + p_img->desc->app_imem_entry = 0; + p_img->desc->app_dmem_offset = 0; + p_img->desc->app_resident_code_offset = + g->ctxsw_ucode_info.fecs.code.offset; + p_img->desc->app_resident_code_size = + g->ctxsw_ucode_info.fecs.code.size; + p_img->desc->app_resident_data_offset = + g->ctxsw_ucode_info.fecs.data.offset; + p_img->desc->app_resident_data_size = + g->ctxsw_ucode_info.fecs.data.size; + p_img->data = g->ctxsw_ucode_info.surface_desc.cpuva; + p_img->data_size = p_img->desc->image_size; + + p_img->fw_ver = NULL; + p_img->header = NULL; + p_img->lsf_desc = (struct lsf_ucode_desc *)lsf_desc; + gm20b_dbg_pmu("fecs fw loaded 2\n"); + return 0; +} + int prepare_ucode_blob(struct gk20a *g) { struct device *d = dev_from_gk20a(g); @@ -132,6 +184,7 @@ int prepare_ucode_blob(struct gk20a *g) memset((void *)plsfm, 0, sizeof(struct ls_flcn_mgr)); gm20b_dbg_pmu("fetching GMMU regs\n"); gm20b_mm_mmu_vpr_info_fetch(g); + gr_gk20a_init_ctxsw_ucode(g); /* Discover all managed falcons*/ status = lsfm_discover_ucode_images(g, plsfm); diff --git a/drivers/gpu/nvgpu/gm20b/acr_gm20b.h b/drivers/gpu/nvgpu/gm20b/acr_gm20b.h index e0dd50d0..84473c30 100644 --- a/drivers/gpu/nvgpu/gm20b/acr_gm20b.h +++ b/drivers/gpu/nvgpu/gm20b/acr_gm20b.h @@ -21,7 +21,7 @@ /*Defines*/ /*chip specific defines*/ -#define MAX_SUPPORTED_LSFM 1 /*PMU, FECS, GPCCS*/ +#define MAX_SUPPORTED_LSFM 2 /*PMU, FECS, GPCCS*/ #define LSF_UCODE_DATA_ALIGNMENT 4096 #define GM20B_PMU_UCODE_IMAGE "gpmu_ucode.bin" diff --git a/drivers/gpu/nvgpu/gm20b/gr_gm20b.c b/drivers/gpu/nvgpu/gm20b/gr_gm20b.c index 2efb7228..ae7864df 100644 --- a/drivers/gpu/nvgpu/gm20b/gr_gm20b.c +++ b/drivers/gpu/nvgpu/gm20b/gr_gm20b.c @@ -655,6 +655,56 @@ static int gr_gm20b_load_ctxsw_ucode_segments(struct gk20a *g, u64 addr_base, return 0; } +#ifdef CONFIG_TEGRA_ACR +static void gr_gm20b_load_gpccs_with_bootloader(struct gk20a *g) +{ + struct gk20a_ctxsw_ucode_info *ucode_info = &g->ctxsw_ucode_info; + u64 addr_base = ucode_info->ucode_gpuva; + + gr_gk20a_load_falcon_bind_instblk(g); + + g->ops.gr.falcon_load_ucode(g, addr_base, + &g->ctxsw_ucode_info.gpccs, + gr_gpcs_gpccs_falcon_hwcfg_r() - + gr_fecs_falcon_hwcfg_r()); +} + +static int gr_gm20b_load_ctxsw_ucode(struct gk20a *g) +{ + struct gk20a_ctxsw_ucode_info *ucode_info = &g->ctxsw_ucode_info; + u64 addr_base = ucode_info->ucode_gpuva; + int i; + + gk20a_dbg_fn(""); + + if (tegra_platform_is_linsim()) { + gk20a_writel(g, gr_fecs_ctxsw_mailbox_r(7), + gr_fecs_ctxsw_mailbox_value_f(0xc0de7777)); + gk20a_writel(g, gr_gpccs_ctxsw_mailbox_r(7), + gr_gpccs_ctxsw_mailbox_value_f(0xc0de7777)); + } + + gr_gk20a_load_falcon_bind_instblk(g); + g->ops.gr.falcon_load_ucode(g, addr_base, + &g->ctxsw_ucode_info.gpccs, + gr_gpcs_gpccs_falcon_hwcfg_r() - + gr_fecs_falcon_hwcfg_r()); + + gk20a_writel(g, gr_fecs_ctxsw_mailbox_clear_r(0), 0x0); + gk20a_writel(g, gr_fecs_ctxsw_mailbox_r(1), 0x1); + gk20a_writel(g, gr_fecs_ctxsw_mailbox_clear_r(6), 0xffffffff); + + gk20a_writel(g, gr_gpccs_dmactl_r(), gr_gpccs_dmactl_require_ctx_f(0)); + + gk20a_writel(g, gr_gpccs_cpuctl_r(), gr_gpccs_cpuctl_startcpu_f(1)); + gk20a_writel(g, gr_fecs_cpuctl_alias_r(), gr_fecs_cpuctl_startcpu_f(1)); + + gk20a_dbg_fn("done"); + + return 0; +} +#endif + void gm20b_init_gr(struct gpu_ops *gops) { gops->gr.init_gpc_mmu = gr_gm20b_init_gpc_mmu; @@ -676,4 +726,9 @@ void gm20b_init_gr(struct gpu_ops *gops) gops->gr.init_fs_state = gr_gm20b_ctx_state_floorsweep; gops->gr.set_hww_esr_report_mask = gr_gm20b_set_hww_esr_report_mask; gops->gr.falcon_load_ucode = gr_gm20b_load_ctxsw_ucode_segments; +#ifdef CONFIG_TEGRA_ACR + gops->gr.load_ctxsw_ucode = gr_gm20b_load_ctxsw_ucode; +#else + gops->gr.load_ctxsw_ucode = gr_gk20a_load_ctxsw_ucode; +#endif } -- cgit v1.2.2