summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/nvgpu/clk/clk_arb.c
diff options
context:
space:
mode:
authorDavid Nieto <dmartineznie@nvidia.com>2016-11-11 13:02:34 -0500
committerDeepak Nibade <dnibade@nvidia.com>2016-12-27 04:56:53 -0500
commit7e2d79cd65cd1c0dc32b161f6309d51e4bd5b630 (patch)
tree50dc7a81f24e23030251a9f5bd3a7a1e2cc6f259 /drivers/gpu/nvgpu/clk/clk_arb.c
parent26265b997447c8c1fddac6a904ac4b6ef2b2f3b5 (diff)
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>
Diffstat (limited to 'drivers/gpu/nvgpu/clk/clk_arb.c')
-rw-r--r--drivers/gpu/nvgpu/clk/clk_arb.c60
1 files changed, 49 insertions, 11 deletions
diff --git a/drivers/gpu/nvgpu/clk/clk_arb.c b/drivers/gpu/nvgpu/clk/clk_arb.c
index 7c22a83d..3f35fac7 100644
--- a/drivers/gpu/nvgpu/clk/clk_arb.c
+++ b/drivers/gpu/nvgpu/clk/clk_arb.c
@@ -503,6 +503,7 @@ static int nvgpu_clk_arb_update_vf_table(struct nvgpu_clk_arb *arb)
503 503
504 struct clk_set_info *p5_info, *p0_info; 504 struct clk_set_info *p5_info, *p0_info;
505 505
506
506 table = ACCESS_ONCE(arb->current_vf_table); 507 table = ACCESS_ONCE(arb->current_vf_table);
507 /* make flag visible when all data has resolved in the tables */ 508 /* make flag visible when all data has resolved in the tables */
508 smp_rmb(); 509 smp_rmb();
@@ -512,11 +513,18 @@ static int nvgpu_clk_arb_update_vf_table(struct nvgpu_clk_arb *arb)
512 513
513 /* Get allowed memory ranges */ 514 /* Get allowed memory ranges */
514 if (nvgpu_clk_arb_get_arbiter_clk_range(g, NVGPU_GPU_CLK_DOMAIN_GPC2CLK, 515 if (nvgpu_clk_arb_get_arbiter_clk_range(g, NVGPU_GPU_CLK_DOMAIN_GPC2CLK,
515 &gpc2clk_min, &gpc2clk_max) < 0) 516 &gpc2clk_min,
517 &gpc2clk_max) < 0) {
518 gk20a_err(dev_from_gk20a(g),
519 "failed to fetch GPC2CLK range");
516 goto exit_vf_table; 520 goto exit_vf_table;
521 }
517 if (nvgpu_clk_arb_get_arbiter_clk_range(g, NVGPU_GPU_CLK_DOMAIN_MCLK, 522 if (nvgpu_clk_arb_get_arbiter_clk_range(g, NVGPU_GPU_CLK_DOMAIN_MCLK,
518 &mclk_min, &mclk_max) < 0) 523 &mclk_min, &mclk_max) < 0) {
524 gk20a_err(dev_from_gk20a(g),
525 "failed to fetch MCLK range");
519 goto exit_vf_table; 526 goto exit_vf_table;
527 }
520 528
521 if (clk_domain_get_f_points(arb->g, NVGPU_GPU_CLK_DOMAIN_GPC2CLK, 529 if (clk_domain_get_f_points(arb->g, NVGPU_GPU_CLK_DOMAIN_GPC2CLK,
522 &table->gpc2clk_num_points, arb->gpc2clk_f_points)) { 530 &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)
524 "failed to fetch GPC2CLK frequency points"); 532 "failed to fetch GPC2CLK frequency points");
525 goto exit_vf_table; 533 goto exit_vf_table;
526 } 534 }
535
536 table->gpc2clk_num_points = MAX_F_POINTS;
537 table->mclk_num_points = MAX_F_POINTS;
538
527 if (clk_domain_get_f_points(arb->g, NVGPU_GPU_CLK_DOMAIN_MCLK, 539 if (clk_domain_get_f_points(arb->g, NVGPU_GPU_CLK_DOMAIN_MCLK,
528 &table->mclk_num_points, arb->mclk_f_points)) { 540 &table->mclk_num_points, arb->mclk_f_points)) {
529 gk20a_err(dev_from_gk20a(g), 541 gk20a_err(dev_from_gk20a(g),
530 "failed to fetch MCLK frequency points"); 542 "failed to fetch MCLK frequency points");
531 goto exit_vf_table; 543 goto exit_vf_table;
532 } 544 }
545 if (!table->mclk_num_points || !table->gpc2clk_num_points) {
546 gk20a_err(dev_from_gk20a(g),
547 "empty queries to f points mclk %d gpc2clk %d",
548 table->mclk_num_points, table->gpc2clk_num_points);
549 status = -EINVAL;
550 goto exit_vf_table;
551 }
533 552
534 memset(table->mclk_points, 0, 553 memset(table->mclk_points, 0,
535 table->mclk_num_points*sizeof(struct nvgpu_clk_vf_point)); 554 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)
538 557
539 p5_info = pstate_get_clk_set_info(g, 558 p5_info = pstate_get_clk_set_info(g,
540 CTRL_PERF_PSTATE_P5, clkwhich_mclk); 559 CTRL_PERF_PSTATE_P5, clkwhich_mclk);
541 if (!p5_info) 560 if (!p5_info) {
561 gk20a_err(dev_from_gk20a(g),
562 "failed to get MCLK P5 info");
542 goto exit_vf_table; 563 goto exit_vf_table;
543 564 }
544 p0_info = pstate_get_clk_set_info(g, 565 p0_info = pstate_get_clk_set_info(g,
545 CTRL_PERF_PSTATE_P0, clkwhich_mclk); 566 CTRL_PERF_PSTATE_P0, clkwhich_mclk);
546 if (!p0_info) 567 if (!p0_info) {
568 gk20a_err(dev_from_gk20a(g),
569 "failed to get MCLK P0 info");
547 goto exit_vf_table; 570 goto exit_vf_table;
571 }
548 572
549 for (i = 0, j = 0, num_points = 0, clk_cur = 0; 573 for (i = 0, j = 0, num_points = 0, clk_cur = 0;
550 i < table->mclk_num_points; i++) { 574 i < table->mclk_num_points; i++) {
@@ -600,6 +624,8 @@ static int nvgpu_clk_arb_update_vf_table(struct nvgpu_clk_arb *arb)
600 CTRL_PERF_PSTATE_P5, clkwhich_gpc2clk); 624 CTRL_PERF_PSTATE_P5, clkwhich_gpc2clk);
601 if (!p5_info) { 625 if (!p5_info) {
602 status = -EINVAL; 626 status = -EINVAL;
627 gk20a_err(dev_from_gk20a(g),
628 "failed to get GPC2CLK P5 info");
603 goto exit_vf_table; 629 goto exit_vf_table;
604 } 630 }
605 631
@@ -607,12 +633,14 @@ static int nvgpu_clk_arb_update_vf_table(struct nvgpu_clk_arb *arb)
607 CTRL_PERF_PSTATE_P0, clkwhich_gpc2clk); 633 CTRL_PERF_PSTATE_P0, clkwhich_gpc2clk);
608 if (!p0_info) { 634 if (!p0_info) {
609 status = -EINVAL; 635 status = -EINVAL;
636 gk20a_err(dev_from_gk20a(g),
637 "failed to get GPC2CLK P0 info");
610 goto exit_vf_table; 638 goto exit_vf_table;
611 } 639 }
612 640
613 /* GPC2CLK needs to be checked in two passes. The first determines the 641 /* GPC2CLK needs to be checked in two passes. The first determines the
614 * relationships between GPC2CLK, SYS2CLK and XBAR2CLK, while the 642 * relationships between GPC2CLK, SYS2CLK and XBAR2CLK, while the
615 * second verifies that the clocks minimum DVCO is satisfied and sets 643 * second verifies that the clocks minimum is satisfied and sets
616 * the voltages 644 * the voltages
617 */ 645 */
618 for (i = 0, j = 0, num_points = 0, clk_cur = 0; 646 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)
669 clkwhich_sys2clk); 697 clkwhich_sys2clk);
670 if (!p5_info) { 698 if (!p5_info) {
671 status = -EINVAL; 699 status = -EINVAL;
700 gk20a_err(dev_from_gk20a(g),
701 "failed to get SYS2CLK P5 info");
672 goto exit_vf_table; 702 goto exit_vf_table;
673 } 703 }
674 /* sys2clk below DVCO min, need to find correct clock */ 704
705 /* sys2clk below clk min, need to find correct clock */
675 if (table->gpc2clk_points[i].sys_mhz < p5_info->min_mhz) { 706 if (table->gpc2clk_points[i].sys_mhz < p5_info->min_mhz) {
676 for (j = i + 1; j < table->gpc2clk_num_points; j++) { 707 for (j = i + 1; j < table->gpc2clk_num_points; j++) {
677 708
@@ -693,6 +724,8 @@ static int nvgpu_clk_arb_update_vf_table(struct nvgpu_clk_arb *arb)
693 } 724 }
694 /* no VF exists that satisfies condition */ 725 /* no VF exists that satisfies condition */
695 if (j == table->gpc2clk_num_points) { 726 if (j == table->gpc2clk_num_points) {
727 gk20a_err(dev_from_gk20a(g),
728 "NO SYS2CLK VF point possible");
696 status = -EINVAL; 729 status = -EINVAL;
697 goto exit_vf_table; 730 goto exit_vf_table;
698 } 731 }
@@ -704,10 +737,12 @@ static int nvgpu_clk_arb_update_vf_table(struct nvgpu_clk_arb *arb)
704 clkwhich_xbar2clk); 737 clkwhich_xbar2clk);
705 if (!p5_info) { 738 if (!p5_info) {
706 status = -EINVAL; 739 status = -EINVAL;
740 gk20a_err(dev_from_gk20a(g),
741 "failed to get SYS2CLK P5 info");
707 goto exit_vf_table; 742 goto exit_vf_table;
708 } 743 }
709 744
710 /* xbar2clk below DVCO min, need to find correct clock */ 745 /* xbar2clk below clk min, need to find correct clock */
711 if (table->gpc2clk_points[i].xbar_mhz < p5_info->min_mhz) { 746 if (table->gpc2clk_points[i].xbar_mhz < p5_info->min_mhz) {
712 for (j = i; j < table->gpc2clk_num_points; j++) { 747 for (j = i; j < table->gpc2clk_num_points; j++) {
713 if (table->gpc2clk_points[j].xbar_mhz >= 748 if (table->gpc2clk_points[j].xbar_mhz >=
@@ -728,6 +763,8 @@ static int nvgpu_clk_arb_update_vf_table(struct nvgpu_clk_arb *arb)
728 /* no VF exists that satisfies condition */ 763 /* no VF exists that satisfies condition */
729 if (j == table->gpc2clk_num_points) { 764 if (j == table->gpc2clk_num_points) {
730 status = -EINVAL; 765 status = -EINVAL;
766 gk20a_err(dev_from_gk20a(g),
767 "NO XBAR2CLK VF point possible");
731 768
732 goto exit_vf_table; 769 goto exit_vf_table;
733 } 770 }
@@ -1244,9 +1281,10 @@ static u8 nvgpu_clk_arb_find_vf_point(struct nvgpu_clk_arb *arb,
1244 1281
1245 if (!table) 1282 if (!table)
1246 continue; 1283 continue;
1247 if ((!table->gpc2clk_num_points) || (!table->mclk_num_points)) 1284 if ((!table->gpc2clk_num_points) || (!table->mclk_num_points)) {
1285 gk20a_err(dev_from_gk20a(arb->g), "found empty table");
1248 goto find_exit; 1286 goto find_exit;
1249 1287 }
1250 /* First we check MCLK to find out which PSTATE we are 1288 /* First we check MCLK to find out which PSTATE we are
1251 * are requesting, and from there try to find the minimum 1289 * are requesting, and from there try to find the minimum
1252 * GPC2CLK on the same PSTATE that satisfies the request. 1290 * GPC2CLK on the same PSTATE that satisfies the request.
@@ -1304,7 +1342,7 @@ recalculate_vf_point:
1304 gpc2clk_voltuv_sram = 1342 gpc2clk_voltuv_sram =
1305 table->gpc2clk_points[index-1]. 1343 table->gpc2clk_points[index-1].
1306 uvolt_sram; 1344 uvolt_sram;
1307 } else if (index_mclk == table->mclk_num_points - 1) { 1345 } else if (index_mclk >= table->mclk_num_points - 1) {
1308 /* There is no available combination of MCLK 1346 /* There is no available combination of MCLK
1309 * and GPC2CLK, we need to fail this 1347 * and GPC2CLK, we need to fail this
1310 */ 1348 */