mirror of
git://nv-tegra.nvidia.com/linux-nvgpu.git
synced 2025-12-22 09:12:24 +03:00
gpu: nvgpu: acquire platforms clocks on floorsweeping gpc
bpmp will floorsweep GPCs as per parameters to tpc_pg_mask sysfs.
While doing that corresponding GPC clocks are also disabled.
nvgpu should re-initialize the clocks every time the
GPC/TPC pg_masks are passed to bpmp mrq.
Also print error when clk_prepare_enable fails.
Introduce platform->clks_lock to protect access to platform->clks
and platform->num_clks done from unrailgate/railgate and bpmp
mrq set calls from sysfs.
Acquire static_pg_lock in railgate path to synchronize railgate
with sysfs.
Bug 3688506
Change-Id: I3203d78b87289e7a847d78b3117e2d3119be3425
Signed-off-by: Sagar Kamble <skamble@nvidia.com>
Reviewed-on: https://git-master.nvidia.com/r/c/linux-nvgpu/+/2738920
(cherry picked from commit 28ddb0996f)
Reviewed-on: https://git-master.nvidia.com/r/c/linux-nvgpu/+/2741029
Reviewed-by: svc-mobile-coverity <svc-mobile-coverity@nvidia.com>
Reviewed-by: Vijayakumar Subbu <vsubbu@nvidia.com>
GVS: Gerrit_Virtual_Submit
This commit is contained in:
committed by
mobile promotions
parent
fb466b5b25
commit
c99819ffd8
@@ -1177,12 +1177,17 @@ static int gk20a_pm_railgate(struct device *dev)
|
||||
g->pstats.last_rail_ungate_complete);
|
||||
#endif
|
||||
|
||||
nvgpu_mutex_acquire(&g->static_pg_lock);
|
||||
|
||||
ret = platform->railgate(dev);
|
||||
if (ret) {
|
||||
nvgpu_err(g, "failed to railgate platform, err=%d", ret);
|
||||
nvgpu_mutex_release(&g->static_pg_lock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
nvgpu_mutex_release(&g->static_pg_lock);
|
||||
|
||||
#ifdef CONFIG_DEBUG_FS
|
||||
g->pstats.last_rail_gate_complete = jiffies;
|
||||
#endif
|
||||
|
||||
@@ -123,14 +123,16 @@ static bool ga10b_tegra_is_clock_available(struct gk20a *g, char *clk_name)
|
||||
}
|
||||
|
||||
if ((strcmp(clk_name, "gpc0clk") == 0) &&
|
||||
(gpc_disable & NVGPU_GPC0_DISABLE)) {
|
||||
nvgpu_info(g, "GPC0 is floor-swept");
|
||||
((gpc_disable & NVGPU_GPC0_DISABLE) ||
|
||||
(g->gpc_pg_mask & NVGPU_GPC0_DISABLE))) {
|
||||
nvgpu_log_info(g, "GPC0 is floor-swept");
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((strcmp(clk_name, "gpc1clk") == 0) &&
|
||||
(gpc_disable & NVGPU_GPC1_DISABLE)) {
|
||||
nvgpu_info(g, "GPC1 is floor-swept");
|
||||
((gpc_disable & NVGPU_GPC1_DISABLE) ||
|
||||
(g->gpc_pg_mask & NVGPU_GPC1_DISABLE))) {
|
||||
nvgpu_log_info(g, "GPC1 is floor-swept");
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -149,7 +151,7 @@ static int ga10b_tegra_acquire_platform_clocks(struct device *dev,
|
||||
struct gk20a_platform *platform = dev_get_drvdata(dev);
|
||||
struct gk20a *g = platform->g;
|
||||
struct device_node *np = nvgpu_get_node(g);
|
||||
unsigned int i, num_clks_dt;
|
||||
unsigned int i, j = 0, num_clks_dt;
|
||||
int err;
|
||||
|
||||
/* Get clocks only on supported platforms(silicon and fpga) */
|
||||
@@ -167,6 +169,8 @@ static int ga10b_tegra_acquire_platform_clocks(struct device *dev,
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
nvgpu_mutex_acquire(&platform->clks_lock);
|
||||
|
||||
platform->num_clks = 0;
|
||||
|
||||
for (i = 0; i < num_clks_dt; i++) {
|
||||
@@ -187,11 +191,17 @@ static int ga10b_tegra_acquire_platform_clocks(struct device *dev,
|
||||
} else {
|
||||
rate = clk_entries[i].default_rate;
|
||||
clk_set_rate(c, rate);
|
||||
platform->clk[i] = c;
|
||||
|
||||
/*
|
||||
* Note that DT clocks are iterated by index 'i' and
|
||||
* available clocks are iterated by index 'j' in the
|
||||
* platform->clk array.
|
||||
*/
|
||||
platform->clk[j++] = c;
|
||||
}
|
||||
}
|
||||
|
||||
platform->num_clks = i;
|
||||
platform->num_clks = j;
|
||||
|
||||
#ifdef CONFIG_NV_TEGRA_BPMP
|
||||
if (platform->clk[0]) {
|
||||
@@ -202,14 +212,18 @@ static int ga10b_tegra_acquire_platform_clocks(struct device *dev,
|
||||
}
|
||||
#endif
|
||||
|
||||
nvgpu_mutex_release(&platform->clks_lock);
|
||||
|
||||
return 0;
|
||||
|
||||
err_get_clock:
|
||||
while (i > 0 && i--) {
|
||||
clk_put(platform->clk[i]);
|
||||
platform->clk[i] = NULL;
|
||||
while (j > 0 && j--) {
|
||||
clk_put(platform->clk[j]);
|
||||
platform->clk[j] = NULL;
|
||||
}
|
||||
|
||||
nvgpu_mutex_release(&platform->clks_lock);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
@@ -292,6 +306,8 @@ static int ga10b_tegra_probe(struct device *dev)
|
||||
nvgpu_set_enabled(g, NVGPU_CAN_RAILGATE, false);
|
||||
}
|
||||
|
||||
nvgpu_mutex_init(&platform->clks_lock);
|
||||
|
||||
err = ga10b_tegra_get_clocks(dev);
|
||||
if (err != 0) {
|
||||
return err;
|
||||
@@ -326,6 +342,7 @@ static int ga10b_tegra_remove(struct device *dev)
|
||||
#endif
|
||||
|
||||
nvgpu_mutex_destroy(&platform->clk_get_freq_lock);
|
||||
nvgpu_mutex_destroy(&platform->clks_lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -434,6 +451,13 @@ static int ga10b_tegra_bpmp_mrq_set(struct device *dev)
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
/* re-initialize the clocks */
|
||||
ret = ga10b_tegra_get_clocks(dev);
|
||||
if (ret != 0) {
|
||||
nvgpu_err(g, "get clocks failed ");
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
|
||||
@@ -342,6 +342,9 @@ struct gk20a_platform {
|
||||
|
||||
/* synchronized access to platform->clk_get_freqs */
|
||||
struct nvgpu_mutex clk_get_freq_lock;
|
||||
|
||||
/* synchronized access to platform->clks */
|
||||
struct nvgpu_mutex clks_lock;
|
||||
};
|
||||
|
||||
static inline struct gk20a_platform *gk20a_get_platform(
|
||||
|
||||
@@ -96,6 +96,8 @@ int gp10b_tegra_acquire_platform_clocks(struct device *dev,
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
nvgpu_mutex_acquire(&platform->clks_lock);
|
||||
|
||||
platform->num_clks = 0;
|
||||
|
||||
for (i = 0; i < num_clks_dt; i++) {
|
||||
@@ -124,6 +126,8 @@ int gp10b_tegra_acquire_platform_clocks(struct device *dev,
|
||||
}
|
||||
#endif
|
||||
|
||||
nvgpu_mutex_release(&platform->clks_lock);
|
||||
|
||||
return 0;
|
||||
|
||||
err_get_clock:
|
||||
@@ -132,6 +136,8 @@ err_get_clock:
|
||||
platform->clk[i] = NULL;
|
||||
}
|
||||
|
||||
nvgpu_mutex_release(&platform->clks_lock);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
@@ -166,8 +172,11 @@ void gp10b_tegra_clks_control(struct device *dev, bool enable)
|
||||
{
|
||||
struct gk20a_platform *platform = gk20a_get_platform(dev);
|
||||
struct gk20a *g = get_gk20a(dev);
|
||||
int err;
|
||||
int i;
|
||||
|
||||
nvgpu_mutex_acquire(&platform->clks_lock);
|
||||
|
||||
for (i = 0; i < platform->num_clks; i++) {
|
||||
if (!platform->clk[i]) {
|
||||
continue;
|
||||
@@ -176,13 +185,18 @@ void gp10b_tegra_clks_control(struct device *dev, bool enable)
|
||||
if (enable) {
|
||||
nvgpu_log(g, gpu_dbg_info,
|
||||
"clk_prepare_enable");
|
||||
clk_prepare_enable(platform->clk[i]);
|
||||
err = clk_prepare_enable(platform->clk[i]);
|
||||
if (err != 0) {
|
||||
nvgpu_err(g, "could not turn on clock %d", i);
|
||||
}
|
||||
} else {
|
||||
nvgpu_log(g, gpu_dbg_info,
|
||||
"clk_disable_unprepare");
|
||||
clk_disable_unprepare(platform->clk[i]);
|
||||
}
|
||||
}
|
||||
|
||||
nvgpu_mutex_release(&platform->clks_lock);
|
||||
}
|
||||
|
||||
int gp10b_tegra_reset_assert(struct device *dev)
|
||||
|
||||
@@ -105,6 +105,8 @@ static int gv11b_tegra_probe(struct device *dev)
|
||||
nvgpu_set_enabled(g, NVGPU_CAN_RAILGATE, false);
|
||||
}
|
||||
|
||||
nvgpu_mutex_init(&platform->clks_lock);
|
||||
|
||||
err = gp10b_tegra_get_clocks(dev);
|
||||
if (err != 0) {
|
||||
return err;
|
||||
@@ -140,6 +142,7 @@ static int gv11b_tegra_remove(struct device *dev)
|
||||
#endif
|
||||
|
||||
nvgpu_mutex_destroy(&platform->clk_get_freq_lock);
|
||||
nvgpu_mutex_destroy(&platform->clks_lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user