This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Question about DDR3 parameter setting on AM3354

Other Parts Discussed in Thread: AM3354

Hi:

     we are using AM3354 and because we had to change our current DDR3 model.We need to get the correct DDR3 initialization parameter working.

    our DDR3 is K4B2G0846Q-BCK0, 2pcs and 512MB in total.It's supposed to support DDR3-1600.But for now our DDR PLL is still set to 303MHz as it originally were in the previous code.

   our uboot version is u-boot-2011.09-psp04.06.00.03

   So.

   According to          processors.wiki.ti.com/index.php/Sitara_Linux_Training:_Tuning_the_DDR3_Timings_on_BeagleBoneBlack

   we got the TIM register value and PHY register value from AM335x_DDR_register_calc_tool.xls    and    RatioSeed_AM335x_boards.xls

   then i changed SDCFG register as well . (also there are some of the bits that i don't understand what is means..like reg_ddr_term)

   but after i finished changing these values above.download the MLO and uboot to board.

   the cpu hang somewhere.  

   The log is like:

   

Welcome to use TQ3358 Board!
config_am335x_ddr3
boot from SD card...

  Got no clue .I don't know if it's some wrong setting of the registers or something.Was i wrong on some of the steps?

  I haven't tried to use CCS+JTAG yet...

  I wish to attach the file :

AM335x_DDR_register_calc_tool.xls

RatioSeed_AM335x_boards.xls

DS_K4B2G0846Q-BC_Rev11.pdf          (spec of the DDR chip)

ddr_defs.h

but i can't find any place to attach those files.

thanks a lot guys.

semiyd

1307.AM335x_DDR_register_calc_tool.xls3463.RatioSeed_AM335x_boards.xlsDS_K4B2G0846Q-BC_Rev11.pdfddr_defs.h

  • Your tck value should be for the speed that you plan to clock the memory you used 1.24nS, which corresponds to 800MHz. you should be using 3.3nS. I also recommend going through the CCS and Jtag tuning process, it will give you a better feel if your memory is working right, and it will probably be faster to test.
  • Hi Geoffrey:
    Thanks a lot for the reply!
    since the DDR PLL is 303MHz clock output in the u-boot code.
    i'm quite confused that the current DDR frequency would be 303MHz x 4? which is 1212MHz? (unlike the typical 1066 ,1333,1600?)
    because you told me that it should be 3.3ns for tck.So i guess 1212MHz should use the Speed Bins of 1333MHz? Or 1066MHz?
    in this case the CL is 5 or 6. and CWL=5 or 6. Right?

    i'm installing CCS today and will use it to optimize the parameters once the board can boot successfully.

    thanks!

    semiyd
  •   hi

      You are definitely right about my tck setting.

      although i tried to udpate the TIM register values by re-calculating them in the excel file.And after that cpu still hang somewhere.

      at least it's getting me closer to the correct value to make it run.

      I'm attaching my AM335x_DDR_register_calc_tool.xls here.

    thanks!

    semiyd

    2728.ddr_defs.h

    AM335x_DDR_register_calc_tool-0222.xls

  • I've attached the file I used for the 400MHz Micron MT41K memory that I use.   Note, importantly, that it is a single chip, not two in parallel, (reg_narrow_mode) so it will be different for you.

    I added a section to the bottom the the table which calculates ALLOPP_DDR3_SDRAM_CONFIG, depending on what chps your board was running previously, it may be usefult to you.

    AM335x_DDR_register_calc_tool mt41J KV1 20151021 400MHz.xls

  • Hi Geoffrey 

        the section of ALLOPP_DDR3_SDRAM_CONFIG of your table is very easy to config.thanks!

        I think reg_narrow_mode should always be 1 because am335x supports only 16bit data bus.Right? In my hardware it's dual ddr3 chip. 8bit + 8bit wide.

        but still i got no luck today...

        I will be trying to go through this whole ddr initialization parameter based on our old board and old ddr. Just to see if this is because our new ddr has a hardware/layout problem..

        thanks for the help!

    7230.ddr_defs.h

  • Hi Geoffrey

    Can you answer my question about the 3.3ns you mentioned?
    It will be very helpful if i can understand why you picked 3.3ns for tck for me...

    in the previous post i wrote:
    "since the DDR PLL is 303MHz clock output in the u-boot code.
    i'm quite confused that the current DDR frequency would be 303MHz x 4? which is 1212MHz? (unlike the typical 1066 ,1333,1600?)
    because you told me that it should be 3.3ns for tck.So i guess 1212MHz should use the Speed Bins of 1333MHz? Or 1066MHz?
    in this case the CL is 5 or 6. and CWL=5 or 6. Right? "

    3326.DS_K4B2G0846Q-BC_Rev11.pdf

    thanks!

  • the Tck that is referred to in the spreadsheet is the clock rate of the memory, not the data transfer rate (which would be 2x the clock rate)

    What I did was to use numbers from the slowest speed bin (which was still faster that AM335x can run the ram)  in the cases where I had to use numbers in clock cycles, and the spec sheet only provided times, I computed clock cycles by dividing by 3.3ns.

    I hope that helps.

  • Hi Geoffrey

         i think i at last understand...thanks

         3.3ns comes from 303MHz clock.    1/303MHz=3.3ns

        so this way the DDR runs at DDR3-606. Which is still slower than DDR3-800.So i had to use DDR3-800 speed bin. (i were using DDR3-1333 speed bin previously)

        thanks a lot for clearify this for me!

        just tried but still no luck. But this is a huge step forward...

       thanks!

    semiyd

  • Hi Geoffrey

        Can you attach your "RatioSeed_AM335x_boards.xls"?

       I wanted to check your phy register setting for the micron ddr...

        thanks!

    semiyd

  • 7752.RatioSeed_AM335x_boards.xls

    Hi Semiyd  the file is attached.    

    Other thoughts about your bring-up issues:    

    is the pcb the same as it was, or were changes made on that too?  There may be differences in termination, and the settings required around bus termination.

    What was the memory that was previously installed?  Are you making a big change, or a small one?

    Were the new chips professionally installed?  BGAs are very difficult to swap if you are trying to do it yourself, I'd be suspect of the installation.

  • Hi Geoffrey 

       thank you for the file.

      here is what happened:

       we were originally using the chip model K4B2G0846D-HCH9

       and it's running fine. 

       the u-boot we are using are from some evaluation board company.And they have hide the ddr_defs.h for DDR3 parameters into a lib. So we can't see the original parameter.we can't tune it.

       And now. we changed the ddr chip from K4B2G0846D-HCH9 to K4B2G0846Q-BCK0

       basically the techincal specification of these 2 chips are quite identical.The timing specification are exactly the same for DDR3-800 speed bin.I found out this when i fill in the excel chart of AM335x_DDR_register_calc_tool.xls

      the only difference between these two chips.are that the new chip K4B2G0846Q-BCK0 can run at the speed of DDR3-1600 (11-11-11).While the old one can run at DDR3-1333 (9-9-9).

      But.Since you mentioned that the fastest speed of am335x is only 400MHz.And that makes the ddr to run at DDR3-800.

      So i guess there shouldn't be any timing difference at all when switch from K4B2G0846D-HCH9 to K4B2G0846Q-BCK0. (although maybe there's internal difference that we were not able to notice...)

      And back to your questions:

       according to our hardware engineer.Yes.the pcb layout the exactly the same.They told me that they haven't changed a bit.

       and the new chip is installed in the PCB factory.So it should be professionally installed.Although i have only one board on hand,

       

       And here's some strange experiment that i've done yesterday.

       I were always tuning the parameter on the new chips these days.So i figured that i should try my parameters on my old chips.Right?

       Because there are 2 excel files."AM335x_DDR_register_calc_tool.xls" for TIM registers and "RatioSeed_AM335x_boards.xls" for PHY registers.And i have 

       configured the SDRAM_CONFIG register as well. So these are the 3 group of registers that i experimented on .

        here's what i got:

        for K4B2G0846D-HCH9 (the old chip)

        303MHz:

        my own TIM register setting + some PHY setting i grabbed from a blog from the internet + my own SDRAM_CONFIG  =  works fine.

         my own TIM register setting + my own PHY setting + my own SDRAM_CONFIG  =  cpu hang. don't work.

        400MHz:

        my own TIM register setting + some PHY setting i grabbed from a blog from the internet + my own SDRAM_CONFIG  =  works fine.

         my own TIM register setting + my own PHY setting + my own SDRAM_CONFIG  =  cpu hang. don't work.

       for  K4B2G0846Q-BCK0 (the new chip)

         none of the combination of parameter ever worked.

        always end up like :

    Welcome to use TQ3358 Board!
    boot from SD card...

    mmc_read_data: timedout waiting for status!

    spl: fat register err - -1

         So.

         It seems the conclusion could be:

        1.there's something wrong with my PHY setting.because on the old chip.when i used my own phy setting generated from the excel chart.cpu is dead.

        2.there's some kind of difference between the new chip and the old chip.The hardware is different somewhere.But don't know what exactly is the difference.

        As for conclusion 1.

        i actually found out that it's the setting of DDR3_WR_DQS that make the difference.

        Here's what i generated from the excel chart."RatioSeed_AM335x_boards.xls"

    #define DDR3_INVERT_CLKOUT 0x0
    #define DDR3_RD_DQS 0x40 
    #define DDR3_WR_DQS 0x5

    #define DDR3_RATIO              0x80
    #define DDR3_PHY_FIFO_WE 0x76

        The excel file is here:

        6888.RatioSeed_AM335x_boards.xls

         I have checked with our hardware engineer several times.

        And it seems that the input in the chart should be correct.

        I also confirmed that our DDR use a "T" shape routing.

        Now.

        Here is the PHY setting that did make our old chip work.I grabbed from a blog online.

       

    #define DDR3_INVERT_CLKOUT 0x0
    #define DDR3_RD_DQS 0x3B
    #define DDR3_WR_DQS 0x85
    #define DDR3_PHY_FIFO_WE 0x100

           

        So it seems quite strange that the WR DQS value is much larger than the one i generated myself.

        I also checked inside RatioSeed_AM335x_boards.xls that i can see some sample tabs that shows the phy setting for TI am335x evaluation boards.

        and the value of WR DQS is all quite small. 

        So this is really strange and i don't understand why.

        I also opened the RatioSeed_AM335x_boards.xls you sent me. Your WR DQS is 0.

       very confused here....

    thanks!

    semiyd

  • I like the experiment you did, it is pretty revealing.   I would make sure you can get working results on the old board first, before you move to the new one.  You may have a hardware issue as well as a software issue happening. So by using the old known-good board you eliminate one potential part of the problem. Instead of using uboot, I would try the JTAG tools, you may even be able to read in the memory configuration registers on the old board after going through uboot.

    One important note; I am using DDR3 memory not LPDDR3, I don't have any experience with LPDDR, so the difference could be related to that.  There is a tab on the spreadsheet for mDDR - is this what you should be using for LPDDR?

    One followup question for you hardware engineer is whether the board was fabricated with controlled impedance - the ddr3 bus signals are going to require controlled impedance, If the pcb manufacturer didn't know the proper impedance for the traces, then this may be a reason for a problem.   You could try putting your new chips on an old board to identify this issue.

    If you look in the formulas for the WR_DQS calc, you see that it is driven by the trace lengths of clk and dqs (rows 7&8).  So the numbers here must be very different to get 85.  numbers should be in inches;  certainly using millimeters could cause that issue.

  • Hi Geoffrey

          thanks a lot for the tips!

          Here's what i tried according to your suggestion:

         1. We used printf() to show the DDR register value of our old working DDR3. And it shows like this:

    EMIF4_0_SDRAM_TIM_1 is 0x888a39b 
    EMIF4_0_SDRAM_TIM_2 is 0x26337fda 
    EMIF4_0_SDRAM_TIM_3 is 0x501f830f 
    EMIF4_0_SDRAM_CONFIG is 0x61c04ab2
    DATA0_WR_DQS_SLAVE_RATIO_0 is 0x0
    DATA0_RD_DQS_SLAVE_RATIO_1 is 0x0
    DATA0_FIFO_WE_SLAVE_RATIO_0 is 0x0
    EMIF_READ_LATENCY is 0x6
    CMD0_INVERT_CLKOUT_0 is 0x0
    DDR3_RATIO is 0x0'

             I actually noticed that the PHY registers can not be read.Only write is permitted.So all i can get is the TIM and SDRAM_CONFIG.

             At least the TIM looks quite similar to what i generated myself. As for PHY....i can't read so i have not idea what the values are.

       2.I'm really not sure if we should be using "mDDR" tab in the excel chart.For LPDDR. The techinical spec of either old or new ddr3 chip did not mention any words like 'LPDDR' or 'mDDR'. It just refer to it as 'DDR3'.   However.I checked the definition on 'mDDR'.   On wikipedia it says that mDDR or mobile DDR is different than normal ddr in that the supply voltage is 1.8v or less compared to 2.5v.                en.wikipedia.org/wiki/Mobile_DDR

    So i tried to measure our VDD_DDR on the am3354 board.it measures 1.5v. This is where I'm quite confused. Thus i tried to use the mDDR tab to calculate in both RatioSeed_AM335x_boards.xls and AM335x_DDR_register_calc_tool.xls. And then use this mDDR parameter on our old working DDR. The strange thing is it worked. Unlike previously that i can not used my own generated PHY register value. This time i used both my own TIM value and PHY value.As well as SDRAM_CONFIG of course.

    The working parameters are like this :

    define DDR3_EMIF_TIM1 0x0888B3CB
    #define DDR3_EMIF_TIM2 0x20330CC2
    #define DDR3_EMIF_TIM3 0x00000308
    #define DDR3_EMIF_SDCFG 0x62C04B32

    #define DDR3_RATIO 0x80
    #define DDR3_INVERT_CLKOUT 0x0
    #define DDR3_RD_DQS 0x40
    #define DDR3_WR_DQS 0x5

    #define DDR3_PHY_FIFO_WE        0x110 

            TIM2 and TIM3 looks quite different than DDR3 parameters.

            But then again.Here's the conflicting part. As you suggested that i dumpped the actual parameter of the old working ddr to see what's the value written by the hidden library.Right? As i mentioned first above.

            So as you can see.The value in the hidden library seems more like DDR3 not mDDR.

            So in all.....I have no idea if i should used the mDDR tab....

       3.You mentioned controlled impedance .So i forwarded this part to our hardware engineer. And the answer came back that he said we have done the impedance matching.So i'm really not sure if controlled impedance is impedance matching.Or he did not understand what controlled impedance means if it's not impedance matching.

       4.Yes you are right.

          DDR3_WR_DQS is 0x85 for the ddr to work is really odd.

         I checked all the sample tabs in RatioSeed_AM335x_boards.xls. The WR DQS value are all quite small for DDR3.

    thanks again for all the help!

    semiyd

  • Semiyd - I'm happy to [try to] help.   

    1.  Glad you were able to get some confirmation by reading the device.  Hopefully it will lead to an insight.

    2. I did some research on the the samsung website - it seems that there is a category of parts that are mDDR3    , and you parts are not on that list, so I think that means you have regular DDR.  

    The DDR voltage listed in wikipedia is very suprising to me,my  standard DDR3 is 1.5 volts, and newer versions are 1.35.  It seems that the biggest difference between DDR3 and LPDDR3 is the existence of some lower power modes. 

    3. It sounds like there is a chance that your board my not have been fabricated with controlled impedance.  Impedance matching means that the impedance of the traces matches the termination resistance.   However, the circuit board trace impedance can vary a lot depending on the stackup and processing of the PCB.  So "controlled impedance" is used when the board is fabricated to ensure that the traces have the impedance they have been designed for.    

    The only Idea I can think of next is to suggest that you look into the forumulas in the spreadsheet, and understand how they are calculated, and what the settings actually do (via the TRM).   Maybe that will help find the problem.   If I think of anything else, I'll reply again.

  • Hi

      Your reply is really helpful. Clearifies a lot of things for me.

       It's just at times I almost lost hope because i "try" this and that many times without total success.  : )

       I also checked the samsung website and i can find my  new ddr part number on the standard DDR3 page instead of mDDR.You are right.It should be DDR3 not mDDR.

       I've forwarded the impedance control information to our hardware people and will see what's the response on his side.

       Right now the hardware people are trying to use a Micron DDR3 to replace the new samsung DDR3 I'm working on.

       They told me that they think Micron DDR3 operates at the max speed of DDR3-1333 just like the old ddr K4B2G0846D-HCH9

       While the new samsung ddr3 K4B2G0846Q-BCK0 operates at DDR3-1600 at max.

       So in a sense they think Micron is closer to the old ddr3 K4B2G0846D-HCH9.

       I know that whatever the max speed is.They will all working on DDR3-606 or DDR3-800.

       But hardware people wanted to try this out.

       will see....

    thanks!

    semiyd

       

  • 1. The device you're using is definitely a DDR3 device. Make sure you're using the DDR3 tab of the various EMIF timing spreadsheets (e.g. register config and seed value).

    2. The version of u-boot you referenced is very old and many bugs have been squashed since then. You should move to the latest u-boot (i.e. the one bundled in the current SDK).

    3. After you've programmed migrated to the new u-boot and updated your register settings you should run the script from here:

    processors.wiki.ti.com/.../How_to_use_the_AM335x_IBIS_Models

    4. Zip up everything and post for review.
  • Hi Brad:

       1.ok. thanks for help confirm that i'm using ddr3.

       2 and 3.yes i know.we will do this in future for sure. right now the uboot is used by an existing product.And since the old ddr is not available on market anymore.we had to switch to new ddr.but we don't have time/resource to do the upgrade of uboot immediately....thanks for the tip!

      4.I'm attaching the ddr driver and parameter file here. Is it enough? Should i attach the entire uboot code?

      7041.ddr_defs.h

    /*
     * evm.c
     *
     * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
     *
     * This program is free software; you can redistribute it and/or
     * modify it under the terms of the GNU General Public License as
     * published by the Free Software Foundation version 2.
     *
     * This program is distributed "as is" WITHOUT ANY WARRANTY of any
     * kind, whether express or implied; without even the implied warranty
     * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
     * GNU General Public License for more details.
     */
    
    #include <common.h>
    #include <asm/cache.h>
    #include <asm/omap_common.h>
    #include <asm/io.h>
    #include <asm/arch/cpu.h>
    #include <asm/arch/ddr_defs.h>
    #include <asm/arch/hardware.h>
    #include <asm/arch/mmc_host_def.h>
    #include <asm/arch/sys_proto.h>
    #include <asm/arch/mem.h>
    #include <asm/arch/nand.h>
    #include <asm/arch/clock.h>
    #include <linux/mtd/nand.h>
    #include <nand.h>
    #include <net.h>
    #include <miiphy.h>
    #include <netdev.h>
    #include <spi_flash.h>
    #include "common_def.h"
    #include "pmic.h"
    #include "tps65217.h"
    #include <i2c.h>
    #include <serial.h>
    #include <fastboot.h>
    #include <TQ3358/soc_AM335x.h>
    #include <TQ3358/hw_cm_dpll.h>
    #include <TQ3358/evmAM335x.h>
    #include <TQ3358/gpio_v2.h>
    DECLARE_GLOBAL_DATA_PTR;
    
    #define MDDR_SEL_DDR2		0xefffffff		/* IOs set for DDR2-STL Mode */
    #define CKE_NORMAL_OP		0x00000001		/* Normal Op:CKE controlled by EMIF */
    /* UART Defines */
    #define UART_SYSCFG_OFFSET	(0x54)
    #define UART_SYSSTS_OFFSET	(0x58)
    
    #define UART_RESET		(0x1 << 1)
    #define UART_CLK_RUNNING_MASK	0x1
    #define UART_SMART_IDLE_EN	(0x1 << 0x3)
    
    /* Timer Defines */
    #define TSICR_REG		0x54
    #define TIOCP_CFG_REG		0x10
    #define TCLR_REG		0x38
    
    /* CPLD registers */
    #define CFG_REG			0x10
    
    /*
     * I2C Address of various board
     */
    #define I2C_BASE_BOARD_ADDR	0x50
    #define I2C_DAUGHTER_BOARD_ADDR 0x51
    #define I2C_LCD_BOARD_ADDR	0x52
    
    #define I2C_CPLD_ADDR		0x35
    
    /* RGMII mode define */
    #ifdef CONFIG_RTL8211
    #define RGMII_MODE_ENABLE	0x3A
    #else
    #define RGMII_MODE_ENABLE	0xA
    #endif
    #define RMII_MODE_ENABLE	0x5
    #define MII_MODE_ENABLE		0x0
    #define RMII1_MODE_ENABLE	0x1
    #define RMII1_REFCLK_OUTSOURCED	0x40
    
    /* TLK110 PHY registers */
    #define TLK110_COARSEGAIN_REG	0x00A3
    #define TLK110_LPFHPF_REG	0x00AC
    #define TLK110_SPAREANALOG_REG	0x00B9
    #define TLK110_VRCR_REG		0x00D0
    #define TLK110_SETFFE_REG	(unsigned char)0x0107
    #define TLK110_FTSP_REG		(unsigned char)0x0154
    #define TLK110_ALFATPIDL_REG	0x002A
    #define TLK110_PSCOEF21_REG	0x0096
    #define TLK110_PSCOEF3_REG	0x0097
    #define TLK110_ALFAFACTOR1_REG	0x002C
    #define TLK110_ALFAFACTOR2_REG	0x0023
    #define TLK110_CFGPS_REG	0x0095
    #define TLK110_FTSPTXGAIN_REG	(unsigned char)0x0150
    #define TLK110_SWSCR3_REG	0x000B
    #define TLK110_SCFALLBACK_REG	0x0040
    #define TLK110_PHYRCR_REG	0x001F
    
    /* TLK110 register writes values */
    #define TLK110_COARSEGAIN_VAL	0x0000
    #define TLK110_LPFHPF_VAL	0x8000
    #define TLK110_SPAREANALOG_VAL	0x0000
    #define TLK110_VRCR_VAL		0x0008
    #define TLK110_SETFFE_VAL	0x0605
    #define TLK110_FTSP_VAL		0x0255
    #define TLK110_ALFATPIDL_VAL	0x7998
    #define TLK110_PSCOEF21_VAL	0x3A20
    #define TLK110_PSCOEF3_VAL	0x003F
    #define TLK110_ALFAFACTOR1_VAL	0xFF80
    #define TLK110_ALFAFACTOR2_VAL	0x021C
    #define TLK110_CFGPS_VAL	0x0000
    #define TLK110_FTSPTXGAIN_VAL	0x6A88
    #define TLK110_SWSCR3_VAL	0x0000
    #define TLK110_SCFALLBACK_VAL	0xC11D
    #define TLK110_PHYRCR_VAL	0x4000
    #define TLK110_PHYIDR1		0x2000
    #define TLK110_PHYIDR2		0xA201
    
    #define NO_OF_MAC_ADDR          3
    #define ETH_ALEN		6
    
    #define RTC_KICK0_REG		0x6c
    #define RTC_KICK1_REG		0x70
    #define RTC_OSC_REG		0x54
    
    struct am335x_baseboard_id {
    	unsigned int  magic;
    	char name[8];
    	char version[4];
    	char serial[12];
    	char config[32];
    	char mac_addr[NO_OF_MAC_ADDR][ETH_ALEN];
    };
    
    #ifdef CONFIG_CMD_FASTBOOT
    #ifdef FASTBOOT_PORT_OMAPZOOM_NAND_FLASHING
    
    #define MAX_PTN                 5
    
    /* Initialize the name of fastboot flash name mappings */
    fastboot_ptentry ptn[MAX_PTN] = {
    	{
    		.name   = "spl",
    		.start  = 0x0000000,
    		.length = 0x0020000, /* 128 K */
    		/* Written into the first 4 0x20000 blocks
    		   Use HW ECC */
    		.flags  = FASTBOOT_PTENTRY_FLAGS_WRITE_I |
    			  FASTBOOT_PTENTRY_FLAGS_WRITE_HW_BCH8_ECC |
    			  FASTBOOT_PTENTRY_FLAGS_REPEAT_4,
    	},
    	{
    		.name   = "uboot",
    		.start  = 0x0080000,
    		.length = 0x01E0000, /* 1.875 M */
    		/* Skip bad blocks on write
    		   Use HW ECC */
    		.flags  = FASTBOOT_PTENTRY_FLAGS_WRITE_I |
    			  FASTBOOT_PTENTRY_FLAGS_WRITE_HW_BCH8_ECC,
    	},
    	{
    		.name   = "environment",
    		.start  = MNAND_ENV_OFFSET,  /* set in config file */
    		.length = 0x0020000,
    		.flags  = FASTBOOT_PTENTRY_FLAGS_WRITE_ENV |
    			  FASTBOOT_PTENTRY_FLAGS_WRITE_HW_ECC,
    	},
    	{
    		.name   = "kernel",
    		.start  = 0x0280000,
    		.length = 0x0500000, /* 5 M */
    		.flags  = FASTBOOT_PTENTRY_FLAGS_WRITE_I |
    			  FASTBOOT_PTENTRY_FLAGS_WRITE_HW_BCH8_ECC,
    	},
    	{
    		.name   = "filesystem",
    		.start  = 0x0780000,
    		.length = 0xF880000, /* 248.5 M */
    		.flags  = FASTBOOT_PTENTRY_FLAGS_WRITE_I |
    			  FASTBOOT_PTENTRY_FLAGS_WRITE_HW_BCH8_ECC,
    	},
    };
    #endif /* FASTBOOT_PORT_OMAPZOOM_NAND_FLASHING */
    #endif /* CONFIG_FASTBOOT */
    
    static struct am335x_baseboard_id header;
    extern void cpsw_eth_set_mac_addr(const u_int8_t *addr);
    static unsigned char daughter_board_connected;
    #ifdef CONFIG_RTL8211
    static volatile int board_id = EMBEDSKY_BOARD;
    #else
    static volatile int board_id = BASE_BOARD;
    #endif
    
    /*
     * dram_init:
     * At this point we have initialized the i2c bus and can read the
     * EEPROM which will tell us what board and revision we are on.
     */
    int dram_init(void)
    {
    	gd->ram_size = PHYS_DRAM_1_SIZE;
    
    	return 0;
    }
    
    void dram_init_banksize (void)
    {
    	/* Fill up board info */
    	gd->bd->bi_dram[0].start = PHYS_DRAM_1;
    	gd->bd->bi_dram[0].size = PHYS_DRAM_1_SIZE;
    }
    
    #ifdef CONFIG_SPL_BUILD
    static void init_timer(void)
    {
    	/* Reset the Timer */
    	__raw_writel(0x2, (DM_TIMER2_BASE + TSICR_REG));
    
    	/* Wait until the reset is done */
    	while (__raw_readl(DM_TIMER2_BASE + TIOCP_CFG_REG) & 1);
    
    	/* Start the Timer */
    	__raw_writel(0x1, (DM_TIMER2_BASE + TCLR_REG));
    }
    
    static void rtc32k_enable(void)
    {
    	/* Unlock the rtc's registers */
    	__raw_writel(0x83e70b13, (AM335X_RTC_BASE + RTC_KICK0_REG));
    	__raw_writel(0x95a4f1e0, (AM335X_RTC_BASE + RTC_KICK1_REG));
    
    	/* Enable the RTC 32K OSC */
    	__raw_writel(0x48, (AM335X_RTC_BASE + RTC_OSC_REG));
    }
    #endif
    
    /*
     * Read header information from EEPROM into global structure.
     */
    int read_eeprom(void)
    {
            /* Check if baseboard eeprom is available */
    	if (i2c_probe(I2C_BASE_BOARD_ADDR)) {
    		printf("Could not probe the EEPROM; something fundamentally "
    			"wrong on the I2C bus.\n");
    		return 1;
    	}
    
    	/* read the eeprom using i2c */
    	if (i2c_read(I2C_BASE_BOARD_ADDR, 0, 2, (uchar *)&header,
    							sizeof(header))) {
    		printf("Could not read the EEPROM; something fundamentally"
    			" wrong on the I2C bus.\n");
    		return 1;
    	}
    
    	if (header.magic != 0xEE3355AA) {
    		/* read the eeprom using i2c again, but use only a 1 byte address */
    		if (i2c_read(I2C_BASE_BOARD_ADDR, 0, 1, (uchar *)&header,
    								sizeof(header))) {
    			printf("Could not read the EEPROM; something fundamentally"
    				" wrong on the I2C bus.\n");
    			return 1;
    		}
    
    		if (header.magic != 0xEE3355AA) {
    			printf("Incorrect magic number in EEPROM\n");
    			return 1;
    		}
    	}
    	return 0;
    }
    
    #if defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_BOARD_INIT)
    
    /**
     * tps65217_reg_read() - Generic function that can read a TPS65217 register
     * @src_reg:          Source register address
     * @src_val:          Address of destination variable
     */
    
    unsigned char tps65217_reg_read(uchar src_reg, uchar *src_val)
    {
    	if (i2c_read(TPS65217_CHIP_PM, src_reg, 1, src_val, 1))
    		return 1;
    	return 0;
    }
    
    /**
     *  tps65217_reg_write() - Generic function that can write a TPS65217 PMIC
     *                         register or bit field regardless of protection
     *                         level.
     *
     *  @prot_level:        Register password protection.
     *                      use PROT_LEVEL_NONE, PROT_LEVEL_1, or PROT_LEVEL_2
     *  @dest_reg:          Register address to write.
     *  @dest_val:          Value to write.
     *  @mask:              Bit mask (8 bits) to be applied.  Function will only
     *                      change bits that are set in the bit mask.
     *
     *  @return:            0 for success, 1 for failure.
     */
    int tps65217_reg_write(uchar prot_level, uchar dest_reg,
            uchar dest_val, uchar mask)
    {
            uchar read_val;
            uchar xor_reg;
    
            /* if we are affecting only a bit field, read dest_reg and apply the mask */
            if (mask != MASK_ALL_BITS) {
                    if (i2c_read(TPS65217_CHIP_PM, dest_reg, 1, &read_val, 1))
                            return 1;
                    read_val &= (~mask);
                    read_val |= (dest_val & mask);
                    dest_val = read_val;
            }
    
            if (prot_level > 0) {
                    xor_reg = dest_reg ^ PASSWORD_UNLOCK;
                    if (i2c_write(TPS65217_CHIP_PM, PASSWORD, 1, &xor_reg, 1))
                            return 1;
            }
    
            if (i2c_write(TPS65217_CHIP_PM, dest_reg, 1, &dest_val, 1))
                    return 1;
    
            if (prot_level == PROT_LEVEL_2) {
                    if (i2c_write(TPS65217_CHIP_PM, PASSWORD, 1, &xor_reg, 1))
                            return 1;
    
                    if (i2c_write(TPS65217_CHIP_PM, dest_reg, 1, &dest_val, 1))
                            return 1;
            }
    
            return 0;
    }
    
    /**
     *  tps65217_voltage_update() - Controls output voltage setting for the DCDC1,
     *       DCDC2, or DCDC3 control registers in the PMIC.
     *
     *  @dc_cntrl_reg:      DCDC Control Register address.
     *                      Must be DEFDCDC1, DEFDCDC2, or DEFDCDC3.
     *  @volt_sel:          Register value to set.  See PMIC TRM for value set.
     *
     *  @return:            0 for success, 1 for failure.
     */
    int tps65217_voltage_update(unsigned char dc_cntrl_reg, unsigned char volt_sel)
    {
            if ((dc_cntrl_reg != DEFDCDC1) && (dc_cntrl_reg != DEFDCDC2)
                    && (dc_cntrl_reg != DEFDCDC3))
                    return 1;
    
            /* set voltage level */
            if (tps65217_reg_write(PROT_LEVEL_2, dc_cntrl_reg, volt_sel, MASK_ALL_BITS))
                    return 1;
    
            /* set GO bit to initiate voltage transition */
            if (tps65217_reg_write(PROT_LEVEL_2, DEFSLEW, DCDC_GO, DCDC_GO))
                    return 1;
    
            return 0;
    }
    
    /*
     * voltage switching for MPU frequency switching.
     * @module = mpu - 0, core - 1
     * @vddx_op_vol_sel = vdd voltage to set
     */
    
    #define MPU		0
    #define CORE	1
    
    int voltage_update(unsigned int module, unsigned char vddx_op_vol_sel)
    {
    	uchar buf[4];
    	unsigned int reg_offset;
    
    	if(module == MPU)
    		reg_offset = PMIC_VDD1_OP_REG;
    	else
    		reg_offset = PMIC_VDD2_OP_REG;
    
    	/* Select VDDx OP   */
    	if (i2c_read(PMIC_CTRL_I2C_ADDR, reg_offset, 1, buf, 1))
    		return 1;
    
    	buf[0] &= ~PMIC_OP_REG_CMD_MASK;
    
    	if (i2c_write(PMIC_CTRL_I2C_ADDR, reg_offset, 1, buf, 1))
    		return 1;
    
    	/* Configure VDDx OP  Voltage */
    	if (i2c_read(PMIC_CTRL_I2C_ADDR, reg_offset, 1, buf, 1))
    		return 1;
    
    	buf[0] &= ~PMIC_OP_REG_SEL_MASK;
    	buf[0] |= vddx_op_vol_sel;
    
    	if (i2c_write(PMIC_CTRL_I2C_ADDR, reg_offset, 1, buf, 1))
    		return 1;
    
    	if (i2c_read(PMIC_CTRL_I2C_ADDR, reg_offset, 1, buf, 1))
    		return 1;
    
    	if ((buf[0] & PMIC_OP_REG_SEL_MASK ) != vddx_op_vol_sel)
    		return 1;
    
    	return 0;
    }
    
    extern void set_tps659101(void);
    /*hxs amend 2012-9-12  RTC and BATERRY*/
    void spl_board_init(void)
    {
    	uchar pmic_status_reg = 0;
    
    	/* Configure the i2c0 pin mux */
    	enable_i2c0_pin_mux();
    
    	i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
    
    	/*if (read_eeprom()) {
    		printf("read_eeprom() failure\n");
    		return;
    	}*/
    #if 0
    	if (!strncmp("A335BONE", header.name, 8)) {
    		printd("evm.c/spl_board_init:: TPS65217_CHIP_PM = %d \n", TPS65217_CHIP_PM);
    		/* BeagleBone PMIC Code */
    		if (i2c_probe(TPS65217_CHIP_PM))
    			return;
    
    		printd("TPS659101 read DEVCTRL_REG = %d! \n", pmic_status_reg);
    
    		if (tps65217_reg_write(PROT_LEVEL_2, DEVCTRL_REG,
    				       0X44, LDO_MASK))
    			printf("tps65217_reg_write DEVCTRL_REG failure\n");	
    
    		printd("TPS659101 set DEVCTRL_REG success! \n");	
    
    		if (tps65217_reg_read(DEVCTRL_REG, &pmic_status_reg))
    			return;
    
    		printd("TPS659101 read DEVCTRL_REG = %d! \n", pmic_status_reg);
    		/* Increase USB current limit to 1300mA */
    		if (tps65217_reg_write(PROT_LEVEL_NONE, POWER_PATH,
    				       USB_INPUT_CUR_LIMIT_1300MA,
    				       USB_INPUT_CUR_LIMIT_MASK))
    			printf("tps65217_reg_write failure\n");
    
    		/* Only perform PMIC configurations if board rev > A1 */
    		if (!strncmp(header.version, "00A1", 4))
    			return;
    
    		/* Set DCDC2 (MPU) voltage to 1.275V */
    		if (tps65217_voltage_update(DEFDCDC2,
    					     DCDC_VOLT_SEL_1275MV)) {
    			printf("tps65217_voltage_update failure\n");
    			return;
    		}
    
    		/* Set LDO3, LDO4 output voltage to 3.3V */
    		if (tps65217_reg_write(PROT_LEVEL_2, DEFLS1,
    				       LDO_VOLTAGE_OUT_3_3, LDO_MASK))
    			printf("tps65217_reg_write failure\n");
    
    		if (tps65217_reg_write(PROT_LEVEL_2, DEFLS2,
    				       LDO_VOLTAGE_OUT_3_3, LDO_MASK))
    			printf("tps65217_reg_write failure\n");
    
    		if (!(pmic_status_reg & PWR_SRC_AC_BITMASK)) {
    			printf("No AC power, disabling frequency switch\n");
    			return;
    		}
    
    		/* Set MPU Frequency to 720MHz */
    		mpu_pll_config(MPUPLL_M_720);
    	} 
    	else {
    #else
    	if (1) {
    #endif /* 1 */
    		set_tps659101();
    	}
    }
    #endif
    
    
    void open_led(void)
    {
    	//yandong add led default state
    	GPIO0ModuleClkConfig();
        	GPIO1ModuleClkConfig();
    	GPIO0PinMuxSetup(18);	//GPIO0_18_ALARM	
    	GPIO0PinMuxSetup(19);	//GPIO0_19_RUN
    	GPIO0PinMuxSetup(20);	//GPIO0_20_FAULT
    	//GPIO1PinMuxSetup(14);	//GPIO1_14_LCM_ALARM
    	//GPIO1PinMuxSetup(17);	//GPIO1_17_LED_ERR
    	//GPIO1PinMuxSetup(18);	//GPIO1_18_LED_RST
       /* Resetting the GPIO module. */
    	GPIOModuleReset(SOC_GPIO_0_REGS);
        	GPIOModuleReset(SOC_GPIO_1_REGS);
    
        /* Enabling the GPIO module. */
    	GPIOModuleEnable(SOC_GPIO_0_REGS);
        	GPIOModuleEnable(SOC_GPIO_1_REGS);
    
        /* Setting the GPIO pin as an input pin. */    
        	GPIODirModeSet(SOC_GPIO_0_REGS,18,GPIO_DIR_OUTPUT);
        	GPIODirModeSet(SOC_GPIO_0_REGS,19,GPIO_DIR_OUTPUT);
        	GPIODirModeSet(SOC_GPIO_0_REGS,20,GPIO_DIR_OUTPUT);
        	//GPIODirModeSet(SOC_GPIO_1_REGS,14,GPIO_DIR_OUTPUT);	
        	//GPIODirModeSet(SOC_GPIO_1_REGS,17,GPIO_DIR_OUTPUT);
        	//GPIODirModeSet(SOC_GPIO_1_REGS,18,GPIO_DIR_OUTPUT);
    #if 0//ON
        	GPIOPinWrite(SOC_GPIO_0_REGS, 18,GPIO_PIN_LOW);
        	GPIOPinWrite(SOC_GPIO_0_REGS, 19,GPIO_PIN_LOW);
    	GPIOPinWrite(SOC_GPIO_0_REGS, 20,GPIO_PIN_HIGH);
    #else//OFF
        	GPIOPinWrite(SOC_GPIO_0_REGS, 18,GPIO_PIN_HIGH);
        	GPIOPinWrite(SOC_GPIO_0_REGS, 19,GPIO_PIN_HIGH);
    	GPIOPinWrite(SOC_GPIO_0_REGS, 20,GPIO_PIN_LOW);
    #endif
    }
    /*end here*/
    
    static void config_vtp(void)
    {
    	__raw_writel(__raw_readl(VTP0_CTRL_REG) | VTP_CTRL_ENABLE,
    			VTP0_CTRL_REG);
    	__raw_writel(__raw_readl(VTP0_CTRL_REG) & (~VTP_CTRL_START_EN),
    			VTP0_CTRL_REG);
    	__raw_writel(__raw_readl(VTP0_CTRL_REG) | VTP_CTRL_START_EN,
    			VTP0_CTRL_REG);
    
    	/* Poll for READY */
    	while ((__raw_readl(VTP0_CTRL_REG) & VTP_CTRL_READY) != VTP_CTRL_READY);
    }
    
    static void config_emif_ddr3(void)  
    {          
        /*Program EMIF0 CFG Registers*/  
        writel(DDR3_EMIF_READ_LATENCY, EMIF4_0_DDR_PHY_CTRL_1);  
        writel(DDR3_EMIF_READ_LATENCY, EMIF4_0_DDR_PHY_CTRL_1_SHADOW);  
        writel(DDR3_EMIF_READ_LATENCY, EMIF4_0_DDR_PHY_CTRL_2);  
        writel(DDR3_EMIF_TIM1, EMIF4_0_SDRAM_TIM_1);  
        writel(DDR3_EMIF_TIM1, EMIF4_0_SDRAM_TIM_1_SHADOW);  
        writel(DDR3_EMIF_TIM2, EMIF4_0_SDRAM_TIM_2);  
        writel(DDR3_EMIF_TIM2, EMIF4_0_SDRAM_TIM_2_SHADOW);  
        writel(DDR3_EMIF_TIM3, EMIF4_0_SDRAM_TIM_3);  
        writel(DDR3_EMIF_TIM3, EMIF4_0_SDRAM_TIM_3_SHADOW);  
      
      
        writel(DDR3_EMIF_SDREF, EMIF4_0_SDRAM_REF_CTRL);  
        writel(DDR3_EMIF_SDREF, EMIF4_0_SDRAM_REF_CTRL_SHADOW);  
        writel(DDR3_ZQ_CFG, EMIF0_0_ZQ_CONFIG);  
      
        writel(DDR3_EMIF_SDCFG, EMIF4_0_SDRAM_CONFIG);  
       
     }  
    
    
    /*
     * early system init of muxing and clocks.
     */
    static void phy_config_cmd(void)  
    {  
        writel(DDR3_RATIO, CMD0_CTRL_SLAVE_RATIO_0);  
        writel(DDR3_INVERT_CLKOUT, CMD0_INVERT_CLKOUT_0);  
        writel(DDR3_RATIO, CMD1_CTRL_SLAVE_RATIO_0);  
        writel(DDR3_INVERT_CLKOUT, CMD1_INVERT_CLKOUT_0);  
        writel(DDR3_RATIO, CMD2_CTRL_SLAVE_RATIO_0);  
        writel(DDR3_INVERT_CLKOUT, CMD2_INVERT_CLKOUT_0);  
    }  
      
    static void phy_config_data(void)  
    {  
      
        writel(DDR3_RD_DQS, DATA0_RD_DQS_SLAVE_RATIO_0);  
        writel(DDR3_WR_DQS, DATA0_WR_DQS_SLAVE_RATIO_0);  
        writel(DDR3_PHY_FIFO_WE, DATA0_FIFO_WE_SLAVE_RATIO_0);  
        writel(DDR3_PHY_WR_DATA, DATA0_WR_DATA_SLAVE_RATIO_0);  
      
        writel(DDR3_RD_DQS, DATA1_RD_DQS_SLAVE_RATIO_0);  
        writel(DDR3_WR_DQS, DATA1_WR_DQS_SLAVE_RATIO_0);  
        writel(DDR3_PHY_FIFO_WE, DATA1_FIFO_WE_SLAVE_RATIO_0);  
        writel(DDR3_PHY_WR_DATA, DATA1_WR_DATA_SLAVE_RATIO_0);  
    } 
    
    static void config_new_ddr3(void)  
    {  
        enable_ddr3_clocks();  
      
        config_vtp();   
        phy_config_cmd();  
        phy_config_data();  
      
        /* set IO control registers */  
        writel(DDR3_IOCTRL_VALUE, DDR_CMD0_IOCTRL);  
        writel(DDR3_IOCTRL_VALUE, DDR_CMD1_IOCTRL);  
        writel(DDR3_IOCTRL_VALUE, DDR_CMD2_IOCTRL);  
        writel(DDR3_IOCTRL_VALUE, DDR_DATA0_IOCTRL);  
        writel(DDR3_IOCTRL_VALUE, DDR_DATA1_IOCTRL);  
      
        /* IOs set for DDR3 */  
        writel(readl(DDR_IO_CTRL) & MDDR_SEL_DDR2, DDR_IO_CTRL);  
        /* CKE controlled by EMIF/DDR_PHY */  
        writel(readl(DDR_CKE_CTRL) | CKE_NORMAL_OP, DDR_CKE_CTRL);  
      
        config_emif_ddr3();  
       
    }  
    void s_init(void)
    {
    	/* Can be removed as A8 comes up with L2 enabled */
    	l2_cache_enable();
    
    	/* WDT1 is already running when the bootloader gets control
    	 * Disable it to avoid "random" resets
    	 */
    	__raw_writel(0xAAAA, WDT_WSPR);
    	while(__raw_readl(WDT_WWPS) != 0x0);
    	__raw_writel(0x5555, WDT_WSPR);
    	while(__raw_readl(WDT_WWPS) != 0x0);
    
    #ifdef CONFIG_SPL_BUILD
    	/* Setup the PLLs and the clocks for the peripherals */
    	pll_init();
    
    	/* Enable RTC32K clock */
    	rtc32k_enable();
    
    	/* UART softreset */
    	u32 regVal;
    	u32 uart_base = DEFAULT_UART_BASE;
    
    	enable_uart0_pin_mux();
    	enable_uart4_pin_mux();
    
    
    	/* IA Motor Control Board has default console on UART3*/
    	/* XXX: This is before we've probed / set board_id */
    	//if (board_id == IA_BOARD) {
    	//	uart_base = UART3_BASE;
    	//}
    
    	regVal = __raw_readl(uart_base + UART_SYSCFG_OFFSET);
    	regVal |= UART_RESET;
    	__raw_writel(regVal, (uart_base + UART_SYSCFG_OFFSET) );
    	while ((__raw_readl(uart_base + UART_SYSSTS_OFFSET) &
    			UART_CLK_RUNNING_MASK) != UART_CLK_RUNNING_MASK);
    
    	/* Disable smart idle */
    	regVal = __raw_readl((uart_base + UART_SYSCFG_OFFSET));
    	regVal |= UART_SMART_IDLE_EN;
    	__raw_writel(regVal, (uart_base + UART_SYSCFG_OFFSET));
    
    	/* Initialize the Timer */
    	init_timer();
    
    	preloader_console_init();
    
    
    		config_new_ddr3();
    
    	
    #endif
    }
    
    static void detect_daughter_board(void)
    {
    	/* Check if daughter board is conneted */
    	if (i2c_probe(I2C_DAUGHTER_BOARD_ADDR)) {
    		printf("No daughter card present\n");
    		return;
    	} else {
    		printf("Found a daughter card connected\n");
    		daughter_board_connected = 1;
    	}
    }
    
    static unsigned char profile = PROFILE_0;
    static void detect_daughter_board_profile(void)
    {
    	unsigned short val;
    
    	if (i2c_probe(I2C_CPLD_ADDR))
    		return;
    
    	if (i2c_read(I2C_CPLD_ADDR, CFG_REG, 1, (unsigned char *)(&val), 2))
    		return;
    
    	profile = 1 << (val & 0x7);
    }
    
    /*
     * Basic board specific setup
     */
    #ifndef CONFIG_SPL_BUILD
    int board_evm_init(void)
    {
    	/* mach type passed to kernel */
    	if (board_id == IA_BOARD)
    		gd->bd->bi_arch_number = MACH_TYPE_TIAM335IAEVM;
    	else
    		gd->bd->bi_arch_number = MACH_TYPE_TIAM335EVM;
    
    	/* address of boot parameters */
    	gd->bd->bi_boot_params = PHYS_DRAM_1 + 0x100;
    
    	return 0;
    }
    #endif
    
    #if 0
    struct serial_device *default_serial_console(void)
    {
    
    	if (board_id != IA_BOARD) {
    		return &eserial1_device;	/* UART0 */
    	} else {
    		return &eserial4_device;	/* UART3 */
    	}
    }
    #endif
    
    int board_init(void)
    {
    	/* Configure the i2c0 pin mux */
    	enable_i2c0_pin_mux();
    
    	/* set gmii1_sel bit to rmii mode and rmii1_io_clk_en bit is set to 1 in gmii_sel register */
    	/* moved to the time before configure_evm_pin_mux() is called to ensure rmii1_refclk is not scrambled	*
    	 *  because otherwise cpu and the outside crystal will output 50MHz ref clk at the same time.		*		
    	 */
    	__raw_writel(RMII1_MODE_ENABLE|RMII1_REFCLK_OUTSOURCED, MAC_MII_SEL);
    
    	i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
    
    	/*if (read_eeprom())
    		goto err_out;*/
    
    	//detect_daughter_board();  	//	hxs delete 2012-9-26
    
    	/*if (!strncmp("SKU#01", header.config, 6)) {
    		board_id = GP_BOARD;
    		detect_daughter_board_profile();
    	} else if (!strncmp("SKU#02", header.config, 6)) {
    		board_id = IA_BOARD;
    		detect_daughter_board_profile();
    	} else if (!strncmp("SKU#03", header.config, 6)) {
    		board_id = IPP_BOARD;
    	} else if (!strncmp("A335BONE", header.name, 8)) {
    		board_id = BONE_BOARD;
    		profile = 1;	
    		daughter_board_connected = 0;
    	} else {
    		printf("Did not find a recognized configuration, "
    			"assuming General purpose EVM in Profile 0 with "
    			"Daughter board\n");
    		board_id = GP_BOARD;
    		profile = 1;	
    		daughter_board_connected = 1;
    	}*/
    	
    #ifdef CONFIG_RTL8211
    	board_id = GP_BOARD;//ken add 2013-05-12
    #else
    	board_id = BONE_BOARD;
    #endif
    	profile = 1;	/* profile 0 is internally considered as 1 */
    	daughter_board_connected = 1;
    	
    	printd("board_id=%d \n", board_id);
    
    	configure_evm_pin_mux(board_id, header.version, profile, daughter_board_connected);
    
    #ifndef CONFIG_SPL_BUILD
    	board_evm_init();
    #endif
    
    	gpmc_init();//nand 初始化
    
    #ifdef CONFIG_CMD_FASTBOOT
    #ifdef FASTBOOT_PORT_OMAPZOOM_NAND_FLASHING
    	int indx;
    
    	for (indx = 0; indx < MAX_PTN; indx++)
    		fastboot_flash_add_ptn(&ptn[indx]);
    #endif /* FASTBOOT_PORT_OMAPZOOM_NAND_FLASHING */
    #endif /* CONFIG_FASTBOOT */
    
    	return 0;
    
    err_out:
    	/*
    	 * When we cannot use the EEPROM to determine what board we
    	 * are we assume BeagleBone currently as we have not yet
    	 * programmed the EEPROMs.
    	 */
    #ifdef CONFIG_RTL8211
    	board_id = EMBEDSKY_BOARD;
    #else
    	board_id = BONE_BOARD;
    #endif
    	profile = 1;	/* profile 0 is internally considered as 1 */
    	daughter_board_connected = 1;
    	configure_evm_pin_mux(board_id, header.version, profile, daughter_board_connected);
    
    #ifndef CONFIG_SPL_BUILD
    	board_evm_init();
    #endif
    
    	gpmc_init();//nand 初始化
    
    	return 0;
    }
    
    int misc_init_r(void)
    {
    #ifdef DEBUG
    	unsigned int cntr;
    	unsigned char *valPtr;
    
    	debug("EVM Configuration - ");
    	debug("\tBoard id %x, profile %x, db %d\n", board_id, profile,
    						daughter_board_connected);
    	debug("Base Board EEPROM Data\n");
    	valPtr = (unsigned char *)&header;
    	for(cntr = 0; cntr < sizeof(header); cntr++) {
    		if(cntr % 16 == 0)
    			debug("\n0x%02x :", cntr);
    		debug(" 0x%02x", (unsigned int)valPtr[cntr]);
    	}
    	debug("\n\n");
    
    	debug("Board identification from EEPROM contents:\n");
    	debug("\tBoard name   : %.8s\n", header.name);
    	debug("\tBoard version: %.4s\n", header.version);
    	debug("\tBoard serial : %.12s\n", header.serial);
    	debug("\tBoard config : %.6s\n\n", header.config);
    #endif
    	return 0;
    }
    
    #ifdef BOARD_LATE_INIT
    int board_late_init(void)
    {
    	if (board_id == IA_BOARD) {
    		/*
    		* SPI bus number is switched to in case Industrial Automation
    		* motor control EVM.
    		*/
    		setenv("spi_bus_no", "1");
    		/* Change console to tty03 for IA Motor Control EVM */
    		setenv("console", "ttyO3,115200n8");
    	}
    
    	return 0;
    }
    #endif
    
    #ifdef CONFIG_DRIVER_TI_CPSW
    /* TODO : Check for the board specific PHY */
    static void evm_phy_init(char *name, int addr)
    {
    	unsigned short val;
    	unsigned int cntr = 0;
    	unsigned short phyid1, phyid2;
    	int bone_pre_a3 = 0;
    
    	if (board_id == BONE_BOARD && (!strncmp(header.version, "00A1", 4) ||
    		    !strncmp(header.version, "00A2", 4)))
    		bone_pre_a3 = 1;
    
    	/*
    	 * This is done as a workaround to support TLK110 rev1.0 PHYs.
    	 * We can only perform these reads on these PHYs (currently
    	 * only found on the IA EVM).
    	 */
    	if ((miiphy_read(name, addr, MII_PHYSID1, &phyid1) != 0) ||
    			(miiphy_read(name, addr, MII_PHYSID2, &phyid2) != 0))
    		return;
    
    	if ((phyid1 == TLK110_PHYIDR1) && (phyid2 == TLK110_PHYIDR2)) {
    		miiphy_read(name, addr, TLK110_COARSEGAIN_REG, &val);
    		val |= TLK110_COARSEGAIN_VAL;
    		miiphy_write(name, addr, TLK110_COARSEGAIN_REG, val);
    
    		miiphy_read(name, addr, TLK110_LPFHPF_REG, &val);
    		val |= TLK110_LPFHPF_VAL;
    		miiphy_write(name, addr, TLK110_LPFHPF_REG, val);
    
    		miiphy_read(name, addr, TLK110_SPAREANALOG_REG, &val);
    		val |= TLK110_SPAREANALOG_VAL;
    		miiphy_write(name, addr, TLK110_SPAREANALOG_REG, val);
    
    		miiphy_read(name, addr, TLK110_VRCR_REG, &val);
    		val |= TLK110_VRCR_VAL;
    		miiphy_write(name, addr, TLK110_VRCR_REG, val);
    
    		miiphy_read(name, addr, TLK110_SETFFE_REG, &val);
    		val |= TLK110_SETFFE_VAL;
    		miiphy_write(name, addr, TLK110_SETFFE_REG, val);
    
    		miiphy_read(name, addr, TLK110_FTSP_REG, &val);
    		val |= TLK110_FTSP_VAL;
    		miiphy_write(name, addr, TLK110_FTSP_REG, val);
    
    		miiphy_read(name, addr, TLK110_ALFATPIDL_REG, &val);
    		val |= TLK110_ALFATPIDL_VAL;
    		miiphy_write(name, addr, TLK110_ALFATPIDL_REG, val);
    
    		miiphy_read(name, addr, TLK110_PSCOEF21_REG, &val);
    		val |= TLK110_PSCOEF21_VAL;
    		miiphy_write(name, addr, TLK110_PSCOEF21_REG, val);
    
    		miiphy_read(name, addr, TLK110_PSCOEF3_REG, &val);
    		val |= TLK110_PSCOEF3_VAL;
    		miiphy_write(name, addr, TLK110_PSCOEF3_REG, val);
    
    		miiphy_read(name, addr, TLK110_ALFAFACTOR1_REG, &val);
    		val |= TLK110_ALFAFACTOR1_VAL;
    		miiphy_write(name, addr, TLK110_ALFAFACTOR1_REG, val);
    
    		miiphy_read(name, addr, TLK110_ALFAFACTOR2_REG, &val);
    		val |= TLK110_ALFAFACTOR2_VAL;
    		miiphy_write(name, addr, TLK110_ALFAFACTOR2_REG, val);
    
    		miiphy_read(name, addr, TLK110_CFGPS_REG, &val);
    		val |= TLK110_CFGPS_VAL;
    		miiphy_write(name, addr, TLK110_CFGPS_REG, val);
    
    		miiphy_read(name, addr, TLK110_FTSPTXGAIN_REG, &val);
    		val |= TLK110_FTSPTXGAIN_VAL;
    		miiphy_write(name, addr, TLK110_FTSPTXGAIN_REG, val);
    
    		miiphy_read(name, addr, TLK110_SWSCR3_REG, &val);
    		val |= TLK110_SWSCR3_VAL;
    		miiphy_write(name, addr, TLK110_SWSCR3_REG, val);
    
    		miiphy_read(name, addr, TLK110_SCFALLBACK_REG, &val);
    		val |= TLK110_SCFALLBACK_VAL;
    		miiphy_write(name, addr, TLK110_SCFALLBACK_REG, val);
    
    		miiphy_read(name, addr, TLK110_PHYRCR_REG, &val);
    		val |= TLK110_PHYRCR_VAL;
    		miiphy_write(name, addr, TLK110_PHYRCR_REG, val);
    	}
    
    	/* Enable Autonegotiation */
    	if (miiphy_read(name, addr, MII_BMCR, &val) != 0) {
    		printf("failed to read bmcr\n");
    		return;
    	}
    
    	if (bone_pre_a3) {
    		val &= ~(BMCR_FULLDPLX | BMCR_ANENABLE | BMCR_SPEED100);
    		val |= BMCR_FULLDPLX;
    	} else
    		val |= BMCR_FULLDPLX | BMCR_ANENABLE | BMCR_SPEED100;
    
    	if (miiphy_write(name, addr, MII_BMCR, val) != 0) {
    		printf("failed to write bmcr\n");
    		return;
    	}
    	miiphy_read(name, addr, MII_BMCR, &val);
    
    	//header.version = "1.0";//hxs add
    	strcpy(header.version, "1.0");//hxs add
    	/*
    	 * The 1.0 revisions of the GP board don't have functional
    	 * gigabit ethernet so we need to disable advertising.
    	 */
    	if (board_id == GP_BOARD && !strncmp(header.version, "1.0", 3)) {
    		miiphy_read(name, addr, MII_CTRL1000, &val);
    		val &= ~PHY_1000BTCR_1000FD;
    		val &= ~PHY_1000BTCR_1000HD;
    		miiphy_write(name, addr, MII_CTRL1000, val);
    		miiphy_read(name, addr, MII_CTRL1000, &val);
    		printd("header.version = 1.0  \n");
    	}
    
    	/* Setup general advertisement */
    	if (miiphy_read(name, addr, MII_ADVERTISE, &val) != 0) {
    		printf("failed to read anar\n");
    		return;
    	}
    
    	if (bone_pre_a3)
    		val |= (LPA_10HALF | LPA_10FULL);
    	else
    		val |= (LPA_10HALF | LPA_10FULL | LPA_100HALF | LPA_100FULL);
    
    	if (miiphy_write(name, addr, MII_ADVERTISE, val) != 0) {
    		printf("failed to write anar\n");
    		return;
    	}
    	miiphy_read(name, addr, MII_ADVERTISE, &val);
    
    	/* Restart auto negotiation*/
    	miiphy_read(name, addr, MII_BMCR, &val);
    	val |= BMCR_ANRESTART;
    	miiphy_write(name, addr, MII_BMCR, val);
    
    	/*check AutoNegotiate complete - it can take upto 3 secs*/
    	do {
    		udelay(40000);
    		cntr++;
    		if (!miiphy_read(name, addr, MII_BMSR, &val)) {
    			if (val & BMSR_ANEGCOMPLETE)
    				break;
    		}
    	} while (cntr < 250);
    
    	if (cntr >= 250)
    		printf("Auto negotitation failed\n");
    
    	return;
    }
    
    static void cpsw_control(int enabled)
    {
    	/* nothing for now */
    	/* TODO : VTP was here before */
    	return;
    }
    
    static struct cpsw_slave_data cpsw_slaves[] = {
    	{
    		.slave_reg_ofs	= 0x208,
    		.sliver_reg_ofs	= 0xd80,
    		.phy_id		= 0,
    	},
    	{
    		.slave_reg_ofs	= 0x308,
    		.sliver_reg_ofs	= 0xdc0,
    		.phy_id		= 1,
    	},
    };
    
    static struct cpsw_platform_data cpsw_data = {
    	.mdio_base		= AM335X_CPSW_MDIO_BASE,
    	.cpsw_base		= AM335X_CPSW_BASE,
    	.mdio_div		= 0xff,
    	.channels		= 8,
    	.cpdma_reg_ofs		= 0x800,
    	.slaves			= 2,
    	.slave_data		= cpsw_slaves,
    	.ale_reg_ofs		= 0xd00,
    	.ale_entries		= 1024,
    	.host_port_reg_ofs	= 0x108,
    	.hw_stats_reg_ofs	= 0x900,
    	.mac_control		= (1 << 5) /* MIIEN */,
    	.control		= cpsw_control,
    	.phy_init		= evm_phy_init,
    	.gigabit_en		= 1,
    	.host_port_num		= 0,
    	.version		= CPSW_CTRL_VERSION_2,
    };
    
    int board_eth_init(bd_t *bis)
    {
    	uint8_t mac_addr[6];
    	uint32_t mac_hi, mac_lo;
    	u_int32_t i;
    
    	if (!eth_getenv_enetaddr("ethaddr", mac_addr)) {
    		debug("<ethaddr> not set. Reading from E-fuse\n");
    		/* try reading mac address from efuse */
    		mac_lo = __raw_readl(MAC_ID0_LO);
    		mac_hi = __raw_readl(MAC_ID0_HI);
    		mac_addr[0] = mac_hi & 0xFF;
    		mac_addr[1] = (mac_hi & 0xFF00) >> 8;
    		mac_addr[2] = (mac_hi & 0xFF0000) >> 16;
    		mac_addr[3] = (mac_hi & 0xFF000000) >> 24;
    		mac_addr[4] = mac_lo & 0xFF;
    		mac_addr[5] = (mac_lo & 0xFF00) >> 8;
    		
    		printd("set MAC addr! \n");
    
    		if (!is_valid_ether_addr(mac_addr)) {
    			debug("Did not find a valid mac address in e-fuse. "
    					"Trying the one present in EEPROM\n");
    
    			for (i = 0; i < ETH_ALEN; i++)
    				mac_addr[i] = header.mac_addr[0][i];
    		}
    
    		if (is_valid_ether_addr(mac_addr))
    			eth_setenv_enetaddr("ethaddr", mac_addr);
    		else {
    			printf("Caution: Using hardcoded mac address. "
    				"Set <ethaddr> variable to overcome this.\n");
    		}
    	}
    
    	
    	/* set gmii1_sel bit to rmii mode and rmii1_io_clk_en bit is set to 1 in gmii_sel register */
    	/* moved to the time before configure_evm_pin_mux() is called to ensure rmii1_refclk is not scrambled	*
    	 *  because otherwise cpu and the outside crystal will output 50MHz ref clk at the same time.		*		
    	 */
    	//__raw_writel(0x41, MAC_MII_SEL);
    
    	/* GP EVM 1.0 (A, B) does not have functional gigabit */
    	if (board_id == GP_BOARD && !strncmp(header.version, "1.0", 3))
    		cpsw_data.gigabit_en = 0;
    
    	return cpsw_register(&cpsw_data);
    }
    #endif
    
    #ifndef CONFIG_SPL_BUILD
    #ifdef CONFIG_GENERIC_MMC
    int board_mmc_init(bd_t *bis)
    {
    	omap_mmc_init(0);
    	return 0;
    }
    #endif
    
    #ifdef CONFIG_NAND_TI81XX
    /******************************************************************************
     * Command to switch between NAND HW and SW ecc
     *****************************************************************************/
    extern void ti81xx_nand_switch_ecc(nand_ecc_modes_t hardware, int32_t mode);
    int do_switch_ecc(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
    {
    	int type = 0;
    	if (argc < 2)
    		goto usage;
    
    	if (strncmp(argv[1], "hw", 2) == 0) {
    		if (argc == 3)
    			type = simple_strtoul(argv[2], NULL, 10);
    		ti81xx_nand_switch_ecc(NAND_ECC_HW, type);
    	}
    	else if (strncmp(argv[1], "sw", 2) == 0)
    		ti81xx_nand_switch_ecc(NAND_ECC_SOFT, 0);
    	else
    		goto usage;
    
    	return 0;
    
    usage:
    	printf("Usage: nandecc %s\n", cmdtp->usage);
    	return 1;
    }
    
    U_BOOT_CMD(
    	nandecc, 3, 1,	do_switch_ecc,
    	"Switch NAND ECC calculation algorithm b/w hardware and software",
    	"[sw|hw <hw_type>] \n"
    	"   [sw|hw]- Switch b/w hardware(hw) & software(sw) ecc algorithm\n"
    	"   hw_type- 0 for Hamming code\n"
    	"            1 for bch4\n"
    	"            2 for bch8\n"
    	"            3 for bch16\n"
    );
    
    #endif /* CONFIG_NAND_TI81XX */
    #endif /* CONFIG_SPL_BUILD */
    

    AM335x_DDR_register_calc_tool-0224.xls

    3731.RatioSeed_AM335x_boards.xls

    thanks

    semiyd

  • In your ddr_defs.h:

    • DLL_LOCK_DIFF should be set to 4 not 1.  This is one of many issues in old versions of u-boot.
    • Your SDCFG currently specifies a CAS latency of 5.  According to the DRAM data sheet, you should be using CAS=6.  So in other words, change 0x62C04B32 to 0x62C05332.
    • EMIF_READ_LATENCY should be 7.  Note you are not configuring a critical field in this register.  Specifically, you are not enabling ODT.  You're also not enabling the power-down bit.  I recommend programming this register as 0x0010027.


    You'll need to re-run software leveling with this configuration.  I think that should get you back to a point where you're stable.

  • Hi Brad:

         thanks a lot for the information!

         I installed CCS 6 in my windows computer and we have a JLink jtag v9.  but when i try to setup the software leveling environment.The "test connection" button in CCS6 is grey and i can't click on it.So I'm stuck here considering software leveling.

         I changed the value according to your suggestion.DLL_LOCK_DIFF to 4.SDRAM_CONFIG to 0x62C05332 and EMIF_READ_LATENCY  to 0x0010027.

         with our own TIM setting and PHY setting....the cpu hangs and boot did not start successfully.

         I tried this on my old working DDR that has been used for sometime.(the original uboot code we use do not include ddr driver parameter and it hide them into some kind of library).

         We actually can boot the old working DDR with a strange set of PHY register values that i grabbed from online.

         I'm attaching the current ddr_defs.h that's not working:

        ddr_defs_bad.h

      and the PHY register excel chart we used:

    6837.RatioSeed_AM335x_boards.xls

       And below is the working one (on old ddr K4B2G0846D-HCH9) with strange large WR DQS value grabbed from some internet blog:

    ddr_defs_working.h

        We actually have a new DDR(K4B2G0846Q-BCK0) but it never worked however the combination of TIM+PHY setting is.

       attaching the old ddr spec:

    K4B2G0846D-HCH9.pdf

    thanks again for the help!

    semiyd

  • Hi

       About the software leveling.

      I refered to the steps mentioned in processors.wiki.ti.com/index.php/Sitara_Linux_Training:_Tuning_the_DDR3_Timings_on_BeagleBoneBlack

      I tried to install CCS 6 today and configureed my JLink jtag debugger in ccxml.

      I skipped the "test connection" step.Cause the button is grey and i guess jlink don't support this operation.

      then when I locate my new Target Configuration file, right click it and select Launch Selected Configuration

      it shows that I'm not licensed...?

      

     can you help?

      I used to think that maybe i should get myself a "Blackhawk XDS560v2-USB System Trace Emulator"

      but this pop-up window says that XDS560 is restricted as well?>

     thanks

    semiyd

  • The timings I mentioned were specifically for the K4B2G0846Q-BCK0.

    With respect to your CCS issue, that's the error you would see when you have not purchased CCS. Please purchase CCS.

    Also, here is the wiki page that I generally use for software leveling:

    processors.wiki.ti.com/.../AM335x_DDR_PHY_register_configuration_for_DDR3_using_Software_Leveling

  • Hi

       Yes I tried to run on K4B2G0846Q-BCK0 and on K4B2G0846D-HCH9.

       The phenomenon is like before.K4B2G0846Q-BCK0 don't start and K4B2G0846D-HCH9 can start only with the PHY setting with that large WR DQS value.

       i will need to buy the license in this case.Got it.

    thanks

    semmiyd

  • Another option is to use a xds100v2 debugger. It works with a free license of CCS. That's actually cheaper than a CCS license if you only need it for leveling.

  • thanks for the tip!
  • Hi Geoffrey 

          Can you tell me your value of DDR3_WR_DQS in the real uboot code?

          I know that in the RatioSeed_AM335x_boards.xls of yours the Micron chip.It is 0.

          I just want to confirm if it's also 0 in the real uboot code.

    thanks

    semiyd

  • Do you mean what is in the ddr_defs.h file?   Here is what I have there:

    /* Micron MT41J128M16JT-125 at 400MHz*/
    #define MT41J128MJT125_EMIF_READ_LATENCY_400MHz 0x100007
    #define MT41J128MJT125_EMIF_TIM1_400MHz 0x0AAAD4DB
    #define MT41J128MJT125_EMIF_TIM2_400MHz 0x26437FDA
    #define MT41J128MJT125_EMIF_TIM3_400MHz 0x501F83FF
    #define MT41J128MJT125_EMIF_SDCFG_400MHz 0x61C052B2
    #define MT41J128MJT125_EMIF_SDREF_400MHz 0x00000C30
    #define MT41J128MJT125_ZQ_CFG_400MHz 0x50074BE4
    #define MT41J128MJT125_RATIO_400MHz 0x80
    #define MT41J128MJT125_INVERT_CLKOUT_400MHz 0x0
    #define MT41J128MJT125_RD_DQS_400MHz 0x3A
    #define MT41J128MJT125_WR_DQS_400MHz 0x3B
    #define MT41J128MJT125_PHY_WR_DATA_400MHz 0x76
    #define MT41J128MJT125_PHY_FIFO_WE_400MHz 0x96

  • Hi Geoffrey:
    yes.
    i think i at least partially understand now why the WR DQS looks large.
    because WR DQS value calculated in RatioSeed_AM335x_boards.xls was originally small.
    and after software leveling in CCS. WR DQS become a large value.
    So the value calculated from RatioSeed_AM335x_boards.xls can't be put directly into the u-boot code.
    in other words i can't get the correct value of WR DQS without going through the software leveling steps.

    I'm getting a xds100v2 jtag to see if i can work on the software leveling.

    thanks

    semiyd
  • Hi Brad:

          I got the XDS100v2 debugger and finally was able to do the software leveling on my new DDR chip.

          At first I thought our hardware design got a problem. But surprisingly. I was able to do the leveling successfully.

          The result of the leveling is:

    Optimal values have been found!!

    ***************************************************************
    The Slave Ratio Search Program Values are...
    ***************************************************************
    PARAMETER MAX | MIN | OPTIMUM | RANGE
    ***************************************************************
    DATA_PHY_RD_DQS_SLAVE_RATIO 0x06e | 0x007 | 0x03a | 0x067
    DATA_PHY_FIFO_WE_SLAVE_RATIO 0x14f | 0x000 | 0x0a7 | 0x14f
    DATA_PHY_WR_DQS_SLAVE_RATIO 0x087 | 0x02d | 0x05a | 0x05a
    DATA_PHY_WR_DATA_SLAVE_RATIO 0x0c3 | 0x05b | 0x08f | 0x068
    ***************************************************************

          I also tried to used this PHY value generated by leveling to do a EDMA test for the new DDR in the CCS.

         and EDMA test also passed.

          So at this point i'm quite convinced that our hardware design should be no problem. (layout...etc)

          However when i used this leveling value to boot the u-boot. (SD mode boot up)

          it failed. like this:

    Welcome to use TQ3358 Board!
    boot from SD...

    mmc_read_data: timedout waiting for status!
    spl: fat register err - -1
    ### ERROR ### Please RESET the board ###

         Since the hardware got no problem i suppose. Then i thought this could be a SD driver bug in uboot.Right?

         So i tried to boot this u-boot from NAND.

         and this time CPU is dead.

    Welcome to use TQ3358 Board!
    boot from NAND...  

       So till now.I know that the hardware is ok and it's not a SD card driver bug.because nand boot do not go through SD read operation.

       And by accident.I found that adding a small delay after the initialization function of ddr3 will have the board boot successfully.

       Like this: (inside s_init() )

    /* Disable smart idle */
    regVal = __raw_readl((uart_base + UART_SYSCFG_OFFSET));
    regVal |= UART_SMART_IDLE_EN;
    __raw_writel(regVal, (uart_base + UART_SYSCFG_OFFSET));

    /* Initialize the Timer */
    init_timer();

    preloader_console_init();


    config_new_ddr3();
    mdelay(10);//3ms delay at least

    #endif
    }

      so this is really getting very strange here.Although it seems the board is running ok with the delay.

      basically what i can be sure is that the hardware is ok.And some kind of bug inside my u-boot code caused this strange phenomenon.

      I know you mentioned that many bugs are solved in the new u-boot. But since i can't really upgrade the entire u-boot for now.  

      it seems like a work around. but i really don't understand why it works...

    semiyd

  • You may want to verify you're not seeing any droop on vdd_core or vdds_ddr. Gel files are very slow to execute so that might naturally have that kind of delay.

    If there's not any kind of hardware correlation, you would really need to migrate to a newer u-boot before I could invest any further effort.
  • Hi Brad

        I suspect that there is a hardware correlation.Because the same code (without delay) works on my old DDR but not on my new DDR.

        something hardware has changed.But i'm not sure.Maybe it's not a hardware problem but some kind of hardware difference that triggered this bug in u-boot.

       I will check if there's a drop in vdd_core vdd_ddr.

    thanks for the help!

    semiyd

  • Hi Brad:
    just checked the vdd_core and vdd_ddr with oscilloscope. And found not significant drop during the boot up phase...

    semiyd
  • You might also want to check ddr_rst and cke.
  • hi Brad:
    checked .
    both ddr_rst and cke become active after like 72ms the time vdd_ddr is provided.
    and both did not seem any drop during active...