summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/nvgpu/gm20b/clk_gm20b.c
diff options
context:
space:
mode:
authorAlex Frid <afrid@nvidia.com>2014-08-15 01:44:33 -0400
committerDan Willemsen <dwillemsen@nvidia.com>2015-03-18 15:11:05 -0400
commit5cd313e20221c93008f1d56ac223d6e08966505e (patch)
tree939aaaec6b7cbdc146782ce76e4d6328f4e62fe1 /drivers/gpu/nvgpu/gm20b/clk_gm20b.c
parent834a7ba4e1a80b1841e189eaff4747e7e62e8374 (diff)
gpu: nvgpu: Update GM20b GPCPLL operations
Moved detection of idempotent GPCPLL operations from set_pll_freq() function to its callers, e.g., explicitly check when enable operation is called on already enabled PLL, instead of passing same frequency to set_pll_freq() in such case. Similarly explicitly check when disable operation is called on already disabled PLL. Also moved check for GPU powered on from set_pll_freq() to callers, and skip call to set interface if not. Added last GPCPLL configuration structure updated after successful completion of set_pll_freq() function. Bug 1450787 Change-Id: I8c14b8cab2a8548e98c9b2d223c465c68fb87b61 Signed-off-by: Alex Frid <afrid@nvidia.com> Reviewed-on: http://git-master/r/488027 Reviewed-by: Automatic_Commit_Validation_User Reviewed-by: Krishna Reddy <vdumpa@nvidia.com>
Diffstat (limited to 'drivers/gpu/nvgpu/gm20b/clk_gm20b.c')
-rw-r--r--drivers/gpu/nvgpu/gm20b/clk_gm20b.c51
1 files changed, 28 insertions, 23 deletions
diff --git a/drivers/gpu/nvgpu/gm20b/clk_gm20b.c b/drivers/gpu/nvgpu/gm20b/clk_gm20b.c
index 4c1b9012..c7c2e8af 100644
--- a/drivers/gpu/nvgpu/gm20b/clk_gm20b.c
+++ b/drivers/gpu/nvgpu/gm20b/clk_gm20b.c
@@ -453,7 +453,6 @@ static int clk_program_gpc_pll(struct gk20a *g, struct pll *gpll_new,
453 gpll.PL = (gpll_new->PL < 2) ? 2 : gpll_new->PL; 453 gpll.PL = (gpll_new->PL < 2) ? 2 : gpll_new->PL;
454#endif 454#endif
455 clk_lock_gpc_pll_under_bypass(g, &gpll); 455 clk_lock_gpc_pll_under_bypass(g, &gpll);
456 gpll_new->enabled = true;
457 456
458#if PLDIV_GLITCHLESS 457#if PLDIV_GLITCHLESS
459 coeff = gk20a_readl(g, trim_sys_gpcpll_coeff_r()); 458 coeff = gk20a_readl(g, trim_sys_gpcpll_coeff_r());
@@ -646,28 +645,31 @@ static int set_pll_target(struct gk20a *g, u32 freq, u32 old_freq)
646 return 0; 645 return 0;
647} 646}
648 647
649static int set_pll_freq(struct gk20a *g, u32 freq, u32 old_freq) 648static int set_pll_freq(struct gk20a *g, int allow_slide)
650{ 649{
651 struct clk_gk20a *clk = &g->clk; 650 struct clk_gk20a *clk = &g->clk;
652 int err = 0; 651 int err = 0;
653 652
654 gk20a_dbg_fn("curr freq: %dMHz, target freq %dMHz", old_freq, freq); 653 gk20a_dbg_fn("last freq: %dMHz, target freq %dMHz",
654 clk->gpc_pll_last.freq, clk->gpc_pll.freq);
655 655
656 if ((freq == old_freq) && clk->gpc_pll.enabled) 656 /* If programming with dynamic sliding failed, re-try under bypass */
657 return 0; 657 err = clk_program_gpc_pll(g, &clk->gpc_pll, allow_slide);
658 if (err && allow_slide)
659 err = clk_program_gpc_pll(g, &clk->gpc_pll, 0);
658 660
659 /* change frequency only if power is on */ 661 if (!err) {
660 if (g->clk.clk_hw_on) { 662 clk->gpc_pll.enabled = true;
661 err = clk_program_gpc_pll(g, &clk->gpc_pll, 1); 663 clk->gpc_pll_last = clk->gpc_pll;
662 if (err) 664 return 0;
663 err = clk_program_gpc_pll(g, &clk->gpc_pll, 0);
664 } 665 }
665 666
666 /* Just report error but not restore PLL since dvfs could already change 667 /*
667 voltage even when it returns error. */ 668 * Just report error but not restore PLL since dvfs could already change
668 if (err) 669 * voltage even when programming failed.
669 gk20a_err(dev_from_gk20a(g), 670 */
670 "failed to set pll to %d", freq); 671 gk20a_err(dev_from_gk20a(g), "failed to set pll to %d",
672 clk->gpc_pll.freq);
671 return err; 673 return err;
672} 674}
673 675
@@ -682,8 +684,8 @@ static int gm20b_clk_export_set_rate(void *data, unsigned long *rate)
682 mutex_lock(&clk->clk_mutex); 684 mutex_lock(&clk->clk_mutex);
683 old_freq = clk->gpc_pll.freq; 685 old_freq = clk->gpc_pll.freq;
684 ret = set_pll_target(g, rate_gpu_to_gpc2clk(*rate), old_freq); 686 ret = set_pll_target(g, rate_gpu_to_gpc2clk(*rate), old_freq);
685 if (!ret && clk->gpc_pll.enabled) 687 if (!ret && clk->gpc_pll.enabled && clk->clk_hw_on)
686 ret = set_pll_freq(g, clk->gpc_pll.freq, old_freq); 688 ret = set_pll_freq(g, 1);
687 if (!ret) 689 if (!ret)
688 *rate = rate_gpc2clk_to_gpu(clk->gpc_pll.freq); 690 *rate = rate_gpc2clk_to_gpu(clk->gpc_pll.freq);
689 mutex_unlock(&clk->clk_mutex); 691 mutex_unlock(&clk->clk_mutex);
@@ -693,12 +695,13 @@ static int gm20b_clk_export_set_rate(void *data, unsigned long *rate)
693 695
694static int gm20b_clk_export_enable(void *data) 696static int gm20b_clk_export_enable(void *data)
695{ 697{
696 int ret; 698 int ret = 0;
697 struct gk20a *g = data; 699 struct gk20a *g = data;
698 struct clk_gk20a *clk = &g->clk; 700 struct clk_gk20a *clk = &g->clk;
699 701
700 mutex_lock(&clk->clk_mutex); 702 mutex_lock(&clk->clk_mutex);
701 ret = set_pll_freq(g, clk->gpc_pll.freq, clk->gpc_pll.freq); 703 if (!clk->gpc_pll.enabled && clk->clk_hw_on)
704 ret = set_pll_freq(g, 1);
702 mutex_unlock(&clk->clk_mutex); 705 mutex_unlock(&clk->clk_mutex);
703 return ret; 706 return ret;
704} 707}
@@ -709,7 +712,7 @@ static void gm20b_clk_export_disable(void *data)
709 struct clk_gk20a *clk = &g->clk; 712 struct clk_gk20a *clk = &g->clk;
710 713
711 mutex_lock(&clk->clk_mutex); 714 mutex_lock(&clk->clk_mutex);
712 if (g->clk.clk_hw_on) 715 if (clk->gpc_pll.enabled && clk->clk_hw_on)
713 clk_disable_gpcpll(g, 1); 716 clk_disable_gpcpll(g, 1);
714 mutex_unlock(&clk->clk_mutex); 717 mutex_unlock(&clk->clk_mutex);
715} 718}
@@ -789,7 +792,8 @@ static int gm20b_init_clk_support(struct gk20a *g)
789 792
790 /* The prev call may not enable PLL if gbus is unbalanced - force it */ 793 /* The prev call may not enable PLL if gbus is unbalanced - force it */
791 mutex_lock(&clk->clk_mutex); 794 mutex_lock(&clk->clk_mutex);
792 err = set_pll_freq(g, clk->gpc_pll.freq, clk->gpc_pll.freq); 795 if (!clk->gpc_pll.enabled)
796 err = set_pll_freq(g, 1);
793 mutex_unlock(&clk->clk_mutex); 797 mutex_unlock(&clk->clk_mutex);
794 if (err) 798 if (err)
795 return err; 799 return err;
@@ -805,13 +809,14 @@ static int gm20b_init_clk_support(struct gk20a *g)
805 809
806static int gm20b_suspend_clk_support(struct gk20a *g) 810static int gm20b_suspend_clk_support(struct gk20a *g)
807{ 811{
808 int ret; 812 int ret = 0;
809 813
810 clk_disable(g->clk.tegra_clk); 814 clk_disable(g->clk.tegra_clk);
811 815
812 /* The prev call may not disable PLL if gbus is unbalanced - force it */ 816 /* The prev call may not disable PLL if gbus is unbalanced - force it */
813 mutex_lock(&g->clk.clk_mutex); 817 mutex_lock(&g->clk.clk_mutex);
814 ret = clk_disable_gpcpll(g, 1); 818 if (g->clk.gpc_pll.enabled)
819 ret = clk_disable_gpcpll(g, 1);
815 g->clk.clk_hw_on = false; 820 g->clk.clk_hw_on = false;
816 mutex_unlock(&g->clk.clk_mutex); 821 mutex_unlock(&g->clk.clk_mutex);
817 return ret; 822 return ret;