gpu: nvgpu: specify devfreq timer through dt

Originally,
nvgpu uses deferrable timer for devfreq polling by default,
this leads to issues below because of unstable polling interval.
 - out of time frequency scaling
 - unstable GPU frequency scaling

This change lets users be able to specify devfreq timer through dt.
If the dt node 'devfreq-timer' equals to 'delayed', then gpu will uses
delayed timer for devfreq polling.

Bug 3823798

Change-Id: Idc0849b4a6b8af52fda8e88f5c831f183b7a27de
Signed-off-by: shaochunk <shaochunk@nvidia.com>
Reviewed-on: https://git-master.nvidia.com/r/c/linux-nvgpu/+/2897026
Reviewed-by: Divya Singhatwaria <dsinghatwari@nvidia.com>
Reviewed-by: Rajkumar Kasirajan <rkasirajan@nvidia.com>
GVS: Gerrit_Virtual_Submit <buildbot_gerritrpt@nvidia.com>
This commit is contained in:
shaochunk
2023-05-02 15:16:57 +08:00
committed by mobile promotions
parent c066401be7
commit c655a5e058
3 changed files with 33 additions and 2 deletions

View File

@@ -23,6 +23,7 @@
#include <linux/pm_runtime.h>
#include <linux/of_platform.h>
#include <uapi/linux/nvgpu.h>
#include <linux/devfreq.h>
#include <nvgpu/defaults.h>
#include <nvgpu/kmem.h>
@@ -43,6 +44,7 @@
#include "os_linux.h"
#include "sysfs.h"
#include "ioctl.h"
#include "scale.h"
#define EMC3D_DEFAULT_RATIO 750
@@ -73,6 +75,32 @@ void nvgpu_read_support_gpu_tools(struct gk20a *g)
}
}
void nvgpu_read_devfreq_timer(struct gk20a *g)
{
struct device_node *np;
int ret = 0;
const char *timer;
np = nvgpu_get_node(g);
ret = of_property_read_string(np, "devfreq-timer", &timer);
if (ret != 0) {
nvgpu_log_info(g, "GPU devfreq monitor uses default timer");
} else {
if (strncmp(timer, "deferrable",
sizeof("deferrable") - 1) == 0) {
g->scale_profile->devfreq_profile.timer =
DEVFREQ_TIMER_DEFERRABLE;
} else if (strncmp(timer, "delayed",
sizeof("delayed") - 1) == 0) {
g->scale_profile->devfreq_profile.timer =
DEVFREQ_TIMER_DELAYED;
} else {
nvgpu_err(g, "dt specified "
"invalid devfreq timer for GPU: %s", timer);
}
}
}
static void nvgpu_init_vars(struct gk20a *g)
{
struct nvgpu_os_linux *l = nvgpu_os_linux_from_gk20a(g);

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2016-2021, NVIDIA CORPORATION. All rights reserved.
* Copyright (c) 2016-2023, 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,
@@ -24,5 +24,6 @@ int nvgpu_probe(struct gk20a *g,
void nvgpu_init_gk20a(struct gk20a *g);
void nvgpu_read_support_gpu_tools(struct gk20a *g);
void nvgpu_read_devfreq_timer(struct gk20a *g);
#endif

View File

@@ -1,7 +1,7 @@
/*
* gk20a clock scaling profile
*
* Copyright (c) 2013-2022, NVIDIA Corporation. All rights reserved.
* Copyright (c) 2013-2023, 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,
@@ -40,6 +40,7 @@
#include "platform_gk20a.h"
#include "scale.h"
#include "os_linux.h"
#include "driver_common.h"
/*
* gk20a_scale_qos_notify()
@@ -520,6 +521,7 @@ void gk20a_scale_init(struct device *dev)
int error = 0;
register_gpu_opp(dev);
nvgpu_read_devfreq_timer(g);
profile->devfreq_profile.initial_freq =
profile->devfreq_profile.freq_table[0];