gpu: nvgpu: add fuse clock support

1) added support for fuse clock directly from nvgpu linux build for GV11B
and GP10B.
2) added a common function platform_acquire_clock thats used by both
GP10B, GV11B to acquire their respective clocks.
3) remove use of tegra_fuse_clock_enable/disable APIs

The clock parsing code is changed to verify the clock-names obtained
via DT with the static clock-names in the platform code before proceeding
with clk_enable.

Bug 2887230

Change-Id: I177cde9c4bf1a8be6f3437f36e1c6f75cd9c9279
Signed-off-by: Debarshi Dutta <ddutta@nvidia.com>
Reviewed-on: https://git-master.nvidia.com/r/c/linux-nvgpu/+/2307136
Reviewed-by: automaticguardword <automaticguardword@nvidia.com>
Reviewed-by: Vijayakumar Subbu <vsubbu@nvidia.com>
Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com>
Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
GVS: Gerrit_Virtual_Submit
This commit is contained in:
Debarshi Dutta
2020-03-26 10:33:42 +05:30
committed by Alex Waterman
parent f9e9e41c7b
commit a2080a1208
4 changed files with 64 additions and 36 deletions

View File

@@ -1137,12 +1137,6 @@ static int gk20a_pm_railgate(struct device *dev)
g->pstats.last_rail_gate_complete = jiffies;
#endif
#ifdef CONFIG_NVGPU_TEGRA_FUSE
ret = tegra_fuse_clock_disable();
if (ret)
nvgpu_err(g, "failed to disable tegra fuse clock, err=%d", ret);
#endif
return ret;
}
@@ -1156,14 +1150,6 @@ static int gk20a_pm_unrailgate(struct device *dev)
if (!platform->unrailgate)
return 0;
#ifdef CONFIG_NVGPU_TEGRA_FUSE
ret = tegra_fuse_clock_enable();
if (ret) {
nvgpu_err(g, "failed to enable tegra fuse clock, err=%d", ret);
return ret;
}
#endif
#ifdef CONFIG_DEBUG_FS
g->pstats.last_rail_ungate_start = jiffies;
if (g->pstats.railgating_cycle_count >= 1)

View File

@@ -20,6 +20,10 @@
#define _GP10B_PLATFORM_H_
struct device;
struct gk20a_platform_clk {
char *name;
unsigned long default_rate;
};
void gp10b_tegra_clks_control(struct device *dev, bool enable);
int gp10b_tegra_get_clocks(struct device *dev);

View File

@@ -13,6 +13,7 @@
* more details.
*/
#include <linux/string.h>
#include <linux/clk.h>
#include <linux/of_platform.h>
#include <linux/debugfs.h>
@@ -51,6 +52,7 @@
#include "platform_gk20a_tegra.h"
#include "platform_gp10b.h"
#include "scale.h"
#include "module.h"
/* Select every GP10B_FREQ_SELECT_STEP'th frequency from h/w table */
#define GP10B_FREQ_SELECT_STEP 8
@@ -71,51 +73,80 @@ static int num_supported_freq;
#define GPCCLK_INIT_RATE 1000000000
static struct {
char *name;
unsigned long default_rate;
} tegra_gp10b_clocks[] = {
struct gk20a_platform_clk tegra_gp10b_clocks[] = {
{"gpu", GPCCLK_INIT_RATE},
{"gpu_sys", 204000000} };
{"gpu_sys", 204000000},
{"fuse", UINT_MAX}
};
/*
* gp10b_tegra_get_clocks()
*
* This function finds clocks in tegra platform and populates
* the clock information to gp10b platform data.
* the clock information to platform data.
*/
int gp10b_tegra_get_clocks(struct device *dev)
static int acquire_platform_clocks(struct device *dev,
struct gk20a_platform_clk *clk_entries,
unsigned int num_clk_entries)
{
struct gk20a_platform *platform = dev_get_drvdata(dev);
unsigned int i;
struct gk20a *g = platform->g;
struct device_node *np = nvgpu_get_node(g);
unsigned int i, num_clks_dt;
int err = 0;
num_clks_dt = of_clk_get_parent_count(np);
if (num_clks_dt > num_clk_entries) {
nvgpu_err(g, "maximum number of clocks supported is %d",
num_clk_entries);
return -EINVAL;
} else if (num_clks_dt == 0) {
nvgpu_err(g, "unable to read clocks from DT");
return -ENODEV;
}
platform->num_clks = 0;
for (i = 0; i < ARRAY_SIZE(tegra_gp10b_clocks); i++) {
long rate = tegra_gp10b_clocks[i].default_rate;
struct clk *c;
c = clk_get(dev, tegra_gp10b_clocks[i].name);
for (i = 0; i < num_clks_dt; i++) {
long rate;
struct clk *c = of_clk_get_by_name(np, clk_entries[i].name);
if (IS_ERR(c)) {
nvgpu_err(platform->g, "cannot get clock %s",
tegra_gp10b_clocks[i].name);
} else {
clk_set_rate(c, rate);
platform->clk[i] = c;
nvgpu_err(g, "cannot get clock %s",
clk_entries[i].name);
err = PTR_ERR(c);
goto err_get_clock;
}
rate = clk_entries[i].default_rate;
clk_set_rate(c, rate);
platform->clk[i] = c;
}
platform->num_clks = i;
#ifdef CONFIG_NV_TEGRA_BPMP
if (platform->clk[0]) {
i = tegra_bpmp_dvfs_get_clk_id(dev->of_node,
tegra_gp10b_clocks[0].name);
clk_entries[0].name);
if (i > 0)
platform->maxmin_clk_id = i;
}
#endif
return 0;
err_get_clock:
while (i--) {
clk_put(platform->clk[i]);
platform->clk[i] = NULL;
}
return err;
}
int gp10b_tegra_get_clocks(struct device *dev)
{
return acquire_platform_clocks(dev, tegra_gp10b_clocks,
ARRAY_SIZE(tegra_gp10b_clocks));
}
void gp10b_tegra_scale_init(struct device *dev)
@@ -186,7 +217,11 @@ static int gp10b_tegra_probe(struct device *dev)
nvgpu_set_enabled(g, NVGPU_CAN_RAILGATE, false);
}
gp10b_tegra_get_clocks(dev);
ret = gp10b_tegra_get_clocks(dev);
if (ret != 0) {
return ret;
}
nvgpu_linux_init_clk_support(platform->g);
nvgpu_mutex_init(&platform->clk_get_freq_lock);

View File

@@ -112,7 +112,10 @@ static int gv11b_tegra_probe(struct device *dev)
nvgpu_set_enabled(g, NVGPU_CAN_RAILGATE, false);
}
gp10b_tegra_get_clocks(dev);
err = gp10b_tegra_get_clocks(dev);
if (err != 0) {
return err;
}
nvgpu_linux_init_clk_support(platform->g);
nvgpu_mutex_init(&platform->clk_get_freq_lock);