summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/nvgpu/gm20b/clk_gm20b.c
diff options
context:
space:
mode:
authorSrikar Srimath Tirumala <srikars@nvidia.com>2018-03-16 13:26:23 -0400
committermobile promotions <svcmobile_promotions@nvidia.com>2018-03-19 14:26:25 -0400
commitc5ca711f1efbd30fa760df139f3b63aa471d28a9 (patch)
treefb73fcb15ac7d2072565cbc80028cf87eed93c3c /drivers/gpu/nvgpu/gm20b/clk_gm20b.c
parent2aad9366fe6d5f537751b5b16a82231e2c4b1bdf (diff)
gpu: nvgpu: disable throttling during vco switch
Switching GPU clock in/out of bypass concurrently with h/w thermal throttling may result in unpredictable/unstable clock output from GPU linear divider. Hence, made sure thermal throttling is disabled before bypass entry, and enabled after bypass exit. Bug 1893467 Change-Id: Ia919c599eeb0115e11a34370aea3982aa935db2f Signed-off-by: Srikar Srimath Tirumala <srikars@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/1677022 Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
Diffstat (limited to 'drivers/gpu/nvgpu/gm20b/clk_gm20b.c')
-rw-r--r--drivers/gpu/nvgpu/gm20b/clk_gm20b.c28
1 files changed, 25 insertions, 3 deletions
diff --git a/drivers/gpu/nvgpu/gm20b/clk_gm20b.c b/drivers/gpu/nvgpu/gm20b/clk_gm20b.c
index 0f7d5cde..fa751ecc 100644
--- a/drivers/gpu/nvgpu/gm20b/clk_gm20b.c
+++ b/drivers/gpu/nvgpu/gm20b/clk_gm20b.c
@@ -701,16 +701,30 @@ static int clk_slide_gpc_pll(struct gk20a *g, struct pll *gpll)
701 return 0; 701 return 0;
702} 702}
703 703
704static void throttle_enable(struct gk20a *g, u32 val)
705{
706 gk20a_writel(g, therm_use_a_r(), val);
707}
708
709static u32 throttle_disable(struct gk20a *g)
710{
711 u32 val = gk20a_readl(g, therm_use_a_r());
712 gk20a_writel(g, therm_use_a_r(), 0);
713 return val;
714}
715
704/* GPCPLL bypass methods */ 716/* GPCPLL bypass methods */
705static int clk_change_pldiv_under_bypass(struct gk20a *g, struct pll *gpll) 717static int clk_change_pldiv_under_bypass(struct gk20a *g, struct pll *gpll)
706{ 718{
707 u32 data, coeff; 719 u32 data, coeff, throt;
708 720
709 /* put PLL in bypass before programming it */ 721 /* put PLL in bypass before programming it */
722 throt = throttle_disable(g);
710 data = gk20a_readl(g, trim_sys_sel_vco_r()); 723 data = gk20a_readl(g, trim_sys_sel_vco_r());
711 data = set_field(data, trim_sys_sel_vco_gpc2clk_out_m(), 724 data = set_field(data, trim_sys_sel_vco_gpc2clk_out_m(),
712 trim_sys_sel_vco_gpc2clk_out_bypass_f()); 725 trim_sys_sel_vco_gpc2clk_out_bypass_f());
713 gk20a_writel(g, trim_sys_sel_vco_r(), data); 726 gk20a_writel(g, trim_sys_sel_vco_r(), data);
727 throttle_enable(g, throt);
714 728
715 /* change PLDIV */ 729 /* change PLDIV */
716 coeff = gk20a_readl(g, trim_sys_gpcpll_coeff_r()); 730 coeff = gk20a_readl(g, trim_sys_gpcpll_coeff_r());
@@ -720,24 +734,28 @@ static int clk_change_pldiv_under_bypass(struct gk20a *g, struct pll *gpll)
720 gk20a_writel(g, trim_sys_gpcpll_coeff_r(), coeff); 734 gk20a_writel(g, trim_sys_gpcpll_coeff_r(), coeff);
721 735
722 /* put PLL back on vco */ 736 /* put PLL back on vco */
737 throt = throttle_disable(g);
723 data = gk20a_readl(g, trim_sys_sel_vco_r()); 738 data = gk20a_readl(g, trim_sys_sel_vco_r());
724 nvgpu_udelay(1); 739 nvgpu_udelay(1);
725 data = set_field(data, trim_sys_sel_vco_gpc2clk_out_m(), 740 data = set_field(data, trim_sys_sel_vco_gpc2clk_out_m(),
726 trim_sys_sel_vco_gpc2clk_out_vco_f()); 741 trim_sys_sel_vco_gpc2clk_out_vco_f());
727 gk20a_writel(g, trim_sys_sel_vco_r(), data); 742 gk20a_writel(g, trim_sys_sel_vco_r(), data);
743 throttle_enable(g, throt);
728 744
729 return 0; 745 return 0;
730} 746}
731 747
732static int clk_lock_gpc_pll_under_bypass(struct gk20a *g, struct pll *gpll) 748static int clk_lock_gpc_pll_under_bypass(struct gk20a *g, struct pll *gpll)
733{ 749{
734 u32 data, cfg, coeff, timeout; 750 u32 data, cfg, coeff, timeout, throt;
735 751
736 /* put PLL in bypass before programming it */ 752 /* put PLL in bypass before programming it */
753 throt = throttle_disable(g);
737 data = gk20a_readl(g, trim_sys_sel_vco_r()); 754 data = gk20a_readl(g, trim_sys_sel_vco_r());
738 data = set_field(data, trim_sys_sel_vco_gpc2clk_out_m(), 755 data = set_field(data, trim_sys_sel_vco_gpc2clk_out_m(),
739 trim_sys_sel_vco_gpc2clk_out_bypass_f()); 756 trim_sys_sel_vco_gpc2clk_out_bypass_f());
740 gk20a_writel(g, trim_sys_sel_vco_r(), data); 757 gk20a_writel(g, trim_sys_sel_vco_r(), data);
758 throttle_enable(g, throt);
741 759
742 cfg = gk20a_readl(g, trim_sys_gpcpll_cfg_r()); 760 cfg = gk20a_readl(g, trim_sys_gpcpll_cfg_r());
743 nvgpu_udelay(1); 761 nvgpu_udelay(1);
@@ -835,10 +853,12 @@ pll_locked:
835 gk20a_readl(g, trim_sys_gpcpll_cfg_r()); 853 gk20a_readl(g, trim_sys_gpcpll_cfg_r());
836 854
837 /* put PLL back on vco */ 855 /* put PLL back on vco */
856 throt = throttle_disable(g);
838 data = gk20a_readl(g, trim_sys_sel_vco_r()); 857 data = gk20a_readl(g, trim_sys_sel_vco_r());
839 data = set_field(data, trim_sys_sel_vco_gpc2clk_out_m(), 858 data = set_field(data, trim_sys_sel_vco_gpc2clk_out_m(),
840 trim_sys_sel_vco_gpc2clk_out_vco_f()); 859 trim_sys_sel_vco_gpc2clk_out_vco_f());
841 gk20a_writel(g, trim_sys_sel_vco_r(), data); 860 gk20a_writel(g, trim_sys_sel_vco_r(), data);
861 throttle_enable(g, throt);
842 862
843 return 0; 863 return 0;
844} 864}
@@ -1095,7 +1115,7 @@ static int clk_program_na_gpc_pll(struct gk20a *g, struct pll *gpll_new,
1095 1115
1096static int clk_disable_gpcpll(struct gk20a *g, int allow_slide) 1116static int clk_disable_gpcpll(struct gk20a *g, int allow_slide)
1097{ 1117{
1098 u32 cfg, coeff; 1118 u32 cfg, coeff, throt;
1099 struct clk_gk20a *clk = &g->clk; 1119 struct clk_gk20a *clk = &g->clk;
1100 struct pll gpll = clk->gpc_pll; 1120 struct pll gpll = clk->gpc_pll;
1101 1121
@@ -1112,10 +1132,12 @@ static int clk_disable_gpcpll(struct gk20a *g, int allow_slide)
1112 } 1132 }
1113 1133
1114 /* put PLL in bypass before disabling it */ 1134 /* put PLL in bypass before disabling it */
1135 throt = throttle_disable(g);
1115 cfg = gk20a_readl(g, trim_sys_sel_vco_r()); 1136 cfg = gk20a_readl(g, trim_sys_sel_vco_r());
1116 cfg = set_field(cfg, trim_sys_sel_vco_gpc2clk_out_m(), 1137 cfg = set_field(cfg, trim_sys_sel_vco_gpc2clk_out_m(),
1117 trim_sys_sel_vco_gpc2clk_out_bypass_f()); 1138 trim_sys_sel_vco_gpc2clk_out_bypass_f());
1118 gk20a_writel(g, trim_sys_sel_vco_r(), cfg); 1139 gk20a_writel(g, trim_sys_sel_vco_r(), cfg);
1140 throttle_enable(g, throt);
1119 1141
1120 /* clear SYNC_MODE before disabling PLL */ 1142 /* clear SYNC_MODE before disabling PLL */
1121 cfg = gk20a_readl(g, trim_sys_gpcpll_cfg_r()); 1143 cfg = gk20a_readl(g, trim_sys_gpcpll_cfg_r());