diff options
Diffstat (limited to 'drivers/gpu/nvgpu')
-rw-r--r-- | drivers/gpu/nvgpu/clk/clk_arb.c | 60 |
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 | */ |