mirror of
git://nv-tegra.nvidia.com/linux-nvgpu.git
synced 2025-12-22 17:36:20 +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 Reviewed-by: Amulya Yarlagadda <ayarlagadda@nvidia.com> GVS: Gerrit_Virtual_Submit
This commit is contained in:
committed by
mobile promotions
parent
96292d688b
commit
28ddb0996f
@@ -1177,12 +1177,17 @@ static int gk20a_pm_railgate(struct device *dev)
|
|||||||
g->pstats.last_rail_ungate_complete);
|
g->pstats.last_rail_ungate_complete);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
nvgpu_mutex_acquire(&g->static_pg_lock);
|
||||||
|
|
||||||
ret = platform->railgate(dev);
|
ret = platform->railgate(dev);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
nvgpu_err(g, "failed to railgate platform, err=%d", ret);
|
nvgpu_err(g, "failed to railgate platform, err=%d", ret);
|
||||||
|
nvgpu_mutex_release(&g->static_pg_lock);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nvgpu_mutex_release(&g->static_pg_lock);
|
||||||
|
|
||||||
#ifdef CONFIG_DEBUG_FS
|
#ifdef CONFIG_DEBUG_FS
|
||||||
g->pstats.last_rail_gate_complete = jiffies;
|
g->pstats.last_rail_gate_complete = jiffies;
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -123,14 +123,16 @@ static bool ga10b_tegra_is_clock_available(struct gk20a *g, char *clk_name)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ((strcmp(clk_name, "gpc0clk") == 0) &&
|
if ((strcmp(clk_name, "gpc0clk") == 0) &&
|
||||||
(gpc_disable & NVGPU_GPC0_DISABLE)) {
|
((gpc_disable & NVGPU_GPC0_DISABLE) ||
|
||||||
nvgpu_info(g, "GPC0 is floor-swept");
|
(g->gpc_pg_mask & NVGPU_GPC0_DISABLE))) {
|
||||||
|
nvgpu_log_info(g, "GPC0 is floor-swept");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((strcmp(clk_name, "gpc1clk") == 0) &&
|
if ((strcmp(clk_name, "gpc1clk") == 0) &&
|
||||||
(gpc_disable & NVGPU_GPC1_DISABLE)) {
|
((gpc_disable & NVGPU_GPC1_DISABLE) ||
|
||||||
nvgpu_info(g, "GPC1 is floor-swept");
|
(g->gpc_pg_mask & NVGPU_GPC1_DISABLE))) {
|
||||||
|
nvgpu_log_info(g, "GPC1 is floor-swept");
|
||||||
return false;
|
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_platform *platform = dev_get_drvdata(dev);
|
||||||
struct gk20a *g = platform->g;
|
struct gk20a *g = platform->g;
|
||||||
struct device_node *np = nvgpu_get_node(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;
|
int err;
|
||||||
|
|
||||||
/* Get clocks only on supported platforms(silicon and fpga) */
|
/* 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;
|
return -ENODEV;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nvgpu_mutex_acquire(&platform->clks_lock);
|
||||||
|
|
||||||
platform->num_clks = 0;
|
platform->num_clks = 0;
|
||||||
|
|
||||||
for (i = 0; i < num_clks_dt; i++) {
|
for (i = 0; i < num_clks_dt; i++) {
|
||||||
@@ -187,11 +191,17 @@ static int ga10b_tegra_acquire_platform_clocks(struct device *dev,
|
|||||||
} else {
|
} else {
|
||||||
rate = clk_entries[i].default_rate;
|
rate = clk_entries[i].default_rate;
|
||||||
clk_set_rate(c, 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
|
#ifdef CONFIG_NV_TEGRA_BPMP
|
||||||
if (platform->clk[0]) {
|
if (platform->clk[0]) {
|
||||||
@@ -202,14 +212,18 @@ static int ga10b_tegra_acquire_platform_clocks(struct device *dev,
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
nvgpu_mutex_release(&platform->clks_lock);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
err_get_clock:
|
err_get_clock:
|
||||||
while (i > 0 && i--) {
|
while (j > 0 && j--) {
|
||||||
clk_put(platform->clk[i]);
|
clk_put(platform->clk[j]);
|
||||||
platform->clk[i] = NULL;
|
platform->clk[j] = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nvgpu_mutex_release(&platform->clks_lock);
|
||||||
|
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -292,6 +306,8 @@ static int ga10b_tegra_probe(struct device *dev)
|
|||||||
nvgpu_set_enabled(g, NVGPU_CAN_RAILGATE, false);
|
nvgpu_set_enabled(g, NVGPU_CAN_RAILGATE, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nvgpu_mutex_init(&platform->clks_lock);
|
||||||
|
|
||||||
err = ga10b_tegra_get_clocks(dev);
|
err = ga10b_tegra_get_clocks(dev);
|
||||||
if (err != 0) {
|
if (err != 0) {
|
||||||
return err;
|
return err;
|
||||||
@@ -326,6 +342,7 @@ static int ga10b_tegra_remove(struct device *dev)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
nvgpu_mutex_destroy(&platform->clk_get_freq_lock);
|
nvgpu_mutex_destroy(&platform->clk_get_freq_lock);
|
||||||
|
nvgpu_mutex_destroy(&platform->clks_lock);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -434,6 +451,13 @@ static int ga10b_tegra_bpmp_mrq_set(struct device *dev)
|
|||||||
return ret;
|
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;
|
return 0;
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* GK20A Platform (SoC) Interface
|
* GK20A Platform (SoC) Interface
|
||||||
*
|
*
|
||||||
* Copyright (c) 2014-2021, NVIDIA CORPORATION. All rights reserved.
|
* Copyright (c) 2014-2022, NVIDIA CORPORATION. All rights reserved.
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify it
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
* under the terms and conditions of the GNU General Public License,
|
* under the terms and conditions of the GNU General Public License,
|
||||||
@@ -333,6 +333,9 @@ struct gk20a_platform {
|
|||||||
|
|
||||||
/* synchronized access to platform->clk_get_freqs */
|
/* synchronized access to platform->clk_get_freqs */
|
||||||
struct nvgpu_mutex clk_get_freq_lock;
|
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(
|
static inline struct gk20a_platform *gk20a_get_platform(
|
||||||
|
|||||||
@@ -96,6 +96,8 @@ int gp10b_tegra_acquire_platform_clocks(struct device *dev,
|
|||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nvgpu_mutex_acquire(&platform->clks_lock);
|
||||||
|
|
||||||
platform->num_clks = 0;
|
platform->num_clks = 0;
|
||||||
|
|
||||||
for (i = 0; i < num_clks_dt; i++) {
|
for (i = 0; i < num_clks_dt; i++) {
|
||||||
@@ -124,6 +126,8 @@ int gp10b_tegra_acquire_platform_clocks(struct device *dev,
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
nvgpu_mutex_release(&platform->clks_lock);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
err_get_clock:
|
err_get_clock:
|
||||||
@@ -132,6 +136,8 @@ err_get_clock:
|
|||||||
platform->clk[i] = NULL;
|
platform->clk[i] = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nvgpu_mutex_release(&platform->clks_lock);
|
||||||
|
|
||||||
return err;
|
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_platform *platform = gk20a_get_platform(dev);
|
||||||
struct gk20a *g = get_gk20a(dev);
|
struct gk20a *g = get_gk20a(dev);
|
||||||
|
int err;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
nvgpu_mutex_acquire(&platform->clks_lock);
|
||||||
|
|
||||||
for (i = 0; i < platform->num_clks; i++) {
|
for (i = 0; i < platform->num_clks; i++) {
|
||||||
if (!platform->clk[i]) {
|
if (!platform->clk[i]) {
|
||||||
continue;
|
continue;
|
||||||
@@ -176,13 +185,18 @@ void gp10b_tegra_clks_control(struct device *dev, bool enable)
|
|||||||
if (enable) {
|
if (enable) {
|
||||||
nvgpu_log(g, gpu_dbg_info,
|
nvgpu_log(g, gpu_dbg_info,
|
||||||
"clk_prepare_enable");
|
"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 {
|
} else {
|
||||||
nvgpu_log(g, gpu_dbg_info,
|
nvgpu_log(g, gpu_dbg_info,
|
||||||
"clk_disable_unprepare");
|
"clk_disable_unprepare");
|
||||||
clk_disable_unprepare(platform->clk[i]);
|
clk_disable_unprepare(platform->clk[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nvgpu_mutex_release(&platform->clks_lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
int gp10b_tegra_reset_assert(struct device *dev)
|
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_set_enabled(g, NVGPU_CAN_RAILGATE, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nvgpu_mutex_init(&platform->clks_lock);
|
||||||
|
|
||||||
err = gp10b_tegra_get_clocks(dev);
|
err = gp10b_tegra_get_clocks(dev);
|
||||||
if (err != 0) {
|
if (err != 0) {
|
||||||
return err;
|
return err;
|
||||||
@@ -140,6 +142,7 @@ static int gv11b_tegra_remove(struct device *dev)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
nvgpu_mutex_destroy(&platform->clk_get_freq_lock);
|
nvgpu_mutex_destroy(&platform->clk_get_freq_lock);
|
||||||
|
nvgpu_mutex_destroy(&platform->clks_lock);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user