summaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/gpu/nvgpu/gk20a/gk20a.h4
-rw-r--r--drivers/gpu/nvgpu/gk20a/hal_gk20a.c1
-rw-r--r--drivers/gpu/nvgpu/gk20a/pmu_gk20a.c8
-rw-r--r--drivers/gpu/nvgpu/gm20b/acr_gm20b.c112
-rw-r--r--drivers/gpu/nvgpu/gm20b/acr_gm20b.h4
-rw-r--r--drivers/gpu/nvgpu/gm20b/gr_gm20b.c86
-rw-r--r--drivers/gpu/nvgpu/gm20b/hal_gm20b.c1
-rw-r--r--drivers/gpu/nvgpu/gm20b/pmu_gm20b.c11
8 files changed, 173 insertions, 54 deletions
diff --git a/drivers/gpu/nvgpu/gk20a/gk20a.h b/drivers/gpu/nvgpu/gk20a/gk20a.h
index ce8d1d62..67a6123e 100644
--- a/drivers/gpu/nvgpu/gk20a/gk20a.h
+++ b/drivers/gpu/nvgpu/gk20a/gk20a.h
@@ -377,15 +377,15 @@ struct gpu_ops {
377 int (*pmu_setup_hw_and_bootstrap)(struct gk20a *g); 377 int (*pmu_setup_hw_and_bootstrap)(struct gk20a *g);
378 int (*pmu_setup_elpg)(struct gk20a *g); 378 int (*pmu_setup_elpg)(struct gk20a *g);
379 int (*init_wpr_region)(struct gk20a *g); 379 int (*init_wpr_region)(struct gk20a *g);
380 bool lspmuwprinitdone; 380 u32 lspmuwprinitdone;
381 bool fecsbootstrapdone; 381 bool fecsbootstrapdone;
382 u32 fecsrecoveryinprogress;
383 } pmu; 382 } pmu;
384 struct { 383 struct {
385 int (*init_clk_support)(struct gk20a *g); 384 int (*init_clk_support)(struct gk20a *g);
386 int (*suspend_clk_support)(struct gk20a *g); 385 int (*suspend_clk_support)(struct gk20a *g);
387 } clk; 386 } clk;
388 bool privsecurity; 387 bool privsecurity;
388 bool securegpccs;
389 struct { 389 struct {
390 const struct regop_offset_range* ( 390 const struct regop_offset_range* (
391 *get_global_whitelist_ranges)(void); 391 *get_global_whitelist_ranges)(void);
diff --git a/drivers/gpu/nvgpu/gk20a/hal_gk20a.c b/drivers/gpu/nvgpu/gk20a/hal_gk20a.c
index 5a9c38ea..b8268e1f 100644
--- a/drivers/gpu/nvgpu/gk20a/hal_gk20a.c
+++ b/drivers/gpu/nvgpu/gk20a/hal_gk20a.c
@@ -52,6 +52,7 @@ int gk20a_init_hal(struct gk20a *g)
52 52
53 *gops = gk20a_ops; 53 *gops = gk20a_ops;
54 gops->privsecurity = 0; 54 gops->privsecurity = 0;
55 gops->securegpccs = 0;
55 gk20a_init_mc(gops); 56 gk20a_init_mc(gops);
56 gk20a_init_ltc(gops); 57 gk20a_init_ltc(gops);
57 gk20a_init_gr_ops(gops); 58 gk20a_init_gr_ops(gops);
diff --git a/drivers/gpu/nvgpu/gk20a/pmu_gk20a.c b/drivers/gpu/nvgpu/gk20a/pmu_gk20a.c
index 6313b9d5..2456c784 100644
--- a/drivers/gpu/nvgpu/gk20a/pmu_gk20a.c
+++ b/drivers/gpu/nvgpu/gk20a/pmu_gk20a.c
@@ -3333,12 +3333,16 @@ int pmu_wait_message_cond(struct pmu_gk20a *pmu, u32 timeout,
3333 struct gk20a *g = gk20a_from_pmu(pmu); 3333 struct gk20a *g = gk20a_from_pmu(pmu);
3334 unsigned long end_jiffies = jiffies + msecs_to_jiffies(timeout); 3334 unsigned long end_jiffies = jiffies + msecs_to_jiffies(timeout);
3335 unsigned long delay = GR_IDLE_CHECK_DEFAULT; 3335 unsigned long delay = GR_IDLE_CHECK_DEFAULT;
3336 u32 servicedpmuint;
3336 3337
3338 servicedpmuint = pwr_falcon_irqstat_halt_true_f() |
3339 pwr_falcon_irqstat_exterr_true_f() |
3340 pwr_falcon_irqstat_swgen0_true_f();
3337 do { 3341 do {
3338 if (*var == val) 3342 if (*var == val)
3339 return 0; 3343 return 0;
3340 3344
3341 if (gk20a_readl(g, pwr_falcon_irqstat_r())) 3345 if (gk20a_readl(g, pwr_falcon_irqstat_r()) & servicedpmuint)
3342 gk20a_pmu_isr(g); 3346 gk20a_pmu_isr(g);
3343 3347
3344 usleep_range(delay, delay * 2); 3348 usleep_range(delay, delay * 2);
@@ -4042,8 +4046,6 @@ int gk20a_pmu_destroy(struct gk20a *g)
4042 pmu->zbc_ready = false; 4046 pmu->zbc_ready = false;
4043 g->ops.pmu.lspmuwprinitdone = false; 4047 g->ops.pmu.lspmuwprinitdone = false;
4044 g->ops.pmu.fecsbootstrapdone = false; 4048 g->ops.pmu.fecsbootstrapdone = false;
4045 g->ops.pmu.fecsrecoveryinprogress = 0;
4046
4047 4049
4048 gk20a_dbg_fn("done"); 4050 gk20a_dbg_fn("done");
4049 return 0; 4051 return 0;
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);
57static get_ucode_details pmu_acr_supp_ucode_list[] = { 57static 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}
213int 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;
278free_lsf_desc:
279 kfree(lsf_desc);
280rel_sig:
281 release_firmware(gpccs_sig);
282 return err;
283}
212 284
213int prepare_ucode_blob(struct gk20a *g) 285int 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;
diff --git a/drivers/gpu/nvgpu/gm20b/acr_gm20b.h b/drivers/gpu/nvgpu/gm20b/acr_gm20b.h
index c279d797..3a5fa7d0 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 2 /*PMU, FECS, GPCCS*/ 24#define MAX_SUPPORTED_LSFM 3 /*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_image.bin" 27#define GM20B_PMU_UCODE_IMAGE "gpmu_ucode_image.bin"
@@ -75,6 +75,8 @@
75#define NV_FLCN_ACR_LSF_FLAG_LOAD_CODE_AT_0_TRUE 1 75#define NV_FLCN_ACR_LSF_FLAG_LOAD_CODE_AT_0_TRUE 1
76#define NV_FLCN_ACR_LSF_FLAG_DMACTL_REQ_CTX_FALSE 0 76#define NV_FLCN_ACR_LSF_FLAG_DMACTL_REQ_CTX_FALSE 0
77#define NV_FLCN_ACR_LSF_FLAG_DMACTL_REQ_CTX_TRUE 4 77#define NV_FLCN_ACR_LSF_FLAG_DMACTL_REQ_CTX_TRUE 4
78#define NV_FLCN_ACR_LSF_FLAG_FORCE_PRIV_LOAD_TRUE 8
79#define NV_FLCN_ACR_LSF_FLAG_FORCE_PRIV_LOAD_FALSE 0
78 80
79/*! 81/*!
80 * Light Secure WPR Content Alignments 82 * Light Secure WPR Content Alignments
diff --git a/drivers/gpu/nvgpu/gm20b/gr_gm20b.c b/drivers/gpu/nvgpu/gm20b/gr_gm20b.c
index 55a21c98..1fa1eb24 100644
--- a/drivers/gpu/nvgpu/gm20b/gr_gm20b.c
+++ b/drivers/gpu/nvgpu/gm20b/gr_gm20b.c
@@ -710,6 +710,10 @@ static int gr_gm20b_ctx_wait_lsf_ready(struct gk20a *g, u32 timeout, u32 val)
710static int gr_gm20b_load_ctxsw_ucode(struct gk20a *g) 710static int gr_gm20b_load_ctxsw_ucode(struct gk20a *g)
711{ 711{
712 u32 err; 712 u32 err;
713 unsigned long timeout = gk20a_get_gr_idle_timeout(g);
714 u32 reg_offset = gr_gpcs_gpccs_falcon_hwcfg_r() -
715 gr_fecs_falcon_hwcfg_r();
716
713 gk20a_dbg_fn(""); 717 gk20a_dbg_fn("");
714 718
715 if (tegra_platform_is_linsim()) { 719 if (tegra_platform_is_linsim()) {
@@ -719,50 +723,68 @@ static int gr_gm20b_load_ctxsw_ucode(struct gk20a *g)
719 gr_gpccs_ctxsw_mailbox_value_f(0xc0de7777)); 723 gr_gpccs_ctxsw_mailbox_value_f(0xc0de7777));
720 } 724 }
721 725
722 gk20a_writel(g, gr_fecs_ctxsw_mailbox_clear_r(0), ~0x0); 726 if (g->ops.pmu.fecsbootstrapdone) {
723 gm20b_pmu_load_lsf(g, LSF_FALCON_ID_FECS); 727 gk20a_writel(g, gr_fecs_ctxsw_mailbox_clear_r(0), ~0x0);
724 728 gm20b_pmu_load_lsf(g, LSF_FALCON_ID_FECS);
725 gr_gm20b_load_gpccs_with_bootloader(g);
726
727 if (g->ops.pmu.fecsrecoveryinprogress) {
728 unsigned long timeout = gk20a_get_gr_idle_timeout(g);
729 err = gr_gm20b_ctx_wait_lsf_ready(g, timeout, 0x55AA55AA); 729 err = gr_gm20b_ctx_wait_lsf_ready(g, timeout, 0x55AA55AA);
730 if (err) { 730 if (err) {
731 gk20a_err(dev_from_gk20a(g), "Unable to recover FECS"); 731 gk20a_err(dev_from_gk20a(g), "Unable to recover FECS");
732 return err; 732 return err;
733 } else { 733 } else {
734 g->ops.pmu.fecsrecoveryinprogress = 0; 734 if (!g->ops.securegpccs) {
735 gk20a_writel(g, gr_fecs_ctxsw_mailbox_clear_r(0), ~0x0); 735 gr_gm20b_load_gpccs_with_bootloader(g);
736 gk20a_writel(g, gr_fecs_ctxsw_mailbox_r(1), 0x1); 736 gk20a_writel(g, gr_gpccs_dmactl_r(),
737 gk20a_writel(g, gr_fecs_ctxsw_mailbox_clear_r(6),
738 0xffffffff);
739
740 gk20a_writel(g, gr_gpccs_dmactl_r(),
741 gr_gpccs_dmactl_require_ctx_f(0)); 737 gr_gpccs_dmactl_require_ctx_f(0));
742 gk20a_writel(g, gr_gpccs_cpuctl_r(), 738 gk20a_writel(g, gr_gpccs_cpuctl_r(),
743 gr_gpccs_cpuctl_startcpu_f(1)); 739 gr_gpccs_cpuctl_startcpu_f(1));
744 740 } else {
745 gk20a_writel(g, gr_fecs_cpuctl_alias_r(), 741 gk20a_writel(g,
746 gr_fecs_cpuctl_startcpu_f(1)); 742 gr_fecs_ctxsw_mailbox_clear_r(0), ~0x0);
743 gm20b_pmu_load_lsf(g, LSF_FALCON_ID_GPCCS);
744 err = gr_gm20b_ctx_wait_lsf_ready(g, timeout,
745 0x55AA55AA);
746 gk20a_writel(g, reg_offset +
747 gr_fecs_cpuctl_alias_r(),
748 gr_gpccs_cpuctl_startcpu_f(1));
749 }
747 } 750 }
748 } 751 } else {
749
750
751 if (!g->ops.pmu.fecsbootstrapdone) {
752 g->ops.pmu.fecsbootstrapdone = true; 752 g->ops.pmu.fecsbootstrapdone = true;
753 gk20a_writel(g, gr_fecs_ctxsw_mailbox_clear_r(0), ~0x0); 753 if (!g->ops.securegpccs) {
754 gk20a_writel(g, gr_fecs_ctxsw_mailbox_r(1), 0x1); 754 gr_gm20b_load_gpccs_with_bootloader(g);
755 gk20a_writel(g, gr_fecs_ctxsw_mailbox_clear_r(6), 0xffffffff); 755 gk20a_writel(g, gr_gpccs_dmactl_r(),
756 756 gr_gpccs_dmactl_require_ctx_f(0));
757 gk20a_writel(g, gr_gpccs_dmactl_r(), 757 gk20a_writel(g, gr_gpccs_cpuctl_r(),
758 gr_gpccs_dmactl_require_ctx_f(0)); 758 gr_gpccs_cpuctl_startcpu_f(1));
759 gk20a_writel(g, gr_gpccs_cpuctl_r(), 759 } else {
760 pmu_wait_message_cond(&g->pmu,
761 gk20a_get_gr_idle_timeout(g),
762 &g->ops.pmu.lspmuwprinitdone, 1);
763 if (!g->ops.pmu.lspmuwprinitdone) {
764 gk20a_err(dev_from_gk20a(g),
765 "PMU WPR needed but not ready yet");
766 return -ETIMEDOUT;
767 }
768 gk20a_writel(g, gr_fecs_ctxsw_mailbox_clear_r(0), ~0x0);
769 gm20b_pmu_load_lsf(g, LSF_FALCON_ID_GPCCS);
770 err = gr_gm20b_ctx_wait_lsf_ready(g, timeout,
771 0x55AA55AA);
772 if (err) {
773 gk20a_err(dev_from_gk20a(g),
774 "Unable to boot GPCCS\n");
775 return err;
776 }
777 gk20a_writel(g, reg_offset +
778 gr_fecs_cpuctl_alias_r(),
760 gr_gpccs_cpuctl_startcpu_f(1)); 779 gr_gpccs_cpuctl_startcpu_f(1));
761 780 }
762 gk20a_writel(g, gr_fecs_cpuctl_alias_r(),
763 gr_fecs_cpuctl_startcpu_f(1));
764 } 781 }
765 782
783 gk20a_writel(g, gr_fecs_ctxsw_mailbox_clear_r(0), ~0x0);
784 gk20a_writel(g, gr_fecs_ctxsw_mailbox_r(1), 0x1);
785 gk20a_writel(g, gr_fecs_ctxsw_mailbox_clear_r(6), 0xffffffff);
786 gk20a_writel(g, gr_fecs_cpuctl_alias_r(),
787 gr_fecs_cpuctl_startcpu_f(1));
766 gk20a_dbg_fn("done"); 788 gk20a_dbg_fn("done");
767 789
768 return 0; 790 return 0;
diff --git a/drivers/gpu/nvgpu/gm20b/hal_gm20b.c b/drivers/gpu/nvgpu/gm20b/hal_gm20b.c
index d5a6e422..1ab65836 100644
--- a/drivers/gpu/nvgpu/gm20b/hal_gm20b.c
+++ b/drivers/gpu/nvgpu/gm20b/hal_gm20b.c
@@ -91,6 +91,7 @@ int gm20b_init_hal(struct gk20a *g)
91 struct nvgpu_gpu_characteristics *c = &g->gpu_characteristics; 91 struct nvgpu_gpu_characteristics *c = &g->gpu_characteristics;
92 92
93 *gops = gm20b_ops; 93 *gops = gm20b_ops;
94 gops->securegpccs = false;
94#ifdef CONFIG_TEGRA_ACR 95#ifdef CONFIG_TEGRA_ACR
95 if (tegra_platform_is_linsim()) { 96 if (tegra_platform_is_linsim()) {
96 gops->privsecurity = 1; 97 gops->privsecurity = 1;
diff --git a/drivers/gpu/nvgpu/gm20b/pmu_gm20b.c b/drivers/gpu/nvgpu/gm20b/pmu_gm20b.c
index c25d2d56..28b40b1c 100644
--- a/drivers/gpu/nvgpu/gm20b/pmu_gm20b.c
+++ b/drivers/gpu/nvgpu/gm20b/pmu_gm20b.c
@@ -161,7 +161,7 @@ static void pmu_handle_acr_init_wpr_msg(struct gk20a *g, struct pmu_msg *msg,
161 gm20b_dbg_pmu("reply PMU_ACR_CMD_ID_INIT_WPR_REGION"); 161 gm20b_dbg_pmu("reply PMU_ACR_CMD_ID_INIT_WPR_REGION");
162 162
163 if (msg->msg.acr.acrmsg.errorcode == PMU_ACR_SUCCESS) 163 if (msg->msg.acr.acrmsg.errorcode == PMU_ACR_SUCCESS)
164 g->ops.pmu.lspmuwprinitdone = true; 164 g->ops.pmu.lspmuwprinitdone = 1;
165 gk20a_dbg_fn("done"); 165 gk20a_dbg_fn("done");
166} 166}
167 167
@@ -213,7 +213,7 @@ void gm20b_pmu_load_lsf(struct gk20a *g, u8 falcon_id)
213 gk20a_dbg_fn(""); 213 gk20a_dbg_fn("");
214 214
215 gm20b_dbg_pmu("wprinit status = %x\n", g->ops.pmu.lspmuwprinitdone); 215 gm20b_dbg_pmu("wprinit status = %x\n", g->ops.pmu.lspmuwprinitdone);
216 if (g->ops.pmu.lspmuwprinitdone && g->ops.pmu.fecsbootstrapdone) { 216 if (g->ops.pmu.lspmuwprinitdone) {
217 /* send message to load FECS falcon */ 217 /* send message to load FECS falcon */
218 memset(&cmd, 0, sizeof(struct pmu_cmd)); 218 memset(&cmd, 0, sizeof(struct pmu_cmd));
219 cmd.hdr.unit_id = PMU_UNIT_ACR; 219 cmd.hdr.unit_id = PMU_UNIT_ACR;
@@ -224,8 +224,8 @@ void gm20b_pmu_load_lsf(struct gk20a *g, u8 falcon_id)
224 cmd.cmd.acr.bootstrap_falcon.flags = 224 cmd.cmd.acr.bootstrap_falcon.flags =
225 PMU_ACR_CMD_BOOTSTRAP_FALCON_FLAGS_RESET_YES; 225 PMU_ACR_CMD_BOOTSTRAP_FALCON_FLAGS_RESET_YES;
226 cmd.cmd.acr.bootstrap_falcon.falconid = falcon_id; 226 cmd.cmd.acr.bootstrap_falcon.falconid = falcon_id;
227 gm20b_dbg_pmu("cmd post PMU_ACR_CMD_ID_BOOTSTRAP_FALCON"); 227 gm20b_dbg_pmu("cmd post PMU_ACR_CMD_ID_BOOTSTRAP_FALCON: %x\n",
228 g->ops.pmu.fecsrecoveryinprogress = 1; 228 falcon_id);
229 gk20a_pmu_cmd_post(g, &cmd, NULL, NULL, PMU_COMMAND_QUEUE_HPQ, 229 gk20a_pmu_cmd_post(g, &cmd, NULL, NULL, PMU_COMMAND_QUEUE_HPQ,
230 pmu_handle_fecs_boot_acr_msg, pmu, &seq, ~0); 230 pmu_handle_fecs_boot_acr_msg, pmu, &seq, ~0);
231 } 231 }
@@ -244,7 +244,6 @@ void gm20b_init_pmu_ops(struct gpu_ops *gops)
244 gops->pmu.init_wpr_region = NULL; 244 gops->pmu.init_wpr_region = NULL;
245 } 245 }
246 gops->pmu.pmu_setup_elpg = gm20b_pmu_setup_elpg; 246 gops->pmu.pmu_setup_elpg = gm20b_pmu_setup_elpg;
247 gops->pmu.lspmuwprinitdone = false; 247 gops->pmu.lspmuwprinitdone = 0;
248 gops->pmu.fecsbootstrapdone = false; 248 gops->pmu.fecsbootstrapdone = false;
249 gops->pmu.fecsrecoveryinprogress = 0;
250} 249}