mirror of
git://nv-tegra.nvidia.com/linux-nvgpu.git
synced 2025-12-22 17:36:20 +03:00
gpu: nvgpu: enable CONFIG_GK20A_DEVFREQ for k5.9
Enable CONFIG_GK20A_DEVFREQ and apply corresponding changes for kernel-5.9 - Remove frequency clipping of devfreq min/max frequency constraint due to devfreq already takes care of it. - Register available GPU frequencies to OPP framework due to devfreq access available device frequencies through OPP frameworks during device frequency transition. Bug 200639056 Change-Id: I72e4a7825ae9ca814791dc283138d17a5cfbe8e2 Signed-off-by: Aaron Tian <atian@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/linux-nvgpu/+/2400107 Reviewed-by: automaticguardword <automaticguardword@nvidia.com> Reviewed-by: Terje Bergstrom <tbergstrom@nvidia.com> Reviewed-by: Alex Waterman <alexw@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> GVS: Gerrit_Virtual_Submit Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
This commit is contained in:
committed by
Alex Waterman
parent
c8add76c8d
commit
5d740f98b0
@@ -148,7 +148,6 @@ ifneq ($(findstring stable,$(NV_BUILD_KERNEL_OPTIONS)),)
|
|||||||
CONFIG_GK20A_DEVFREQ := n
|
CONFIG_GK20A_DEVFREQ := n
|
||||||
CONFIG_GK20A_PM_QOS := n
|
CONFIG_GK20A_PM_QOS := n
|
||||||
else ifneq ($(findstring 5.9,$(NV_BUILD_KERNEL_OPTIONS)),)
|
else ifneq ($(findstring 5.9,$(NV_BUILD_KERNEL_OPTIONS)),)
|
||||||
CONFIG_GK20A_DEVFREQ := n
|
|
||||||
CONFIG_GK20A_PM_QOS := n
|
CONFIG_GK20A_PM_QOS := n
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
|||||||
@@ -19,6 +19,7 @@
|
|||||||
#include <linux/devfreq.h>
|
#include <linux/devfreq.h>
|
||||||
#include <linux/export.h>
|
#include <linux/export.h>
|
||||||
#include <linux/pm_qos.h>
|
#include <linux/pm_qos.h>
|
||||||
|
#include <linux/version.h>
|
||||||
|
|
||||||
#include <governor.h>
|
#include <governor.h>
|
||||||
|
|
||||||
@@ -149,9 +150,11 @@ static int gk20a_scale_target(struct device *dev, unsigned long *freq,
|
|||||||
{
|
{
|
||||||
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 nvgpu_os_linux *l = nvgpu_os_linux_from_gk20a(g);
|
|
||||||
struct gk20a_scale_profile *profile = g->scale_profile;
|
struct gk20a_scale_profile *profile = g->scale_profile;
|
||||||
|
#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 8, 0)
|
||||||
|
struct nvgpu_os_linux *l = nvgpu_os_linux_from_gk20a(g);
|
||||||
struct devfreq *devfreq = l->devfreq;
|
struct devfreq *devfreq = l->devfreq;
|
||||||
|
#endif
|
||||||
unsigned long local_freq = *freq;
|
unsigned long local_freq = *freq;
|
||||||
unsigned long rounded_rate;
|
unsigned long rounded_rate;
|
||||||
unsigned long min_freq = 0, max_freq = 0;
|
unsigned long min_freq = 0, max_freq = 0;
|
||||||
@@ -173,8 +176,18 @@ static int gk20a_scale_target(struct device *dev, unsigned long *freq,
|
|||||||
* In case we have conflict (min_freq > max_freq) after above
|
* In case we have conflict (min_freq > max_freq) after above
|
||||||
* steps, we ensure that max_freq wins over min_freq
|
* steps, we ensure that max_freq wins over min_freq
|
||||||
*/
|
*/
|
||||||
|
#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 8, 0)
|
||||||
min_freq = max_t(u32, devfreq->min_freq, profile->qos_min_freq);
|
min_freq = max_t(u32, devfreq->min_freq, profile->qos_min_freq);
|
||||||
max_freq = min_t(u32, devfreq->max_freq, profile->qos_max_freq);
|
max_freq = min_t(u32, devfreq->max_freq, profile->qos_max_freq);
|
||||||
|
#else
|
||||||
|
/*
|
||||||
|
* devfreq takes care of min/max freq clipping in update_devfreq() then
|
||||||
|
* invoked devfreq->profile->target(), thus we only need to do freq
|
||||||
|
* clipping based on pm_qos constraint
|
||||||
|
*/
|
||||||
|
min_freq = profile->qos_min_freq;
|
||||||
|
max_freq = profile->qos_max_freq;
|
||||||
|
#endif
|
||||||
|
|
||||||
if (min_freq > max_freq)
|
if (min_freq > max_freq)
|
||||||
min_freq = max_freq;
|
min_freq = max_freq;
|
||||||
@@ -320,6 +333,46 @@ static int get_cur_freq(struct device *dev, unsigned long *freq)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 8, 0)
|
||||||
|
static int register_gpu_opp(struct device *dev)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void unregister_gpu_opp(struct device *dev)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
static void unregister_gpu_opp(struct device *dev)
|
||||||
|
{
|
||||||
|
dev_pm_opp_remove_all_dynamic(dev);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int register_gpu_opp(struct device *dev)
|
||||||
|
{
|
||||||
|
struct gk20a_platform *platform = dev_get_drvdata(dev);
|
||||||
|
struct gk20a *g = platform->g;
|
||||||
|
struct gk20a_scale_profile *profile = g->scale_profile;
|
||||||
|
unsigned long *freq_table = profile->devfreq_profile.freq_table;
|
||||||
|
int max_states = profile->devfreq_profile.max_state;
|
||||||
|
int i;
|
||||||
|
int err = 0;
|
||||||
|
|
||||||
|
for (i = 0; i < max_states; ++i) {
|
||||||
|
err = dev_pm_opp_add(dev, freq_table[i], 0);
|
||||||
|
if (err) {
|
||||||
|
nvgpu_err(g,
|
||||||
|
"Failed to add OPP %lu: %d\n",
|
||||||
|
freq_table[i],
|
||||||
|
err);
|
||||||
|
unregister_gpu_opp(dev);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* gk20a_scale_init(dev)
|
* gk20a_scale_init(dev)
|
||||||
@@ -362,6 +415,8 @@ void gk20a_scale_init(struct device *dev)
|
|||||||
struct devfreq *devfreq;
|
struct devfreq *devfreq;
|
||||||
int error = 0;
|
int error = 0;
|
||||||
|
|
||||||
|
register_gpu_opp(dev);
|
||||||
|
|
||||||
profile->devfreq_profile.initial_freq =
|
profile->devfreq_profile.initial_freq =
|
||||||
profile->devfreq_profile.freq_table[0];
|
profile->devfreq_profile.freq_table[0];
|
||||||
profile->devfreq_profile.target = gk20a_scale_target;
|
profile->devfreq_profile.target = gk20a_scale_target;
|
||||||
@@ -432,6 +487,8 @@ void gk20a_scale_exit(struct device *dev)
|
|||||||
|
|
||||||
err = devfreq_remove_device(l->devfreq);
|
err = devfreq_remove_device(l->devfreq);
|
||||||
l->devfreq = NULL;
|
l->devfreq = NULL;
|
||||||
|
|
||||||
|
unregister_gpu_opp(dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
nvgpu_kfree(g, g->scale_profile);
|
nvgpu_kfree(g, g->scale_profile);
|
||||||
|
|||||||
Reference in New Issue
Block a user