diff --git a/arch/nvgpu-common.yaml b/arch/nvgpu-common.yaml index 11f9a6d65..99f4067f2 100644 --- a/arch/nvgpu-common.yaml +++ b/arch/nvgpu-common.yaml @@ -600,6 +600,7 @@ pmu: include/nvgpu/pmu/pmuif/clk.h, include/nvgpu/pmu/pmuif/perf.h, include/nvgpu/pmu/pmuif/perfvfe.h, + include/nvgpu/pmu/pmuif/perfpstate.h, include/nvgpu/pmu/pmuif/pmgr.h, include/nvgpu/pmu/pmuif/seq.h, include/nvgpu/pmu/pmuif/therm.h, diff --git a/drivers/gpu/nvgpu/common/pmu/fw/fw_ver_ops.c b/drivers/gpu/nvgpu/common/pmu/fw/fw_ver_ops.c index 6a0b06ecd..014c2a173 100644 --- a/drivers/gpu/nvgpu/common/pmu/fw/fw_ver_ops.c +++ b/drivers/gpu/nvgpu/common/pmu/fw/fw_ver_ops.c @@ -41,7 +41,7 @@ #include /* PMU F/W version */ -#define APP_VERSION_TU10X 25633681U +#define APP_VERSION_TU10X 26497652U #define APP_VERSION_GV11B 25005711U #define APP_VERSION_GV10X 25633490U #define APP_VERSION_GP10X 24076634U diff --git a/drivers/gpu/nvgpu/common/pmu/perf/perf_ps35.c b/drivers/gpu/nvgpu/common/pmu/perf/perf_ps35.c index b8a533cb5..800052b8b 100644 --- a/drivers/gpu/nvgpu/common/pmu/perf/perf_ps35.c +++ b/drivers/gpu/nvgpu/common/pmu/perf/perf_ps35.c @@ -68,6 +68,9 @@ static int tu104_pmu_handle_perf_event(struct gk20a *g, void *pmumsg) case NV_PMU_PERF_MSG_ID_CHANGE_SEQ_COMPLETION: nvgpu_log_fn(g, "Change Seq Completed"); break; + case NV_PMU_PERF_MSG_ID_PSTATES_INVALIDATE: + nvgpu_log_fn(g, "Pstate Invalidated"); + break; default: WARN_ON(true); break; @@ -104,18 +107,22 @@ int nvgpu_perf_pmu_vfe_load_ps35(struct gk20a *g) struct nv_pmu_rpc_struct_perf_load rpc; int status = 0; + status = perf_pmu_init_vfe_perf_event(g); + if (status != 0) { + return status; + } + + /*register call back for future VFE updates*/ + g->ops.pmu_perf.handle_pmu_perf_event = tu104_pmu_handle_perf_event; + (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); + nvgpu_thread_stop(&g->perf_pmu->vfe_init.state_task); } - status = 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/common/pmu/perf/perf_pstate.c b/drivers/gpu/nvgpu/common/pmu/perf/perf_pstate.c index fc30dfd78..f4e6f69e6 100644 --- a/drivers/gpu/nvgpu/common/pmu/perf/perf_pstate.c +++ b/drivers/gpu/nvgpu/common/pmu/perf/perf_pstate.c @@ -33,49 +33,119 @@ #include #include #include +#include #include "perf_pstate.h" +static int pstate_init_pmudata_super(struct gk20a *g, + struct boardobj *board_obj_ptr, + struct nv_pmu_boardobj *ppmudata) +{ + return nvgpu_boardobj_pmu_data_init_super(g, board_obj_ptr, ppmudata); +} + +static int pstate_init_pmudata(struct gk20a *g, + struct boardobj *board_obj_ptr, + struct nv_pmu_boardobj *ppmudata) +{ + int status = 0; + u32 clkidx; + struct pstate *pstate; + struct nv_pmu_perf_pstate_35 *pstate_pmu_data; + + status = pstate_init_pmudata_super(g, board_obj_ptr, ppmudata); + if (status != 0) { + return status; + } + + pstate = (struct pstate *)board_obj_ptr; + pstate_pmu_data = (struct nv_pmu_perf_pstate_35 *)ppmudata; + + pstate_pmu_data->super.super.lpwrEntryIdx = pstate->lpwr_entry_idx; + pstate_pmu_data->super.super.flags = pstate->flags; + pstate_pmu_data->nvlinkIdx = pstate->nvlink_idx; + pstate_pmu_data->pcieIdx = pstate->pcie_idx; + + for (clkidx = 0; clkidx < pstate->clklist.num_info; clkidx++) { + pstate_pmu_data->clkEntries[clkidx].max.baseFreqKhz = + pstate->clklist.clksetinfo[clkidx].max_mhz*1000; + pstate_pmu_data->clkEntries[clkidx].max.freqKz = + pstate->clklist.clksetinfo[clkidx].max_mhz*1000; + pstate_pmu_data->clkEntries[clkidx].max.origFreqKhz = + pstate->clklist.clksetinfo[clkidx].max_mhz*1000; + pstate_pmu_data->clkEntries[clkidx].max.porFreqKhz = + pstate->clklist.clksetinfo[clkidx].max_mhz*1000; + + pstate_pmu_data->clkEntries[clkidx].min.baseFreqKhz = + pstate->clklist.clksetinfo[clkidx].min_mhz*1000; + pstate_pmu_data->clkEntries[clkidx].min.freqKz = + pstate->clklist.clksetinfo[clkidx].min_mhz*1000; + pstate_pmu_data->clkEntries[clkidx].min.origFreqKhz = + pstate->clklist.clksetinfo[clkidx].min_mhz*1000; + pstate_pmu_data->clkEntries[clkidx].min.porFreqKhz = + pstate->clklist.clksetinfo[clkidx].min_mhz*1000; + + pstate_pmu_data->clkEntries[clkidx].nom.baseFreqKhz = + pstate->clklist.clksetinfo[clkidx].nominal_mhz*1000; + pstate_pmu_data->clkEntries[clkidx].nom.freqKz = + pstate->clklist.clksetinfo[clkidx].nominal_mhz*1000; + pstate_pmu_data->clkEntries[clkidx].nom.origFreqKhz = + pstate->clklist.clksetinfo[clkidx].nominal_mhz*1000; + pstate_pmu_data->clkEntries[clkidx].nom.porFreqKhz = + pstate->clklist.clksetinfo[clkidx].nominal_mhz*1000; + } + + return status; +} + static int pstate_construct_super(struct gk20a *g, struct boardobj **ppboardobj, size_t size, void *args) { - struct pstate *ptmppstate = (struct pstate *)args; - struct pstate *pstate; - int err; + return nvgpu_boardobj_construct_super(g, ppboardobj, size, args); - err = nvgpu_boardobj_construct_super(g, ppboardobj, size, args); - if (err != 0) { - return err; - } - - pstate = (struct pstate *)*ppboardobj; - - pstate->num = ptmppstate->num; - pstate->clklist = ptmppstate->clklist; - pstate->lpwr_entry_idx = ptmppstate->lpwr_entry_idx; - - return 0; } -static int pstate_construct_3x(struct gk20a *g, struct boardobj **ppboardobj, - size_t size, void *args) +static int pstate_construct_35(struct gk20a *g, struct boardobj **ppboardobj, + u16 size, void *args) { struct boardobj *ptmpobj = (struct boardobj *)args; - ptmpobj->type_mask |= BIT32(CTRL_PERF_PSTATE_TYPE_3X); + ptmpobj->type_mask |= BIT32(CTRL_PERF_PSTATE_TYPE_35); return pstate_construct_super(g, ppboardobj, size, args); } static struct pstate *pstate_construct(struct gk20a *g, void *args) { struct pstate *pstate = NULL; - struct pstate *tmp = (struct pstate *)args; + struct pstate *ptmppstate = (struct pstate *)args; + int status; + u32 clkidx; - if ((tmp->super.type != CTRL_PERF_PSTATE_TYPE_3X) || - (pstate_construct_3x(g, (struct boardobj **)&pstate, - sizeof(struct pstate), args) != 0)) { + status = pstate_construct_35(g, (struct boardobj **)&pstate, + (u16)sizeof(struct pstate), args); + if (status != 0) { nvgpu_err(g, - "error constructing pstate num=%u", tmp->num); + "error constructing pstate num=%u", ptmppstate->num); + return NULL; + } + + pstate->super.pmudatainit = pstate_init_pmudata; + pstate->num = ptmppstate->num; + pstate->flags = ptmppstate->flags; + pstate->lpwr_entry_idx = ptmppstate->lpwr_entry_idx; + pstate->pcie_idx = ptmppstate->pcie_idx; + pstate->nvlink_idx = ptmppstate->nvlink_idx; + pstate->clklist.num_info = ptmppstate->clklist.num_info; + + for (clkidx = 0; clkidx < ptmppstate->clklist.num_info; clkidx++) { + pstate->clklist.clksetinfo[clkidx].clkwhich = + ptmppstate->clklist.clksetinfo[clkidx].clkwhich; + pstate->clklist.clksetinfo[clkidx].max_mhz = + ptmppstate->clklist.clksetinfo[clkidx].max_mhz; + pstate->clklist.clksetinfo[clkidx].min_mhz = + ptmppstate->clklist.clksetinfo[clkidx].min_mhz; + pstate->clklist.clksetinfo[clkidx].nominal_mhz = + ptmppstate->clklist.clksetinfo[clkidx].nominal_mhz; } return pstate; @@ -94,7 +164,7 @@ static int pstate_insert(struct gk20a *g, struct pstate *pstate, u8 index) return err; } - pstates->num_levels++; + pstates->num_clk_domains++; return err; } @@ -108,14 +178,14 @@ static int parse_pstate_entry_6x(struct gk20a *g, u32 clkidx; p += hdr->base_entry_size; - (void) memset(pstate, 0, sizeof(struct pstate)); - pstate->super.type = CTRL_PERF_PSTATE_TYPE_3X; + pstate->super.type = CTRL_PERF_PSTATE_TYPE_35; pstate->num = 0x0FU - U32(entry->pstate_level); pstate->clklist.num_info = hdr->clock_entry_count; pstate->lpwr_entry_idx = entry->lpwr_entry_idx; - - nvgpu_log_info(g, "pstate P%u", pstate->num); + pstate->flags = entry->flags0; + pstate->nvlink_idx = entry->nvlink_idx; + pstate->pcie_idx = entry->pcie_idx; for (clkidx = 0; clkidx < hdr->clock_entry_count; clkidx++) { struct clk_set_info *pclksetinfo; @@ -203,25 +273,11 @@ done: return err; } -int nvgpu_pmu_perf_pstate_sw_setup(struct gk20a *g) +static int devinit_get_pstate_table(struct gk20a *g) { struct vbios_pstate_header_6x *hdr = NULL; int err = 0; - nvgpu_log_fn(g, " "); - - nvgpu_cond_init(&g->perf_pmu->pstatesobjs.pstate_notifier_wq); - - nvgpu_mutex_init(&g->perf_pmu->pstatesobjs.pstate_mutex); - - err = nvgpu_boardobjgrp_construct_e32(g, &g->perf_pmu->pstatesobjs.super); - if (err != 0) { - nvgpu_err(g, - "error creating boardobjgrp for pstates, err=%d", - err); - goto done; - } - hdr = (struct vbios_pstate_header_6x *) nvgpu_bios_get_perf_table_ptrs(g, nvgpu_bios_get_bit_token(g, NVGPU_BIOS_PERF_TOKEN), @@ -242,20 +298,145 @@ int nvgpu_pmu_perf_pstate_sw_setup(struct gk20a *g) err = parse_pstate_table_6x(g, hdr); done: - if (err != 0) { - nvgpu_mutex_destroy(&g->perf_pmu->pstatesobjs.pstate_mutex); - } return err; } +static int perf_pstate_pmudatainit(struct gk20a *g, + struct boardobjgrp *pboardobjgrp, + struct nv_pmu_boardobjgrp_super *pboardobjgrppmu) +{ + int status = 0; + struct nv_pmu_perf_pstate_boardobjgrp_set_header *pset = + (struct nv_pmu_perf_pstate_boardobjgrp_set_header *) + (void *)pboardobjgrppmu; + struct pstates *pprogs = (struct pstates *)(void *)pboardobjgrp; + + status = boardobjgrp_pmudatainit_e32(g, pboardobjgrp, pboardobjgrppmu); + if (status != 0) { + nvgpu_err(g, "error updating pmu boardobjgrp for vfe equ 0x%x", + status); + goto done; + } + + pset->numClkDomains = pprogs->num_clk_domains; + +done: + return status; +} + +static int perf_pstate_pmudata_instget(struct gk20a *g, + struct nv_pmu_boardobjgrp *pmuboardobjgrp, + struct nv_pmu_boardobj **ppboardobjpmudata, u8 idx) +{ + struct nv_pmu_perf_pstate_boardobj_grp_set *pgrp_set = + (struct nv_pmu_perf_pstate_boardobj_grp_set *) + (void *)pmuboardobjgrp; + + /* check whether pmuboardobjgrp has a valid boardobj in index */ + if (idx >= CTRL_BOARDOBJGRP_E32_MAX_OBJECTS) { + return -EINVAL; + } + + *ppboardobjpmudata = (struct nv_pmu_boardobj *) + &pgrp_set->objects[idx].data.boardObj; + + return 0; +} + +static int perf_pstate_pmustatus_instget(struct gk20a *g, + void *pboardobjgrppmu, + struct nv_pmu_boardobj_query **ppboardobjpmustatus, u8 idx) +{ + struct nv_pmu_perf_pstate_boardobj_grp_get_status *pgrp_get_status = + (struct nv_pmu_perf_pstate_boardobj_grp_get_status *)(void *) + pboardobjgrppmu; + + /*Check for valid pmuboardobjgrp index*/ + if ((BIT32(idx) & + pgrp_get_status->hdr.data.super.obj_mask.super.data[0]) == 0U) { + return -EINVAL; + } + + *ppboardobjpmustatus = (struct nv_pmu_boardobj_query *) + &pgrp_get_status->objects[idx].data.board_obj; + return 0; +} + +int nvgpu_pmu_perf_pstate_sw_setup(struct gk20a *g) +{ + int status; + struct boardobjgrp *pboardobjgrp = NULL; + + status = nvgpu_boardobjgrp_construct_e32(g, + &g->perf_pmu->pstatesobjs.super); + if (status != 0) { + nvgpu_err(g, + "error creating boardobjgrp for pstate, status - 0x%x", + status); + goto done; + } + + pboardobjgrp = &g->perf_pmu->pstatesobjs.super.super; + + BOARDOBJGRP_PMU_CONSTRUCT(pboardobjgrp, PERF, PSTATE); + + status = BOARDOBJGRP_PMU_CMD_GRP_SET_CONSTRUCT(g, pboardobjgrp, + perf, PERF, pstate, PSTATE); + if (status != 0) { + nvgpu_err(g, + "error constructing PSTATE_SET interface - 0x%x", + status); + goto done; + } + + g->perf_pmu->pstatesobjs.num_clk_domains = + VBIOS_PSTATE_CLOCK_ENTRY_6X_COUNT; + + status = BOARDOBJGRP_PMU_CMD_GRP_GET_STATUS_CONSTRUCT(g, pboardobjgrp, + perf, PERF, pstate, PSTATE); + if (status != 0) { + nvgpu_err(g, + "error constructing PSTATE_GET_STATUS interface - 0x%x", + status); + goto done; + } + + pboardobjgrp->pmudatainit = perf_pstate_pmudatainit; + pboardobjgrp->pmudatainstget = perf_pstate_pmudata_instget; + pboardobjgrp->pmustatusinstget = perf_pstate_pmustatus_instget; + + status = devinit_get_pstate_table(g); + if (status != 0) { + nvgpu_err(g, "Error parsing the performance Vbios tables"); + goto done; + } + +done: + return status; +} + +int nvgpu_pmu_perf_pstate_pmu_setup(struct gk20a *g) +{ + int status; + struct boardobjgrp *pboardobjgrp = NULL; + + pboardobjgrp = &g->perf_pmu->pstatesobjs.super.super; + if (!pboardobjgrp->bconstructed) { + return -EINVAL; + } + + status = pboardobjgrp->pmuinithandle(g, pboardobjgrp); + + return status; +} + + struct pstate *nvgpu_pmu_perf_pstate_find(struct gk20a *g, u32 num) { struct pstates *pstates = &(g->perf_pmu->pstatesobjs); struct pstate *pstate; u8 i; - nvgpu_log_info(g, "pstates = %p", pstates); - BOARDOBJGRP_FOR_EACH(&pstates->super.super, struct pstate *, pstate, i) { nvgpu_log_info(g, "pstate=%p num=%u (looking for num=%u)", @@ -274,8 +455,6 @@ struct clk_set_info *nvgpu_pmu_perf_pstate_get_clk_set_info(struct gk20a *g, struct clk_set_info *info; u32 clkidx; - nvgpu_log_info(g, "pstate = %p", pstate); - if (pstate == NULL) { return NULL; } diff --git a/drivers/gpu/nvgpu/common/pmu/perf/perf_pstate.h b/drivers/gpu/nvgpu/common/pmu/perf/perf_pstate.h index c76d77088..43491516b 100644 --- a/drivers/gpu/nvgpu/common/pmu/perf/perf_pstate.h +++ b/drivers/gpu/nvgpu/common/pmu/perf/perf_pstate.h @@ -25,6 +25,6 @@ #ifndef NVGPU_PERF_PSTATE_H #define NVGPU_PERF_PSTATE_H -#define CTRL_PERF_PSTATE_TYPE_3X 0x3U +#define CTRL_PERF_PSTATE_TYPE_35 0x05U #endif /* NVGPU_PERF_PSTATE_H */ diff --git a/drivers/gpu/nvgpu/common/pmu/perf/pmu_perf.c b/drivers/gpu/nvgpu/common/pmu/perf/pmu_perf.c index 7708646e3..87e3f6daa 100644 --- a/drivers/gpu/nvgpu/common/pmu/perf/pmu_perf.c +++ b/drivers/gpu/nvgpu/common/pmu/perf/pmu_perf.c @@ -57,7 +57,6 @@ void nvgpu_perf_pmu_free_pmupstate(struct gk20a *g) vfe_thread_stop_cb, &g->perf_pmu->vfe_init.wq); } nvgpu_cond_destroy(&g->perf_pmu->vfe_init.wq); - nvgpu_mutex_destroy(&g->perf_pmu->pstatesobjs.pstate_mutex); nvgpu_kfree(g, g->perf_pmu); g->perf_pmu = NULL; } diff --git a/drivers/gpu/nvgpu/common/pmu/pmu_pstate.c b/drivers/gpu/nvgpu/common/pmu/pmu_pstate.c index 94e5be72a..cd1d109dd 100644 --- a/drivers/gpu/nvgpu/common/pmu/pmu_pstate.c +++ b/drivers/gpu/nvgpu/common/pmu/pmu_pstate.c @@ -439,6 +439,11 @@ static int pmu_pstate_perf_pmu_setup(struct gk20a *g) } } + err = nvgpu_pmu_perf_pstate_pmu_setup(g); + if (err != 0) { + return err; + } + if (g->ops.pmu_perf.support_changeseq) { err = nvgpu_perf_change_seq_pmu_setup(g); if (err != 0) { diff --git a/drivers/gpu/nvgpu/common/pmu/super_surface/super_surface_priv.h b/drivers/gpu/nvgpu/common/pmu/super_surface/super_surface_priv.h index 68b3a4635..dc8fd3a8f 100644 --- a/drivers/gpu/nvgpu/common/pmu/super_surface/super_surface_priv.h +++ b/drivers/gpu/nvgpu/common/pmu/super_surface/super_surface_priv.h @@ -151,6 +151,10 @@ struct nv_pmu_super_surface { vfe_var_grp_set; struct nv_pmu_perf_vfe_var_boardobj_grp_get_status_pack vfe_var_grp_get_status; + struct nv_pmu_perf_pstate_boardobj_grp_set + pstate_grp_set; + struct nv_pmu_perf_pstate_boardobj_grp_get_status + pstate_grp_get_status; } perf; struct { struct nv_pmu_therm_therm_channel_boardobj_grp_set diff --git a/drivers/gpu/nvgpu/include/nvgpu/bios.h b/drivers/gpu/nvgpu/include/nvgpu/bios.h index e6365014d..eb2f78bca 100644 --- a/drivers/gpu/nvgpu/include/nvgpu/bios.h +++ b/drivers/gpu/nvgpu/include/nvgpu/bios.h @@ -587,8 +587,19 @@ struct vbios_pstate_header_6x { u8 cpi_features; } __packed; -#define VBIOS_PSTATE_CLOCK_ENTRY_6X_SIZE_6 6U -#define VBIOS_PSTATE_BASE_ENTRY_6X_SIZE_5 0x5U +#define VBIOS_PSTATE_HEADER_6X_FLAGS0_PSTATES_MASK 0x1U +#define VBIOS_PSTATE_HEADER_6X_FLAGS0_PSTATES_SHIFT 0x0U +#define VBIOS_PSTATE_HEADER_6X_FLAGS0_PSTATES_NOT_REQUIRED 0x0U +#define VBIOS_PSTATE_HEADER_6X_FLAGS0_PSTATES_REQUIRED 0x1U +#define VBIOS_PSTATE_HEADER_6X_FLAGS0_ARBITER_LOCK_MASK 0x2U +#define VBIOS_PSTATE_HEADER_6X_FLAGS0_ARBITER_LOCK_SHIFT 0x1U +#define VBIOS_PSTATE_HEADER_6X_FLAGS0_ARBITER_LOCK_DISABLED 0x0U +#define VBIOS_PSTATE_HEADER_6X_FLAGS0_ARBITER_LOCK_ENABLED 0x1U + +#define VBIOS_PSTATE_CLOCK_ENTRY_6X_SIZE_6 6U +#define VBIOS_PSTATE_BASE_ENTRY_6X_SIZE_5 0x5U +#define VBIOS_PSTATE_CLOCK_ENTRY_6X_COUNT 10U + struct vbios_pstate_entry_clock_6x { u16 param0; @@ -599,10 +610,34 @@ struct vbios_pstate_entry_6x { u8 pstate_level; u8 flags0; u8 lpwr_entry_idx; + u8 pcie_idx; + u8 nvlink_idx; struct vbios_pstate_entry_clock_6x nvgpu_clockEntry[PERF_CLK_DOMAINS_IDX_MAX]; } __packed; +#define VBIOS_PSTATE_6X_FLAGS0_PSTATE_CAP_MASK 0x3U +#define VBIOS_PSTATE_6X_FLAGS0_PSTATE_CAP_SHIFT 0x0U +#define VBIOS_PSTATE_6X_FLAGS0_PSTATE_CAP_RM_DEFAULT 0x0U +#define VBIOS_PSTATE_6X_FLAGS0_PSTATE_CAP_GLITCHY 0x1U +#define VBIOS_PSTATE_6X_FLAGS0_PSTATE_CAP_WAIT_VBLANK 0x2U + +#define VBIOS_PSTATE_6X_FLAGS0_CUDA_MASK 0x4U +#define VBIOS_PSTATE_6X_FLAGS0_CUDA_SHIFT 0x2U +#define VBIOS_PSTATE_6X_FLAGS0_CUDA_SAFE 0x0U +#define VBIOS_PSTATE_6X_FLAGS0_CUDA_NOT_SAFE 0x1U + +#define VBIOS_PSTATE_6X_FLAGS0_OVOC_MASK 0x8U +#define VBIOS_PSTATE_6X_FLAGS0_OVOC_SHIFT 0x3U +#define VBIOS_PSTATE_6X_FLAGS0_OVOC_DISABLED 0x0U +#define VBIOS_PSTATE_6X_FLAGS0_OVOC_ENABLED 0x1U + +#define VBIOS_PSTATE_6X_FLAGS0_DECREASE_THRESHOLD_MASK 0x10U +#define VBIOS_PSTATE_6X_FLAGS0_DECREASE_THRESHOLD_SHIFT 0x4U +#define VBIOS_PSTATE_6X_FLAGS0_DECREASE_THRESHOLD_DEFAULT 0x0U +#define VBIOS_PSTATE_6X_FLAGS0_DECREASE_THRESHOLD_IGNORE_FB 0x1U + + #define VBIOS_PSTATE_6X_CLOCK_PROG_PARAM0_NOM_FREQ_MHZ_SHIFT 0U #define VBIOS_PSTATE_6X_CLOCK_PROG_PARAM0_NOM_FREQ_MHZ_MASK 0x00003FFFU diff --git a/drivers/gpu/nvgpu/include/nvgpu/pmu/perf_pstate.h b/drivers/gpu/nvgpu/include/nvgpu/pmu/perf_pstate.h index 1c9d22082..78321efd7 100644 --- a/drivers/gpu/nvgpu/include/nvgpu/pmu/perf_pstate.h +++ b/drivers/gpu/nvgpu/include/nvgpu/pmu/perf_pstate.h @@ -53,15 +53,15 @@ struct pstate { struct boardobj super; u32 num; u8 lpwr_entry_idx; + u32 flags; + u8 pcie_idx; + u8 nvlink_idx; struct clk_set_info_list clklist; }; struct pstates { struct boardobjgrp_e32 super; - u32 num_levels; - struct nvgpu_cond pstate_notifier_wq; - u32 is_pstate_switch_on; - struct nvgpu_mutex pstate_mutex; /* protect is_pstate_switch_on */ + u8 num_clk_domains; }; struct clk_set_info *nvgpu_pmu_perf_pstate_get_clk_set_info(struct gk20a *g, @@ -69,5 +69,6 @@ struct clk_set_info *nvgpu_pmu_perf_pstate_get_clk_set_info(struct gk20a *g, u32 clkwhich); struct pstate *nvgpu_pmu_perf_pstate_find(struct gk20a *g, u32 num); int nvgpu_pmu_perf_pstate_sw_setup(struct gk20a *g); +int nvgpu_pmu_perf_pstate_pmu_setup(struct gk20a *g); #endif /* NVGPU_PMU_PERF_PSTATE_H_ */ diff --git a/drivers/gpu/nvgpu/include/nvgpu/pmu/pmuif/perf.h b/drivers/gpu/nvgpu/include/nvgpu/pmu/pmuif/perf.h index 9cb1723ca..1dac5b401 100644 --- a/drivers/gpu/nvgpu/include/nvgpu/pmu/pmuif/perf.h +++ b/drivers/gpu/nvgpu/include/nvgpu/pmu/pmuif/perf.h @@ -24,6 +24,7 @@ #include "volt.h" #include "perfvfe.h" +#include "perfpstate.h" /* * Enumeration of BOARDOBJGRP class IDs within OBJPERF. Used as "classId" @@ -32,6 +33,7 @@ */ #define NV_PMU_PERF_BOARDOBJGRP_CLASS_ID_VFE_VAR 0x00U #define NV_PMU_PERF_BOARDOBJGRP_CLASS_ID_VFE_EQU 0x01U +#define NV_PMU_PERF_BOARDOBJGRP_CLASS_ID_PSTATE 0x03U #define NV_PMU_PERF_CMD_ID_RPC (0x00000002U) #define NV_PMU_PERF_CMD_ID_BOARDOBJ_GRP_SET (0x00000003U) @@ -126,6 +128,7 @@ struct nv_pmu_perf_rpc { #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) +#define NV_PMU_PERF_MSG_ID_PSTATES_INVALIDATE (0x00000008U) /* * Message carrying the result of the perf RPC execution. diff --git a/drivers/gpu/nvgpu/include/nvgpu/pmu/pmuif/perfpstate.h b/drivers/gpu/nvgpu/include/nvgpu/pmu/pmuif/perfpstate.h new file mode 100644 index 000000000..681afff7b --- /dev/null +++ b/drivers/gpu/nvgpu/include/nvgpu/pmu/pmuif/perfpstate.h @@ -0,0 +1,128 @@ +/* + * Copyright (c) 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_PMUIF_PERFPSTATE_H_ +#define NVGPU_PMUIF_PERFPSTATE_H_ + +#include +#include "boardobj.h" + +#define PMU_PERF_CLK_DOMAINS_IDX_MAX (16U) + +struct nv_pmu_boardobjgrp_e32; +struct nv_pmu_boardobj; +struct ctrl_perf_pstate_clk_entry; + +struct nv_pmu_perf_pstate_boardobjgrp_set_header { + struct nv_pmu_boardobjgrp_e32 super; + u8 numClkDomains; +}; + +struct nv_pmu_perf_pstate { + struct nv_pmu_boardobj super; + u8 lpwrEntryIdx; + u32 flags; +}; + +struct nv_pmu_perf_pstate_3x { + struct nv_pmu_perf_pstate super; +}; + +struct nv_ctrl_perf_pstate_clk_freq_35 { + u32 freqKz; + u32 freqVfMaxKhz; + u32 baseFreqKhz; + u32 origFreqKhz; + u32 porFreqKhz; +}; + +struct ctrl_perf_pstate_clk_entry_35 { + struct nv_ctrl_perf_pstate_clk_freq_35 min; + struct nv_ctrl_perf_pstate_clk_freq_35 max; + struct nv_ctrl_perf_pstate_clk_freq_35 nom; +}; + +struct ctrl_perf_pstate_clk_entry_30 { + u32 targetFreqKhz; + u32 freqRangeMinKhz; + u32 freqRangeMaxKhz; +}; + +struct nv_pmu_perf_pstate_30 { + struct nv_pmu_perf_pstate_3x super; + struct ctrl_perf_pstate_clk_entry_30 + clkEntries[PMU_PERF_CLK_DOMAINS_IDX_MAX]; +}; + +struct nv_pmu_perf_pstate_35 { + struct nv_pmu_perf_pstate_3x super; + u8 pcieIdx; + u8 nvlinkIdx; + struct ctrl_perf_pstate_clk_entry_35 + clkEntries[PMU_PERF_CLK_DOMAINS_IDX_MAX]; +}; + +union nv_pmu_perf_pstate_boardobj_set_union { + struct nv_pmu_boardobj boardObj; + struct nv_pmu_perf_pstate super; + struct nv_pmu_perf_pstate_3x v3x; + struct nv_pmu_perf_pstate_30 v30; + struct nv_pmu_perf_pstate_35 v35; +}; + +NV_PMU_BOARDOBJ_GRP_SET_MAKE_E32(perf, pstate); + +struct nv_pmu_perf_pstate_boardobjgrp_get_status_header { + struct nv_pmu_boardobjgrp_e32 super; +}; + +struct nv_pmu_perf_pstate_get_status_super { + struct nv_pmu_boardobj boardObj; +}; + +struct nv_pmu_perf_pstate_35_get_status { + struct nv_pmu_perf_pstate_get_status_super super; + struct ctrl_perf_pstate_clk_entry_35 + clkEntries[PMU_PERF_CLK_DOMAINS_IDX_MAX]; +}; + +union nv_pmu_perf_pstate_boardobj_get_status_union { + struct nv_pmu_boardobj board_obj; + struct nv_pmu_perf_pstate_get_status_super super; + struct nv_pmu_perf_pstate_35_get_status v35; +}; + +NV_PMU_BOARDOBJ_GRP_GET_STATUS_MAKE_E32(perf, pstate); + +struct nv_pmu_perf_pstate_clk_domain_status { + u32 clkFreqKHz; + u32 clkFlags; + u8 currentRegimeId; +}; + +struct nv_pmu_perf_pstate_status { + u8 pstateCurrIdx; + struct nv_pmu_perf_pstate_clk_domain_status + clkDomains[PMU_PERF_CLK_DOMAINS_IDX_MAX]; +}; + + +#endif /* NVGPU_PMUIF_PERFPSTATE_H_ */ diff --git a/drivers/gpu/nvgpu/include/nvgpu/pmu/super_surface.h b/drivers/gpu/nvgpu/include/nvgpu/pmu/super_surface.h index 8dd6557ff..991c3afab 100644 --- a/drivers/gpu/nvgpu/include/nvgpu/pmu/super_surface.h +++ b/drivers/gpu/nvgpu/include/nvgpu/pmu/super_surface.h @@ -51,8 +51,9 @@ struct pmu_super_surface; #define NV_PMU_SUPER_SURFACE_MEMBER_CLK_FREQ_CONTROLLER_GRP 0x18U #define NV_PMU_SUPER_SURFACE_MEMBER_CLK_FREQ_DOMAIN_GRP 0x19U #define NV_PMU_SUPER_SURFACE_MEMBER_CHANGE_SEQ_GRP 0x1EU +#define NV_PMU_SUPER_SURFACE_MEMBER_PSTATE_GRP 0x1FU -#define NV_PMU_SUPER_SURFACE_MEMBER_COUNT 0x1FU +#define NV_PMU_SUPER_SURFACE_MEMBER_COUNT 0x20U u32 nvgpu_pmu_get_ss_member_set_offset(struct gk20a *g, struct nvgpu_pmu *pmu, u32 member_id);