Looks exciting!! Especially for us who use full HD! Hope we'll be able to test something soon. :)
Clement On Apr 6, 2014, at 12:43 PM, Siarhei Siamashka <siarhei.siamas...@gmail.com> wrote: > 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. -- 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.