summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/gpu/nvgpu/clk/clk_arb.c46
1 files changed, 29 insertions, 17 deletions
diff --git a/drivers/gpu/nvgpu/clk/clk_arb.c b/drivers/gpu/nvgpu/clk/clk_arb.c
index 1b974d17..f3d6cfab 100644
--- a/drivers/gpu/nvgpu/clk/clk_arb.c
+++ b/drivers/gpu/nvgpu/clk/clk_arb.c
@@ -83,6 +83,7 @@ struct nvgpu_clk_arb {
83 struct llist_head requests; 83 struct llist_head requests;
84 84
85 struct gk20a *g; 85 struct gk20a *g;
86 int status;
86 87
87 struct nvgpu_clk_arb_target actual_pool[2]; 88 struct nvgpu_clk_arb_target actual_pool[2];
88 struct nvgpu_clk_arb_target *actual; 89 struct nvgpu_clk_arb_target *actual;
@@ -269,7 +270,8 @@ int nvgpu_clk_arb_init_arbiter(struct gk20a *g)
269 atomic_read(&arb->req_nr)); 270 atomic_read(&arb->req_nr));
270 } while (!atomic_read(&arb->req_nr)); 271 } while (!atomic_read(&arb->req_nr));
271 272
272 return 0; 273
274 return arb->status;
273 275
274init_fail: 276init_fail:
275 277
@@ -533,6 +535,7 @@ static int nvgpu_clk_arb_update_vf_table(struct nvgpu_clk_arb *arb)
533 clk_cur = table->mclk_points[j].mhz; 535 clk_cur = table->mclk_points[j].mhz;
534 j++; 536 j++;
535 num_points++; 537 num_points++;
538
536 } 539 }
537 } 540 }
538 table->mclk_num_points = num_points; 541 table->mclk_num_points = num_points;
@@ -605,7 +608,7 @@ static void nvgpu_clk_arb_run_vf_table_cb(struct work_struct *work)
605 err = clk_vf_point_cache(g); 608 err = clk_vf_point_cache(g);
606 if (err) { 609 if (err) {
607 gk20a_err(dev_from_gk20a(g), 610 gk20a_err(dev_from_gk20a(g),
608 "failed to get GPC2CLK SRAM voltage"); 611 "failed to cache VF table");
609 return; 612 return;
610 } 613 }
611 nvgpu_clk_arb_update_vf_table(arb); 614 nvgpu_clk_arb_update_vf_table(arb);
@@ -625,7 +628,7 @@ static void nvgpu_clk_arb_run_arbiter_cb(struct work_struct *work)
625 u32 voltuv, voltuv_sram; 628 u32 voltuv, voltuv_sram;
626 bool mclk_set, gpc2clk_set; 629 bool mclk_set, gpc2clk_set;
627 630
628 int status; 631 int status = 0;
629 632
630 /* Temporary variables for checking target frequency */ 633 /* Temporary variables for checking target frequency */
631 u16 gpc2clk_target, mclk_target; 634 u16 gpc2clk_target, mclk_target;
@@ -742,15 +745,21 @@ static void nvgpu_clk_arb_run_arbiter_cb(struct work_struct *work)
742 actual->gpc2clk = gpc2clk_target; 745 actual->gpc2clk = gpc2clk_target;
743 actual->mclk = mclk_target; 746 actual->mclk = mclk_target;
744 arb->voltuv_actual = voltuv; 747 arb->voltuv_actual = voltuv;
748 arb->status = status;
745 749
746 /* Make changes visible to other threads */ 750 /* Make changes visible to other threads */
747 smp_wmb(); 751 smp_wmb();
748 xchg(&arb->actual, actual); 752 xchg(&arb->actual, actual);
749 753
754 /* status must be visible before atomic inc */
755 smp_wmb();
750 atomic_inc(&arb->req_nr); 756 atomic_inc(&arb->req_nr);
751 757
752 wake_up_interruptible(&arb->request_wq); 758 wake_up_interruptible(&arb->request_wq);
753 759
760 if (status < 0)
761 gk20a_err(dev_from_gk20a(g),
762 "Error in arbiter update");
754 763
755#ifdef CONFIG_DEBUG_FS 764#ifdef CONFIG_DEBUG_FS
756 g->ops.read_ptimer(g, &t1); 765 g->ops.read_ptimer(g, &t1);
@@ -1016,20 +1025,23 @@ static void nvgpu_clk_arb_find_vf_point(struct nvgpu_clk_arb *arb,
1016 struct nvgpu_clk_vf_table *table; 1025 struct nvgpu_clk_vf_table *table;
1017 u32 index; 1026 u32 index;
1018 1027
1019 gpc2clk_target = *gpc2clk;
1020 mclk_target = *mclk;
1021 gpc2clk_voltuv = 0;
1022 gpc2clk_voltuv_sram = 0;
1023 mclk_voltuv = 0;
1024 mclk_voltuv_sram = 0;
1025
1026 do { 1028 do {
1029 gpc2clk_target = *gpc2clk;
1030 mclk_target = *mclk;
1031 gpc2clk_voltuv = 0;
1032 gpc2clk_voltuv_sram = 0;
1033 mclk_voltuv = 0;
1034 mclk_voltuv_sram = 0;
1035
1027 table = ACCESS_ONCE(arb->current_vf_table); 1036 table = ACCESS_ONCE(arb->current_vf_table);
1028 /* pointer to table can be updated by callback */ 1037 /* pointer to table can be updated by callback */
1029 smp_rmb(); 1038 smp_rmb();
1030 1039
1031 if (!table) 1040 if (!table)
1032 continue; 1041 continue;
1042 if ((!table->gpc2clk_num_points) || (!table->mclk_num_points))
1043 goto find_exit;
1044
1033 /* round up the freq requests */ 1045 /* round up the freq requests */
1034 for (index = 0; index < table->gpc2clk_num_points; index++) { 1046 for (index = 0; index < table->gpc2clk_num_points; index++) {
1035 if (table->gpc2clk_points[index].mhz >= 1047 if (table->gpc2clk_points[index].mhz >=
@@ -1045,10 +1057,10 @@ static void nvgpu_clk_arb_find_vf_point(struct nvgpu_clk_arb *arb,
1045 } 1057 }
1046 1058
1047 if (index == table->gpc2clk_num_points) { 1059 if (index == table->gpc2clk_num_points) {
1048 gpc2clk_target = table->gpc2clk_points[index].mhz; 1060 gpc2clk_target = table->gpc2clk_points[index-1].mhz;
1049 gpc2clk_voltuv = table->gpc2clk_points[index].uvolt; 1061 gpc2clk_voltuv = table->gpc2clk_points[index-1].uvolt;
1050 gpc2clk_voltuv_sram = 1062 gpc2clk_voltuv_sram =
1051 table->gpc2clk_points[index].uvolt_sram; 1063 table->gpc2clk_points[index-1].uvolt_sram;
1052 } 1064 }
1053 1065
1054 for (index = 0; index < table->mclk_num_points; index++) { 1066 for (index = 0; index < table->mclk_num_points; index++) {
@@ -1061,14 +1073,15 @@ static void nvgpu_clk_arb_find_vf_point(struct nvgpu_clk_arb *arb,
1061 } 1073 }
1062 } 1074 }
1063 if (index == table->mclk_num_points) { 1075 if (index == table->mclk_num_points) {
1064 mclk_target = table->mclk_points[index].mhz; 1076 mclk_target = table->mclk_points[index-1].mhz;
1065 mclk_voltuv = table->mclk_points[index].uvolt; 1077 mclk_voltuv = table->mclk_points[index-1].uvolt;
1066 mclk_voltuv_sram = 1078 mclk_voltuv_sram =
1067 table->mclk_points[index].uvolt_sram; 1079 table->mclk_points[index-1].uvolt_sram;
1068 } 1080 }
1069 } while (!table || 1081 } while (!table ||
1070 (ACCESS_ONCE(arb->current_vf_table) != table)); 1082 (ACCESS_ONCE(arb->current_vf_table) != table));
1071 1083
1084find_exit:
1072 *voltuv = gpc2clk_voltuv > mclk_voltuv ? gpc2clk_voltuv : mclk_voltuv; 1085 *voltuv = gpc2clk_voltuv > mclk_voltuv ? gpc2clk_voltuv : mclk_voltuv;
1073 *voltuv_sram = gpc2clk_voltuv_sram > mclk_voltuv_sram ? 1086 *voltuv_sram = gpc2clk_voltuv_sram > mclk_voltuv_sram ?
1074 gpc2clk_voltuv_sram : mclk_voltuv_sram; 1087 gpc2clk_voltuv_sram : mclk_voltuv_sram;
@@ -1136,7 +1149,6 @@ static int nvgpu_clk_arb_change_vf_point(struct gk20a *g, u16 gpc2clk_target,
1136 status = clk_program_fll_clks(g, &fllclk); 1149 status = clk_program_fll_clks(g, &fllclk);
1137 if (status < 0) 1150 if (status < 0)
1138 return status; 1151 return status;
1139
1140 } 1152 }
1141 1153
1142 return 0; 1154 return 0;