diff --git a/drivers/gpu/nvgpu/Kconfig b/drivers/gpu/nvgpu/Kconfig index 92c6d877a..2e1ebcf2c 100644 --- a/drivers/gpu/nvgpu/Kconfig +++ b/drivers/gpu/nvgpu/Kconfig @@ -167,3 +167,10 @@ config NVGPU_DEBUGGER default y help Support for debugger APIs + +config NVGPU_LS_PMU + bool "LS PMU support" + depends on GK20A + default y + help + Support for iGPU LS PMU enable/disable diff --git a/drivers/gpu/nvgpu/Makefile b/drivers/gpu/nvgpu/Makefile index d55d3ac58..8e498e11c 100644 --- a/drivers/gpu/nvgpu/Makefile +++ b/drivers/gpu/nvgpu/Makefile @@ -21,6 +21,10 @@ ifeq ($(CONFIG_NVGPU_DEBUGGER),y) ccflags-y += -DNVGPU_DEBUGGER endif +ifeq ($(CONFIG_NVGPU_LS_PMU),y) +ccflags-y += -DNVGPU_LS_PMU +endif + obj-$(CONFIG_GK20A) := nvgpu.o # OS independent parts of nvgpu. The work to collect files here diff --git a/drivers/gpu/nvgpu/Makefile.sources b/drivers/gpu/nvgpu/Makefile.sources index d545f8005..5fa0c20da 100644 --- a/drivers/gpu/nvgpu/Makefile.sources +++ b/drivers/gpu/nvgpu/Makefile.sources @@ -342,3 +342,9 @@ srcs += common/sim.c \ ifeq ($(NVGPU_DEBUGGER),1) srcs += common/debugger.c endif + +ifeq ($(NVGPU_LS_PMU),1) +# Add LS PMU files which are required for normal build +# TBD: currently LS PMU unit files are dependent on another unit, files can be +# added once refactored & removed dependency +endif diff --git a/drivers/gpu/nvgpu/Makefile.tmk b/drivers/gpu/nvgpu/Makefile.tmk index 8d495a5e5..130decbf2 100644 --- a/drivers/gpu/nvgpu/Makefile.tmk +++ b/drivers/gpu/nvgpu/Makefile.tmk @@ -63,7 +63,10 @@ NV_COMPONENT_CFLAGS += \ ifeq ($(NVGPU_REDUCED), 0) # Enable debugger APIs for normal builds NVGPU_DEBUGGER := 1 +# Enable iGPU LS PMU for normal builds +NVGPU_LS_PMU := 1 NV_COMPONENT_CFLAGS += -DNVGPU_DEBUGGER +NV_COMPONENT_CFLAGS += -DNVGPU_LS_PMU endif _NV_TOOLCHAIN_CFLAGS += -rdynamic -g diff --git a/drivers/gpu/nvgpu/common/acr/acr_gv11b.c b/drivers/gpu/nvgpu/common/acr/acr_gv11b.c index fbb35c643..210396bac 100644 --- a/drivers/gpu/nvgpu/common/acr/acr_gv11b.c +++ b/drivers/gpu/nvgpu/common/acr/acr_gv11b.c @@ -81,6 +81,11 @@ static int gv11b_acr_patch_wpr_info_to_ucode(struct gk20a *g, static u32 gv11b_acr_lsf_pmu(struct gk20a *g, struct acr_lsf_config *lsf) { + if (!g->support_ls_pmu) { + /* skip adding LS PMU ucode to ACR blob */ + return 0; + } + /* PMU LS falcon info */ lsf->falcon_id = FALCON_ID_PMU; lsf->falcon_dma_idx = GK20A_PMU_DMAIDX_UCODE; @@ -99,7 +104,11 @@ static u32 gv11b_acr_lsf_fecs(struct gk20a *g, /* FECS LS falcon info */ lsf->falcon_id = FALCON_ID_FECS; lsf->falcon_dma_idx = GK20A_PMU_DMAIDX_UCODE; - lsf->is_lazy_bootstrap = true; + /* + * FECS LSF cold/recovery bootstrap is handled by ACR when LS PMU + * not present + */ + lsf->is_lazy_bootstrap = g->support_ls_pmu ? true : false; lsf->is_priv_load = false; lsf->get_lsf_ucode_details = nvgpu_acr_lsf_fecs_ucode_details_v1; lsf->get_cmd_line_args_offset = NULL; @@ -110,10 +119,14 @@ static u32 gv11b_acr_lsf_fecs(struct gk20a *g, static u32 gv11b_acr_lsf_gpccs(struct gk20a *g, struct acr_lsf_config *lsf) { - /* FECS LS falcon info */ + /* GPCCS LS falcon info */ lsf->falcon_id = FALCON_ID_GPCCS; lsf->falcon_dma_idx = GK20A_PMU_DMAIDX_UCODE; - lsf->is_lazy_bootstrap = true; + /* + * GPCCS LSF cold/recovery bootstrap is handled by ACR when LS PMU + * not present + */ + lsf->is_lazy_bootstrap = g->support_ls_pmu ? true : false; lsf->is_priv_load = true; lsf->get_lsf_ucode_details = nvgpu_acr_lsf_gpccs_ucode_details_v1; lsf->get_cmd_line_args_offset = NULL; diff --git a/drivers/gpu/nvgpu/common/gr/zbc/gr_zbc.c b/drivers/gpu/nvgpu/common/gr/zbc/gr_zbc.c index d1dd1417f..c9dce4940 100644 --- a/drivers/gpu/nvgpu/common/gr/zbc/gr_zbc.c +++ b/drivers/gpu/nvgpu/common/gr/zbc/gr_zbc.c @@ -132,7 +132,9 @@ static int nvgpu_gr_zbc_add(struct gk20a *g, struct nvgpu_gr_zbc *zbc, /* update zbc for elpg only when new entry is added */ entries = max(zbc->max_used_color_index, zbc->max_used_depth_index); - g->ops.pmu.save_zbc(g, entries); + if (g->elpg_enabled) { + g->ops.pmu.save_zbc(g, entries); + } } err_mutex: diff --git a/drivers/gpu/nvgpu/common/pmu/pmu.c b/drivers/gpu/nvgpu/common/pmu/pmu.c index 1d929c770..bdfd47213 100644 --- a/drivers/gpu/nvgpu/common/pmu/pmu.c +++ b/drivers/gpu/nvgpu/common/pmu/pmu.c @@ -96,8 +96,6 @@ static int pmu_enable(struct nvgpu_pmu *pmu, bool enable) if (err != 0) { goto exit; } - - g->ops.pmu.pmu_enable_irq(pmu, true); } exit: diff --git a/drivers/gpu/nvgpu/common/pmu/pmu_fw.c b/drivers/gpu/nvgpu/common/pmu/pmu_fw.c index c69538ea2..da8fc6180 100644 --- a/drivers/gpu/nvgpu/common/pmu/pmu_fw.c +++ b/drivers/gpu/nvgpu/common/pmu/pmu_fw.c @@ -1761,6 +1761,12 @@ int nvgpu_early_init_pmu_sw(struct gk20a *g, struct nvgpu_pmu *pmu) if (!g->ops.pmu.is_pmu_supported(g)) { g->support_ls_pmu = false; + + /* Disable LS PMU global checkers */ + g->can_elpg = false; + g->elpg_enabled = false; + g->aelpg_enabled = false; + nvgpu_set_enabled(g, NVGPU_PMU_PERFMON, false); goto exit; } @@ -1838,4 +1844,3 @@ int nvgpu_pmu_prepare_ns_ucode_blob(struct gk20a *g) exit: return err; } - diff --git a/drivers/gpu/nvgpu/common/pmu/pmu_gm20b.c b/drivers/gpu/nvgpu/common/pmu/pmu_gm20b.c index 1dc7a547e..8ee355fb1 100644 --- a/drivers/gpu/nvgpu/common/pmu/pmu_gm20b.c +++ b/drivers/gpu/nvgpu/common/pmu/pmu_gm20b.c @@ -381,24 +381,14 @@ int gm20b_pmu_setup_hw_and_bl_bootstrap(struct gk20a *g, struct hs_acr *acr_desc, struct nvgpu_falcon_bl_info *bl_info) { - struct nvgpu_pmu *pmu = &g->pmu; int err; nvgpu_log_fn(g, " "); - nvgpu_mutex_acquire(&pmu->isr_mutex); - /* - * disable irqs for hs falcon booting - * as we will poll for halt - */ - g->ops.pmu.pmu_enable_irq(pmu, false); - pmu->isr_enabled = false; err = nvgpu_falcon_reset(acr_desc->acr_flcn); if (err != 0) { - nvgpu_mutex_release(&pmu->isr_mutex); goto exit; } - nvgpu_mutex_release(&pmu->isr_mutex); if (g->ops.pmu.setup_apertures != NULL) { g->ops.pmu.setup_apertures(g); diff --git a/drivers/gpu/nvgpu/common/pmu/pmu_gv11b.c b/drivers/gpu/nvgpu/common/pmu/pmu_gv11b.c index bf12beee9..ecaf34b7d 100644 --- a/drivers/gpu/nvgpu/common/pmu/pmu_gv11b.c +++ b/drivers/gpu/nvgpu/common/pmu/pmu_gv11b.c @@ -157,7 +157,12 @@ int gv11b_pmu_setup_elpg(struct gk20a *g) bool gv11b_is_pmu_supported(struct gk20a *g) { +#ifdef NVGPU_LS_PMU return true; +#else + /* set to false to disable LS PMU ucode support */ + return false; +#endif } int gv11b_pmu_bootstrap(struct nvgpu_pmu *pmu) diff --git a/drivers/gpu/nvgpu/gm20b/gr_gm20b.c b/drivers/gpu/nvgpu/gm20b/gr_gm20b.c index 80f5b21c5..226168704 100644 --- a/drivers/gpu/nvgpu/gm20b/gr_gm20b.c +++ b/drivers/gpu/nvgpu/gm20b/gr_gm20b.c @@ -770,7 +770,7 @@ static void gr_gm20b_load_gpccs_with_bootloader(struct gk20a *g) int gr_gm20b_load_ctxsw_ucode(struct gk20a *g) { - int err; + int err = 0; u32 reg_offset = gr_gpcs_gpccs_falcon_hwcfg_r() - gr_fecs_falcon_hwcfg_r(); u8 falcon_id_mask = 0; @@ -799,10 +799,15 @@ int gr_gm20b_load_ctxsw_ucode(struct gk20a *g) FALCON_ID_FECS); err = nvgpu_sec2_bootstrap_ls_falcons(g, &g->sec2, FALCON_ID_GPCCS); + } else if (g->support_ls_pmu) { + err = g->ops.pmu.load_lsfalcon_ucode(g, + BIT32(FALCON_ID_FECS) | + BIT32(FALCON_ID_GPCCS)); } else { - err = g->ops.pmu.load_lsfalcon_ucode(g, - BIT32(FALCON_ID_FECS) | - BIT32(FALCON_ID_GPCCS)); + err = g->acr.bootstrap_hs_acr(g, &g->acr, &g->acr.acr); + if (err != 0) { + nvgpu_err(g, "GR Recovery: ACR GR LSF bootstrap failed"); + } } } if (err != 0) { @@ -830,8 +835,11 @@ int gr_gm20b_load_ctxsw_ucode(struct gk20a *g) FALCON_ID_FECS); err = nvgpu_sec2_bootstrap_ls_falcons(g, &g->sec2, FALCON_ID_GPCCS); - } else { + } else if (g->support_ls_pmu) { err = g->ops.pmu.load_lsfalcon_ucode(g, falcon_id_mask); + } else { + /* GR falcons bootstrapped by ACR */ + err = 0; } if (err != 0) { diff --git a/drivers/gpu/nvgpu/gv11b/hal_gv11b.c b/drivers/gpu/nvgpu/gv11b/hal_gv11b.c index 2bcfa1d19..ebfdbb07b 100644 --- a/drivers/gpu/nvgpu/gv11b/hal_gv11b.c +++ b/drivers/gpu/nvgpu/gv11b/hal_gv11b.c @@ -840,49 +840,68 @@ static const struct gpu_ops gv11b_ops = { .elcg_init_idle_filters = gv11b_elcg_init_idle_filters, }, .pmu = { + /* + * Basic init ops are must, as PMU engine used by ACR to + * load & bootstrap GR LS falcons without LS PMU, remaining + * ops can be assigned/ignored as per build flag request + */ + /* Basic init ops */ + .is_pmu_supported = gv11b_is_pmu_supported, .falcon_base_addr = gk20a_pmu_falcon_base_addr, - .pmu_setup_elpg = gv11b_pmu_setup_elpg, + .pmu_reset = nvgpu_pmu_reset, + .reset_engine = gp106_pmu_engine_reset, + .is_engine_in_reset = gp106_pmu_is_engine_in_reset, + .is_debug_mode_enabled = gm20b_pmu_is_debug_mode_en, + .setup_apertures = gv11b_setup_apertures, + .secured_pmu_start = gm20b_secured_pmu_start, + .write_dmatrfbase = gp10b_write_dmatrfbase, + /* ISR */ + .pmu_enable_irq = gk20a_pmu_enable_irq, +#ifdef NVGPU_LS_PMU + .get_irqdest = gv11b_pmu_get_irqdest, + .handle_ext_irq = gv11b_pmu_handle_ext_irq, + .pmu_is_interrupted = gk20a_pmu_is_interrupted, + .pmu_isr = gk20a_pmu_isr, + /* queue */ .pmu_get_queue_head = pwr_pmu_queue_head_r, .pmu_get_queue_head_size = pwr_pmu_queue_head__size_1_v, .pmu_get_queue_tail = pwr_pmu_queue_tail_r, .pmu_get_queue_tail_size = pwr_pmu_queue_tail__size_1_v, - .pmu_reset = nvgpu_pmu_reset, .pmu_queue_head = gk20a_pmu_queue_head, .pmu_queue_tail = gk20a_pmu_queue_tail, .pmu_msgq_tail = gk20a_pmu_msgq_tail, + /* mutex */ .pmu_mutex_size = pwr_pmu_mutex__size_1_v, .pmu_mutex_acquire = gk20a_pmu_mutex_acquire, .pmu_mutex_release = gk20a_pmu_mutex_release, - .pmu_is_interrupted = gk20a_pmu_is_interrupted, - .pmu_isr = gk20a_pmu_isr, - .pmu_init_perfmon_counter = gk20a_pmu_init_perfmon_counter, + /* power-gating */ + .pmu_pg_init_param = gv11b_pg_gr_init, + .pmu_setup_elpg = gv11b_pmu_setup_elpg, .pmu_pg_idle_counter_config = gk20a_pmu_pg_idle_counter_config, + .pmu_pg_supported_engines_list = gk20a_pmu_pg_engines_list, + .pmu_pg_engines_feature_list = gk20a_pmu_pg_feature_list, + .pmu_pg_set_sub_feature_mask = gv11b_pg_set_subfeature_mask, + .pmu_elpg_statistics = gp106_pmu_elpg_statistics, + .pmu_dump_elpg_stats = gk20a_pmu_dump_elpg_stats, + /* perfmon */ + .pmu_init_perfmon_counter = gk20a_pmu_init_perfmon_counter, .pmu_read_idle_counter = gk20a_pmu_read_idle_counter, .pmu_reset_idle_counter = gk20a_pmu_reset_idle_counter, .pmu_read_idle_intr_status = gk20a_pmu_read_idle_intr_status, .pmu_clear_idle_intr_status = gk20a_pmu_clear_idle_intr_status, - .pmu_dump_elpg_stats = gk20a_pmu_dump_elpg_stats, - .pmu_dump_falcon_stats = gk20a_pmu_dump_falcon_stats, - .pmu_enable_irq = gk20a_pmu_enable_irq, - .write_dmatrfbase = gp10b_write_dmatrfbase, - .pmu_elpg_statistics = gp106_pmu_elpg_statistics, .pmu_init_perfmon = nvgpu_pmu_init_perfmon_rpc, .pmu_perfmon_start_sampling = nvgpu_pmu_perfmon_start_sampling_rpc, .pmu_perfmon_stop_sampling = nvgpu_pmu_perfmon_stop_sampling_rpc, .pmu_perfmon_get_samples_rpc = nvgpu_pmu_perfmon_get_samples_rpc, - .pmu_pg_init_param = gv11b_pg_gr_init, - .pmu_pg_supported_engines_list = gk20a_pmu_pg_engines_list, - .pmu_pg_engines_feature_list = gk20a_pmu_pg_feature_list, + /* debug */ .dump_secure_fuses = pmu_dump_security_fuses_gm20b, - .reset_engine = gp106_pmu_engine_reset, - .is_engine_in_reset = gp106_pmu_is_engine_in_reset, - .pmu_nsbootstrap = gv11b_pmu_bootstrap, - .pmu_pg_set_sub_feature_mask = gv11b_pg_set_subfeature_mask, - .is_pmu_supported = gv11b_is_pmu_supported, - .get_irqdest = gv11b_pmu_get_irqdest, - .handle_ext_irq = gv11b_pmu_handle_ext_irq, - .is_debug_mode_enabled = gm20b_pmu_is_debug_mode_en, + .pmu_dump_falcon_stats = gk20a_pmu_dump_falcon_stats, + /* PMU uocde */ + .update_lspmu_cmdline_args = gm20b_update_lspmu_cmdline_args, + .init_wpr_region = gm20b_pmu_init_acr, + .load_lsfalcon_ucode = gp10b_load_falcon_ucode, .save_zbc = gk20a_pmu_save_zbc, +#endif }, .clk_arb = { .check_clk_arb_support = gp10b_check_clk_arb_support, @@ -1104,18 +1123,10 @@ int gv11b_init_hal(struct gk20a *g) /* priv security dependent ops */ if (nvgpu_is_enabled(g, NVGPU_SEC_PRIVSECURITY)) { - /* Add in ops from gm20b acr */ - gops->pmu.update_lspmu_cmdline_args = - gm20b_update_lspmu_cmdline_args; - gops->pmu.setup_apertures = gv11b_setup_apertures; - gops->pmu.secured_pmu_start = gm20b_secured_pmu_start; - - gops->pmu.init_wpr_region = gm20b_pmu_init_acr; - gops->pmu.load_lsfalcon_ucode = gp10b_load_falcon_ucode; - gops->gr.load_ctxsw_ucode = gr_gm20b_load_ctxsw_ucode; } else { - /* Inherit from gk20a */ + /* non-secure boot */ + gops->pmu.pmu_nsbootstrap = gv11b_pmu_bootstrap; gops->pmu.pmu_setup_hw_and_bootstrap = gm20b_ns_pmu_setup_hw_and_bootstrap;