gpu: nvgpu: Use cached VF table for target voltage instead of RPC

Nvgpu uses RPC to get target voltage for a freq, though this gets
the latest Voltage, there could be mismatch b/w data in nvgpu & PMU.
To make it consistent, use the local VF table for getting the voltage.
Also the slave ratio calculation is inaccurate due to quantization.
So instead of calculating, use the slave ratio from parsed vbios table.

Bug 200545403

Change-Id: Ibb064f2a0f5eba77166e2b3f9868da9e3fcc7193
Signed-off-by: Abdul Salam <absalam@nvidia.com>
Reviewed-on: https://git-master.nvidia.com/r/2183546
Reviewed-by: svc-mobile-coverity <svc-mobile-coverity@nvidia.com>
GVS: Gerrit_Virtual_Submit
Reviewed-by: Mahantesh Kumbar <mkumbar@nvidia.com>
Reviewed-by: Vijayakumar Subbu <vsubbu@nvidia.com>
Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com>
Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
This commit is contained in:
Abdul Salam
2019-08-26 14:55:33 +05:30
committed by mobile promotions
parent 2272e04861
commit 3ee12f5370
4 changed files with 29 additions and 24 deletions

View File

@@ -34,6 +34,7 @@
#include <nvgpu/timers.h>
#include <nvgpu/pmu/pmu_pstate.h>
#include <nvgpu/pmu/perf_pstate.h>
#include <nvgpu/pmu/clk/clk_vf_point.h>
void nvgpu_clkrpc_pmucmdhandler(struct gk20a *g, struct pmu_msg *msg,
void *param, u32 status)
@@ -57,24 +58,25 @@ void nvgpu_clkrpc_pmucmdhandler(struct gk20a *g, struct pmu_msg *msg,
int nvgpu_clk_domain_freq_to_volt(struct gk20a *g, u8 clkdomain_idx,
u32 *pclkmhz, u32 *pvoltuv, u8 railidx)
{
struct nv_pmu_rpc_clk_domain_35_prog_freq_to_volt rpc;
struct nvgpu_pmu *pmu = g->pmu;
int status = -EINVAL;
(void)memset(&rpc, 0,
sizeof(struct nv_pmu_rpc_clk_domain_35_prog_freq_to_volt));
rpc.volt_rail_idx =
nvgpu_volt_rail_volt_domain_convert_to_idx(g, railidx);
rpc.clk_domain_idx = clkdomain_idx;
rpc.voltage_type = CTRL_VOLT_DOMAIN_LOGIC;
rpc.input.value = *pclkmhz;
PMU_RPC_EXECUTE_CPB(status, pmu, CLK,
CLK_DOMAIN_35_PROG_FREQ_TO_VOLT, &rpc, 0);
if (status != 0) {
nvgpu_err(g, "Failed to execute Freq to Volt RPC status=0x%x",
status);
struct nvgpu_clk_vf_points *pclk_vf_points;
struct boardobjgrp *pboardobjgrp;
struct boardobj *pboardobj = NULL;
int status = -EINVAL;
struct clk_vf_point *pclk_vf_point;
u8 index;
nvgpu_log_info(g, " ");
pclk_vf_points = g->pmu->clk_pmu->clk_vf_pointobjs;
pboardobjgrp = &pclk_vf_points->super.super;
BOARDOBJGRP_FOR_EACH(pboardobjgrp, struct boardobj*, pboardobj, index) {
pclk_vf_point = (struct clk_vf_point *)(void *)pboardobj;
if((*pclkmhz) <= pclk_vf_point->pair.freq_mhz) {
*pvoltuv = pclk_vf_point->pair.voltage_uv;
return 0;
}
}
*pvoltuv = rpc.output.value;
return status;
}

View File

@@ -778,7 +778,8 @@ static int clkdomaingetslaveclk(struct gk20a *g,
pprog1xmaster = (struct clk_prog_1x_master *)(void *)pprog;
status = pprog1xmaster->getslaveclk(g, pclk, pprog1xmaster,
slaveidx, pclkmhz, masterclkmhz);
slaveidx, pclkmhz, masterclkmhz, &pdomain->ratio_domain);
return status;
}
@@ -1604,7 +1605,8 @@ static void clk_set_p0_clk_per_domain(struct gk20a *g, u8 *gpcclk_domain,
nvgpu_err(g, "failed to get XBARCLK P0 info");
break;
}
max_ratio = (vf_point->xbar_mhz*100U)/vf_point->gpc_mhz;
max_ratio = pclk_domain->ratio_domain;
if (vf_point->xbar_mhz < p0_info->min_mhz) {
vf_point->xbar_mhz = p0_info->min_mhz;
}
@@ -1630,7 +1632,7 @@ static void clk_set_p0_clk_per_domain(struct gk20a *g, u8 *gpcclk_domain,
nvgpu_err(g, "failed to get SYSCLK P0 info");
break;
}
max_ratio = (vf_point->sys_mhz*100U)/vf_point->gpc_mhz;
max_ratio = pclk_domain->ratio_domain;
if (vf_point->sys_mhz < p0_info->min_mhz) {
vf_point->sys_mhz = p0_info->min_mhz;
}
@@ -1656,7 +1658,7 @@ static void clk_set_p0_clk_per_domain(struct gk20a *g, u8 *gpcclk_domain,
nvgpu_err(g, "failed to get NVDCLK P0 info");
break;
}
max_ratio = (vf_point->nvd_mhz*100U)/vf_point->gpc_mhz;
max_ratio = pclk_domain->ratio_domain;
if (vf_point->nvd_mhz < p0_info->min_mhz) {
vf_point->nvd_mhz = p0_info->min_mhz;
}
@@ -1682,7 +1684,7 @@ static void clk_set_p0_clk_per_domain(struct gk20a *g, u8 *gpcclk_domain,
nvgpu_err(g, "failed to get HOSTCLK P0 info");
break;
}
max_ratio = (vf_point->host_mhz*100U)/vf_point->gpc_mhz;
max_ratio = pclk_domain->ratio_domain;
if (vf_point->host_mhz < p0_info->min_mhz) {
vf_point->host_mhz = p0_info->min_mhz;
}

View File

@@ -59,7 +59,7 @@ static int getslaveclk_prog_1x_master(struct gk20a *g,
struct clk_prog_1x_master *p1xmaster,
u8 slave_clk_domain,
u16 *pclkmhz,
u16 masterclkmhz);
u16 masterclkmhz, u8 *ratio);
static int _clk_progs_pmudatainit(struct gk20a *g,
struct boardobjgrp *pboardobjgrp,
@@ -1298,7 +1298,7 @@ done:
static int getslaveclk_prog_1x_master(struct gk20a *g,
struct nvgpu_clk_pmupstate *pclk,
struct clk_prog_1x_master *p1xmaster,
u8 slave_clk_domain, u16 *pclkmhz, u16 masterclkmhz
u8 slave_clk_domain, u16 *pclkmhz, u16 masterclkmhz, u8 *ratio
)
{
struct nvgpu_clk_progs *pclkprogobjs;
@@ -1362,6 +1362,7 @@ static int getslaveclk_prog_1x_master(struct gk20a *g,
*pclkmhz = (masterclkmhz * pslaveents->ratio)/100U;
/* Floor/Quantize all the slave clocks to the multiple of step size*/
*pclkmhz = (*pclkmhz / FREQ_STEP_SIZE_MHZ) * FREQ_STEP_SIZE_MHZ;
*ratio = pslaveents->ratio;
} else {
/* only support ratio for now */
return -EINVAL;

View File

@@ -47,7 +47,7 @@ typedef int vf_lookup(struct gk20a *g, struct nvgpu_clk_pmupstate *pclk,
typedef int get_slaveclk(struct gk20a *g, struct nvgpu_clk_pmupstate *pclk,
struct clk_prog_1x_master *p1xmaster,
u8 slave_clk_domain_idx, u16 *pclkmhz,
u16 masterclkmhz);
u16 masterclkmhz, u8 *ratio);
typedef int get_fpoints(struct gk20a *g, struct nvgpu_clk_pmupstate *pclk,
struct clk_prog_1x_master *p1xmaster,