mirror of
git://nv-tegra.nvidia.com/linux-nvgpu.git
synced 2025-12-24 02:22:34 +03:00
gpu: nvgpu: fix CLFC arbiter vf table update
(1) Adding additional debug in case of VF update failure (2) The length of the tables must be re-initialized prior to requesting the vf table update JIRA: DNVGPU-193 Change-Id: Id5a369359bc5f52ee58da539bfc3ec1ec7887de1 Signed-off-by: David Nieto <dmartineznie@nvidia.com> Reviewed-on: http://git-master/r/1252061 (cherry picked from commit dfb6fec02f8e3ff6a22bbea000347923b0306018) Reviewed-on: http://git-master/r/1274547 Reviewed-by: Automatic_Commit_Validation_User Tested-by: Thomas Fleury <tfleury@nvidia.com> Reviewed-by: Vijayakumar Subbu <vsubbu@nvidia.com> GVS: Gerrit_Virtual_Submit Reviewed-by: Terje Bergstrom <tbergstrom@nvidia.com>
This commit is contained in:
committed by
Deepak Nibade
parent
26265b9974
commit
7e2d79cd65
@@ -503,6 +503,7 @@ static int nvgpu_clk_arb_update_vf_table(struct nvgpu_clk_arb *arb)
|
||||
|
||||
struct clk_set_info *p5_info, *p0_info;
|
||||
|
||||
|
||||
table = ACCESS_ONCE(arb->current_vf_table);
|
||||
/* make flag visible when all data has resolved in the tables */
|
||||
smp_rmb();
|
||||
@@ -512,11 +513,18 @@ static int nvgpu_clk_arb_update_vf_table(struct nvgpu_clk_arb *arb)
|
||||
|
||||
/* Get allowed memory ranges */
|
||||
if (nvgpu_clk_arb_get_arbiter_clk_range(g, NVGPU_GPU_CLK_DOMAIN_GPC2CLK,
|
||||
&gpc2clk_min, &gpc2clk_max) < 0)
|
||||
&gpc2clk_min,
|
||||
&gpc2clk_max) < 0) {
|
||||
gk20a_err(dev_from_gk20a(g),
|
||||
"failed to fetch GPC2CLK range");
|
||||
goto exit_vf_table;
|
||||
}
|
||||
if (nvgpu_clk_arb_get_arbiter_clk_range(g, NVGPU_GPU_CLK_DOMAIN_MCLK,
|
||||
&mclk_min, &mclk_max) < 0)
|
||||
&mclk_min, &mclk_max) < 0) {
|
||||
gk20a_err(dev_from_gk20a(g),
|
||||
"failed to fetch MCLK range");
|
||||
goto exit_vf_table;
|
||||
}
|
||||
|
||||
if (clk_domain_get_f_points(arb->g, NVGPU_GPU_CLK_DOMAIN_GPC2CLK,
|
||||
&table->gpc2clk_num_points, arb->gpc2clk_f_points)) {
|
||||
@@ -524,12 +532,23 @@ static int nvgpu_clk_arb_update_vf_table(struct nvgpu_clk_arb *arb)
|
||||
"failed to fetch GPC2CLK frequency points");
|
||||
goto exit_vf_table;
|
||||
}
|
||||
|
||||
table->gpc2clk_num_points = MAX_F_POINTS;
|
||||
table->mclk_num_points = MAX_F_POINTS;
|
||||
|
||||
if (clk_domain_get_f_points(arb->g, NVGPU_GPU_CLK_DOMAIN_MCLK,
|
||||
&table->mclk_num_points, arb->mclk_f_points)) {
|
||||
gk20a_err(dev_from_gk20a(g),
|
||||
"failed to fetch MCLK frequency points");
|
||||
goto exit_vf_table;
|
||||
}
|
||||
if (!table->mclk_num_points || !table->gpc2clk_num_points) {
|
||||
gk20a_err(dev_from_gk20a(g),
|
||||
"empty queries to f points mclk %d gpc2clk %d",
|
||||
table->mclk_num_points, table->gpc2clk_num_points);
|
||||
status = -EINVAL;
|
||||
goto exit_vf_table;
|
||||
}
|
||||
|
||||
memset(table->mclk_points, 0,
|
||||
table->mclk_num_points*sizeof(struct nvgpu_clk_vf_point));
|
||||
@@ -538,13 +557,18 @@ static int nvgpu_clk_arb_update_vf_table(struct nvgpu_clk_arb *arb)
|
||||
|
||||
p5_info = pstate_get_clk_set_info(g,
|
||||
CTRL_PERF_PSTATE_P5, clkwhich_mclk);
|
||||
if (!p5_info)
|
||||
if (!p5_info) {
|
||||
gk20a_err(dev_from_gk20a(g),
|
||||
"failed to get MCLK P5 info");
|
||||
goto exit_vf_table;
|
||||
|
||||
}
|
||||
p0_info = pstate_get_clk_set_info(g,
|
||||
CTRL_PERF_PSTATE_P0, clkwhich_mclk);
|
||||
if (!p0_info)
|
||||
if (!p0_info) {
|
||||
gk20a_err(dev_from_gk20a(g),
|
||||
"failed to get MCLK P0 info");
|
||||
goto exit_vf_table;
|
||||
}
|
||||
|
||||
for (i = 0, j = 0, num_points = 0, clk_cur = 0;
|
||||
i < table->mclk_num_points; i++) {
|
||||
@@ -600,6 +624,8 @@ static int nvgpu_clk_arb_update_vf_table(struct nvgpu_clk_arb *arb)
|
||||
CTRL_PERF_PSTATE_P5, clkwhich_gpc2clk);
|
||||
if (!p5_info) {
|
||||
status = -EINVAL;
|
||||
gk20a_err(dev_from_gk20a(g),
|
||||
"failed to get GPC2CLK P5 info");
|
||||
goto exit_vf_table;
|
||||
}
|
||||
|
||||
@@ -607,12 +633,14 @@ static int nvgpu_clk_arb_update_vf_table(struct nvgpu_clk_arb *arb)
|
||||
CTRL_PERF_PSTATE_P0, clkwhich_gpc2clk);
|
||||
if (!p0_info) {
|
||||
status = -EINVAL;
|
||||
gk20a_err(dev_from_gk20a(g),
|
||||
"failed to get GPC2CLK P0 info");
|
||||
goto exit_vf_table;
|
||||
}
|
||||
|
||||
/* GPC2CLK needs to be checked in two passes. The first determines the
|
||||
* relationships between GPC2CLK, SYS2CLK and XBAR2CLK, while the
|
||||
* second verifies that the clocks minimum DVCO is satisfied and sets
|
||||
* second verifies that the clocks minimum is satisfied and sets
|
||||
* the voltages
|
||||
*/
|
||||
for (i = 0, j = 0, num_points = 0, clk_cur = 0;
|
||||
@@ -669,9 +697,12 @@ static int nvgpu_clk_arb_update_vf_table(struct nvgpu_clk_arb *arb)
|
||||
clkwhich_sys2clk);
|
||||
if (!p5_info) {
|
||||
status = -EINVAL;
|
||||
gk20a_err(dev_from_gk20a(g),
|
||||
"failed to get SYS2CLK P5 info");
|
||||
goto exit_vf_table;
|
||||
}
|
||||
/* sys2clk below DVCO min, need to find correct clock */
|
||||
|
||||
/* sys2clk below clk min, need to find correct clock */
|
||||
if (table->gpc2clk_points[i].sys_mhz < p5_info->min_mhz) {
|
||||
for (j = i + 1; j < table->gpc2clk_num_points; j++) {
|
||||
|
||||
@@ -693,6 +724,8 @@ static int nvgpu_clk_arb_update_vf_table(struct nvgpu_clk_arb *arb)
|
||||
}
|
||||
/* no VF exists that satisfies condition */
|
||||
if (j == table->gpc2clk_num_points) {
|
||||
gk20a_err(dev_from_gk20a(g),
|
||||
"NO SYS2CLK VF point possible");
|
||||
status = -EINVAL;
|
||||
goto exit_vf_table;
|
||||
}
|
||||
@@ -704,10 +737,12 @@ static int nvgpu_clk_arb_update_vf_table(struct nvgpu_clk_arb *arb)
|
||||
clkwhich_xbar2clk);
|
||||
if (!p5_info) {
|
||||
status = -EINVAL;
|
||||
gk20a_err(dev_from_gk20a(g),
|
||||
"failed to get SYS2CLK P5 info");
|
||||
goto exit_vf_table;
|
||||
}
|
||||
|
||||
/* xbar2clk below DVCO min, need to find correct clock */
|
||||
/* xbar2clk below clk min, need to find correct clock */
|
||||
if (table->gpc2clk_points[i].xbar_mhz < p5_info->min_mhz) {
|
||||
for (j = i; j < table->gpc2clk_num_points; j++) {
|
||||
if (table->gpc2clk_points[j].xbar_mhz >=
|
||||
@@ -728,6 +763,8 @@ static int nvgpu_clk_arb_update_vf_table(struct nvgpu_clk_arb *arb)
|
||||
/* no VF exists that satisfies condition */
|
||||
if (j == table->gpc2clk_num_points) {
|
||||
status = -EINVAL;
|
||||
gk20a_err(dev_from_gk20a(g),
|
||||
"NO XBAR2CLK VF point possible");
|
||||
|
||||
goto exit_vf_table;
|
||||
}
|
||||
@@ -1244,9 +1281,10 @@ static u8 nvgpu_clk_arb_find_vf_point(struct nvgpu_clk_arb *arb,
|
||||
|
||||
if (!table)
|
||||
continue;
|
||||
if ((!table->gpc2clk_num_points) || (!table->mclk_num_points))
|
||||
if ((!table->gpc2clk_num_points) || (!table->mclk_num_points)) {
|
||||
gk20a_err(dev_from_gk20a(arb->g), "found empty table");
|
||||
goto find_exit;
|
||||
|
||||
}
|
||||
/* First we check MCLK to find out which PSTATE we are
|
||||
* are requesting, and from there try to find the minimum
|
||||
* GPC2CLK on the same PSTATE that satisfies the request.
|
||||
@@ -1304,7 +1342,7 @@ recalculate_vf_point:
|
||||
gpc2clk_voltuv_sram =
|
||||
table->gpc2clk_points[index-1].
|
||||
uvolt_sram;
|
||||
} else if (index_mclk == table->mclk_num_points - 1) {
|
||||
} else if (index_mclk >= table->mclk_num_points - 1) {
|
||||
/* There is no available combination of MCLK
|
||||
* and GPC2CLK, we need to fail this
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user