diff options
-rw-r--r-- | drivers/gpu/nvgpu/gm20b/clk_gm20b.c | 20 |
1 files changed, 18 insertions, 2 deletions
diff --git a/drivers/gpu/nvgpu/gm20b/clk_gm20b.c b/drivers/gpu/nvgpu/gm20b/clk_gm20b.c index 561a0427..fffac551 100644 --- a/drivers/gpu/nvgpu/gm20b/clk_gm20b.c +++ b/drivers/gpu/nvgpu/gm20b/clk_gm20b.c | |||
@@ -25,6 +25,7 @@ | |||
25 | #include "gk20a/gk20a.h" | 25 | #include "gk20a/gk20a.h" |
26 | #include "hw_trim_gm20b.h" | 26 | #include "hw_trim_gm20b.h" |
27 | #include "hw_timer_gm20b.h" | 27 | #include "hw_timer_gm20b.h" |
28 | #include "hw_therm_gm20b.h" | ||
28 | #include "clk_gm20b.h" | 29 | #include "clk_gm20b.h" |
29 | 30 | ||
30 | #define gk20a_dbg_clk(fmt, arg...) \ | 31 | #define gk20a_dbg_clk(fmt, arg...) \ |
@@ -877,6 +878,7 @@ static int monitor_get(void *data, u64 *val) | |||
877 | { | 878 | { |
878 | struct gk20a *g = (struct gk20a *)data; | 879 | struct gk20a *g = (struct gk20a *)data; |
879 | struct clk_gk20a *clk = &g->clk; | 880 | struct clk_gk20a *clk = &g->clk; |
881 | u32 clk_slowdown, clk_slowdown_save; | ||
880 | int err; | 882 | int err; |
881 | 883 | ||
882 | u32 ncycle = 100; /* count GPCCLK for ncycle of clkin */ | 884 | u32 ncycle = 100; /* count GPCCLK for ncycle of clkin */ |
@@ -887,6 +889,16 @@ static int monitor_get(void *data, u64 *val) | |||
887 | if (err) | 889 | if (err) |
888 | return err; | 890 | return err; |
889 | 891 | ||
892 | mutex_lock(&g->clk.clk_mutex); | ||
893 | |||
894 | /* Disable clock slowdown during measurements */ | ||
895 | clk_slowdown_save = gk20a_readl(g, therm_clk_slowdown_r(0)); | ||
896 | clk_slowdown = set_field(clk_slowdown_save, | ||
897 | therm_clk_slowdown_idle_factor_m(), | ||
898 | therm_clk_slowdown_idle_factor_disabled_f()); | ||
899 | gk20a_writel(g, therm_clk_slowdown_r(0), clk_slowdown); | ||
900 | gk20a_readl(g, therm_clk_slowdown_r(0)); | ||
901 | |||
890 | gk20a_writel(g, trim_gpc_clk_cntr_ncgpcclk_cfg_r(0), | 902 | gk20a_writel(g, trim_gpc_clk_cntr_ncgpcclk_cfg_r(0), |
891 | trim_gpc_clk_cntr_ncgpcclk_cfg_reset_asserted_f()); | 903 | trim_gpc_clk_cntr_ncgpcclk_cfg_reset_asserted_f()); |
892 | gk20a_writel(g, trim_gpc_clk_cntr_ncgpcclk_cfg_r(0), | 904 | gk20a_writel(g, trim_gpc_clk_cntr_ncgpcclk_cfg_r(0), |
@@ -895,10 +907,10 @@ static int monitor_get(void *data, u64 *val) | |||
895 | trim_gpc_clk_cntr_ncgpcclk_cfg_noofipclks_f(ncycle)); | 907 | trim_gpc_clk_cntr_ncgpcclk_cfg_noofipclks_f(ncycle)); |
896 | /* start */ | 908 | /* start */ |
897 | 909 | ||
898 | /* It should take about 8us to finish 100 cycle of 12MHz. | 910 | /* It should take less than 5us to finish 100 cycle of 38.4MHz. |
899 | But longer than 100us delay is required here. */ | 911 | But longer than 100us delay is required here. */ |
900 | gk20a_readl(g, trim_gpc_clk_cntr_ncgpcclk_cfg_r(0)); | 912 | gk20a_readl(g, trim_gpc_clk_cntr_ncgpcclk_cfg_r(0)); |
901 | udelay(2000); | 913 | udelay(200); |
902 | 914 | ||
903 | count1 = gk20a_readl(g, trim_gpc_clk_cntr_ncgpcclk_cnt_r(0)); | 915 | count1 = gk20a_readl(g, trim_gpc_clk_cntr_ncgpcclk_cnt_r(0)); |
904 | udelay(100); | 916 | udelay(100); |
@@ -907,6 +919,10 @@ static int monitor_get(void *data, u64 *val) | |||
907 | do_div(freq, ncycle); | 919 | do_div(freq, ncycle); |
908 | *val = freq; | 920 | *val = freq; |
909 | 921 | ||
922 | /* Restore clock slowdown */ | ||
923 | gk20a_writel(g, therm_clk_slowdown_r(0), clk_slowdown_save); | ||
924 | mutex_unlock(&g->clk.clk_mutex); | ||
925 | |||
910 | gk20a_idle(g->dev); | 926 | gk20a_idle(g->dev); |
911 | 927 | ||
912 | if (count1 != count2) | 928 | if (count1 != count2) |