summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/nvgpu/clk/clk_arb.c
diff options
context:
space:
mode:
authorThomas Fleury <tfleury@nvidia.com>2017-04-11 16:43:24 -0400
committermobile promotions <svcmobile_promotions@nvidia.com>2017-04-18 19:14:49 -0400
commitf4e36283437ff5dfcac08205aa994c62d95e1d21 (patch)
tree0f8df44fe8551edab0fac94c850aac34724a2be5 /drivers/gpu/nvgpu/clk/clk_arb.c
parent03e7ef2657b4de22eff521b3e44fc4ed5cdf4dca (diff)
gpu: nvgpu: clip target frequencies in arbiter
It is currently possible to set GPCCLK lower than the minimum allowed frequency. Clip target GPCCLK/MCLK according to valid min/max range in arbiter. We could do this before submitting request to arbiter, but then we would loose information on the requested target frequency. Instead, we cache the clock range in arbiter context, and check target frequency when running arbiter. Bug 200288036 Change-Id: I29f5176e6365a926d1041430c05a63f0c8447e2b Reviewed-on: http://git-master/r/1460834 (cherry picked from commit eb626903e4fc046fe1f0eaee703c857e9a0f2b4d) Signed-off-by: Thomas Fleury <tfleury@nvidia.com> Reviewed-on: http://git-master/r/1461715 Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
Diffstat (limited to 'drivers/gpu/nvgpu/clk/clk_arb.c')
-rw-r--r--drivers/gpu/nvgpu/clk/clk_arb.c32
1 files changed, 24 insertions, 8 deletions
diff --git a/drivers/gpu/nvgpu/clk/clk_arb.c b/drivers/gpu/nvgpu/clk/clk_arb.c
index 572de674..22dc6fb7 100644
--- a/drivers/gpu/nvgpu/clk/clk_arb.c
+++ b/drivers/gpu/nvgpu/clk/clk_arb.c
@@ -163,6 +163,9 @@ struct nvgpu_clk_arb {
163 u16 mclk_default_mhz; 163 u16 mclk_default_mhz;
164 u32 voltuv_actual; 164 u32 voltuv_actual;
165 165
166 u16 gpc2clk_min, gpc2clk_max;
167 u16 mclk_min, mclk_max;
168
166 struct work_struct update_fn_work; 169 struct work_struct update_fn_work;
167 struct workqueue_struct *update_work_queue; 170 struct workqueue_struct *update_work_queue;
168 struct work_struct vf_table_fn_work; 171 struct work_struct vf_table_fn_work;
@@ -690,8 +693,7 @@ static int nvgpu_clk_arb_update_vf_table(struct nvgpu_clk_arb *arb)
690 int status = -EINVAL; 693 int status = -EINVAL;
691 u32 gpc2clk_voltuv = 0, mclk_voltuv = 0; 694 u32 gpc2clk_voltuv = 0, mclk_voltuv = 0;
692 u32 gpc2clk_voltuv_sram = 0, mclk_voltuv_sram = 0; 695 u32 gpc2clk_voltuv_sram = 0, mclk_voltuv_sram = 0;
693 u16 gpc2clk_min, gpc2clk_max, clk_cur; 696 u16 clk_cur;
694 u16 mclk_min, mclk_max;
695 u32 num_points; 697 u32 num_points;
696 698
697 struct clk_set_info *p5_info, *p0_info; 699 struct clk_set_info *p5_info, *p0_info;
@@ -706,12 +708,14 @@ static int nvgpu_clk_arb_update_vf_table(struct nvgpu_clk_arb *arb)
706 708
707 /* Get allowed memory ranges */ 709 /* Get allowed memory ranges */
708 if (g->ops.clk_arb.get_arbiter_clk_range(g, CTRL_CLK_DOMAIN_GPC2CLK, 710 if (g->ops.clk_arb.get_arbiter_clk_range(g, CTRL_CLK_DOMAIN_GPC2CLK,
709 &gpc2clk_min, &gpc2clk_max) < 0) { 711 &arb->gpc2clk_min,
712 &arb->gpc2clk_max) < 0) {
710 nvgpu_err(g, "failed to fetch GPC2CLK range"); 713 nvgpu_err(g, "failed to fetch GPC2CLK range");
711 goto exit_vf_table; 714 goto exit_vf_table;
712 } 715 }
713 if (g->ops.clk_arb.get_arbiter_clk_range(g, CTRL_CLK_DOMAIN_MCLK, 716 if (g->ops.clk_arb.get_arbiter_clk_range(g, CTRL_CLK_DOMAIN_MCLK,
714 &mclk_min, &mclk_max) < 0) { 717 &arb->mclk_min,
718 &arb->mclk_max) < 0) {
715 nvgpu_err(g, "failed to fetch MCLK range"); 719 nvgpu_err(g, "failed to fetch MCLK range");
716 goto exit_vf_table; 720 goto exit_vf_table;
717 } 721 }
@@ -758,8 +762,8 @@ static int nvgpu_clk_arb_update_vf_table(struct nvgpu_clk_arb *arb)
758 for (i = 0, j = 0, num_points = 0, clk_cur = 0; 762 for (i = 0, j = 0, num_points = 0, clk_cur = 0;
759 i < table->mclk_num_points; i++) { 763 i < table->mclk_num_points; i++) {
760 764
761 if ((arb->mclk_f_points[i] >= mclk_min) && 765 if ((arb->mclk_f_points[i] >= arb->mclk_min) &&
762 (arb->mclk_f_points[i] <= mclk_max) && 766 (arb->mclk_f_points[i] <= arb->mclk_max) &&
763 (arb->mclk_f_points[i] != clk_cur)) { 767 (arb->mclk_f_points[i] != clk_cur)) {
764 768
765 table->mclk_points[j].mem_mhz = arb->mclk_f_points[i]; 769 table->mclk_points[j].mem_mhz = arb->mclk_f_points[i];
@@ -829,8 +833,8 @@ static int nvgpu_clk_arb_update_vf_table(struct nvgpu_clk_arb *arb)
829 i < table->gpc2clk_num_points; i++) { 833 i < table->gpc2clk_num_points; i++) {
830 struct set_fll_clk setfllclk; 834 struct set_fll_clk setfllclk;
831 835
832 if ((arb->gpc2clk_f_points[i] >= gpc2clk_min) && 836 if ((arb->gpc2clk_f_points[i] >= arb->gpc2clk_min) &&
833 (arb->gpc2clk_f_points[i] <= gpc2clk_max) && 837 (arb->gpc2clk_f_points[i] <= arb->gpc2clk_max) &&
834 (arb->gpc2clk_f_points[i] != clk_cur)) { 838 (arb->gpc2clk_f_points[i] != clk_cur)) {
835 839
836 table->gpc2clk_points[j].gpc_mhz = 840 table->gpc2clk_points[j].gpc_mhz =
@@ -1110,9 +1114,21 @@ static void nvgpu_clk_arb_run_arbiter_cb(struct work_struct *work)
1110 gpc2clk_target = (gpc2clk_target > 0) ? gpc2clk_target : 1114 gpc2clk_target = (gpc2clk_target > 0) ? gpc2clk_target :
1111 arb->gpc2clk_default_mhz; 1115 arb->gpc2clk_default_mhz;
1112 1116
1117 if (gpc2clk_target < arb->gpc2clk_min)
1118 gpc2clk_target = arb->gpc2clk_min;
1119
1120 if (gpc2clk_target > arb->gpc2clk_max)
1121 gpc2clk_target = arb->gpc2clk_max;
1122
1113 mclk_target = (mclk_target > 0) ? mclk_target: 1123 mclk_target = (mclk_target > 0) ? mclk_target:
1114 arb->mclk_default_mhz; 1124 arb->mclk_default_mhz;
1115 1125
1126 if (mclk_target < arb->mclk_min)
1127 mclk_target = arb->mclk_min;
1128
1129 if (mclk_target > arb->mclk_max)
1130 mclk_target = arb->mclk_max;
1131
1116 sys2clk_target = 0; 1132 sys2clk_target = 0;
1117 xbar2clk_target = 0; 1133 xbar2clk_target = 0;
1118 1134