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:
Sagar Kamble
2022-07-02 22:12:02 +05:30
committed by mobile promotions
parent fb466b5b25
commit c99819ffd8
5 changed files with 60 additions and 11 deletions

View File

@@ -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

View File

@@ -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;

View File

@@ -342,6 +342,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(

View File

@@ -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)

View File

@@ -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;
} }