diff options
Diffstat (limited to 'drivers/gpu/nvgpu/gm20b')
-rw-r--r-- | drivers/gpu/nvgpu/gm20b/acr_gm20b.c | 55 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/gm20b/acr_gm20b.h | 2 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/gm20b/gr_gm20b.c | 55 |
3 files changed, 110 insertions, 2 deletions
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, | |||
55 | 55 | ||
56 | /*Globals*/ | 56 | /*Globals*/ |
57 | static void __iomem *mc = IO_ADDRESS(TEGRA_MC_BASE); | 57 | static void __iomem *mc = IO_ADDRESS(TEGRA_MC_BASE); |
58 | get_ucode_details pmu_acr_supp_ucode_list[MAX_SUPPORTED_LSFM] = { | 58 | get_ucode_details pmu_acr_supp_ucode_list[] = { |
59 | pmu_ucode_details, | 59 | pmu_ucode_details, |
60 | fecs_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*/ |
@@ -116,6 +117,57 @@ int pmu_ucode_details(struct gk20a *g, struct flcn_ucode_img *p_img) | |||
116 | return 0; | 117 | return 0; |
117 | } | 118 | } |
118 | 119 | ||
120 | int fecs_ucode_details(struct gk20a *g, struct flcn_ucode_img *p_img) | ||
121 | { | ||
122 | int err = 0; | ||
123 | struct lsf_ucode_desc *lsf_desc; | ||
124 | |||
125 | lsf_desc = kzalloc(sizeof(struct lsf_ucode_desc), GFP_KERNEL); | ||
126 | if (!lsf_desc) | ||
127 | return -ENOMEM; | ||
128 | lsf_desc->falcon_id = LSF_FALCON_ID_FECS; | ||
129 | |||
130 | p_img->desc = kzalloc(sizeof(struct pmu_ucode_desc), GFP_KERNEL); | ||
131 | if (p_img->desc == NULL) { | ||
132 | kfree(lsf_desc); | ||
133 | return -ENOMEM; | ||
134 | } | ||
135 | |||
136 | p_img->desc->bootloader_start_offset = | ||
137 | g->ctxsw_ucode_info.fecs.boot.offset; | ||
138 | p_img->desc->bootloader_size = | ||
139 | g->ctxsw_ucode_info.fecs.boot.size; | ||
140 | p_img->desc->bootloader_imem_offset = | ||
141 | g->ctxsw_ucode_info.fecs.boot_imem_offset; | ||
142 | p_img->desc->bootloader_entry_point = | ||
143 | g->ctxsw_ucode_info.fecs.boot_entry; | ||
144 | |||
145 | p_img->desc->image_size = g->ctxsw_ucode_info.fecs.boot.size + | ||
146 | g->ctxsw_ucode_info.fecs.code.size + | ||
147 | g->ctxsw_ucode_info.fecs.data.size; | ||
148 | p_img->desc->app_size = 0; | ||
149 | p_img->desc->app_start_offset = 0; | ||
150 | p_img->desc->app_imem_offset = 0; | ||
151 | p_img->desc->app_imem_entry = 0; | ||
152 | p_img->desc->app_dmem_offset = 0; | ||
153 | p_img->desc->app_resident_code_offset = | ||
154 | g->ctxsw_ucode_info.fecs.code.offset; | ||
155 | p_img->desc->app_resident_code_size = | ||
156 | g->ctxsw_ucode_info.fecs.code.size; | ||
157 | p_img->desc->app_resident_data_offset = | ||
158 | g->ctxsw_ucode_info.fecs.data.offset; | ||
159 | p_img->desc->app_resident_data_size = | ||
160 | g->ctxsw_ucode_info.fecs.data.size; | ||
161 | p_img->data = g->ctxsw_ucode_info.surface_desc.cpuva; | ||
162 | p_img->data_size = p_img->desc->image_size; | ||
163 | |||
164 | p_img->fw_ver = NULL; | ||
165 | p_img->header = NULL; | ||
166 | p_img->lsf_desc = (struct lsf_ucode_desc *)lsf_desc; | ||
167 | gm20b_dbg_pmu("fecs fw loaded 2\n"); | ||
168 | return 0; | ||
169 | } | ||
170 | |||
119 | int prepare_ucode_blob(struct gk20a *g) | 171 | int prepare_ucode_blob(struct gk20a *g) |
120 | { | 172 | { |
121 | struct device *d = dev_from_gk20a(g); | 173 | struct device *d = dev_from_gk20a(g); |
@@ -132,6 +184,7 @@ int prepare_ucode_blob(struct gk20a *g) | |||
132 | memset((void *)plsfm, 0, sizeof(struct ls_flcn_mgr)); | 184 | memset((void *)plsfm, 0, sizeof(struct ls_flcn_mgr)); |
133 | gm20b_dbg_pmu("fetching GMMU regs\n"); | 185 | gm20b_dbg_pmu("fetching GMMU regs\n"); |
134 | gm20b_mm_mmu_vpr_info_fetch(g); | 186 | gm20b_mm_mmu_vpr_info_fetch(g); |
187 | gr_gk20a_init_ctxsw_ucode(g); | ||
135 | 188 | ||
136 | /* Discover all managed falcons*/ | 189 | /* Discover all managed falcons*/ |
137 | status = lsfm_discover_ucode_images(g, plsfm); | 190 | 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 @@ | |||
21 | /*Defines*/ | 21 | /*Defines*/ |
22 | 22 | ||
23 | /*chip specific defines*/ | 23 | /*chip specific defines*/ |
24 | #define MAX_SUPPORTED_LSFM 1 /*PMU, FECS, GPCCS*/ | 24 | #define MAX_SUPPORTED_LSFM 2 /*PMU, FECS, GPCCS*/ |
25 | #define LSF_UCODE_DATA_ALIGNMENT 4096 | 25 | #define LSF_UCODE_DATA_ALIGNMENT 4096 |
26 | 26 | ||
27 | #define GM20B_PMU_UCODE_IMAGE "gpmu_ucode.bin" | 27 | #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, | |||
655 | return 0; | 655 | return 0; |
656 | } | 656 | } |
657 | 657 | ||
658 | #ifdef CONFIG_TEGRA_ACR | ||
659 | static void gr_gm20b_load_gpccs_with_bootloader(struct gk20a *g) | ||
660 | { | ||
661 | struct gk20a_ctxsw_ucode_info *ucode_info = &g->ctxsw_ucode_info; | ||
662 | u64 addr_base = ucode_info->ucode_gpuva; | ||
663 | |||
664 | gr_gk20a_load_falcon_bind_instblk(g); | ||
665 | |||
666 | g->ops.gr.falcon_load_ucode(g, addr_base, | ||
667 | &g->ctxsw_ucode_info.gpccs, | ||
668 | gr_gpcs_gpccs_falcon_hwcfg_r() - | ||
669 | gr_fecs_falcon_hwcfg_r()); | ||
670 | } | ||
671 | |||
672 | static int gr_gm20b_load_ctxsw_ucode(struct gk20a *g) | ||
673 | { | ||
674 | struct gk20a_ctxsw_ucode_info *ucode_info = &g->ctxsw_ucode_info; | ||
675 | u64 addr_base = ucode_info->ucode_gpuva; | ||
676 | int i; | ||
677 | |||
678 | gk20a_dbg_fn(""); | ||
679 | |||
680 | if (tegra_platform_is_linsim()) { | ||
681 | gk20a_writel(g, gr_fecs_ctxsw_mailbox_r(7), | ||
682 | gr_fecs_ctxsw_mailbox_value_f(0xc0de7777)); | ||
683 | gk20a_writel(g, gr_gpccs_ctxsw_mailbox_r(7), | ||
684 | gr_gpccs_ctxsw_mailbox_value_f(0xc0de7777)); | ||
685 | } | ||
686 | |||
687 | gr_gk20a_load_falcon_bind_instblk(g); | ||
688 | g->ops.gr.falcon_load_ucode(g, addr_base, | ||
689 | &g->ctxsw_ucode_info.gpccs, | ||
690 | gr_gpcs_gpccs_falcon_hwcfg_r() - | ||
691 | gr_fecs_falcon_hwcfg_r()); | ||
692 | |||
693 | gk20a_writel(g, gr_fecs_ctxsw_mailbox_clear_r(0), 0x0); | ||
694 | gk20a_writel(g, gr_fecs_ctxsw_mailbox_r(1), 0x1); | ||
695 | gk20a_writel(g, gr_fecs_ctxsw_mailbox_clear_r(6), 0xffffffff); | ||
696 | |||
697 | gk20a_writel(g, gr_gpccs_dmactl_r(), gr_gpccs_dmactl_require_ctx_f(0)); | ||
698 | |||
699 | gk20a_writel(g, gr_gpccs_cpuctl_r(), gr_gpccs_cpuctl_startcpu_f(1)); | ||
700 | gk20a_writel(g, gr_fecs_cpuctl_alias_r(), gr_fecs_cpuctl_startcpu_f(1)); | ||
701 | |||
702 | gk20a_dbg_fn("done"); | ||
703 | |||
704 | return 0; | ||
705 | } | ||
706 | #endif | ||
707 | |||
658 | void gm20b_init_gr(struct gpu_ops *gops) | 708 | void gm20b_init_gr(struct gpu_ops *gops) |
659 | { | 709 | { |
660 | gops->gr.init_gpc_mmu = gr_gm20b_init_gpc_mmu; | 710 | gops->gr.init_gpc_mmu = gr_gm20b_init_gpc_mmu; |
@@ -676,4 +726,9 @@ void gm20b_init_gr(struct gpu_ops *gops) | |||
676 | gops->gr.init_fs_state = gr_gm20b_ctx_state_floorsweep; | 726 | gops->gr.init_fs_state = gr_gm20b_ctx_state_floorsweep; |
677 | gops->gr.set_hww_esr_report_mask = gr_gm20b_set_hww_esr_report_mask; | 727 | gops->gr.set_hww_esr_report_mask = gr_gm20b_set_hww_esr_report_mask; |
678 | gops->gr.falcon_load_ucode = gr_gm20b_load_ctxsw_ucode_segments; | 728 | gops->gr.falcon_load_ucode = gr_gm20b_load_ctxsw_ucode_segments; |
729 | #ifdef CONFIG_TEGRA_ACR | ||
730 | gops->gr.load_ctxsw_ucode = gr_gm20b_load_ctxsw_ucode; | ||
731 | #else | ||
732 | gops->gr.load_ctxsw_ucode = gr_gk20a_load_ctxsw_ucode; | ||
733 | #endif | ||
679 | } | 734 | } |