mirror of
git://nv-tegra.nvidia.com/linux-nvgpu.git
synced 2025-12-22 09:12:24 +03:00
nvpmodel updates the devfreq frequency limits as per power requirements
for specific chip. Clock arbiter ignored these limits and set clock
to maximum supported frequency which may lead to leaking power and
over heating.
Add support to get the devfreq limits by registering PM_QOS notifiers.
Note that with this patch we enable CONFIG_GK20A_PM_QOS when PM_DEVFREQ
is enabled. So it will be enabled for all supported kernels (4.9, 4.14
kernels continue to support this. For 5.10+ kernels notifiers added in
this patch will be used. Thermal framework related notifiers for kernels
after 4.14 will not be registered as those use downstream interfaces
that are not available.)
We maintain devfreq min/max limits in the scale profile and update those
in the notifier calls. We use these limits to clamp the frequency in the
clock arbiter.
Bug 3852824
Change-Id: I734a9fb080fee1a91e9b5da071b662dbd9a18682
Signed-off-by: Sagar Kamble <skamble@nvidia.com>
Reviewed-on: https://git-master.nvidia.com/r/c/linux-nvgpu/+/2822686
(cherry picked from commit eacaf8cec2)
Reviewed-on: https://git-master.nvidia.com/r/c/linux-nvgpu/+/2822682
Reviewed-by: svc-mobile-coverity <svc-mobile-coverity@nvidia.com>
Reviewed-by: Rajesh Devaraj <rdevaraj@nvidia.com>
Reviewed-by: Vaibhav Kachore <vkachore@nvidia.com>
GVS: Gerrit_Virtual_Submit <buildbot_gerritrpt@nvidia.com>
102 lines
3.0 KiB
C
102 lines
3.0 KiB
C
/*
|
|
* gk20a clock scaling profile
|
|
*
|
|
* Copyright (c) 2013-2022, 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,
|
|
* version 2, as published by the Free Software Foundation.
|
|
*
|
|
* This program is distributed in the hope it will be useful, but WITHOUT
|
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
|
* more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#ifndef GK20A_SCALE_H
|
|
#define GK20A_SCALE_H
|
|
|
|
#include <linux/devfreq.h>
|
|
#include <linux/version.h>
|
|
|
|
struct clk;
|
|
|
|
struct gk20a_scale_profile {
|
|
struct device *dev;
|
|
ktime_t last_event_time;
|
|
struct devfreq_dev_profile devfreq_profile;
|
|
struct devfreq_dev_status dev_stat;
|
|
struct notifier_block qos_notify_block;
|
|
struct notifier_block qos_min_notify_block;
|
|
struct notifier_block qos_max_notify_block;
|
|
unsigned long qos_min_freq;
|
|
unsigned long qos_max_freq;
|
|
void *private_data;
|
|
struct nvgpu_mutex lock;
|
|
};
|
|
|
|
/* Initialization and de-initialization for module */
|
|
void gk20a_scale_init(struct device *);
|
|
void gk20a_scale_exit(struct device *);
|
|
void gk20a_scale_hw_init(struct device *dev);
|
|
|
|
#if defined(CONFIG_GK20A_DEVFREQ)
|
|
/*
|
|
* call when performing submit to notify scaling mechanism that the module is
|
|
* in use
|
|
*/
|
|
void gk20a_scale_notify_busy(struct device *);
|
|
void gk20a_scale_notify_idle(struct device *);
|
|
|
|
void gk20a_scale_suspend(struct device *);
|
|
void gk20a_scale_resume(struct device *);
|
|
|
|
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 10, 0)
|
|
int gk20a_scale_qos_min_notify(struct notifier_block *nb,
|
|
unsigned long n, void *p);
|
|
int gk20a_scale_qos_max_notify(struct notifier_block *nb,
|
|
unsigned long n, void *p);
|
|
u16 gk20a_scale_clamp_clk_target(struct gk20a *g,
|
|
u16 gpc2clk_target);
|
|
#else
|
|
int gk20a_scale_qos_notify(struct notifier_block *nb,
|
|
unsigned long n, void *p);
|
|
#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(5, 10, 0) */
|
|
|
|
#else
|
|
static inline void gk20a_scale_notify_busy(struct device *dev) {}
|
|
static inline void gk20a_scale_notify_idle(struct device *dev) {}
|
|
static inline void gk20a_scale_suspend(struct device *dev) {}
|
|
static inline void gk20a_scale_resume(struct device *dev) {}
|
|
|
|
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 10, 0)
|
|
static inline int gk20a_scale_qos_min_notify(struct notifier_block *nb,
|
|
unsigned long n, void *p)
|
|
{
|
|
return -ENOSYS;
|
|
}
|
|
static inline int gk20a_scale_qos_max_notify(struct notifier_block *nb,
|
|
unsigned long n, void *p)
|
|
{
|
|
return -ENOSYS;
|
|
}
|
|
static inline u16 gk20a_scale_clamp_clk_target(struct gk20a *g,
|
|
u16 gpc2clk_target)
|
|
{
|
|
return gpc2clk_target;
|
|
}
|
|
#else
|
|
static inline int gk20a_scale_qos_notify(struct notifier_block *nb,
|
|
unsigned long n, void *p)
|
|
{
|
|
return -ENOSYS;
|
|
}
|
|
#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(5, 10, 0) */
|
|
|
|
#endif
|
|
|
|
#endif
|