From d664ff12afdda8dfb975d9920759bf868ea58a6a Mon Sep 17 00:00:00 2001 From: Thomas Fleury Date: Tue, 11 Apr 2017 13:43:24 -0700 Subject: [PATCH] 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 Signed-off-by: Thomas Fleury (cherry picked from commit eb626903e4fc046fe1f0eaee703c857e9a0f2b4d) Reviewed-on: http://git-master/r/1461882 (cherry picked from commit 3615061045276c8913057e1c0e8cc443b70d2ad9) Reviewed-on: http://git-master/r/1467627 Reviewed-by: Automatic_Commit_Validation_User Reviewed-by: svccoveritychecker GVS: Gerrit_Virtual_Submit Reviewed-by: Vladislav Buzov --- drivers/gpu/nvgpu/clk/clk_arb.c | 32 ++++++++++++++++++++++++-------- 1 file changed, 24 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/nvgpu/clk/clk_arb.c b/drivers/gpu/nvgpu/clk/clk_arb.c index f5c30adaf..c7f1eb86a 100644 --- a/drivers/gpu/nvgpu/clk/clk_arb.c +++ b/drivers/gpu/nvgpu/clk/clk_arb.c @@ -157,6 +157,9 @@ struct nvgpu_clk_arb { u16 mclk_default_mhz; u32 voltuv_actual; + u16 gpc2clk_min, gpc2clk_max; + u16 mclk_min, mclk_max; + struct work_struct update_fn_work; struct workqueue_struct *update_work_queue; struct work_struct vf_table_fn_work; @@ -683,8 +686,7 @@ static int nvgpu_clk_arb_update_vf_table(struct nvgpu_clk_arb *arb) int status = -EINVAL; u32 gpc2clk_voltuv = 0, mclk_voltuv = 0; u32 gpc2clk_voltuv_sram = 0, mclk_voltuv_sram = 0; - u16 gpc2clk_min, gpc2clk_max, clk_cur; - u16 mclk_min, mclk_max; + u16 clk_cur; u32 num_points; struct clk_set_info *p5_info, *p0_info; @@ -699,13 +701,15 @@ static int nvgpu_clk_arb_update_vf_table(struct nvgpu_clk_arb *arb) /* Get allowed memory ranges */ if (g->ops.clk_arb.get_arbiter_clk_range(g, CTRL_CLK_DOMAIN_GPC2CLK, - &gpc2clk_min, &gpc2clk_max) < 0) { + &arb->gpc2clk_min, + &arb->gpc2clk_max) < 0) { gk20a_err(dev_from_gk20a(g), "failed to fetch GPC2CLK range"); goto exit_vf_table; } if (g->ops.clk_arb.get_arbiter_clk_range(g, CTRL_CLK_DOMAIN_MCLK, - &mclk_min, &mclk_max) < 0) { + &arb->mclk_min, + &arb->mclk_max) < 0) { gk20a_err(dev_from_gk20a(g), "failed to fetch MCLK range"); goto exit_vf_table; @@ -758,8 +762,8 @@ static int nvgpu_clk_arb_update_vf_table(struct nvgpu_clk_arb *arb) for (i = 0, j = 0, num_points = 0, clk_cur = 0; i < table->mclk_num_points; i++) { - if ((arb->mclk_f_points[i] >= mclk_min) && - (arb->mclk_f_points[i] <= mclk_max) && + if ((arb->mclk_f_points[i] >= arb->mclk_min) && + (arb->mclk_f_points[i] <= arb->mclk_max) && (arb->mclk_f_points[i] != clk_cur)) { table->mclk_points[j].mem_mhz = arb->mclk_f_points[i]; @@ -832,8 +836,8 @@ static int nvgpu_clk_arb_update_vf_table(struct nvgpu_clk_arb *arb) i < table->gpc2clk_num_points; i++) { struct set_fll_clk setfllclk; - if ((arb->gpc2clk_f_points[i] >= gpc2clk_min) && - (arb->gpc2clk_f_points[i] <= gpc2clk_max) && + if ((arb->gpc2clk_f_points[i] >= arb->gpc2clk_min) && + (arb->gpc2clk_f_points[i] <= arb->gpc2clk_max) && (arb->gpc2clk_f_points[i] != clk_cur)) { table->gpc2clk_points[j].gpc_mhz = @@ -1120,9 +1124,21 @@ static void nvgpu_clk_arb_run_arbiter_cb(struct work_struct *work) gpc2clk_target = (gpc2clk_target > 0) ? gpc2clk_target : arb->gpc2clk_default_mhz; + if (gpc2clk_target < arb->gpc2clk_min) + gpc2clk_target = arb->gpc2clk_min; + + if (gpc2clk_target > arb->gpc2clk_max) + gpc2clk_target = arb->gpc2clk_max; + mclk_target = (mclk_target > 0) ? mclk_target: arb->mclk_default_mhz; + if (mclk_target < arb->mclk_min) + mclk_target = arb->mclk_min; + + if (mclk_target > arb->mclk_max) + mclk_target = arb->mclk_max; + sys2clk_target = 0; xbar2clk_target = 0;