diff --git a/drivers/gpu/nvgpu/clk/clk.c b/drivers/gpu/nvgpu/clk/clk.c index 08da3dee2..fe24d8f72 100644 --- a/drivers/gpu/nvgpu/clk/clk.c +++ b/drivers/gpu/nvgpu/clk/clk.c @@ -990,7 +990,8 @@ int nvgpu_clk_set_boot_fll_clk_tu10x(struct gk20a *g) struct clk_set_info *p0_clk_set_info; struct clk_domain *pclk_domain; int status = 0; - u8 i = 0; + u8 i = 0, gpcclk_domain=0; + u32 gpcclk_clkmhz=0, gpcclk_voltuv=0; (void) memset(&change_input, 0, sizeof(struct ctrl_perf_change_seq_change_input)); @@ -1003,17 +1004,19 @@ int nvgpu_clk_set_boot_fll_clk_tu10x(struct gk20a *g) switch (pclk_domain->api_domain) { case CTRL_CLK_DOMAIN_GPCCLK: + gpcclk_domain = i; + gpcclk_clkmhz = p0_clk_set_info->max_mhz; + change_input.clk[i].clk_freq_khz = + p0_clk_set_info->max_mhz * 1000U; + change_input.clk_domains_mask.super.data[0] |= (u32) BIT(i); + break; case CTRL_CLK_DOMAIN_XBARCLK: case CTRL_CLK_DOMAIN_SYSCLK: case CTRL_CLK_DOMAIN_NVDCLK: case CTRL_CLK_DOMAIN_HOSTCLK: change_input.clk[i].clk_freq_khz = p0_clk_set_info->max_mhz * 1000U; - change_input.clk_domains_mask.super.data[0] |= (u32) BIT(i); - - nvgpu_pmu_dbg(g, "domain - 0x%x freq %d", pclk_domain->api_domain, - change_input.clk[i].clk_freq_khz); break; default: nvgpu_pmu_dbg(g, "Fixed clock domain"); @@ -1024,8 +1027,12 @@ int nvgpu_clk_set_boot_fll_clk_tu10x(struct gk20a *g) change_input.pstate_index = 0U; change_input.flags = CTRL_PERF_CHANGE_SEQ_CHANGE_FORCE; change_input.vf_points_cache_counter = 0xFFFFFFFFU; - change_input.volt[0].voltage_uv = 900U*1000U; - change_input.volt[0].voltage_min_noise_unaware_uv = 900U*1000U; + + status = clk_domain_freq_to_volt(g, gpcclk_domain, + &gpcclk_clkmhz, &gpcclk_voltuv, CTRL_VOLT_DOMAIN_LOGIC); + + change_input.volt[0].voltage_uv = gpcclk_voltuv; + change_input.volt[0].voltage_min_noise_unaware_uv = gpcclk_voltuv; change_input.volt_rails_mask.super.data[0] = 1U; /* RPC to PMU to queue to execute change sequence request*/ @@ -1046,6 +1053,32 @@ int nvgpu_clk_set_boot_fll_clk_tu10x(struct gk20a *g) return status; } +int 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 = 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); + } + *pvoltuv = rpc.output.value; + return status; +} + int clk_domain_get_f_or_v( struct gk20a *g, u32 clkapidomain, diff --git a/drivers/gpu/nvgpu/clk/clk.h b/drivers/gpu/nvgpu/clk/clk.h index b9b66dcc8..52ef4ec2c 100644 --- a/drivers/gpu/nvgpu/clk/clk.h +++ b/drivers/gpu/nvgpu/clk/clk.h @@ -133,6 +133,13 @@ int clk_domain_get_f_or_v( u32 *pvoltuv, u8 railidx ); +int clk_domain_freq_to_volt( + struct gk20a *g, + u8 clkdomain_idx, + u32 *pclkmhz, + u32 *pvoltuv, + u8 railidx +); int clk_get_fll_clks(struct gk20a *g, struct set_fll_clk *setfllclk); int clk_set_fll_clks(struct gk20a *g, struct set_fll_clk *setfllclk); int clk_pmu_freq_controller_load(struct gk20a *g, bool bload, u8 bit_idx); diff --git a/drivers/gpu/nvgpu/include/nvgpu/pmuif/gpmuifclk.h b/drivers/gpu/nvgpu/include/nvgpu/pmuif/gpmuifclk.h index e977caa10..411f2ddd7 100644 --- a/drivers/gpu/nvgpu/include/nvgpu/pmuif/gpmuifclk.h +++ b/drivers/gpu/nvgpu/include/nvgpu/pmuif/gpmuifclk.h @@ -551,6 +551,9 @@ NV_PMU_BOARDOBJ_GRP_SET_MAKE_E32(clk, clk_freq_controller); #define NV_PMU_CLK_RPC_ID_CLK_VF_CHANGE_INJECT (0x00000000U) #define NV_PMU_CLK_RPC_ID_CLK_FREQ_EFF_AVG (0x00000002U) +#define NV_PMU_RPC_ID_CLK_CLK_DOMAIN_35_PROG_VOLT_TO_FREQ (0x00000002U) +#define NV_PMU_RPC_ID_CLK_CLK_DOMAIN_35_PROG_FREQ_TO_VOLT (0x00000003U) + struct nv_pmu_clk_cmd_rpc { u8 cmd_type; u8 pad[3]; @@ -670,4 +673,16 @@ union nv_pmu_clk_clk_freq_domain_boardobj_set_union { }; NV_PMU_BOARDOBJ_GRP_SET_MAKE_E32(clk, clk_freq_domain); + +struct nv_pmu_rpc_clk_domain_35_prog_freq_to_volt { + /*[IN/OUT] Must be first field in RPC structure */ + struct nv_pmu_rpc_header hdr; + u8 clk_domain_idx; + u8 volt_rail_idx; + u8 voltage_type; + struct ctrl_clk_vf_input input; + struct ctrl_clk_vf_output output; + u32 scratch[1]; +}; + #endif /*NVGPU_PMUIF_GPMUIFCLK_H*/