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.

Reply via email to