mirror of
git://nv-tegra.nvidia.com/linux-nvgpu.git
synced 2025-12-24 10:34:43 +03:00
gpu: nvgpu: scaling driver update
Update scaling driver to support to differnt clock frameworks. Bug 200147662 Reviewed-on: http://git-master/r/816929 (cherry picked from commit cbd4cb575fb2d27870089797ff2a8f22540b87e8) Change-Id: Ie50304b4a593d74bd43b271005cc9616fdb52a6e Signed-off-by: Seshendra Gadagottu <sgadagottu@nvidia.com> Reviewed-on: http://git-master/r/834748 Reviewed-by: Terje Bergstrom <tbergstrom@nvidia.com> Tested-by: Terje Bergstrom <tbergstrom@nvidia.com>
This commit is contained in:
committed by
Terje Bergstrom
parent
d3cf581199
commit
acde16dd16
@@ -36,7 +36,7 @@ config GK20A_PERFMON
|
||||
decrease frequency if idle).
|
||||
|
||||
config GK20A_DEVFREQ
|
||||
depends on TEGRA_CLK_FRAMEWORK
|
||||
depends on TEGRA_CLK_FRAMEWORK || COMMON_CLK
|
||||
bool "Use Devfreq"
|
||||
help
|
||||
Select this to use devfreq based scaling.
|
||||
|
||||
@@ -56,7 +56,8 @@ static int gk20a_scale_qos_notify(struct notifier_block *nb,
|
||||
|
||||
/* get the frequency requirement. if devfreq is enabled, check if it
|
||||
* has higher demand than qos */
|
||||
freq = gk20a_clk_round_rate(g, pm_qos_request(platform->qos_id));
|
||||
freq = platform->clk_round_rate(profile->pdev,
|
||||
pm_qos_request(platform->qos_id));
|
||||
if (g->devfreq)
|
||||
freq = max(g->devfreq->previous_freq, freq);
|
||||
|
||||
@@ -76,17 +77,13 @@ static int gk20a_scale_qos_notify(struct notifier_block *nb,
|
||||
|
||||
static int gk20a_scale_make_freq_table(struct gk20a_scale_profile *profile)
|
||||
{
|
||||
struct gk20a *g = get_gk20a(profile->pdev);
|
||||
unsigned long *freqs;
|
||||
struct gk20a_platform *platform = platform_get_drvdata(profile->pdev);
|
||||
int num_freqs, err;
|
||||
unsigned long *freqs;
|
||||
|
||||
/* make sure the clock is available */
|
||||
if (!gk20a_clk_get(g))
|
||||
return -ENOSYS;
|
||||
|
||||
/* get gpu dvfs table */
|
||||
err = tegra_dvfs_get_freqs(clk_get_parent(g->clk.tegra_clk),
|
||||
&freqs, &num_freqs);
|
||||
/* get gpu frequency table */
|
||||
err = platform->get_clk_freqs(profile->pdev, &freqs,
|
||||
&num_freqs);
|
||||
if (err)
|
||||
return -ENOSYS;
|
||||
|
||||
@@ -105,23 +102,23 @@ static int gk20a_scale_make_freq_table(struct gk20a_scale_profile *profile)
|
||||
static int gk20a_scale_target(struct device *dev, unsigned long *freq,
|
||||
u32 flags)
|
||||
{
|
||||
struct gk20a *g = get_gk20a(to_platform_device(dev));
|
||||
struct gk20a_platform *platform = dev_get_drvdata(dev);
|
||||
struct gk20a_scale_profile *profile = g->scale_profile;
|
||||
unsigned long rounded_rate = gk20a_clk_round_rate(g, *freq);
|
||||
struct platform_device *pdev = to_platform_device(dev);
|
||||
unsigned long rounded_rate =
|
||||
platform->clk_round_rate(pdev, *freq);
|
||||
|
||||
if (gk20a_clk_get_rate(g) == rounded_rate)
|
||||
if (platform->clk_get_rate(pdev) == rounded_rate)
|
||||
*freq = rounded_rate;
|
||||
else {
|
||||
gk20a_clk_set_rate(g, rounded_rate);
|
||||
*freq = gk20a_clk_get_rate(g);
|
||||
platform->clk_set_rate(pdev, rounded_rate);
|
||||
*freq = platform->clk_get_rate(pdev);
|
||||
}
|
||||
|
||||
/* postscale will only scale emc (dram clock) if evaluating
|
||||
* gk20a_tegra_get_emc_rate() produces a new or different emc
|
||||
* target because the load or_and gpufreq has changed */
|
||||
if (platform->postscale)
|
||||
platform->postscale(profile->pdev, rounded_rate);
|
||||
platform->postscale(pdev, rounded_rate);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -237,9 +234,12 @@ static int gk20a_scale_get_dev_status(struct device *dev,
|
||||
{
|
||||
struct gk20a *g = get_gk20a(to_platform_device(dev));
|
||||
struct gk20a_scale_profile *profile = g->scale_profile;
|
||||
struct platform_device *pdev = to_platform_device(dev);
|
||||
struct gk20a_platform *platform = platform_get_drvdata(pdev);
|
||||
|
||||
/* Make sure there are correct values for the current frequency */
|
||||
profile->dev_stat.current_frequency = gk20a_clk_get_rate(g);
|
||||
profile->dev_stat.current_frequency =
|
||||
platform->clk_get_rate(profile->pdev);
|
||||
|
||||
/* Update load estimate */
|
||||
update_load_estimate_gpmu(to_platform_device(dev));
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* gk20a clock scaling profile
|
||||
*
|
||||
* Copyright (c) 2013-2014, NVIDIA Corporation. All rights reserved.
|
||||
* Copyright (c) 2013-2015, NVIDIA Corporation. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
@@ -38,7 +38,7 @@ void gk20a_scale_init(struct platform_device *);
|
||||
void gk20a_scale_exit(struct platform_device *);
|
||||
void gk20a_scale_hw_init(struct platform_device *pdev);
|
||||
|
||||
#ifdef CONFIG_GK20A_DEVFREQ
|
||||
#if defined(CONFIG_GK20A_DEVFREQ)
|
||||
/*
|
||||
* call when performing submit to notify scaling mechanism that the module is
|
||||
* in use
|
||||
|
||||
@@ -154,6 +154,18 @@ struct gk20a_platform {
|
||||
/* Called to check state of device */
|
||||
bool (*is_railgated)(struct platform_device *dev);
|
||||
|
||||
/* get supported frequency list */
|
||||
int (*get_clk_freqs)(struct platform_device *pdev,
|
||||
unsigned long **freqs, int *num_freqs);
|
||||
|
||||
/* clk related supported functions */
|
||||
unsigned long (*clk_get_rate)(struct platform_device *pdev);
|
||||
long (*clk_round_rate)(struct platform_device *pdev,
|
||||
unsigned long rate);
|
||||
int (*clk_set_rate)(struct platform_device *pdev,
|
||||
unsigned long rate);
|
||||
|
||||
|
||||
/* Postscale callback is called after frequency change */
|
||||
void (*postscale)(struct platform_device *pdev,
|
||||
unsigned long freq);
|
||||
|
||||
@@ -800,6 +800,49 @@ static int gk20a_tegra_suspend(struct device *dev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_TEGRA_CLK_FRAMEWORK
|
||||
static unsigned long gk20a_get_clk_rate(struct platform_device *dev)
|
||||
{
|
||||
struct gk20a_platform *platform = gk20a_get_platform(dev);
|
||||
struct gk20a *g = platform->g;
|
||||
|
||||
return gk20a_clk_get_rate(g);
|
||||
|
||||
}
|
||||
|
||||
static long gk20a_round_clk_rate(struct platform_device *dev,
|
||||
unsigned long rate)
|
||||
{
|
||||
struct gk20a_platform *platform = gk20a_get_platform(dev);
|
||||
struct gk20a *g = platform->g;
|
||||
|
||||
return gk20a_clk_round_rate(g, rate);
|
||||
}
|
||||
|
||||
int gk20a_set_clk_rate(struct platform_device *dev, unsigned long rate)
|
||||
{
|
||||
struct gk20a_platform *platform = gk20a_get_platform(dev);
|
||||
struct gk20a *g = platform->g;
|
||||
|
||||
return gk20a_clk_set_rate(g, rate);
|
||||
}
|
||||
|
||||
static int gk20a_clk_get_freqs(struct platform_device *dev,
|
||||
unsigned long **freqs, int *num_freqs)
|
||||
{
|
||||
struct gk20a_platform *platform = gk20a_get_platform(dev);
|
||||
struct gk20a *g = platform->g;
|
||||
|
||||
/* make sure the clock is available */
|
||||
if (!gk20a_clk_get(g))
|
||||
return -ENOSYS;
|
||||
|
||||
return tegra_dvfs_get_freqs(clk_get_parent(g->clk.tegra_clk),
|
||||
freqs, num_freqs);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
struct gk20a_platform gk20a_tegra_platform = {
|
||||
.has_syncpoints = true,
|
||||
|
||||
@@ -838,6 +881,13 @@ struct gk20a_platform gk20a_tegra_platform = {
|
||||
.reset_assert = gk20a_tegra_reset_assert,
|
||||
.reset_deassert = gk20a_tegra_reset_deassert,
|
||||
|
||||
#ifdef CONFIG_TEGRA_CLK_FRAMEWORK
|
||||
.clk_get_rate = gk20a_get_clk_rate,
|
||||
.clk_round_rate = gk20a_round_clk_rate,
|
||||
.clk_set_rate = gk20a_set_clk_rate,
|
||||
.get_clk_freqs = gk20a_clk_get_freqs,
|
||||
#endif
|
||||
|
||||
/* frequency scaling configuration */
|
||||
.prescale = gk20a_tegra_prescale,
|
||||
.postscale = gk20a_tegra_postscale,
|
||||
@@ -887,6 +937,13 @@ struct gk20a_platform gm20b_tegra_platform = {
|
||||
.reset_assert = gm20b_tegra_reset_assert,
|
||||
.reset_deassert = gk20a_tegra_reset_deassert,
|
||||
|
||||
#ifdef CONFIG_TEGRA_CLK_FRAMEWORK
|
||||
.clk_get_rate = gk20a_get_clk_rate,
|
||||
.clk_round_rate = gk20a_round_clk_rate,
|
||||
.clk_set_rate = gk20a_set_clk_rate,
|
||||
.get_clk_freqs = gk20a_clk_get_freqs,
|
||||
#endif
|
||||
|
||||
/* frequency scaling configuration */
|
||||
.prescale = gk20a_tegra_prescale,
|
||||
.postscale = gk20a_tegra_postscale,
|
||||
|
||||
Reference in New Issue
Block a user