mirror of
git://nv-tegra.nvidia.com/linux-nvgpu.git
synced 2025-12-23 18:16:01 +03:00
gpu: nvgpu: gpu railgate handling with runtime pm
Earlier implementation of railgate disable config is disabling runtime pm during pm_init. This is causing multiple issues: 1. gpu rail will be on as soon as nvgpu driver probe is called. Actual gpu hw init may happen at much later point of time. 2. This is breaking railgate_enable sysfs node functionality. railgate_enable is not working if runtime pm is disabled. To avoid all these issues for railgate disable, enable runtime pm during pm_init and set auto-suspend delay to negative (-1), which will disable runtime pm suspend calls. Also fixed following issues along with this: 1. Updated railgate_enable debugfs implementation to use auto-suspend delay. To disable railgating: Set auto-suspend delay with negative value(-1) which will disable runtime pm suspend. To enable railgating: Set auto-suspend delay with railgate_delay value. Also removed redundant user_railgate_disabled gk20a device data and replaced with can_railgate, where ever it is applicable. 2. Initialized default railgate_delay to 500msec to avoid railgate on/off transitions with railigate enable from disabled state. 3. Created railgate_residency debug fs node irrespective of can_railgate initial state. This is helping with the case, where initial state of railgate state off and then railgate enable is done through sysfs node. Bug 2073029 Change-Id: I531da6d93ba8907e806f65a1de2a447c1ec2665c Signed-off-by: seshendra Gadagottu <sgadagottu@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/1694944 Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
This commit is contained in:
committed by
Tejal Kudav
parent
0545465255
commit
40cefb666f
@@ -267,9 +267,6 @@ static int gk20a_railgating_debugfs_init(struct gk20a *g)
|
|||||||
struct nvgpu_os_linux *l = nvgpu_os_linux_from_gk20a(g);
|
struct nvgpu_os_linux *l = nvgpu_os_linux_from_gk20a(g);
|
||||||
struct dentry *d;
|
struct dentry *d;
|
||||||
|
|
||||||
if (!g->can_railgate)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
d = debugfs_create_file(
|
d = debugfs_create_file(
|
||||||
"railgate_residency", S_IRUGO|S_IWUSR, l->debugfs, g,
|
"railgate_residency", S_IRUGO|S_IWUSR, l->debugfs, g,
|
||||||
&railgate_residency_fops);
|
&railgate_residency_fops);
|
||||||
|
|||||||
@@ -168,8 +168,12 @@ static void nvgpu_init_pm_vars(struct gk20a *g)
|
|||||||
g->ptimer_src_freq = platform->ptimer_src_freq;
|
g->ptimer_src_freq = platform->ptimer_src_freq;
|
||||||
g->support_pmu = support_gk20a_pmu(dev_from_gk20a(g));
|
g->support_pmu = support_gk20a_pmu(dev_from_gk20a(g));
|
||||||
g->can_railgate = platform->can_railgate_init;
|
g->can_railgate = platform->can_railgate_init;
|
||||||
g->railgate_delay = platform->railgate_delay_init;
|
|
||||||
g->ldiv_slowdown_factor = platform->ldiv_slowdown_factor_init;
|
g->ldiv_slowdown_factor = platform->ldiv_slowdown_factor_init;
|
||||||
|
/* if default delay is not set, set default delay to 500msec */
|
||||||
|
if (platform->railgate_delay_init)
|
||||||
|
g->railgate_delay = platform->railgate_delay_init;
|
||||||
|
else
|
||||||
|
g->railgate_delay = NVGPU_DEFAULT_RAILGATE_IDLE_TIMEOUT;
|
||||||
__nvgpu_set_enabled(g, NVGPU_PMU_PERFMON, platform->enable_perfmon);
|
__nvgpu_set_enabled(g, NVGPU_PMU_PERFMON, platform->enable_perfmon);
|
||||||
|
|
||||||
/* set default values to aelpg parameters */
|
/* set default values to aelpg parameters */
|
||||||
|
|||||||
@@ -458,10 +458,10 @@ int __gk20a_do_idle(struct gk20a *g, bool force_reset)
|
|||||||
* If User disables rail gating, we take one more
|
* If User disables rail gating, we take one more
|
||||||
* extra refcount
|
* extra refcount
|
||||||
*/
|
*/
|
||||||
if (g->user_railgate_disabled)
|
if (g->can_railgate)
|
||||||
target_ref_cnt = 2;
|
|
||||||
else
|
|
||||||
target_ref_cnt = 1;
|
target_ref_cnt = 1;
|
||||||
|
else
|
||||||
|
target_ref_cnt = 2;
|
||||||
nvgpu_mutex_acquire(&platform->railgate_lock);
|
nvgpu_mutex_acquire(&platform->railgate_lock);
|
||||||
|
|
||||||
nvgpu_timeout_init(g, &timeout, GK20A_WAIT_FOR_IDLE_MS,
|
nvgpu_timeout_init(g, &timeout, GK20A_WAIT_FOR_IDLE_MS,
|
||||||
@@ -964,7 +964,7 @@ static int gk20a_pm_suspend(struct device *dev)
|
|||||||
struct gk20a_platform *platform = dev_get_drvdata(dev);
|
struct gk20a_platform *platform = dev_get_drvdata(dev);
|
||||||
struct gk20a *g = get_gk20a(dev);
|
struct gk20a *g = get_gk20a(dev);
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
int idle_usage_count = g->user_railgate_disabled ? 1 : 0;
|
int idle_usage_count = 0;
|
||||||
|
|
||||||
if (!g->power_on) {
|
if (!g->power_on) {
|
||||||
if (!pm_runtime_enabled(dev))
|
if (!pm_runtime_enabled(dev))
|
||||||
@@ -1020,23 +1020,19 @@ static int gk20a_pm_init(struct device *dev)
|
|||||||
|
|
||||||
nvgpu_log_fn(g, " ");
|
nvgpu_log_fn(g, " ");
|
||||||
|
|
||||||
/* Initialise pm runtime */
|
/*
|
||||||
if (g->railgate_delay) {
|
* Initialise pm runtime. For railgate disable
|
||||||
|
* case, set autosuspend delay to negative which
|
||||||
|
* will suspend runtime pm
|
||||||
|
*/
|
||||||
|
if (g->railgate_delay && g->can_railgate)
|
||||||
pm_runtime_set_autosuspend_delay(dev,
|
pm_runtime_set_autosuspend_delay(dev,
|
||||||
g->railgate_delay);
|
g->railgate_delay);
|
||||||
pm_runtime_use_autosuspend(dev);
|
else
|
||||||
}
|
pm_runtime_set_autosuspend_delay(dev, -1);
|
||||||
|
|
||||||
if (g->can_railgate) {
|
pm_runtime_use_autosuspend(dev);
|
||||||
pm_runtime_enable(dev);
|
pm_runtime_enable(dev);
|
||||||
if (!pm_runtime_enabled(dev))
|
|
||||||
gk20a_pm_unrailgate(dev);
|
|
||||||
else
|
|
||||||
gk20a_pm_railgate(dev);
|
|
||||||
} else {
|
|
||||||
__pm_runtime_disable(dev, false);
|
|
||||||
gk20a_pm_unrailgate(dev);
|
|
||||||
}
|
|
||||||
|
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -305,24 +305,23 @@ static ssize_t railgate_enable_store(struct device *dev,
|
|||||||
unsigned long railgate_enable = 0;
|
unsigned long railgate_enable = 0;
|
||||||
/* dev is guaranteed to be valid here. Ok to de-reference */
|
/* dev is guaranteed to be valid here. Ok to de-reference */
|
||||||
struct gk20a *g = get_gk20a(dev);
|
struct gk20a *g = get_gk20a(dev);
|
||||||
int err = 0;
|
int err;
|
||||||
|
|
||||||
if (kstrtoul(buf, 10, &railgate_enable) < 0)
|
if (kstrtoul(buf, 10, &railgate_enable) < 0)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
if (railgate_enable && !g->can_railgate) {
|
if (railgate_enable && !g->can_railgate) {
|
||||||
/* release extra ref count */
|
|
||||||
gk20a_idle(g);
|
|
||||||
g->can_railgate = true;
|
g->can_railgate = true;
|
||||||
g->user_railgate_disabled = false;
|
pm_runtime_set_autosuspend_delay(dev, g->railgate_delay);
|
||||||
} else if (railgate_enable == 0 && g->can_railgate) {
|
} else if (railgate_enable == 0 && g->can_railgate) {
|
||||||
/* take extra ref count */
|
|
||||||
err = gk20a_busy(g);
|
|
||||||
if (err)
|
|
||||||
return err;
|
|
||||||
g->can_railgate = false;
|
g->can_railgate = false;
|
||||||
g->user_railgate_disabled = true;
|
pm_runtime_set_autosuspend_delay(dev, -1);
|
||||||
}
|
}
|
||||||
|
/* wake-up system to make rail-gating setting effective */
|
||||||
|
err = gk20a_busy(g);
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
gk20a_idle(g);
|
||||||
|
|
||||||
nvgpu_info(g, "railgate is %s.", g->can_railgate ?
|
nvgpu_info(g, "railgate is %s.", g->can_railgate ?
|
||||||
"enabled" : "disabled");
|
"enabled" : "disabled");
|
||||||
|
|||||||
@@ -370,9 +370,6 @@ int gk20a_wait_for_idle(struct gk20a *g)
|
|||||||
if (!g)
|
if (!g)
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
|
|
||||||
if (g->user_railgate_disabled)
|
|
||||||
target_usage_count = 1;
|
|
||||||
|
|
||||||
while ((nvgpu_atomic_read(&g->usage_count) != target_usage_count)
|
while ((nvgpu_atomic_read(&g->usage_count) != target_usage_count)
|
||||||
&& (wait_length-- >= 0))
|
&& (wait_length-- >= 0))
|
||||||
nvgpu_msleep(20);
|
nvgpu_msleep(20);
|
||||||
|
|||||||
@@ -1358,7 +1358,6 @@ struct gk20a {
|
|||||||
u32 ptimer_src_freq;
|
u32 ptimer_src_freq;
|
||||||
|
|
||||||
bool can_railgate;
|
bool can_railgate;
|
||||||
bool user_railgate_disabled;
|
|
||||||
int railgate_delay;
|
int railgate_delay;
|
||||||
u8 ldiv_slowdown_factor;
|
u8 ldiv_slowdown_factor;
|
||||||
unsigned int aggressive_sync_destroy_thresh;
|
unsigned int aggressive_sync_destroy_thresh;
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2017, NVIDIA CORPORATION. All rights reserved.
|
* Copyright (c) 2017-2018, NVIDIA CORPORATION. All rights reserved.
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
* copy of this software and associated documentation files (the "Software"),
|
* copy of this software and associated documentation files (the "Software"),
|
||||||
@@ -28,4 +28,6 @@
|
|||||||
*/
|
*/
|
||||||
#define NVGPU_DEFAULT_GR_IDLE_TIMEOUT 3000
|
#define NVGPU_DEFAULT_GR_IDLE_TIMEOUT 3000
|
||||||
|
|
||||||
|
#define NVGPU_DEFAULT_RAILGATE_IDLE_TIMEOUT 500
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
Reference in New Issue
Block a user