From 56f736b4a59d6db1fe18bbea0107a5b84cb6e708 Mon Sep 17 00:00:00 2001 From: Vaikundanathan S Date: Tue, 4 Dec 2018 12:44:51 +0530 Subject: [PATCH] gpu: nvgpu: Add VF Point boardobj set and get_status for PS3.5. 1. Update PMU VF interfaces for PS3.5 Added boardobjs for nv_pmu_clk_clk_vf_point_volt_35_sec_boardobj_set nv_pmu_clk_clk_vf_point_35_freq_boardobj_get_status nv_pmu_clk_clk_vf_point_35_volt_pri_boardobj_get_status 2. Updated PERF Load commandfor TU104 nv_pmu_clk_clk_vf_point_35_volt_sec_boardobj_get_status JIRA NVGPU-1152 Change-Id: Iefb39960038f2ef082450358da691699ba18fa2b Signed-off-by: Vaikundanathan S Reviewed-on: https://git-master.nvidia.com/r/1964927 Reviewed-by: mobile promotions Tested-by: mobile promotions --- drivers/gpu/nvgpu/Makefile | 1 + drivers/gpu/nvgpu/Makefile.sources | 1 + drivers/gpu/nvgpu/clk/clk_prog.c | 25 +++- drivers/gpu/nvgpu/clk/clk_vf_point.c | 130 +++++++++++++++--- drivers/gpu/nvgpu/include/nvgpu/boardobjgrp.h | 29 ++++ .../gpu/nvgpu/include/nvgpu/pmuif/ctrlclk.h | 34 +++++ .../include/nvgpu/pmuif/gpmu_super_surf_if.h | 6 + .../gpu/nvgpu/include/nvgpu/pmuif/gpmuifclk.h | 41 ++++++ .../nvgpu/include/nvgpu/pmuif/gpmuifperf.h | 2 + drivers/gpu/nvgpu/pmu_perf/perf_gv100.h | 1 - drivers/gpu/nvgpu/pmu_perf/perf_tu104.c | 125 +++++++++++++++++ drivers/gpu/nvgpu/pmu_perf/perf_tu104.h | 35 +++++ drivers/gpu/nvgpu/pstate/pstate.c | 10 +- drivers/gpu/nvgpu/tu104/hal_tu104.c | 8 +- 14 files changed, 417 insertions(+), 31 deletions(-) create mode 100644 drivers/gpu/nvgpu/pmu_perf/perf_tu104.c create mode 100644 drivers/gpu/nvgpu/pmu_perf/perf_tu104.h diff --git a/drivers/gpu/nvgpu/Makefile b/drivers/gpu/nvgpu/Makefile index 13ac739b6..e756aac55 100644 --- a/drivers/gpu/nvgpu/Makefile +++ b/drivers/gpu/nvgpu/Makefile @@ -386,6 +386,7 @@ nvgpu-y += \ pmu_perf/vfe_equ.o \ pmu_perf/pmu_perf.o \ pmu_perf/perf_gv100.o \ + pmu_perf/perf_tu104.o \ pmu_perf/change_seq.o \ clk/clk.o \ gp106/clk_gp106.o \ diff --git a/drivers/gpu/nvgpu/Makefile.sources b/drivers/gpu/nvgpu/Makefile.sources index e9089a4c9..dfc28ce9b 100644 --- a/drivers/gpu/nvgpu/Makefile.sources +++ b/drivers/gpu/nvgpu/Makefile.sources @@ -183,6 +183,7 @@ srcs := os/posix/nvgpu.c \ pmu_perf/vfe_equ.c \ pmu_perf/vfe_var.c \ pmu_perf/perf_gv100.c \ + pmu_perf/perf_tu104.c \ pmu_perf/change_seq.c \ pmgr/pmgr.c \ pmgr/pmgrpmu.c \ diff --git a/drivers/gpu/nvgpu/clk/clk_prog.c b/drivers/gpu/nvgpu/clk/clk_prog.c index 4b9bb24b4..f84f5be5d 100644 --- a/drivers/gpu/nvgpu/clk/clk_prog.c +++ b/drivers/gpu/nvgpu/clk/clk_prog.c @@ -1378,6 +1378,7 @@ static int vfflatten_prog_1x_master(struct gk20a *g, u8 freq_step_size_mhz = 0; u8 vf_point_idx; u8 vf_rail_idx; + u32 ver = g->params.gpu_arch + g->params.gpu_impl; nvgpu_log_info(g, " "); (void) memset(&vf_point_data, 0x0, sizeof(vf_point_data)); @@ -1414,10 +1415,16 @@ static int vfflatten_prog_1x_master(struct gk20a *g, /* Intentional fall-through.*/ case CTRL_CLK_PROG_1X_SOURCE_ONE_SOURCE: - vf_point_data.board_obj.type = - CTRL_CLK_CLK_VF_POINT_TYPE_FREQ; - do { - clkvfpointfreqmhzset(g, &vf_point_data.vf_point, + if (ver == NVGPU_GPUID_TU104) { + vf_point_data.board_obj.type = + CTRL_CLK_CLK_VF_POINT_TYPE_35_FREQ; + } + else { + vf_point_data.board_obj.type = + CTRL_CLK_CLK_VF_POINT_TYPE_FREQ; + } + do { + clkvfpointfreqmhzset(g, &vf_point_data.vf_point, p1xmaster->super.freq_max_mhz - U16(step_count) * U16(freq_step_size_mhz)); @@ -1437,8 +1444,14 @@ static int vfflatten_prog_1x_master(struct gk20a *g, step_count = CLK_FLL_LUT_VF_NUM_ENTRIES(pclk); /* FLL sources use a voltage-based VF_POINT.*/ - vf_point_data.board_obj.type = - CTRL_CLK_CLK_VF_POINT_TYPE_VOLT; + if (ver == NVGPU_GPUID_TU104) { + vf_point_data.board_obj.type = + CTRL_CLK_CLK_VF_POINT_TYPE_35_VOLT; + } + else { + vf_point_data.board_obj.type = + CTRL_CLK_CLK_VF_POINT_TYPE_VOLT; + } for (i = 0; i < step_count; i++) { vf_point_data.volt.source_voltage_uv = voltage_min_uv + i * voltage_step_size_uv; diff --git a/drivers/gpu/nvgpu/clk/clk_vf_point.c b/drivers/gpu/nvgpu/clk/clk_vf_point.c index 7731be594..23d0dc134 100644 --- a/drivers/gpu/nvgpu/clk/clk_vf_point.c +++ b/drivers/gpu/nvgpu/clk/clk_vf_point.c @@ -96,6 +96,7 @@ int clk_vf_point_sw_setup(struct gk20a *g) { int status; struct boardobjgrp *pboardobjgrp = NULL; + u32 ver = g->params.gpu_arch + g->params.gpu_impl; nvgpu_log_info(g, " "); @@ -111,25 +112,48 @@ int clk_vf_point_sw_setup(struct gk20a *g) BOARDOBJGRP_PMU_CONSTRUCT(pboardobjgrp, CLK, CLK_VF_POINT); - status = BOARDOBJGRP_PMU_CMD_GRP_SET_CONSTRUCT(g, pboardobjgrp, - clk, CLK, clk_vf_point, CLK_VF_POINT); - if (status != 0) { - nvgpu_err(g, - "error constructing PMU_BOARDOBJ_CMD_GRP_SET interface - 0x%x", - status); - goto done; - } - - status = BOARDOBJGRP_PMU_CMD_GRP_GET_STATUS_CONSTRUCT(g, - &g->clk_pmu->clk_vf_pointobjs.super.super, + if (ver == NVGPU_GPUID_TU104) { + status = BOARDOBJGRP_PMU_CMD_GRP_SET_CONSTRUCT_35(g, pboardobjgrp, clk, CLK, clk_vf_point, CLK_VF_POINT); - if (status != 0) { - nvgpu_err(g, - "error constructing PMU_BOARDOBJ_CMD_GRP_SET interface - 0x%x", - status); - goto done; - } + if (status != 0) { + nvgpu_err(g, + "error constructing PMU_BOARDOBJ_CMD_GRP_SET interface - 0x%x", + status); + goto done; + } + status = BOARDOBJGRP_PMU_CMD_GRP_GET_STATUS_CONSTRUCT_35(g, + &g->clk_pmu->clk_vf_pointobjs.super.super, + clk, CLK, clk_vf_point, CLK_VF_POINT); + if (status != 0) { + nvgpu_err(g, + "error constructing PMU_BOARDOBJ_CMD_GRP_SET interface - 0x%x", + status); + goto done; + } + } + else { + status = BOARDOBJGRP_PMU_CMD_GRP_SET_CONSTRUCT(g, pboardobjgrp, + clk, CLK, clk_vf_point, CLK_VF_POINT); + if (status != 0) { + nvgpu_err(g, + "error constructing PMU_BOARDOBJ_CMD_GRP_SET interface - 0x%x", + status); + goto done; + } + + nvgpu_err(g,"GV100 vf_point ss_offset %x", pboardobjgrp->pmu.set.super_surface_offset); + + status = BOARDOBJGRP_PMU_CMD_GRP_GET_STATUS_CONSTRUCT(g, + &g->clk_pmu->clk_vf_pointobjs.super.super, + clk, CLK, clk_vf_point, CLK_VF_POINT); + if (status != 0) { + nvgpu_err(g, + "error constructing PMU_BOARDOBJ_CMD_GRP_SET interface - 0x%x", + status); + goto done; + } + } pboardobjgrp->pmudatainit = _clk_vf_points_pmudatainit; pboardobjgrp->pmudatainstget = _clk_vf_points_pmudata_instget; pboardobjgrp->pmustatusinstget = _clk_vf_points_pmustatus_instget; @@ -303,6 +327,68 @@ static int clk_vf_point_construct_freq(struct gk20a *g, return status; } +static int clk_vf_point_construct_volt_35(struct gk20a *g, + struct boardobj **ppboardobj, + u16 size, void *pargs) +{ + struct boardobj *ptmpobj = (struct boardobj *)pargs; + struct clk_vf_point_volt *pclkvfpoint; + struct clk_vf_point_volt *ptmpvfpoint = + (struct clk_vf_point_volt *)pargs; + int status = 0; + + if (BOARDOBJ_GET_TYPE(pargs) != CTRL_CLK_CLK_VF_POINT_TYPE_35_VOLT) { + return -EINVAL; + } + + ptmpobj->type_mask = (u32) BIT(CTRL_CLK_CLK_VF_POINT_TYPE_35_VOLT); + status = clk_vf_point_construct_super(g, ppboardobj, size, pargs); + if (status != 0) { + return -EINVAL; + } + + pclkvfpoint = (struct clk_vf_point_volt *) (void *) *ppboardobj; + + pclkvfpoint->super.super.pmudatainit = + _clk_vf_point_pmudatainit_volt; + + pclkvfpoint->source_voltage_uv = ptmpvfpoint->source_voltage_uv; + pclkvfpoint->freq_delta = ptmpvfpoint->freq_delta; + + return status; +} + +static int clk_vf_point_construct_freq_35(struct gk20a *g, + struct boardobj **ppboardobj, + u16 size, void *pargs) +{ + struct boardobj *ptmpobj = (struct boardobj *)pargs; + struct clk_vf_point_freq *pclkvfpoint; + struct clk_vf_point_freq *ptmpvfpoint = + (struct clk_vf_point_freq *)pargs; + int status = 0; + + if (BOARDOBJ_GET_TYPE(pargs) != CTRL_CLK_CLK_VF_POINT_TYPE_35_FREQ) { + return -EINVAL; + } + + ptmpobj->type_mask = (u32) BIT(CTRL_CLK_CLK_VF_POINT_TYPE_35_FREQ); + status = clk_vf_point_construct_super(g, ppboardobj, size, pargs); + if (status != 0) { + return -EINVAL; + } + + pclkvfpoint = (struct clk_vf_point_freq *)(void*) *ppboardobj; + + pclkvfpoint->super.super.pmudatainit = + _clk_vf_point_pmudatainit_freq; + + clkvfpointfreqmhzset(g, &pclkvfpoint->super, + clkvfpointfreqmhzget(g, &ptmpvfpoint->super)); + + return status; +} + struct clk_vf_point *construct_clk_vf_point(struct gk20a *g, void *pargs) { struct boardobj *board_obj_ptr = NULL; @@ -320,6 +406,16 @@ struct clk_vf_point *construct_clk_vf_point(struct gk20a *g, void *pargs) sizeof(struct clk_vf_point_volt), pargs); break; + case CTRL_CLK_CLK_VF_POINT_TYPE_35_FREQ: + status = clk_vf_point_construct_freq_35(g, &board_obj_ptr, + sizeof(struct clk_vf_point_freq), pargs); + break; + + case CTRL_CLK_CLK_VF_POINT_TYPE_35_VOLT: + status = clk_vf_point_construct_volt_35(g, &board_obj_ptr, + sizeof(struct clk_vf_point_volt), pargs); + break; + default: return NULL; } diff --git a/drivers/gpu/nvgpu/include/nvgpu/boardobjgrp.h b/drivers/gpu/nvgpu/include/nvgpu/boardobjgrp.h index 228b87710..9d90a13ff 100644 --- a/drivers/gpu/nvgpu/include/nvgpu/boardobjgrp.h +++ b/drivers/gpu/nvgpu/include/nvgpu/boardobjgrp.h @@ -339,6 +339,20 @@ do { \ (u32)offsetof(struct nv_pmu_super_surface, eng.class##_grp_set), \ NV_PMU_RPC_ID_##ENG##_BOARD_OBJ_GRP_CMD) +#define BOARDOBJGRP_PMU_CMD_GRP_SET_CONSTRUCT_35(g, pboardobjgrp, eng, ENG, \ + class, CLASS) \ + g->ops.pmu_ver.boardobj.boardobjgrp_pmucmd_construct_impl( \ + g, /* pgpu */ \ + pboardobjgrp, /* pboardobjgrp */ \ + &((pboardobjgrp)->pmu.set), /* pcmd */ \ + NV_PMU_##ENG##_CMD_ID_BOARDOBJ_GRP_SET, /* id */ \ + NV_PMU_##ENG##_MSG_ID_BOARDOBJ_GRP_SET, /* msgid */ \ + (u32)sizeof(union nv_pmu_##eng##_##class##_boardobjgrp_set_header_aligned), \ + (u32)sizeof(union nv_pmu_##eng##_##class##_boardobj_set_union_aligned), \ + (u32)sizeof(struct nv_pmu_##eng##_##class##_boardobj_grp_set), \ + (u32)offsetof(struct nv_pmu_super_surface, eng##_35.class##_grp_set), \ + NV_PMU_RPC_ID_##ENG##_BOARD_OBJ_GRP_CMD) + #define BOARDOBJGRP_PMU_CMD_GRP_GET_STATUS_CONSTRUCT(g, pboardobjgrp, \ eng, ENG, class, CLASS) \ (g)->ops.pmu_ver.boardobj.boardobjgrp_pmucmd_construct_impl( \ @@ -353,6 +367,20 @@ do { \ (u32)offsetof(struct nv_pmu_super_surface, eng.class##_grp_get_status), \ NV_PMU_RPC_ID_##ENG##_BOARD_OBJ_GRP_CMD) +#define BOARDOBJGRP_PMU_CMD_GRP_GET_STATUS_CONSTRUCT_35(g, pboardobjgrp, \ + eng, ENG, class, CLASS) \ + g->ops.pmu_ver.boardobj.boardobjgrp_pmucmd_construct_impl( \ + g, /* pGpu */ \ + pboardobjgrp, /* pBoardObjGrp */ \ + &((pboardobjgrp)->pmu.getstatus), /* pCmd */ \ + NV_PMU_##ENG##_CMD_ID_BOARDOBJ_GRP_GET_STATUS, /* id */ \ + NV_PMU_##ENG##_MSG_ID_BOARDOBJ_GRP_GET_STATUS, /* msgid */ \ + (u32)sizeof(union nv_pmu_##eng##_##class##_boardobjgrp_get_status_header_aligned), \ + (u32)sizeof(union nv_pmu_##eng##_##class##_boardobj_get_status_union_aligned), \ + (u32)sizeof(struct nv_pmu_##eng##_##class##_boardobj_grp_get_status), \ + (u32)offsetof(struct nv_pmu_super_surface, eng##_35.class##_grp_get_status), \ + NV_PMU_RPC_ID_##ENG##_BOARD_OBJ_GRP_CMD) + #define BOARDOBJGRP_PMU_CMD_GRP_SET_PACK_CONSTRUCT(g, pboardobjgrp, eng, ENG, \ class, CLASS) \ g->ops.pmu_ver.boardobj.boardobjgrp_pmucmd_construct_impl( \ @@ -367,6 +395,7 @@ do { \ (u32)offsetof(struct nv_pmu_super_surface, eng.class##_grp_set), \ NV_PMU_RPC_ID_##ENG##_BOARD_OBJ_GRP_CMD) + #define BOARDOBJGRP_PMU_CMD_GRP_GET_STATUS_PACK_CONSTRUCT(g, pboardobjgrp, \ eng, ENG, class, CLASS) \ g->ops.pmu_ver.boardobj.boardobjgrp_pmucmd_construct_impl( \ diff --git a/drivers/gpu/nvgpu/include/nvgpu/pmuif/ctrlclk.h b/drivers/gpu/nvgpu/include/nvgpu/pmuif/ctrlclk.h index a7deeb555..f565690e2 100644 --- a/drivers/gpu/nvgpu/include/nvgpu/pmuif/ctrlclk.h +++ b/drivers/gpu/nvgpu/include/nvgpu/pmuif/ctrlclk.h @@ -200,6 +200,40 @@ struct ctrl_clk_vf_pair { u32 voltage_uv; }; +#define CTRL_CLK_CLK_VF_POINT_FREQ_TUPLE_MAX_SIZE 0x5U + +struct ctrl_clk_vf_point_freq_tuple { + u16 freqMHz; +}; + +struct ctrl_clk_vf_point_base_vf_tuple { + struct ctrl_clk_vf_point_freq_tuple + freqTuple[CTRL_CLK_CLK_VF_POINT_FREQ_TUPLE_MAX_SIZE]; + u32 voltageuV; +}; + +#define CTRL_CLK_CLK_VF_POINT_DVCO_OFFSET_CODE_INVALID 0xFFU + +struct ctrl_clk_vf_point_base_vf_tuple_sec { + struct ctrl_clk_vf_point_base_vf_tuple super; + u8 dvco_offset_code; +}; + +struct ctrl_clk_vf_point_vf_tuple { + u16 freqMHz; + u32 voltageuV; +}; + +struct ctrl_clk_vf_input { + u8 flags; + u32 value; +}; + +struct ctrl_clk_vf_output { + u32 input_best_match; + u32 value; +}; + struct ctrl_clk_clk_domain_list_item { u32 clk_domain; u32 clk_freq_khz; diff --git a/drivers/gpu/nvgpu/include/nvgpu/pmuif/gpmu_super_surf_if.h b/drivers/gpu/nvgpu/include/nvgpu/pmuif/gpmu_super_surf_if.h index f781d7c63..bc448f471 100644 --- a/drivers/gpu/nvgpu/include/nvgpu/pmuif/gpmu_super_surf_if.h +++ b/drivers/gpu/nvgpu/include/nvgpu/pmuif/gpmu_super_surf_if.h @@ -81,6 +81,12 @@ struct nv_pmu_super_surface { struct perf_change_seq_pmu_script script_last; struct perf_change_seq_pmu_script script_query; } change_seq; + struct { + struct nv_pmu_clk_clk_vf_point_boardobj_grp_set clk_vf_point_grp_set; + struct nv_pmu_clk_clk_vf_point_boardobj_grp_set clk_vf_point_sec_grp_set; + struct nv_pmu_clk_clk_vf_point_boardobj_grp_get_status clk_vf_point_grp_get_status; + }clk_35; + }; #endif /* NVGPU_PMUIF_GPMU_SUPER_SURF_IF_H */ diff --git a/drivers/gpu/nvgpu/include/nvgpu/pmuif/gpmuifclk.h b/drivers/gpu/nvgpu/include/nvgpu/pmuif/gpmuifclk.h index 24e0bbc27..e977caa10 100644 --- a/drivers/gpu/nvgpu/include/nvgpu/pmuif/gpmuifclk.h +++ b/drivers/gpu/nvgpu/include/nvgpu/pmuif/gpmuifclk.h @@ -356,6 +356,9 @@ struct nv_pmu_clk_clk_vf_point_boardobjgrp_set_header { struct nv_pmu_boardobjgrp_e255 super; }; +struct nv_pmu_clk_clk_vf_point_sec_boardobjgrp_set_header { + struct nv_pmu_boardobjgrp_e255 super; +}; struct nv_pmu_clk_clk_vf_point_boardobj_set { struct nv_pmu_boardobj super; u8 vfe_equ_idx; @@ -374,6 +377,11 @@ struct nv_pmu_clk_clk_vf_point_volt_boardobj_set { struct ctrl_clk_freq_delta freq_delta; }; +struct nv_pmu_clk_clk_vf_point_volt_35_sec_boardobj_set { + struct nv_pmu_clk_clk_vf_point_volt_boardobj_set super; + u8 dvco_offset_code_override; +}; + union nv_pmu_clk_clk_vf_point_boardobj_set_union { struct nv_pmu_boardobj board_obj; struct nv_pmu_clk_clk_vf_point_boardobj_set super; @@ -381,13 +389,43 @@ union nv_pmu_clk_clk_vf_point_boardobj_set_union { struct nv_pmu_clk_clk_vf_point_volt_boardobj_set volt; }; +union nv_pmu_clk_clk_vf_point_sec_boardobj_set_union { + struct nv_pmu_boardobj board_obj; + struct nv_pmu_clk_clk_vf_point_boardobj_set super; + struct nv_pmu_clk_clk_vf_point_freq_boardobj_set freq; + struct nv_pmu_clk_clk_vf_point_volt_boardobj_set volt; + struct nv_pmu_clk_clk_vf_point_volt_35_sec_boardobj_set v35_volt_sec; +}; + NV_PMU_BOARDOBJ_GRP_SET_MAKE_E255(clk, clk_vf_point); +NV_PMU_BOARDOBJ_GRP_SET_MAKE_E255(clk, clk_vf_point_sec); struct nv_pmu_clk_clk_vf_point_boardobjgrp_get_status_header { struct nv_pmu_boardobjgrp_e255 super; u32 vf_points_cahce_counter; }; +struct nv_pmu_clk_clk_vf_point_35_freq_boardobj_get_status { + struct nv_pmu_boardobj super; + struct ctrl_clk_vf_point_base_vf_tuple base_vf_tuple; + struct ctrl_clk_vf_point_vf_tuple + offseted_vf_tuple[CTRL_CLK_CLK_VF_POINT_FREQ_TUPLE_MAX_SIZE]; +}; + +struct nv_pmu_clk_clk_vf_point_35_volt_pri_boardobj_get_status { + struct nv_pmu_boardobj super; + struct ctrl_clk_vf_point_base_vf_tuple base_vf_tuple; + struct ctrl_clk_vf_point_vf_tuple + offseted_vf_tuple[CTRL_CLK_CLK_VF_POINT_FREQ_TUPLE_MAX_SIZE]; +}; + +struct nv_pmu_clk_clk_vf_point_35_volt_sec_boardobj_get_status { + struct nv_pmu_boardobj super; + struct ctrl_clk_vf_point_base_vf_tuple_sec base_vf_tuple; + struct ctrl_clk_vf_point_vf_tuple + offseted_vf_tuple[CTRL_CLK_CLK_VF_POINT_FREQ_TUPLE_MAX_SIZE]; +}; + struct nv_pmu_clk_clk_vf_point_boardobj_get_status { struct nv_pmu_boardobj super; struct ctrl_clk_vf_pair pair; @@ -403,6 +441,9 @@ union nv_pmu_clk_clk_vf_point_boardobj_get_status_union { struct nv_pmu_boardobj board_obj; struct nv_pmu_clk_clk_vf_point_boardobj_get_status super; struct nv_pmu_clk_clk_vf_point_volt_boardobj_get_status volt; + struct nv_pmu_clk_clk_vf_point_35_freq_boardobj_get_status v35_freq; + struct nv_pmu_clk_clk_vf_point_35_volt_pri_boardobj_get_status v35_volt_pri; + struct nv_pmu_clk_clk_vf_point_35_volt_sec_boardobj_get_status v35_volt_sec; }; NV_PMU_BOARDOBJ_GRP_GET_STATUS_MAKE_E255(clk, clk_vf_point); diff --git a/drivers/gpu/nvgpu/include/nvgpu/pmuif/gpmuifperf.h b/drivers/gpu/nvgpu/include/nvgpu/pmuif/gpmuifperf.h index 862b8e16d..f7fe176e4 100644 --- a/drivers/gpu/nvgpu/include/nvgpu/pmuif/gpmuifperf.h +++ b/drivers/gpu/nvgpu/include/nvgpu/pmuif/gpmuifperf.h @@ -61,6 +61,7 @@ struct nv_pmu_rpc_struct_perf_load { /*[IN/OUT] Must be first field in RPC structure */ struct nv_pmu_rpc_header hdr; + bool b_load; u32 scratch[1]; }; @@ -124,6 +125,7 @@ struct nv_pmu_perf_rpc { #define NV_PMU_PERF_MSG_ID_BOARDOBJ_GRP_SET (0x00000004U) #define NV_PMU_PERF_MSG_ID_BOARDOBJ_GRP_GET_STATUS (0x00000006U) #define NV_PMU_PERF_MSG_ID_VFE_CALLBACK (0x00000005U) +#define NV_PMU_PERF_MSG_ID_CHANGE_SEQ_COMPLETION (0x00000007U) /*! * Message carrying the result of the perf RPC execution. diff --git a/drivers/gpu/nvgpu/pmu_perf/perf_gv100.h b/drivers/gpu/nvgpu/pmu_perf/perf_gv100.h index e3d83d9fe..2754cc3f2 100644 --- a/drivers/gpu/nvgpu/pmu_perf/perf_gv100.h +++ b/drivers/gpu/nvgpu/pmu_perf/perf_gv100.h @@ -32,5 +32,4 @@ struct gk20a; u32 perf_pmu_init_vfe_perf_event(struct gk20a *g); int gv100_perf_pmu_vfe_load(struct gk20a *g); - #endif /* NVGPU_PERF_GV100_H */ diff --git a/drivers/gpu/nvgpu/pmu_perf/perf_tu104.c b/drivers/gpu/nvgpu/pmu_perf/perf_tu104.c new file mode 100644 index 000000000..133d353f8 --- /dev/null +++ b/drivers/gpu/nvgpu/pmu_perf/perf_tu104.c @@ -0,0 +1,125 @@ +/* + * GV100 PERF + * + * Copyright (c) 2018, 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 "perf_tu104.h" +#include "pmu_perf/pmu_perf.h" + +static int pmu_set_boot_clk_runcb_fn(void *arg) +{ + struct gk20a *g = (struct gk20a *)arg; + struct nvgpu_pmu *pmu = &g->pmu; + struct nv_pmu_rpc_struct_perf_load rpc; + struct perf_pmupstate *perf_pmu = g->perf_pmu; + struct nvgpu_vfe_invalidate *vfe_init = &perf_pmu->vfe_init; + int status = 0; + + nvgpu_log_fn(g, "thread start"); + + while (true) { + NVGPU_COND_WAIT_INTERRUPTIBLE(&vfe_init->wq, + (vfe_init->state_change == true), 0); + + vfe_init->state_change = false; + + (void) memset(&rpc, 0, + sizeof(struct nv_pmu_rpc_struct_perf_load)); + PMU_RPC_EXECUTE_CPB(status, pmu, PERF, LOAD, &rpc, 0); + if (status != 0) { + nvgpu_err(g, "Failed to execute RPC status=0x%x", + status); + } + } + + return 0; +} + +static int tu104_pmu_handle_perf_event(struct gk20a *g, void *pmumsg) +{ + struct nv_pmu_perf_msg *msg = (struct nv_pmu_perf_msg *)pmumsg; + struct perf_pmupstate *perf_pmu = g->perf_pmu; + + nvgpu_log_fn(g, " "); + switch (msg->msg_type) { + case NV_PMU_PERF_MSG_ID_VFE_CALLBACK: + perf_pmu->vfe_init.state_change = true; + (void) nvgpu_cond_signal(&perf_pmu->vfe_init.wq); + break; + case NV_PMU_PERF_MSG_ID_CHANGE_SEQ_COMPLETION: + nvgpu_log_fn(g, "Change Seq Completed"); + break; + default: + WARN_ON(true); + break; + } + return 0; +} + +int tu104_perf_pmu_init_vfe_perf_event(struct gk20a *g) +{ + struct perf_pmupstate *perf_pmu = g->perf_pmu; + char thread_name[64]; + int err = 0; + + nvgpu_log_fn(g, " "); + + nvgpu_cond_init(&perf_pmu->vfe_init.wq); + + (void) snprintf(thread_name, sizeof(thread_name), + "nvgpu_vfe_invalidate_init_%s", g->name); + + err = nvgpu_thread_create(&perf_pmu->vfe_init.state_task, g, + pmu_set_boot_clk_runcb_fn, thread_name); + if (err != 0U) { + nvgpu_err(g, "failed to start nvgpu_vfe_invalidate_init thread"); + } + + return err; + +} + +int tu104_perf_pmu_vfe_load(struct gk20a *g) +{ + struct nvgpu_pmu *pmu = &g->pmu; + struct nv_pmu_rpc_struct_perf_load rpc; + int status = 0; + + (void) memset(&rpc, 0, sizeof(struct nv_pmu_rpc_struct_perf_load)); + rpc.b_load = true; + PMU_RPC_EXECUTE_CPB(status, pmu, PERF, LOAD, &rpc, 0); + if (status != 0) { + nvgpu_err(g, "Failed to execute RPC status=0x%x", + status); + } + + status = tu104_perf_pmu_init_vfe_perf_event(g); + + /*register call back for future VFE updates*/ + g->ops.pmu_perf.handle_pmu_perf_event = tu104_pmu_handle_perf_event; + + return status; +} diff --git a/drivers/gpu/nvgpu/pmu_perf/perf_tu104.h b/drivers/gpu/nvgpu/pmu_perf/perf_tu104.h new file mode 100644 index 000000000..9cb6d8e6d --- /dev/null +++ b/drivers/gpu/nvgpu/pmu_perf/perf_tu104.h @@ -0,0 +1,35 @@ +/* + * GV100 PERF + * + * Copyright (c) 2018, 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_PERF_TU104_H +#define NVGPU_PERF_TU104_H + +#include + +struct gk20a; + +int tu104_perf_pmu_init_vfe_perf_event(struct gk20a *g); +int tu104_perf_pmu_vfe_load(struct gk20a *g); + +#endif /* NVGPU_PERF_TU104_H */ diff --git a/drivers/gpu/nvgpu/pstate/pstate.c b/drivers/gpu/nvgpu/pstate/pstate.c index 7c3344380..45a145403 100644 --- a/drivers/gpu/nvgpu/pstate/pstate.c +++ b/drivers/gpu/nvgpu/pstate/pstate.c @@ -277,16 +277,16 @@ int gk20a_init_pstate_pmu_support(struct gk20a *g) return err; } - if (g->ops.clk.support_vf_point && - g->ops.pmu_perf.support_vfe) { - err = clk_vf_point_pmu_setup(g); + if (g->ops.clk.support_clk_freq_controller) { + err = clk_freq_controller_pmu_setup(g); if (err != 0U) { return err; } } - if (g->ops.clk.support_clk_freq_controller) { - err = clk_freq_controller_pmu_setup(g); + if (g->ops.clk.support_vf_point && + g->ops.pmu_perf.support_vfe) { + err = clk_vf_point_pmu_setup(g); if (err != 0U) { return err; } diff --git a/drivers/gpu/nvgpu/tu104/hal_tu104.c b/drivers/gpu/nvgpu/tu104/hal_tu104.c index 810b0805e..40c68ea82 100644 --- a/drivers/gpu/nvgpu/tu104/hal_tu104.c +++ b/drivers/gpu/nvgpu/tu104/hal_tu104.c @@ -116,6 +116,7 @@ #include "gv100/gr_gv100.h" #include "gv100/mm_gv100.h" #include "gv100/regops_gv100.h" +#include "pmu_perf/perf_tu104.h" #include "tu104/fifo_tu104.h" #include "tu104/gr_tu104.h" @@ -942,6 +943,7 @@ static const struct gpu_ops tu104_ops = { .get_rate_cntr = gv100_get_rate_cntr, .measure_freq = gv100_clk_measure_freq, .suspend_clk_support = gv100_suspend_clk_support, + .perf_pmu_vfe_load = tu104_perf_pmu_vfe_load, }, .clk_arb = { .get_arbiter_clk_domains = NULL, @@ -1208,8 +1210,10 @@ int tu104_init_hal(struct gk20a *g) gops->clk.support_lpwr_pg = false; gops->clk.support_clk_freq_domain = true; gops->pmu_perf.support_changeseq = true; - gops->pmu_perf.support_vfe = false; - gops->clk.support_vf_point = false; + gops->pmu_perf.support_vfe = true; + gops->clk.support_vf_point = true; + gops->clk.lut_num_entries = CTRL_CLK_LUT_NUM_ENTRIES_GV10x; + gops->clk.perf_pmu_vfe_load = tu104_perf_pmu_vfe_load; /* dGpu VDK support */ if (nvgpu_is_enabled(g, NVGPU_IS_FMODEL)){