mirror of
git://nv-tegra.nvidia.com/linux-nvgpu.git
synced 2025-12-25 02:52:51 +03:00
gpu: nvgpu: set gv10x boot clock
- Set gv10x boot gpcclk to 952 MHz - Created ops to set gv10x boot gpcclk instead of using clk arbiter to set clocks Bug 200399373 Change-Id: Ice5956f79d4a52abf455506a798cf7b914f3d3ed Signed-off-by: Vaikundanathan S <vaikuns@nvidia.com> Signed-off-by: Mahantesh Kumbar <mkumbar@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/1700788 Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
This commit is contained in:
committed by
Tejal Kudav
parent
14d8430697
commit
0545465255
@@ -182,6 +182,7 @@ u32 clk_pmu_vin_load(struct gk20a *g)
|
||||
(u32)sizeof(struct pmu_hdr);
|
||||
|
||||
cmd.cmd.clk.cmd_type = NV_PMU_CLK_CMD_ID_RPC;
|
||||
cmd.cmd.clk.generic.b_perf_daemon_cmd =false;
|
||||
|
||||
payload.in.buf = (u8 *)&rpccall;
|
||||
payload.in.size = (u32)sizeof(struct nv_pmu_clk_rpc);
|
||||
@@ -547,6 +548,156 @@ u32 clk_domain_print_vf_table(struct gk20a *g, u32 clkapidomain)
|
||||
return status;
|
||||
}
|
||||
|
||||
static int clk_program_fllclks(struct gk20a *g, struct change_fll_clk *fllclk)
|
||||
{
|
||||
int status = -EINVAL;
|
||||
struct clk_domain *pdomain;
|
||||
u8 i;
|
||||
struct clk_pmupstate *pclk = &g->clk_pmu;
|
||||
u16 clkmhz = 0;
|
||||
struct clk_domain_3x_master *p3xmaster;
|
||||
struct clk_domain_3x_slave *p3xslave;
|
||||
unsigned long slaveidxmask;
|
||||
struct set_fll_clk setfllclk;
|
||||
|
||||
if (fllclk->api_clk_domain != CTRL_CLK_DOMAIN_GPCCLK)
|
||||
return -EINVAL;
|
||||
if (fllclk->voltuv == 0)
|
||||
return -EINVAL;
|
||||
if (fllclk->clkmhz == 0)
|
||||
return -EINVAL;
|
||||
|
||||
setfllclk.voltuv = fllclk->voltuv;
|
||||
setfllclk.gpc2clkmhz = fllclk->clkmhz;
|
||||
|
||||
BOARDOBJGRP_FOR_EACH(&(pclk->clk_domainobjs.super.super),
|
||||
struct clk_domain *, pdomain, i) {
|
||||
|
||||
if (pdomain->api_domain == fllclk->api_clk_domain) {
|
||||
|
||||
if (!pdomain->super.implements(g, &pdomain->super,
|
||||
CTRL_CLK_CLK_DOMAIN_TYPE_3X_MASTER)) {
|
||||
status = -EINVAL;
|
||||
goto done;
|
||||
}
|
||||
p3xmaster = (struct clk_domain_3x_master *)pdomain;
|
||||
slaveidxmask = p3xmaster->slave_idxs_mask;
|
||||
for_each_set_bit(i, &slaveidxmask, 32) {
|
||||
p3xslave = (struct clk_domain_3x_slave *)
|
||||
CLK_CLK_DOMAIN_GET(pclk, i);
|
||||
if ((p3xslave->super.super.super.api_domain !=
|
||||
CTRL_CLK_DOMAIN_XBARCLK) &&
|
||||
(p3xslave->super.super.super.api_domain !=
|
||||
CTRL_CLK_DOMAIN_SYSCLK))
|
||||
continue;
|
||||
clkmhz = 0;
|
||||
status = p3xslave->clkdomainclkgetslaveclk(g,
|
||||
pclk,
|
||||
(struct clk_domain *)p3xslave,
|
||||
&clkmhz,
|
||||
fllclk->clkmhz);
|
||||
if (status) {
|
||||
status = -EINVAL;
|
||||
goto done;
|
||||
}
|
||||
if (p3xslave->super.super.super.api_domain ==
|
||||
CTRL_CLK_DOMAIN_XBARCLK)
|
||||
setfllclk.xbar2clkmhz = clkmhz;
|
||||
if (p3xslave->super.super.super.api_domain ==
|
||||
CTRL_CLK_DOMAIN_SYSCLK)
|
||||
setfllclk.sys2clkmhz = clkmhz;
|
||||
}
|
||||
}
|
||||
}
|
||||
/*set regime ids */
|
||||
status = get_regime_id(g, CTRL_CLK_DOMAIN_GPCCLK,
|
||||
&setfllclk.current_regime_id_gpc);
|
||||
if (status)
|
||||
goto done;
|
||||
|
||||
setfllclk.target_regime_id_gpc = find_regime_id(g,
|
||||
CTRL_CLK_DOMAIN_GPCCLK, setfllclk.gpc2clkmhz);
|
||||
|
||||
status = get_regime_id(g, CTRL_CLK_DOMAIN_SYSCLK,
|
||||
&setfllclk.current_regime_id_sys);
|
||||
if (status)
|
||||
goto done;
|
||||
|
||||
setfllclk.target_regime_id_sys = find_regime_id(g,
|
||||
CTRL_CLK_DOMAIN_SYSCLK, setfllclk.sys2clkmhz);
|
||||
|
||||
status = get_regime_id(g, CTRL_CLK_DOMAIN_XBARCLK,
|
||||
&setfllclk.current_regime_id_xbar);
|
||||
if (status)
|
||||
goto done;
|
||||
|
||||
setfllclk.target_regime_id_xbar = find_regime_id(g,
|
||||
CTRL_CLK_DOMAIN_XBARCLK, setfllclk.xbar2clkmhz);
|
||||
|
||||
status = clk_pmu_vf_inject(g, &setfllclk);
|
||||
|
||||
if (status)
|
||||
nvgpu_err(g,
|
||||
"vf inject to change clk failed");
|
||||
|
||||
/* save regime ids */
|
||||
status = set_regime_id(g, CTRL_CLK_DOMAIN_XBARCLK,
|
||||
setfllclk.target_regime_id_xbar);
|
||||
if (status)
|
||||
goto done;
|
||||
|
||||
status = set_regime_id(g, CTRL_CLK_DOMAIN_GPCCLK,
|
||||
setfllclk.target_regime_id_gpc);
|
||||
if (status)
|
||||
goto done;
|
||||
|
||||
status = set_regime_id(g, CTRL_CLK_DOMAIN_SYSCLK,
|
||||
setfllclk.target_regime_id_sys);
|
||||
if (status)
|
||||
goto done;
|
||||
done:
|
||||
return status;
|
||||
}
|
||||
|
||||
u32 nvgpu_clk_set_boot_fll_clk_gv10x(struct gk20a *g)
|
||||
{
|
||||
int status;
|
||||
struct change_fll_clk bootfllclk;
|
||||
u16 gpcclk_clkmhz = BOOT_GPCCLK_MHZ;
|
||||
u32 gpcclk_voltuv = 0;
|
||||
u32 voltuv = 0;
|
||||
|
||||
status = clk_vf_point_cache(g);
|
||||
if (status) {
|
||||
nvgpu_err(g,"caching failed");
|
||||
return status;
|
||||
}
|
||||
|
||||
status = clk_domain_get_f_or_v(g, CTRL_CLK_DOMAIN_GPCCLK,
|
||||
&gpcclk_clkmhz, &gpcclk_voltuv, CTRL_VOLT_DOMAIN_LOGIC);
|
||||
if (status) {
|
||||
nvgpu_err(g,"failed 1");
|
||||
return status;
|
||||
}
|
||||
|
||||
voltuv = gpcclk_voltuv;
|
||||
|
||||
status = volt_set_voltage(g, voltuv, 0);
|
||||
if (status)
|
||||
nvgpu_err(g,
|
||||
"attempt to set boot voltage failed %d",
|
||||
voltuv);
|
||||
|
||||
bootfllclk.api_clk_domain = CTRL_CLK_DOMAIN_GPCCLK;
|
||||
bootfllclk.clkmhz = gpcclk_clkmhz;
|
||||
bootfllclk.voltuv = voltuv;
|
||||
status = clk_program_fllclks(g, &bootfllclk);
|
||||
if (status)
|
||||
nvgpu_err(g, "attempt to set boot gpcclk failed");
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
u32 clk_domain_get_f_or_v(
|
||||
struct gk20a *g,
|
||||
u32 clkapidomain,
|
||||
|
||||
@@ -35,9 +35,12 @@
|
||||
#define NV_PERF_DOMAIN_4X_CLOCK_DOMAIN_SKIP 0x10
|
||||
#define NV_PERF_DOMAIN_4X_CLOCK_DOMAIN_MASK 0x1F
|
||||
#define NV_PERF_DOMAIN_4X_CLOCK_DOMAIN_SHIFT 0
|
||||
#define BOOT_GPCCLK_MHZ 952
|
||||
|
||||
struct gk20a;
|
||||
|
||||
int clk_set_boot_fll_clk(struct gk20a *g);
|
||||
|
||||
/* clock related defines for GPUs supporting clock control from pmu*/
|
||||
struct clk_pmupstate {
|
||||
struct avfsvinobjs avfs_vinobjs;
|
||||
@@ -56,6 +59,12 @@ struct clockentry {
|
||||
u32 api_clk_domain;
|
||||
};
|
||||
|
||||
struct change_fll_clk {
|
||||
u32 api_clk_domain;
|
||||
u16 clkmhz;
|
||||
u32 voltuv;
|
||||
};
|
||||
|
||||
struct set_fll_clk {
|
||||
u32 voltuv;
|
||||
u16 gpc2clkmhz;
|
||||
@@ -133,4 +142,5 @@ u32 nvgpu_clk_vf_change_inject_data_fill_gv10x(struct gk20a *g,
|
||||
u32 nvgpu_clk_vf_change_inject_data_fill_gp10x(struct gk20a *g,
|
||||
struct nv_pmu_clk_rpc *rpccall,
|
||||
struct set_fll_clk *setfllclk);
|
||||
u32 nvgpu_clk_set_boot_fll_clk_gv10x(struct gk20a *g);
|
||||
#endif
|
||||
|
||||
@@ -1313,6 +1313,8 @@ static int nvgpu_init_pmu_fw_ver_ops(struct nvgpu_pmu *pmu)
|
||||
nvgpu_clk_vf_change_inject_data_fill_gv10x;
|
||||
g->ops.pmu_ver.clk.perf_pmu_vfe_load =
|
||||
perf_pmu_vfe_load_gv10x;
|
||||
g->ops.pmu_ver.clk.clk_set_boot_clk =
|
||||
nvgpu_clk_set_boot_fll_clk_gv10x;
|
||||
} else {
|
||||
g->ops.pmu_ver.get_pmu_init_msg_pmu_queue_params =
|
||||
get_pmu_init_msg_pmu_queue_params_v4;
|
||||
@@ -1484,8 +1486,6 @@ static int nvgpu_init_pmu_fw_ver_ops(struct nvgpu_pmu *pmu)
|
||||
clk_avfs_get_vin_cal_fuse_v10;
|
||||
g->ops.pmu_ver.clk.clk_vf_change_inject_data_fill =
|
||||
nvgpu_clk_vf_change_inject_data_fill_gp10x;
|
||||
g->ops.pmu_ver.clk.clk_set_boot_clk =
|
||||
nvgpu_clk_set_boot_fll_clk_gv10x;
|
||||
g->ops.pmu_ver.clk.perf_pmu_vfe_load =
|
||||
perf_pmu_vfe_load;
|
||||
break;
|
||||
|
||||
@@ -281,10 +281,14 @@ int gk20a_finalize_poweron(struct gk20a *g)
|
||||
}
|
||||
}
|
||||
|
||||
err = nvgpu_clk_arb_init_arbiter(g);
|
||||
if (err) {
|
||||
nvgpu_err(g, "failed to init clk arb");
|
||||
goto done;
|
||||
if (g->ops.pmu_ver.clk.clk_set_boot_clk && nvgpu_is_enabled(g, NVGPU_PMU_PSTATE))
|
||||
g->ops.pmu_ver.clk.clk_set_boot_clk(g);
|
||||
else {
|
||||
err = nvgpu_clk_arb_init_arbiter(g);
|
||||
if (err) {
|
||||
nvgpu_err(g, "failed to init clk arb");
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
err = gk20a_init_therm_support(g);
|
||||
|
||||
@@ -820,6 +820,7 @@ struct gpu_ops {
|
||||
struct nv_pmu_clk_rpc *rpccall,
|
||||
struct set_fll_clk *setfllclk);
|
||||
u32 (*perf_pmu_vfe_load)(struct gk20a *g);
|
||||
u32 (*clk_set_boot_clk)(struct gk20a *g);
|
||||
}clk;
|
||||
} pmu_ver;
|
||||
struct {
|
||||
|
||||
@@ -448,6 +448,12 @@ struct nv_pmu_clk_cmd_rpc {
|
||||
struct nv_pmu_allocation request;
|
||||
};
|
||||
|
||||
struct nv_pmu_clk_cmd_generic {
|
||||
u8 cmd_type;
|
||||
bool b_perf_daemon_cmd;
|
||||
u8 pad[2];
|
||||
};
|
||||
|
||||
#define NV_PMU_CLK_CMD_RPC_ALLOC_OFFSET \
|
||||
(offsetof(struct nv_pmu_clk_cmd_rpc, request))
|
||||
|
||||
@@ -455,6 +461,7 @@ struct nv_pmu_clk_cmd {
|
||||
union {
|
||||
u8 cmd_type;
|
||||
struct nv_pmu_boardobj_cmd_grp grp_set;
|
||||
struct nv_pmu_clk_cmd_generic generic;
|
||||
struct nv_pmu_clk_cmd_rpc rpc;
|
||||
struct nv_pmu_boardobj_cmd_grp grp_get_status;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user