Overclock.net banner

VRMtool - a simple tool to read and write to I2C VRM controllers

57347 Views 80 Replies 25 Participants Last post by  Lucy183
2
VRMtool 0.04 (2016-07-17)
To simplify poking around in I2C registers I wrote a simple tool to dump and modify the I2C registers of VRM controllers connected to AMD/ATI cards. This now evolved into a handy tool to control many aspects of supported VRM chips.

Currently I only have the RX 480 reference card to test and as such only for the IR3567B the tool is able to interpret and change some of the PMBus commands and I2C registers. Additional information about registers of this and other voltage controller chips are very welcome.

Special thanks go to elmor for helping with the IR3567B PMBus commands.

The tool makes intense use of the I2C bus while it is running so you will likely notice microstutters in 3d games/benchmarks. A future version will allow to start/stop live monitoring to allow benchmark runs without needing to close the tool.

RX 480 + IR3567B specific support
  • live graphs for temperature, output voltage, output current and input power
  • override VID
  • change voltage offset
  • change output current scaling
  • phase load balancing/gain (move more/less load to PCIe 6pin)
  • enable/disable load line
  • change load line slope
  • change VRM PWM frequency

Changelog
v0.04
  • live graphs for temperature, output voltage, output current and input power
  • added controls to override VID, add a voltage offset, change output current scaling, phase load balancing (move more load to PCIe 6pin), load line enable/disable + slope, VRM PWM frequency
v0.03
  • minor bugfixes including not uploading the debug version
DISCLAIMER: I take no responsibility at all. I can not be held responsible. Everything you do is on your own risk.



VRMtool004.zip 72k .zip file

Attachments

See less See more
  • Rep+
Reactions: 5
1 - 20 of 81 Posts
Just uploaded a newer version (0.02) which is more informative about the analysed registers of the IR3567B and how to modify them. It now also includes reading of the output current scaling register that derBauer changed with the eVc to cheat the GPU into thinking it consumes less power than it does. This means with this tool one can do the same thing without owning and soldering an eVc to the board.
Quote:
Originally Posted by rjc862003 View Post

zip is missing files or wasn't compiled correctly
throwing runtime errors
The zip should only contain a single exe. If you tell me the exact errors and your graphics card(s) I should be able to help you. It might be that you're just missing the MS C++ redistributable package.
Quote:
Originally Posted by ndunnett View Post



I've tried reinstalling all my C++ redistributables, I'm using an EVGA GTX 780 FTW.
Ok, I will see to that. I either bundle the MFC libs or statically link them but that still doesn't solve the problem that you're using an Nvidia card and are trying to use a tool from the ATI/AMD overclocking section - it only works with AMD cards atm.
Quote:
Originally Posted by ndunnett View Post

Woops, sorry! I didn't even realise. I found this thread via google after having trouble applying the volt mod manually.
Sorry to disappoint! Maybe I will add nvidia card compatibility at one point...

For everybody else: I just uploaded v0.03 it's basically just a fix such that it only requires the standard MFC libraries and not the debug ones.
See my post above yours, I uploaded a version
Quote:
Originally Posted by rjc862003 View Post

using debug libs requires that you have VC installed
ms doesn't ship the debug libs to the public
See my reply above your post: a version that doesn't require the debug libs has already been uploaded. Give it a try!
I just uploaded version 0.04 which is basically a complete overhaul. Now has live graphs and tons of controls:

RX 480 + IR3567B specific support
  • live graphs for temperature, output voltage, output current and input power
  • override VID
  • change voltage offset
  • change output current scaling
  • phase load balancing/gain (move more/less load to PCIe 6pin)
  • enable/disable load line
  • change load line slope
  • change VRM PWM frequency
See less See more
  • Rep+
Reactions: 1
Quote:
Originally Posted by EniGma1987 View Post

Assuming custom cards use the same voltage controller which they should), this software should be compatible with custom RX 480's like the Sapphire Nitro as well correct?
Yes it should work - but to be safe first check if all values displayed actually make sense before trying to change them. Also I would love to see an I2C register dump and screenshot before calling the non reference boards 'supported'.
Quote:
Originally Posted by mtrai View Post

YOu need to download and install https://www.microsoft.com/en-us/download/details.aspx?id=48145 to get those 2 .dlls at least on windows 10.
Yes indeed Visual C++ Redistributables 2015. Thanks for providing the link!
Quote:
Originally Posted by Bartouille View Post

+rep

Wish this was open source tho (learning purpose). Does this use its own driver to access the i2c bus or you can do this using the ADL?
Currently it uses ADL to access the I2C lines. Regarding releasing it as open source, I'll probably do that at one point but currently the code is an ugly hack to get everything working.

Quote:
Originally Posted by OneB1t View Post

Someone tested with 290? :)
I don't think so. Please go ahead and report
smile.gif
See less See more
Quote:
Originally Posted by OneB1t View Post

looks like its working
smile.gif
but im to scared to change any value
biggrin.gif
biggrin.gif


will this be opensource after some time?
wink.gif


edit: on windows 10 graphs are little bit broken
Regarding open source: see answer above
smile.gif


Could you post a screenshot? That way I can see if the values are all sane and what's wrong with the graphs.
See less See more
Quote:
Originally Posted by OneB1t View Post

https://s31.postimg.org/6dwt4h5aj/vrmtool.png
values looks fine i crosschecked with hawaii bios reader VRM section

what is interesting is that LLC is enabled even on bioses which does not have it in VRM command table o_O

maybe driver is in control of this value?

output scaling and phase gain is prolly not used on 290X
Awesome, the values look all good. Only issue is that it seems to detect two IR3567B devices but only one I2C one - which probably means one of the PMBus devices correspond to the unidentified I2C device. Which version of the 290X do you have?

The LLC setting is probably set as a default setting stored in the VRM chip.

Regarding the graphs, I probably just have to draw it correctly for different UI scaling values. I use a 4k monitor @ 125%.
Quote:
Originally Posted by BromoL View Post

@deeper-blue I am trying to use ADL2_Display_WriteAndReadI2C but the desciption of the ADLI2C structure members are lacking. What are the correct values?

I2C clock speed in KHz is 100 (Normal), 400 (Fast) or 1000 (Max speed). So is 400 ok?
This is my wrapper code for using this function it shoudl get you started. I use 100 but I think 400 should also be no problem.

Code:

Code:
int I2C_WriteAndRead(int iAdapterIndex, int iLine, int iAddress, int iOffset, int iAction, int iDataSize, char *pI2Cdata)
{
        ADLI2C *pI2C;
        ADLI2C I2Cstore;
        pI2C = &I2Cstore;

        pI2C->iSize = sizeof(ADLI2C);
        pI2C->iSpeed = 100;
        pI2C->iAction = iAction;

        pI2C->iLine = iLine;
        pI2C->iAddress = iAddress << 1;

        pI2C->iOffset = iOffset;

        pI2C->iDataSize = iDataSize;
        pI2C->pcData = pI2Cdata;

        return ADL_Display_WriteAndReadI2C(iAdapterIndex, pI2C);
}
See less See more
  • Rep+
Reactions: 1
Quote:
Originally Posted by BromoL View Post

Ok, thanks. On problem i still have is, that i can only read single bytes. Setting iDataSize greater one only repeats the first byte multiple times.

So far i am using the ADL2-variants of functions with context argument. But i have some performance issues. Reading 6 values per second (directly one after the other) already produces stuttering in 3d applications. Is the locking mechanism only relevant for multithreading and performance better without it? Or does using the wrong frequency add some expensive frequency switching? I will make some more tests.
If you haven't already figured it out yourself, here is how I can read a word instead of just one byte - which you will need to read from the PMBus address of the I2C device. And yes as you guessed that's what I'm reading out to generate the graphs.

Also I don't think the context versions of the functions make any difference, they are more meant for preventing issues if you access ADL from multiple threads in your app.

Regarding the problem of stalling the GPU during access - it seems like we can't prevent that. Running VRM tool and having it read out all the register values does interrupt the GPU quite heavily. Not sure if there's a better way do to it.

I'm in the middle of rewriting the whole thing to allow me more flexibility for things that I want to support - when/if that works it will be put up on github.

Code:

Code:
     char *pI2Cdata;
        UINT16 I2Cdata;
        pI2Cdata = (char *)&I2Cdata;

        int iResult = I2C_WriteAndRead(iAdapterIndex, iLine, iAddress, iRegister, ADL_DL_I2C_ACTIONREAD_REPEATEDSTART, 2, pI2Cdata);
        if (iResult != ADL_OK) {
                m_TextOut.Format(_T("%s\r\nFailed to read from I2C register. Error code: %d\r\n"), m_TextOut.GetString(), iResult);
        }
See less See more
  • Rep+
Reactions: 1
Quote:
Originally Posted by mynm View Post

Could you incude support for r9 380 and 285 NCP81022?. This datasheet will help: http://media.digikey.com/pdf/Data%20Sheets/ON%20Semiconductor%20PDFs/NCP81022.pdf

I2c dump is:
Code:

Code:
------[ ATI I2C Device GPU #1 / B06-D24 ]------

  0000  FF 80 17 7F FF FF FF FF FF FF FF FF FF FF FF FF  ...............
  0010  00 FF FF FF FF FF FF FF FF B0 FF FF FF FF FF FF  ................
  0020  22 00 FF FF 00 18 A8 FF FF FF FF FF FF FF FF FF  "...............
  0030  FF FF FF FF FF FF FF FF 01 00 FF FF FF FF FF FF  ................
  0040  FF FF FF FF FF FF FF FF FF FF 64 FF FF FF FF 55  ..........d....U
  0050  FF 46 00 64 FF 10 FF FF FF FF FF FF FF FF FF FF  .F.d............
  0060  FF FF FF FF FF FF FF FF 2C FF FF FF FF FF FF FF  ........,.......
  0070  FF FF FF FF FF FF FF FF 00 00 00 00 00 00 FF FF  ................
  0080  FF FF FF FF FF FF FF FF E9 FF FF 3F F0 00 FF FF  ...........?....
  0090  FF FF FF FF FF FF 64 FF FF 1A 22 03 FF FF FF FF  ......d...".....
  00A0  FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF  ................
  00B0  FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF  ................
  00C0  FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF  ................
  00D0  00 01 00 03 50 02 00 FF FF FF 01 FF FF FF FF FF  ....P...........
  00E0  FF 00 00 02 03 03 00 3D FF FF FF FF FF FF FF FF  .......=........
  00F0  FF FF FF 68 FF FF FF 0A BC 9C FF 07 FF 0F FF FF  ...h............

------[ ATI I2C Device GPU #1 / B06-D24 ]------

  0000  FFFF 2F80 7E17 FF7F FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF 
  0010  6F00 FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF 4CB0 FFFF FFFF FFFF FFFF FFFF FFFF 
  0020  6022 0000 FFFF FFFF 0000 0018 00A8 FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF 
  0030  FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF 0001 0000 FFFF FFFF FFFF FFFF FFFF FFFF 
  0040  FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF 0064 FFFF FFFF FFFF FFFF 0055 
  0050  FFFF 0046 0000 0064 FFFF 0010 FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF 
  0060  FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF 012C FFFF FFFF FFFF FFFF FFFF FFFF FFFF 
  0070  FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF FB00 0000 2D00 4600 5000 3B00 FFFF FFFF 
  0080  FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF D2E9 FFFF FFFF 013F A2F0 0000 FFFF FFFF 
  0090  FFFF FFFF FFFF FFFF FFFF FFFF A364 FFFF FFFF 001A 1022 8103 FFFF FFFF FFFF FFFF 
  00A0  FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF 
  00B0  FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF 
  00C0  FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF 
  00D0  E200 8E01 3400 5603 BA50 2C02 9F00 FFFF FFFF FFFF 6201 FFFF FFFF FFFF FFFF FFFF 
  00E0  FFFF 6800 D500 B002 A103 CA03 7E00 003D FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF 
  00F0  FFFF FFFF FFFF 0368 FFFF FFFF FFFF 810A F5BC F29C FFFF 5807 FFFF 1D0F FFFF FFFF

Thanks
thumb.gif
Thank you for the dump!
And yes I plan to add support for that VRM controller. I'm rewriting the tool right now to make it easier for me to extend it with additional chips and functionality.
Quote:
Originally Posted by BromoL View Post

I think I am using only ADL_DL_I2C_ACTIONREAD to read 2 bytes (as a word) from the PMBus. It is working there, but not for multiple consecutive I2C registers (where i only get the first byte repeated several times). The PMBus does not work like registers, because consecutive command codes return different data sizes.

Regarding the locking and multithreading i am confused. There are 4 variants of ADL_Main_Control_Create. The difference ADL2 variants create a context handle with unknown purpose. The SDK explicitly states: "ADL initialized using ADL2_Main_Control_Create will not enforce serialization of ADL API executions by multiple threads." Only the X2 variants have an argument that sets the threading model. But it is still unclear how/whether serialization is done for multiple processes. I had two system crashes while running GPU-Z and my application simultaneously. But it never crashed with only my application running.
I too noticed that just ACTIONREAD does seem to work - but from reading the PMBus spec I think the REPEATED_START would be the correct approach.
Now I'm not sure what exactly you're trying to do but each register is only one byte and you cannot read out all registers in one command, you do have to read one single byte from each register to get the whole register map - which of course is super slow hence you only want to do this for sparsingly.

The crashes are easily explained and the context functions of ADL don't work across processes. So what happens is that two apps access the I2C bus and their commands can corrupt each other which can quickly result in a crash (a simple way to see that it's easy to crash the system via I2C is this: just try to read one single byte from all the PMBus device offsets, aka just make a register map like you would for the I2C register interface of the VRM -> Reboot every single time).
I've read that afterburner does work with a mutex that is supposed to safeguard I2C access across different tools that access the bus - but haven't really looked into it yet.
Also the Fury cards crash very fast after starting VRM tool. I suspect the I2C commands from the GPU interfere with the I2C commands from the tool, newer/older GPUs likely have a safeguard against that.
See less See more
Quote:
Originally Posted by TsagasLr View Post

Doesn't do jack on the XFX RX 480 8GB GTR-S Black Edition
mad.gif

Can't read anything

It works though on the ASUS RX 570 4GB Strix Edition

My favorite app for undervolting. 0.816Vcore @1180Mhz (for mining). Awesome!
That's awesome since the TRIXX was making the 570 chip go haywire
biggrin.gif
Sounds like the GTR-S has a different voltage controller that I don't support (yet) with VRMtool.
Quote:
Originally Posted by bardacuda View Post

Is there a way to determine which controller a given card has in Windows? Maybe with an AIDA64 dump? I'd like to figure out which cards have IR3567B vs. NCP81022 vs. uP9505 so I can proceed with trying to tweak VDDCI and LLC, etc.

If not, what's the process for doing this in Linux? I'm a Linux n00b but I could muddle through. Is there a built-in tool to safely probe the controllers over I2C or would I have to grab it from some repository or compile it?
You can try dumping the i2c bus using aida64 or afterburner. In the dump you can then see if you find the identifying registers of the different VRM controllers.
Quote:
Originally Posted by bardacuda View Post

I see a bunch of 4-byte hex strings but I have no clue what I am looking at. Can you elaborate on how to find the identifying registers? This is a dump of one particular MSI card.
Ok, you dumped the ATI/AMD registers but you need to dump the I2C/PMBus
smile.gif
See less See more
Quote:
Originally Posted by bardacuda View Post

Would that be "ATI SMBus Dump"?

I'm not seeing anything referring to I2C or PMBus in AIDA.
Yes, that should be the correct one.
1 - 20 of 81 Posts
Top