I recently decided to spend some time to figure out some of the low-level details of how the BIOS works on my R9 380 cards. A few months ago I had found Tonga Bios Editor, but hadn't done anything more than modify the memory frequency table so the card would default to 1500Mhz instead of 1375. My goal was to modify the memory timing and to reduce power usage.
The card I decided to test the memory timing mods on was a Club3D 4GB R9 380 with Elpida W4032BABG-60-F RAM. Although the RAM is rated for 6Gbps/1.5Ghz, the default memory clock is 1475Mhz. In my previous testing I found that the card was stable with the memory overclocked well above 1.5Ghz, but the mining performance was actually slower at 1.6Ghz compared to 1.5Ghz. Unfortunately Tonga Bios Reader does not provide a way to edit the memory timings aka straps, so I'd have to use a hex editor.
I've highlighted the 1500Mhz memory timing in the screen shot above. I found it by searching for the string F0 49 02, which you first have to convert from little-endian to get 249F0, and then from hex to get 150,000, which is expressed in increments of .01Mhz. The timing for up to 1625Mhz (C4 7A 02) comes after it, and then 1750Mhz (98 AB 02). The Club3D BIOS actually has 2 sets of timings, one for memory type 01 (the number after F0 49 02), as and for memory type 02 (not shown). This is so the same BIOS can be used on a card that can be made with different memory. Obviously one type of memory the BIOS supports is Elpida, and from comparing BIOS images from other cards, I determined that memory type 02 is for Hynix.
To reduce the chance of bricking my card, the first time I modified only the 1625Mhz memory timing. Since the default memory timing is 1475Mhz, my modified timing would only be used when overclocking the memory over 1500Mhz. So if the the card crashed on the 1625Mhz timing, it would be back to the safe 1500Mhz timing after a reboot. To actually make the change I copied the 1500Mhz timing (starting with 77 71) to the 1625Mhz timing. After the change, the BIOS checksum is invalid, so I simply loaded the BIOS in Tonga Bios Reader and re-saved it in order to update the checksum.
I used Atiflash 2.71 to flash the BIOS since I have found no DOS or Linux flash utilities for Tonga GPUs. After flashing the updated BIOS, I overclocked the RAM to 1625Mhz, and my eth mining speed went from just under 21Mh to about 22.5Mh. To get even faster timings, I copied the 1375Mhz timings from a MSI R9 380 with Elpida RAM to the Club3d 1625Mhz memory timing. That boosted my mining speed at 1625Mhz to slightly over 23Mh
I then tried a number of ways to improve the timing beyond 1625Mhz, but I found nothing that was both stable and faster at 1700Mhz. Different cards may overclock better, depending on both the GPU asic and the memory. Hynix memory seems to overclock a bit better than Elpida, while Samsung memory, which seems rather rare on R9 380 cards, tends to overclock the best. The memory controller on the GPU also needs to be able overclock from 1475Mhz. Unlike the simple voltage modding the Hawaii BIOS, there is no easy way to modify the memory controller voltage (VDDCI) on Tonga. The ability to over-volt the memory controller would make it easier to overclock the memory speed beyond 1625Mhz.
Since the Club3D BIOS supports both Elpida and Hynix memory, I improved the timing for both memory types. This allows me to use a single BIOS image for cards that have either Elpida or Hynix memory. It's also dependent on the card having a NCP81022 voltage controller, but all my R9 380 cards have the same voltage controller. I've shared it on my google drive as 380NR.ROM if you want to try it (at the possible risk of bricking your card). Atiflash checks the subsystem ID of the target card against the BIOS to be flashed, so it is necessary to use the command-line version of atiflash with the "-fs" option:
atiflash -p 0 380RN.ROM -fs
In addition to improving memory speeds, I wanted to reduce power usage of my 380 cards. On Windows it is possible to use a tool like MSI Afterburner to reduce the core voltage (VDDC), but on Linux there is no similar tool. To reduce the voltage in the BIOS, modify value0 in Voltage Table2 for the different DPM states. After a lot of experimenting, I made two different BIOSes with different voltage levels since some cards under-volt better than others. The first one has 975, 1050, and 1100 mV for dpm 5, 6, & 7, while the other has 1025, 1100, & 1150 mV. These are also shared on my google drive as 380NR1100.ROM and 380NR1150.ROM.
With the faster RAM timing and voltage modifications I've improved my eth mining hashrates by about 10%, without any material change in power use. I've tried my custom ROM on four different cards. Although two of them seem to be OK with 900/1650Mhz clocks, I'm playing it safe and running all four at 885/1625Mhz. If you are lucky and have a card that is stable at 925/1700Mhz, you can mine eth at almost 25Mh/s. With most cards you can expect to get between 23 and 24Mh/s.
2021-09 Update
I no longer recommend BIOS modifications, as runtime modification of GPU settings is much safer. For the past few years I have been using tools like UMR and ROCm-SMI. For people who still wish to access my BIOS mod files for educational reasons, Google has changed shared drive links, so this is the new link.