summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMahantesh Kumbar <mkumbar@nvidia.com>2016-06-02 08:08:37 -0400
committerTerje Bergstrom <tbergstrom@nvidia.com>2016-06-04 18:21:35 -0400
commitf99de40936236b4e8b00fa847f502c7b94af85c3 (patch)
tree0be307642c99a03e1807fbe5549e5c47fb6ded1e
parent608101dbfa1c99069ca2abe9d70a204419f8e719 (diff)
gpu: nvgpu: WPR & PMU interface update
Update WPR interface & PMU interface to support latest ACR/PMU ucode versions Change-Id: I4d1bd7a5c43751e96c1db58832cd316006d56954 Signed-off-by: Mahantesh Kumbar <mkumbar@nvidia.com> Reviewed-on: http://git-master/r/1158070 Reviewed-by: Automatic_Commit_Validation_User GVS: Gerrit_Virtual_Submit Reviewed-by: Terje Bergstrom <tbergstrom@nvidia.com> Tested-by: Terje Bergstrom <tbergstrom@nvidia.com>
-rw-r--r--drivers/gpu/nvgpu/gk20a/gk20a.h4
-rw-r--r--drivers/gpu/nvgpu/gk20a/pmu_gk20a.c4
-rw-r--r--drivers/gpu/nvgpu/gk20a/pmu_gk20a.h32
-rw-r--r--drivers/gpu/nvgpu/gm20b/acr_gm20b.c40
-rw-r--r--drivers/gpu/nvgpu/gm20b/acr_gm20b.h6
5 files changed, 62 insertions, 24 deletions
diff --git a/drivers/gpu/nvgpu/gk20a/gk20a.h b/drivers/gpu/nvgpu/gk20a/gk20a.h
index 85289087..3da19cc8 100644
--- a/drivers/gpu/nvgpu/gk20a/gk20a.h
+++ b/drivers/gpu/nvgpu/gk20a/gk20a.h
@@ -549,10 +549,10 @@ struct gpu_ops {
549 int (*falcon_clear_halt_interrupt_status)(struct gk20a *g, 549 int (*falcon_clear_halt_interrupt_status)(struct gk20a *g,
550 unsigned int timeout); 550 unsigned int timeout);
551 int (*init_falcon_setup_hw)(struct gk20a *g, 551 int (*init_falcon_setup_hw)(struct gk20a *g,
552 struct flcn_bl_dmem_desc *desc, u32 bl_sz); 552 void *desc, u32 bl_sz);
553 bool (*is_lazy_bootstrap)(u32 falcon_id); 553 bool (*is_lazy_bootstrap)(u32 falcon_id);
554 bool (*is_priv_load)(u32 falcon_id); 554 bool (*is_priv_load)(u32 falcon_id);
555 void (*get_wpr)(struct gk20a *g, u64 *base, u64 *size); 555 void (*get_wpr)(struct gk20a *g, struct wpr_carveout_info *inf);
556 int (*alloc_blob_space)(struct gk20a *g, 556 int (*alloc_blob_space)(struct gk20a *g,
557 size_t size, struct mem_desc *mem); 557 size_t size, struct mem_desc *mem);
558 int (*pmu_populate_loader_cfg)(struct gk20a *g, 558 int (*pmu_populate_loader_cfg)(struct gk20a *g,
diff --git a/drivers/gpu/nvgpu/gk20a/pmu_gk20a.c b/drivers/gpu/nvgpu/gk20a/pmu_gk20a.c
index 51ffc552..d12c5987 100644
--- a/drivers/gpu/nvgpu/gk20a/pmu_gk20a.c
+++ b/drivers/gpu/nvgpu/gk20a/pmu_gk20a.c
@@ -1623,7 +1623,7 @@ void pmu_copy_to_dmem(struct pmu_gk20a *pmu,
1623 return; 1623 return;
1624} 1624}
1625 1625
1626static int pmu_idle(struct pmu_gk20a *pmu) 1626int pmu_idle(struct pmu_gk20a *pmu)
1627{ 1627{
1628 struct gk20a *g = gk20a_from_pmu(pmu); 1628 struct gk20a *g = gk20a_from_pmu(pmu);
1629 unsigned long end_jiffies = jiffies + 1629 unsigned long end_jiffies = jiffies +
@@ -1714,7 +1714,7 @@ void pmu_enable_irq(struct pmu_gk20a *pmu, bool enable)
1714 gk20a_dbg_fn("done"); 1714 gk20a_dbg_fn("done");
1715} 1715}
1716 1716
1717static int pmu_enable_hw(struct pmu_gk20a *pmu, bool enable) 1717int pmu_enable_hw(struct pmu_gk20a *pmu, bool enable)
1718{ 1718{
1719 struct gk20a *g = gk20a_from_pmu(pmu); 1719 struct gk20a *g = gk20a_from_pmu(pmu);
1720 1720
diff --git a/drivers/gpu/nvgpu/gk20a/pmu_gk20a.h b/drivers/gpu/nvgpu/gk20a/pmu_gk20a.h
index b8bb18a2..7d91b111 100644
--- a/drivers/gpu/nvgpu/gk20a/pmu_gk20a.h
+++ b/drivers/gpu/nvgpu/gk20a/pmu_gk20a.h
@@ -450,6 +450,31 @@ struct pmu_ucode_desc {
450 u32 compressed; 450 u32 compressed;
451}; 451};
452 452
453struct pmu_ucode_desc_v1 {
454 u32 descriptor_size;
455 u32 image_size;
456 u32 tools_version;
457 u32 app_version;
458 char date[GK20A_PMU_UCODE_NB_MAX_DATE_LENGTH];
459 u32 bootloader_start_offset;
460 u32 bootloader_size;
461 u32 bootloader_imem_offset;
462 u32 bootloader_entry_point;
463 u32 app_start_offset;
464 u32 app_size;
465 u32 app_imem_offset;
466 u32 app_imem_entry;
467 u32 app_dmem_offset;
468 u32 app_resident_code_offset;
469 u32 app_resident_code_size;
470 u32 app_resident_data_offset;
471 u32 app_resident_data_size;
472 u32 nb_imem_overlays;
473 u32 nb_dmem_overlays;
474 struct {u32 start; u32 size; } load_ovl[64];
475 u32 compressed;
476};
477
453#define PMU_UNIT_REWIND (0x00) 478#define PMU_UNIT_REWIND (0x00)
454#define PMU_UNIT_PG (0x03) 479#define PMU_UNIT_PG (0x03)
455#define PMU_UNIT_INIT (0x07) 480#define PMU_UNIT_INIT (0x07)
@@ -1295,7 +1320,10 @@ struct pmu_pg_stats {
1295 1320
1296struct pmu_gk20a { 1321struct pmu_gk20a {
1297 1322
1298 struct pmu_ucode_desc *desc; 1323 union {
1324 struct pmu_ucode_desc *desc;
1325 struct pmu_ucode_desc_v1 *desc_v1;
1326 };
1299 struct mem_desc ucode; 1327 struct mem_desc ucode;
1300 1328
1301 struct mem_desc pg_buf; 1329 struct mem_desc pg_buf;
@@ -1427,5 +1455,7 @@ void pmu_handle_fecs_boot_acr_msg(struct gk20a *g, struct pmu_msg *msg,
1427void gk20a_pmu_elpg_statistics(struct gk20a *g, 1455void gk20a_pmu_elpg_statistics(struct gk20a *g,
1428 u32 *ingating_time, u32 *ungating_time, u32 *gating_cnt); 1456 u32 *ingating_time, u32 *ungating_time, u32 *gating_cnt);
1429int gk20a_pmu_reset(struct gk20a *g); 1457int gk20a_pmu_reset(struct gk20a *g);
1458int pmu_idle(struct pmu_gk20a *pmu);
1459int pmu_enable_hw(struct pmu_gk20a *pmu, bool enable);
1430 1460
1431#endif /*__PMU_GK20A_H__*/ 1461#endif /*__PMU_GK20A_H__*/
diff --git a/drivers/gpu/nvgpu/gm20b/acr_gm20b.c b/drivers/gpu/nvgpu/gm20b/acr_gm20b.c
index 1b8e7b5f..7ef6be09 100644
--- a/drivers/gpu/nvgpu/gm20b/acr_gm20b.c
+++ b/drivers/gpu/nvgpu/gm20b/acr_gm20b.c
@@ -43,7 +43,7 @@ static int gm20b_bootstrap_hs_flcn(struct gk20a *g);
43static int pmu_wait_for_halt(struct gk20a *g, unsigned int timeout); 43static int pmu_wait_for_halt(struct gk20a *g, unsigned int timeout);
44static int clear_halt_interrupt_status(struct gk20a *g, unsigned int timeout); 44static int clear_halt_interrupt_status(struct gk20a *g, unsigned int timeout);
45static int gm20b_init_pmu_setup_hw1(struct gk20a *g, 45static int gm20b_init_pmu_setup_hw1(struct gk20a *g,
46 struct flcn_bl_dmem_desc *desc, u32 bl_sz); 46 void *desc, u32 bl_sz);
47static int lsfm_discover_ucode_images(struct gk20a *g, 47static int lsfm_discover_ucode_images(struct gk20a *g,
48 struct ls_flcn_mgr *plsfm); 48 struct ls_flcn_mgr *plsfm);
49static int lsfm_add_ucode_img(struct gk20a *g, struct ls_flcn_mgr *plsfm, 49static int lsfm_add_ucode_img(struct gk20a *g, struct ls_flcn_mgr *plsfm,
@@ -62,7 +62,7 @@ static int gm20b_alloc_blob_space(struct gk20a *g,
62 size_t size, struct mem_desc *mem); 62 size_t size, struct mem_desc *mem);
63static bool gm20b_is_priv_load(u32 falcon_id); 63static bool gm20b_is_priv_load(u32 falcon_id);
64static bool gm20b_is_lazy_bootstrap(u32 falcon_id); 64static bool gm20b_is_lazy_bootstrap(u32 falcon_id);
65static void gm20b_wpr_info(struct gk20a *g, u64 *base, u64 *size); 65static void gm20b_wpr_info(struct gk20a *g, struct wpr_carveout_info *inf);
66 66
67/*Globals*/ 67/*Globals*/
68static get_ucode_details pmu_acr_supp_ucode_list[] = { 68static get_ucode_details pmu_acr_supp_ucode_list[] = {
@@ -83,13 +83,15 @@ static void start_gm20b_pmu(struct gk20a *g)
83 pwr_falcon_cpuctl_startcpu_f(1)); 83 pwr_falcon_cpuctl_startcpu_f(1));
84} 84}
85 85
86static void gm20b_wpr_info(struct gk20a *g, u64 *base, u64 *size) 86static void gm20b_wpr_info(struct gk20a *g, struct wpr_carveout_info *inf)
87{ 87{
88 struct mc_carveout_info inf; 88 struct mc_carveout_info mem_inf;
89 89
90 mc_get_carveout_info(&inf, NULL, MC_SECURITY_CARVEOUT2); 90 mc_get_carveout_info(&mem_inf, NULL, MC_SECURITY_CARVEOUT2);
91 *base = inf.base; 91
92 *size = inf.size; 92 inf->wpr_base = mem_inf.base;
93 inf->nonwpr_base = 0;
94 inf->size = mem_inf.size;
93} 95}
94 96
95void gm20b_init_secure_pmu(struct gpu_ops *gops) 97void gm20b_init_secure_pmu(struct gpu_ops *gops)
@@ -368,7 +370,7 @@ int prepare_ucode_blob(struct gk20a *g)
368 u32 wprsize; 370 u32 wprsize;
369 struct mm_gk20a *mm = &g->mm; 371 struct mm_gk20a *mm = &g->mm;
370 struct vm_gk20a *vm = &mm->pmu.vm; 372 struct vm_gk20a *vm = &mm->pmu.vm;
371 struct mc_carveout_info inf; 373 struct wpr_carveout_info wpr_inf;
372 struct sg_table *sgt; 374 struct sg_table *sgt;
373 struct page *page; 375 struct page *page;
374 376
@@ -388,10 +390,10 @@ int prepare_ucode_blob(struct gk20a *g)
388 gm20b_mm_mmu_vpr_info_fetch(g); 390 gm20b_mm_mmu_vpr_info_fetch(g);
389 gr_gk20a_init_ctxsw_ucode(g); 391 gr_gk20a_init_ctxsw_ucode(g);
390 392
391 g->ops.pmu.get_wpr(g, &inf.base, &inf.size); 393 g->ops.pmu.get_wpr(g, &wpr_inf);
392 wpr_addr = (phys_addr_t)inf.base; 394 wpr_addr = (phys_addr_t)wpr_inf.wpr_base;
393 wprsize = (u32)inf.size; 395 wprsize = (u32)wpr_inf.size;
394 gm20b_dbg_pmu("wpr carveout base:%llx\n", inf.base); 396 gm20b_dbg_pmu("wpr carveout base:%llx\n", wpr_inf.wpr_base);
395 gm20b_dbg_pmu("wpr carveout size :%x\n", wprsize); 397 gm20b_dbg_pmu("wpr carveout size :%x\n", wprsize);
396 398
397 sgt = kzalloc(sizeof(*sgt), GFP_KERNEL); 399 sgt = kzalloc(sizeof(*sgt), GFP_KERNEL);
@@ -539,7 +541,7 @@ static int lsfm_discover_ucode_images(struct gk20a *g,
539static int gm20b_pmu_populate_loader_cfg(struct gk20a *g, 541static int gm20b_pmu_populate_loader_cfg(struct gk20a *g,
540 void *lsfm, u32 *p_bl_gen_desc_size) 542 void *lsfm, u32 *p_bl_gen_desc_size)
541{ 543{
542 struct mc_carveout_info inf; 544 struct wpr_carveout_info wpr_inf;
543 struct pmu_gk20a *pmu = &g->pmu; 545 struct pmu_gk20a *pmu = &g->pmu;
544 struct lsfm_managed_ucode_img *p_lsfm = 546 struct lsfm_managed_ucode_img *p_lsfm =
545 (struct lsfm_managed_ucode_img *)lsfm; 547 (struct lsfm_managed_ucode_img *)lsfm;
@@ -563,8 +565,8 @@ static int gm20b_pmu_populate_loader_cfg(struct gk20a *g,
563 physical addresses of each respective segment. 565 physical addresses of each respective segment.
564 */ 566 */
565 addr_base = p_lsfm->lsb_header.ucode_off; 567 addr_base = p_lsfm->lsb_header.ucode_off;
566 g->ops.pmu.get_wpr(g, &inf.base, &inf.size); 568 g->ops.pmu.get_wpr(g, &wpr_inf);
567 addr_base += inf.base; 569 addr_base += wpr_inf.wpr_base;
568 gm20b_dbg_pmu("pmu loader cfg u32 addrbase %x\n", (u32)addr_base); 570 gm20b_dbg_pmu("pmu loader cfg u32 addrbase %x\n", (u32)addr_base);
569 /*From linux*/ 571 /*From linux*/
570 addr_code = u64_lo32((addr_base + 572 addr_code = u64_lo32((addr_base +
@@ -611,7 +613,7 @@ static int gm20b_pmu_populate_loader_cfg(struct gk20a *g,
611static int gm20b_flcn_populate_bl_dmem_desc(struct gk20a *g, 613static int gm20b_flcn_populate_bl_dmem_desc(struct gk20a *g,
612 void *lsfm, u32 *p_bl_gen_desc_size, u32 falconid) 614 void *lsfm, u32 *p_bl_gen_desc_size, u32 falconid)
613{ 615{
614 struct mc_carveout_info inf; 616 struct wpr_carveout_info wpr_inf;
615 struct lsfm_managed_ucode_img *p_lsfm = 617 struct lsfm_managed_ucode_img *p_lsfm =
616 (struct lsfm_managed_ucode_img *)lsfm; 618 (struct lsfm_managed_ucode_img *)lsfm;
617 struct flcn_ucode_img *p_img = &(p_lsfm->ucode_img); 619 struct flcn_ucode_img *p_img = &(p_lsfm->ucode_img);
@@ -635,11 +637,11 @@ static int gm20b_flcn_populate_bl_dmem_desc(struct gk20a *g,
635 physical addresses of each respective segment. 637 physical addresses of each respective segment.
636 */ 638 */
637 addr_base = p_lsfm->lsb_header.ucode_off; 639 addr_base = p_lsfm->lsb_header.ucode_off;
638 g->ops.pmu.get_wpr(g, &inf.base, &inf.size); 640 g->ops.pmu.get_wpr(g, &wpr_inf);
639 if (falconid == LSF_FALCON_ID_GPCCS) 641 if (falconid == LSF_FALCON_ID_GPCCS)
640 addr_base += g->pmu.wpr_buf.gpu_va; 642 addr_base += g->pmu.wpr_buf.gpu_va;
641 else 643 else
642 addr_base += inf.base; 644 addr_base += wpr_inf.wpr_base;
643 gm20b_dbg_pmu("gen loader cfg %x u32 addrbase %x ID\n", (u32)addr_base, 645 gm20b_dbg_pmu("gen loader cfg %x u32 addrbase %x ID\n", (u32)addr_base,
644 p_lsfm->wpr_header.falcon_id); 646 p_lsfm->wpr_header.falcon_id);
645 addr_code = u64_lo32((addr_base + 647 addr_code = u64_lo32((addr_base +
@@ -1299,7 +1301,7 @@ int gm20b_init_nspmu_setup_hw1(struct gk20a *g)
1299} 1301}
1300 1302
1301static int gm20b_init_pmu_setup_hw1(struct gk20a *g, 1303static int gm20b_init_pmu_setup_hw1(struct gk20a *g,
1302 struct flcn_bl_dmem_desc *desc, u32 bl_sz) 1304 void *desc, u32 bl_sz)
1303{ 1305{
1304 1306
1305 struct pmu_gk20a *pmu = &g->pmu; 1307 struct pmu_gk20a *pmu = &g->pmu;
diff --git a/drivers/gpu/nvgpu/gm20b/acr_gm20b.h b/drivers/gpu/nvgpu/gm20b/acr_gm20b.h
index a1dceae9..51492827 100644
--- a/drivers/gpu/nvgpu/gm20b/acr_gm20b.h
+++ b/drivers/gpu/nvgpu/gm20b/acr_gm20b.h
@@ -386,6 +386,12 @@ struct acr_fw_header {
386 u32 hdr_size; /*size of above header*/ 386 u32 hdr_size; /*size of above header*/
387}; 387};
388 388
389struct wpr_carveout_info {
390 u64 wpr_base;
391 u64 nonwpr_base;
392 u64 size;
393};
394
389void gm20b_init_secure_pmu(struct gpu_ops *gops); 395void gm20b_init_secure_pmu(struct gpu_ops *gops);
390int prepare_ucode_blob(struct gk20a *g); 396int prepare_ucode_blob(struct gk20a *g);
391int gm20b_pmu_setup_sw(struct gk20a *g); 397int gm20b_pmu_setup_sw(struct gk20a *g);