mirror of
git://nv-tegra.nvidia.com/linux-nvgpu.git
synced 2025-12-25 02:52:51 +03:00
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:
committed by
mobile promotions
parent
2272e04861
commit
3ee12f5370
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user