On Sat, 05 Apr 2014 17:58:11 +0200 Jens Kuske <jensku...@gmail.com> wrote:
> On 03/04/14 07:49, Siarhei Siamashka wrote: > > > > I would guess that the .tpr settings, bundled with .cas=6, are likely > > assuming 400MHz memory clock speed. Which also agrees with the tRFC > > hardcoded values as you mentioned above. And also with the A10 > > and A20 user manuals, which specify 0~400MHz range for SDRAM_clk. > > > > The .cas=9 style sets of timings are likely very conservative and > > assuming memory clock speeds up to 667MHz if we take the cas value > > as a hint. If we are running dram at around 480MHz, these settings > > may unnecessarily sacrifice some performance. > > I found some documentation for TPR registers in the rk30xx manual from > radxa. Their dram controller is pretty much different, but comparing the > default values and settable bits of the TPR registers makes it likely > that at least these registers have nearly the same bitfields. > > This makes the .cas=6 set look like: > tMRD = 2, tRTP = 4, tWTR = 4, tRP = 6, tRCD = 6, > tRAS = 18, tRRD = 4, tRC = 24, tCCD = 0 > tAOND_tAOFD = 0, tRTW = 0, tFAW = 18, tMOD = 0, tRTODT = 0 > tXS = 200, tXP = 8, tCKE = 3 > > Assuming this is valid, we can do some trail and error again and try to > figure out the original timings. > > As it turns out, your guess was pretty good. The settings *exactly* > match DDR2(!)-800E speed bin at 400MHz. Its DDR2 again, as with tRFC. > Interesting part is, if we assume DDR3-1333H chips (as on cubieboard) > many parameters are still in spec up to 480MHz (not all however, tFAW, > tXS and what else I missed not). > > And for the .cas=9 set, most settings match DDR3-1333H speed bin at > 667MHz. But some settings, like tFAW and tXP are too low, > they only fit for ~420MHz. > > tMRD = 3, tRTP = 5, tWTR = 5, tRP = 9, tRCD = 9, > tRAS = 24, tRRD = 6, tRC = 33, tCCD = 0 > tAOND_tAOFD = 0, tRTW = 0, tFAW = 18, tMOD = 0, tRTODT = 0 > tXS = 512, tXP = 10, tCKE = 4 That's a very nice catch. Thanks! Looks like this is a stepping stone in the memory controller reverse engineering. However things would have been surely much easier if all of this was properly documented by Allwinner. > I tried to calculate the correct parameters for 480MHz on cubietruck, > and currently lima-memtester is running without any errors till now. I > first accidentally kept the clock at 432MHz and only changed the tprs, > and even that gave a ~150MB/s boost at tinymembench compared to the > original values. > This is highly experimental, but if somebody wants to try (only > cubietruck, other dram chips need different timings): > .clock = 480 > .cas = 7 > .tpr0 = 0x30b27790 > .tpr1 = 0x0000a078 > .tpr2 = 0x0001b200 > > These timings are calculated by hand, but maybe this could lead to some > program or even function in u-boot that calculates matching parameters > for given dram chip type and speed. Well, not a big surprise, but my "lucky" Cubietruck fails lima-memtester tests with these settings too: Kernel driver is version 14 Detected 1 Mali-400 GP Cores. Detected 2 Mali-400 PP Cores. FB: 1280x720@32bpp at 0x51001000 (0x00A8C000) Using dual buffered direct rendering to FB. memtester version 4.3.0 (32-bit) Copyright (C) 2001-2012 Charles Cazabon. Licensed under the GNU General Public License version 2 (only). pagesize is 4096 pagesizemask is 0xfffff000 want 300MB (314572800 bytes) got 300MB (314572800 bytes), trying mlock ...locked. Loop 1: Stuck Address : ok Random Value : ok Compare XOR : ok Compare SUB : ok Compare MUL : ok Compare DIV : ok Compare OR : ok Compare AND : ok Sequential Increment: ok Solid Bits : ok Block Sequential : ok Checkerboard : ok Bit Spread : ok Bit Flip : testing 221FAILURE: 0xf7ffffff != 0xf7ffff00 at offset 0x03e041fc. FAILURE: 0x08000000 != 0x0800000c at offset 0x03e04200. FAILURE: 0xf7ffffff != 0xf7ffff06 at offset 0x03e04204. Walking Ones : ok Walking Zeroes : ok Loop 2: Stuck Address : ok Random Value : ok Compare XOR : ok Compare SUB : ok Compare MUL : ok Compare DIV : ok Compare OR : ok Compare AND : ok Sequential Increment: ok Solid Bits : ok Block Sequential : ok Checkerboard : ok Bit Spread : ok Bit Flip : testing 213FAILURE: 0xfbffffff != 0xfbffff00 at offset 0x038051bc. FAILURE: 0x04000000 != 0x040000ff at offset 0x038051c0. FAILURE: 0xfbffffff != 0xfbffff00 at offset 0x038051c4. FAILURE: 0x04000000 != 0x040000ff at offset 0x038051c8. FAILURE: 0xfbffffff != 0xfbffff00 at offset 0x038051cc. FAILURE: 0x04000000 != 0x040000ff at offset 0x038051d0. FAILURE: 0xfbffffff != 0xfbffff00 at offset 0x038051d4. FAILURE: 0x04000000 != 0x040000ff at offset 0x038051d8. FAILURE: 0xfbffffff != 0xfbffff00 at offset 0x038051dc. FAILURE: 0x04000000 != 0x040000ff at offset 0x038051e0. FAILURE: 0xfbffffff != 0xfbffff00 at offset 0x038051e4. FAILURE: 0x04000000 != 0x040000ff at offset 0x038051e8. FAILURE: 0xfbffffff != 0xfbffff00 at offset 0x038051ec. FAILURE: 0x04000000 != 0x040000ff at offset 0x038051f0. FAILURE: 0xfbffffff != 0xfbffff00 at offset 0x038051f4. FAILURE: 0x04000000 != 0x040000ff at offset 0x038051f8. Walking Ones : ok Walking Zeroes : ok > Last warning, all numbers were juggled around many times and I did never > check them again, so they could easily be wrong. But the overall idea > should be correct. Thanks for spotting all of this. The rk30xx manual is indeed a good reference. BTW, I'm playing with the following ruby script right now: #!/usr/bin/env ruby # Bitfields for DDR_PHYCTL_DTPR0, DDR_PHYCTL_DTPR1, DDR_PHYCTL_DTPR2 from # RK30xx manual represented as [highest bit, lowest bit, add constant, name] $tpr_bitfields = [ [ # .tpr0 [31, 31, 0, "tCCD"], [30, 25, 0, "tRC"], [24, 21, 0, "tRRD"], [20, 16, 0, "tRAS"], [15, 12, 0, "tRCD"], [11, 8, 0, "tRP"], [ 7, 5, 0, "tWTR"], [ 4, 2, 0, "tRTP"], [ 1, 0, 4, "tMRD"], ], [ # .tpr1 [23, 16, 0, "tRFC"], [15, 12, 0, "reserved"], [11, 11, 0, "tRTODT"], [10, 9, 12, "tMOD"], [ 8, 3, 0, "tFAW"], [ 2, 2, 0, "tTRW"], ], [ # .tpr2 [28, 19, 0, "tDLLK"], [18, 15, 0, "tCKE"], [14, 10, 0, "tXP"], [ 9, 0, 0, "tXS"], ] ] # Convert an array with 3 magic constants to a key->value hash def convert_from_tpr(tpr) result = {} tpr.each_index {|i| $tpr_bitfields[i].each {|v| maxbit = v[0] minbit = v[1] x = (tpr[i] >> minbit) & ((1 << (maxbit - minbit + 1)) - 1) result[v[3]] = x + v[2] } } return result end # Convert from a key->value hash back to an array with 3 magic constants def convert_to_tpr(a) result = [0, 0, 0] tmp_hash = {} $tpr_bitfields.each_index {|i| $tpr_bitfields[i].each {|v| tmp_hash[v[3]] = [i, v[1], v[2]] } } a.each {|k, v| result[tmp_hash[k][0]] |= (v - tmp_hash[k][2]) << tmp_hash[k][1] } return result end # Format 3 magic tpr constants as dram_para stuct in u-boot sources def print_tpr(comment, dram_clock, tpr) # A sanity check: ensure that the roundtrip conversion to the # key->value hash and back to three 32-bit magic constants does # not introduce any errors new_tpr = convert_to_tpr(convert_from_tpr(tpr)) raise "Roundtrip conversion failed" unless new_tpr[0] == tpr[0] && new_tpr[1] == tpr[1] && new_tpr[2] == tpr[2] printf("\n%s\n", comment) tmp = convert_from_tpr(tpr) used_keys = {} printf("\t/*\n") # Show the most interesting values in a special sorting order ["tRCD", "tRC", "tRAS", "tRP", "tFAW", "tRRD", "tRFC"].each {|k| used_keys[k] = 1 printf("\t * %8s = %8.2f ns (%d)\n", k, tmp[k].to_f * 1000 / dram_clock, tmp[k]) } # Show the rest of the values in any order tmp.each {|k, v| next if used_keys[k] printf("\t * %8s = %8.2f ns (%d)\n", k, tmp[k].to_f * 1000 / dram_clock, tmp[k]) } printf("\t */\n") printf("\t.clock = %d\n", dram_clock) printf("\t.tpr0 = 0x%x,\n\t.tpr1 = 0x%x,\n\t.tpr2 = 0x%x,\n", tpr[0], tpr[1], tpr[2]) end # Define interesting sets of tpr magic values tpr_cas6 = [0x30926692, 0x1090, 0x1a0c8] tpr_cas9 = [0x42d899b7, 0xa090, 0x22a00] tpr_jemk_cas7 = [0x30b27790, 0x0000a078, 0x0001b200] # And print more details about them print_tpr("/* the original .cas=6 set at 400MHz */", 400, tpr_cas6) print_tpr("/* the original .cas=9 set at 667MHz */", 667, tpr_cas9) print_tpr("/* the experimental .cas=7 set from jemk */", 480, tpr_jemk_cas7) # Tweak .cas=9 set to modify the tFAW bitfield value tmp = convert_from_tpr(tpr_cas9) tmp["tFAW"] = 35 print_tpr("/* .cas=9 set with tFAW changed to 35 */", 480, convert_to_tpr(tmp)) -- You received this message because you are subscribed to the Google Groups "linux-sunxi" group. To unsubscribe from this group and stop receiving emails from it, send an email to linux-sunxi+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.