Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100755 356 lines (280 sloc) 17.919 kb
02dcc66 @mjmvisser renamed atitweak.py to atitweak, added #!
authored
1 #!/usr/bin/python
4b7b7d8 @mjmvisser added licensing
authored
2 # Copyright (C) 2011 by Mark Visser <mjmvisser@gmail.com>
3 #
4 # Permission is hereby granted, free of charge, to any person obtaining a copy
5 # of this software and associated documentation files (the "Software"), to deal
6 # in the Software without restriction, including without limitation the rights
7 # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 # copies of the Software, and to permit persons to whom the Software is
9 # furnished to do so, subject to the following conditions:
10 #
11 # The above copyright notice and this permission notice shall be included in
12 # all copies or substantial portions of the Software.
13 #
14 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 # THE SOFTWARE.
02dcc66 @mjmvisser renamed atitweak.py to atitweak, added #!
authored
21
8f9bc1d @mjmvisser now assumes DISPLAY is :0 if not set in environment
authored
22 import os, sys
fe83028 @mjmvisser sample use of adl3 library to tweak performance levels
authored
23 from optparse import OptionParser
24 from adl3 import *
d82d4f7 @lueo Select correct controller by AdapterID.
lueo authored
25 import collections
fe83028 @mjmvisser sample use of adl3 library to tweak performance levels
authored
26
27 class ADLError(Exception):
28 pass
29
30 adapters = []
31
32 def initialize():
8f9bc1d @mjmvisser now assumes DISPLAY is :0 if not set in environment
authored
33 # check for unset DISPLAY, assume :0
34 if "DISPLAY" not in os.environ:
35 os.environ["DISPLAY"] = ":0"
36
fe83028 @mjmvisser sample use of adl3 library to tweak performance levels
authored
37 # the '1' means only retrieve info for active adapters
38 if ADL_Main_Control_Create(ADL_Main_Memory_Alloc, 1) != ADL_OK:
39 raise ADLError("Couldn't initialize ADL interface.")
40
41 def shutdown():
42 if ADL_Main_Control_Destroy() != ADL_OK:
43 raise ADLError("Couldn't destroy ADL interface global pointers.")
44
45 def get_adapter_info():
62cdead @lueo Select correct controller by AdapterID.
lueo authored
46 adapter_info = []
fe83028 @mjmvisser sample use of adl3 library to tweak performance levels
authored
47 num_adapters = c_int(-1)
48 if ADL_Adapter_NumberOfAdapters_Get(byref(num_adapters)) != ADL_OK:
49 raise ADLError("ADL_Adapter_NumberOfAdapters_Get failed.")
50
51 # allocate an array of AdapterInfo, see ctypes docs for more info
d82d4f7 @lueo Select correct controller by AdapterID.
lueo authored
52 AdapterInfoArray = (AdapterInfo * num_adapters.value)()
fe83028 @mjmvisser sample use of adl3 library to tweak performance levels
authored
53
54 # AdapterInfo_Get grabs info for ALL adapters in the system
d82d4f7 @lueo Select correct controller by AdapterID.
lueo authored
55 if ADL_Adapter_AdapterInfo_Get(cast(AdapterInfoArray, LPAdapterInfo), sizeof(AdapterInfoArray)) != ADL_OK:
fe83028 @mjmvisser sample use of adl3 library to tweak performance levels
authored
56 raise ADLError("ADL_Adapter_AdapterInfo_Get failed.")
57
d82d4f7 @lueo Select correct controller by AdapterID.
lueo authored
58 deviceAdapter = collections.namedtuple('DeviceAdapter', ['AdapterIndex', 'AdapterID', 'BusNumber', 'UDID'])
59 devices = []
60
61 for adapter in AdapterInfoArray:
62 index = adapter.iAdapterIndex
63 busNum = adapter.iBusNumber
64 udid = adapter.strUDID
65
66 adapterID = c_int(-1)
67 #status = c_int(-1)
68
69 if ADL_Adapter_ID_Get(index, byref(adapterID)) != ADL_OK:
fe83028 @mjmvisser sample use of adl3 library to tweak performance levels
authored
70 raise ADLError("ADL_Adapter_Active_Get failed.")
d82d4f7 @lueo Select correct controller by AdapterID.
lueo authored
71
72 found = False
73 for device in devices:
74 debug_here()
75 if (device.AdapterID.value == adapterID.value):
76 found = True
77 break
78
79 # save it in our list if it's the first index of the adapter
80 if (found == False):
81 devices.append(deviceAdapter(index,adapterID,busNum,udid))
82
83 #debug_here()
84
85 for device in devices:
86 adapter_info.append(AdapterInfoArray[device.AdapterIndex])
fe83028 @mjmvisser sample use of adl3 library to tweak performance levels
authored
87
88 return adapter_info
89
90 def list_adapters(adapter_list=None):
91 adapter_info = get_adapter_info()
92
93 for index, info in enumerate(adapter_info):
94 if adapter_list is None or index in adapter_list:
95 print "%d. %s (%s)" % (index, info.strAdapterName, info.strDisplayName)
96
97 od_parameters = ADLODParameters()
98 od_parameters.iSize = sizeof(od_parameters)
99
100 if ADL_Overdrive5_ODParameters_Get(info.iAdapterIndex, byref(od_parameters)) != ADL_OK:
101 raise ADLError("ADL_Overdrive5_ODParameters_Get failed.")
102
103 print " engine clock range is %g - %gMHz" % (od_parameters.sEngineClock.iMin/100.0,od_parameters.sEngineClock.iMax/100.0)
104 print " memory clock range is %g - %gMHz" % (od_parameters.sMemoryClock.iMin/100.0, od_parameters.sMemoryClock.iMax/100.0)
105 print " core voltage range is %g - %gVDC" % (od_parameters.sVddc.iMin/1000.0, od_parameters.sVddc.iMax/1000.0)
106
107 if od_parameters.iDiscretePerformanceLevels:
108 plevels = ADLODPerformanceLevels()
109 plevels_size = sizeof(ADLODPerformanceLevels) + sizeof(ADLODPerformanceLevel) * (od_parameters.iNumberOfPerformanceLevels -1)
110 resize(plevels, plevels_size)
111 plevels.iSize = plevels_size
112
113 if ADL_Overdrive5_ODPerformanceLevels_Get(info.iAdapterIndex, 0, byref(plevels)) != ADL_OK:
114 raise ADLError("ADL_Overdrive5_ODPerformanceLevels_Get failed.")
115
116 levels = cast(plevels.aLevels, POINTER(ADLODPerformanceLevel))
117
118 for index in range(0, od_parameters.iNumberOfPerformanceLevels):
119 print " performance level %d: engine clock %gMHz, memory clock %gMHz, core voltage %gVDC" % (index,
120 levels[index].iEngineClock/100.0,
121 levels[index].iMemoryClock/100.0,
122 levels[index].iVddc/1000.0)
123
8f9bc1d @mjmvisser now assumes DISPLAY is :0 if not set in environment
authored
124 fan_speed_info = ADLFanSpeedInfo()
125 fan_speed_info.iSize = sizeof(fan_speed_info)
126
127 if ADL_Overdrive5_FanSpeedInfo_Get(info.iAdapterIndex, 0, byref(fan_speed_info)) != ADL_OK:
128 raise ADLError("ADL_Overdrive5_FanSpeedInfo_Get failed.")
129
130 print " fan speed range: %d - %d%%, %d - %d RPM" % (fan_speed_info.iMinPercent, fan_speed_info.iMaxPercent,
131 fan_speed_info.iMinRPM, fan_speed_info.iMaxRPM)
132
133
134
135 def show_status(adapter_list=None):
136 adapter_info = get_adapter_info()
137
138 for index, info in enumerate(adapter_info):
139 if adapter_list is None or index in adapter_list:
140 print "%d. %s (%s)" % (index, info.strAdapterName, info.strDisplayName)
141
142 activity = ADLPMActivity()
143 activity.iSize = sizeof(activity)
144
145 if ADL_Overdrive5_CurrentActivity_Get(info.iAdapterIndex, byref(activity)) != ADL_OK:
146 raise ADLError("ADL_Overdrive5_CurrentActivity_Get failed.")
147
148 print (" engine clock %gMHz, memory clock %gMHz, core voltage %gVDC, performance level %d, utilization %d%%" %
149 (activity.iEngineClock/100.0, activity.iMemoryClock/100.0, activity.iVddc/1000.0,
150 activity.iCurrentPerformanceLevel, activity.iActivityPercent))
151
545e286 @mjmvisser catch failure of ADL_Overdrive5_FanSpeed_Get and continue gracefully
authored
152 try:
153 fan_speed = {}
154 for speed_type in (ADL_DL_FANCTRL_SPEED_TYPE_PERCENT, ADL_DL_FANCTRL_SPEED_TYPE_RPM):
155 fan_speed_value = ADLFanSpeedValue()
156 fan_speed_value.iSize = sizeof(fan_speed_value)
157 fan_speed_value.iSpeedType = speed_type
158
159 if ADL_Overdrive5_FanSpeed_Get(info.iAdapterIndex, 0, byref(fan_speed_value)) != ADL_OK:
160 raise ADLError("ADL_Overdrive5_FanSpeed_Get failed.")
161
162 fan_speed[speed_type] = fan_speed_value.iFanSpeed
163 user_defined = fan_speed_value.iFlags & ADL_DL_FANCTRL_FLAG_USER_DEFINED_SPEED
8f9bc1d @mjmvisser now assumes DISPLAY is :0 if not set in environment
authored
164
545e286 @mjmvisser catch failure of ADL_Overdrive5_FanSpeed_Get and continue gracefully
authored
165 print " fan speed %d%% (%d RPM) (%s)" % (fan_speed[ADL_DL_FANCTRL_SPEED_TYPE_PERCENT],
166 fan_speed[ADL_DL_FANCTRL_SPEED_TYPE_RPM],
167 "user-defined" if user_defined else "default")
168 except ADLError:
169 print " unable to get fan speed"
8f9bc1d @mjmvisser now assumes DISPLAY is :0 if not set in environment
authored
170
171 temperature = ADLTemperature()
172 temperature.iSize = sizeof(temperature)
173
174 if ADL_Overdrive5_Temperature_Get(info.iAdapterIndex, 0, byref(temperature)) != ADL_OK:
175 raise ADLError("ADL_Overdrive5_Temperature_Get failed.")
176
177 print " temperature %g C" % (temperature.iTemperature/1000.0)
178
179
fe83028 @mjmvisser sample use of adl3 library to tweak performance levels
authored
180 def set_plevels(adapter_list=None,
181 plevel_list=None,
182 engine_clock=None,
183 memory_clock=None,
184 core_voltage=None):
185 adapter_info = get_adapter_info()
186
187 for adapter_index, info in enumerate(adapter_info):
188 if adapter_list is None or adapter_index in adapter_list:
189 od_parameters = ADLODParameters()
190 od_parameters.iSize = sizeof(od_parameters)
191
192 if ADL_Overdrive5_ODParameters_Get(info.iAdapterIndex, byref(od_parameters)) != ADL_OK:
193 raise ADLError("ADL_Overdrive5_ODParameters_Get failed.")
194
195 if od_parameters.iDiscretePerformanceLevels:
196 plevels = ADLODPerformanceLevels()
197 plevels_size = sizeof(ADLODPerformanceLevels) + sizeof(ADLODPerformanceLevel) * (od_parameters.iNumberOfPerformanceLevels -1)
198 resize(plevels, plevels_size)
199 plevels.iSize = plevels_size
200
201 if ADL_Overdrive5_ODPerformanceLevels_Get(info.iAdapterIndex, 0, byref(plevels)) != ADL_OK:
202 raise ADLError("ADL_Overdrive5_ODPerformanceLevels_Get failed.")
203
204 levels = cast(plevels.aLevels, POINTER(ADLODPerformanceLevel))
205
206 for plevel_index in range(0, od_parameters.iNumberOfPerformanceLevels):
207 if plevel_list is None or plevel_index in plevel_list:
208 message = []
209
210 if engine_clock is not None:
211 levels[plevel_index].iEngineClock = int(engine_clock*100.0)
212 message.append("engine clock %gMHz" % engine_clock)
213 if memory_clock is not None:
214 levels[plevel_index].iMemoryClock = int(memory_clock*100.0)
215 message.append("memory clock %gMHz" % memory_clock)
216 if core_voltage is not None:
217 levels[plevel_index].iVddc = int(core_voltage*1000.0)
218 message.append("core voltage %gVDC" % core_voltage)
219
220 print "Setting performance level %d on adapter %d: %s" % (plevel_index,
221 adapter_index,
222 ", ".join(message))
223
224 # set the performance levels for this adapter
225 if ADL_Overdrive5_ODPerformanceLevels_Set(info.iAdapterIndex, byref(plevels)) != ADL_OK:
226 raise ADLError("ADL_Overdrive5_ODPerformanceLevels_Set failed.")
227
228 else:
229 print "Adapter %d does not support discrete performance levels." % adapter_index
976ed7a @mjmvisser added --set-fan-speed option
authored
230
231 def set_fan_speed(adapter_list=None,
8f9bc1d @mjmvisser now assumes DISPLAY is :0 if not set in environment
authored
232 fan_speed=None):
976ed7a @mjmvisser added --set-fan-speed option
authored
233 adapter_info = get_adapter_info()
234
235 for adapter_index, info in enumerate(adapter_info):
236 if adapter_list is None or adapter_index in adapter_list:
8f9bc1d @mjmvisser now assumes DISPLAY is :0 if not set in environment
authored
237 if fan_speed == "default":
238 print "Setting fan speed to default on adapter %d" % (adapter_index)
239 if ADL_Overdrive5_FanSpeedToDefault_Set(info.iAdapterIndex, 0) != ADL_OK:
240 raise ADLError("ADL_Overdrive5_FanSpeedToDefault_Set failed.")
241 else:
242 fan_speed_value = ADLFanSpeedValue()
243 fan_speed_value.iSize = sizeof(fan_speed_value)
244 fan_speed_value.iSpeedType = ADL_DL_FANCTRL_SPEED_TYPE_PERCENT
245 fan_speed_value.iFanSpeed = fan_speed
246 fan_speed_value.iFlags = ADL_DL_FANCTRL_FLAG_USER_DEFINED_SPEED
247
248 print "Setting fan speed to %d%% on adapter %d" % (fan_speed, adapter_index)
249 if ADL_Overdrive5_FanSpeed_Set(info.iAdapterIndex, 0, byref(fan_speed_value)) != ADL_OK:
250 raise ADLError("ADL_Overdrive5_FanSpeed_Set failed.")
fe83028 @mjmvisser sample use of adl3 library to tweak performance levels
authored
251
545e286 @mjmvisser catch failure of ADL_Overdrive5_FanSpeed_Get and continue gracefully
authored
252 #def i2c_get_core_voltage(adapter_list=None):
253 # adapter_info = get_adapter_info()
254 #
255 # for adapter_index, info in enumerate(adapter_info):
256 # if adapter_list is None or adapter_index in adapter_list:
257 # i2c_data = ADLI2C()
258 # i2c_data.iSize = sizeof(i2c_data)
259 # i2c_data.iLine = ADL_DL_I2C_LINE_OD_CONTROL
260 # i2c_data.iAddress = 0x70 << 1
261 # i2c_data.iOffset = 0x15 + 2
262 # i2c_data.iAction = ADL_DL_I2C_ACTIONREAD
263 # i2c_data.iSpeed = 10
264 # i2c_data.iDataSize = 1
265 # i2c_data.pcData = c_char_p("\0")
266 #
267 # if ADL_Display_WriteAndReadI2C(info.iAdapterIndex, byref(i2c_data)) != ADL_OK:
268 # raise ADLError("ADL_DisplayWriteAndReadI2C failed.")
269 #
270 # print "Voltage: %g" % (0.450 + 0.0125 * (i2c_data.pcData[0] & 0x7f))
271 #
272
fe83028 @mjmvisser sample use of adl3 library to tweak performance levels
authored
273 if __name__ == "__main__":
274 usage = "usage: %prog [options]"
275
276 parser = OptionParser(usage=usage)
277
278 parser.add_option("-l", "--list-adapters", dest="action", action="store_const", const="list_adapters",
279 help="Lists all detected and supported display adapters.")
8f9bc1d @mjmvisser now assumes DISPLAY is :0 if not set in environment
authored
280 parser.add_option("-s", "--status", dest="action", action="store_const", const="status",
281 help="Shows current clock speeds, core voltage, utilization and performance level.")
fe83028 @mjmvisser sample use of adl3 library to tweak performance levels
authored
282
283 parser.add_option("-e", "--set-engine-clock", dest="engine_clock", type="float", action="store", default=None,
284 help="Sets engine clock speed (in MHz) for the selected performance levels on the "
285 "selected adapters.")
286 parser.add_option("-m", "--set-memory-clock", dest="memory_clock", type="float", action="store", default=None,
287 help="Sets memory clock speed (in MHz) for the selected peformance levels on the "
288 "selected adapters.")
289 parser.add_option("-v", "--set-core-voltage", dest="core_voltage", type="float", action="store", default=None,
290 help="Sets core voltage level (in VDC) for the selected performance levels on the "
291 "selected adapters.""")
976ed7a @mjmvisser added --set-fan-speed option
authored
292 parser.add_option("-f", "--set-fan-speed", dest="fan_speed", type="int", action="store", default=None,
293 help="""Sets the fan speed (in percent) for the selected adapters.""")
8f9bc1d @mjmvisser now assumes DISPLAY is :0 if not set in environment
authored
294 parser.add_option("-d", "--set-fan-speed-default", dest="fan_speed", action="store_const", const="default",
295 help="""Resets the fan speed to its default setting.""")
fe83028 @mjmvisser sample use of adl3 library to tweak performance levels
authored
296
297 parser.add_option("-A", "--adapter", dest="adapter_list", default="all", metavar="ADAPTERLIST",
298 help="Selects which adapters returned by --list-adapters should "
299 "be affected by other atitweak options. ADAPTERLIST contains "
300 "either a comma-seperated sequence of the index numbers of the "
301 "adapters to be affected or else contains the keyword \"all\" to "
302 "select all the adapters. If --adapter is missing, all adapters "
303 "will be affected.")
304
305 parser.add_option("-P", "--performance-level", dest="plevel", default="all",
306 metavar="PERFORMANCELEVELLIST",
307 help="Selects which performance levels returned by --list-adapters should be "
308 "affected by other atitweak options. PERFORMANCELEVELLIST contains either "
309 "a comma-separated sequence of the index numbers of the performance levels "
310 "to be affected or else contains the keyword \"all\" to select all "
311 "performance levels. If --performance-level is missing, all performance "
312 "levels will be affected.")
313
314 (options, args) = parser.parse_args()
315
316 if options.adapter_list == "all":
317 adapter_list = None
318 else:
319 adapter_list = [int(adapter) for adapter in options.adapter_list.split(",")]
320
321 if options.plevel == "all":
322 plevel_list = None
323 else:
324 plevel_list = [int(plevel) for plevel in options.plevel.split(",")]
325
326 result = 0
327
328 try:
329 initialize()
330
331 if options.action == "list_adapters":
332 list_adapters(adapter_list=adapter_list)
8f9bc1d @mjmvisser now assumes DISPLAY is :0 if not set in environment
authored
333 elif options.action == "status":
334 show_status(adapter_list=adapter_list)
976ed7a @mjmvisser added --set-fan-speed option
authored
335 elif options.action is None:
336 if options.engine_clock or options.memory_clock or options.core_voltage:
337 set_plevels(adapter_list=adapter_list,
338 plevel_list=plevel_list,
339 engine_clock=options.engine_clock,
340 memory_clock=options.memory_clock,
341 core_voltage=options.core_voltage)
342 if options.fan_speed:
343 set_fan_speed(adapter_list=adapter_list,
8f9bc1d @mjmvisser now assumes DISPLAY is :0 if not set in environment
authored
344 fan_speed=options.fan_speed)
fe83028 @mjmvisser sample use of adl3 library to tweak performance levels
authored
345 else:
346 parser.print_help()
347
348 except ADLError, err:
349 result = 1
350 print err
351
352 finally:
353 shutdown()
354
02dcc66 @mjmvisser renamed atitweak.py to atitweak, added #!
authored
355 sys.exit(result)
Something went wrong with that request. Please try again.