Looking for help: U-Boot RAM Timings


Given that there are memory issues on boot, before Tiler should become an issue I don't think this is an issue yet.
I'm not sure if DMM is already in use at uboot time. Thought it was more for Linux to use, but a quick google suggests that it could be set up in uboot.
When I've experienced crashes inside Linux, I've generally been doing nothing. I'll be looking something up or compiling on a different machine and when I return the device is unresponsive.
Hmm... I'm experiencing that even on my devboard
 
I've never had the devboard fail to boot, but yes, I've had my devboard randomly crash.
It got better when I was blowing air over the heatsink but I always worried that my power supply was only just good enough.
Was hoping that the battery in the Pyra would would provide ample power for the changing situations.
 
I've never had the devboard fail to boot, but yes, I've had my devboard randomly crash.
It got better when I was blowing air over the heatsink but I always worried that my power supply was only just good enough.
Was hoping that the battery in the Pyra would would provide ample power for the changing situations.
Yeah, my devboard always boots too. I haven't checked my power supply, but it could be that. I figure that overheat should show at least some warning in the logs before shutdown
 
Yeah, my devboard always boots too. I haven't checked my power supply, but it could be that. I figure that overheat should show at least some warning in the logs before shutdown
The Devboard is supposed to run on either 5V or 12Volts, but I've always had to use a 12V supply to be stable on mine and I've powered it on my Bench power supplies that can provide 10A if it had to.
 
So ages ago I wrote a script to look at the configuration of the memory by the CPU. Finally added some more registers.
Bash:
#!/bin/bash

focusAdd=$1

function readMem {
    add=$1
    name=$2
    val=`devmem2 $add | grep -Po "(?<=: )0x.*"`
    valI=$(( $val * 1))
    valB=`echo "obase=2;$valI" | bc`
    bits=("${@:3}")
    count=${#bits[@]}
    echo $name @ $add = $val
    if [ -n $focusAdd ] && [ "$focusAdd" == "$add" ]; then
        echo $valB is the bit value of the register.
    fi
    for (( i = 0; $i < ${count}; i += 2 ))
    do
        name=${bits[$i]}
        split=(${bits[$i + 1]//:/ })
        size=${split[0]}
        pos=${split[1]}
        mask=$(( ( 1 << $size ) - 1 << $pos ))
        maskS=`echo "obase=2;$mask" | bc`
        bitV=$(( ($val & $mask) >> $pos ))
        if [ -z $focusAdd ]; then
            echo -ne "$name: $bitV\t"
        elif [ "$focusAdd" == "$add" ]; then
            echo `printf %32s $maskS | tr ' ' 0` $name = $bitV
        fi
    done;
    if [ -z $focusAdd ]; then
        echo ""
    fi
}

function readMem2 {
    copy=("${@:1}")
    readMem $@
    copy[0]=`printf 0x%X $((${copy[0]} + 0x01000000))`
    #echo Offset: ${copy[@]}
    readMem ${copy[@]}
}
readMem2 0x4c000000 EMIF_REV revision 32:0
readMem2 0x4c000004 EMIF_STATUS be 1:31 dualClk 1:30 fastInit 1:29 rdlgate 1:6 rdlto 1:5 wrlto 1:4 phyDll 1:2
readMem2 0x4c000008 EMIF_CONFIG type 3:29 pos 2:27 ddr3TermR 3:24 ddr2Ddqs 1:23 ddr3Odt 2:21 ddrDisableDll 1:20 driveStre 2:18 cwl 2:16 narrowMode 2:14 cl 4:10 rowSize 3:7 iBank 3:4 eBank 1:3 pageS 3:0
readMem2 0x4c00000c EMIF_CONFIG2 cs1nvmen 1:30 ebankPos 1:27 rdbnum 2:4 rdbsize 3:0
readMem2 0x4c000010 EMIF_REFRESH initDis 1:31 srt 1:29 asr 1:28 pasr 3:24 refreshRate 16:0
readMem2 0x4c000018 EMIF_TIM1 tRTW 3:29 tRP 4:25 tRCD 4:21 tWR 4:17 tRAS 5:12 tRC 6:6 tRRD 3:3 tWTR 3:0
readMem2 0x4c000020 EMIF_TIM2 tXP 3:28 tODT 3:25 tXSNR 9:16 xXSRD 10:6 tRTP 3:3 tCKE 3:0
readMem2 0x4c000028 EMIF_TIM3 tDDLunl 4:28 tCSTA 4:24 tCKESR 3:21 ZQCS 6:15 tTDQSCKmax 2:13 tRFC 9:4 tRASmax 4:0
readMem2 0x4c000038 EMIF_POW PDTIM 4:12 dpdEn 1:11 lpMode 3:8 srTim 4:4
readMem2 0x4c000040 EMIF_ddr2D val0 7:0
readMem2 0x4c000050 EMIF_ddr2config cs 1:31 refresh 1:30 add 8:0
readMem2 0x4c000054 EMIF_OCP_CONF sysMax 4:24 mpuMax 4:20 llMax 4:16
readMem2 0x4c000058 EMIF_OCP_CONFV1 sysBusW 2:30 llBusW 2:28 wrFifoD 8:8 cmdFifoD 8:0
readMem2 0x4c00005C EMIF_OCP_CONFV2 counter1 32:0
readMem2 0x4c0000C8 EMIF_SDRAM_OUTPUT_IMPEDANCE_CALIB_CONF zqCS1 1:31 z1CS0 1:30 zqDual 1:29 zqSelfRefresh 1:28 zqOnPowerdown 1:27 zqZqintMult 2:18 zqZqclMult 2:16 zqRefInterval 15:0
readMem2 0x4c000080 EMIF_PERFORMANCE_COUNTER_1
readMem2 0x4c000084 EMIF_PERFORMANCE_COUNTER_2
readMem2 0x4c000088 EMIF PERFORMANCE_COUNTER_CONFIG cntr2MconnidEn 1:31 cntr2RegionEn 1:30 cntr2Cfg 4:16 cntr1MconnidEn 1:15 cntr1RegionEn 1:14 cntr1Cfg 4:0
readMem2 0x4c00008C EMIF_PERFORMANCE_COUNTER_MASTER_REGION_SELECT mconnid2 8:24 regionSel2 2:16 mconnid1 8:8 regionSel1 2:0
readMem2 0x4c000090 EMIF_PERFORMANCE_COUNTER_TIME
readMem2 0x4c000094 EMIF_MISC_REG dllCallibOneShot 1:0
readMem2 0x4c000098 EMIF_DLL_CALIB_CTRL ack_wait 4:16 dllCalibInterval 9:0
readMem2 0x4c0000A4 EMIF_SYSTEM_OCP_INTERRUPT_RAW_STATUS dnvSys 1:2 taSys 1:1 errSys 1:0
readMem2 0x4c0000A8 EMIF_LOW_LATENCY_OCP_INTERRUPT_RAW_STATUS dnvLL 1:2 taLL 1:1 errLL 1:0
readMem2 0x4c0000AC EMIF_SYSTEM_OCP_INTERRUPT_STATUS dnvSys 1:2 taSys 1:1 errSys 1:0
readMem2 0x4c0000B0 EMIF_LOW_LATENCY_OCP_INTERRUPT_STATUS dnvLL 1:2 taLL 1:1 errLL 1:0
readMem2 0x4c0000B4 EMIF_SYSTEM_OCP_INTERRUPT_ENABLE_SET enDnvSys 1:2 enTaSys 1:1 enErrSys 1:0
readMem2 0x4c0000B8 EMIF_LOW_LATENCY_OCP_INTERRUPT_ENABLE_SET enDnvLL 1:2 enTaLL 1:1 EnErrLL 1:0
readMem2 0x4c0000BC EMIF_SYSTEM_OCP_INTERRUPT_ENABLE_CLEAR enDnvSys 1:2 enTaSys 1:1 enErrSys 1:0
readMem2 0x4c0000C0 EMIF_LOW_LATENCY_OCP_INTERRUPT_ENABLE_CLEAR enDnvLL 1:2 enTaLL 1:1 enErrLL 1:0
readMem2 0x4c0000C8 EMIF_SDRAM_OUTPUT_IMPEDANCE_CALIBRATION_CONFIG zqCS1En 1:31 zqCS0En 1:30 zqDualCalEn 1:29 zqSfExitEn 1:28 zqPdExitEnd 1:27 zqZqInitMult 2:18 zqZqClMult 2:16 zqRefInterval 16:0
readMem2 0x4c0000CC EMIF_TEMPERATURE_ALERT_CONFIG TaCS1En 1:31 taCS0En 1:30 taSfExitEn 1:28 taDevWdt 2:26 taRefInterval 22:0
readMem2 0x4c0000D0 EMIF_OCP_ERROR_LOG mAddrSpace 2:14 bBurstSeq 3:11 mCMD 3:8 mConnID 8:0
readMem2 0x4c0000E4 EMIF_DDR_PHY_CONTROL1 rdLvlMask 1:27 rdLvlGateMask 1:26 wrLvlMask 1:25 phyHalfDelays 1:21 phyClkStallLevel 1:20 phyDisCalibRst 1:19 phyInvertClkOut 1:18 phyDllLockDiff 8:10 phyFastDllLock 1:9 readLatency 5:0
readMem2 0x4c000120 EMIF_READ_WRITE_EXECUTION_THRESHOLD mFlagOverride 1:31 llBubbleEnable 1:30 wrThrsh 5:8 rdThrsh 5:0
readMem2 0x4c000140 EMIF_PHY_STATUS_1
readMem2 0x4c000200 EMIF_EXT_PHY_CONTROL_1 dllRatio2 10:20 dllRatio1 10:10 dllRatio0 10:0
readMem2 0x4c000208 EMIF_EXT_PHY_CONTROL_2 dqsDelayRatio10 10:22 dqsDelayRatio01 11:11 dqsDelayRatio00 11:0
readMem2 0x4c000210 EMIF_EXT_PHY_CONTROL_3 dqsDelayRatio21 9:23 dqsDelayRatio20 11:12 dqsDelayRatio11 11:1 dqsDelayRatio10 1:0
readMem2 0x4c00021C EMIF_EXT_PHY_CONTROL_4 dqsDelayRatio31 11:13 dqsDelayRatio30 11:2 dqsDelayRatio21 2:0
readMem2 0x4c000280 EMIF_EXT_PHY_CONTROL_17 gateLvlInitMode 1:1 useRank0Delay 1:0
readMem2 0x4c000288 EMIF_EXT_PHY_CONTROL_18 dqsTrainingRatio10 10:22 dqsTrainingRatio01 11:11 dqsTrainingRatio00 11:0
readMem2 0x4c000290 EMIF_EXT_PHY_CONTROL_19 dqsTrainingRatio21 9:23  dqsTrainingRatio20 11:12 dqsTrainingRatio11 11:1 dqsTrainingRatio10 1:0
readMem2 0x4c000298 EMIF_EXT_PHY_CONTROL_20 dqsTrainingRatio31 11:13 dqsTrainingRatio30 11:2  dqsTrainingRatio21 2:0
readMem2 0x4c0002A0 EMIF_EXT_PHY_CONTROL_21 WrLevelingRatio11 2:30  WrLevelingRatio10 10:20 WrLevelingRatio01 10:10 WrLevelingRatio00 10:0
readMem2 0x4c0002A8 EMIF_EXT_PHY_CONTROL_22 WrLevelingRatio30 4:28  WrLevelingRatio21 10:18 WrLevelingRatio20 10:8  WrLevelingRatio11 8:0
readMem2 0x4c0002B0 EMIF_EXT_PHY_CONTROL_23 WrLevelingRatio31 10:6  WrLevelingRatio30 6:0
readMem2 0x4c0002B8 EMIF_EXT_PHY_CONTROL_24 fifoReset 1:10 phyMdllClear 1:9 fifoMisalignedReset 1:8 wrLvlNumOfDq0 4:4 gateLvlNumOfDq0 4:0
But it didn't get me far enough. To the best of my knowledge, I was filling out all of the fields correctly. It was nice that the Pyra would sometimes boot better, but it would always lock up.

There was always a bit of an unknown about the memory. The stupid thing was, @hns had given the exact version of the memory being used in production Pyras.
But I had to ask EvilDragon for a picture of the CPU board to be sure (I was feeling too lazy to pull the unit apart).

The challenging thing is, the RAM is 800mhz being used in a 533mhz slot. The documentation sometimes talks about clock speeds and sometimes about picoseconds. I had pointed this out earlier but I didn't know how relevant it was going to be.
Most of our settings seem like they come from 533mhz section of the documentation. But the devices clearly need so many clock cycles to do certain operations.
I am still going to struggle to understand what settings to take from which section. I started feeling confident when I started, but then I ran into a configuration that needed so many clock cycles, but needed to be completed in so many picoseconds (otherwise it would be considered timed out?)

So, I've got a uboot that boots with this ram. It is becoming clear that the ram settings need to be pulled from the DTB since I believe we have a few units that will have old ram (2gb units?).
I have uploaded it to the Pyra discord for @EvilDragon to test. I think it has a huge performance penalty attached.
But if it finally boots more of the dead boards, I'll have something exciting to work from.
 
Sorry, I tried to look at documentation from the Wiki, but didn't find much.
What do you mean "slot"?
The challenging thing is, the RAM is 800mhz being used in a 533mhz slot.
I thought the RAM chips would be directly soldered to the PCB. Is the RAM socketed ?
Or do you mean the SOC requires 533MHz RAM and the RAM chips are 800MHz ? That would sound doable (maybe tricky?).
But if it finally boots more of the dead boards, I'll have something exciting to work from.
Of course. Thanks and good luck.
 
thought the RAM chips would be directly soldered to the PCB. Is the RAM socketed ?
It's directly soldered onto the CPU board, but I don't think he meant it in the sense of slotting or socketing, but used slot as a term for essentially saying in the same spot or place.
 
I thought the RAM chips would be directly soldered to the PCB. Is the RAM socketed ?
Or do you mean the SOC requires 533MHz RAM and the RAM chips are 800MHz ? That would sound doable (maybe tricky?).
They are soldered. I just think of it slotted in. Maybe I should have said 800mhz devices connected to a 533mhz clock?
Tricky is an under statement when we don't know what we are doing :p

Yeah. I put a little more information in the wiki. It's not a lot but it can fill in some blanks.
 
So ages ago I wrote a script to look at the configuration of the memory by the CPU. Finally added some more registers.
Bash:
#!/bin/bash

focusAdd=$1

function readMem {
    add=$1
    name=$2
    val=`devmem2 $add | grep -Po "(?<=: )0x.*"`
    valI=$(( $val * 1))
    valB=`echo "obase=2;$valI" | bc`
    bits=("${@:3}")
    count=${#bits[@]}
    echo $name @ $add = $val
    if [ -n $focusAdd ] && [ "$focusAdd" == "$add" ]; then
        echo $valB is the bit value of the register.
    fi
    for (( i = 0; $i < ${count}; i += 2 ))
    do
        name=${bits[$i]}
        split=(${bits[$i + 1]//:/ })
        size=${split[0]}
        pos=${split[1]}
        mask=$(( ( 1 << $size ) - 1 << $pos ))
        maskS=`echo "obase=2;$mask" | bc`
        bitV=$(( ($val & $mask) >> $pos ))
        if [ -z $focusAdd ]; then
            echo -ne "$name: $bitV\t"
        elif [ "$focusAdd" == "$add" ]; then
            echo `printf %32s $maskS | tr ' ' 0` $name = $bitV
        fi
    done;
    if [ -z $focusAdd ]; then
        echo ""
    fi
}

function readMem2 {
    copy=("${@:1}")
    readMem $@
    copy[0]=`printf 0x%X $((${copy[0]} + 0x01000000))`
    #echo Offset: ${copy[@]}
    readMem ${copy[@]}
}
readMem2 0x4c000000 EMIF_REV revision 32:0
readMem2 0x4c000004 EMIF_STATUS be 1:31 dualClk 1:30 fastInit 1:29 rdlgate 1:6 rdlto 1:5 wrlto 1:4 phyDll 1:2
readMem2 0x4c000008 EMIF_CONFIG type 3:29 pos 2:27 ddr3TermR 3:24 ddr2Ddqs 1:23 ddr3Odt 2:21 ddrDisableDll 1:20 driveStre 2:18 cwl 2:16 narrowMode 2:14 cl 4:10 rowSize 3:7 iBank 3:4 eBank 1:3 pageS 3:0
readMem2 0x4c00000c EMIF_CONFIG2 cs1nvmen 1:30 ebankPos 1:27 rdbnum 2:4 rdbsize 3:0
readMem2 0x4c000010 EMIF_REFRESH initDis 1:31 srt 1:29 asr 1:28 pasr 3:24 refreshRate 16:0
readMem2 0x4c000018 EMIF_TIM1 tRTW 3:29 tRP 4:25 tRCD 4:21 tWR 4:17 tRAS 5:12 tRC 6:6 tRRD 3:3 tWTR 3:0
readMem2 0x4c000020 EMIF_TIM2 tXP 3:28 tODT 3:25 tXSNR 9:16 xXSRD 10:6 tRTP 3:3 tCKE 3:0
readMem2 0x4c000028 EMIF_TIM3 tDDLunl 4:28 tCSTA 4:24 tCKESR 3:21 ZQCS 6:15 tTDQSCKmax 2:13 tRFC 9:4 tRASmax 4:0
readMem2 0x4c000038 EMIF_POW PDTIM 4:12 dpdEn 1:11 lpMode 3:8 srTim 4:4
readMem2 0x4c000040 EMIF_ddr2D val0 7:0
readMem2 0x4c000050 EMIF_ddr2config cs 1:31 refresh 1:30 add 8:0
readMem2 0x4c000054 EMIF_OCP_CONF sysMax 4:24 mpuMax 4:20 llMax 4:16
readMem2 0x4c000058 EMIF_OCP_CONFV1 sysBusW 2:30 llBusW 2:28 wrFifoD 8:8 cmdFifoD 8:0
readMem2 0x4c00005C EMIF_OCP_CONFV2 counter1 32:0
readMem2 0x4c0000C8 EMIF_SDRAM_OUTPUT_IMPEDANCE_CALIB_CONF zqCS1 1:31 z1CS0 1:30 zqDual 1:29 zqSelfRefresh 1:28 zqOnPowerdown 1:27 zqZqintMult 2:18 zqZqclMult 2:16 zqRefInterval 15:0
readMem2 0x4c000080 EMIF_PERFORMANCE_COUNTER_1
readMem2 0x4c000084 EMIF_PERFORMANCE_COUNTER_2
readMem2 0x4c000088 EMIF PERFORMANCE_COUNTER_CONFIG cntr2MconnidEn 1:31 cntr2RegionEn 1:30 cntr2Cfg 4:16 cntr1MconnidEn 1:15 cntr1RegionEn 1:14 cntr1Cfg 4:0
readMem2 0x4c00008C EMIF_PERFORMANCE_COUNTER_MASTER_REGION_SELECT mconnid2 8:24 regionSel2 2:16 mconnid1 8:8 regionSel1 2:0
readMem2 0x4c000090 EMIF_PERFORMANCE_COUNTER_TIME
readMem2 0x4c000094 EMIF_MISC_REG dllCallibOneShot 1:0
readMem2 0x4c000098 EMIF_DLL_CALIB_CTRL ack_wait 4:16 dllCalibInterval 9:0
readMem2 0x4c0000A4 EMIF_SYSTEM_OCP_INTERRUPT_RAW_STATUS dnvSys 1:2 taSys 1:1 errSys 1:0
readMem2 0x4c0000A8 EMIF_LOW_LATENCY_OCP_INTERRUPT_RAW_STATUS dnvLL 1:2 taLL 1:1 errLL 1:0
readMem2 0x4c0000AC EMIF_SYSTEM_OCP_INTERRUPT_STATUS dnvSys 1:2 taSys 1:1 errSys 1:0
readMem2 0x4c0000B0 EMIF_LOW_LATENCY_OCP_INTERRUPT_STATUS dnvLL 1:2 taLL 1:1 errLL 1:0
readMem2 0x4c0000B4 EMIF_SYSTEM_OCP_INTERRUPT_ENABLE_SET enDnvSys 1:2 enTaSys 1:1 enErrSys 1:0
readMem2 0x4c0000B8 EMIF_LOW_LATENCY_OCP_INTERRUPT_ENABLE_SET enDnvLL 1:2 enTaLL 1:1 EnErrLL 1:0
readMem2 0x4c0000BC EMIF_SYSTEM_OCP_INTERRUPT_ENABLE_CLEAR enDnvSys 1:2 enTaSys 1:1 enErrSys 1:0
readMem2 0x4c0000C0 EMIF_LOW_LATENCY_OCP_INTERRUPT_ENABLE_CLEAR enDnvLL 1:2 enTaLL 1:1 enErrLL 1:0
readMem2 0x4c0000C8 EMIF_SDRAM_OUTPUT_IMPEDANCE_CALIBRATION_CONFIG zqCS1En 1:31 zqCS0En 1:30 zqDualCalEn 1:29 zqSfExitEn 1:28 zqPdExitEnd 1:27 zqZqInitMult 2:18 zqZqClMult 2:16 zqRefInterval 16:0
readMem2 0x4c0000CC EMIF_TEMPERATURE_ALERT_CONFIG TaCS1En 1:31 taCS0En 1:30 taSfExitEn 1:28 taDevWdt 2:26 taRefInterval 22:0
readMem2 0x4c0000D0 EMIF_OCP_ERROR_LOG mAddrSpace 2:14 bBurstSeq 3:11 mCMD 3:8 mConnID 8:0
readMem2 0x4c0000E4 EMIF_DDR_PHY_CONTROL1 rdLvlMask 1:27 rdLvlGateMask 1:26 wrLvlMask 1:25 phyHalfDelays 1:21 phyClkStallLevel 1:20 phyDisCalibRst 1:19 phyInvertClkOut 1:18 phyDllLockDiff 8:10 phyFastDllLock 1:9 readLatency 5:0
readMem2 0x4c000120 EMIF_READ_WRITE_EXECUTION_THRESHOLD mFlagOverride 1:31 llBubbleEnable 1:30 wrThrsh 5:8 rdThrsh 5:0
readMem2 0x4c000140 EMIF_PHY_STATUS_1
readMem2 0x4c000200 EMIF_EXT_PHY_CONTROL_1 dllRatio2 10:20 dllRatio1 10:10 dllRatio0 10:0
readMem2 0x4c000208 EMIF_EXT_PHY_CONTROL_2 dqsDelayRatio10 10:22 dqsDelayRatio01 11:11 dqsDelayRatio00 11:0
readMem2 0x4c000210 EMIF_EXT_PHY_CONTROL_3 dqsDelayRatio21 9:23 dqsDelayRatio20 11:12 dqsDelayRatio11 11:1 dqsDelayRatio10 1:0
readMem2 0x4c00021C EMIF_EXT_PHY_CONTROL_4 dqsDelayRatio31 11:13 dqsDelayRatio30 11:2 dqsDelayRatio21 2:0
readMem2 0x4c000280 EMIF_EXT_PHY_CONTROL_17 gateLvlInitMode 1:1 useRank0Delay 1:0
readMem2 0x4c000288 EMIF_EXT_PHY_CONTROL_18 dqsTrainingRatio10 10:22 dqsTrainingRatio01 11:11 dqsTrainingRatio00 11:0
readMem2 0x4c000290 EMIF_EXT_PHY_CONTROL_19 dqsTrainingRatio21 9:23  dqsTrainingRatio20 11:12 dqsTrainingRatio11 11:1 dqsTrainingRatio10 1:0
readMem2 0x4c000298 EMIF_EXT_PHY_CONTROL_20 dqsTrainingRatio31 11:13 dqsTrainingRatio30 11:2  dqsTrainingRatio21 2:0
readMem2 0x4c0002A0 EMIF_EXT_PHY_CONTROL_21 WrLevelingRatio11 2:30  WrLevelingRatio10 10:20 WrLevelingRatio01 10:10 WrLevelingRatio00 10:0
readMem2 0x4c0002A8 EMIF_EXT_PHY_CONTROL_22 WrLevelingRatio30 4:28  WrLevelingRatio21 10:18 WrLevelingRatio20 10:8  WrLevelingRatio11 8:0
readMem2 0x4c0002B0 EMIF_EXT_PHY_CONTROL_23 WrLevelingRatio31 10:6  WrLevelingRatio30 6:0
readMem2 0x4c0002B8 EMIF_EXT_PHY_CONTROL_24 fifoReset 1:10 phyMdllClear 1:9 fifoMisalignedReset 1:8 wrLvlNumOfDq0 4:4 gateLvlNumOfDq0 4:0
But it didn't get me far enough. To the best of my knowledge, I was filling out all of the fields correctly. It was nice that the Pyra would sometimes boot better, but it would always lock up.

There was always a bit of an unknown about the memory. The stupid thing was, @hns had given the exact version of the memory being used in production Pyras.
But I had to ask EvilDragon for a picture of the CPU board to be sure (I was feeling too lazy to pull the unit apart).

The challenging thing is, the RAM is 800mhz being used in a 533mhz slot. The documentation sometimes talks about clock speeds and sometimes about picoseconds. I had pointed this out earlier but I didn't know how relevant it was going to be.
Most of our settings seem like they come from 533mhz section of the documentation. But the devices clearly need so many clock cycles to do certain operations.
I am still going to struggle to understand what settings to take from which section. I started feeling confident when I started, but then I ran into a configuration that needed so many clock cycles, but needed to be completed in so many picoseconds (otherwise it would be considered timed out?)

So, I've got a uboot that boots with this ram. It is becoming clear that the ram settings need to be pulled from the DTB since I believe we have a few units that will have old ram (2gb units?).
I have uploaded it to the Pyra discord for @EvilDragon to test. I think it has a huge performance penalty attached.
But if it finally boots more of the dead boards, I'll have something exciting to work from.
I'm going to say something I have never said before: if that script were written in perl it would be more straight forward.
 
They are soldered. I just think of it slotted in. Maybe I should have said 800mhz devices connected to a 533mhz clock?
Tricky is an under statement when we don't know what we are doing :p

Yeah. I put a little more information in the wiki. It's not a lot but it can fill in some blanks.
Uh, nope, not quite.
With 533MHz, the RAM should be setup with timings for DDR3-1066
So if the RAM has DDR3-800 timings, it would be wrong, and would cause issues.
 
So if the RAM has DDR3-800 timings, it would be wrong, and would cause issues.
K4B8G1646D-MYK0 is DDR3L-1600 (11-11-11), so would be most performant on an 800mhz clock.
Fortunately: "7. Any DDR3-1600 speed bin also supports functional operation at lower frequencies as shown in the table which are not subject to Production Tests but verified by Design/Characterization."
Yes, a lot of the settings are pulled from the 1066 table. But it is still a 1600 device. Although I've been able to claw back some performance by one of the settings that has seemed to make the unit more stable, which doesn't make sense (to me) if it really does need longer delay.
But the fact that the documentation says all of the 8Gb chips have a 2KB page size and the unit keeps crashing when I change it from 1 to 2 makes me doubt the accuracy of the documentation.
-edit-
Unless I am completely out of line. I am just coming at this as a programmer that thought he understood reading documentation.
Getting down to electrical characteristics has given me some doubt in my abilities >.<
-edit2-
Just had a conversation with EvilDragon on IRC and he pointed out that 2KB page size requires some different timings. Somehow I had overlooked that part of one of the table. I'll do some testing later and report back.
 
Last edited:
AFAIK, RAMs are produced and binned like that:
They start testing the DDR3 chips with the highest speed. If it runs stable, it's binned and sold as being usable for that speed.
If the DDR3 fails, they use the next lower clock and test it again. And so on.

So technically, they're all the same chip, just are being binned differently. But lower clock speeds than the tested ones all should run fine.
 
But lower clock speeds than the tested ones all should run fine.
Except that lower clocks are commonly also used with lower latency settings, which can actually result in overall more aggressive timings that can still cause issues. Actually calculating the absolute time period from both the latency cycles and the frequency makes it more obvious.

Additionally, the frequency we're talking about here is only used for the interface, internally the actual memory is clocked with a completely different clock. DRAM timings are complex AF for a reason.
 
Last edited:

Today at 4:47 AM​

<EvilDragon> @pimaster Just tried your MLO and U-Boot. Out of 20 boards we put aside because of the memory readback error during initialization, all of them booted :)
Well. Looks like I've got to clean up a lot of code. Work out why USB isn't working and make it available.
This was far more of a journey than I was expecting.
 
ERgh. I've finally got my changes up on git: https://dev.pyra-handheld.com/pimaster/pyra-uboot/-/tree/pimaster-dll
Ended up basing it on https://dev.pyra-handheld.com/kernel/pyra-uboot instead of https://dev.pyra-handheld.com/daveshah/pyra-uboot
There just seemed more niceties for pyra start up (like not turning on when plugged in, keep your finger on the power button until the side lights go green). I did have to pluck some memory changes from Dave S.
I was all excited to announce it on IRC when I discovered that Pyra had frozen with screen tearing issues. First time it has done it in ages. Going to just pretend it was an anomaly (it's been sitting idle for about an hour now without issue). Or maybe I have to pluck more Dave S changes.

The biggest thing I had to add was disabling EMIF power saving for this to work with DLL on. It would constantly freeze at desktop if it was left as is. I'll need to look into that some more.
Hopefully it doesn't punish the battery too much (more)

Still embarrassed at how long this has taken me.
 
Back
Top