diff options
author | Thomas Fleury <tfleury@nvidia.com> | 2017-04-11 16:43:24 -0400 |
---|---|---|
committer | mobile promotions <svcmobile_promotions@nvidia.com> | 2017-04-18 19:14:49 -0400 |
commit | f4e36283437ff5dfcac08205aa994c62d95e1d21 (patch) | |
tree | 0f8df44fe8551edab0fac94c850aac34724a2be5 | |
parent | 03e7ef2657b4de22eff521b3e44fc4ed5cdf4dca (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>
-rw-r--r-- | drivers/gpu/nvgpu/clk/clk_arb.c | 32 |
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 | ||