adjustor 3.2.1__tar.gz → 3.3.1__tar.gz
Sign up to get free protection for your applications and to get access to all the features.
- {adjustor-3.2.1/src/adjustor.egg-info → adjustor-3.3.1}/PKG-INFO +1 -1
- {adjustor-3.2.1 → adjustor-3.3.1}/pyproject.toml +1 -1
- {adjustor-3.2.1 → adjustor-3.3.1}/src/adjustor/core/const.py +14 -1
- {adjustor-3.2.1 → adjustor-3.3.1}/src/adjustor/core/lenovo.py +38 -2
- {adjustor-3.2.1 → adjustor-3.3.1}/src/adjustor/drivers/amd/__init__.py +71 -6
- {adjustor-3.2.1 → adjustor-3.3.1}/src/adjustor/drivers/amd/settings.yml +12 -0
- {adjustor-3.2.1 → adjustor-3.3.1}/src/adjustor/drivers/lenovo/__init__.py +26 -2
- {adjustor-3.2.1 → adjustor-3.3.1}/src/adjustor/drivers/lenovo/settings.yml +7 -2
- {adjustor-3.2.1 → adjustor-3.3.1}/src/adjustor/hhd.py +12 -0
- {adjustor-3.2.1 → adjustor-3.3.1/src/adjustor.egg-info}/PKG-INFO +1 -1
- {adjustor-3.2.1 → adjustor-3.3.1}/LICENSE +0 -0
- {adjustor-3.2.1 → adjustor-3.3.1}/MANIFEST.in +0 -0
- {adjustor-3.2.1 → adjustor-3.3.1}/readme.md +0 -0
- {adjustor-3.2.1 → adjustor-3.3.1}/setup.cfg +0 -0
- {adjustor-3.2.1 → adjustor-3.3.1}/src/adjustor/__init__.py +0 -0
- {adjustor-3.2.1 → adjustor-3.3.1}/src/adjustor/__main__.py +0 -0
- {adjustor-3.2.1 → adjustor-3.3.1}/src/adjustor/core/__init__.py +0 -0
- {adjustor-3.2.1 → adjustor-3.3.1}/src/adjustor/core/acpi.py +0 -0
- {adjustor-3.2.1 → adjustor-3.3.1}/src/adjustor/core/alib.py +0 -0
- {adjustor-3.2.1 → adjustor-3.3.1}/src/adjustor/core/platform.py +0 -0
- {adjustor-3.2.1 → adjustor-3.3.1}/src/adjustor/drivers/__init__.py +0 -0
- {adjustor-3.2.1 → adjustor-3.3.1}/src/adjustor/drivers/amd/power-profiles-daemon.dbus.xml.in +0 -0
- {adjustor-3.2.1 → adjustor-3.3.1}/src/adjustor/drivers/amd/ppd.py +0 -0
- {adjustor-3.2.1 → adjustor-3.3.1}/src/adjustor/drivers/asus/__init__.py +0 -0
- {adjustor-3.2.1 → adjustor-3.3.1}/src/adjustor/drivers/asus/settings.yml +0 -0
- {adjustor-3.2.1 → adjustor-3.3.1}/src/adjustor/drivers/smu/__init__.py +0 -0
- {adjustor-3.2.1 → adjustor-3.3.1}/src/adjustor/drivers/smu/qam.yml +0 -0
- {adjustor-3.2.1 → adjustor-3.3.1}/src/adjustor/drivers/smu/smu.yml +0 -0
- {adjustor-3.2.1 → adjustor-3.3.1}/src/adjustor/events.py +0 -0
- {adjustor-3.2.1 → adjustor-3.3.1}/src/adjustor/fuse/__init__.py +0 -0
- {adjustor-3.2.1 → adjustor-3.3.1}/src/adjustor/fuse/driver.py +0 -0
- {adjustor-3.2.1 → adjustor-3.3.1}/src/adjustor/fuse/gpu.py +0 -0
- {adjustor-3.2.1 → adjustor-3.3.1}/src/adjustor/fuse/utils.py +0 -0
- {adjustor-3.2.1 → adjustor-3.3.1}/src/adjustor/i18n.py +0 -0
- {adjustor-3.2.1 → adjustor-3.3.1}/src/adjustor/settings.yml +0 -0
- {adjustor-3.2.1 → adjustor-3.3.1}/src/adjustor.egg-info/SOURCES.txt +0 -0
- {adjustor-3.2.1 → adjustor-3.3.1}/src/adjustor.egg-info/dependency_links.txt +0 -0
- {adjustor-3.2.1 → adjustor-3.3.1}/src/adjustor.egg-info/entry_points.txt +0 -0
- {adjustor-3.2.1 → adjustor-3.3.1}/src/adjustor.egg-info/requires.txt +0 -0
- {adjustor-3.2.1 → adjustor-3.3.1}/src/adjustor.egg-info/top_level.txt +0 -0
- {adjustor-3.2.1 → adjustor-3.3.1}/usr/share/dbus-1/system.d/hhd-net.hadess.PowerProfiles.conf +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: adjustor
|
3
|
-
Version: 3.
|
3
|
+
Version: 3.3.1
|
4
4
|
Summary: Adjustor, a userspace program for managing the TDP of handheld devices.
|
5
5
|
Author-email: Kapenekakis Antheas <pypi@antheas.dev>
|
6
6
|
Project-URL: Homepage, https://github.com/hhd-dev/adjustor
|
@@ -41,12 +41,25 @@ DEV_PARAMS_7040: dict[str, DeviceParams] = {
|
|
41
41
|
"temp_target": D(60, 70, 85, 90, 100),
|
42
42
|
}
|
43
43
|
|
44
|
+
DEV_PARAMS_28W: dict[str, DeviceParams] = {
|
45
|
+
"stapm_limit": D(0, 4, 15, 28, 35),
|
46
|
+
"skin_limit": D(0, 4, 15, 28, 35),
|
47
|
+
"slow_limit": D(0, 4, 20, 32, 37),
|
48
|
+
"fast_limit": D(0, 4, 25, 35, 40),
|
49
|
+
# Times
|
50
|
+
"slow_time": D(5, 5, 10, 10, 10),
|
51
|
+
"stapm_time": D(100, 100, 100, 200, 200),
|
52
|
+
# Temp
|
53
|
+
"temp_target": D(60, 70, 85, 90, 100),
|
54
|
+
}
|
55
|
+
|
44
56
|
DEV_PARAMS_6040: dict[str, DeviceParams] = DEV_PARAMS_7040
|
45
57
|
DEV_PARAMS_8040: dict[str, DeviceParams] = DEV_PARAMS_7040
|
46
58
|
DEV_PARAMS_LEGO = DEV_PARAMS_7040
|
47
59
|
|
48
60
|
DEV_DATA: dict[str, tuple[dict[str, DeviceParams], dict[str, AlibParams], bool]] = {
|
49
|
-
"NEO-01": (
|
61
|
+
"NEO-01": (DEV_PARAMS_28W, ALIB_PARAMS_7040, False),
|
62
|
+
"V3": (DEV_PARAMS_28W, ALIB_PARAMS_8040, False),
|
50
63
|
"83E1": (DEV_PARAMS_LEGO, ALIB_PARAMS_7040, False),
|
51
64
|
}
|
52
65
|
|
@@ -104,12 +104,12 @@ def set_fan_curve(arr: Sequence[int], lim: Sequence[int] | None = None):
|
|
104
104
|
)
|
105
105
|
|
106
106
|
|
107
|
-
def
|
107
|
+
def set_power_light_v1(enabled: bool):
|
108
108
|
logger.debug(f"Setting power light status.")
|
109
109
|
return call(r"\_SB.GZFD.WMAF", [0, 0x02, bytes([0x03, int(enabled), 0x00])])
|
110
110
|
|
111
111
|
|
112
|
-
def
|
112
|
+
def get_power_light_v1():
|
113
113
|
logger.debug(f"Getting power light status.")
|
114
114
|
if not call(r"\_SB.GZFD.WMAF", [0, 0x01, 0x03], risky=False):
|
115
115
|
return None
|
@@ -119,6 +119,42 @@ def get_power_light():
|
|
119
119
|
return None
|
120
120
|
|
121
121
|
|
122
|
+
def set_power_light(enabled: bool, suspend: bool = False):
|
123
|
+
logger.debug(f"Setting power light status.")
|
124
|
+
if enabled:
|
125
|
+
if suspend:
|
126
|
+
cb = 0x03
|
127
|
+
else:
|
128
|
+
cb = 0x02
|
129
|
+
else:
|
130
|
+
cb = 0x01
|
131
|
+
return call(
|
132
|
+
r"\_SB.GZFD.WMAF",
|
133
|
+
[0, 0x02, bytes([0x024 if suspend else 0x04, 0x00, cb])],
|
134
|
+
)
|
135
|
+
|
136
|
+
|
137
|
+
def get_power_light(suspend: bool = False):
|
138
|
+
logger.debug(f"Getting power light status.")
|
139
|
+
if not call(r"\_SB.GZFD.WMAF", [0, 0x01, 0x024 if suspend else 0x04], risky=False):
|
140
|
+
return None
|
141
|
+
o = read()
|
142
|
+
if isinstance(o, bytes) and len(o) == 2:
|
143
|
+
return o[1] == (0x03 if suspend else 0x02)
|
144
|
+
return None
|
145
|
+
|
146
|
+
|
147
|
+
def get_bios_version():
|
148
|
+
raw = None
|
149
|
+
try:
|
150
|
+
with open("/sys/class/dmi/id/bios_version") as f:
|
151
|
+
raw = f.read()
|
152
|
+
return int(raw.replace("N3CN", "").split("WW")[0].strip())
|
153
|
+
except Exception as e:
|
154
|
+
logger.error(f"Failed to get BIOS version from '{raw}' with error:\n{e}")
|
155
|
+
return 1
|
156
|
+
|
157
|
+
|
122
158
|
def get_feature(id: int):
|
123
159
|
if not call(
|
124
160
|
r"\_SB.GZFD.WMAE",
|
@@ -2,10 +2,11 @@ import logging
|
|
2
2
|
import os
|
3
3
|
import subprocess
|
4
4
|
import sys
|
5
|
-
from threading import Event as TEvent
|
6
5
|
from threading import Thread
|
7
6
|
from typing import Literal
|
7
|
+
import shutil
|
8
8
|
import time
|
9
|
+
import signal
|
9
10
|
|
10
11
|
from hhd.plugins import Context, HHDPlugin, load_relative_yaml
|
11
12
|
from hhd.plugins.conf import Config
|
@@ -67,14 +68,18 @@ class AmdGPUPlugin(HHDPlugin):
|
|
67
68
|
self.ppd_conflict = False
|
68
69
|
self.initialized = False
|
69
70
|
self.supports_boost = False
|
71
|
+
self.supports_sched = False
|
72
|
+
self.avail_scheds = {}
|
70
73
|
|
71
74
|
self.proc = None
|
72
75
|
self.t = None
|
73
76
|
|
74
77
|
self.queue = None
|
78
|
+
self.sched_proc = None
|
75
79
|
self.old_ppd = False
|
76
80
|
self.old_gpu = None
|
77
81
|
self.old_freq = None
|
82
|
+
self.old_sched = "disabled"
|
78
83
|
self.old_boost = None
|
79
84
|
self.old_epp = None
|
80
85
|
self.old_target = None
|
@@ -174,6 +179,31 @@ class AmdGPUPlugin(HHDPlugin):
|
|
174
179
|
"cpu_pref"
|
175
180
|
]
|
176
181
|
|
182
|
+
self.avail_scheds = {}
|
183
|
+
avail_pretty = {}
|
184
|
+
kernel_supports = os.path.isfile("/sys/kernel/sched_ext/state")
|
185
|
+
if kernel_supports:
|
186
|
+
for sched, pretty in sets["enabled"]["children"]["mode"]["modes"]["manual"][
|
187
|
+
"children"
|
188
|
+
]["sched"]["options"].items():
|
189
|
+
if sched == "disabled":
|
190
|
+
avail_pretty[sched] = pretty
|
191
|
+
continue
|
192
|
+
|
193
|
+
exe = shutil.which(sched)
|
194
|
+
if exe:
|
195
|
+
self.avail_scheds[sched] = exe
|
196
|
+
avail_pretty[sched] = pretty
|
197
|
+
|
198
|
+
if self.avail_scheds:
|
199
|
+
sets["enabled"]["children"]["mode"]["modes"]["manual"]["children"]["sched"][
|
200
|
+
"options"
|
201
|
+
] = avail_pretty
|
202
|
+
else:
|
203
|
+
del sets["enabled"]["children"]["mode"]["modes"]["manual"]["children"][
|
204
|
+
"sched"
|
205
|
+
]
|
206
|
+
|
177
207
|
self.logged_boost = True
|
178
208
|
return {
|
179
209
|
"tdp": {"amd_energy": sets["enabled"]},
|
@@ -197,7 +227,7 @@ class AmdGPUPlugin(HHDPlugin):
|
|
197
227
|
self.proc.stdin.flush()
|
198
228
|
except Exception as e:
|
199
229
|
logger.error(f"Failed to send PPD mode:\n{e}")
|
200
|
-
self.
|
230
|
+
self.close_ppd()
|
201
231
|
|
202
232
|
def update(self, conf: Config):
|
203
233
|
self.core_enabled = conf["hhd.settings.tdp_enable"].to(bool)
|
@@ -224,9 +254,9 @@ class AmdGPUPlugin(HHDPlugin):
|
|
224
254
|
self.proc, self.t = _open_ppd_server(self.emit)
|
225
255
|
except Exception as e:
|
226
256
|
logger.error(f"Failed to open PPD server:\n{e}")
|
227
|
-
self.
|
257
|
+
self.close_ppd()
|
228
258
|
else:
|
229
|
-
self.
|
259
|
+
self.close_ppd()
|
230
260
|
|
231
261
|
if conf["tdp.amd_energy.mode.mode"].to(str) == "auto":
|
232
262
|
curr = time.perf_counter()
|
@@ -239,6 +269,8 @@ class AmdGPUPlugin(HHDPlugin):
|
|
239
269
|
logger.info(
|
240
270
|
f"Handling energy settings for power profile '{self.target}'."
|
241
271
|
)
|
272
|
+
# Unless it is set manually, use the default scheduler.
|
273
|
+
self.close_sched()
|
242
274
|
try:
|
243
275
|
match self.target:
|
244
276
|
case "balanced":
|
@@ -329,10 +361,43 @@ class AmdGPUPlugin(HHDPlugin):
|
|
329
361
|
except Exception as e:
|
330
362
|
logger.error(f"Failed to set minimum CPU frequency:\n{e}")
|
331
363
|
|
332
|
-
|
364
|
+
if self.avail_scheds:
|
365
|
+
# Check health and print error
|
366
|
+
if self.sched_proc and self.sched_proc.poll():
|
367
|
+
err = self.sched_proc.poll()
|
368
|
+
self.sched_proc = None
|
369
|
+
logger.error(
|
370
|
+
f"Scheduler from sched_ext '{self.old_sched}' closed with error code: {err}"
|
371
|
+
)
|
372
|
+
|
373
|
+
new_sched = conf.get("tdp.amd_energy.mode.manual.sched", "disabled")
|
374
|
+
if new_sched != self.old_sched:
|
375
|
+
self.close_sched()
|
376
|
+
self.old_sched = new_sched
|
377
|
+
if new_sched and new_sched != "disabled":
|
378
|
+
logger.info(f"Starting sched_ext scheduler '{new_sched}'")
|
379
|
+
self.sched_proc = subprocess.Popen(
|
380
|
+
self.avail_scheds[new_sched],
|
381
|
+
stderr=subprocess.DEVNULL,
|
382
|
+
stdout=subprocess.DEVNULL,
|
383
|
+
)
|
384
|
+
|
385
|
+
def close_ppd(self):
|
333
386
|
if self.proc is not None:
|
334
|
-
self.proc.
|
387
|
+
self.proc.send_signal(signal.SIGINT)
|
335
388
|
self.proc.wait()
|
389
|
+
self.proc = None
|
336
390
|
if self.t is not None:
|
337
391
|
self.t.join()
|
338
392
|
self.t = None
|
393
|
+
|
394
|
+
def close_sched(self):
|
395
|
+
if self.sched_proc is not None:
|
396
|
+
logger.info(f"Closing sched_ext scheduler '{self.old_sched}'.")
|
397
|
+
self.sched_proc.send_signal(signal.SIGINT)
|
398
|
+
self.sched_proc.wait()
|
399
|
+
self.sched_proc = None
|
400
|
+
|
401
|
+
def close(self):
|
402
|
+
self.close_ppd()
|
403
|
+
self.close_sched()
|
@@ -87,6 +87,18 @@ enabled:
|
|
87
87
|
max: 2000
|
88
88
|
step: 100
|
89
89
|
default: 1000
|
90
|
+
sched:
|
91
|
+
type: multiple
|
92
|
+
title: Custom Scheduler
|
93
|
+
hint: >-
|
94
|
+
Allows attaching a scheduler to the kernel sched_ext.
|
95
|
+
Schedulers need to be installed and kernel needs to support sched_ext.
|
96
|
+
options:
|
97
|
+
disabled: Disabled
|
98
|
+
scx_lavd: LAVD
|
99
|
+
scx_bpfland: bpfland
|
100
|
+
scx_rusty: rusty
|
101
|
+
default: disabled
|
90
102
|
|
91
103
|
conflict:
|
92
104
|
title: Energy Management
|
@@ -20,6 +20,9 @@ from adjustor.core.lenovo import (
|
|
20
20
|
set_slow_tdp,
|
21
21
|
set_steady_tdp,
|
22
22
|
set_tdp_mode,
|
23
|
+
get_bios_version,
|
24
|
+
get_power_light_v1,
|
25
|
+
set_power_light_v1,
|
23
26
|
)
|
24
27
|
|
25
28
|
logger = logging.getLogger(__name__)
|
@@ -40,6 +43,10 @@ class LenovoDriverPlugin(HHDPlugin):
|
|
40
43
|
self.old_conf = None
|
41
44
|
self.fan_curve_set = False
|
42
45
|
|
46
|
+
bios_version = get_bios_version()
|
47
|
+
logger.info(f"Lenovo BIOS version: {bios_version}")
|
48
|
+
self.power_light_v2 = bios_version >= 35
|
49
|
+
|
43
50
|
self.queue_fan = None
|
44
51
|
self.queue_tdp = None
|
45
52
|
self.new_tdp = None
|
@@ -55,6 +62,8 @@ class LenovoDriverPlugin(HHDPlugin):
|
|
55
62
|
|
56
63
|
self.initialized = True
|
57
64
|
out = {"tdp": {"lenovo": load_relative_yaml("settings.yml")}}
|
65
|
+
if not self.power_light_v2:
|
66
|
+
del out["tdp"]["lenovo"]["children"]["power_light_sleep"]
|
58
67
|
if not self.enforce_limits:
|
59
68
|
out["tdp"]["lenovo"]["children"]["tdp"]["modes"]["custom"]["children"][
|
60
69
|
"tdp"
|
@@ -88,7 +97,12 @@ class LenovoDriverPlugin(HHDPlugin):
|
|
88
97
|
tdp_reset = self.startup
|
89
98
|
if self.startup:
|
90
99
|
conf["tdp.lenovo.ffss"] = get_full_fan_speed()
|
91
|
-
|
100
|
+
if self.power_light_v2:
|
101
|
+
conf["tdp.lenovo.power_light"] = get_power_light(suspend=False)
|
102
|
+
conf["tdp.lenovo.power_light_sleep"] = get_power_light(suspend=True)
|
103
|
+
else:
|
104
|
+
conf["tdp.lenovo.power_light"] = get_power_light_v1()
|
105
|
+
|
92
106
|
conf["tdp.lenovo.charge_limit"] = get_charge_limit()
|
93
107
|
|
94
108
|
# If not old config, exit, as values can not be set
|
@@ -109,7 +123,17 @@ class LenovoDriverPlugin(HHDPlugin):
|
|
109
123
|
if power_light is not None and power_light != self.old_conf["power_light"].to(
|
110
124
|
bool
|
111
125
|
):
|
112
|
-
|
126
|
+
if self.power_light_v2:
|
127
|
+
set_power_light(power_light, suspend=False)
|
128
|
+
else:
|
129
|
+
set_power_light_v1(power_light)
|
130
|
+
if self.power_light_v2:
|
131
|
+
power_light_sleep = conf["tdp.lenovo.power_light_sleep"].to(bool)
|
132
|
+
if (
|
133
|
+
power_light_sleep != self.old_conf["power_light_sleep"].to(bool)
|
134
|
+
and power_light_sleep is not None
|
135
|
+
):
|
136
|
+
set_power_light(power_light_sleep, suspend=True)
|
113
137
|
|
114
138
|
charge_limit = conf["tdp.lenovo.charge_limit"].to(bool)
|
115
139
|
if charge_limit is not None and charge_limit != self.old_conf[
|
@@ -137,11 +137,16 @@ children:
|
|
137
137
|
charge_limit:
|
138
138
|
tags: [advanced]
|
139
139
|
type: bool
|
140
|
-
title:
|
140
|
+
title: Charge Limit (80%)
|
141
141
|
hint: >-
|
142
142
|
Limits device charging to 80%. Lenovo EC method. Available since BIOSv29.
|
143
143
|
|
144
144
|
power_light:
|
145
145
|
tags: [advanced]
|
146
146
|
type: bool
|
147
|
-
title:
|
147
|
+
title: Power Light (Awake)
|
148
|
+
|
149
|
+
power_light_sleep:
|
150
|
+
tags: [advanced]
|
151
|
+
type: bool
|
152
|
+
title: Power Light (Sleep)
|
@@ -274,6 +274,18 @@ def autodetect(existing: Sequence[HHDPlugin]) -> Sequence[HHDPlugin]:
|
|
274
274
|
|
275
275
|
if not drivers_matched and prod in DEV_DATA:
|
276
276
|
dev, cpu, pp_enable = DEV_DATA[prod]
|
277
|
+
|
278
|
+
try:
|
279
|
+
# Set values for the steam slider
|
280
|
+
if dev["skin_limit"].smin:
|
281
|
+
min_tdp = dev["skin_limit"].smin
|
282
|
+
if dev["skin_limit"].default:
|
283
|
+
default_tdp = dev["skin_limit"].default
|
284
|
+
if dev["skin_limit"].smax:
|
285
|
+
max_tdp = dev["skin_limit"].smax
|
286
|
+
except Exception as e:
|
287
|
+
logger.error(f"Failed to get TDP limits for {prod}:\n{e}")
|
288
|
+
|
277
289
|
pp_enable |= bool(os.environ.get("HHD_ADJ_DEBUG"))
|
278
290
|
drivers.append(
|
279
291
|
SmuDriverPlugin(
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: adjustor
|
3
|
-
Version: 3.
|
3
|
+
Version: 3.3.1
|
4
4
|
Summary: Adjustor, a userspace program for managing the TDP of handheld devices.
|
5
5
|
Author-email: Kapenekakis Antheas <pypi@antheas.dev>
|
6
6
|
Project-URL: Homepage, https://github.com/hhd-dev/adjustor
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{adjustor-3.2.1 → adjustor-3.3.1}/src/adjustor/drivers/amd/power-profiles-daemon.dbus.xml.in
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{adjustor-3.2.1 → adjustor-3.3.1}/usr/share/dbus-1/system.d/hhd-net.hadess.PowerProfiles.conf
RENAMED
File without changes
|