Compare commits
5 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
1a0693dd45 | ||
|
cc5e53f109 | ||
|
37369b74eb | ||
|
bf02edcc5e | ||
|
a4c0ab6b9f |
@@ -3,7 +3,7 @@
|
||||
# Linux distribution you are using, options are "Arch", "Ubuntu", "Debian", "Fedora", "Suse", "Gentoo", "Generic".
|
||||
# It is automatically set to "Arch" when using PKGBUILD.
|
||||
# If left empty, the script will prompt
|
||||
_distro=""
|
||||
_distro="Arch"
|
||||
|
||||
# Kernel Version - x.x format without the subversion (will always grab latest available subversion) is recommended
|
||||
# you can also set a specific kernel version, e.g. "6.0-rc4" or "5.10.51",
|
||||
@@ -46,7 +46,7 @@ CUSTOM_GCC_PATH=""
|
||||
CUSTOM_LLVM_PATH=""
|
||||
|
||||
# Set to true to bypass makepkg.conf and use all available threads for compilation. False will respect your makepkg.conf options.
|
||||
_force_all_threads="true"
|
||||
_force_all_threads="false"
|
||||
|
||||
# Set to true to prevent ccache from being used and set CONFIG_GCC_PLUGINS=y (which needs to be disabled for ccache to work properly)
|
||||
_noccache="false"
|
||||
@@ -66,10 +66,10 @@ _modprobeddb="false"
|
||||
_modprobeddb_db_path=~/.config/modprobed.db
|
||||
|
||||
# Set to "1" to call make menuconfig, "2" to call make nconfig, "3" to call make xconfig, before building the kernel. Set to false to disable and skip the prompt.
|
||||
_menunconfig=""
|
||||
_menunconfig="false"
|
||||
|
||||
# Set to true to generate a kernel config fragment from your changes in menuconfig/nconfig. Set to false to disable and skip the prompt.
|
||||
_diffconfig=""
|
||||
_diffconfig="false"
|
||||
|
||||
# Set to the file name where the generated config fragment should be written to. Only used if _diffconfig is active.
|
||||
_diffconfig_name=""
|
||||
@@ -104,11 +104,11 @@ _STRIP="true"
|
||||
|
||||
# CPU scheduler - Options are "pds", "bmq", "cacule", "tt", "bore", "bore-eevdf", "eevdf" or "cfs" (kernel's default)
|
||||
# "upds" (TkG's Undead PDS) and "muqss" are also available on legacy kernel revisions
|
||||
_cpusched=""
|
||||
_cpusched="pds"
|
||||
|
||||
# Compiler to use - Options are "gcc" or "llvm".
|
||||
# For advanced users.
|
||||
_compiler=""
|
||||
_compiler="gcc"
|
||||
|
||||
# Force the use of the LLVM Integrated Assembler whether using LLVM, LTO or not.
|
||||
# Set to "1" to enable.
|
||||
@@ -138,7 +138,7 @@ _preempt_rt_force=""
|
||||
# For BMQ: 0: No yield.
|
||||
# 1: Deboost and requeue task. (Default)
|
||||
# 2: Set rq skip task.
|
||||
_sched_yield_type=""
|
||||
_sched_yield_type="0"
|
||||
|
||||
# Round Robin interval is the longest duration two tasks with the same nice level will be delayed for. When CPU time is requested by a task, it receives a time slice equal
|
||||
# to the rr_interval in addition to a virtual deadline. When using yield_type 2, a low value can help offset the disadvantages of rescheduling a process that has yielded.
|
||||
@@ -146,7 +146,7 @@ _sched_yield_type=""
|
||||
# PDS default: 4ms"
|
||||
# BMQ default: 2ms"
|
||||
# Set to "1" for 2ms, "2" for 4ms, "3" for 6ms, "4" for 8ms, or "default" to keep the chosen scheduler defaults.
|
||||
_rr_interval=""
|
||||
_rr_interval="default"
|
||||
|
||||
# Set to "true" to disable FUNCTION_TRACER/GRAPH_TRACER, lowering overhead but limiting debugging and analyzing of kernel functions - Kernel default is "false"
|
||||
_ftracedisable="false"
|
||||
@@ -161,10 +161,10 @@ _misc_adds="true"
|
||||
# Full tickless can give higher performances in case you use isolation of CPUs for tasks
|
||||
# and it works only when using the nohz_full kernel parameter, otherwise behaves like idle.
|
||||
# Just tickless idle perform better for most platforms.
|
||||
_tickless=""
|
||||
_tickless="2"
|
||||
|
||||
# Set to "true" to use ACS override patch - https://wiki.archlinux.org/index.php/PCI_passthrough_via_OVMF#Bypassing_the_IOMMU_groups_.28ACS_override_patch.29 - Kernel default is "false"
|
||||
_acs_override=""
|
||||
_acs_override="false"
|
||||
|
||||
# Set to "true" to add Bcache filesystem support. You'll have to install bcachefs-tools-git from AUR for utilities - https://bcachefs.org/ - If in doubt, set to "false"
|
||||
# This can be buggy and isn't recommended on a production machine, also enabling this option will not allow you to enable MGLRU.
|
||||
@@ -175,7 +175,7 @@ _bcachefs="false"
|
||||
_winesync="false"
|
||||
|
||||
# Set to "true" to enable Binder modules to use Waydroid Android containers
|
||||
_waydroid=""
|
||||
_waydroid="false"
|
||||
|
||||
# Various patches and tweaks from Zen/Liquorix, Xanmod and the community - Default is "true"
|
||||
_glitched_base="true"
|
||||
@@ -185,7 +185,7 @@ _glitched_base="true"
|
||||
_zenify="true"
|
||||
|
||||
# compiler optimization level - 1. Optimize for performance (-O2); 2. Optimize harder (-O3); 3. Optimize for size (-Os) - Kernel default is "1"
|
||||
_compileroptlevel="1"
|
||||
_compileroptlevel="2"
|
||||
|
||||
# CPU compiler optimizations - Defaults to prompt at kernel config if left empty
|
||||
# AMD CPUs : "k8" "k8sse3" "k10" "barcelona" "bobcat" "jaguar" "bulldozer" "piledriver" "steamroller" "excavator" "zen" "zen2" "zen3" "zen4" (zen3 opt support depends on GCC11) (zen4 opt support depends on GCC13)
|
||||
@@ -199,7 +199,7 @@ _compileroptlevel="1"
|
||||
# - "generic_v2" (depends on GCC11 - to share the package between machines with different CPU µarch supporting at least x86-64-v2
|
||||
# - "generic_v3" (depends on GCC11 - to share the package between machines with different CPU µarch supporting at least x86-64-v3
|
||||
# - "generic_v4" (depends on GCC11 - to share the package between machines with different CPU µarch supporting at least x86-64-v4
|
||||
_processor_opt=""
|
||||
_processor_opt="skylake"
|
||||
|
||||
# CacULE only - Enable Response Driven Balancer, an experimental load balancer for CacULE
|
||||
_cacule_rdb="false"
|
||||
@@ -212,13 +212,13 @@ _cacule_rdb_interval="19"
|
||||
_tt_high_hz="false"
|
||||
|
||||
# MuQSS and PDS only - SMT (Hyperthreading) aware nice priority and policy support (SMT_NICE) - Kernel default is "true" - You can disable this on non-SMT/HT CPUs for lower overhead
|
||||
_smt_nice=""
|
||||
_smt_nice="true"
|
||||
|
||||
# Trust the CPU manufacturer to initialize Linux's CRNG (RANDOM_TRUST_CPU) - Kernel default is "false"
|
||||
_random_trust_cpu="true"
|
||||
|
||||
# Timer frequency - "100" "250" "300" "500" "750" "1000" ("2000" is available for cacule cpusched only) - More options available in kernel config prompt when left empty depending on selected cpusched with the default option pointed with a ">" (2000 for cacule, 100 for muqss and 1000 for other cpu schedulers)
|
||||
_timer_freq=""
|
||||
_timer_freq="1000"
|
||||
|
||||
# Default CPU governor - "performance", "ondemand", "schedutil" or leave empty for default (schedutil)
|
||||
_default_cpu_gov="ondemand"
|
||||
@@ -234,7 +234,7 @@ _aggressive_ondemand="true"
|
||||
_tcp_cong_alg=""
|
||||
|
||||
# You can pass a default set of kernel command line options here - example: "intel_pstate=passive nowatchdog amdgpu.ppfeaturemask=0xfffd7fff mitigations=off"
|
||||
_custom_commandline="intel_pstate=passive split_lock_detect=off"
|
||||
_custom_commandline=""
|
||||
|
||||
# Selection of Clearlinux patches
|
||||
_clear_patches="true"
|
||||
|
@@ -1,6 +1,6 @@
|
||||
#
|
||||
# Automatically generated file; DO NOT EDIT.
|
||||
# Linux/x86 6.6.0-rc1 Kernel Configuration
|
||||
# Linux/x86 6.6.0-rc3 Kernel Configuration
|
||||
#
|
||||
CONFIG_CC_VERSION_TEXT="gcc (GCC) 13.2.1 20230801"
|
||||
CONFIG_CC_IS_GCC=y
|
||||
@@ -4701,7 +4701,6 @@ CONFIG_I2C_MUX_REG=m
|
||||
CONFIG_I2C_MUX_MLXCPLD=m
|
||||
# end of Multiplexer I2C Chip support
|
||||
|
||||
CONFIG_I2C_ATR=m
|
||||
CONFIG_I2C_HELPER_AUTO=y
|
||||
CONFIG_I2C_SMBUS=m
|
||||
CONFIG_I2C_ALGOBIT=m
|
||||
@@ -10276,8 +10275,8 @@ CONFIG_XFS_DRAIN_INTENTS=y
|
||||
CONFIG_XFS_ONLINE_SCRUB=y
|
||||
CONFIG_XFS_ONLINE_SCRUB_STATS=y
|
||||
CONFIG_XFS_ONLINE_REPAIR=y
|
||||
# CONFIG_XFS_WARN is not set
|
||||
# CONFIG_XFS_DEBUG is not set
|
||||
CONFIG_XFS_DEBUG=y
|
||||
CONFIG_XFS_ASSERT_FATAL=y
|
||||
CONFIG_GFS2_FS=m
|
||||
CONFIG_GFS2_FS_LOCKING_DLM=y
|
||||
CONFIG_OCFS2_FS=m
|
||||
|
@@ -257,7 +257,7 @@ _set_cpu_scheduler() {
|
||||
["upds"]="Undead PDS (TkG)"
|
||||
["cacule"]="CacULE"
|
||||
["tt"]="TT (TaskType)"
|
||||
["bore"]="BORE (Burst-Oriented Response Enhancer - CFS variant) CPU Scheduler"
|
||||
["bore"]="BORE (Burst-Oriented Response Enhancer) CPU Scheduler"
|
||||
["bore-eevdf"]="BORE (Burst-Oriented Response Enhancer - EEVDF variant) CPU Scheduler"
|
||||
["eevdf"]="Earliest Eligible Virtual Deadline First (EEVDF) scheduler"
|
||||
)
|
||||
@@ -302,7 +302,7 @@ _set_cpu_scheduler() {
|
||||
elif [ "$_kver" = "605" ]; then
|
||||
_avail_cpu_scheds=("cfs" "eevdf" "pds" "bmq" "tt" "bore" "bore-eevdf")
|
||||
elif [ "$_kver" = "606" ]; then
|
||||
_avail_cpu_scheds=("eevdf")
|
||||
_avail_cpu_scheds=("eevdf" "bore")
|
||||
else
|
||||
_avail_cpu_scheds=("cfs")
|
||||
fi
|
||||
@@ -859,11 +859,7 @@ _tkg_srcprep() {
|
||||
|
||||
if [ "${_cpusched}" = "bore-eevdf" ]; then
|
||||
_msg="Applying BORE-EEVDF patch"
|
||||
if [ "$_kver" != "605" ]; then
|
||||
curl "https://raw.githubusercontent.com/CachyOS/kernel-patches/master/${_basekernel}/sched/0001-bore-eevdf.patch" > "$srcdir"/0001-bore-eevdf.patch
|
||||
else
|
||||
curl "https://raw.githubusercontent.com/sirlucjan/kernel-patches/master/${_basekernel}/bore-eevdf-patches-v2-sep/0016-linux6.5-bore3.1.3.patch" > "$srcdir"/0001-bore-eevdf.patch
|
||||
fi
|
||||
curl "https://raw.githubusercontent.com/CachyOS/kernel-patches/master/${_basekernel}/sched/0001-bore-eevdf.patch" > "$srcdir"/0001-bore-eevdf.patch
|
||||
tkgpatch="$srcdir/0001-bore-eevdf.patch" && _tkg_patcher
|
||||
fi
|
||||
fi
|
||||
|
@@ -2896,514 +2896,3 @@ index 03db55504..f68919800 100644
|
||||
--
|
||||
2.42.0
|
||||
|
||||
|
||||
From edbc7fe6658db891c80f244dc397f4e0247f6f3d Mon Sep 17 00:00:00 2001
|
||||
From: Peter Zijlstra <peterz@infradead.org>
|
||||
Date: Fri, 15 Sep 2023 00:48:55 +0200
|
||||
Subject: [PATCH 13/15] sched/eevdf: Also update slice on placement
|
||||
|
||||
Tasks that never consume their full slice would not update their slice value.
|
||||
This means that tasks that are spawned before the sysctl scaling keep their
|
||||
original (UP) slice length.
|
||||
|
||||
Fixes: 147f3efaa241 ("sched/fair: Implement an EEVDF-like scheduling policy")
|
||||
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
|
||||
---
|
||||
kernel/sched/fair.c | 6 ++++--
|
||||
1 file changed, 4 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
|
||||
index 1cdc95725..efbcdc69c 100644
|
||||
--- a/kernel/sched/fair.c
|
||||
+++ b/kernel/sched/fair.c
|
||||
@@ -4918,10 +4918,12 @@ static inline void update_misfit_status(struct task_struct *p, struct rq *rq) {}
|
||||
static void
|
||||
place_entity(struct cfs_rq *cfs_rq, struct sched_entity *se, int flags)
|
||||
{
|
||||
- u64 vslice = calc_delta_fair(se->slice, se);
|
||||
- u64 vruntime = avg_vruntime(cfs_rq);
|
||||
+ u64 vslice, vruntime = avg_vruntime(cfs_rq);
|
||||
s64 lag = 0;
|
||||
|
||||
+ se->slice = sysctl_sched_base_slice;
|
||||
+ vslice = calc_delta_fair(se->slice, se);
|
||||
+
|
||||
/*
|
||||
* Due to how V is constructed as the weighted average of entities,
|
||||
* adding tasks with positive lag, or removing tasks with negative lag
|
||||
--
|
||||
2.42.0
|
||||
|
||||
|
||||
From 0f1fadfb03ba9ba181e4631de8cd97ba765fae1d Mon Sep 17 00:00:00 2001
|
||||
From: Peter Zijlstra <peterz@infradead.org>
|
||||
Date: Fri, 15 Sep 2023 00:48:45 +0200
|
||||
Subject: [PATCH 14/15] sched/eevdf: Delay dequeue
|
||||
|
||||
For tasks that have negative-lag (have received 'excess' service), delay the
|
||||
dequeue and keep them in the runnable tree until they're elegible again. Or
|
||||
rather, keep them until they're selected again, since finding their elegibility
|
||||
crossover point is expensive.
|
||||
|
||||
The effect is a bit like sleeper bonus, the tasks keep contending for service
|
||||
until either they get a wakeup or until they're selected again and are really
|
||||
dequeued.
|
||||
|
||||
This means that any actual dequeue happens with positive lag (serviced owed)
|
||||
and are more readily ran when wakeup.
|
||||
|
||||
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
|
||||
---
|
||||
include/linux/sched.h | 1 +
|
||||
kernel/sched/core.c | 41 +++++++++++++++++++++++++++++++++++------
|
||||
kernel/sched/fair.c | 9 +++++++++
|
||||
kernel/sched/features.h | 1 +
|
||||
kernel/sched/sched.h | 3 ++-
|
||||
5 files changed, 48 insertions(+), 7 deletions(-)
|
||||
|
||||
diff --git a/include/linux/sched.h b/include/linux/sched.h
|
||||
index 35331c35f..d40d98313 100644
|
||||
--- a/include/linux/sched.h
|
||||
+++ b/include/linux/sched.h
|
||||
@@ -891,6 +891,7 @@ struct task_struct {
|
||||
unsigned sched_reset_on_fork:1;
|
||||
unsigned sched_contributes_to_load:1;
|
||||
unsigned sched_migrated:1;
|
||||
+ unsigned sched_delayed:1;
|
||||
|
||||
/* Force alignment to the next boundary: */
|
||||
unsigned :0;
|
||||
diff --git a/kernel/sched/core.c b/kernel/sched/core.c
|
||||
index 8116ef56d..cfb0ffa69 100644
|
||||
--- a/kernel/sched/core.c
|
||||
+++ b/kernel/sched/core.c
|
||||
@@ -6551,6 +6551,16 @@ pick_next_task(struct rq *rq, struct task_struct *prev, struct rq_flags *rf)
|
||||
# define SM_MASK_PREEMPT SM_PREEMPT
|
||||
#endif
|
||||
|
||||
+static void __deschedule_task(struct rq *rq, struct task_struct *p)
|
||||
+{
|
||||
+ deactivate_task(rq, p, DEQUEUE_SLEEP | DEQUEUE_NOCLOCK);
|
||||
+
|
||||
+ if (p->in_iowait) {
|
||||
+ atomic_inc(&rq->nr_iowait);
|
||||
+ delayacct_blkio_start();
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
/*
|
||||
* __schedule() is the main scheduler function.
|
||||
*
|
||||
@@ -6663,17 +6673,36 @@ static void __sched notrace __schedule(unsigned int sched_mode)
|
||||
*
|
||||
* After this, schedule() must not care about p->state any more.
|
||||
*/
|
||||
- deactivate_task(rq, prev, DEQUEUE_SLEEP | DEQUEUE_NOCLOCK);
|
||||
+ if (!(sched_feat(DELAY_DEQUEUE) &&
|
||||
+ prev->sched_class->eligible_task &&
|
||||
+ !prev->sched_class->eligible_task(rq, prev)))
|
||||
+ __deschedule_task(rq, prev);
|
||||
+ else
|
||||
+ prev->sched_delayed = 1;
|
||||
+ }
|
||||
+ switch_count = &prev->nvcsw;
|
||||
+ }
|
||||
+
|
||||
+ for (struct task_struct *tmp = prev;;) {
|
||||
|
||||
- if (prev->in_iowait) {
|
||||
- atomic_inc(&rq->nr_iowait);
|
||||
- delayacct_blkio_start();
|
||||
+ next = pick_next_task(rq, tmp, &rf);
|
||||
+ if (unlikely(tmp != prev))
|
||||
+ finish_task(tmp);
|
||||
+
|
||||
+ if (sched_feat(DELAY_DEQUEUE) && unlikely(next->sched_delayed)) {
|
||||
+ next->sched_delayed = 0;
|
||||
+ if (READ_ONCE(next->__state)) {
|
||||
+ prepare_task(next);
|
||||
+ smp_wmb();
|
||||
+ __deschedule_task(rq, next);
|
||||
+ tmp = next;
|
||||
+ continue;
|
||||
}
|
||||
}
|
||||
- switch_count = &prev->nvcsw;
|
||||
+
|
||||
+ break;
|
||||
}
|
||||
|
||||
- next = pick_next_task(rq, prev, &rf);
|
||||
clear_tsk_need_resched(prev);
|
||||
clear_preempt_need_resched();
|
||||
#ifdef CONFIG_SCHED_DEBUG
|
||||
diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
|
||||
index efbcdc69c..729507e40 100644
|
||||
--- a/kernel/sched/fair.c
|
||||
+++ b/kernel/sched/fair.c
|
||||
@@ -8174,6 +8174,14 @@ static struct task_struct *__pick_next_task_fair(struct rq *rq)
|
||||
return pick_next_task_fair(rq, NULL, NULL);
|
||||
}
|
||||
|
||||
+static bool eligible_task_fair(struct rq *rq, struct task_struct *p)
|
||||
+{
|
||||
+ struct sched_entity *se = &p->se;
|
||||
+ struct cfs_rq *cfs_rq = cfs_rq_of(se);
|
||||
+
|
||||
+ return entity_eligible(cfs_rq, se);
|
||||
+}
|
||||
+
|
||||
/*
|
||||
* Account for a descheduled task:
|
||||
*/
|
||||
@@ -12628,6 +12636,7 @@ DEFINE_SCHED_CLASS(fair) = {
|
||||
|
||||
.check_preempt_curr = check_preempt_wakeup,
|
||||
|
||||
+ .eligible_task = eligible_task_fair,
|
||||
.pick_next_task = __pick_next_task_fair,
|
||||
.put_prev_task = put_prev_task_fair,
|
||||
.set_next_task = set_next_task_fair,
|
||||
diff --git a/kernel/sched/features.h b/kernel/sched/features.h
|
||||
index 546d212ef..5ae5a6f92 100644
|
||||
--- a/kernel/sched/features.h
|
||||
+++ b/kernel/sched/features.h
|
||||
@@ -7,6 +7,7 @@
|
||||
SCHED_FEAT(PLACE_LAG, true)
|
||||
SCHED_FEAT(PLACE_DEADLINE_INITIAL, true)
|
||||
SCHED_FEAT(RUN_TO_PARITY, true)
|
||||
+SCHED_FEAT(DELAY_DEQUEUE, true)
|
||||
|
||||
/*
|
||||
* Prefer to schedule the task we woke last (assuming it failed
|
||||
diff --git a/kernel/sched/sched.h b/kernel/sched/sched.h
|
||||
index 576d371c8..c18ab7c2f 100644
|
||||
--- a/kernel/sched/sched.h
|
||||
+++ b/kernel/sched/sched.h
|
||||
@@ -2219,6 +2219,7 @@ struct sched_class {
|
||||
|
||||
void (*check_preempt_curr)(struct rq *rq, struct task_struct *p, int flags);
|
||||
|
||||
+ bool (*eligible_task)(struct rq *rq, struct task_struct *p);
|
||||
struct task_struct *(*pick_next_task)(struct rq *rq);
|
||||
|
||||
void (*put_prev_task)(struct rq *rq, struct task_struct *p);
|
||||
@@ -2272,7 +2273,7 @@ struct sched_class {
|
||||
|
||||
static inline void put_prev_task(struct rq *rq, struct task_struct *prev)
|
||||
{
|
||||
- WARN_ON_ONCE(rq->curr != prev);
|
||||
+// WARN_ON_ONCE(rq->curr != prev);
|
||||
prev->sched_class->put_prev_task(rq, prev);
|
||||
}
|
||||
|
||||
--
|
||||
2.42.0
|
||||
|
||||
|
||||
From 4aba3e1c3bbe4a36d4b9e405be8a66d7c10d6495 Mon Sep 17 00:00:00 2001
|
||||
From: Peter Zijlstra <peterz@infradead.org>
|
||||
Date: Mon, 22 May 2023 13:46:30 +0200
|
||||
Subject: [PATCH 15/15] sched/eevdf: Use sched_attr::sched_runtime to set
|
||||
request/slice suggestion
|
||||
|
||||
Allow applications to directly set a suggested request/slice length using
|
||||
sched_attr::sched_runtime.
|
||||
|
||||
The implementation clamps the value to: 0.1[ms] <= slice <= 100[ms]
|
||||
which is 1/10 the size of HZ=1000 and 10 times the size of HZ=100.
|
||||
|
||||
Applications should strive to use their periodic runtime at a high
|
||||
confidence interval (95%+) as the target slice. Using a smaller slice
|
||||
will introduce undue preemptions, while using a larger value will
|
||||
increase latency.
|
||||
|
||||
For all the following examples assume a scheduling quantum of 8, and for
|
||||
consistency all examples have W=4:
|
||||
|
||||
{A,B,C,D}(w=1,r=8):
|
||||
|
||||
ABCD...
|
||||
+---+---+---+---
|
||||
|
||||
t=0, V=1.5 t=1, V=3.5
|
||||
A |------< A |------<
|
||||
B |------< B |------<
|
||||
C |------< C |------<
|
||||
D |------< D |------<
|
||||
---+*------+-------+--- ---+--*----+-------+---
|
||||
|
||||
t=2, V=5.5 t=3, V=7.5
|
||||
A |------< A |------<
|
||||
B |------< B |------<
|
||||
C |------< C |------<
|
||||
D |------< D |------<
|
||||
---+----*--+-------+--- ---+------*+-------+---
|
||||
|
||||
Note: 4 identical tasks in FIFO order
|
||||
|
||||
~~~
|
||||
|
||||
{A,B}(w=1,r=16) C(w=2,r=16)
|
||||
|
||||
AACCBBCC...
|
||||
+---+---+---+---
|
||||
|
||||
t=0, V=1.25 t=2, V=5.25
|
||||
A |--------------< A |--------------<
|
||||
B |--------------< B |--------------<
|
||||
C |------< C |------<
|
||||
---+*------+-------+--- ---+----*--+-------+---
|
||||
|
||||
t=4, V=8.25 t=6, V=12.25
|
||||
A |--------------< A |--------------<
|
||||
B |--------------< B |--------------<
|
||||
C |------< C |------<
|
||||
---+-------*-------+--- ---+-------+---*---+---
|
||||
|
||||
Note: 1 heavy task -- because q=8, double r such that the deadline of the w=2
|
||||
task doesn't go below q.
|
||||
|
||||
Note: observe the full schedule becomes: W*max(r_i/w_i) = 4*2q = 8q in length.
|
||||
|
||||
Note: the period of the heavy task is half the full period at:
|
||||
W*(r_i/w_i) = 4*(2q/2) = 4q
|
||||
|
||||
~~~
|
||||
|
||||
{A,C,D}(w=1,r=16) B(w=1,r=8):
|
||||
|
||||
BAACCBDD...
|
||||
+---+---+---+---
|
||||
|
||||
t=0, V=1.5 t=1, V=3.5
|
||||
A |--------------< A |---------------<
|
||||
B |------< B |------<
|
||||
C |--------------< C |--------------<
|
||||
D |--------------< D |--------------<
|
||||
---+*------+-------+--- ---+--*----+-------+---
|
||||
|
||||
t=3, V=7.5 t=5, V=11.5
|
||||
A |---------------< A |---------------<
|
||||
B |------< B |------<
|
||||
C |--------------< C |--------------<
|
||||
D |--------------< D |--------------<
|
||||
---+------*+-------+--- ---+-------+--*----+---
|
||||
|
||||
t=6, V=13.5
|
||||
A |---------------<
|
||||
B |------<
|
||||
C |--------------<
|
||||
D |--------------<
|
||||
---+-------+----*--+---
|
||||
|
||||
Note: 1 short task -- again double r so that the deadline of the short task
|
||||
won't be below q. Made B short because its not the leftmost task, but is
|
||||
eligible with the 0,1,2,3 spread.
|
||||
|
||||
Note: like with the heavy task, the period of the short task observes:
|
||||
W*(r_i/w_i) = 4*(1q/1) = 4q
|
||||
|
||||
~~~
|
||||
|
||||
A(w=1,r=16) B(w=1,r=8) C(w=2,r=16)
|
||||
|
||||
BCCAABCC...
|
||||
+---+---+---+---
|
||||
|
||||
t=0, V=1.25 t=1, V=3.25
|
||||
A |--------------< A |--------------<
|
||||
B |------< B |------<
|
||||
C |------< C |------<
|
||||
---+*------+-------+--- ---+--*----+-------+---
|
||||
|
||||
t=3, V=7.25 t=5, V=11.25
|
||||
A |--------------< A |--------------<
|
||||
B |------< B |------<
|
||||
C |------< C |------<
|
||||
---+------*+-------+--- ---+-------+--*----+---
|
||||
|
||||
t=6, V=13.25
|
||||
A |--------------<
|
||||
B |------<
|
||||
C |------<
|
||||
---+-------+----*--+---
|
||||
|
||||
Note: 1 heavy and 1 short task -- combine them all.
|
||||
|
||||
Note: both the short and heavy task end up with a period of 4q
|
||||
|
||||
~~~
|
||||
|
||||
A(w=1,r=16) B(w=2,r=16) C(w=1,r=8)
|
||||
|
||||
BBCAABBC...
|
||||
+---+---+---+---
|
||||
|
||||
t=0, V=1 t=2, V=5
|
||||
A |--------------< A |--------------<
|
||||
B |------< B |------<
|
||||
C |------< C |------<
|
||||
---+*------+-------+--- ---+----*--+-------+---
|
||||
|
||||
t=3, V=7 t=5, V=11
|
||||
A |--------------< A |--------------<
|
||||
B |------< B |------<
|
||||
C |------< C |------<
|
||||
---+------*+-------+--- ---+-------+--*----+---
|
||||
|
||||
t=7, V=15
|
||||
A |--------------<
|
||||
B |------<
|
||||
C |------<
|
||||
---+-------+------*+---
|
||||
|
||||
Note: as before but permuted
|
||||
|
||||
~~~
|
||||
|
||||
From all this it can be deduced that, for the steady state:
|
||||
|
||||
- the total period (P) of a schedule is: W*max(r_i/w_i)
|
||||
- the average period of a task is: W*(r_i/w_i)
|
||||
- each task obtains the fair share: w_i/W of each full period P
|
||||
|
||||
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
|
||||
---
|
||||
include/linux/sched.h | 3 +++
|
||||
kernel/sched/core.c | 33 ++++++++++++++++++++++++++-------
|
||||
kernel/sched/fair.c | 6 ++++--
|
||||
3 files changed, 33 insertions(+), 9 deletions(-)
|
||||
|
||||
diff --git a/include/linux/sched.h b/include/linux/sched.h
|
||||
index d40d98313..93c03b162 100644
|
||||
--- a/include/linux/sched.h
|
||||
+++ b/include/linux/sched.h
|
||||
@@ -555,6 +555,9 @@ struct sched_entity {
|
||||
struct list_head group_node;
|
||||
unsigned int on_rq;
|
||||
|
||||
+ unsigned int custom_slice : 1;
|
||||
+ /* 31 bits hole */
|
||||
+
|
||||
u64 exec_start;
|
||||
u64 sum_exec_runtime;
|
||||
u64 prev_sum_exec_runtime;
|
||||
diff --git a/kernel/sched/core.c b/kernel/sched/core.c
|
||||
index cfb0ffa69..1ae5a8272 100644
|
||||
--- a/kernel/sched/core.c
|
||||
+++ b/kernel/sched/core.c
|
||||
@@ -4502,7 +4502,6 @@ static void __sched_fork(unsigned long clone_flags, struct task_struct *p)
|
||||
p->se.nr_migrations = 0;
|
||||
p->se.vruntime = 0;
|
||||
p->se.vlag = 0;
|
||||
- p->se.slice = sysctl_sched_base_slice;
|
||||
INIT_LIST_HEAD(&p->se.group_node);
|
||||
|
||||
#ifdef CONFIG_FAIR_GROUP_SCHED
|
||||
@@ -4756,6 +4755,8 @@ int sched_fork(unsigned long clone_flags, struct task_struct *p)
|
||||
|
||||
p->prio = p->normal_prio = p->static_prio;
|
||||
set_load_weight(p, false);
|
||||
+ p->se.custom_slice = 0;
|
||||
+ p->se.slice = sysctl_sched_base_slice;
|
||||
|
||||
/*
|
||||
* We don't need the reset flag anymore after the fork. It has
|
||||
@@ -7556,10 +7557,20 @@ static void __setscheduler_params(struct task_struct *p,
|
||||
|
||||
p->policy = policy;
|
||||
|
||||
- if (dl_policy(policy))
|
||||
+ if (dl_policy(policy)) {
|
||||
__setparam_dl(p, attr);
|
||||
- else if (fair_policy(policy))
|
||||
+ } else if (fair_policy(policy)) {
|
||||
p->static_prio = NICE_TO_PRIO(attr->sched_nice);
|
||||
+ if (attr->sched_runtime) {
|
||||
+ p->se.custom_slice = 1;
|
||||
+ p->se.slice = clamp_t(u64, attr->sched_runtime,
|
||||
+ NSEC_PER_MSEC/10, /* HZ=1000 * 10 */
|
||||
+ NSEC_PER_MSEC*100); /* HZ=100 / 10 */
|
||||
+ } else {
|
||||
+ p->se.custom_slice = 0;
|
||||
+ p->se.slice = sysctl_sched_base_slice;
|
||||
+ }
|
||||
+ }
|
||||
|
||||
/*
|
||||
* __sched_setscheduler() ensures attr->sched_priority == 0 when
|
||||
@@ -7744,7 +7755,9 @@ static int __sched_setscheduler(struct task_struct *p,
|
||||
* but store a possible modification of reset_on_fork.
|
||||
*/
|
||||
if (unlikely(policy == p->policy)) {
|
||||
- if (fair_policy(policy) && attr->sched_nice != task_nice(p))
|
||||
+ if (fair_policy(policy) &&
|
||||
+ (attr->sched_nice != task_nice(p) ||
|
||||
+ (attr->sched_runtime && attr->sched_runtime != p->se.slice)))
|
||||
goto change;
|
||||
if (rt_policy(policy) && attr->sched_priority != p->rt_priority)
|
||||
goto change;
|
||||
@@ -7890,6 +7903,9 @@ static int _sched_setscheduler(struct task_struct *p, int policy,
|
||||
.sched_nice = PRIO_TO_NICE(p->static_prio),
|
||||
};
|
||||
|
||||
+ if (p->se.custom_slice)
|
||||
+ attr.sched_runtime = p->se.slice;
|
||||
+
|
||||
/* Fixup the legacy SCHED_RESET_ON_FORK hack. */
|
||||
if ((policy != SETPARAM_POLICY) && (policy & SCHED_RESET_ON_FORK)) {
|
||||
attr.sched_flags |= SCHED_FLAG_RESET_ON_FORK;
|
||||
@@ -8066,12 +8082,14 @@ static int sched_copy_attr(struct sched_attr __user *uattr, struct sched_attr *a
|
||||
|
||||
static void get_params(struct task_struct *p, struct sched_attr *attr)
|
||||
{
|
||||
- if (task_has_dl_policy(p))
|
||||
+ if (task_has_dl_policy(p)) {
|
||||
__getparam_dl(p, attr);
|
||||
- else if (task_has_rt_policy(p))
|
||||
+ } else if (task_has_rt_policy(p)) {
|
||||
attr->sched_priority = p->rt_priority;
|
||||
- else
|
||||
+ } else {
|
||||
attr->sched_nice = task_nice(p);
|
||||
+ attr->sched_runtime = p->se.slice;
|
||||
+ }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -10090,6 +10108,7 @@ void __init sched_init(void)
|
||||
}
|
||||
|
||||
set_load_weight(&init_task, false);
|
||||
+ init_task.se.slice = sysctl_sched_base_slice,
|
||||
|
||||
/*
|
||||
* The boot idle thread does lazy MMU switching as well:
|
||||
diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
|
||||
index 729507e40..51e19a1fb 100644
|
||||
--- a/kernel/sched/fair.c
|
||||
+++ b/kernel/sched/fair.c
|
||||
@@ -973,7 +973,8 @@ static void update_deadline(struct cfs_rq *cfs_rq, struct sched_entity *se)
|
||||
* nice) while the request time r_i is determined by
|
||||
* sysctl_sched_base_slice.
|
||||
*/
|
||||
- se->slice = sysctl_sched_base_slice;
|
||||
+ if (!se->custom_slice)
|
||||
+ se->slice = sysctl_sched_base_slice;
|
||||
|
||||
/*
|
||||
* EEVDF: vd_i = ve_i + r_i / w_i
|
||||
@@ -4921,7 +4922,8 @@ place_entity(struct cfs_rq *cfs_rq, struct sched_entity *se, int flags)
|
||||
u64 vslice, vruntime = avg_vruntime(cfs_rq);
|
||||
s64 lag = 0;
|
||||
|
||||
- se->slice = sysctl_sched_base_slice;
|
||||
+ if (!se->custom_slice)
|
||||
+ se->slice = sysctl_sched_base_slice;
|
||||
vslice = calc_delta_fair(se->slice, se);
|
||||
|
||||
/*
|
||||
--
|
||||
2.42.0
|
||||
|
||||
|
@@ -64,3 +64,760 @@ index 2c7171e0b0010..85de313ddec29 100644
|
||||
select CPU_FREQ_GOV_PERFORMANCE
|
||||
help
|
||||
|
||||
From 7695eb71d0872ed9633daf0ca779da3344b87dec Mon Sep 17 00:00:00 2001
|
||||
From: Evan Quan <evan.quan@amd.com>
|
||||
Date: Mon, 21 Aug 2023 14:15:13 +0800
|
||||
Subject: [PATCH] drm/amd/pm: correct SMU13 gfx voltage related OD settings
|
||||
|
||||
The voltage offset setting will be applied to the whole v/f curve line
|
||||
instead of per anchor point base.
|
||||
|
||||
Signed-off-by: Evan Quan <evan.quan@amd.com>
|
||||
Acked-by: Alex Deucher <alexander.deucher@amd.com>
|
||||
---
|
||||
drivers/gpu/drm/amd/pm/amdgpu_pm.c | 45 +++++++------------
|
||||
.../drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c | 31 ++++++-------
|
||||
.../drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c | 31 ++++++-------
|
||||
3 files changed, 43 insertions(+), 64 deletions(-)
|
||||
|
||||
diff --git a/drivers/gpu/drm/amd/pm/amdgpu_pm.c b/drivers/gpu/drm/amd/pm/amdgpu_pm.c
|
||||
index 1da7ece4c627..06aa5c18b40f 100644
|
||||
--- a/drivers/gpu/drm/amd/pm/amdgpu_pm.c
|
||||
+++ b/drivers/gpu/drm/amd/pm/amdgpu_pm.c
|
||||
@@ -643,18 +643,14 @@ static ssize_t amdgpu_set_pp_table(struct device *dev,
|
||||
* They can be used to calibrate the sclk voltage curve. This is
|
||||
* available for Vega20 and NV1X.
|
||||
*
|
||||
- * - voltage offset for the six anchor points of the v/f curve labeled
|
||||
- * OD_VDDC_CURVE. They can be used to calibrate the v/f curve. This
|
||||
- * is only availabe for some SMU13 ASICs.
|
||||
- *
|
||||
* - voltage offset(in mV) applied on target voltage calculation.
|
||||
- * This is available for Sienna Cichlid, Navy Flounder and Dimgrey
|
||||
- * Cavefish. For these ASICs, the target voltage calculation can be
|
||||
- * illustrated by "voltage = voltage calculated from v/f curve +
|
||||
- * overdrive vddgfx offset"
|
||||
+ * This is available for Sienna Cichlid, Navy Flounder, Dimgrey
|
||||
+ * Cavefish and some later SMU13 ASICs. For these ASICs, the target
|
||||
+ * voltage calculation can be illustrated by "voltage = voltage
|
||||
+ * calculated from v/f curve + overdrive vddgfx offset"
|
||||
*
|
||||
- * - a list of valid ranges for sclk, mclk, and voltage curve points
|
||||
- * labeled OD_RANGE
|
||||
+ * - a list of valid ranges for sclk, mclk, voltage curve points
|
||||
+ * or voltage offset labeled OD_RANGE
|
||||
*
|
||||
* < For APUs >
|
||||
*
|
||||
@@ -686,24 +682,17 @@ static ssize_t amdgpu_set_pp_table(struct device *dev,
|
||||
* E.g., "p 2 0 800" would set the minimum core clock on core
|
||||
* 2 to 800Mhz.
|
||||
*
|
||||
- * For sclk voltage curve,
|
||||
- * - For NV1X, enter the new values by writing a string that
|
||||
- * contains "vc point clock voltage" to the file. The points
|
||||
- * are indexed by 0, 1 and 2. E.g., "vc 0 300 600" will update
|
||||
- * point1 with clock set as 300Mhz and voltage as 600mV. "vc 2
|
||||
- * 1000 1000" will update point3 with clock set as 1000Mhz and
|
||||
- * voltage 1000mV.
|
||||
- * - For SMU13 ASICs, enter the new values by writing a string that
|
||||
- * contains "vc anchor_point_index voltage_offset" to the file.
|
||||
- * There are total six anchor points defined on the v/f curve with
|
||||
- * index as 0 - 5.
|
||||
- * - "vc 0 10" will update the voltage offset for point1 as 10mv.
|
||||
- * - "vc 5 -10" will update the voltage offset for point6 as -10mv.
|
||||
- *
|
||||
- * To update the voltage offset applied for gfxclk/voltage calculation,
|
||||
- * enter the new value by writing a string that contains "vo offset".
|
||||
- * This is supported by Sienna Cichlid, Navy Flounder and Dimgrey Cavefish.
|
||||
- * And the offset can be a positive or negative value.
|
||||
+ * For sclk voltage curve supported by Vega20 and NV1X, enter the new
|
||||
+ * values by writing a string that contains "vc point clock voltage"
|
||||
+ * to the file. The points are indexed by 0, 1 and 2. E.g., "vc 0 300
|
||||
+ * 600" will update point1 with clock set as 300Mhz and voltage as 600mV.
|
||||
+ * "vc 2 1000 1000" will update point3 with clock set as 1000Mhz and
|
||||
+ * voltage 1000mV.
|
||||
+ *
|
||||
+ * For voltage offset supported by Sienna Cichlid, Navy Flounder, Dimgrey
|
||||
+ * Cavefish and some later SMU13 ASICs, enter the new value by writing a
|
||||
+ * string that contains "vo offset". E.g., "vo -10" will update the extra
|
||||
+ * voltage offset applied to the whole v/f curve line as -10mv.
|
||||
*
|
||||
* - When you have edited all of the states as needed, write "c" (commit)
|
||||
* to the file to commit your changes
|
||||
diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c
|
||||
index 3903a47669e4..bd0d5f027cac 100644
|
||||
--- a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c
|
||||
+++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c
|
||||
@@ -1304,16 +1304,14 @@ static int smu_v13_0_0_print_clk_levels(struct smu_context *smu,
|
||||
od_table->OverDriveTable.UclkFmax);
|
||||
break;
|
||||
|
||||
- case SMU_OD_VDDC_CURVE:
|
||||
+ case SMU_OD_VDDGFX_OFFSET:
|
||||
if (!smu_v13_0_0_is_od_feature_supported(smu,
|
||||
PP_OD_FEATURE_GFX_VF_CURVE_BIT))
|
||||
break;
|
||||
|
||||
- size += sysfs_emit_at(buf, size, "OD_VDDC_CURVE:\n");
|
||||
- for (i = 0; i < PP_NUM_OD_VF_CURVE_POINTS; i++)
|
||||
- size += sysfs_emit_at(buf, size, "%d: %dmv\n",
|
||||
- i,
|
||||
- od_table->OverDriveTable.VoltageOffsetPerZoneBoundary[i]);
|
||||
+ size += sysfs_emit_at(buf, size, "OD_VDDGFX_OFFSET:\n");
|
||||
+ size += sysfs_emit_at(buf, size, "%dmV\n",
|
||||
+ od_table->OverDriveTable.VoltageOffsetPerZoneBoundary[0]);
|
||||
break;
|
||||
|
||||
case SMU_OD_RANGE:
|
||||
@@ -1355,7 +1353,7 @@ static int smu_v13_0_0_print_clk_levels(struct smu_context *smu,
|
||||
PP_OD_FEATURE_GFX_VF_CURVE,
|
||||
&min_value,
|
||||
&max_value);
|
||||
- size += sysfs_emit_at(buf, size, "VDDC_CURVE: %7dmv %10dmv\n",
|
||||
+ size += sysfs_emit_at(buf, size, "VDDGFX_OFFSET: %7dmv %10dmv\n",
|
||||
min_value, max_value);
|
||||
}
|
||||
break;
|
||||
@@ -1504,29 +1502,26 @@ static int smu_v13_0_0_od_edit_dpm_table(struct smu_context *smu,
|
||||
}
|
||||
break;
|
||||
|
||||
- case PP_OD_EDIT_VDDC_CURVE:
|
||||
+ case PP_OD_EDIT_VDDGFX_OFFSET:
|
||||
if (!smu_v13_0_0_is_od_feature_supported(smu, PP_OD_FEATURE_GFX_VF_CURVE_BIT)) {
|
||||
- dev_warn(adev->dev, "VF curve setting not supported!\n");
|
||||
+ dev_warn(adev->dev, "Gfx offset setting not supported!\n");
|
||||
return -ENOTSUPP;
|
||||
}
|
||||
|
||||
- if (input[0] >= PP_NUM_OD_VF_CURVE_POINTS ||
|
||||
- input[0] < 0)
|
||||
- return -EINVAL;
|
||||
-
|
||||
smu_v13_0_0_get_od_setting_limits(smu,
|
||||
PP_OD_FEATURE_GFX_VF_CURVE,
|
||||
&minimum,
|
||||
&maximum);
|
||||
- if (input[1] < minimum ||
|
||||
- input[1] > maximum) {
|
||||
+ if (input[0] < minimum ||
|
||||
+ input[0] > maximum) {
|
||||
dev_info(adev->dev, "Voltage offset (%ld) must be within [%d, %d]!\n",
|
||||
- input[1], minimum, maximum);
|
||||
+ input[0], minimum, maximum);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
- od_table->OverDriveTable.VoltageOffsetPerZoneBoundary[input[0]] = input[1];
|
||||
- od_table->OverDriveTable.FeatureCtrlMask |= 1U << PP_OD_FEATURE_GFX_VF_CURVE_BIT;
|
||||
+ for (i = 0; i < PP_NUM_OD_VF_CURVE_POINTS; i++)
|
||||
+ od_table->OverDriveTable.VoltageOffsetPerZoneBoundary[i] = input[0];
|
||||
+ od_table->OverDriveTable.FeatureCtrlMask |= BIT(PP_OD_FEATURE_GFX_VF_CURVE_BIT);
|
||||
break;
|
||||
|
||||
case PP_OD_RESTORE_DEFAULT_TABLE:
|
||||
diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c
|
||||
index 94ef5b4d116d..b9b3bf41eed3 100644
|
||||
--- a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c
|
||||
+++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c
|
||||
@@ -1284,16 +1284,14 @@ static int smu_v13_0_7_print_clk_levels(struct smu_context *smu,
|
||||
od_table->OverDriveTable.UclkFmax);
|
||||
break;
|
||||
|
||||
- case SMU_OD_VDDC_CURVE:
|
||||
+ case SMU_OD_VDDGFX_OFFSET:
|
||||
if (!smu_v13_0_7_is_od_feature_supported(smu,
|
||||
PP_OD_FEATURE_GFX_VF_CURVE_BIT))
|
||||
break;
|
||||
|
||||
- size += sysfs_emit_at(buf, size, "OD_VDDC_CURVE:\n");
|
||||
- for (i = 0; i < PP_NUM_OD_VF_CURVE_POINTS; i++)
|
||||
- size += sysfs_emit_at(buf, size, "%d: %dmv\n",
|
||||
- i,
|
||||
- od_table->OverDriveTable.VoltageOffsetPerZoneBoundary[i]);
|
||||
+ size += sysfs_emit_at(buf, size, "OD_VDDGFX_OFFSET:\n");
|
||||
+ size += sysfs_emit_at(buf, size, "%dmV\n",
|
||||
+ od_table->OverDriveTable.VoltageOffsetPerZoneBoundary[0]);
|
||||
break;
|
||||
|
||||
case SMU_OD_RANGE:
|
||||
@@ -1335,7 +1333,7 @@ static int smu_v13_0_7_print_clk_levels(struct smu_context *smu,
|
||||
PP_OD_FEATURE_GFX_VF_CURVE,
|
||||
&min_value,
|
||||
&max_value);
|
||||
- size += sysfs_emit_at(buf, size, "VDDC_CURVE: %7dmv %10dmv\n",
|
||||
+ size += sysfs_emit_at(buf, size, "VDDGFX_OFFSET: %7dmv %10dmv\n",
|
||||
min_value, max_value);
|
||||
}
|
||||
break;
|
||||
@@ -1484,29 +1482,26 @@ static int smu_v13_0_7_od_edit_dpm_table(struct smu_context *smu,
|
||||
}
|
||||
break;
|
||||
|
||||
- case PP_OD_EDIT_VDDC_CURVE:
|
||||
+ case PP_OD_EDIT_VDDGFX_OFFSET:
|
||||
if (!smu_v13_0_7_is_od_feature_supported(smu, PP_OD_FEATURE_GFX_VF_CURVE_BIT)) {
|
||||
- dev_warn(adev->dev, "VF curve setting not supported!\n");
|
||||
+ dev_warn(adev->dev, "Gfx offset setting not supported!\n");
|
||||
return -ENOTSUPP;
|
||||
}
|
||||
|
||||
- if (input[0] >= PP_NUM_OD_VF_CURVE_POINTS ||
|
||||
- input[0] < 0)
|
||||
- return -EINVAL;
|
||||
-
|
||||
smu_v13_0_7_get_od_setting_limits(smu,
|
||||
PP_OD_FEATURE_GFX_VF_CURVE,
|
||||
&minimum,
|
||||
&maximum);
|
||||
- if (input[1] < minimum ||
|
||||
- input[1] > maximum) {
|
||||
+ if (input[0] < minimum ||
|
||||
+ input[0] > maximum) {
|
||||
dev_info(adev->dev, "Voltage offset (%ld) must be within [%d, %d]!\n",
|
||||
- input[1], minimum, maximum);
|
||||
+ input[0], minimum, maximum);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
- od_table->OverDriveTable.VoltageOffsetPerZoneBoundary[input[0]] = input[1];
|
||||
- od_table->OverDriveTable.FeatureCtrlMask |= 1U << PP_OD_FEATURE_GFX_VF_CURVE_BIT;
|
||||
+ for (i = 0; i < PP_NUM_OD_VF_CURVE_POINTS; i++)
|
||||
+ od_table->OverDriveTable.VoltageOffsetPerZoneBoundary[i] = input[0];
|
||||
+ od_table->OverDriveTable.FeatureCtrlMask |= BIT(PP_OD_FEATURE_GFX_VF_CURVE_BIT);
|
||||
break;
|
||||
|
||||
case PP_OD_RESTORE_DEFAULT_TABLE:
|
||||
--
|
||||
GitLab
|
||||
|
||||
|
||||
From 8bad128720ebc69e37f1c66767fb276088ef4fa7 Mon Sep 17 00:00:00 2001
|
||||
From: Evan Quan <evan.quan@amd.com>
|
||||
Date: Wed, 16 Aug 2023 14:51:19 +0800
|
||||
Subject: [PATCH] drm/amd/pm: fulfill the support for SMU13 `pp_dpm_dcefclk`
|
||||
interface
|
||||
|
||||
Fulfill the incomplete SMU13 `pp_dpm_dcefclk` implementation.
|
||||
|
||||
Reported-by: Guan Yu <guan.yu@amd.com>
|
||||
Signed-off-by: Evan Quan <evan.quan@amd.com>
|
||||
Acked-by: Alex Deucher <alexander.deucher@amd.com>
|
||||
---
|
||||
.../drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c | 27 +++++++++++++++++++
|
||||
.../drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c | 27 +++++++++++++++++++
|
||||
2 files changed, 54 insertions(+)
|
||||
|
||||
diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c
|
||||
index bd0d5f027cac..5fdb2b3c042a 100644
|
||||
--- a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c
|
||||
+++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c
|
||||
@@ -176,6 +176,7 @@ static struct cmn2asic_mapping smu_v13_0_0_clk_map[SMU_CLK_COUNT] = {
|
||||
CLK_MAP(VCLK1, PPCLK_VCLK_1),
|
||||
CLK_MAP(DCLK, PPCLK_DCLK_0),
|
||||
CLK_MAP(DCLK1, PPCLK_DCLK_1),
|
||||
+ CLK_MAP(DCEFCLK, PPCLK_DCFCLK),
|
||||
};
|
||||
|
||||
static struct cmn2asic_mapping smu_v13_0_0_feature_mask_map[SMU_FEATURE_COUNT] = {
|
||||
@@ -707,6 +708,22 @@ static int smu_v13_0_0_set_default_dpm_table(struct smu_context *smu)
|
||||
pcie_table->num_of_link_levels++;
|
||||
}
|
||||
|
||||
+ /* dcefclk dpm table setup */
|
||||
+ dpm_table = &dpm_context->dpm_tables.dcef_table;
|
||||
+ if (smu_cmn_feature_is_enabled(smu, SMU_FEATURE_DPM_DCN_BIT)) {
|
||||
+ ret = smu_v13_0_set_single_dpm_table(smu,
|
||||
+ SMU_DCEFCLK,
|
||||
+ dpm_table);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+ } else {
|
||||
+ dpm_table->count = 1;
|
||||
+ dpm_table->dpm_levels[0].value = smu->smu_table.boot_values.dcefclk / 100;
|
||||
+ dpm_table->dpm_levels[0].enabled = true;
|
||||
+ dpm_table->min = dpm_table->dpm_levels[0].value;
|
||||
+ dpm_table->max = dpm_table->dpm_levels[0].value;
|
||||
+ }
|
||||
+
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -794,6 +811,9 @@ static int smu_v13_0_0_get_smu_metrics_data(struct smu_context *smu,
|
||||
case METRICS_CURR_FCLK:
|
||||
*value = metrics->CurrClock[PPCLK_FCLK];
|
||||
break;
|
||||
+ case METRICS_CURR_DCEFCLK:
|
||||
+ *value = metrics->CurrClock[PPCLK_DCFCLK];
|
||||
+ break;
|
||||
case METRICS_AVERAGE_GFXCLK:
|
||||
if (metrics->AverageGfxActivity <= SMU_13_0_0_BUSY_THRESHOLD)
|
||||
*value = metrics->AverageGfxclkFrequencyPostDs;
|
||||
@@ -1047,6 +1067,9 @@ static int smu_v13_0_0_get_current_clk_freq_by_table(struct smu_context *smu,
|
||||
case PPCLK_DCLK_1:
|
||||
member_type = METRICS_AVERAGE_DCLK1;
|
||||
break;
|
||||
+ case PPCLK_DCFCLK:
|
||||
+ member_type = METRICS_CURR_DCEFCLK;
|
||||
+ break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
@@ -1196,6 +1219,9 @@ static int smu_v13_0_0_print_clk_levels(struct smu_context *smu,
|
||||
case SMU_DCLK1:
|
||||
single_dpm_table = &(dpm_context->dpm_tables.dclk_table);
|
||||
break;
|
||||
+ case SMU_DCEFCLK:
|
||||
+ single_dpm_table = &(dpm_context->dpm_tables.dcef_table);
|
||||
+ break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -1209,6 +1235,7 @@ static int smu_v13_0_0_print_clk_levels(struct smu_context *smu,
|
||||
case SMU_VCLK1:
|
||||
case SMU_DCLK:
|
||||
case SMU_DCLK1:
|
||||
+ case SMU_DCEFCLK:
|
||||
ret = smu_v13_0_0_get_current_clk_freq_by_table(smu, clk_type, &curr_freq);
|
||||
if (ret) {
|
||||
dev_err(smu->adev->dev, "Failed to get current clock freq!");
|
||||
diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c
|
||||
index b9b3bf41eed3..12949928e285 100644
|
||||
--- a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c
|
||||
+++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c
|
||||
@@ -147,6 +147,7 @@ static struct cmn2asic_mapping smu_v13_0_7_clk_map[SMU_CLK_COUNT] = {
|
||||
CLK_MAP(VCLK1, PPCLK_VCLK_1),
|
||||
CLK_MAP(DCLK, PPCLK_DCLK_0),
|
||||
CLK_MAP(DCLK1, PPCLK_DCLK_1),
|
||||
+ CLK_MAP(DCEFCLK, PPCLK_DCFCLK),
|
||||
};
|
||||
|
||||
static struct cmn2asic_mapping smu_v13_0_7_feature_mask_map[SMU_FEATURE_COUNT] = {
|
||||
@@ -696,6 +697,22 @@ static int smu_v13_0_7_set_default_dpm_table(struct smu_context *smu)
|
||||
pcie_table->num_of_link_levels++;
|
||||
}
|
||||
|
||||
+ /* dcefclk dpm table setup */
|
||||
+ dpm_table = &dpm_context->dpm_tables.dcef_table;
|
||||
+ if (smu_cmn_feature_is_enabled(smu, SMU_FEATURE_DPM_DCN_BIT)) {
|
||||
+ ret = smu_v13_0_set_single_dpm_table(smu,
|
||||
+ SMU_DCEFCLK,
|
||||
+ dpm_table);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+ } else {
|
||||
+ dpm_table->count = 1;
|
||||
+ dpm_table->dpm_levels[0].value = smu->smu_table.boot_values.dcefclk / 100;
|
||||
+ dpm_table->dpm_levels[0].enabled = true;
|
||||
+ dpm_table->min = dpm_table->dpm_levels[0].value;
|
||||
+ dpm_table->max = dpm_table->dpm_levels[0].value;
|
||||
+ }
|
||||
+
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -777,6 +794,9 @@ static int smu_v13_0_7_get_smu_metrics_data(struct smu_context *smu,
|
||||
case METRICS_CURR_FCLK:
|
||||
*value = metrics->CurrClock[PPCLK_FCLK];
|
||||
break;
|
||||
+ case METRICS_CURR_DCEFCLK:
|
||||
+ *value = metrics->CurrClock[PPCLK_DCFCLK];
|
||||
+ break;
|
||||
case METRICS_AVERAGE_GFXCLK:
|
||||
*value = metrics->AverageGfxclkFrequencyPreDs;
|
||||
break;
|
||||
@@ -1027,6 +1047,9 @@ static int smu_v13_0_7_get_current_clk_freq_by_table(struct smu_context *smu,
|
||||
case PPCLK_DCLK_1:
|
||||
member_type = METRICS_CURR_DCLK1;
|
||||
break;
|
||||
+ case PPCLK_DCFCLK:
|
||||
+ member_type = METRICS_CURR_DCEFCLK;
|
||||
+ break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
@@ -1176,6 +1199,9 @@ static int smu_v13_0_7_print_clk_levels(struct smu_context *smu,
|
||||
case SMU_DCLK1:
|
||||
single_dpm_table = &(dpm_context->dpm_tables.dclk_table);
|
||||
break;
|
||||
+ case SMU_DCEFCLK:
|
||||
+ single_dpm_table = &(dpm_context->dpm_tables.dcef_table);
|
||||
+ break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -1189,6 +1215,7 @@ static int smu_v13_0_7_print_clk_levels(struct smu_context *smu,
|
||||
case SMU_VCLK1:
|
||||
case SMU_DCLK:
|
||||
case SMU_DCLK1:
|
||||
+ case SMU_DCEFCLK:
|
||||
ret = smu_v13_0_7_get_current_clk_freq_by_table(smu, clk_type, &curr_freq);
|
||||
if (ret) {
|
||||
dev_err(smu->adev->dev, "Failed to get current clock freq!");
|
||||
--
|
||||
GitLab
|
||||
|
||||
From 3a2fb905145e76e4bbb32e90e0c6cd532dafb1b0 Mon Sep 17 00:00:00 2001
|
||||
From: Evan Quan <evan.quan@amd.com>
|
||||
Date: Mon, 14 Aug 2023 10:16:27 +0800
|
||||
Subject: [PATCH] Revert "drm/amd/pm: disable the SMU13 OD feature support
|
||||
temporarily"
|
||||
|
||||
This reverts commit 3592cc20beeece83db4c50a0f400e2dd15139de9.
|
||||
|
||||
The enablement for the new OD mechanism completed. Also, the support for
|
||||
fan control related OD feature has been added via this new mechanism.
|
||||
Thus, it is time to bring back the SMU13 OD support.
|
||||
|
||||
Signed-off-by: Evan Quan <evan.quan@amd.com>
|
||||
Acked-by: Alex Deucher <alexander.deucher@amd.com>
|
||||
---
|
||||
.../drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c | 18 +++---------------
|
||||
.../drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c | 12 +++---------
|
||||
2 files changed, 6 insertions(+), 24 deletions(-)
|
||||
|
||||
diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c
|
||||
index c48f81450d24..093962a37688 100644
|
||||
--- a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c
|
||||
+++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c
|
||||
@@ -348,13 +348,10 @@ static int smu_v13_0_0_check_powerplay_table(struct smu_context *smu)
|
||||
table_context->power_play_table;
|
||||
struct smu_baco_context *smu_baco = &smu->smu_baco;
|
||||
PPTable_t *pptable = smu->smu_table.driver_pptable;
|
||||
-#if 0
|
||||
- PPTable_t *pptable = smu->smu_table.driver_pptable;
|
||||
const OverDriveLimits_t * const overdrive_upperlimits =
|
||||
&pptable->SkuTable.OverDriveLimitsBasicMax;
|
||||
const OverDriveLimits_t * const overdrive_lowerlimits =
|
||||
&pptable->SkuTable.OverDriveLimitsMin;
|
||||
-#endif
|
||||
|
||||
if (powerplay_table->platform_caps & SMU_13_0_0_PP_PLATFORM_CAP_HARDWAREDC)
|
||||
smu->dc_controlled_by_gpio = true;
|
||||
@@ -366,27 +363,18 @@ static int smu_v13_0_0_check_powerplay_table(struct smu_context *smu)
|
||||
if (powerplay_table->platform_caps & SMU_13_0_0_PP_PLATFORM_CAP_MACO)
|
||||
smu_baco->maco_support = true;
|
||||
|
||||
- /*
|
||||
- * We are in the transition to a new OD mechanism.
|
||||
- * Disable the OD feature support for SMU13 temporarily.
|
||||
- * TODO: get this reverted when new OD mechanism online
|
||||
- */
|
||||
-#if 0
|
||||
if (!overdrive_lowerlimits->FeatureCtrlMask ||
|
||||
!overdrive_upperlimits->FeatureCtrlMask)
|
||||
smu->od_enabled = false;
|
||||
|
||||
+ table_context->thermal_controller_type =
|
||||
+ powerplay_table->thermal_controller_type;
|
||||
+
|
||||
/*
|
||||
* Instead of having its own buffer space and get overdrive_table copied,
|
||||
* smu->od_settings just points to the actual overdrive_table
|
||||
*/
|
||||
smu->od_settings = &powerplay_table->overdrive_table;
|
||||
-#else
|
||||
- smu->od_enabled = false;
|
||||
-#endif
|
||||
-
|
||||
- table_context->thermal_controller_type =
|
||||
- powerplay_table->thermal_controller_type;
|
||||
|
||||
smu->adev->pm.no_fan =
|
||||
!(pptable->SkuTable.FeaturesToRun[0] & (1 << FEATURE_FAN_CONTROL_BIT));
|
||||
diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c
|
||||
index 99bc449799a6..430ad1b05ba3 100644
|
||||
--- a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c
|
||||
+++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c
|
||||
@@ -338,12 +338,10 @@ static int smu_v13_0_7_check_powerplay_table(struct smu_context *smu)
|
||||
struct smu_baco_context *smu_baco = &smu->smu_baco;
|
||||
PPTable_t *smc_pptable = table_context->driver_pptable;
|
||||
BoardTable_t *BoardTable = &smc_pptable->BoardTable;
|
||||
-#if 0
|
||||
const OverDriveLimits_t * const overdrive_upperlimits =
|
||||
&smc_pptable->SkuTable.OverDriveLimitsBasicMax;
|
||||
const OverDriveLimits_t * const overdrive_lowerlimits =
|
||||
&smc_pptable->SkuTable.OverDriveLimitsMin;
|
||||
-#endif
|
||||
|
||||
if (powerplay_table->platform_caps & SMU_13_0_7_PP_PLATFORM_CAP_HARDWAREDC)
|
||||
smu->dc_controlled_by_gpio = true;
|
||||
@@ -355,22 +353,18 @@ static int smu_v13_0_7_check_powerplay_table(struct smu_context *smu)
|
||||
if (smu_baco->platform_support && (BoardTable->HsrEnabled || BoardTable->VddqOffEnabled))
|
||||
smu_baco->maco_support = true;
|
||||
|
||||
-#if 0
|
||||
if (!overdrive_lowerlimits->FeatureCtrlMask ||
|
||||
!overdrive_upperlimits->FeatureCtrlMask)
|
||||
smu->od_enabled = false;
|
||||
|
||||
+ table_context->thermal_controller_type =
|
||||
+ powerplay_table->thermal_controller_type;
|
||||
+
|
||||
/*
|
||||
* Instead of having its own buffer space and get overdrive_table copied,
|
||||
* smu->od_settings just points to the actual overdrive_table
|
||||
*/
|
||||
smu->od_settings = &powerplay_table->overdrive_table;
|
||||
-#else
|
||||
- smu->od_enabled = false;
|
||||
-#endif
|
||||
-
|
||||
- table_context->thermal_controller_type =
|
||||
- powerplay_table->thermal_controller_type;
|
||||
|
||||
return 0;
|
||||
}
|
||||
--
|
||||
GitLab
|
||||
|
||||
From 072a8dc3b5260ba08ba2e66036c2c63abd77df52 Mon Sep 17 00:00:00 2001
|
||||
From: Lijo Lazar <lijo.lazar@amd.com>
|
||||
Date: Thu, 24 Aug 2023 17:25:51 +0530
|
||||
Subject: [PATCH] drm/amd/pm: Fix clock reporting for SMUv13.0.6
|
||||
|
||||
On SMU v13.0.6, effective clocks are reported by FW which won't exactly
|
||||
match with DPM level. Report the current clock based on the values
|
||||
matching closest to the effective clock. Also, when deep sleep is
|
||||
applied to a clock, report it with a special level "S:" as in sample
|
||||
clock levels below
|
||||
|
||||
S: 19Mhz *
|
||||
0: 615Mhz
|
||||
1: 800Mhz
|
||||
2: 888Mhz
|
||||
3: 1000Mhz
|
||||
|
||||
Signed-off-by: Lijo Lazar <lijo.lazar@amd.com>
|
||||
Reviewed-by: Hawking Zhang <Hawking.Zhang@amd.com>
|
||||
Reviewed-by: Evan Quan <evan.quan@amd.com>
|
||||
---
|
||||
.../drm/amd/pm/swsmu/smu13/smu_v13_0_6_ppt.c | 159 +++++++-----------
|
||||
1 file changed, 62 insertions(+), 97 deletions(-)
|
||||
|
||||
diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_6_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_6_ppt.c
|
||||
index c2308783053c..29e1cada7667 100644
|
||||
--- a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_6_ppt.c
|
||||
+++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_6_ppt.c
|
||||
@@ -91,6 +91,8 @@
|
||||
#define PCIE_LC_SPEED_CNTL__LC_CURRENT_DATA_RATE__SHIFT 0x5
|
||||
#define LINK_SPEED_MAX 4
|
||||
|
||||
+#define SMU_13_0_6_DSCLK_THRESHOLD 100
|
||||
+
|
||||
static const struct cmn2asic_msg_mapping smu_v13_0_6_message_map[SMU_MSG_MAX_COUNT] = {
|
||||
MSG_MAP(TestMessage, PPSMC_MSG_TestMessage, 0),
|
||||
MSG_MAP(GetSmuVersion, PPSMC_MSG_GetSmuVersion, 1),
|
||||
@@ -783,13 +785,61 @@ static int smu_v13_0_6_get_current_clk_freq_by_table(struct smu_context *smu,
|
||||
return smu_v13_0_6_get_smu_metrics_data(smu, member_type, value);
|
||||
}
|
||||
|
||||
+static int smu_v13_0_6_print_clks(struct smu_context *smu, char *buf,
|
||||
+ struct smu_13_0_dpm_table *single_dpm_table,
|
||||
+ uint32_t curr_clk, const char *clk_name)
|
||||
+{
|
||||
+ struct pp_clock_levels_with_latency clocks;
|
||||
+ int i, ret, size = 0, level = -1;
|
||||
+ uint32_t clk1, clk2;
|
||||
+
|
||||
+ ret = smu_v13_0_6_get_clk_table(smu, &clocks, single_dpm_table);
|
||||
+ if (ret) {
|
||||
+ dev_err(smu->adev->dev, "Attempt to get %s clk levels failed!",
|
||||
+ clk_name);
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ if (!clocks.num_levels)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ if (curr_clk < SMU_13_0_6_DSCLK_THRESHOLD) {
|
||||
+ size = sysfs_emit_at(buf, size, "S: %uMhz *\n", curr_clk);
|
||||
+ for (i = 0; i < clocks.num_levels; i++)
|
||||
+ size += sysfs_emit_at(buf, size, "%d: %uMhz\n", i,
|
||||
+ clocks.data[i].clocks_in_khz /
|
||||
+ 1000);
|
||||
+
|
||||
+ } else {
|
||||
+ if ((clocks.num_levels == 1) ||
|
||||
+ (curr_clk < (clocks.data[0].clocks_in_khz / 1000)))
|
||||
+ level = 0;
|
||||
+ for (i = 0; i < clocks.num_levels; i++) {
|
||||
+ clk1 = clocks.data[i].clocks_in_khz / 1000;
|
||||
+
|
||||
+ if (i < (clocks.num_levels - 1))
|
||||
+ clk2 = clocks.data[i + 1].clocks_in_khz / 1000;
|
||||
+
|
||||
+ if (curr_clk >= clk1 && curr_clk < clk2) {
|
||||
+ level = (curr_clk - clk1) <= (clk2 - curr_clk) ?
|
||||
+ i :
|
||||
+ i + 1;
|
||||
+ }
|
||||
+
|
||||
+ size += sysfs_emit_at(buf, size, "%d: %uMhz %s\n", i,
|
||||
+ clk1, (level == i) ? "*" : "");
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return size;
|
||||
+}
|
||||
+
|
||||
static int smu_v13_0_6_print_clk_levels(struct smu_context *smu,
|
||||
enum smu_clk_type type, char *buf)
|
||||
{
|
||||
- int i, now, size = 0;
|
||||
+ int now, size = 0;
|
||||
int ret = 0;
|
||||
struct smu_umd_pstate_table *pstate_table = &smu->pstate_table;
|
||||
- struct pp_clock_levels_with_latency clocks;
|
||||
struct smu_13_0_dpm_table *single_dpm_table;
|
||||
struct smu_dpm_context *smu_dpm = &smu->smu_dpm;
|
||||
struct smu_13_0_dpm_context *dpm_context = NULL;
|
||||
@@ -852,26 +902,9 @@ static int smu_v13_0_6_print_clk_levels(struct smu_context *smu,
|
||||
}
|
||||
|
||||
single_dpm_table = &(dpm_context->dpm_tables.uclk_table);
|
||||
- ret = smu_v13_0_6_get_clk_table(smu, &clocks, single_dpm_table);
|
||||
- if (ret) {
|
||||
- dev_err(smu->adev->dev,
|
||||
- "Attempt to get memory clk levels Failed!");
|
||||
- return ret;
|
||||
- }
|
||||
|
||||
- for (i = 0; i < clocks.num_levels; i++)
|
||||
- size += sysfs_emit_at(
|
||||
- buf, size, "%d: %uMhz %s\n", i,
|
||||
- clocks.data[i].clocks_in_khz / 1000,
|
||||
- (clocks.num_levels == 1) ?
|
||||
- "*" :
|
||||
- (smu_v13_0_6_freqs_in_same_level(
|
||||
- clocks.data[i].clocks_in_khz /
|
||||
- 1000,
|
||||
- now) ?
|
||||
- "*" :
|
||||
- ""));
|
||||
- break;
|
||||
+ return smu_v13_0_6_print_clks(smu, buf, single_dpm_table, now,
|
||||
+ "mclk");
|
||||
|
||||
case SMU_SOCCLK:
|
||||
ret = smu_v13_0_6_get_current_clk_freq_by_table(smu, SMU_SOCCLK,
|
||||
@@ -883,26 +916,9 @@ static int smu_v13_0_6_print_clk_levels(struct smu_context *smu,
|
||||
}
|
||||
|
||||
single_dpm_table = &(dpm_context->dpm_tables.soc_table);
|
||||
- ret = smu_v13_0_6_get_clk_table(smu, &clocks, single_dpm_table);
|
||||
- if (ret) {
|
||||
- dev_err(smu->adev->dev,
|
||||
- "Attempt to get socclk levels Failed!");
|
||||
- return ret;
|
||||
- }
|
||||
|
||||
- for (i = 0; i < clocks.num_levels; i++)
|
||||
- size += sysfs_emit_at(
|
||||
- buf, size, "%d: %uMhz %s\n", i,
|
||||
- clocks.data[i].clocks_in_khz / 1000,
|
||||
- (clocks.num_levels == 1) ?
|
||||
- "*" :
|
||||
- (smu_v13_0_6_freqs_in_same_level(
|
||||
- clocks.data[i].clocks_in_khz /
|
||||
- 1000,
|
||||
- now) ?
|
||||
- "*" :
|
||||
- ""));
|
||||
- break;
|
||||
+ return smu_v13_0_6_print_clks(smu, buf, single_dpm_table, now,
|
||||
+ "socclk");
|
||||
|
||||
case SMU_FCLK:
|
||||
ret = smu_v13_0_6_get_current_clk_freq_by_table(smu, SMU_FCLK,
|
||||
@@ -914,26 +930,9 @@ static int smu_v13_0_6_print_clk_levels(struct smu_context *smu,
|
||||
}
|
||||
|
||||
single_dpm_table = &(dpm_context->dpm_tables.fclk_table);
|
||||
- ret = smu_v13_0_6_get_clk_table(smu, &clocks, single_dpm_table);
|
||||
- if (ret) {
|
||||
- dev_err(smu->adev->dev,
|
||||
- "Attempt to get fclk levels Failed!");
|
||||
- return ret;
|
||||
- }
|
||||
|
||||
- for (i = 0; i < single_dpm_table->count; i++)
|
||||
- size += sysfs_emit_at(
|
||||
- buf, size, "%d: %uMhz %s\n", i,
|
||||
- single_dpm_table->dpm_levels[i].value,
|
||||
- (clocks.num_levels == 1) ?
|
||||
- "*" :
|
||||
- (smu_v13_0_6_freqs_in_same_level(
|
||||
- clocks.data[i].clocks_in_khz /
|
||||
- 1000,
|
||||
- now) ?
|
||||
- "*" :
|
||||
- ""));
|
||||
- break;
|
||||
+ return smu_v13_0_6_print_clks(smu, buf, single_dpm_table, now,
|
||||
+ "fclk");
|
||||
|
||||
case SMU_VCLK:
|
||||
ret = smu_v13_0_6_get_current_clk_freq_by_table(smu, SMU_VCLK,
|
||||
@@ -945,26 +944,9 @@ static int smu_v13_0_6_print_clk_levels(struct smu_context *smu,
|
||||
}
|
||||
|
||||
single_dpm_table = &(dpm_context->dpm_tables.vclk_table);
|
||||
- ret = smu_v13_0_6_get_clk_table(smu, &clocks, single_dpm_table);
|
||||
- if (ret) {
|
||||
- dev_err(smu->adev->dev,
|
||||
- "Attempt to get vclk levels Failed!");
|
||||
- return ret;
|
||||
- }
|
||||
|
||||
- for (i = 0; i < single_dpm_table->count; i++)
|
||||
- size += sysfs_emit_at(
|
||||
- buf, size, "%d: %uMhz %s\n", i,
|
||||
- single_dpm_table->dpm_levels[i].value,
|
||||
- (clocks.num_levels == 1) ?
|
||||
- "*" :
|
||||
- (smu_v13_0_6_freqs_in_same_level(
|
||||
- clocks.data[i].clocks_in_khz /
|
||||
- 1000,
|
||||
- now) ?
|
||||
- "*" :
|
||||
- ""));
|
||||
- break;
|
||||
+ return smu_v13_0_6_print_clks(smu, buf, single_dpm_table, now,
|
||||
+ "vclk");
|
||||
|
||||
case SMU_DCLK:
|
||||
ret = smu_v13_0_6_get_current_clk_freq_by_table(smu, SMU_DCLK,
|
||||
@@ -976,26 +958,9 @@ static int smu_v13_0_6_print_clk_levels(struct smu_context *smu,
|
||||
}
|
||||
|
||||
single_dpm_table = &(dpm_context->dpm_tables.dclk_table);
|
||||
- ret = smu_v13_0_6_get_clk_table(smu, &clocks, single_dpm_table);
|
||||
- if (ret) {
|
||||
- dev_err(smu->adev->dev,
|
||||
- "Attempt to get dclk levels Failed!");
|
||||
- return ret;
|
||||
- }
|
||||
|
||||
- for (i = 0; i < single_dpm_table->count; i++)
|
||||
- size += sysfs_emit_at(
|
||||
- buf, size, "%d: %uMhz %s\n", i,
|
||||
- single_dpm_table->dpm_levels[i].value,
|
||||
- (clocks.num_levels == 1) ?
|
||||
- "*" :
|
||||
- (smu_v13_0_6_freqs_in_same_level(
|
||||
- clocks.data[i].clocks_in_khz /
|
||||
- 1000,
|
||||
- now) ?
|
||||
- "*" :
|
||||
- ""));
|
||||
- break;
|
||||
+ return smu_v13_0_6_print_clks(smu, buf, single_dpm_table, now,
|
||||
+ "dclk");
|
||||
|
||||
default:
|
||||
break;
|
||||
--
|
||||
GitLab
|
||||
|
||||
|
Reference in New Issue
Block a user