summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArun Kannan <akannan@nvidia.com>2018-03-05 17:32:08 -0500
committermobile promotions <svcmobile_promotions@nvidia.com>2018-04-23 15:12:52 -0400
commite9a6d179a42e7bdd6bb4876fb14f4ff7ab0df852 (patch)
treef2700ecb7c4f04041f9b333e6c8fe888bef7e082
parent0e3181a5d710a4ef066c81ec9d699dbcb3d9c995 (diff)
gpu: nvgpu: cache gpu clk rate
Cache the rate used in clk_set_rate(). Return that cached rate on clk_get_rate(), don't read from hardware. This cached rate is used to avoid duplicate requests to clk_set_rate(). Motivation is to support multiple governors for gpu clk. Reading clock from hardware is unreliable in multi-governor situation. Relying on hardware clock value could mislead the kernel gpu governor in its scaling calculations. Bug 2051688 Change-Id: I43fc056eea6f69fe0889c45640fcb892b658071c Signed-off-by: Arun Kannan <akannan@nvidia.com> (cherry picked from commit 7f819a9ba707e6e905168b00b0f3bf6348e86188) Reviewed-on: https://git-master.nvidia.com/r/1662759 Reviewed-on: https://git-master.nvidia.com/r/1668919 Reviewed-by: Automatic_Commit_Validation_User Reviewed-by: svc-mobile-coverity <svc-mobile-coverity@nvidia.com> GVS: Gerrit_Virtual_Submit Reviewed-by: Terje Bergstrom <tbergstrom@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
-rw-r--r--drivers/gpu/nvgpu/common/linux/clk.c19
-rw-r--r--drivers/gpu/nvgpu/common/linux/platform_gk20a.h3
-rw-r--r--drivers/gpu/nvgpu/common/linux/platform_gk20a_tegra.c2
-rw-r--r--drivers/gpu/nvgpu/common/linux/platform_gp10b_tegra.c6
-rw-r--r--drivers/gpu/nvgpu/gk20a/clk_gk20a.h5
5 files changed, 28 insertions, 7 deletions
diff --git a/drivers/gpu/nvgpu/common/linux/clk.c b/drivers/gpu/nvgpu/common/linux/clk.c
index ea5b023d..8bffc07b 100644
--- a/drivers/gpu/nvgpu/common/linux/clk.c
+++ b/drivers/gpu/nvgpu/common/linux/clk.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * Linux clock support 2 * Linux clock support
3 * 3 *
4 * Copyright (c) 2017, NVIDIA CORPORATION. All rights reserved. 4 * Copyright (c) 2017-2018, NVIDIA CORPORATION. All rights reserved.
5 * 5 *
6 * This program is free software; you can redistribute it and/or modify it 6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms and conditions of the GNU General Public License, 7 * under the terms and conditions of the GNU General Public License,
@@ -34,9 +34,13 @@ static unsigned long nvgpu_linux_clk_get_rate(struct gk20a *g, u32 api_domain)
34 switch (api_domain) { 34 switch (api_domain) {
35 case CTRL_CLK_DOMAIN_GPCCLK: 35 case CTRL_CLK_DOMAIN_GPCCLK:
36 if (g->clk.tegra_clk) 36 if (g->clk.tegra_clk)
37 ret = clk_get_rate(g->clk.tegra_clk); 37 ret = g->clk.cached_rate ?
38 g->clk.cached_rate :
39 clk_get_rate(g->clk.tegra_clk);
38 else 40 else
39 ret = clk_get_rate(platform->clk[0]); 41 ret = platform->cached_rate ?
42 platform->cached_rate :
43 clk_get_rate(platform->clk[0]);
40 break; 44 break;
41 case CTRL_CLK_DOMAIN_PWRCLK: 45 case CTRL_CLK_DOMAIN_PWRCLK:
42 ret = clk_get_rate(platform->clk[1]); 46 ret = clk_get_rate(platform->clk[1]);
@@ -58,10 +62,15 @@ static int nvgpu_linux_clk_set_rate(struct gk20a *g,
58 62
59 switch (api_domain) { 63 switch (api_domain) {
60 case CTRL_CLK_DOMAIN_GPCCLK: 64 case CTRL_CLK_DOMAIN_GPCCLK:
61 if (g->clk.tegra_clk) 65 if (g->clk.tegra_clk) {
62 ret = clk_set_rate(g->clk.tegra_clk, rate); 66 ret = clk_set_rate(g->clk.tegra_clk, rate);
63 else 67 if (!ret)
68 g->clk.cached_rate = rate;
69 } else {
64 ret = clk_set_rate(platform->clk[0], rate); 70 ret = clk_set_rate(platform->clk[0], rate);
71 if (!ret)
72 platform->cached_rate = rate;
73 }
65 break; 74 break;
66 case CTRL_CLK_DOMAIN_PWRCLK: 75 case CTRL_CLK_DOMAIN_PWRCLK:
67 ret = clk_set_rate(platform->clk[1], rate); 76 ret = clk_set_rate(platform->clk[1], rate);
diff --git a/drivers/gpu/nvgpu/common/linux/platform_gk20a.h b/drivers/gpu/nvgpu/common/linux/platform_gk20a.h
index aed50ed7..43afbbf9 100644
--- a/drivers/gpu/nvgpu/common/linux/platform_gk20a.h
+++ b/drivers/gpu/nvgpu/common/linux/platform_gk20a.h
@@ -256,6 +256,9 @@ struct gk20a_platform {
256 256
257 /* stream id to use */ 257 /* stream id to use */
258 u32 ltc_streamid; 258 u32 ltc_streamid;
259
260 /* scaling rate */
261 unsigned long cached_rate;
259}; 262};
260 263
261static inline struct gk20a_platform *gk20a_get_platform( 264static inline struct gk20a_platform *gk20a_get_platform(
diff --git a/drivers/gpu/nvgpu/common/linux/platform_gk20a_tegra.c b/drivers/gpu/nvgpu/common/linux/platform_gk20a_tegra.c
index 3e1c6996..82648ca3 100644
--- a/drivers/gpu/nvgpu/common/linux/platform_gk20a_tegra.c
+++ b/drivers/gpu/nvgpu/common/linux/platform_gk20a_tegra.c
@@ -506,6 +506,8 @@ static int gk20a_tegra_get_clocks(struct device *dev)
506 rate = clk_round_rate(c, rate); 506 rate = clk_round_rate(c, rate);
507 clk_set_rate(c, rate); 507 clk_set_rate(c, rate);
508 platform->clk[i] = c; 508 platform->clk[i] = c;
509 if (i == 0)
510 platform->cached_rate = rate;
509 } 511 }
510 platform->num_clks = i; 512 platform->num_clks = i;
511 513
diff --git a/drivers/gpu/nvgpu/common/linux/platform_gp10b_tegra.c b/drivers/gpu/nvgpu/common/linux/platform_gp10b_tegra.c
index 782a3d88..96acf24b 100644
--- a/drivers/gpu/nvgpu/common/linux/platform_gp10b_tegra.c
+++ b/drivers/gpu/nvgpu/common/linux/platform_gp10b_tegra.c
@@ -57,11 +57,13 @@ gp10b_freq_table[GP10B_MAX_SUPPORTED_FREQS / GP10B_FREQ_SELECT_STEP];
57 57
58#define EMC_BW_RATIO (TEGRA_GP10B_BW_PER_FREQ / TEGRA_DDR4_BW_PER_FREQ) 58#define EMC_BW_RATIO (TEGRA_GP10B_BW_PER_FREQ / TEGRA_DDR4_BW_PER_FREQ)
59 59
60#define GPCCLK_INIT_RATE 1000000000
61
60static struct { 62static struct {
61 char *name; 63 char *name;
62 unsigned long default_rate; 64 unsigned long default_rate;
63} tegra_gp10b_clocks[] = { 65} tegra_gp10b_clocks[] = {
64 {"gpu", 1000000000}, 66 {"gpu", GPCCLK_INIT_RATE},
65 {"gpu_sys", 204000000} }; 67 {"gpu_sys", 204000000} };
66 68
67static void gr_gp10b_remove_sysfs(struct device *dev); 69static void gr_gp10b_remove_sysfs(struct device *dev);
@@ -90,6 +92,8 @@ int gp10b_tegra_get_clocks(struct device *dev)
90 } else { 92 } else {
91 clk_set_rate(c, rate); 93 clk_set_rate(c, rate);
92 platform->clk[i] = c; 94 platform->clk[i] = c;
95 if (i == 0)
96 platform->cached_rate = rate;
93 } 97 }
94 } 98 }
95 platform->num_clks = i; 99 platform->num_clks = i;
diff --git a/drivers/gpu/nvgpu/gk20a/clk_gk20a.h b/drivers/gpu/nvgpu/gk20a/clk_gk20a.h
index ec7022aa..d84e5969 100644
--- a/drivers/gpu/nvgpu/gk20a/clk_gk20a.h
+++ b/drivers/gpu/nvgpu/gk20a/clk_gk20a.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2011 - 2017, NVIDIA CORPORATION. All rights reserved. 2 * Copyright (c) 2011 - 2018, NVIDIA CORPORATION. All rights reserved.
3 * 3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a 4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"), 5 * copy of this software and associated documentation files (the "Software"),
@@ -96,6 +96,9 @@ struct clk_gk20a {
96#if defined(CONFIG_COMMON_CLK) 96#if defined(CONFIG_COMMON_CLK)
97 struct clk *tegra_clk; 97 struct clk *tegra_clk;
98 struct clk_hw hw; 98 struct clk_hw hw;
99
100 /* scaling rate */
101 unsigned long cached_rate;
99#endif 102#endif
100 struct pll gpc_pll; 103 struct pll gpc_pll;
101 struct pll gpc_pll_last; 104 struct pll gpc_pll_last;