diff --git a/drivers/gpu/nvgpu/common/pmu/clk/clk.c b/drivers/gpu/nvgpu/common/pmu/clk/clk.c index 6082494f1..7f5357b23 100644 --- a/drivers/gpu/nvgpu/common/pmu/clk/clk.c +++ b/drivers/gpu/nvgpu/common/pmu/clk/clk.c @@ -34,6 +34,7 @@ #include #include #include +#include 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; } diff --git a/drivers/gpu/nvgpu/common/pmu/clk/clk_domain.c b/drivers/gpu/nvgpu/common/pmu/clk/clk_domain.c index 80fed16a1..10e96d175 100644 --- a/drivers/gpu/nvgpu/common/pmu/clk/clk_domain.c +++ b/drivers/gpu/nvgpu/common/pmu/clk/clk_domain.c @@ -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; } diff --git a/drivers/gpu/nvgpu/common/pmu/clk/clk_prog.c b/drivers/gpu/nvgpu/common/pmu/clk/clk_prog.c index 216982e2c..5c0e22f95 100644 --- a/drivers/gpu/nvgpu/common/pmu/clk/clk_prog.c +++ b/drivers/gpu/nvgpu/common/pmu/clk/clk_prog.c @@ -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; diff --git a/drivers/gpu/nvgpu/common/pmu/clk/clk_prog.h b/drivers/gpu/nvgpu/common/pmu/clk/clk_prog.h index 21f60cb42..e1a417529 100644 --- a/drivers/gpu/nvgpu/common/pmu/clk/clk_prog.h +++ b/drivers/gpu/nvgpu/common/pmu/clk/clk_prog.h @@ -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,