summaryrefslogtreecommitdiffstats
path: root/drivers/gpu
diff options
context:
space:
mode:
authorTerje Bergstrom <tbergstrom@nvidia.com>2014-06-23 02:56:45 -0400
committerDan Willemsen <dwillemsen@nvidia.com>2015-03-18 15:10:18 -0400
commit20408d5b32e5564b2fb410bc5b0bb0a198629437 (patch)
tree965dac6015b8ab7f9865f79a07b0876025f63309 /drivers/gpu
parentb57c6501c75b478b08b9ea6e226c55e5039b5c86 (diff)
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 <tbergstrom@nvidia.com> Reviewed-on: http://git-master/r/424251
Diffstat (limited to 'drivers/gpu')
-rw-r--r--drivers/gpu/nvgpu/gk20a/gk20a.c6
-rw-r--r--drivers/gpu/nvgpu/gk20a/gk20a.h1
-rw-r--r--drivers/gpu/nvgpu/gk20a/gr_gk20a.c89
-rw-r--r--drivers/gpu/nvgpu/gk20a/gr_gk20a.h4
-rw-r--r--drivers/gpu/nvgpu/gk20a/pmu_gk20a.c29
-rw-r--r--drivers/gpu/nvgpu/gk20a/pmu_gk20a.h3
-rw-r--r--drivers/gpu/nvgpu/gm20b/acr_gm20b.c55
-rw-r--r--drivers/gpu/nvgpu/gm20b/acr_gm20b.h2
-rw-r--r--drivers/gpu/nvgpu/gm20b/gr_gm20b.c55
9 files changed, 201 insertions, 43 deletions
diff --git a/drivers/gpu/nvgpu/gk20a/gk20a.c b/drivers/gpu/nvgpu/gk20a/gk20a.c
index 5305f612..2310b81c 100644
--- a/drivers/gpu/nvgpu/gk20a/gk20a.c
+++ b/drivers/gpu/nvgpu/gk20a/gk20a.c
@@ -897,6 +897,12 @@ static int gk20a_pm_finalize_poweron(struct device *dev)
897 goto done; 897 goto done;
898 } 898 }
899 899
900 err = gk20a_enable_gr_hw(g);
901 if (err) {
902 gk20a_err(dev, "failed to enable gr");
903 goto done;
904 }
905
900 err = g->ops.pmu.prepare_ucode(g); 906 err = g->ops.pmu.prepare_ucode(g);
901 if (err) { 907 if (err) {
902 gk20a_err(dev, "failed to init pmu ucode"); 908 gk20a_err(dev, "failed to init pmu ucode");
diff --git a/drivers/gpu/nvgpu/gk20a/gk20a.h b/drivers/gpu/nvgpu/gk20a/gk20a.h
index 07826675..991891c5 100644
--- a/drivers/gpu/nvgpu/gk20a/gk20a.h
+++ b/drivers/gpu/nvgpu/gk20a/gk20a.h
@@ -128,6 +128,7 @@ struct gpu_ops {
128 u64 addr_base, 128 u64 addr_base,
129 struct gk20a_ctxsw_ucode_segments *segments, 129 struct gk20a_ctxsw_ucode_segments *segments,
130 u32 reg_offset); 130 u32 reg_offset);
131 int (*load_ctxsw_ucode)(struct gk20a *g);
131 } gr; 132 } gr;
132 const char *name; 133 const char *name;
133 struct { 134 struct {
diff --git a/drivers/gpu/nvgpu/gk20a/gr_gk20a.c b/drivers/gpu/nvgpu/gk20a/gr_gk20a.c
index 4a6dd6c5..bd9476e4 100644
--- a/drivers/gpu/nvgpu/gk20a/gr_gk20a.c
+++ b/drivers/gpu/nvgpu/gk20a/gr_gk20a.c
@@ -1867,7 +1867,7 @@ static int gr_gk20a_copy_ctxsw_ucode_segments(
1867 return 0; 1867 return 0;
1868} 1868}
1869 1869
1870static int gr_gk20a_init_ctxsw_ucode(struct gk20a *g) 1870int gr_gk20a_init_ctxsw_ucode(struct gk20a *g)
1871{ 1871{
1872 struct device *d = dev_from_gk20a(g); 1872 struct device *d = dev_from_gk20a(g);
1873 struct mm_gk20a *mm = &g->mm; 1873 struct mm_gk20a *mm = &g->mm;
@@ -1992,7 +1992,7 @@ static int gr_gk20a_init_ctxsw_ucode(struct gk20a *g)
1992 return err; 1992 return err;
1993} 1993}
1994 1994
1995static void gr_gk20a_load_falcon_bind_instblk(struct gk20a *g) 1995void gr_gk20a_load_falcon_bind_instblk(struct gk20a *g)
1996{ 1996{
1997 struct gk20a_ctxsw_ucode_info *ucode_info = &g->ctxsw_ucode_info; 1997 struct gk20a_ctxsw_ucode_info *ucode_info = &g->ctxsw_ucode_info;
1998 int retries = 20; 1998 int retries = 20;
@@ -2149,9 +2149,8 @@ static void gr_gk20a_load_falcon_with_bootloader(struct gk20a *g)
2149 gr_fecs_falcon_hwcfg_r()); 2149 gr_fecs_falcon_hwcfg_r());
2150} 2150}
2151 2151
2152static int gr_gk20a_load_ctxsw_ucode(struct gk20a *g, struct gr_gk20a *gr) 2152int gr_gk20a_load_ctxsw_ucode(struct gk20a *g)
2153{ 2153{
2154 u32 ret;
2155 2154
2156 gk20a_dbg_fn(""); 2155 gk20a_dbg_fn("");
2157 2156
@@ -2171,11 +2170,20 @@ static int gr_gk20a_load_ctxsw_ucode(struct gk20a *g, struct gr_gk20a *gr)
2171 gr_gk20a_load_falcon_imem(g); 2170 gr_gk20a_load_falcon_imem(g);
2172 gr_gk20a_start_falcon_ucode(g); 2171 gr_gk20a_start_falcon_ucode(g);
2173 } else { 2172 } else {
2174 if (!gr->skip_ucode_init) 2173 if (!g->gr.skip_ucode_init)
2175 gr_gk20a_init_ctxsw_ucode(g); 2174 gr_gk20a_init_ctxsw_ucode(g);
2176 gr_gk20a_load_falcon_with_bootloader(g); 2175 gr_gk20a_load_falcon_with_bootloader(g);
2177 gr->skip_ucode_init = true; 2176 g->gr.skip_ucode_init = true;
2178 } 2177 }
2178 gk20a_dbg_fn("done");
2179 return 0;
2180}
2181
2182static int gr_gk20a_wait_ctxsw_ready(struct gk20a *g)
2183{
2184 u32 ret;
2185
2186 gk20a_dbg_fn("");
2179 2187
2180 ret = gr_gk20a_ctx_wait_ucode(g, 0, 0, 2188 ret = gr_gk20a_ctx_wait_ucode(g, 0, 0,
2181 GR_IS_UCODE_OP_EQUAL, 2189 GR_IS_UCODE_OP_EQUAL,
@@ -4449,9 +4457,36 @@ static int gr_gk20a_wait_mem_scrubbing(struct gk20a *g)
4449 return -ETIMEDOUT; 4457 return -ETIMEDOUT;
4450} 4458}
4451 4459
4452static int gk20a_init_gr_reset_enable_hw(struct gk20a *g) 4460int gr_gk20a_init_ctxsw(struct gk20a *g)
4453{ 4461{
4454 struct gr_gk20a *gr = &g->gr; 4462 struct gr_gk20a *gr = &g->gr;
4463 u32 err = 0;
4464
4465 err = g->ops.gr.load_ctxsw_ucode(g);
4466 if (err)
4467 goto out;
4468
4469 err = gr_gk20a_wait_ctxsw_ready(g);
4470 if (err)
4471 goto out;
4472
4473 /* this appears query for sw states but fecs actually init
4474 ramchain, etc so this is hw init */
4475 err = gr_gk20a_init_ctx_state(g, gr);
4476 if (err)
4477 goto out;
4478
4479out:
4480 if (err)
4481 gk20a_err(dev_from_gk20a(g), "fail");
4482 else
4483 gk20a_dbg_fn("done");
4484
4485 return 0;
4486}
4487
4488int gk20a_init_gr_reset_enable_hw(struct gk20a *g)
4489{
4455 struct av_list_gk20a *sw_non_ctx_load = &g->gr.ctx_vars.sw_non_ctx_load; 4490 struct av_list_gk20a *sw_non_ctx_load = &g->gr.ctx_vars.sw_non_ctx_load;
4456 unsigned long end_jiffies = jiffies + 4491 unsigned long end_jiffies = jiffies +
4457 msecs_to_jiffies(gk20a_get_gr_idle_timeout(g)); 4492 msecs_to_jiffies(gk20a_get_gr_idle_timeout(g));
@@ -4483,16 +4518,6 @@ static int gk20a_init_gr_reset_enable_hw(struct gk20a *g)
4483 if (err) 4518 if (err)
4484 goto out; 4519 goto out;
4485 4520
4486 err = gr_gk20a_load_ctxsw_ucode(g, gr);
4487 if (err)
4488 goto out;
4489
4490 /* this appears query for sw states but fecs actually init
4491 ramchain, etc so this is hw init */
4492 err = gr_gk20a_init_ctx_state(g, gr);
4493 if (err)
4494 goto out;
4495
4496out: 4521out:
4497 if (err) 4522 if (err)
4498 gk20a_err(dev_from_gk20a(g), "fail"); 4523 gk20a_err(dev_from_gk20a(g), "fail");
@@ -4624,14 +4649,10 @@ int gk20a_init_gr_support(struct gk20a *g)
4624 4649
4625 gk20a_dbg_fn(""); 4650 gk20a_dbg_fn("");
4626 4651
4627 err = gk20a_init_gr_prepare(g);
4628 if (err)
4629 return err;
4630
4631 /* this is required before gr_gk20a_init_ctx_state */ 4652 /* this is required before gr_gk20a_init_ctx_state */
4632 mutex_init(&g->gr.fecs_mutex); 4653 mutex_init(&g->gr.fecs_mutex);
4633 4654
4634 err = gk20a_init_gr_reset_enable_hw(g); 4655 err = gr_gk20a_init_ctxsw(g);
4635 if (err) 4656 if (err)
4636 return err; 4657 return err;
4637 4658
@@ -4817,10 +4838,11 @@ static void gk20a_gr_set_alpha_circular_buffer_size(struct gk20a *g, u32 data)
4817 } 4838 }
4818} 4839}
4819 4840
4820int gk20a_gr_reset(struct gk20a *g) 4841int gk20a_enable_gr_hw(struct gk20a *g)
4821{ 4842{
4822 int err; 4843 int err;
4823 u32 size; 4844
4845 gk20a_dbg_fn("");
4824 4846
4825 err = gk20a_init_gr_prepare(g); 4847 err = gk20a_init_gr_prepare(g);
4826 if (err) 4848 if (err)
@@ -4830,10 +4852,28 @@ int gk20a_gr_reset(struct gk20a *g)
4830 if (err) 4852 if (err)
4831 return err; 4853 return err;
4832 4854
4855 gk20a_dbg_fn("done");
4856
4857 return 0;
4858}
4859
4860int gk20a_gr_reset(struct gk20a *g)
4861{
4862 int err;
4863 u32 size;
4864
4865 err = gk20a_enable_gr_hw(g);
4866 if (err)
4867 return err;
4868
4833 err = gk20a_init_gr_setup_hw(g); 4869 err = gk20a_init_gr_setup_hw(g);
4834 if (err) 4870 if (err)
4835 return err; 4871 return err;
4836 4872
4873 err = gr_gk20a_init_ctxsw(g);
4874 if (err)
4875 return err;
4876
4837 size = 0; 4877 size = 0;
4838 err = gr_gk20a_fecs_get_reglist_img_size(g, &size); 4878 err = gr_gk20a_fecs_get_reglist_img_size(g, &size);
4839 if (err) { 4879 if (err) {
@@ -6934,4 +6974,5 @@ void gk20a_init_gr_ops(struct gpu_ops *gops)
6934 gops->gr.set_hww_esr_report_mask = gr_gk20a_set_hww_esr_report_mask; 6974 gops->gr.set_hww_esr_report_mask = gr_gk20a_set_hww_esr_report_mask;
6935 gops->gr.setup_alpha_beta_tables = gr_gk20a_setup_alpha_beta_tables; 6975 gops->gr.setup_alpha_beta_tables = gr_gk20a_setup_alpha_beta_tables;
6936 gops->gr.falcon_load_ucode = gr_gk20a_load_ctxsw_ucode_segments; 6976 gops->gr.falcon_load_ucode = gr_gk20a_load_ctxsw_ucode_segments;
6977 gops->gr.load_ctxsw_ucode = gr_gk20a_load_ctxsw_ucode;
6937} 6978}
diff --git a/drivers/gpu/nvgpu/gk20a/gr_gk20a.h b/drivers/gpu/nvgpu/gk20a/gr_gk20a.h
index cae69ba6..3376747b 100644
--- a/drivers/gpu/nvgpu/gk20a/gr_gk20a.h
+++ b/drivers/gpu/nvgpu/gk20a/gr_gk20a.h
@@ -319,6 +319,7 @@ struct gpu_ops;
319void gk20a_init_gr(struct gk20a *g); 319void gk20a_init_gr(struct gk20a *g);
320void gk20a_init_gr_ops(struct gpu_ops *gops); 320void gk20a_init_gr_ops(struct gpu_ops *gops);
321int gk20a_init_gr_support(struct gk20a *g); 321int gk20a_init_gr_support(struct gk20a *g);
322int gk20a_enable_gr_hw(struct gk20a *g);
322int gk20a_gr_reset(struct gk20a *g); 323int gk20a_gr_reset(struct gk20a *g);
323void gk20a_gr_wait_initialized(struct gk20a *g); 324void gk20a_gr_wait_initialized(struct gk20a *g);
324 325
@@ -415,6 +416,9 @@ void gr_gk20a_get_sm_dsm_perf_ctrl_regs(struct gk20a *g,
415 u32 **sm_dsm_perf_regs, 416 u32 **sm_dsm_perf_regs,
416 u32 *perf_register_stride); 417 u32 *perf_register_stride);
417int gr_gk20a_setup_rop_mapping(struct gk20a *g, struct gr_gk20a *gr); 418int gr_gk20a_setup_rop_mapping(struct gk20a *g, struct gr_gk20a *gr);
419int gr_gk20a_init_ctxsw_ucode(struct gk20a *g);
420int gr_gk20a_load_ctxsw_ucode(struct gk20a *g);
421void gr_gk20a_load_falcon_bind_instblk(struct gk20a *g);
418 422
419void gr_gk20a_free_tsg_gr_ctx(struct tsg_gk20a *c); 423void gr_gk20a_free_tsg_gr_ctx(struct tsg_gk20a *c);
420#endif /*__GR_GK20A_H__*/ 424#endif /*__GR_GK20A_H__*/
diff --git a/drivers/gpu/nvgpu/gk20a/pmu_gk20a.c b/drivers/gpu/nvgpu/gk20a/pmu_gk20a.c
index cfbdceae..de16e403 100644
--- a/drivers/gpu/nvgpu/gk20a/pmu_gk20a.c
+++ b/drivers/gpu/nvgpu/gk20a/pmu_gk20a.c
@@ -487,6 +487,17 @@ static void *get_pmu_sequence_out_alloc_ptr_v0(struct pmu_sequence *seq)
487int gk20a_init_pmu(struct pmu_gk20a *pmu) 487int gk20a_init_pmu(struct pmu_gk20a *pmu)
488{ 488{
489 struct gk20a *g = gk20a_from_pmu(pmu); 489 struct gk20a *g = gk20a_from_pmu(pmu);
490
491 mutex_init(&pmu->elpg_mutex);
492 mutex_init(&pmu->isr_mutex);
493 mutex_init(&pmu->pmu_copy_lock);
494 mutex_init(&pmu->pmu_seq_lock);
495
496 pmu->perfmon_counter.index = 3; /* GR & CE2 */
497 pmu->perfmon_counter.group_id = PMU_DOMAIN_GROUP_PSTATE;
498
499 pmu->remove_support = gk20a_remove_pmu_support;
500
490 switch (pmu->desc->app_version) { 501 switch (pmu->desc->app_version) {
491 case APP_VERSION_GM20B_1: 502 case APP_VERSION_GM20B_1:
492 case APP_VERSION_GM20B: 503 case APP_VERSION_GM20B:
@@ -1700,25 +1711,9 @@ int gk20a_init_pmu_setup_sw(struct gk20a *g)
1700 pmu->seq_buf.size = GK20A_PMU_SEQ_BUF_SIZE; 1711 pmu->seq_buf.size = GK20A_PMU_SEQ_BUF_SIZE;
1701 1712
1702 gk20a_free_sgtable(&sgt_seq_buf); 1713 gk20a_free_sgtable(&sgt_seq_buf);
1703
1704 pmu->sw_ready = true; 1714 pmu->sw_ready = true;
1705 1715
1706skip_init: 1716skip_init:
1707 mutex_init(&pmu->elpg_mutex);
1708 mutex_init(&pmu->isr_mutex);
1709 mutex_init(&pmu->pmu_copy_lock);
1710 mutex_init(&pmu->pmu_seq_lock);
1711
1712 pmu->perfmon_counter.index = 3; /* GR & CE2 */
1713 pmu->perfmon_counter.group_id = PMU_DOMAIN_GROUP_PSTATE;
1714
1715 pmu->remove_support = gk20a_remove_pmu_support;
1716 err = gk20a_init_pmu(pmu);
1717 if (err) {
1718 gk20a_err(d, "failed to set function pointers\n");
1719 return err;
1720 }
1721
1722 gk20a_dbg_fn("done"); 1717 gk20a_dbg_fn("done");
1723 return 0; 1718 return 0;
1724 1719
@@ -1773,7 +1768,6 @@ int gk20a_init_pmu_setup_hw1(struct gk20a *g)
1773 int err; 1768 int err;
1774 1769
1775 gk20a_dbg_fn(""); 1770 gk20a_dbg_fn("");
1776
1777 pmu_reset(pmu); 1771 pmu_reset(pmu);
1778 1772
1779 /* setup apertures - virtual */ 1773 /* setup apertures - virtual */
@@ -3770,4 +3764,5 @@ err_out:
3770 debugfs_remove_recursive(platform->debugfs); 3764 debugfs_remove_recursive(platform->debugfs);
3771 return -ENOMEM; 3765 return -ENOMEM;
3772} 3766}
3767
3773#endif 3768#endif
diff --git a/drivers/gpu/nvgpu/gk20a/pmu_gk20a.h b/drivers/gpu/nvgpu/gk20a/pmu_gk20a.h
index 6f4e6c2e..40d41ee9 100644
--- a/drivers/gpu/nvgpu/gk20a/pmu_gk20a.h
+++ b/drivers/gpu/nvgpu/gk20a/pmu_gk20a.h
@@ -1103,4 +1103,7 @@ void pmu_dump_falcon_stats(struct pmu_gk20a *pmu);
1103void gk20a_remove_pmu_support(struct pmu_gk20a *pmu); 1103void gk20a_remove_pmu_support(struct pmu_gk20a *pmu);
1104void pmu_setup_hw(struct work_struct *work); 1104void pmu_setup_hw(struct work_struct *work);
1105void pmu_seq_init(struct pmu_gk20a *pmu); 1105void pmu_seq_init(struct pmu_gk20a *pmu);
1106
1107int gk20a_init_pmu(struct pmu_gk20a *pmu);
1108
1106#endif /*__PMU_GK20A_H__*/ 1109#endif /*__PMU_GK20A_H__*/
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*/
57static void __iomem *mc = IO_ADDRESS(TEGRA_MC_BASE); 57static void __iomem *mc = IO_ADDRESS(TEGRA_MC_BASE);
58get_ucode_details pmu_acr_supp_ucode_list[MAX_SUPPORTED_LSFM] = { 58get_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
120int 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
119int prepare_ucode_blob(struct gk20a *g) 171int 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
659static 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
672static 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
658void gm20b_init_gr(struct gpu_ops *gops) 708void 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}