summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/nvgpu/os/linux
diff options
context:
space:
mode:
authorDebarshi Dutta <ddutta@nvidia.com>2019-04-30 04:24:08 -0400
committermobile promotions <svcmobile_promotions@nvidia.com>2019-05-09 17:41:30 -0400
commitc81cc032c48a1b25e095b17b77399166c9091ff3 (patch)
treeace7d238c55bbb5e96fb6fd74deb156f3c513bae /drivers/gpu/nvgpu/os/linux
parentf495f52c70c6bd7b7a4e6897270e4696efa57d5c (diff)
gpu: nvgpu: add cg and pg function
Add new power/clock gating functions that can be called by other units. New clock_gating functions will reside in cg.c under common/power_features/cg unit. New power gating functions will reside in pg.c under common/power_features/pg unit. Use nvgpu_pg_elpg_disable and nvgpu_pg_elpg_enable to disable/enable elpg and also in gr_gk20a_elpg_protected macro to access gr registers. Add cg_pg_lock to make elpg_enabled, elcg_enabled, blcg_enabled and slcg_enabled thread safe. JIRA NVGPU-2014 Change-Id: I00d124c2ee16242c9a3ef82e7620fbb7f1297aff Signed-off-by: Seema Khowala <seemaj@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/2025493 Signed-off-by: Debarshi Dutta <ddutta@nvidia.com> (cherry-picked from c90585856567a547173a8b207365b3a4a3ccdd57 in dev-kernel) Reviewed-on: https://git-master.nvidia.com/r/2108406 GVS: Gerrit_Virtual_Submit Reviewed-by: Bibek Basu <bbasu@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
Diffstat (limited to 'drivers/gpu/nvgpu/os/linux')
-rw-r--r--drivers/gpu/nvgpu/os/linux/driver_common.c1
-rw-r--r--drivers/gpu/nvgpu/os/linux/sysfs.c137
-rw-r--r--drivers/gpu/nvgpu/os/linux/vgpu/vgpu_linux.c1
3 files changed, 36 insertions, 103 deletions
diff --git a/drivers/gpu/nvgpu/os/linux/driver_common.c b/drivers/gpu/nvgpu/os/linux/driver_common.c
index cf7877e2..ea4dadac 100644
--- a/drivers/gpu/nvgpu/os/linux/driver_common.c
+++ b/drivers/gpu/nvgpu/os/linux/driver_common.c
@@ -65,6 +65,7 @@ static void nvgpu_init_vars(struct gk20a *g)
65 nvgpu_mutex_init(&g->ctxsw_disable_lock); 65 nvgpu_mutex_init(&g->ctxsw_disable_lock);
66 nvgpu_mutex_init(&g->tpc_pg_lock); 66 nvgpu_mutex_init(&g->tpc_pg_lock);
67 nvgpu_mutex_init(&g->clk_arb_enable_lock); 67 nvgpu_mutex_init(&g->clk_arb_enable_lock);
68 nvgpu_mutex_init(&g->cg_pg_lock);
68 69
69 /* Init the clock req count to 0 */ 70 /* Init the clock req count to 0 */
70 nvgpu_atomic_set(&g->clk_arb_global_nr, 0); 71 nvgpu_atomic_set(&g->clk_arb_global_nr, 0);
diff --git a/drivers/gpu/nvgpu/os/linux/sysfs.c b/drivers/gpu/nvgpu/os/linux/sysfs.c
index 1ffb6539..759c12e8 100644
--- a/drivers/gpu/nvgpu/os/linux/sysfs.c
+++ b/drivers/gpu/nvgpu/os/linux/sysfs.c
@@ -21,6 +21,8 @@
21#include <nvgpu/kmem.h> 21#include <nvgpu/kmem.h>
22#include <nvgpu/nvhost.h> 22#include <nvgpu/nvhost.h>
23#include <nvgpu/ptimer.h> 23#include <nvgpu/ptimer.h>
24#include <nvgpu/power_features/cg.h>
25#include <nvgpu/power_features/pg.h>
24 26
25#include "os_linux.h" 27#include "os_linux.h"
26#include "sysfs.h" 28#include "sysfs.h"
@@ -49,16 +51,14 @@ static ssize_t elcg_enable_store(struct device *dev,
49 return err; 51 return err;
50 52
51 if (val) { 53 if (val) {
52 g->elcg_enabled = true; 54 nvgpu_cg_elcg_set_elcg_enabled(g, true);
53 gr_gk20a_init_cg_mode(g, ELCG_MODE, ELCG_AUTO);
54 } else { 55 } else {
55 g->elcg_enabled = false; 56 nvgpu_cg_elcg_set_elcg_enabled(g, false);
56 gr_gk20a_init_cg_mode(g, ELCG_MODE, ELCG_RUN);
57 } 57 }
58 58
59 gk20a_idle(g); 59 gk20a_idle(g);
60 60
61 nvgpu_info(g, "ELCG is %s.", g->elcg_enabled ? "enabled" : 61 nvgpu_info(g, "ELCG is %s.", val ? "enabled" :
62 "disabled"); 62 "disabled");
63 63
64 return count; 64 return count;
@@ -84,45 +84,19 @@ static ssize_t blcg_enable_store(struct device *dev,
84 if (kstrtoul(buf, 10, &val) < 0) 84 if (kstrtoul(buf, 10, &val) < 0)
85 return -EINVAL; 85 return -EINVAL;
86 86
87 if (val)
88 g->blcg_enabled = true;
89 else
90 g->blcg_enabled = false;
91
92 err = gk20a_busy(g); 87 err = gk20a_busy(g);
93 if (err) 88 if (err)
94 return err; 89 return err;
95 90
96 if (g->ops.clock_gating.blcg_bus_load_gating_prod) 91 if (val) {
97 g->ops.clock_gating.blcg_bus_load_gating_prod(g, 92 nvgpu_cg_blcg_set_blcg_enabled(g, true);
98 g->blcg_enabled); 93 } else {
99 if (g->ops.clock_gating.blcg_ce_load_gating_prod) 94 nvgpu_cg_blcg_set_blcg_enabled(g, false);
100 g->ops.clock_gating.blcg_ce_load_gating_prod(g, 95 }
101 g->blcg_enabled); 96
102 if (g->ops.clock_gating.blcg_ctxsw_firmware_load_gating_prod)
103 g->ops.clock_gating.blcg_ctxsw_firmware_load_gating_prod(g,
104 g->blcg_enabled);
105 if (g->ops.clock_gating.blcg_fb_load_gating_prod)
106 g->ops.clock_gating.blcg_fb_load_gating_prod(g,
107 g->blcg_enabled);
108 if (g->ops.clock_gating.blcg_fifo_load_gating_prod)
109 g->ops.clock_gating.blcg_fifo_load_gating_prod(g,
110 g->blcg_enabled);
111 if (g->ops.clock_gating.blcg_gr_load_gating_prod)
112 g->ops.clock_gating.blcg_gr_load_gating_prod(g,
113 g->blcg_enabled);
114 if (g->ops.clock_gating.blcg_ltc_load_gating_prod)
115 g->ops.clock_gating.blcg_ltc_load_gating_prod(g,
116 g->blcg_enabled);
117 if (g->ops.clock_gating.blcg_pmu_load_gating_prod)
118 g->ops.clock_gating.blcg_pmu_load_gating_prod(g,
119 g->blcg_enabled);
120 if (g->ops.clock_gating.blcg_xbar_load_gating_prod)
121 g->ops.clock_gating.blcg_xbar_load_gating_prod(g,
122 g->blcg_enabled);
123 gk20a_idle(g); 97 gk20a_idle(g);
124 98
125 nvgpu_info(g, "BLCG is %s.", g->blcg_enabled ? "enabled" : 99 nvgpu_info(g, "BLCG is %s.", val ? "enabled" :
126 "disabled"); 100 "disabled");
127 101
128 return count; 102 return count;
@@ -149,59 +123,25 @@ static ssize_t slcg_enable_store(struct device *dev,
149 if (kstrtoul(buf, 10, &val) < 0) 123 if (kstrtoul(buf, 10, &val) < 0)
150 return -EINVAL; 124 return -EINVAL;
151 125
152 if (val) 126 err = gk20a_busy(g);
153 g->slcg_enabled = true; 127 if (err) {
154 else 128 return err;
155 g->slcg_enabled = false; 129 }
130
131 if (val) {
132 nvgpu_cg_slcg_set_slcg_enabled(g, true);
133 } else {
134 nvgpu_cg_slcg_set_slcg_enabled(g, false);
135 }
156 136
157 /* 137 /*
158 * TODO: slcg_therm_load_gating is not enabled anywhere during 138 * TODO: slcg_therm_load_gating is not enabled anywhere during
159 * init. Therefore, it would be incongruous to add it here. Once 139 * init. Therefore, it would be incongruous to add it here. Once
160 * it is added to init, we should add it here too. 140 * it is added to init, we should add it here too.
161 */ 141 */
162 err = gk20a_busy(g);
163 if (err)
164 return err;
165
166 if (g->ops.clock_gating.slcg_bus_load_gating_prod)
167 g->ops.clock_gating.slcg_bus_load_gating_prod(g,
168 g->slcg_enabled);
169 if (g->ops.clock_gating.slcg_ce2_load_gating_prod)
170 g->ops.clock_gating.slcg_ce2_load_gating_prod(g,
171 g->slcg_enabled);
172 if (g->ops.clock_gating.slcg_chiplet_load_gating_prod)
173 g->ops.clock_gating.slcg_chiplet_load_gating_prod(g,
174 g->slcg_enabled);
175 if (g->ops.clock_gating.slcg_ctxsw_firmware_load_gating_prod)
176 g->ops.clock_gating.slcg_ctxsw_firmware_load_gating_prod(g,
177 g->slcg_enabled);
178 if (g->ops.clock_gating.slcg_fb_load_gating_prod)
179 g->ops.clock_gating.slcg_fb_load_gating_prod(g,
180 g->slcg_enabled);
181 if (g->ops.clock_gating.slcg_fifo_load_gating_prod)
182 g->ops.clock_gating.slcg_fifo_load_gating_prod(g,
183 g->slcg_enabled);
184 if (g->ops.clock_gating.slcg_gr_load_gating_prod)
185 g->ops.clock_gating.slcg_gr_load_gating_prod(g,
186 g->slcg_enabled);
187 if (g->ops.clock_gating.slcg_ltc_load_gating_prod)
188 g->ops.clock_gating.slcg_ltc_load_gating_prod(g,
189 g->slcg_enabled);
190 if (g->ops.clock_gating.slcg_perf_load_gating_prod)
191 g->ops.clock_gating.slcg_perf_load_gating_prod(g,
192 g->slcg_enabled);
193 if (g->ops.clock_gating.slcg_priring_load_gating_prod)
194 g->ops.clock_gating.slcg_priring_load_gating_prod(g,
195 g->slcg_enabled);
196 if (g->ops.clock_gating.slcg_pmu_load_gating_prod)
197 g->ops.clock_gating.slcg_pmu_load_gating_prod(g,
198 g->slcg_enabled);
199 if (g->ops.clock_gating.slcg_xbar_load_gating_prod)
200 g->ops.clock_gating.slcg_xbar_load_gating_prod(g,
201 g->slcg_enabled);
202 gk20a_idle(g); 142 gk20a_idle(g);
203 143
204 nvgpu_info(g, "SLCG is %s.", g->slcg_enabled ? "enabled" : 144 nvgpu_info(g, "SLCG is %s.", val ? "enabled" :
205 "disabled"); 145 "disabled");
206 146
207 return count; 147 return count;
@@ -474,7 +414,7 @@ static ssize_t elpg_enable_store(struct device *dev,
474 return -EINVAL; 414 return -EINVAL;
475 415
476 if (!g->power_on) { 416 if (!g->power_on) {
477 g->elpg_enabled = val ? true : false; 417 return -EINVAL;
478 } else { 418 } else {
479 err = gk20a_busy(g); 419 err = gk20a_busy(g);
480 if (err) 420 if (err)
@@ -483,25 +423,14 @@ static ssize_t elpg_enable_store(struct device *dev,
483 * Since elpg is refcounted, we should not unnecessarily call 423 * Since elpg is refcounted, we should not unnecessarily call
484 * enable/disable if it is already so. 424 * enable/disable if it is already so.
485 */ 425 */
486 if (val && !g->elpg_enabled) { 426 if (val != 0) {
487 g->elpg_enabled = true; 427 nvgpu_pg_elpg_set_elpg_enabled(g, true);
488 nvgpu_pmu_pg_global_enable(g, true); 428 } else {
489 429 nvgpu_pg_elpg_set_elpg_enabled(g, false);
490 } else if (!val && g->elpg_enabled) {
491 if (g->ops.pmu.pmu_pg_engines_feature_list &&
492 g->ops.pmu.pmu_pg_engines_feature_list(g,
493 PMU_PG_ELPG_ENGINE_ID_GRAPHICS) !=
494 NVGPU_PMU_GR_FEATURE_MASK_POWER_GATING) {
495 nvgpu_pmu_pg_global_enable(g, false);
496 g->elpg_enabled = false;
497 } else {
498 g->elpg_enabled = false;
499 nvgpu_pmu_pg_global_enable(g, false);
500 }
501 } 430 }
502 gk20a_idle(g); 431 gk20a_idle(g);
503 } 432 }
504 nvgpu_info(g, "ELPG is %s.", g->elpg_enabled ? "enabled" : 433 nvgpu_info(g, "ELPG is %s.", val ? "enabled" :
505 "disabled"); 434 "disabled");
506 435
507 return count; 436 return count;
@@ -512,7 +441,8 @@ static ssize_t elpg_enable_read(struct device *dev,
512{ 441{
513 struct gk20a *g = get_gk20a(dev); 442 struct gk20a *g = get_gk20a(dev);
514 443
515 return snprintf(buf, PAGE_SIZE, "%d\n", g->elpg_enabled ? 1 : 0); 444 return snprintf(buf, PAGE_SIZE, "%d\n",
445 nvgpu_pg_elpg_is_enabled(g) ? 1 : 0);
516} 446}
517 447
518static DEVICE_ATTR(elpg_enable, ROOTRW, elpg_enable_read, elpg_enable_store); 448static DEVICE_ATTR(elpg_enable, ROOTRW, elpg_enable_read, elpg_enable_store);
@@ -610,8 +540,9 @@ static ssize_t mscg_enable_store(struct device *dev,
610 /* make status visible */ 540 /* make status visible */
611 smp_mb(); 541 smp_mb();
612 g->mscg_enabled = false; 542 g->mscg_enabled = false;
613 if (g->elpg_enabled) 543 if (nvgpu_pg_elpg_is_enabled(g)) {
614 nvgpu_pmu_pg_global_enable(g, true); 544 nvgpu_pg_elpg_enable(g);
545 }
615 } 546 }
616 g->mscg_enabled = false; 547 g->mscg_enabled = false;
617 } 548 }
diff --git a/drivers/gpu/nvgpu/os/linux/vgpu/vgpu_linux.c b/drivers/gpu/nvgpu/os/linux/vgpu/vgpu_linux.c
index 91e94696..522f1b86 100644
--- a/drivers/gpu/nvgpu/os/linux/vgpu/vgpu_linux.c
+++ b/drivers/gpu/nvgpu/os/linux/vgpu/vgpu_linux.c
@@ -69,6 +69,7 @@ static void vgpu_init_vars(struct gk20a *g, struct gk20a_platform *platform)
69 nvgpu_mutex_init(&g->power_lock); 69 nvgpu_mutex_init(&g->power_lock);
70 nvgpu_mutex_init(&g->ctxsw_disable_lock); 70 nvgpu_mutex_init(&g->ctxsw_disable_lock);
71 nvgpu_mutex_init(&g->clk_arb_enable_lock); 71 nvgpu_mutex_init(&g->clk_arb_enable_lock);
72 nvgpu_mutex_init(&g->cg_pg_lock);
72 73
73 nvgpu_mutex_init(&priv->vgpu_clk_get_freq_lock); 74 nvgpu_mutex_init(&priv->vgpu_clk_get_freq_lock);
74 75