From 2cf8feedd8729428330337902401c58ae738584d Mon Sep 17 00:00:00 2001 From: Mahantesh Kumbar Date: Thu, 4 Apr 2019 09:30:19 +0530 Subject: [PATCH] gpu: nvgpu: Create PMU HAL Moved PMU HAL code from common/pmu/pmu_chip.c/h to hal at path hal/pmu/pmu_chip.c/h file. some code may need more cleanup but will take care in new patches JIRA NVGPU-2002 Change-Id: I281a2c15e55292e0716b0a4c71f4469c97dd71ab Signed-off-by: Mahantesh Kumbar Reviewed-on: https://git-master.nvidia.com/r/2089410 Reviewed-by: mobile promotions Tested-by: mobile promotions --- drivers/gpu/nvgpu/Makefile | 15 +- drivers/gpu/nvgpu/Makefile.sources | 15 +- drivers/gpu/nvgpu/common/acr/acr_sw_gm20b.c | 9 +- drivers/gpu/nvgpu/common/acr/acr_sw_gv11b.c | 9 +- .../gpu/nvgpu/common/pmu/lsfm/lsfm_sw_gm20b.c | 2 - drivers/gpu/nvgpu/common/pmu/pmu.c | 2 +- drivers/gpu/nvgpu/common/pmu/pmu_debug.c | 16 + drivers/gpu/nvgpu/gm20b/hal_gm20b.c | 7 +- drivers/gpu/nvgpu/gp10b/hal_gp10b.c | 9 +- drivers/gpu/nvgpu/gv100/hal_gv100.c | 11 +- drivers/gpu/nvgpu/gv11b/hal_gv11b.c | 13 +- .../gpu/nvgpu/{common => hal}/pmu/pmu_gk20a.c | 733 +++++++++++------- .../gpu/nvgpu/{common => hal}/pmu/pmu_gk20a.h | 62 +- .../gpu/nvgpu/{common => hal}/pmu/pmu_gm20b.c | 9 +- .../gpu/nvgpu/{common => hal}/pmu/pmu_gm20b.h | 13 +- .../gpu/nvgpu/{common => hal}/pmu/pmu_gp106.c | 0 .../gpu/nvgpu/{common => hal}/pmu/pmu_gp106.h | 6 +- .../gpu/nvgpu/{common => hal}/pmu/pmu_gp10b.c | 4 +- .../gpu/nvgpu/{common => hal}/pmu/pmu_gp10b.h | 8 +- .../gpu/nvgpu/{common => hal}/pmu/pmu_gv11b.c | 5 +- .../gpu/nvgpu/{common => hal}/pmu/pmu_gv11b.h | 10 +- drivers/gpu/nvgpu/hal/pmu/pmu_hal_gk20a.c | 179 ----- drivers/gpu/nvgpu/hal/pmu/pmu_hal_gk20a.h | 41 - .../gpu/nvgpu/{common => hal}/pmu/pmu_tu104.c | 2 +- .../gpu/nvgpu/{common => hal}/pmu/pmu_tu104.h | 8 +- drivers/gpu/nvgpu/include/nvgpu/gk20a.h | 92 ++- drivers/gpu/nvgpu/include/nvgpu/pmu.h | 2 - drivers/gpu/nvgpu/tu104/hal_tu104.c | 13 +- 28 files changed, 609 insertions(+), 686 deletions(-) rename drivers/gpu/nvgpu/{common => hal}/pmu/pmu_gk20a.c (76%) rename drivers/gpu/nvgpu/{common => hal}/pmu/pmu_gk20a.h (75%) rename drivers/gpu/nvgpu/{common => hal}/pmu/pmu_gm20b.c (98%) rename drivers/gpu/nvgpu/{common => hal}/pmu/pmu_gm20b.h (90%) rename drivers/gpu/nvgpu/{common => hal}/pmu/pmu_gp106.c (100%) rename drivers/gpu/nvgpu/{common => hal}/pmu/pmu_gp106.h (94%) rename drivers/gpu/nvgpu/{common => hal}/pmu/pmu_gp10b.c (99%) rename drivers/gpu/nvgpu/{common => hal}/pmu/pmu_gp10b.h (93%) rename drivers/gpu/nvgpu/{common => hal}/pmu/pmu_gv11b.c (99%) rename drivers/gpu/nvgpu/{common => hal}/pmu/pmu_gv11b.h (90%) delete mode 100644 drivers/gpu/nvgpu/hal/pmu/pmu_hal_gk20a.c delete mode 100644 drivers/gpu/nvgpu/hal/pmu/pmu_hal_gk20a.h rename drivers/gpu/nvgpu/{common => hal}/pmu/pmu_tu104.c (95%) rename drivers/gpu/nvgpu/{common => hal}/pmu/pmu_tu104.h (88%) diff --git a/drivers/gpu/nvgpu/Makefile b/drivers/gpu/nvgpu/Makefile index 567c7dfdf..b8a2a3b03 100644 --- a/drivers/gpu/nvgpu/Makefile +++ b/drivers/gpu/nvgpu/Makefile @@ -83,16 +83,10 @@ nvgpu-y += \ common/pmu/pg/pmu_aelpg.o \ common/pmu/perfmon/pmu_perfmon.o \ common/pmu/pmu_debug.o \ - common/pmu/pmu_gk20a.o \ - common/pmu/pmu_gm20b.o \ - common/pmu/pmu_gp10b.o \ - common/pmu/pmu_gp106.o \ - common/pmu/pmu_gv11b.o \ common/pmu/pg/pg_sw_gm20b.o \ common/pmu/pg/pg_sw_gp10b.o \ common/pmu/pg/pg_sw_gp106.o \ common/pmu/pg/pg_sw_gv11b.o \ - common/pmu/pmu_tu104.o \ common/pmu/ipc/pmu_cmd.o \ common/pmu/ipc/pmu_msg.o \ common/pmu/ipc/pmu_queue.o \ @@ -287,9 +281,14 @@ nvgpu-y += \ hal/nvlink/link_mode_transitions_gv100.o \ hal/nvlink/link_mode_transitions_tu104.o \ hal/gsp/gsp_gv100.o \ - hal/pmu/pmu_hal_gk20a.o \ hal/sec2/sec2_gp106.o \ - hal/sec2/sec2_tu104.o + hal/sec2/sec2_tu104.o \ + hal/pmu/pmu_gk20a.o \ + hal/pmu/pmu_gm20b.o \ + hal/pmu/pmu_gp10b.o \ + hal/pmu/pmu_gp106.o \ + hal/pmu/pmu_gv11b.o \ + hal/pmu/pmu_tu104.o # Linux specific parts of nvgpu. nvgpu-y += \ diff --git a/drivers/gpu/nvgpu/Makefile.sources b/drivers/gpu/nvgpu/Makefile.sources index 37ee5159e..0f27ff2dc 100644 --- a/drivers/gpu/nvgpu/Makefile.sources +++ b/drivers/gpu/nvgpu/Makefile.sources @@ -128,16 +128,10 @@ srcs += common/sim.c \ common/pmu/pg/pmu_aelpg.c \ common/pmu/perfmon/pmu_perfmon.c \ common/pmu/pmu_debug.c \ - common/pmu/pmu_gk20a.c \ - common/pmu/pmu_gm20b.c \ - common/pmu/pmu_gp10b.c \ - common/pmu/pmu_gp106.c \ - common/pmu/pmu_gv11b.c \ common/pmu/pg/pg_sw_gm20b.c \ common/pmu/pg/pg_sw_gp10b.c \ common/pmu/pg/pg_sw_gp106.c \ common/pmu/pg/pg_sw_gv11b.c \ - common/pmu/pmu_tu104.c \ common/pmu/ipc/pmu_cmd.c \ common/pmu/ipc/pmu_msg.c \ common/pmu/ipc/pmu_queue.c \ @@ -408,9 +402,14 @@ srcs += common/sim.c \ hal/nvlink/link_mode_transitions_gv100.c \ hal/nvlink/link_mode_transitions_tu104.c \ hal/gsp/gsp_gv100.c \ - hal/pmu/pmu_hal_gk20a.c \ hal/sec2/sec2_gp106.c \ - hal/sec2/sec2_tu104.c + hal/sec2/sec2_tu104.c \ + hal/pmu/pmu_gk20a.c \ + hal/pmu/pmu_gm20b.c \ + hal/pmu/pmu_gp10b.c \ + hal/pmu/pmu_gp106.c \ + hal/pmu/pmu_gv11b.c \ + hal/pmu/pmu_tu104.c ifeq ($(NVGPU_DEBUGGER),1) srcs += common/debugger.c diff --git a/drivers/gpu/nvgpu/common/acr/acr_sw_gm20b.c b/drivers/gpu/nvgpu/common/acr/acr_sw_gm20b.c index 60d430e8c..72d5f2185 100644 --- a/drivers/gpu/nvgpu/common/acr/acr_sw_gm20b.c +++ b/drivers/gpu/nvgpu/common/acr/acr_sw_gm20b.c @@ -20,16 +20,12 @@ * DEALINGS IN THE SOFTWARE. */ -#include "acr_sw_gm20b.h" - #include #include #include #include #include -#include "common/pmu/pmu_gm20b.h" - #include "acr_wpr.h" #include "acr_priv.h" #include "acr_sw_gm20b.h" @@ -169,9 +165,10 @@ static void gm20b_acr_default_sw_init(struct gk20a *g, struct hs_acr *hs_acr) /* set on which falcon ACR need to execute*/ hs_acr->acr_flcn = &g->pmu.flcn; - hs_acr->acr_flcn_setup_boot_config = gm20b_pmu_flcn_setup_boot_config; + hs_acr->acr_flcn_setup_boot_config = + g->ops.pmu.flcn_setup_boot_config; hs_acr->acr_engine_bus_err_status = - gk20a_pmu_bar0_error_status; + g->ops.pmu.bar0_error_status; } void nvgpu_gm20b_acr_sw_init(struct gk20a *g, struct nvgpu_acr *acr) diff --git a/drivers/gpu/nvgpu/common/acr/acr_sw_gv11b.c b/drivers/gpu/nvgpu/common/acr/acr_sw_gv11b.c index 3215da0e9..d80c4cb11 100644 --- a/drivers/gpu/nvgpu/common/acr/acr_sw_gv11b.c +++ b/drivers/gpu/nvgpu/common/acr/acr_sw_gv11b.c @@ -20,15 +20,11 @@ * DEALINGS IN THE SOFTWARE. */ -#include "acr_sw_gv11b.h" - #include #include #include #include -#include "common/pmu/pmu_gm20b.h" - #include "acr_wpr.h" #include "acr_priv.h" #include "acr_blob_alloc.h" @@ -165,11 +161,12 @@ static void gv11b_acr_default_sw_init(struct gk20a *g, struct hs_acr *hs_acr) hs_acr->bl_dmem_desc_size = (u32)sizeof(struct flcn_bl_dmem_desc_v1); hs_acr->acr_flcn = &g->pmu.flcn; - hs_acr->acr_flcn_setup_boot_config = gm20b_pmu_flcn_setup_boot_config; + hs_acr->acr_flcn_setup_boot_config = + g->ops.pmu.flcn_setup_boot_config; hs_acr->report_acr_engine_bus_err_status = nvgpu_pmu_report_bar0_pri_err_status; hs_acr->acr_engine_bus_err_status = - gk20a_pmu_bar0_error_status; + g->ops.pmu.bar0_error_status;; } void nvgpu_gv11b_acr_sw_init(struct gk20a *g, struct nvgpu_acr *acr) diff --git a/drivers/gpu/nvgpu/common/pmu/lsfm/lsfm_sw_gm20b.c b/drivers/gpu/nvgpu/common/pmu/lsfm/lsfm_sw_gm20b.c index 30f8b8590..86d52858d 100644 --- a/drivers/gpu/nvgpu/common/pmu/lsfm/lsfm_sw_gm20b.c +++ b/drivers/gpu/nvgpu/common/pmu/lsfm/lsfm_sw_gm20b.c @@ -27,8 +27,6 @@ #include #include -#include "common/pmu/pmu_gm20b.h" - #include "lsfm_sw_gm20b.h" static void lsfm_handle_acr_init_wpr_region_msg(struct gk20a *g, diff --git a/drivers/gpu/nvgpu/common/pmu/pmu.c b/drivers/gpu/nvgpu/common/pmu/pmu.c index fbd7935d0..75b76d119 100644 --- a/drivers/gpu/nvgpu/common/pmu/pmu.c +++ b/drivers/gpu/nvgpu/common/pmu/pmu.c @@ -301,7 +301,7 @@ int nvgpu_init_pmu_support(struct gk20a *g) err = nvgpu_pmu_prepare_ns_ucode_blob(g); /* Do non-secure PMU boot */ - err = g->ops.pmu.pmu_setup_hw_and_bootstrap(g); + err = g->ops.pmu.pmu_setup_hw_and_bootstrap(g, pmu); if (err != 0) { goto exit; } diff --git a/drivers/gpu/nvgpu/common/pmu/pmu_debug.c b/drivers/gpu/nvgpu/common/pmu/pmu_debug.c index 88d74cbb2..48d1ddb76 100644 --- a/drivers/gpu/nvgpu/common/pmu/pmu_debug.c +++ b/drivers/gpu/nvgpu/common/pmu/pmu_debug.c @@ -23,6 +23,22 @@ #include #include +bool nvgpu_find_hex_in_string(char *strings, struct gk20a *g, u32 *hex_pos) +{ + u32 i = 0, j = (u32)strlen(strings); + + for (; i < j; i++) { + if (strings[i] == '%') { + if (strings[i + 1U] == 'x' || strings[i + 1U] == 'X') { + *hex_pos = i; + return true; + } + } + } + *hex_pos = U32_MAX; + return false; +} + static void print_pmu_trace(struct nvgpu_pmu *pmu) { struct gk20a *g = pmu->g; diff --git a/drivers/gpu/nvgpu/gm20b/hal_gm20b.c b/drivers/gpu/nvgpu/gm20b/hal_gm20b.c index 639442de0..afef52e67 100644 --- a/drivers/gpu/nvgpu/gm20b/hal_gm20b.c +++ b/drivers/gpu/nvgpu/gm20b/hal_gm20b.c @@ -81,13 +81,12 @@ #include "hal/gr/intr/gr_intr_gm20b.h" #include "hal/gr/config/gr_config_gm20b.h" #include "hal/gr/ctxsw_prog/ctxsw_prog_gm20b.h" +#include "hal/pmu/pmu_gk20a.h" +#include "hal/pmu/pmu_gm20b.h" #include "hal/falcon/falcon_gk20a.h" #include "hal/perf/perf_gm20b.h" -#include "hal/pmu/pmu_hal_gk20a.h" #include "hal/netlist/netlist_gm20b.h" -#include "common/pmu/pmu_gk20a.h" -#include "common/pmu/pmu_gm20b.h" #include "common/top/top_gm20b.h" #include "common/sync/syncpt_cmdbuf_gk20a.h" #include "common/sync/sema_cmdbuf_gk20a.h" @@ -875,6 +874,8 @@ static const struct gpu_ops gm20b_ops = { .save_zbc = gm20b_pmu_save_zbc, .pmu_clear_bar0_host_err_status = gm20b_clear_pmu_bar0_host_err_status, + .bar0_error_status = gk20a_pmu_bar0_error_status, + .flcn_setup_boot_config = gm20b_pmu_flcn_setup_boot_config, }, .clk = { .init_clk_support = gm20b_init_clk_support, diff --git a/drivers/gpu/nvgpu/gp10b/hal_gp10b.c b/drivers/gpu/nvgpu/gp10b/hal_gp10b.c index 205c17e47..73386ac4b 100644 --- a/drivers/gpu/nvgpu/gp10b/hal_gp10b.c +++ b/drivers/gpu/nvgpu/gp10b/hal_gp10b.c @@ -101,14 +101,13 @@ #include "hal/gr/intr/gr_intr_gp10b.h" #include "hal/gr/ctxsw_prog/ctxsw_prog_gm20b.h" #include "hal/gr/ctxsw_prog/ctxsw_prog_gp10b.h" +#include "hal/pmu/pmu_gk20a.h" +#include "hal/pmu/pmu_gm20b.h" +#include "hal/pmu/pmu_gp10b.h" #include "hal/falcon/falcon_gk20a.h" #include "hal/perf/perf_gm20b.h" -#include "hal/pmu/pmu_hal_gk20a.h" #include "hal/netlist/netlist_gp10b.h" -#include "common/pmu/pmu_gk20a.h" -#include "common/pmu/pmu_gm20b.h" -#include "common/pmu/pmu_gp10b.h" #include "common/pmu/pg/pg_sw_gm20b.h" #include "common/pmu/pg/pg_sw_gp10b.h" #include "common/top/top_gm20b.h" @@ -972,6 +971,8 @@ static const struct gpu_ops gp10b_ops = { .save_zbc = gm20b_pmu_save_zbc, .pmu_clear_bar0_host_err_status = gm20b_clear_pmu_bar0_host_err_status, + .bar0_error_status = gk20a_pmu_bar0_error_status, + .flcn_setup_boot_config = gm20b_pmu_flcn_setup_boot_config, }, .clk_arb = { .check_clk_arb_support = gp10b_check_clk_arb_support, diff --git a/drivers/gpu/nvgpu/gv100/hal_gv100.c b/drivers/gpu/nvgpu/gv100/hal_gv100.c index 07a2e76f6..c26542c10 100644 --- a/drivers/gpu/nvgpu/gv100/hal_gv100.c +++ b/drivers/gpu/nvgpu/gv100/hal_gv100.c @@ -97,11 +97,15 @@ #include "hal/gr/ctxsw_prog/ctxsw_prog_gm20b.h" #include "hal/gr/ctxsw_prog/ctxsw_prog_gp10b.h" #include "hal/gr/ctxsw_prog/ctxsw_prog_gv11b.h" +#include "hal/pmu/pmu_gk20a.h" +#include "hal/pmu/pmu_gm20b.h" +#include "hal/pmu/pmu_gp10b.h" +#include "hal/pmu/pmu_gp106.h" +#include "hal/pmu/pmu_gv11b.h" #include "hal/falcon/falcon_gk20a.h" #include "hal/nvdec/nvdec_gp106.h" #include "hal/gsp/gsp_gv100.h" #include "hal/perf/perf_gv11b.h" -#include "hal/pmu/pmu_hal_gk20a.h" #include "hal/sec2/sec2_gp106.h" #include "hal/netlist/netlist_gv100.h" @@ -109,11 +113,6 @@ #include "common/top/top_gm20b.h" #include "common/top/top_gp10b.h" #include "common/top/top_gv100.h" -#include "common/pmu/pmu_gk20a.h" -#include "common/pmu/pmu_gm20b.h" -#include "common/pmu/pmu_gp10b.h" -#include "common/pmu/pmu_gp106.h" -#include "common/pmu/pmu_gv11b.h" #include "common/nvlink/init/device_reginit_gv100.h" #include "common/nvlink/intr_and_err_handling_gv100.h" #include "hal/nvlink/minion_gv100.h" diff --git a/drivers/gpu/nvgpu/gv11b/hal_gv11b.c b/drivers/gpu/nvgpu/gv11b/hal_gv11b.c index 31f566fff..9396e9f1f 100644 --- a/drivers/gpu/nvgpu/gv11b/hal_gv11b.c +++ b/drivers/gpu/nvgpu/gv11b/hal_gv11b.c @@ -100,16 +100,15 @@ #include "hal/gr/ctxsw_prog/ctxsw_prog_gm20b.h" #include "hal/gr/ctxsw_prog/ctxsw_prog_gp10b.h" #include "hal/gr/ctxsw_prog/ctxsw_prog_gv11b.h" +#include "hal/pmu/pmu_gk20a.h" +#include "hal/pmu/pmu_gm20b.h" +#include "hal/pmu/pmu_gp106.h" +#include "hal/pmu/pmu_gp10b.h" +#include "hal/pmu/pmu_gv11b.h" #include "hal/falcon/falcon_gk20a.h" #include "hal/perf/perf_gv11b.h" -#include "hal/pmu/pmu_hal_gk20a.h" #include "hal/netlist/netlist_gv11b.h" -#include "common/pmu/pmu_gk20a.h" -#include "common/pmu/pmu_gm20b.h" -#include "common/pmu/pmu_gp10b.h" -#include "common/pmu/pmu_gp106.h" -#include "common/pmu/pmu_gv11b.h" #include "common/pmu/pg/pg_sw_gm20b.h" #include "common/pmu/pg/pg_sw_gp106.h" #include "common/pmu/pg/pg_sw_gv11b.h" @@ -1143,6 +1142,8 @@ static const struct gpu_ops gv11b_ops = { .save_zbc = gm20b_pmu_save_zbc, .pmu_clear_bar0_host_err_status = gm20b_clear_pmu_bar0_host_err_status, + .bar0_error_status = gk20a_pmu_bar0_error_status, + .flcn_setup_boot_config = gm20b_pmu_flcn_setup_boot_config, #endif }, .clk_arb = { diff --git a/drivers/gpu/nvgpu/common/pmu/pmu_gk20a.c b/drivers/gpu/nvgpu/hal/pmu/pmu_gk20a.c similarity index 76% rename from drivers/gpu/nvgpu/common/pmu/pmu_gk20a.c rename to drivers/gpu/nvgpu/hal/pmu/pmu_gk20a.c index 06e3b8aaa..da142668a 100644 --- a/drivers/gpu/nvgpu/common/pmu/pmu_gk20a.c +++ b/drivers/gpu/nvgpu/hal/pmu/pmu_gk20a.c @@ -1,6 +1,4 @@ /* - * GK20A PMU (aka. gPMU outside gk20a context) - * * Copyright (c) 2011-2019, NVIDIA CORPORATION. All rights reserved. * * Permission is hereby granted, free of charge, to any person obtaining a @@ -22,200 +20,142 @@ * DEALINGS IN THE SOFTWARE. */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include #include -#include #include -#include +#include +#include #include +#include +#include + +#include +#include -#include "gk20a/gr_gk20a.h" #include "pmu_gk20a.h" -#include -#include -#include - -bool nvgpu_find_hex_in_string(char *strings, struct gk20a *g, u32 *hex_pos) -{ - u32 i = 0, j = (u32)strlen(strings); - - for (; i < j; i++) { - if (strings[i] == '%') { - if (strings[i + 1U] == 'x' || strings[i + 1U] == 'X') { - *hex_pos = i; - return true; - } - } - } - *hex_pos = U32_MAX; - return false; -} - -u32 gk20a_pmu_get_irqdest(struct gk20a *g) -{ - u32 intr_dest; - - /* dest 0=falcon, 1=host; level 0=irq0, 1=irq1 */ - intr_dest = pwr_falcon_irqdest_host_gptmr_f(0) | - pwr_falcon_irqdest_host_wdtmr_f(1) | - pwr_falcon_irqdest_host_mthd_f(0) | - pwr_falcon_irqdest_host_ctxsw_f(0) | - pwr_falcon_irqdest_host_halt_f(1) | - pwr_falcon_irqdest_host_exterr_f(0) | - pwr_falcon_irqdest_host_swgen0_f(1) | - pwr_falcon_irqdest_host_swgen1_f(0) | - pwr_falcon_irqdest_host_ext_f(0xff) | - pwr_falcon_irqdest_target_gptmr_f(1) | - pwr_falcon_irqdest_target_wdtmr_f(0) | - pwr_falcon_irqdest_target_mthd_f(0) | - pwr_falcon_irqdest_target_ctxsw_f(0) | - pwr_falcon_irqdest_target_halt_f(0) | - pwr_falcon_irqdest_target_exterr_f(0) | - pwr_falcon_irqdest_target_swgen0_f(0) | - pwr_falcon_irqdest_target_swgen1_f(0) | - pwr_falcon_irqdest_target_ext_f(0xff); - - return intr_dest; -} - -void gk20a_pmu_enable_irq(struct nvgpu_pmu *pmu, bool enable) +void gk20a_pmu_dump_falcon_stats(struct nvgpu_pmu *pmu) { struct gk20a *g = gk20a_from_pmu(pmu); - u32 intr_mask; - u32 intr_dest; + unsigned int i; - nvgpu_log_fn(g, " "); - - g->ops.mc.intr_unit_config(g, MC_INTR_UNIT_DISABLE, true, - mc_intr_mask_0_pmu_enabled_f()); - g->ops.mc.intr_unit_config(g, MC_INTR_UNIT_DISABLE, false, - mc_intr_mask_1_pmu_enabled_f()); - - nvgpu_falcon_set_irq(&pmu->flcn, false, 0x0, 0x0); - - if (enable) { - intr_dest = g->ops.pmu.get_irqdest(g); - /* 0=disable, 1=enable */ - intr_mask = pwr_falcon_irqmset_gptmr_f(1) | - pwr_falcon_irqmset_wdtmr_f(1) | - pwr_falcon_irqmset_mthd_f(0) | - pwr_falcon_irqmset_ctxsw_f(0) | - pwr_falcon_irqmset_halt_f(1) | - pwr_falcon_irqmset_exterr_f(1) | - pwr_falcon_irqmset_swgen0_f(1) | - pwr_falcon_irqmset_swgen1_f(1); - - nvgpu_falcon_set_irq(&pmu->flcn, true, intr_mask, intr_dest); - - g->ops.mc.intr_unit_config(g, MC_INTR_UNIT_ENABLE, true, - mc_intr_mask_0_pmu_enabled_f()); + for (i = 0; i < pwr_pmu_mailbox__size_1_v(); i++) { + nvgpu_err(g, "pwr_pmu_mailbox_r(%d) : 0x%x", + i, gk20a_readl(g, pwr_pmu_mailbox_r(i))); } - nvgpu_log_fn(g, "done"); + for (i = 0; i < pwr_pmu_debug__size_1_v(); i++) { + nvgpu_err(g, "pwr_pmu_debug_r(%d) : 0x%x", + i, gk20a_readl(g, pwr_pmu_debug_r(i))); + } + + i = gk20a_readl(g, pwr_pmu_bar0_error_status_r()); + nvgpu_err(g, "pwr_pmu_bar0_error_status_r : 0x%x", i); + if (i != 0U) { + nvgpu_err(g, "pwr_pmu_bar0_addr_r : 0x%x", + gk20a_readl(g, pwr_pmu_bar0_addr_r())); + nvgpu_err(g, "pwr_pmu_bar0_data_r : 0x%x", + gk20a_readl(g, pwr_pmu_bar0_data_r())); + nvgpu_err(g, "pwr_pmu_bar0_timeout_r : 0x%x", + gk20a_readl(g, pwr_pmu_bar0_timeout_r())); + nvgpu_err(g, "pwr_pmu_bar0_ctl_r : 0x%x", + gk20a_readl(g, pwr_pmu_bar0_ctl_r())); + } + + i = gk20a_readl(g, pwr_pmu_bar0_fecs_error_r()); + nvgpu_err(g, "pwr_pmu_bar0_fecs_error_r : 0x%x", i); + + i = gk20a_readl(g, pwr_falcon_exterrstat_r()); + nvgpu_err(g, "pwr_falcon_exterrstat_r : 0x%x", i); + if (pwr_falcon_exterrstat_valid_v(i) == + pwr_falcon_exterrstat_valid_true_v()) { + nvgpu_err(g, "pwr_falcon_exterraddr_r : 0x%x", + gk20a_readl(g, pwr_falcon_exterraddr_r())); + } } - - -int pmu_bootstrap(struct nvgpu_pmu *pmu) +/* perfmon */ +void gk20a_pmu_init_perfmon_counter(struct gk20a *g) { - struct gk20a *g = gk20a_from_pmu(pmu); - struct mm_gk20a *mm = &g->mm; - struct pmu_ucode_desc *desc = - (struct pmu_ucode_desc *)(void *)pmu->fw_image->data; - u32 addr_code, addr_data, addr_load; - u32 i, blocks, addr_args; - int err; - u32 inst_block_ptr; + u32 data; - nvgpu_log_fn(g, " "); + /* use counter #3 for GR && CE2 busy cycles */ + gk20a_writel(g, pwr_pmu_idle_mask_r(3), + pwr_pmu_idle_mask_gr_enabled_f() | + pwr_pmu_idle_mask_ce_2_enabled_f()); - gk20a_writel(g, pwr_falcon_itfen_r(), - gk20a_readl(g, pwr_falcon_itfen_r()) | - pwr_falcon_itfen_ctxen_enable_f()); - inst_block_ptr = nvgpu_inst_block_ptr(g, &mm->pmu.inst_block); - gk20a_writel(g, pwr_pmu_new_instblk_r(), - pwr_pmu_new_instblk_ptr_f(inst_block_ptr) | - pwr_pmu_new_instblk_valid_f(1) | - pwr_pmu_new_instblk_target_sys_coh_f()); + /* disable idle filtering for counters 3 and 6 */ + data = gk20a_readl(g, pwr_pmu_idle_ctrl_r(3)); + data = set_field(data, pwr_pmu_idle_ctrl_value_m() | + pwr_pmu_idle_ctrl_filter_m(), + pwr_pmu_idle_ctrl_value_busy_f() | + pwr_pmu_idle_ctrl_filter_disabled_f()); + gk20a_writel(g, pwr_pmu_idle_ctrl_r(3), data); - /* TBD: load all other surfaces */ - g->ops.pmu_ver.set_pmu_cmdline_args_trace_size( - pmu, GK20A_PMU_TRACE_BUFSIZE); - g->ops.pmu_ver.set_pmu_cmdline_args_trace_dma_base(pmu); - g->ops.pmu_ver.set_pmu_cmdline_args_trace_dma_idx( - pmu, GK20A_PMU_DMAIDX_VIRT); + /* use counter #6 for total cycles */ + data = gk20a_readl(g, pwr_pmu_idle_ctrl_r(6)); + data = set_field(data, pwr_pmu_idle_ctrl_value_m() | + pwr_pmu_idle_ctrl_filter_m(), + pwr_pmu_idle_ctrl_value_always_f() | + pwr_pmu_idle_ctrl_filter_disabled_f()); + gk20a_writel(g, pwr_pmu_idle_ctrl_r(6), data); - g->ops.pmu_ver.set_pmu_cmdline_args_cpu_freq(pmu, - g->ops.clk.get_rate(g, CTRL_CLK_DOMAIN_PWRCLK)); + /* + * We don't want to disturb counters #3 and #6, which are used by + * perfmon, so we add wiring also to counters #1 and #2 for + * exposing raw counter readings. + */ + gk20a_writel(g, pwr_pmu_idle_mask_r(1), + pwr_pmu_idle_mask_gr_enabled_f() | + pwr_pmu_idle_mask_ce_2_enabled_f()); - addr_args = (pwr_falcon_hwcfg_dmem_size_v( - gk20a_readl(g, pwr_falcon_hwcfg_r())) - << GK20A_PMU_DMEM_BLKSIZE2) - - g->ops.pmu_ver.get_pmu_cmdline_args_size(pmu); + data = gk20a_readl(g, pwr_pmu_idle_ctrl_r(1)); + data = set_field(data, pwr_pmu_idle_ctrl_value_m() | + pwr_pmu_idle_ctrl_filter_m(), + pwr_pmu_idle_ctrl_value_busy_f() | + pwr_pmu_idle_ctrl_filter_disabled_f()); + gk20a_writel(g, pwr_pmu_idle_ctrl_r(1), data); - nvgpu_falcon_copy_to_dmem(&pmu->flcn, addr_args, - (u8 *)(g->ops.pmu_ver.get_pmu_cmdline_args_ptr(pmu)), - g->ops.pmu_ver.get_pmu_cmdline_args_size(pmu), 0); + data = gk20a_readl(g, pwr_pmu_idle_ctrl_r(2)); + data = set_field(data, pwr_pmu_idle_ctrl_value_m() | + pwr_pmu_idle_ctrl_filter_m(), + pwr_pmu_idle_ctrl_value_always_f() | + pwr_pmu_idle_ctrl_filter_disabled_f()); + gk20a_writel(g, pwr_pmu_idle_ctrl_r(2), data); - gk20a_writel(g, pwr_falcon_dmemc_r(0), - pwr_falcon_dmemc_offs_f(0) | - pwr_falcon_dmemc_blk_f(0) | - pwr_falcon_dmemc_aincw_f(1)); + /* + * use counters 4 and 0 for perfmon to log busy cycles and total + * cycles counter #0 overflow sets pmu idle intr status bit + */ + gk20a_writel(g, pwr_pmu_idle_intr_r(), + pwr_pmu_idle_intr_en_f(0)); - addr_code = u64_lo32((pmu->ucode.gpu_va + - desc->app_start_offset + - desc->app_resident_code_offset) >> 8) ; - addr_data = u64_lo32((pmu->ucode.gpu_va + - desc->app_start_offset + - desc->app_resident_data_offset) >> 8); - addr_load = u64_lo32((pmu->ucode.gpu_va + - desc->bootloader_start_offset) >> 8); + gk20a_writel(g, pwr_pmu_idle_threshold_r(0), + pwr_pmu_idle_threshold_value_f(0x7FFFFFFF)); - gk20a_writel(g, pwr_falcon_dmemd_r(0), GK20A_PMU_DMAIDX_UCODE); - gk20a_writel(g, pwr_falcon_dmemd_r(0), addr_code); - gk20a_writel(g, pwr_falcon_dmemd_r(0), desc->app_size); - gk20a_writel(g, pwr_falcon_dmemd_r(0), desc->app_resident_code_size); - gk20a_writel(g, pwr_falcon_dmemd_r(0), desc->app_imem_entry); - gk20a_writel(g, pwr_falcon_dmemd_r(0), addr_data); - gk20a_writel(g, pwr_falcon_dmemd_r(0), desc->app_resident_data_size); - gk20a_writel(g, pwr_falcon_dmemd_r(0), addr_code); - gk20a_writel(g, pwr_falcon_dmemd_r(0), 0x1); - gk20a_writel(g, pwr_falcon_dmemd_r(0), addr_args); + data = gk20a_readl(g, pwr_pmu_idle_ctrl_r(0)); + data = set_field(data, pwr_pmu_idle_ctrl_value_m() | + pwr_pmu_idle_ctrl_filter_m(), + pwr_pmu_idle_ctrl_value_always_f() | + pwr_pmu_idle_ctrl_filter_disabled_f()); + gk20a_writel(g, pwr_pmu_idle_ctrl_r(0), data); - g->ops.pmu.write_dmatrfbase(g, - addr_load - (desc->bootloader_imem_offset >> U32(8))); + gk20a_writel(g, pwr_pmu_idle_mask_r(4), + pwr_pmu_idle_mask_gr_enabled_f() | + pwr_pmu_idle_mask_ce_2_enabled_f()); - blocks = ((desc->bootloader_size + 0xFFU) & ~0xFFU) >> 8; + data = gk20a_readl(g, pwr_pmu_idle_ctrl_r(4)); + data = set_field(data, pwr_pmu_idle_ctrl_value_m() | + pwr_pmu_idle_ctrl_filter_m(), + pwr_pmu_idle_ctrl_value_busy_f() | + pwr_pmu_idle_ctrl_filter_disabled_f()); + gk20a_writel(g, pwr_pmu_idle_ctrl_r(4), data); - for (i = 0; i < blocks; i++) { - gk20a_writel(g, pwr_falcon_dmatrfmoffs_r(), - desc->bootloader_imem_offset + (i << 8)); - gk20a_writel(g, pwr_falcon_dmatrffboffs_r(), - desc->bootloader_imem_offset + (i << 8)); - gk20a_writel(g, pwr_falcon_dmatrfcmd_r(), - pwr_falcon_dmatrfcmd_imem_f(1) | - pwr_falcon_dmatrfcmd_write_f(0) | - pwr_falcon_dmatrfcmd_size_f(6) | - pwr_falcon_dmatrfcmd_ctxdma_f(GK20A_PMU_DMAIDX_UCODE)); - } - - err = nvgpu_falcon_bootstrap(&g->pmu.flcn, - desc->bootloader_entry_point); - - gk20a_writel(g, pwr_falcon_os_r(), desc->app_version); - - return err; + gk20a_writel(g, pwr_pmu_idle_count_r(0), + pwr_pmu_idle_count_reset_f(1)); + gk20a_writel(g, pwr_pmu_idle_count_r(4), + pwr_pmu_idle_count_reset_f(1)); + gk20a_writel(g, pwr_pmu_idle_intr_status_r(), + pwr_pmu_idle_intr_status_intr_f(1)); } void gk20a_pmu_pg_idle_counter_config(struct gk20a *g, u32 pg_engine_id) @@ -226,6 +166,145 @@ void gk20a_pmu_pg_idle_counter_config(struct gk20a *g, u32 pg_engine_id) PMU_PG_POST_POWERUP_IDLE_THRESHOLD); } +u32 gk20a_pmu_read_idle_counter(struct gk20a *g, u32 counter_id) +{ + return pwr_pmu_idle_count_value_v( + gk20a_readl(g, pwr_pmu_idle_count_r(counter_id))); +} + +void gk20a_pmu_reset_idle_counter(struct gk20a *g, u32 counter_id) +{ + gk20a_writel(g, pwr_pmu_idle_count_r(counter_id), + pwr_pmu_idle_count_reset_f(1)); +} + +u32 gk20a_pmu_read_idle_intr_status(struct gk20a *g) +{ + return pwr_pmu_idle_intr_status_intr_v( + gk20a_readl(g, pwr_pmu_idle_intr_status_r())); +} + +void gk20a_pmu_clear_idle_intr_status(struct gk20a *g) +{ + gk20a_writel(g, pwr_pmu_idle_intr_status_r(), + pwr_pmu_idle_intr_status_intr_f(1)); +} + +/* ELPG */ +void gk20a_pmu_dump_elpg_stats(struct nvgpu_pmu *pmu) +{ + struct gk20a *g = gk20a_from_pmu(pmu); + + nvgpu_pmu_dbg(g, "pwr_pmu_idle_mask_supp_r(3): 0x%08x", + gk20a_readl(g, pwr_pmu_idle_mask_supp_r(3))); + nvgpu_pmu_dbg(g, "pwr_pmu_idle_mask_1_supp_r(3): 0x%08x", + gk20a_readl(g, pwr_pmu_idle_mask_1_supp_r(3))); + nvgpu_pmu_dbg(g, "pwr_pmu_idle_ctrl_supp_r(3): 0x%08x", + gk20a_readl(g, pwr_pmu_idle_ctrl_supp_r(3))); + nvgpu_pmu_dbg(g, "pwr_pmu_pg_idle_cnt_r(0): 0x%08x", + gk20a_readl(g, pwr_pmu_pg_idle_cnt_r(0))); + nvgpu_pmu_dbg(g, "pwr_pmu_pg_intren_r(0): 0x%08x", + gk20a_readl(g, pwr_pmu_pg_intren_r(0))); + + nvgpu_pmu_dbg(g, "pwr_pmu_idle_count_r(3): 0x%08x", + gk20a_readl(g, pwr_pmu_idle_count_r(3))); + nvgpu_pmu_dbg(g, "pwr_pmu_idle_count_r(4): 0x%08x", + gk20a_readl(g, pwr_pmu_idle_count_r(4))); + nvgpu_pmu_dbg(g, "pwr_pmu_idle_count_r(7): 0x%08x", + gk20a_readl(g, pwr_pmu_idle_count_r(7))); +} + +/* Muetx */ +u32 gk20a_pmu_mutex_owner(struct gk20a *g, struct pmu_mutexes *mutexes, u32 id) +{ + struct pmu_mutex *mutex; + + mutex = &mutexes->mutex[id]; + + return pwr_pmu_mutex_value_v( + gk20a_readl(g, pwr_pmu_mutex_r(mutex->index))); +} + +int gk20a_pmu_mutex_acquire(struct gk20a *g, struct pmu_mutexes *mutexes, + u32 id, u32 *token) +{ + struct pmu_mutex *mutex; + u32 data, owner, max_retry; + int ret = -EBUSY; + + mutex = &mutexes->mutex[id]; + + owner = pwr_pmu_mutex_value_v( + gk20a_readl(g, pwr_pmu_mutex_r(mutex->index))); + + max_retry = 40; + do { + data = pwr_pmu_mutex_id_value_v( + gk20a_readl(g, pwr_pmu_mutex_id_r())); + if (data == pwr_pmu_mutex_id_value_init_v() || + data == pwr_pmu_mutex_id_value_not_avail_v()) { + nvgpu_warn(g, + "fail to generate mutex token: val 0x%08x", + owner); + nvgpu_usleep_range(20, 40); + continue; + } + + owner = data; + gk20a_writel(g, pwr_pmu_mutex_r(mutex->index), + pwr_pmu_mutex_value_f(owner)); + + data = pwr_pmu_mutex_value_v( + gk20a_readl(g, pwr_pmu_mutex_r(mutex->index))); + + if (owner == data) { + nvgpu_log_info(g, "mutex acquired: id=%d, token=0x%x", + mutex->index, *token); + *token = owner; + ret = 0; + break; + } + + nvgpu_log_info(g, "fail to acquire mutex idx=0x%08x", + mutex->index); + + data = gk20a_readl(g, pwr_pmu_mutex_id_release_r()); + data = set_field(data, + pwr_pmu_mutex_id_release_value_m(), + pwr_pmu_mutex_id_release_value_f(owner)); + gk20a_writel(g, pwr_pmu_mutex_id_release_r(), data); + + nvgpu_usleep_range(20, 40); + } while (max_retry-- > 0U); + + return ret; +} + +void gk20a_pmu_mutex_release(struct gk20a *g, struct pmu_mutexes *mutexes, + u32 id, u32 *token) +{ + struct pmu_mutex *mutex; + u32 owner, data; + + mutex = &mutexes->mutex[id]; + + owner = pwr_pmu_mutex_value_v( + gk20a_readl(g, pwr_pmu_mutex_r(mutex->index))); + + gk20a_writel(g, pwr_pmu_mutex_r(mutex->index), + pwr_pmu_mutex_value_initial_lock_f()); + + data = gk20a_readl(g, pwr_pmu_mutex_id_release_r()); + data = set_field(data, pwr_pmu_mutex_id_release_value_m(), + pwr_pmu_mutex_id_release_value_f(owner)); + gk20a_writel(g, pwr_pmu_mutex_id_release_r(), data); + + nvgpu_log_info(g, "mutex released: id=%d, token=0x%x", + mutex->index, *token); +} + + +/* queue */ int gk20a_pmu_queue_head(struct gk20a *g, u32 queue_id, u32 queue_index, u32 *head, bool set) { @@ -327,36 +406,68 @@ void gk20a_pmu_msgq_tail(struct nvgpu_pmu *pmu, u32 *tail, bool set) } } -void gk20a_write_dmatrfbase(struct gk20a *g, u32 addr) +/* ISR */ +u32 gk20a_pmu_get_irqdest(struct gk20a *g) { - gk20a_writel(g, pwr_falcon_dmatrfbase_r(), addr); + u32 intr_dest; + + /* dest 0=falcon, 1=host; level 0=irq0, 1=irq1 */ + intr_dest = pwr_falcon_irqdest_host_gptmr_f(0) | + pwr_falcon_irqdest_host_wdtmr_f(1) | + pwr_falcon_irqdest_host_mthd_f(0) | + pwr_falcon_irqdest_host_ctxsw_f(0) | + pwr_falcon_irqdest_host_halt_f(1) | + pwr_falcon_irqdest_host_exterr_f(0) | + pwr_falcon_irqdest_host_swgen0_f(1) | + pwr_falcon_irqdest_host_swgen1_f(0) | + pwr_falcon_irqdest_host_ext_f(0xff) | + pwr_falcon_irqdest_target_gptmr_f(1) | + pwr_falcon_irqdest_target_wdtmr_f(0) | + pwr_falcon_irqdest_target_mthd_f(0) | + pwr_falcon_irqdest_target_ctxsw_f(0) | + pwr_falcon_irqdest_target_halt_f(0) | + pwr_falcon_irqdest_target_exterr_f(0) | + pwr_falcon_irqdest_target_swgen0_f(0) | + pwr_falcon_irqdest_target_swgen1_f(0) | + pwr_falcon_irqdest_target_ext_f(0xff); + + return intr_dest; } -bool gk20a_pmu_is_engine_in_reset(struct gk20a *g) +void gk20a_pmu_enable_irq(struct nvgpu_pmu *pmu, bool enable) { - bool status = false; + struct gk20a *g = gk20a_from_pmu(pmu); + u32 intr_mask; + u32 intr_dest; - status = g->ops.mc.is_enabled(g, NVGPU_UNIT_PWR); + nvgpu_log_fn(g, " "); - return status; -} + g->ops.mc.intr_unit_config(g, MC_INTR_UNIT_DISABLE, true, + mc_intr_mask_0_pmu_enabled_f()); + g->ops.mc.intr_unit_config(g, MC_INTR_UNIT_DISABLE, false, + mc_intr_mask_1_pmu_enabled_f()); -int gk20a_pmu_engine_reset(struct gk20a *g, bool do_reset) -{ - u32 reset_mask = g->ops.mc.reset_mask(g, NVGPU_UNIT_PWR); + nvgpu_falcon_set_irq(&pmu->flcn, false, 0x0, 0x0); - if (do_reset) { - g->ops.mc.enable(g, reset_mask); - } else { - g->ops.mc.disable(g, reset_mask); + if (enable) { + intr_dest = g->ops.pmu.get_irqdest(g); + /* 0=disable, 1=enable */ + intr_mask = pwr_falcon_irqmset_gptmr_f(1) | + pwr_falcon_irqmset_wdtmr_f(1) | + pwr_falcon_irqmset_mthd_f(0) | + pwr_falcon_irqmset_ctxsw_f(0) | + pwr_falcon_irqmset_halt_f(1) | + pwr_falcon_irqmset_exterr_f(1) | + pwr_falcon_irqmset_swgen0_f(1) | + pwr_falcon_irqmset_swgen1_f(1); + + nvgpu_falcon_set_irq(&pmu->flcn, true, intr_mask, intr_dest); + + g->ops.mc.intr_unit_config(g, MC_INTR_UNIT_ENABLE, true, + mc_intr_mask_0_pmu_enabled_f()); } - return 0; -} - -bool gk20a_is_pmu_supported(struct gk20a *g) -{ - return true; + nvgpu_log_fn(g, "done"); } bool gk20a_pmu_is_interrupted(struct nvgpu_pmu *pmu) @@ -446,117 +557,7 @@ void gk20a_pmu_isr(struct gk20a *g) nvgpu_mutex_release(&pmu->isr_mutex); } -void gk20a_pmu_init_perfmon_counter(struct gk20a *g) -{ - u32 data; - - /* use counter #3 for GR && CE2 busy cycles */ - gk20a_writel(g, pwr_pmu_idle_mask_r(3), - pwr_pmu_idle_mask_gr_enabled_f() | - pwr_pmu_idle_mask_ce_2_enabled_f()); - - /* disable idle filtering for counters 3 and 6 */ - data = gk20a_readl(g, pwr_pmu_idle_ctrl_r(3)); - data = set_field(data, pwr_pmu_idle_ctrl_value_m() | - pwr_pmu_idle_ctrl_filter_m(), - pwr_pmu_idle_ctrl_value_busy_f() | - pwr_pmu_idle_ctrl_filter_disabled_f()); - gk20a_writel(g, pwr_pmu_idle_ctrl_r(3), data); - - /* use counter #6 for total cycles */ - data = gk20a_readl(g, pwr_pmu_idle_ctrl_r(6)); - data = set_field(data, pwr_pmu_idle_ctrl_value_m() | - pwr_pmu_idle_ctrl_filter_m(), - pwr_pmu_idle_ctrl_value_always_f() | - pwr_pmu_idle_ctrl_filter_disabled_f()); - gk20a_writel(g, pwr_pmu_idle_ctrl_r(6), data); - - /* - * We don't want to disturb counters #3 and #6, which are used by - * perfmon, so we add wiring also to counters #1 and #2 for - * exposing raw counter readings. - */ - gk20a_writel(g, pwr_pmu_idle_mask_r(1), - pwr_pmu_idle_mask_gr_enabled_f() | - pwr_pmu_idle_mask_ce_2_enabled_f()); - - data = gk20a_readl(g, pwr_pmu_idle_ctrl_r(1)); - data = set_field(data, pwr_pmu_idle_ctrl_value_m() | - pwr_pmu_idle_ctrl_filter_m(), - pwr_pmu_idle_ctrl_value_busy_f() | - pwr_pmu_idle_ctrl_filter_disabled_f()); - gk20a_writel(g, pwr_pmu_idle_ctrl_r(1), data); - - data = gk20a_readl(g, pwr_pmu_idle_ctrl_r(2)); - data = set_field(data, pwr_pmu_idle_ctrl_value_m() | - pwr_pmu_idle_ctrl_filter_m(), - pwr_pmu_idle_ctrl_value_always_f() | - pwr_pmu_idle_ctrl_filter_disabled_f()); - gk20a_writel(g, pwr_pmu_idle_ctrl_r(2), data); - - /* - * use counters 4 and 0 for perfmon to log busy cycles and total cycles - * counter #0 overflow sets pmu idle intr status bit - */ - gk20a_writel(g, pwr_pmu_idle_intr_r(), - pwr_pmu_idle_intr_en_f(0)); - - gk20a_writel(g, pwr_pmu_idle_threshold_r(0), - pwr_pmu_idle_threshold_value_f(0x7FFFFFFF)); - - data = gk20a_readl(g, pwr_pmu_idle_ctrl_r(0)); - data = set_field(data, pwr_pmu_idle_ctrl_value_m() | - pwr_pmu_idle_ctrl_filter_m(), - pwr_pmu_idle_ctrl_value_always_f() | - pwr_pmu_idle_ctrl_filter_disabled_f()); - gk20a_writel(g, pwr_pmu_idle_ctrl_r(0), data); - - gk20a_writel(g, pwr_pmu_idle_mask_r(4), - pwr_pmu_idle_mask_gr_enabled_f() | - pwr_pmu_idle_mask_ce_2_enabled_f()); - - data = gk20a_readl(g, pwr_pmu_idle_ctrl_r(4)); - data = set_field(data, pwr_pmu_idle_ctrl_value_m() | - pwr_pmu_idle_ctrl_filter_m(), - pwr_pmu_idle_ctrl_value_busy_f() | - pwr_pmu_idle_ctrl_filter_disabled_f()); - gk20a_writel(g, pwr_pmu_idle_ctrl_r(4), data); - - gk20a_writel(g, pwr_pmu_idle_count_r(0), pwr_pmu_idle_count_reset_f(1)); - gk20a_writel(g, pwr_pmu_idle_count_r(4), pwr_pmu_idle_count_reset_f(1)); - gk20a_writel(g, pwr_pmu_idle_intr_status_r(), - pwr_pmu_idle_intr_status_intr_f(1)); -} - -u32 gk20a_pmu_read_idle_counter(struct gk20a *g, u32 counter_id) -{ - return pwr_pmu_idle_count_value_v( - gk20a_readl(g, pwr_pmu_idle_count_r(counter_id))); -} - -void gk20a_pmu_reset_idle_counter(struct gk20a *g, u32 counter_id) -{ - gk20a_writel(g, pwr_pmu_idle_count_r(counter_id), - pwr_pmu_idle_count_reset_f(1)); -} - -u32 gk20a_pmu_read_idle_intr_status(struct gk20a *g) -{ - return pwr_pmu_idle_intr_status_intr_v( - gk20a_readl(g, pwr_pmu_idle_intr_status_r())); -} - -void gk20a_pmu_clear_idle_intr_status(struct gk20a *g) -{ - gk20a_writel(g, pwr_pmu_idle_intr_status_r(), - pwr_pmu_idle_intr_status_intr_f(1)); -} - -u32 gk20a_pmu_falcon_base_addr(void) -{ - return pwr_falcon_irqsset_r(); -} - +/* error handler */ int gk20a_pmu_bar0_error_status(struct gk20a *g, u32 *bar0_status, u32 *etype) { @@ -568,6 +569,7 @@ int gk20a_pmu_bar0_error_status(struct gk20a *g, u32 *bar0_status, if (val == 0U) { return 0; } + if ((val & pwr_pmu_bar0_error_status_timeout_host_m()) != 0U) { *etype = ((val & pwr_pmu_bar0_error_status_err_cmd_m()) != 0U) ? PMU_BAR0_HOST_WRITE_TOUT : PMU_BAR0_HOST_READ_TOUT; @@ -611,3 +613,132 @@ int gk20a_pmu_bar0_error_status(struct gk20a *g, u32 *bar0_status, gk20a_writel(g, pwr_pmu_bar0_error_status_r(), val); return (-EIO); } + +/* non-secure boot */ +int pmu_bootstrap(struct gk20a *g, struct nvgpu_pmu *pmu) +{ + struct mm_gk20a *mm = &g->mm; + struct pmu_ucode_desc *desc = + (struct pmu_ucode_desc *)(void *)pmu->fw_image->data; + u32 addr_code, addr_data, addr_load; + u32 i, blocks, addr_args; + int err; + u64 tmp_addr; + + nvgpu_log_fn(g, " "); + + gk20a_writel(g, pwr_falcon_itfen_r(), + gk20a_readl(g, pwr_falcon_itfen_r()) | + pwr_falcon_itfen_ctxen_enable_f()); + tmp_addr = nvgpu_inst_block_addr(g, &mm->pmu.inst_block) >> 12; + nvgpu_assert(u64_hi32(tmp_addr) == 0U); + gk20a_writel(g, pwr_pmu_new_instblk_r(), + pwr_pmu_new_instblk_ptr_f((u32)tmp_addr) | + pwr_pmu_new_instblk_valid_f(1) | + pwr_pmu_new_instblk_target_sys_coh_f()); + + /* TBD: load all other surfaces */ + g->ops.pmu_ver.set_pmu_cmdline_args_trace_size( + pmu, GK20A_PMU_TRACE_BUFSIZE); + g->ops.pmu_ver.set_pmu_cmdline_args_trace_dma_base(pmu); + g->ops.pmu_ver.set_pmu_cmdline_args_trace_dma_idx( + pmu, GK20A_PMU_DMAIDX_VIRT); + + g->ops.pmu_ver.set_pmu_cmdline_args_cpu_freq(pmu, + g->ops.clk.get_rate(g, CTRL_CLK_DOMAIN_PWRCLK)); + + addr_args = (pwr_falcon_hwcfg_dmem_size_v( + gk20a_readl(g, pwr_falcon_hwcfg_r())) + << GK20A_PMU_DMEM_BLKSIZE2) - + g->ops.pmu_ver.get_pmu_cmdline_args_size(pmu); + + nvgpu_falcon_copy_to_dmem(&pmu->flcn, addr_args, + (u8 *)(g->ops.pmu_ver.get_pmu_cmdline_args_ptr(pmu)), + g->ops.pmu_ver.get_pmu_cmdline_args_size(pmu), 0); + + gk20a_writel(g, pwr_falcon_dmemc_r(0), + pwr_falcon_dmemc_offs_f(0) | + pwr_falcon_dmemc_blk_f(0) | + pwr_falcon_dmemc_aincw_f(1)); + + addr_code = u64_lo32((pmu->ucode.gpu_va + + desc->app_start_offset + + desc->app_resident_code_offset) >> 8) ; + addr_data = u64_lo32((pmu->ucode.gpu_va + + desc->app_start_offset + + desc->app_resident_data_offset) >> 8); + addr_load = u64_lo32((pmu->ucode.gpu_va + + desc->bootloader_start_offset) >> 8); + + gk20a_writel(g, pwr_falcon_dmemd_r(0), GK20A_PMU_DMAIDX_UCODE); + gk20a_writel(g, pwr_falcon_dmemd_r(0), addr_code); + gk20a_writel(g, pwr_falcon_dmemd_r(0), desc->app_size); + gk20a_writel(g, pwr_falcon_dmemd_r(0), desc->app_resident_code_size); + gk20a_writel(g, pwr_falcon_dmemd_r(0), desc->app_imem_entry); + gk20a_writel(g, pwr_falcon_dmemd_r(0), addr_data); + gk20a_writel(g, pwr_falcon_dmemd_r(0), desc->app_resident_data_size); + gk20a_writel(g, pwr_falcon_dmemd_r(0), addr_code); + gk20a_writel(g, pwr_falcon_dmemd_r(0), 0x1); + gk20a_writel(g, pwr_falcon_dmemd_r(0), addr_args); + + g->ops.pmu.write_dmatrfbase(g, + addr_load - (desc->bootloader_imem_offset >> U32(8))); + + blocks = ((desc->bootloader_size + 0xFFU) & ~0xFFU) >> 8; + + for (i = 0; i < blocks; i++) { + gk20a_writel(g, pwr_falcon_dmatrfmoffs_r(), + desc->bootloader_imem_offset + (i << 8)); + gk20a_writel(g, pwr_falcon_dmatrffboffs_r(), + desc->bootloader_imem_offset + (i << 8)); + gk20a_writel(g, pwr_falcon_dmatrfcmd_r(), + pwr_falcon_dmatrfcmd_imem_f(1) | + pwr_falcon_dmatrfcmd_write_f(0) | + pwr_falcon_dmatrfcmd_size_f(6) | + pwr_falcon_dmatrfcmd_ctxdma_f(GK20A_PMU_DMAIDX_UCODE)); + } + + err = nvgpu_falcon_bootstrap(&g->pmu.flcn, + desc->bootloader_entry_point); + + gk20a_writel(g, pwr_falcon_os_r(), desc->app_version); + + return err; +} + +bool gk20a_pmu_is_engine_in_reset(struct gk20a *g) +{ + bool status = false; + + status = g->ops.mc.is_enabled(g, NVGPU_UNIT_PWR); + + return status; +} + +int gk20a_pmu_engine_reset(struct gk20a *g, bool do_reset) +{ + u32 reset_mask = g->ops.mc.reset_mask(g, NVGPU_UNIT_PWR); + + if (do_reset) { + g->ops.mc.enable(g, reset_mask); + } else { + g->ops.mc.disable(g, reset_mask); + } + + return 0; +} + +void gk20a_write_dmatrfbase(struct gk20a *g, u32 addr) +{ + gk20a_writel(g, pwr_falcon_dmatrfbase_r(), addr); +} + +u32 gk20a_pmu_falcon_base_addr(void) +{ + return pwr_falcon_irqsset_r(); +} + +bool gk20a_is_pmu_supported(struct gk20a *g) +{ + return true; +} diff --git a/drivers/gpu/nvgpu/common/pmu/pmu_gk20a.h b/drivers/gpu/nvgpu/hal/pmu/pmu_gk20a.h similarity index 75% rename from drivers/gpu/nvgpu/common/pmu/pmu_gk20a.h rename to drivers/gpu/nvgpu/hal/pmu/pmu_gk20a.h index 0cd3e288c..93448eab3 100644 --- a/drivers/gpu/nvgpu/common/pmu/pmu_gk20a.h +++ b/drivers/gpu/nvgpu/hal/pmu/pmu_gk20a.h @@ -1,9 +1,5 @@ /* - * drivers/video/tegra/host/gk20a/pmu_gk20a.h - * - * GK20A PMU (aka. gPMU outside gk20a context) - * - * Copyright (c) 2011-2019, NVIDIA CORPORATION. All rights reserved. + * Copyright (c) 2011-2019, NVIDIA CORPORATION. All rights reserved * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -23,42 +19,46 @@ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ -#ifndef NVGPU_GK20A_PMU_GK20A_H -#define NVGPU_GK20A_PMU_GK20A_H -#include -#include -#include +#ifndef PMU_GK20A_H +#define PMU_GK20A_H -#define ZBC_MASK(i) U16(~(~(0U) << ((i)+1U)) & 0xfffeU) +#include -bool gk20a_pmu_is_interrupted(struct nvgpu_pmu *pmu); -void gk20a_pmu_isr(struct gk20a *g); +struct gk20a; +struct nvgpu_pmu; +struct pmu_mutexes; +void gk20a_pmu_dump_falcon_stats(struct nvgpu_pmu *pmu); void gk20a_pmu_init_perfmon_counter(struct gk20a *g); - void gk20a_pmu_pg_idle_counter_config(struct gk20a *g, u32 pg_engine_id); - -int gk20a_pmu_queue_head(struct gk20a *g, u32 queue_id, u32 queue_index, - u32 *head, bool set); -int gk20a_pmu_queue_tail(struct gk20a *g, u32 queue_id, u32 queue_index, - u32 *tail, bool set); -void gk20a_pmu_msgq_tail(struct nvgpu_pmu *pmu, u32 *tail, bool set); - u32 gk20a_pmu_read_idle_counter(struct gk20a *g, u32 counter_id); void gk20a_pmu_reset_idle_counter(struct gk20a *g, u32 counter_id); - u32 gk20a_pmu_read_idle_intr_status(struct gk20a *g); void gk20a_pmu_clear_idle_intr_status(struct gk20a *g); - -void gk20a_write_dmatrfbase(struct gk20a *g, u32 addr); -bool gk20a_is_pmu_supported(struct gk20a *g); - -int pmu_bootstrap(struct nvgpu_pmu *pmu); - +void gk20a_pmu_dump_elpg_stats(struct nvgpu_pmu *pmu); +u32 gk20a_pmu_mutex_owner(struct gk20a *g, struct pmu_mutexes *mutexes, + u32 id); +int gk20a_pmu_mutex_acquire(struct gk20a *g, struct pmu_mutexes *mutexes, + u32 id, u32 *token); +void gk20a_pmu_mutex_release(struct gk20a *g, struct pmu_mutexes *mutexes, + u32 id, u32 *token); +int gk20a_pmu_queue_head(struct gk20a *g, u32 queue_id, u32 queue_index, + u32 *head, bool set); +int gk20a_pmu_queue_tail(struct gk20a *g, u32 queue_id, u32 queue_index, + u32 *tail, bool set); +void gk20a_pmu_msgq_tail(struct nvgpu_pmu *pmu, u32 *tail, bool set); +u32 gk20a_pmu_get_irqdest(struct gk20a *g); void gk20a_pmu_enable_irq(struct nvgpu_pmu *pmu, bool enable); -u32 gk20a_pmu_falcon_base_addr(void); +bool gk20a_pmu_is_interrupted(struct nvgpu_pmu *pmu); +void gk20a_pmu_isr(struct gk20a *g); +int gk20a_pmu_bar0_error_status(struct gk20a *g, u32 *bar0_status, + u32 *etype); +int pmu_bootstrap(struct gk20a *g, struct nvgpu_pmu *pmu); bool gk20a_pmu_is_engine_in_reset(struct gk20a *g); int gk20a_pmu_engine_reset(struct gk20a *g, bool do_reset); -u32 gk20a_pmu_get_irqdest(struct gk20a *g); -#endif /*NVGPU_GK20A_PMU_GK20A_H*/ +void gk20a_write_dmatrfbase(struct gk20a *g, u32 addr); +u32 gk20a_pmu_falcon_base_addr(void); +bool gk20a_is_pmu_supported(struct gk20a *g); + +#endif /* PMU_GK20A_H */ diff --git a/drivers/gpu/nvgpu/common/pmu/pmu_gm20b.c b/drivers/gpu/nvgpu/hal/pmu/pmu_gm20b.c similarity index 98% rename from drivers/gpu/nvgpu/common/pmu/pmu_gm20b.c rename to drivers/gpu/nvgpu/hal/pmu/pmu_gm20b.c index fe5b9fc1a..d17fb685a 100644 --- a/drivers/gpu/nvgpu/common/pmu/pmu_gm20b.c +++ b/drivers/gpu/nvgpu/hal/pmu/pmu_gm20b.c @@ -1,6 +1,4 @@ /* - * GM20B PMU - * * Copyright (c) 2015-2019, NVIDIA CORPORATION. All rights reserved. * * Permission is hereby granted, free of charge, to any person obtaining a @@ -142,10 +140,9 @@ bool gm20b_pmu_is_debug_mode_en(struct gk20a *g) return pwr_pmu_scpctl_stat_debug_mode_v(ctl_stat) != 0U; } -int gm20b_ns_pmu_setup_hw_and_bootstrap(struct gk20a *g) +int gm20b_ns_pmu_setup_hw_and_bootstrap(struct gk20a *g, + struct nvgpu_pmu *pmu) { - struct nvgpu_pmu *pmu = &g->pmu; - nvgpu_log_fn(g, " "); nvgpu_mutex_acquire(&pmu->isr_mutex); @@ -169,7 +166,7 @@ int gm20b_ns_pmu_setup_hw_and_bootstrap(struct gk20a *g) pwr_fbif_transcfg_mem_type_physical_f() | pwr_fbif_transcfg_target_noncoherent_sysmem_f()); - return g->ops.pmu.pmu_nsbootstrap(pmu); + return g->ops.pmu.pmu_nsbootstrap(g, pmu); } void gm20b_pmu_setup_apertures(struct gk20a *g) diff --git a/drivers/gpu/nvgpu/common/pmu/pmu_gm20b.h b/drivers/gpu/nvgpu/hal/pmu/pmu_gm20b.h similarity index 90% rename from drivers/gpu/nvgpu/common/pmu/pmu_gm20b.h rename to drivers/gpu/nvgpu/hal/pmu/pmu_gm20b.h index c6e7a4f9e..04da7252a 100644 --- a/drivers/gpu/nvgpu/common/pmu/pmu_gm20b.h +++ b/drivers/gpu/nvgpu/hal/pmu/pmu_gm20b.h @@ -1,6 +1,4 @@ /* - * GM20B PMU - * * Copyright (c) 2014-2019, NVIDIA CORPORATION. All rights reserved. * * Permission is hereby granted, free of charge, to any person obtaining a @@ -22,8 +20,10 @@ * DEALINGS IN THE SOFTWARE. */ -#ifndef NVGPU_GM20B_PMU_GM20B_H -#define NVGPU_GM20B_PMU_GM20B_H +#ifndef PMU_GM20B_H +#define PMU_GM20B_H + +#include struct gk20a; @@ -31,11 +31,12 @@ void gm20b_pmu_setup_elpg(struct gk20a *g); void pmu_dump_security_fuses_gm20b(struct gk20a *g); void gm20b_write_dmatrfbase(struct gk20a *g, u32 addr); bool gm20b_pmu_is_debug_mode_en(struct gk20a *g); -int gm20b_ns_pmu_setup_hw_and_bootstrap(struct gk20a *g); +int gm20b_ns_pmu_setup_hw_and_bootstrap(struct gk20a *g, + struct nvgpu_pmu *pmu); void gm20b_pmu_setup_apertures(struct gk20a *g); void gm20b_pmu_flcn_setup_boot_config(struct gk20a *g); void gm20b_secured_pmu_start(struct gk20a *g); bool gm20b_is_pmu_supported(struct gk20a *g); void gm20b_clear_pmu_bar0_host_err_status(struct gk20a *g); -#endif /*NVGPU_GM20B_PMU_GM20B_H*/ +#endif /* PMU_GM20B_H */ diff --git a/drivers/gpu/nvgpu/common/pmu/pmu_gp106.c b/drivers/gpu/nvgpu/hal/pmu/pmu_gp106.c similarity index 100% rename from drivers/gpu/nvgpu/common/pmu/pmu_gp106.c rename to drivers/gpu/nvgpu/hal/pmu/pmu_gp106.c diff --git a/drivers/gpu/nvgpu/common/pmu/pmu_gp106.h b/drivers/gpu/nvgpu/hal/pmu/pmu_gp106.h similarity index 94% rename from drivers/gpu/nvgpu/common/pmu/pmu_gp106.h rename to drivers/gpu/nvgpu/hal/pmu/pmu_gp106.h index 542b0488a..69aed0295 100644 --- a/drivers/gpu/nvgpu/common/pmu/pmu_gp106.h +++ b/drivers/gpu/nvgpu/hal/pmu/pmu_gp106.h @@ -20,8 +20,8 @@ * DEALINGS IN THE SOFTWARE. */ -#ifndef NVGPU_PMU_GP106_H -#define NVGPU_PMU_GP106_H +#ifndef PMU_GP106_H +#define PMU_GP106_H #include @@ -34,4 +34,4 @@ int gp106_pmu_engine_reset(struct gk20a *g, bool do_reset); void gp106_pmu_setup_apertures(struct gk20a *g); u32 gp106_pmu_falcon_base_addr(void); -#endif /* NVGPU_PMU_GP106_H */ +#endif /* PMU_GP106_H */ diff --git a/drivers/gpu/nvgpu/common/pmu/pmu_gp10b.c b/drivers/gpu/nvgpu/hal/pmu/pmu_gp10b.c similarity index 99% rename from drivers/gpu/nvgpu/common/pmu/pmu_gp10b.c rename to drivers/gpu/nvgpu/hal/pmu/pmu_gp10b.c index 64f85f0a2..439c62b1a 100644 --- a/drivers/gpu/nvgpu/common/pmu/pmu_gp10b.c +++ b/drivers/gpu/nvgpu/hal/pmu/pmu_gp10b.c @@ -1,6 +1,4 @@ /* - * GP10B PMU - * * Copyright (c) 2015-2019, NVIDIA CORPORATION. All rights reserved. * * Permission is hereby granted, free of charge, to any person obtaining a @@ -29,8 +27,8 @@ #include #include -#include "common/pmu/pmu_gp10b.h" #include "pmu_gk20a.h" +#include "pmu_gp10b.h" #include diff --git a/drivers/gpu/nvgpu/common/pmu/pmu_gp10b.h b/drivers/gpu/nvgpu/hal/pmu/pmu_gp10b.h similarity index 93% rename from drivers/gpu/nvgpu/common/pmu/pmu_gp10b.h rename to drivers/gpu/nvgpu/hal/pmu/pmu_gp10b.h index 67364c68e..b4848df30 100644 --- a/drivers/gpu/nvgpu/common/pmu/pmu_gp10b.h +++ b/drivers/gpu/nvgpu/hal/pmu/pmu_gp10b.h @@ -1,6 +1,4 @@ /* - * GP10B PMU - * * Copyright (c) 2015-2019, NVIDIA CORPORATION. All rights reserved. * * Permission is hereby granted, free of charge, to any person obtaining a @@ -22,8 +20,8 @@ * DEALINGS IN THE SOFTWARE. */ -#ifndef NVGPU_PMU_GP10B_H -#define NVGPU_PMU_GP10B_H +#ifndef PMU_GP10B_H +#define PMU_GP10B_H #include @@ -33,4 +31,4 @@ bool gp10b_is_pmu_supported(struct gk20a *g); void gp10b_pmu_setup_elpg(struct gk20a *g); void gp10b_write_dmatrfbase(struct gk20a *g, u32 addr); -#endif /* NVGPU_PMU_GP10B_H */ +#endif /* PMU_GP10B_H */ diff --git a/drivers/gpu/nvgpu/common/pmu/pmu_gv11b.c b/drivers/gpu/nvgpu/hal/pmu/pmu_gv11b.c similarity index 99% rename from drivers/gpu/nvgpu/common/pmu/pmu_gv11b.c rename to drivers/gpu/nvgpu/hal/pmu/pmu_gv11b.c index 5914800ee..a9702d088 100644 --- a/drivers/gpu/nvgpu/common/pmu/pmu_gv11b.c +++ b/drivers/gpu/nvgpu/hal/pmu/pmu_gv11b.c @@ -1,6 +1,4 @@ /* - * GV11B PMU - * * Copyright (c) 2016-2019, NVIDIA CORPORATION. All rights reserved. * * Permission is hereby granted, free of charge, to any person obtaining a @@ -141,9 +139,8 @@ bool gv11b_is_pmu_supported(struct gk20a *g) #endif } -int gv11b_pmu_bootstrap(struct nvgpu_pmu *pmu) +int gv11b_pmu_bootstrap(struct gk20a *g, struct nvgpu_pmu *pmu) { - struct gk20a *g = gk20a_from_pmu(pmu); struct mm_gk20a *mm = &g->mm; struct pmu_ucode_desc *desc = (struct pmu_ucode_desc *)(void *)pmu->fw_image->data; diff --git a/drivers/gpu/nvgpu/common/pmu/pmu_gv11b.h b/drivers/gpu/nvgpu/hal/pmu/pmu_gv11b.h similarity index 90% rename from drivers/gpu/nvgpu/common/pmu/pmu_gv11b.h rename to drivers/gpu/nvgpu/hal/pmu/pmu_gv11b.h index 7fac90ff9..372602216 100644 --- a/drivers/gpu/nvgpu/common/pmu/pmu_gv11b.h +++ b/drivers/gpu/nvgpu/hal/pmu/pmu_gv11b.h @@ -1,6 +1,4 @@ /* - * GV11B PMU - * * Copyright (c) 2016-2019, NVIDIA CORPORATION. All rights reserved. * * Permission is hereby granted, free of charge, to any person obtaining a @@ -22,18 +20,18 @@ * DEALINGS IN THE SOFTWARE. */ -#ifndef NVGPU_PMU_GV11B_H -#define NVGPU_PMU_GV11B_H +#ifndef PMU_GV11B_H +#define PMU_GV11B_H #include struct gk20a; bool gv11b_is_pmu_supported(struct gk20a *g); -int gv11b_pmu_bootstrap(struct nvgpu_pmu *pmu); +int gv11b_pmu_bootstrap(struct gk20a *g, struct nvgpu_pmu *pmu); void gv11b_pmu_setup_elpg(struct gk20a *g); u32 gv11b_pmu_get_irqdest(struct gk20a *g); void gv11b_pmu_handle_ext_irq(struct gk20a *g, u32 intr0); void gv11b_setup_apertures(struct gk20a *g); -#endif /* NVGPU_PMU_GV11B_H */ +#endif /* PMU_GV11B_H */ diff --git a/drivers/gpu/nvgpu/hal/pmu/pmu_hal_gk20a.c b/drivers/gpu/nvgpu/hal/pmu/pmu_hal_gk20a.c deleted file mode 100644 index 0708a3267..000000000 --- a/drivers/gpu/nvgpu/hal/pmu/pmu_hal_gk20a.c +++ /dev/null @@ -1,179 +0,0 @@ -/* - * Copyright (c) 2011-2019, NVIDIA CORPORATION. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ -#include -#include -#include - -#include - -#include "pmu_hal_gk20a.h" - -u32 gk20a_pmu_mutex_owner(struct gk20a *g, struct pmu_mutexes *mutexes, u32 id) -{ - struct pmu_mutex *mutex; - - mutex = &mutexes->mutex[id]; - - return pwr_pmu_mutex_value_v( - gk20a_readl(g, pwr_pmu_mutex_r(mutex->index))); -} - -int gk20a_pmu_mutex_acquire(struct gk20a *g, struct pmu_mutexes *mutexes, - u32 id, u32 *token) -{ - struct pmu_mutex *mutex; - u32 data, owner, max_retry; - int ret = -EBUSY; - - mutex = &mutexes->mutex[id]; - - owner = pwr_pmu_mutex_value_v( - gk20a_readl(g, pwr_pmu_mutex_r(mutex->index))); - - max_retry = 40; - do { - data = pwr_pmu_mutex_id_value_v( - gk20a_readl(g, pwr_pmu_mutex_id_r())); - if (data == pwr_pmu_mutex_id_value_init_v() || - data == pwr_pmu_mutex_id_value_not_avail_v()) { - nvgpu_warn(g, - "fail to generate mutex token: val 0x%08x", - owner); - nvgpu_usleep_range(20, 40); - continue; - } - - owner = data; - gk20a_writel(g, pwr_pmu_mutex_r(mutex->index), - pwr_pmu_mutex_value_f(owner)); - - data = pwr_pmu_mutex_value_v( - gk20a_readl(g, pwr_pmu_mutex_r(mutex->index))); - - if (owner == data) { - nvgpu_log_info(g, "mutex acquired: id=%d, token=0x%x", - mutex->index, *token); - *token = owner; - ret = 0; - break; - } - - nvgpu_log_info(g, "fail to acquire mutex idx=0x%08x", - mutex->index); - - data = gk20a_readl(g, pwr_pmu_mutex_id_release_r()); - data = set_field(data, - pwr_pmu_mutex_id_release_value_m(), - pwr_pmu_mutex_id_release_value_f(owner)); - gk20a_writel(g, pwr_pmu_mutex_id_release_r(), data); - - nvgpu_usleep_range(20, 40); - } while (max_retry-- > 0U); - - return ret; -} - -void gk20a_pmu_mutex_release(struct gk20a *g, struct pmu_mutexes *mutexes, - u32 id, u32 *token) -{ - struct pmu_mutex *mutex; - u32 owner, data; - - mutex = &mutexes->mutex[id]; - - owner = pwr_pmu_mutex_value_v( - gk20a_readl(g, pwr_pmu_mutex_r(mutex->index))); - - gk20a_writel(g, pwr_pmu_mutex_r(mutex->index), - pwr_pmu_mutex_value_initial_lock_f()); - - data = gk20a_readl(g, pwr_pmu_mutex_id_release_r()); - data = set_field(data, pwr_pmu_mutex_id_release_value_m(), - pwr_pmu_mutex_id_release_value_f(owner)); - gk20a_writel(g, pwr_pmu_mutex_id_release_r(), data); - - nvgpu_log_info(g, "mutex released: id=%d, token=0x%x", - mutex->index, *token); -} - -void gk20a_pmu_dump_elpg_stats(struct nvgpu_pmu *pmu) -{ - struct gk20a *g = gk20a_from_pmu(pmu); - - nvgpu_pmu_dbg(g, "pwr_pmu_idle_mask_supp_r(3): 0x%08x", - gk20a_readl(g, pwr_pmu_idle_mask_supp_r(3))); - nvgpu_pmu_dbg(g, "pwr_pmu_idle_mask_1_supp_r(3): 0x%08x", - gk20a_readl(g, pwr_pmu_idle_mask_1_supp_r(3))); - nvgpu_pmu_dbg(g, "pwr_pmu_idle_ctrl_supp_r(3): 0x%08x", - gk20a_readl(g, pwr_pmu_idle_ctrl_supp_r(3))); - nvgpu_pmu_dbg(g, "pwr_pmu_pg_idle_cnt_r(0): 0x%08x", - gk20a_readl(g, pwr_pmu_pg_idle_cnt_r(0))); - nvgpu_pmu_dbg(g, "pwr_pmu_pg_intren_r(0): 0x%08x", - gk20a_readl(g, pwr_pmu_pg_intren_r(0))); - - nvgpu_pmu_dbg(g, "pwr_pmu_idle_count_r(3): 0x%08x", - gk20a_readl(g, pwr_pmu_idle_count_r(3))); - nvgpu_pmu_dbg(g, "pwr_pmu_idle_count_r(4): 0x%08x", - gk20a_readl(g, pwr_pmu_idle_count_r(4))); - nvgpu_pmu_dbg(g, "pwr_pmu_idle_count_r(7): 0x%08x", - gk20a_readl(g, pwr_pmu_idle_count_r(7))); -} - -void gk20a_pmu_dump_falcon_stats(struct nvgpu_pmu *pmu) -{ - struct gk20a *g = gk20a_from_pmu(pmu); - unsigned int i; - - for (i = 0; i < pwr_pmu_mailbox__size_1_v(); i++) { - nvgpu_err(g, "pwr_pmu_mailbox_r(%d) : 0x%x", - i, gk20a_readl(g, pwr_pmu_mailbox_r(i))); - } - - for (i = 0; i < pwr_pmu_debug__size_1_v(); i++) { - nvgpu_err(g, "pwr_pmu_debug_r(%d) : 0x%x", - i, gk20a_readl(g, pwr_pmu_debug_r(i))); - } - - i = gk20a_readl(g, pwr_pmu_bar0_error_status_r()); - nvgpu_err(g, "pwr_pmu_bar0_error_status_r : 0x%x", i); - if (i != 0U) { - nvgpu_err(g, "pwr_pmu_bar0_addr_r : 0x%x", - gk20a_readl(g, pwr_pmu_bar0_addr_r())); - nvgpu_err(g, "pwr_pmu_bar0_data_r : 0x%x", - gk20a_readl(g, pwr_pmu_bar0_data_r())); - nvgpu_err(g, "pwr_pmu_bar0_timeout_r : 0x%x", - gk20a_readl(g, pwr_pmu_bar0_timeout_r())); - nvgpu_err(g, "pwr_pmu_bar0_ctl_r : 0x%x", - gk20a_readl(g, pwr_pmu_bar0_ctl_r())); - } - - i = gk20a_readl(g, pwr_pmu_bar0_fecs_error_r()); - nvgpu_err(g, "pwr_pmu_bar0_fecs_error_r : 0x%x", i); - - i = gk20a_readl(g, pwr_falcon_exterrstat_r()); - nvgpu_err(g, "pwr_falcon_exterrstat_r : 0x%x", i); - if (pwr_falcon_exterrstat_valid_v(i) == - pwr_falcon_exterrstat_valid_true_v()) { - nvgpu_err(g, "pwr_falcon_exterraddr_r : 0x%x", - gk20a_readl(g, pwr_falcon_exterraddr_r())); - } -} diff --git a/drivers/gpu/nvgpu/hal/pmu/pmu_hal_gk20a.h b/drivers/gpu/nvgpu/hal/pmu/pmu_hal_gk20a.h deleted file mode 100644 index 5bb582573..000000000 --- a/drivers/gpu/nvgpu/hal/pmu/pmu_hal_gk20a.h +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright (c) 2011-2019, NVIDIA CORPORATION. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ -#ifndef NVGPU_PMU_MUTEX_GK20A_H -#define NVGPU_PMU_MUTEX_GK20A_H - -#include - -struct pmu_mutexes; -struct nvgpu_pmu; -struct gk20a; - -u32 gk20a_pmu_mutex_owner(struct gk20a *g, struct pmu_mutexes *mutexes, - u32 id); -int gk20a_pmu_mutex_acquire(struct gk20a *g, struct pmu_mutexes *mutexes, - u32 id, u32 *token); -void gk20a_pmu_mutex_release(struct gk20a *g, struct pmu_mutexes *mutexes, - u32 id, u32 *token); - -void gk20a_pmu_dump_elpg_stats(struct nvgpu_pmu *pmu); -void gk20a_pmu_dump_falcon_stats(struct nvgpu_pmu *pmu); - -#endif /* NVGPU_PMU_MUTEX_GK20A_H */ diff --git a/drivers/gpu/nvgpu/common/pmu/pmu_tu104.c b/drivers/gpu/nvgpu/hal/pmu/pmu_tu104.c similarity index 95% rename from drivers/gpu/nvgpu/common/pmu/pmu_tu104.c rename to drivers/gpu/nvgpu/hal/pmu/pmu_tu104.c index df9c6825a..699acb947 100644 --- a/drivers/gpu/nvgpu/common/pmu/pmu_tu104.c +++ b/drivers/gpu/nvgpu/hal/pmu/pmu_tu104.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved. + * Copyright (c) 2018-2019, NVIDIA CORPORATION. All rights reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), diff --git a/drivers/gpu/nvgpu/common/pmu/pmu_tu104.h b/drivers/gpu/nvgpu/hal/pmu/pmu_tu104.h similarity index 88% rename from drivers/gpu/nvgpu/common/pmu/pmu_tu104.h rename to drivers/gpu/nvgpu/hal/pmu/pmu_tu104.h index 8b8296faa..5bbf44361 100644 --- a/drivers/gpu/nvgpu/common/pmu/pmu_tu104.h +++ b/drivers/gpu/nvgpu/hal/pmu/pmu_tu104.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved. + * Copyright (c) 2018-2019, NVIDIA CORPORATION. All rights reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -20,11 +20,11 @@ * DEALINGS IN THE SOFTWARE. */ -#ifndef NVGPU_PMU_TU104_H -#define NVGPU_PMU_TU104_H +#ifndef PMU_TU104_H +#define PMU_TU104_H struct gk20a; bool tu104_is_pmu_supported(struct gk20a *g); -#endif /* NVGPU_PMU_TU104_H */ +#endif /* PMU_TU104_H */ diff --git a/drivers/gpu/nvgpu/include/nvgpu/gk20a.h b/drivers/gpu/nvgpu/include/nvgpu/gk20a.h index 9320e3d8a..569aba03e 100644 --- a/drivers/gpu/nvgpu/include/nvgpu/gk20a.h +++ b/drivers/gpu/nvgpu/include/nvgpu/gk20a.h @@ -1414,46 +1414,83 @@ struct gpu_ops { struct { bool (*is_pmu_supported)(struct gk20a *g); u32 (*falcon_base_addr)(void); - int (*pmu_setup_hw_and_bootstrap)(struct gk20a *g); - int (*pmu_nsbootstrap)(struct nvgpu_pmu *pmu); - int (*pmu_init_perfmon)(struct nvgpu_pmu *pmu); - int (*pmu_perfmon_start_sampling)(struct nvgpu_pmu *pmu); - int (*pmu_perfmon_stop_sampling)(struct nvgpu_pmu *pmu); - int (*pmu_perfmon_get_samples_rpc)(struct nvgpu_pmu *pmu); - void (*pmu_setup_elpg)(struct gk20a *g); + /* reset */ + int (*pmu_reset)(struct gk20a *g); + int (*reset_engine)(struct gk20a *g, bool do_reset); + bool (*is_engine_in_reset)(struct gk20a *g); + /* secure boot */ + void (*setup_apertures)(struct gk20a *g); + void (*write_dmatrfbase)(struct gk20a *g, u32 addr); + bool (*is_debug_mode_enabled)(struct gk20a *g); + void (*secured_pmu_start)(struct gk20a *g); + void (*flcn_setup_boot_config)(struct gk20a *g); + /* non-secure */ + int (*pmu_setup_hw_and_bootstrap)(struct gk20a *g, + struct nvgpu_pmu *pmu); + int (*pmu_nsbootstrap)(struct gk20a *g, struct nvgpu_pmu *pmu); + /* queue */ u32 (*pmu_get_queue_head)(u32 i); u32 (*pmu_get_queue_head_size)(void); u32 (*pmu_get_queue_tail_size)(void); u32 (*pmu_get_queue_tail)(u32 i); - int (*pmu_reset)(struct gk20a *g); int (*pmu_queue_head)(struct gk20a *g, u32 queue_id, - u32 queue_index, u32 *head, bool set); + u32 queue_index, u32 *head, bool set); int (*pmu_queue_tail)(struct gk20a *g, u32 queue_id, - u32 queue_index, u32 *tail, bool set); + u32 queue_index, u32 *tail, bool set); void (*pmu_msgq_tail)(struct nvgpu_pmu *pmu, u32 *tail, bool set); + /* mutex */ u32 (*pmu_mutex_size)(void); u32 (*pmu_mutex_owner)(struct gk20a *g, - struct pmu_mutexes *mutexes, - u32 id); + struct pmu_mutexes *mutexes, u32 id); int (*pmu_mutex_acquire)(struct gk20a *g, - struct pmu_mutexes *mutexes, - u32 id, u32 *token); + struct pmu_mutexes *mutexes, u32 id, + u32 *token); void (*pmu_mutex_release)(struct gk20a *g, - struct pmu_mutexes *mutexes, u32 id, - u32 *token); + struct pmu_mutexes *mutexes, u32 id, + u32 *token); + /* ISR */ bool (*pmu_is_interrupted)(struct nvgpu_pmu *pmu); void (*pmu_isr)(struct gk20a *g); + void (*set_irqmask)(struct gk20a *g); + u32 (*get_irqdest)(struct gk20a *g); + void (*pmu_enable_irq)(struct nvgpu_pmu *pmu, bool enable); + void (*handle_ext_irq)(struct gk20a *g, u32 intr); + /* perfmon */ void (*pmu_init_perfmon_counter)(struct gk20a *g); void (*pmu_pg_idle_counter_config)(struct gk20a *g, u32 pg_engine_id); u32 (*pmu_read_idle_counter)(struct gk20a *g, u32 counter_id); u32 (*pmu_read_idle_intr_status)(struct gk20a *g); void (*pmu_clear_idle_intr_status)(struct gk20a *g); void (*pmu_reset_idle_counter)(struct gk20a *g, u32 counter_id); + /* PG */ + void (*pmu_setup_elpg)(struct gk20a *g); + struct { + int (*report_ecc_parity_err)(struct gk20a *g, + u32 hw_id, u32 inst, + u32 err_id, u64 err_addr, + u64 err_cnt); + int (*report_pmu_err)(struct gk20a *g, + u32 hw_id, u32 err_id, u32 status, + u32 pmu_err_type); + } err_ops; + void (*pmu_clear_bar0_host_err_status)(struct gk20a *g); + int (*bar0_error_status)(struct gk20a *g, u32 *bar0_status, + u32 *etype); + /* debug */ void (*pmu_dump_elpg_stats)(struct nvgpu_pmu *pmu); void (*pmu_dump_falcon_stats)(struct nvgpu_pmu *pmu); - void (*pmu_enable_irq)(struct nvgpu_pmu *pmu, bool enable); - void (*write_dmatrfbase)(struct gk20a *g, u32 addr); + void (*dump_secure_fuses)(struct gk20a *g); + /* + * PMU RTOS FW version ops, should move under struct nvgpu_pmu's + * pg/perfmon unit struct ops + */ + /* perfmon */ + int (*pmu_init_perfmon)(struct nvgpu_pmu *pmu); + int (*pmu_perfmon_start_sampling)(struct nvgpu_pmu *pmu); + int (*pmu_perfmon_stop_sampling)(struct nvgpu_pmu *pmu); + int (*pmu_perfmon_get_samples_rpc)(struct nvgpu_pmu *pmu); + /* pg */ int (*pmu_elpg_statistics)(struct gk20a *g, u32 pg_engine_id, struct pmu_pg_stats_data *pg_stat_data); int (*pmu_pg_init_param)(struct gk20a *g, u32 pg_engine_id); @@ -1467,26 +1504,7 @@ struct gpu_ops { int (*pmu_lpwr_enable_pg)(struct gk20a *g, bool pstate_lock); int (*pmu_lpwr_disable_pg)(struct gk20a *g, bool pstate_lock); int (*pmu_pg_param_post_init)(struct gk20a *g); - void (*dump_secure_fuses)(struct gk20a *g); - int (*reset_engine)(struct gk20a *g, bool do_reset); - bool (*is_engine_in_reset)(struct gk20a *g); - void (*handle_ext_irq)(struct gk20a *g, u32 intr); - void (*set_irqmask)(struct gk20a *g); - void (*setup_apertures)(struct gk20a *g); - u32 (*get_irqdest)(struct gk20a *g); - bool (*is_debug_mode_enabled)(struct gk20a *g); - void (*secured_pmu_start)(struct gk20a *g); - struct { - int (*report_ecc_parity_err)(struct gk20a *g, - u32 hw_id, u32 inst, - u32 err_id, u64 err_addr, - u64 err_cnt); - int (*report_pmu_err)(struct gk20a *g, - u32 hw_id, u32 err_id, u32 status, - u32 pmu_err_type); - } err_ops; void (*save_zbc)(struct gk20a *g, u32 entries); - void (*pmu_clear_bar0_host_err_status)(struct gk20a *g); } pmu; struct { int (*init_debugfs)(struct gk20a *g); diff --git a/drivers/gpu/nvgpu/include/nvgpu/pmu.h b/drivers/gpu/nvgpu/include/nvgpu/pmu.h index faaf428d3..1f08490b4 100644 --- a/drivers/gpu/nvgpu/include/nvgpu/pmu.h +++ b/drivers/gpu/nvgpu/include/nvgpu/pmu.h @@ -317,7 +317,5 @@ struct gk20a *gk20a_from_pmu(struct nvgpu_pmu *pmu); void nvgpu_pmu_report_bar0_pri_err_status(struct gk20a *g, u32 bar0_status, u32 error_type); -int gk20a_pmu_bar0_error_status(struct gk20a *g, u32 *bar0_status, - u32 *etype); #endif /* NVGPU_PMU_H */ diff --git a/drivers/gpu/nvgpu/tu104/hal_tu104.c b/drivers/gpu/nvgpu/tu104/hal_tu104.c index ae71d2c38..4e4f8f96a 100644 --- a/drivers/gpu/nvgpu/tu104/hal_tu104.c +++ b/drivers/gpu/nvgpu/tu104/hal_tu104.c @@ -104,21 +104,20 @@ #include "hal/gr/ctxsw_prog/ctxsw_prog_gm20b.h" #include "hal/gr/ctxsw_prog/ctxsw_prog_gp10b.h" #include "hal/gr/ctxsw_prog/ctxsw_prog_gv11b.h" +#include "hal/pmu/pmu_gk20a.h" +#include "hal/pmu/pmu_gm20b.h" +#include "hal/pmu/pmu_gp106.h" +#include "hal/pmu/pmu_gp10b.h" +#include "hal/pmu/pmu_gv11b.h" +#include "hal/pmu/pmu_tu104.h" #include "hal/falcon/falcon_gk20a.h" #include "hal/nvdec/nvdec_tu104.h" #include "hal/gsp/gsp_gv100.h" #include "hal/perf/perf_gv11b.h" -#include "hal/pmu/pmu_hal_gk20a.h" #include "hal/sec2/sec2_tu104.h" #include "hal/netlist/netlist_tu104.h" #include "common/xve/xve_gp106.h" -#include "common/pmu/pmu_gk20a.h" -#include "common/pmu/pmu_gm20b.h" -#include "common/pmu/pmu_gp10b.h" -#include "common/pmu/pmu_gp106.h" -#include "common/pmu/pmu_gv11b.h" -#include "common/pmu/pmu_tu104.h" #include "common/top/top_gm20b.h" #include "common/top/top_gp10b.h" #include "common/top/top_gv100.h"