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.

Core PLL Frequencies (TRM page 655)

Other Parts Discussed in Thread: TPS65217, AM3354

Hello,

Can someone please let me know if there is a discrepancy in the TRM for the Core PLL table 655. If one considers the clock_am335x.h, the COREPLL_M is set to 1000 which results into a 2Ghz clock, this matches the datasheet.

But the datasheet value for COREPLL_M6 does not match the definition in the header file. The header file definition seems correct.

Can someone please confirm the same.

Also based on the datasheet, in order for me to allow 275Mhz operation for the MPU I only need to define COREPLL_M to 275. Is that correct? (I"m using the 27 speed grade part on the ZCE so the max frequency for the MPU is 275Mhz)

Thank you for your replies

Regards

Santhosh

  • Santhosh,

    What software package and release are you referencing?

  • Hello Brandon,

    I'm using the SDK 5.05.00.00 and the document version is Revised on June 2012. 

    Regards

    Santhosh

  • Hello Brandon,

    I have another question regarding section 7.3.2.2 EMIF Clock Management, again based on values in the clocks_am335x.h, the max frequency requirements are being exceeded in the EVM.

    For eg: DDR PLL output is 266Mhz and M_CLK is 133MHz (DDR PLL / 2). But the table clearly shows that these values cannot exceed 200Mhz and 100Mhz respectively.

    Can you please confirm/clarify?

    Thank you

    Regards

    Santhosh

  • Santhosh

    Looks like the TRM is incorrect and needs to be corrected. The correct value for COREPLL_M6 is indeed 4.

    To set the processor to 27MHZ you should set the MPUPLL to 275.

      Paul

     

     

  • This is an error in te TRM.

    The maximum frequency for m_clk should be 152MHz

    The maximum frequency for cmdx_dfi_clk and datax_dfi_clk is 303MHz

      Paul

  • Hello Paul,

    Thank you for clarifying it, helps to know I'm not going off to lala land. I'm currently stuck with a different problem and was hoping you could shed some light at it..

    I've a design with AM3354, TPS65217 and mDDR, I've confirmed that the power rails come up clean and sequenced properly. I also have code running where the RBL picks up the SPL from the MMC interface and starts executing code. I've also done the same with CCS and stepped through code.

    The problem is that after printing out the first few lines "U-boot... Texas..." the code takes a long time to initialize the DDR interface and then hangs after printing out the boot device number. I used the grabserial utility and printed out the timestamps of the messages being printed out and also added few debug messages of my own, see below.

    The problem is the writing to the DDR CONFIG register takes a long time.. and I can't understand why?? Please also find attached the modified evm.c file for my board. You can clearly see from the time delays that something is not working properly....I followed the evm.c from TI and the datasheet to set me values, so is there a chance I missed something if the TRM needs to be updated??

    0.00       0    
    0.00       0    U-Boot SPL 2011.09 (Nov 01 2012 - 15:32:17)
    0.00       0    Texas Instruments Revision detection unimplemented
    0.02       1    SR: s_init - i2c enabled
    0.02       0    SR: s_init - entering ddr_pll_config
    0.02       0    SR: s_init - entering config_am335x_ddr2
    0.02       0    SR: config_am335x_ddr2 - mddr clocks enabled
    0.03       0    SR: config_am335x_ddr2 - config_vtp done
    0.03       0    SR: config_am335x_ddr2 - Cmd_Macro_Config_ddr2 done
    0.03       0    SR: config_am335x_ddr2 - Data_Macro_Config_ddr2 done
    0.04       0    SR: config_am335x_ddr2 - DATAx_RANK0_DELAYS_0 written
    0.05       0    SR: config_am335x_ddr2 - DDR_CMDx_IOCTRL and DDR_DATAx_IOCTRL written
    0.05       0    SR: config_am335x_ddr2 - DDR_IO_CTRL and DDR_CKE_CTRL written
    0.06       0    SR: config_am335x_ddr2 - Entering function config_emif_ddr2
    0.06       0    SR: config_emif_ddr2 - EMIF4_0_DDR_PHY_CTRL_x values written
    0.07       0    SR: config_emif_ddr2 - EMIF4_0_SDRAM_TIM_x values written
    61.86    6178    SR: config_emif_ddr2 - EMIF4_0_SDRAM_CONFIG values written
    61.86       0    SR: config_emif_ddr2 - EMIF4_0_SDRAM_REF_CTRL values written
    61.87       0    SR: config_emif_ddr2 - Start delay
    73.31    1144    SR: config_emif_ddr2 - End delay
    73.31       0    SR: config_emif_ddr2 - EMIF4_0_SDRAM_REF_CTRL values written
    118.46    4514    SR: config_emif_ddr2 - EMIF4_0_SDRAM_CONFIG values re-written
    118.46       0    DDR Config done
    118.46       0    >>board_init_f()
    118.47       1    >>spl:board_init_r()
    118.75      27    boot device - 0
    118.75       0    SPL: Un-supported Boot Device - 0!!!
    118.75       0    ### ERROR ### Please RESET the board ###

    Thank you for your replies in advance..I've been stuck on this for over a week and any help would be really appreciated.

    Regards

    Santhosh

    /*
     * 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/gpio.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 <asm/arch/gpio.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 "tps65217.h"
    #include <i2c.h>
    #include <serial.h>
    
    DECLARE_GLOBAL_DATA_PTR;
    
    /* 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
    
    /* DDR defines */
    #define MDDR_SEL_DDR2			0xefffffff			/* IOs set for DDR2-STL Mode */
    #define MDDR_SEL_mDDR			(0x10000000)		/* IOs set for mDDR CMOS Mode */
    #define CKE_NORMAL_OP			(0x00000001)		/* Normal Op:CKE controlled by EMIF */
    #define GATELVL_INIT_MODE_SEL	0x1					/* Selects a starting ratio value based
    													   on DATA0/1_REG_PHY_GATELVL_INIT_RATIO_0
    					        						   value programmed by the user */
    #define WRLVL_INIT_MODE_SEL		0x1	           		/* Selects a starting ratio value based
    													   on DATA0/1_REG_PHY_WRLVL_INIT_RATIO_0
    													   value programmed by the user */
    
    /* RGMII mode define */
    #define RGMII_MODE_ENABLE	0xA
    #define RMII_MODE_ENABLE	0x5
    #define MII_MODE_ENABLE		0x0
    
    /* RTC Definitions */
    #define RTC_KICK0_REG	0x6c
    #define RTC_KICK1_REG	0x70
    #define RTC_OSC_REG		0x54
    
    
    /* GPIO base address table */
    static const struct gpio_bank gpio_bank_am335x[4] = {
    	{ (void *)AM335X_GPIO0_BASE, METHOD_GPIO_24XX },
    	{ (void *)AM335X_GPIO1_BASE, METHOD_GPIO_24XX },
    	{ (void *)AM335X_GPIO2_BASE, METHOD_GPIO_24XX },
    	{ (void *)AM335X_GPIO3_BASE, METHOD_GPIO_24XX },
    };
    const struct gpio_bank *const omap_gpio_bank = gpio_bank_am335x;
    
    
    
    /*
     * SR - The following functions are called from board.c in /arch/arm/lib
     * dram_init
     * dram_init_banksize
     */
    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 Data_Macro_Config_ddr2(int dataMacroNum)
    {
            u32 BaseAddrOffset = 0x00;;
    
            if (dataMacroNum == 1)
                    BaseAddrOffset = 0xA4;
    
            writel(((DDR2_RD_DQS<<30)|(DDR2_RD_DQS<<20)
                            |(DDR2_RD_DQS<<10)|(DDR2_RD_DQS<<0)),
                            (DATA0_RD_DQS_SLAVE_RATIO_0 + BaseAddrOffset));
            writel(DDR2_RD_DQS>>2, (DATA0_RD_DQS_SLAVE_RATIO_1 + BaseAddrOffset));
    
            writel(((DDR2_WR_DQS<<30)|(DDR2_WR_DQS<<20)
                            |(DDR2_WR_DQS<<10)|(DDR2_WR_DQS<<0)),
                            (DATA0_WR_DQS_SLAVE_RATIO_0 + BaseAddrOffset));
            writel(DDR2_WR_DQS>>2, (DATA0_WR_DQS_SLAVE_RATIO_1 + BaseAddrOffset));
    
            writel(((DDR2_PHY_WRLVL<<30)|(DDR2_PHY_WRLVL<<20)
                            |(DDR2_PHY_WRLVL<<10)|(DDR2_PHY_WRLVL<<0)),
                            (DATA0_WRLVL_INIT_RATIO_0 + BaseAddrOffset));
            writel(DDR2_PHY_WRLVL>>2, (DATA0_WRLVL_INIT_RATIO_1 + BaseAddrOffset));
    
            writel(((DDR2_PHY_GATELVL<<30)|(DDR2_PHY_GATELVL<<20)
                            |(DDR2_PHY_GATELVL<<10)|(DDR2_PHY_GATELVL<<0)),
                            (DATA0_GATELVL_INIT_RATIO_0 + BaseAddrOffset));
            writel(DDR2_PHY_GATELVL>>2,
                            (DATA0_GATELVL_INIT_RATIO_1 + BaseAddrOffset));
    
            writel(((DDR2_PHY_FIFO_WE<<30)|(DDR2_PHY_FIFO_WE<<20)
                            |(DDR2_PHY_FIFO_WE<<10)|(DDR2_PHY_FIFO_WE<<0)),
                            (DATA0_FIFO_WE_SLAVE_RATIO_0 + BaseAddrOffset));
            writel(DDR2_PHY_FIFO_WE>>2,
                            (DATA0_FIFO_WE_SLAVE_RATIO_1 + BaseAddrOffset));
    
            writel(((DDR2_PHY_WR_DATA<<30)|(DDR2_PHY_WR_DATA<<20)
                            |(DDR2_PHY_WR_DATA<<10)|(DDR2_PHY_WR_DATA<<0)),
                            (DATA0_WR_DATA_SLAVE_RATIO_0 + BaseAddrOffset));
            writel(DDR2_PHY_WR_DATA>>2,
                            (DATA0_WR_DATA_SLAVE_RATIO_1 + BaseAddrOffset));
    
            writel(DDR2_PHY_DLL_LOCK_DIFF,
                            (DATA0_DLL_LOCK_DIFF_0 + BaseAddrOffset));
    }
    
    static void config_vtp(void)
    {
            writel(readl(VTP0_CTRL_REG) | VTP_CTRL_ENABLE, VTP0_CTRL_REG);
            writel(readl(VTP0_CTRL_REG) & (~VTP_CTRL_START_EN), VTP0_CTRL_REG);
            writel(readl(VTP0_CTRL_REG) | VTP_CTRL_START_EN, VTP0_CTRL_REG);
    
            /* Poll for READY */
            while ((readl(VTP0_CTRL_REG) & VTP_CTRL_READY) != VTP_CTRL_READY);
    }
    
    
    static void Cmd_Macro_Config_ddr2(void)
    {
    	writel(DDR2_RATIO, CMD0_CTRL_SLAVE_RATIO_0);
    	writel(DDR2_CMD_FORCE, CMD0_CTRL_SLAVE_FORCE_0);
    	writel(DDR2_CMD_DELAY, CMD0_CTRL_SLAVE_DELAY_0);
    	writel(DDR2_DLL_LOCK_DIFF, CMD0_DLL_LOCK_DIFF_0);
    	writel(DDR2_INVERT_CLKOUT, CMD0_INVERT_CLKOUT_0);
    
    	writel(DDR2_RATIO, CMD1_CTRL_SLAVE_RATIO_0);
    	writel(DDR2_CMD_FORCE, CMD1_CTRL_SLAVE_FORCE_0);
    	writel(DDR2_CMD_DELAY, CMD1_CTRL_SLAVE_DELAY_0);
    	writel(DDR2_DLL_LOCK_DIFF, CMD1_DLL_LOCK_DIFF_0);
    	writel(DDR2_INVERT_CLKOUT, CMD1_INVERT_CLKOUT_0);
    
    	writel(DDR2_RATIO, CMD2_CTRL_SLAVE_RATIO_0);
    	writel(DDR2_CMD_FORCE, CMD2_CTRL_SLAVE_FORCE_0);
    	writel(DDR2_CMD_DELAY, CMD2_CTRL_SLAVE_DELAY_0);
    	writel(DDR2_DLL_LOCK_DIFF, CMD2_DLL_LOCK_DIFF_0);
    	writel(DDR2_INVERT_CLKOUT, CMD2_INVERT_CLKOUT_0);
    }
    
    static void config_emif_ddr2(void)
    {
    	volatile u32 i;
    
    	/*Program EMIF0 CFG Registers*/
    	writel(DDR2_EMIF_READ_LATENCY, EMIF4_0_DDR_PHY_CTRL_1);
    	writel(DDR2_EMIF_READ_LATENCY, EMIF4_0_DDR_PHY_CTRL_1_SHADOW);
    	writel(DDR2_EMIF_READ_LATENCY, EMIF4_0_DDR_PHY_CTRL_2);
    	printf("SR: config_emif_ddr2 - EMIF4_0_DDR_PHY_CTRL_x values written\n");
    
    	writel(DDR2_EMIF_TIM1, EMIF4_0_SDRAM_TIM_1);
    	writel(DDR2_EMIF_TIM1, EMIF4_0_SDRAM_TIM_1_SHADOW);
    	writel(DDR2_EMIF_TIM2, EMIF4_0_SDRAM_TIM_2);
    	writel(DDR2_EMIF_TIM2, EMIF4_0_SDRAM_TIM_2_SHADOW);
    	writel(DDR2_EMIF_TIM3, EMIF4_0_SDRAM_TIM_3);
    	writel(DDR2_EMIF_TIM3, EMIF4_0_SDRAM_TIM_3_SHADOW);
    	printf("SR: config_emif_ddr2 - EMIF4_0_SDRAM_TIM_x values written\n");
    	
    	writel(DDR2_EMIF_SDCFG, EMIF4_0_SDRAM_CONFIG);
    /*	writel(DDR2_EMIF_SDCFG, EMIF4_0_SDRAM_CONFIG2);*/
    	writel(0, EMIF4_0_SDRAM_CONFIG2);
    	printf("SR: config_emif_ddr2 - EMIF4_0_SDRAM_CONFIG values written\n");
    
    	/* writel(DDR2_EMIF_SDMGT, EMIF0_0_SDRAM_MGMT_CTRL);
    	writel(DDR2_EMIF_SDMGT, EMIF0_0_SDRAM_MGMT_CTRL_SHD); */
    	writel(DDR2_EMIF_SDREF1, EMIF4_0_SDRAM_REF_CTRL);
    	writel(DDR2_EMIF_SDREF1, EMIF4_0_SDRAM_REF_CTRL_SHADOW);
    	printf("SR: config_emif_ddr2 - EMIF4_0_SDRAM_REF_CTRL values written\n");
    
    	printf("SR: config_emif_ddr2 - Start delay\n");	
    	for (i = 0; i < 50000000; i++) {
    
    	}	
    	printf("SR: config_emif_ddr2 - End delay\n");
    	/* writel(DDR2_EMIF_SDMGT, EMIF0_0_SDRAM_MGMT_CTRL);
    	writel(DDR2_EMIF_SDMGT, EMIF0_0_SDRAM_MGMT_CTRL_SHD); */
    	writel(DDR2_EMIF_SDREF2, EMIF4_0_SDRAM_REF_CTRL);
    	writel(DDR2_EMIF_SDREF2, EMIF4_0_SDRAM_REF_CTRL_SHADOW);
    	printf("SR: config_emif_ddr2 - EMIF4_0_SDRAM_REF_CTRL values written\n");
    
    	writel(DDR2_EMIF_SDCFG, EMIF4_0_SDRAM_CONFIG);
    /*	writel(DDR2_EMIF_SDCFG, EMIF4_0_SDRAM_CONFIG2);*/
    	writel(0, EMIF4_0_SDRAM_CONFIG2);
    	printf("SR: config_emif_ddr2 - EMIF4_0_SDRAM_CONFIG values re-written\nDDR Config done\n");
    }
    
    static void config_am335x_ddr2(void)
    {
    	int data_macro_0 = 0;
    	int data_macro_1 = 1;
    
    	enable_mddr_clocks();					/* SR - defined in the pll.c, sets up the pll for the mDDR */
    	printf("SR: config_am335x_ddr2 - mddr clocks enabled\n");
    	
    	config_vtp();							/* SR - defined in the evm.c, leave as is */
    	printf("SR: config_am335x_ddr2 - config_vtp done\n");
    	
    	Cmd_Macro_Config_ddr2();				/* SR - defined in the evm.c, leave as is */		
    	printf("SR: config_am335x_ddr2 - Cmd_Macro_Config_ddr2 done\n");
    	
    	Data_Macro_Config_ddr2(data_macro_0);	/* SR - defined in the evm.c, leave as is */
    	Data_Macro_Config_ddr2(data_macro_1);
    	printf("SR: config_am335x_ddr2 - Data_Macro_Config_ddr2 done\n");
    	
    	writel(DDR2_PHY_RANK0_DELAY, DATA0_RANK0_DELAYS_0);
    	writel(DDR2_PHY_RANK0_DELAY, DATA1_RANK0_DELAYS_0);
    	printf("SR: config_am335x_ddr2 - DATAx_RANK0_DELAYS_0 written\n");
    	
    	writel(DDR2_IOCTRL_VALUE, DDR_CMD0_IOCTRL);
    	writel(DDR2_IOCTRL_VALUE, DDR_CMD1_IOCTRL);
    	writel(DDR2_IOCTRL_VALUE, DDR_CMD2_IOCTRL);
    	writel(DDR2_IOCTRL_VALUE, DDR_DATA0_IOCTRL);
    	writel(DDR2_IOCTRL_VALUE, DDR_DATA1_IOCTRL);
    	printf("SR: config_am335x_ddr2 - DDR_CMDx_IOCTRL and DDR_DATAx_IOCTRL written\n");
    	
    	writel((readl(DDR_IO_CTRL) | MDDR_SEL_mDDR), DDR_IO_CTRL);	/* SR- Modified for mDDR */
    	writel((readl(DDR_CKE_CTRL) | CKE_NORMAL_OP), DDR_CKE_CTRL);
    	printf("SR: config_am335x_ddr2 - DDR_IO_CTRL and DDR_CKE_CTRL written\n");
    	
    	printf("SR: config_am335x_ddr2 - Entering function config_emif_ddr2\n");			
    	config_emif_ddr2();
    }
    
    static void init_timer(void)
    {
    	/* Reset the Timer */
    	writel(0x2, (DM_TIMER2_BASE + TSICR_REG));
    
    	/* Wait until the reset is done */
    	while (readl(DM_TIMER2_BASE + TIOCP_CFG_REG) & 1);
    
    	/* Start the Timer */
    	writel(0x1, (DM_TIMER2_BASE + TCLR_REG));
    }
    
    
    
    static void rtc32k_enable(void)
    {
    	/* Unlock the rtc's registers */
    	writel(0x83e70b13, (AM335X_RTC_BASE + RTC_KICK0_REG));
    	writel(0x95a4f1e0, (AM335X_RTC_BASE + RTC_KICK1_REG));
    
    	/* Enable the RTC 32K OSC */
    	writel(0x48, (AM335X_RTC_BASE + RTC_OSC_REG));
    }
    #endif
    
    
    /*
     * CONFIG_SPL_BUILD - defined in the Makefile for SPL
     * CONFIG_SPL_BOARD_INIT - defined in the rp_am335x.h file (include/configs/)
     */
    #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;
    }
    
    
    /*
     * Called from board_init_r (found in arch/arm/cpu/armv7/omap-common/spl.c)
     */
    void spl_board_init(void)
    {
    	uchar pmic_status_reg;
    #ifdef DEBUG
    	uchar pmic_voltage_reg[5];
    	int RetVal = 0;
    #endif
    
    	/* init board_id, configure muxes */
    	board_init();
    
    	/* TPS65217 PMIC Code */
    	if (i2c_probe(TPS65217_CHIP_PM))
    		return;
    
    	if (tps65217_reg_read(STATUS, &pmic_status_reg))
    		return;
    
    	/* Disable the USB supply input */
    	if (tps65217_reg_write( PROT_LEVEL_NONE,
    							POWER_PATH,
    							USB_INPUT_DISABLE,
    							USB_INPUT_ENABLE_MASK))
    	{
    		printf("tps65217_reg_write failure\n");
    	}
    	
    #if 0
    	/* Read the PMIC voltage outputs - the defaults should be good */
    	RetVal = tps65217_reg_read(DEFDCDC1, &pmic_voltage_reg[0]); 
    	RetVal = tps65217_reg_read(DEFDCDC2, &pmic_voltage_reg[1]);
    	RetVal = tps65217_reg_read(DEFDCDC3, &pmic_voltage_reg[2]);
    	RetVal = tps65217_reg_read(DEFLDO1, &pmic_voltage_reg[3]);
    	RetVal = tps65217_reg_read(DEFLDO2, &pmic_voltage_reg[4]);
    	if(RetVal != 0)
    	{
    		printf("TPS65217 voltage read failure...may God bless you!!!\n");
    		return;
    	}
    	else	/* We were able to read the registers */
    	{
    		if(	(pmic_voltage_reg[0] == DCDC_VOLT_SEL_1800MV) &&
    			(pmic_voltage_reg[1] == DCDC_VOLT_SEL_3300MV) &&
    			(pmic_voltage_reg[2] == DCDC_VOLT_SEL_1100MV) &&
    			(pmic_voltage_reg[3] == LDO_VOLT_SEL_1800MV) &&
    			(pmic_voltage_reg[4] == LDO_VOLT_SEL_3300MV) )
    		{
    			printf("TPS65217 DCDC1 - 1.8V\n");
    			printf("TPS65217 DCDC2 - 3.3V\n");
    			printf("TPS65217 DCDC3 - 1.1V\n");
    
    			printf("TPS65217 LDO1 - 1.8V\n");
    			printf("TPS65217 LDO2 - 3.3V\n");
    		}
    		else
    		{
    			printf("DEFDCDC1 - 0x%02X\n", pmic_voltage_reg[0]);
    			printf("DEFDCDC2 - 0x%02X\n", pmic_voltage_reg[1]);
    			printf("DEFDCDC3 - 0x%02X\n", pmic_voltage_reg[2]);
    			printf("DEFLDO1 - 0x%02X\n", pmic_voltage_reg[3]);
    			printf("DEFLDO2 - 0x%02X\n", pmic_voltage_reg[4]);
    		}
    	}
    #endif
    
    	/* Disable LDO3, LDO4 output */
    	if (tps65217_reg_write(	PROT_LEVEL_1,			
    							ENABLE,					
    			       			LDO_3_4_DISABLE,
    							LDO_3_4_ENABLE_MASK))
    	{
    		printf("tps65217_reg_write failure\n");
    	}
    
    
    	if (!(pmic_status_reg & PWR_SRC_AC_BITMASK))
    	{
    		printf("No AC power, disabling frequency switch\n");
    		return;
    	}
     
    }
    #endif
    
    
    /*
     * early system init of muxing and clocks.
     */
    
    /*
     Called from lowlevel_init.S - 
    */
    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
    	 */
    	writel(0xAAAA, WDT_WSPR);
    	while(readl(WDT_WWPS) != 0x0);
    	writel(0x5555, WDT_WSPR);
    	while(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;
    	
    	enable_uart0_pin_mux();
    	
    	regVal = readl(UART0_BASE + UART_SYSCFG_OFFSET);
    	regVal |= UART_RESET;
    	writel(regVal, (UART0_BASE + UART_SYSCFG_OFFSET) );
    	while ((readl(UART0_BASE + UART_SYSSTS_OFFSET) &
    			UART_CLK_RUNNING_MASK) != UART_CLK_RUNNING_MASK);
    
    	/* Disable smart idle */
    	regVal = readl((UART0_BASE + UART_SYSCFG_OFFSET));
    	regVal |= UART_SMART_IDLE_EN;
    	writel(regVal, (UART0_BASE + UART_SYSCFG_OFFSET));
    
    	/* Initialize the Timer */
    	init_timer();
    	
    	/* Initialize the UART console - implemented in spl.c */
    	preloader_console_init();
    	
    	/* Enable the I2C peripheral to talk to the PMIC */
    	enable_i2c0_pin_mux();
    	i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
    	printf("SR: s_init - i2c enabled\n");
    
    	/* Configure the mDDR interface for 166Mhz operation (<Max for OPP-100) */
    	printf("SR: s_init - entering ddr_pll_config\n");
    	ddr_pll_config(DDRPLL_M);
    	printf("SR: s_init - entering config_am335x_ddr2\n");
    	config_am335x_ddr2();
    
    #endif
    }
    
    
    /*
     * This function is called from board_init_r implemented in 
     * arch/arm/lib/board.c		or
     * arch/arm/cpu/armv7/omap-common/spl.c
     */
    int board_init(void)
    {
    	/* Configure the i2c0 pin mux */
    	enable_i2c0_pin_mux();
    	i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
    	
    	/* Configure this for the 2nd time */
    	enable_uart0_pin_mux();
    	
    	enable_nand_pin_mux();
    
    	enable_mmc0_pin_mux();
    
    	enable_mii1_pin_mux();	
    	
    /*
     * Basic board specific setup
     */
    #ifndef CONFIG_SPL_BUILD
    	/* mach type passed to kernel */
    	gd->bd->bi_arch_number = MACH_TYPE_TIAM335EVM;
    
    	/* address of boot parameters */
    	gd->bd->bi_boot_params = PHYS_DRAM_1 + 0x100;
    #endif
    
    #ifdef CONFIG_NAND
    	gpmc_init();
    #endif
    
    	return 0;
    }
    
    
    
    /*
     * This function is called from board_init_r implemented in arch/arm/lib/board.c
     */
    int misc_init_r(void)
    {
    #ifdef DEBUG
    	debug("Aprilaire - Connect II (Debug Messages)\n");
    #endif
    	return 0;
    }
    
    
    
    /*
     * This function is passed as a function pointer parameter which is called 
     * from somewhere (SR-TODO need to find out how and where this is called from...)
     */
    #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;
    	
    	/*
    	 * 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);
    
    	/*
    	 * 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);
    	}
    
    	/* 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 for port %d\n", addr);
    
    	return;
    }
    
    static void cpsw_control(int enabled)
    {
    	/* nothing for now */
    	/* TODO : VTP was here before */
    	return;
    }
    
    static struct cpsw_slave_data cpsw_slaves[] = {	/* SR - We only have one port and it's id is 1 */
    	{
    		.slave_reg_ofs	= 0x208,
    		.sliver_reg_ofs	= 0xd80,
    		.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				= 1,					/* Only one slave */
    	.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			= 0,					/* No gigabit ethernet */
    	.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 = readl(MAC_ID0_LO);
    		mac_hi = 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;
    
    		if (!is_valid_ether_addr(mac_addr))
    		{
    			debug("Did not find a valid mac address in e-fuse. "
    				  "Using the test one...B4-82-55-00-00-01 \n");
    
    			mac_addr[0] = 0xB4;
    			mac_addr[1] = 0x82;
    			mac_addr[2] = 0x55;
    			mac_addr[3] = 0x00;
    			mac_addr[4] = 0x00;
    			mac_addr[5] = 0x01;
    		}
    
    		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");
    		}
    	}
    	
    	/* Enable MII mode */
    	writel(MII_MODE_ENABLE, MAC_MII_SEL);
    
    	return cpsw_register(&cpsw_data);
    }
    #endif /* CONFIG_DRIVER_TI_CPSW */
    
    
    /*
     * If SPL is not used then use this function, else spl_mmc.c has a function to
     * initialize omap_mmc_init(x) - where x depends on which MMC interface is used
     */
    #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);
    static 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 */
    

  • I have the board working...I had to reduce the DDR clock frequency down to 166Mhz and then it works. But there is still the same problem of a significant delay during the DDR initialization. I'm pasting the printout of the timestamps and the messages printed...


    0.00       0    U-Boot SPL 2011.09 (Nov 02 2012 - 14:44:46)
    0.00       0    Texas Instruments Revision detection unimplemented
    0.02       1    SR: s_init - i2c enabled
    0.02       0    SR: s_init - entering ddr_pll_config
    0.02       0    SR: s_init - entering config_am335x_ddr2
    0.02       0    SR: config_am335x_ddr2 - mddr clocks enabled
    0.03       0    SR: config_am335x_ddr2 - config_vtp done
    0.03       0    SR: config_am335x_ddr2 - Cmd_Macro_Config_ddr2 done
    0.03       0    SR: config_am335x_ddr2 - Data_Macro_Config_ddr2 done
    0.04       0    SR: config_am335x_ddr2 - DATAx_RANK0_DELAYS_0 written
    0.04       0    SR: config_am335x_ddr2 - DDR_CMDx_IOCTRL and DDR_DATAx_IOCTRL written
    0.05       0    SR: config_am335x_ddr2 - DDR_IO_CTRL and DDR_CKE_CTRL written
    0.06       0    SR: config_am335x_ddr2 - Entering function config_emif_ddr2
    0.06       0    SR: config_emif_ddr2 - EMIF4_0_DDR_PHY_CTRL_x values written
    0.06       0    SR: config_emif_ddr2 - EMIF4_0_SDRAM_TIM_x values written
    0.07       0   
    0.07       0    SR: config_emif_ddr2 - EMIF4_0_SDRAM_CONFIG-1
    71.52    7144    SR: config_emif_ddr2 - EMIF4_0_SDRAM_CONFIG-2
    71.52       0   
    71.52       0    SR: config_emif_ddr2 - EMIF4_0_SDRAM_REF_CTRL values written
    71.53       0    SR: config_emif_ddr2 - Start delay
    71.53       0    SR: config_emif_ddr2 - End delay
    71.53       0    SR: config_emif_ddr2 - EMIF4_0_SDRAM_REF_CTRL values written
    71.54       0   
    71.54       0    SR: config_emif_ddr2 - EMIF4_0_SDRAM_CONFIG-1
    236.31    16477    SR: config_emif_ddr2 - EMIF4_0_SDRAM_CONFIG-2
    236.31       0   
    236.59      27    OMAP SD/MMC: 0
    236.66       7    reading u-boot.img
    236.66       0    reading u-boot.img
    236.69       2   
    236.69       0   
    236.69       0    U-Boot 2011.09 (Nov 02 2012 - 14:44:46)
    236.70       0   
    236.70       0    I2C:   ready
    236.74       4    DRAM:  256 MiB
    236.77       2    WARNING: Caches not enabled
    236.86       8    MMC:   OMAP SD/MMC: 0
    236.86       0    Using default environment
    236.86       0   
    236.91       5    Hit any key to stop autoboot:  0
    239.99     308    SD/MMC found on device 0
    240.00       0    reading uEnv.txt
    240.00       0   
    240.00       0    ** Unable to read "uEnv.txt" from mmc 0:1 **
    240.01       0    reading uImage
    240.02       0   
    240.02       0    ** Unable to read "uImage" from mmc 0:1 **
    240.02       0    Booting from nand ...
    240.03       1    Unknown command 'nandecc' - try 'help'
    240.04       0    Unknown command 'nand' - try 'help'
    240.04       0    Wrong Image Format for bootm command
    240.05       0    ERROR: can't get kernel image!
    240.05       0    U-Boot#

    You will notice the times in bold are the ones for DDR Config... and these times are random...they are not consistent.

    Any thoughts on this??
    Thank you
    Regards
    Santhosh
  • What value are you programming into SDRAM_CONFIG?  The huge delay happens after writing to that register, so it would seem something is not correct in the value being written.  I've not seen this huge delay before.

  • Hello Brad,

    Thank you for your reply, the value I'm programming into the CONFIG register is 0x20004EA2, this corresponds to,

    1. mDDR

    2. Single ended DQS

    3. Full drive strength (I've tried it with half drive strength and the results are the same)

    4. CAS latency of 3

    5. Row Size =14

    6. Column Size =10

    7. 4 Banks

    Please find attached the DDR definitions file, hope this helps a little more.

    Thank you

    Santhosh

    Regards0216.ddr_defs.h

  • Thanks -- I don't see anything obviously wrong there!  Let's try another approach (and this might solve your 200 MHz issue too).

    A new gel file was uploaded today which shows the programming of the mDDR:

    http://processors.wiki.ti.com/index.php/File:AM335x_13x13_EVM_v1_0.zip

    Please grab that latest version and let's try using it with your board.  When you connect to the target through CCS the OnTargetConnect function runs which then calls a few subroutines that configure all the PLLs and the DDR interface.  You'll need to make a few tweaks to the configuration to account for your different DDR.

    I think it will be easier to get the gel file working with your board first.  That will then give you a known good starting point to figure out what's going wrong in u-boot SPL.

  • Guys, we also recently updated the DDR PHY configuration recommendations:  Please see the "DDR PHY Registers for DDR2 and LPDDR" section of this wiki:

    http://processors.wiki.ti.com/index.php/AM335x_EMIF_Configuration_tips

    The Ratio Seed spreadsheet has also been updated with more optimized values for both LPDDR and DDR2, so be sure to get the latest spreadsheet.

    Regards,

    James

  • Hello Brad, James,

    Thank you for your replies, I have did follow the gel file and modified it to my board and yes it comes up clean every time no delays. However, on multiple occasions I did see the following message in the CCS window

    CortxA8: Trouble Reading Memory Block at 0x4c000004 on Page 0 of Length 0x4: Error 0x80000002/-1205 Fatal Error during: Memory,  The memory bus has encountered a 'ready-hang' condition.

    The Ratioseed file was very useful, I didn't have this file I had the old one. I will update my code and check to see if there are any improvements. Also I noticed that the Gel file uses less steps than the evm.c file. I does not perform multiple writes with delay in between.

    Thanks a lot, I will post my finds in sometime.

    Regards

    Santhosh


  • Hello James, Brad,

    I updated my evm.c and there is some improvement...

    1. The same error, as was observed in the GEL file still exists...sometimes the read of the status registers doesn't complete.

    2. The delay has reduced, it;s now anywhere between 3-10 secs.. sometimes more...in the limited tests that I have done so far.

    3. Please find attached my Ratio seed file and the timing file for reference.

    I'm still curious as to why the status read fails sometimes. Is there something else that you guys would like me to try.

    Thank you once again for your replies.

    Regards

    Santhosh6305.RatioSeed_AM335x_166Mhz.xls4604.AM335x_DDR_register_166Mhz.xls

  • Hello Brad, James,

    I continued testing with the mDDR and here is what I have as the latest...the delay now seems to come primarily from the relocated code. I removed all the DDR printf statements except one at the very end and added printfs in board_init_f and board_init_r.

    I'm running the code form CCS hence the Un-supported boot device...I'm also listing the location of where the printfs are inserted.

    0.00       0    U-Boot SPL 2011.09 (Nov 07 2012 - 10:43:59)
    0.00       0    Texas Instruments Revision detection unimplemented
    0.01       0    SR: DDR Init done!!!
    0.01       0    SR: Entered board_init_f
    6.26     625    SR: Entered board_init_r
    6.54      27    SPL: Un-supported Boot Device - 88!!!
    6.54       0    ### ERROR ### Please RESET the board ###


    evm.c - in the function s_init

    config_am335x_ddr2();
    printf("SR: DDR Init done!!!\n");

    spl.c - in the function board_init_f

    printf("SR: Entered board_init_f\n");
    relocate_code(CONFIG_SPL_STACK, &gdata, CONFIG_SPL_TEXT_BASE);

    spl.c - in the function board_init_r

    printf("SR: Entered board_init_r\n");
    mem_malloc_init(CONFIG_SYS_SPL_MALLOC_START, CONFIG_SYS_SPL_MALLOC_SIZE);

    Please do let me know if you guys have any thoughts on this...I still think that my mDDR timings/configurations are not correct despite the fact that U-boot comes up correctly every time. The reason I say this.. is when U-boot SPL starts out.. there is a warning indicating that caches are not enabled, this is the same for evm as well. But when it prints the message is prints out "WARNING: Cabhes not enabled". This kinda tells me something is not right in RAM...this is my guess..please feel free to correct me :)

    Thank you

    Regards

    Santhosh

  • Santhosh, i'm a little confused on the issue.  Earlier you stated that you changed everything based on the GEL file and everything works fine with no issues, then somehow the delay got back into your code.  If you are running code from CCS you should be able to debug and figure out where the delay is.  I don't think it is a mDDR timing issue at this point, because that would lead to code crashes, not really the delays you are seeing. 

    Regards,

    James

  • Santhosh Ramani said:
    But when it prints the message is prints out "WARNING: Cabhes not enabled". This kinda tells me something is not right in RAM...this is my guess..please feel free to correct me :)

    That could just as easily be a UART issue.

     

    Santhosh Ramani said:

    I'm running the code form CCS hence the Un-supported boot device...I'm also listing the location of where the printfs are inserted.

    0.00       0    U-Boot SPL 2011.09 (Nov 07 2012 - 10:43:59) 0.00       0    Texas Instruments Revision detection unimplemented 0.01       0    SR: DDR Init done!!! 0.01       0    SR: Entered board_init_f 6.26     625    SR: Entered board_init_r 6.54      27    SPL: Un-supported Boot Device - 88!!! 6.54       0    ### ERROR ### Please RESET the board ###

    I had a quick look in the code.  It looks to me like there is nothing in the functions you mentioned aside from the relocate_code() function.  That seems really slow.  Typically if something is multiple orders of magnitude slower than I expect it's often due to the cache being turned off.  Can you see if the instruction cache is on?  In CCS I think there is a window called "ARM Advanced Features" (under the Tools menu?).  I believe it allows you to see quickly the state of the I-cache, D-cache, and MMU.  If it's off you can check the box to enable it (as a quick test).

  • Hello Brad,

    Thank you for your replies, the ARM Advanced Features shows that the instruction cache is enabled, when the code execution starts, please see screen shot attached.

    The MMU and Data Cache is not enabled, I can understand why the MMU is not required but I'm not sure about Data cache.

    James:

    Sorry about the confusion, I should have clarified it better. I followed the setup of the GEL file and using the new RatioSeed file and timing files from TI I modified my configurations and PHY register values. After that, the DDR initialization was never delayed, however, the delay now seems to almost always come after the relocate code.

    Are there any other tests hardware or software that I can run in order to provide more clues to this problem?

    Thank you so much for your patience.

    Regards

    Santhosh

  • Hi Santhosh, if the delay is several seconds, you should be able to break the code execution in CCS and see where in the code you are.  There must be some kind of bug in the relocation code.  Another thing to check is if the relocation is messing around with your PLLs.  Are the PLLs still locked and running at the frequencies set by the GEL?

    REgards,

    James

  • Hello James,

    I was able to break at relocate code in CCS but then I couldn't step through or but a breakpoint in start.S. Also when I try and stop while the delay is in progress CSS gives me an error

    But if I hit cancel it continues and finishes execution. I will check the PLL frequencies shortly and reply back to this post.

    Thank you once again.

    Regards

    Santhosh

  • Hello james, Brad,

    I did look at the DDR clock while the relocate function is executed and the clock frequency does not change.

    I'm not thoroughly confused and the reason behind it is this...

    I was running the DDR clock at 200Mhz, but my timing registers were set for 166Mhz. With this I was getting decent results, average wait time of 15 sec..compared to the 200+. With this setup I have tested the Ethernet interface and the USB interface on my board - I patched USB support for U-boot.

    But when I changed the frequency to 166Mhz to match the timing register values the delay increased back to 200ish secs. I did the same test with 200Mhz, I entered all the timing register values for 200 and the delay is similar.

    I also looked the GEL file I downloaded from TI's website, the register values are set for 166Mhz operation but the DDR PLL is set for 200Mhz. Am I missing something??

    Sorry I'm not able to provide more details..I'll continue testing and report back.

    Thank you

    Regards

    Santhosh

  • Hi Santhosh, it is strange that you can't break the code with CCS during the long delay.  During this time, can you see clocks running (probing XTALIN to make sure the oscillator is still running, and/or CLKOUT1 or CLKOUT2)?  To see CLKOUT1, set SYSBOOT[5]=1.  You should see your system clock frequency.  To see CLKOUT2, it takes some setup.  The GEL file will have examples of how to output different clocks on CLKOUT2.

    Also during the long delay, does everything else look normal?  All power still at the correct levels, no resets are asserted, power consumption is normal? 

    I need to double check the GEL.  I may have changed to 200MHz DDR clock but didn't change the DDR AC timings.  At any rate, you should be able to set your AC timings using the spreadsheet for either 166 or 200.  i can't explain why you are getting drastically different results when you change between these 2 frequencies.

      Regards,

    James

  • Hello James,

    Thank you for your replies, I have a really weird update for you...but first, yes during the delay all the clocks are fine and the power consumption and levels are also the same.

    Here is the weird update...

    I have placed 2 pin jumpers on all the voltage lines going to the processor and peripherals in order to measure power consumption accurately. While checking the power consumption level as per your last suggestion, I connected the Multimeter in series Ampere mode... and when I started measuring the VDD_CORE - there were no longer any delays.

    I removed the DMM from the circuit, used the lead wires and shorted the lead wires together...it works every single time without any delay. But if I short the jumper with a shunt the delay is back. I'm guessing that there is a deeper hardware issue, I don't know exactly what, but it is bizzare that it should come up every single time without any delay.

    Any thoughts, ideas?? How can I send you the schematic so that you are able to see what I'm talking about?

    Thank you once again,

    Regards

    Santhosh

  • Final update for the week...

    I've tried it with both 166Mhz and 200Mhz, consistent results with 200Mhz being faster than 166Mhz..please see printouts below..

    49.20    3953    U-Boot SPL 2011.09 (Nov 09 2012 - 18:15:37)
    0.00    -4919    Texas Instruments Revision detection unimplemented
    0.01       0    SR: DDR Init done!!!
    0.01       0    SR: Entered board_init_f
    0.02       1    SR: Entered board_init_r
    0.30      27    OMAP SD/MMC: 0
    0.37       7    reading u-boot.img
    0.38       0    reading u-boot.img
    0.43       5    
    0.43       0    
    0.43       0    U-Boot 2011.09 (Nov 09 2012 - 18:15:37)
    0.43       0    
    0.43       0    I2C:   ready
    0.48       5    DRAM:  256 MiB
    0.52       3    WARNING: Caches not enabled
    0.60       8    NAND:  HW ECC Hamming Code selected
    0.61       0    256 MiB
    0.61       0    MMC:   OMAP SD/MMC: 0
    0.61       0    Using default environment
    0.61       0    
    0.67       5    Net:   cpsw
    0.67       0    Hit any key to stop autoboot:  0
    3.75     307    SD/MMC found on device 0
    3.76       0    reading uEnv.txt
    3.76       0    
    3.76       0    ** Unable to read "uEnv.txt" from mmc 0:1 **
    3.77       0    reading uImage
    3.77       0    
    3.77       0    ** Unable to read "uImage" from mmc 0:1 **
    3.78       0    Booting from nand ...
    3.78       0    HW ECC BCH8 Selected
    3.79       0    
    3.79       0    NAND read: device 0 offset 0x280000, size 0x500000
    9.65     585     5242880 bytes read: OK
    9.66       0    Wrong Image Format for bootm command
    9.66       0    ERROR: can't get kernel image!
    9.66       0    U-Boot#

    14.54     461    U-Boot SPL 2011.09 (Nov 09 2012 - 17:54:38)
    0.00    -1453    Texas Instruments Revision detection unimplemented
    0.02       1    SR: DDR Init done!!!
    0.02       0    SR: Entered board_init_f
    0.03       1    SR: Entered board_init_r
    0.30      27    OMAP SD/MMC: 0
    0.37       7    reading u-boot.img
    0.37       0    reading u-boot.img
    0.43       5    
    0.43       0    
    0.43       0    U-Boot 2011.09 (Nov 09 2012 - 17:54:38)
    0.43       0    
    0.43       0    I2C:   ready
    0.48       5    DRAM:  256 MiB
    0.52       3    WARNING: Caches not enabled
    0.61       8    NAND:  HW ECC Hamming Code selected
    0.62       0    256 MiB
    0.62       0    MMC:   OMAP SD/MMC: 0
    0.62       0    Using default environment
    0.62       0    
    0.67       5    Net:   cpsw
    0.68       0    Hit any key to stop autoboot:  0
    3.75     307    SD/MMC found on device 0
    3.76       0    reading uEnv.txt
    3.76       0    
    3.76       0    ** Unable to read "uEnv.txt" from mmc 0:1 **
    3.77       0    reading uImage
    3.78       0    
    3.78       0    ** Unable to read "uImage" from mmc 0:1 **
    3.78       0    Booting from nand ...
    3.79       1    HW ECC BCH8 Selected
    3.80       0    
    3.80       0    NAND read: device 0 offset 0x280000, size 0x500000
    9.91     611     5242880 bytes read: OK
    9.92       0    Wrong Image Format for bootm command
    9.92       0    ERROR: can't get kernel image!
    9.92       0    U-Boot#

    Thank you

    Regards

    Santhosh

  • Santhosh, you may want to check for any noise or drop outs on VDD_CORE.  i guess you can post the schematic here if you want, or maybe just the relevant portions.

    regards,

    James

  • Hello James,

    Please see attached the schematic for just the power supply, it's based roughly on the Beagle Bone design. If you don't mind I can email you the entire schematic or if there is a way to send you a message on the forum I could do that as well.

    Thank you once again for all your help.

    Santhosh

  • Santhosh,

    I received the schematic through the distribution FAE and have sent back some replies related to decoupling caps.  In general it does not look like you have met all the requirements in the data manual with respect to DDR decoupling caps (for both the AM335x VDDR rail as well as the mDDR itself).  I expect you'll be receiving the more specific details shortly.

    Brad

  • Hello Brad,

    Thank you for taking a look at the schematic, I will read through all your suggestions and get back to you as soon as I receive them. I've also sent the latest schematic to James (JJD) via a conversation.

    Thank you once again.

    Regards

    Santhosh

  • Hello Brad, James,

    Sorry for not being able to reply before, I performed the tests that you guys had mentioned. And here are the results:

    1. I added the capacitors as mentioned in the email and it did not change the performance. One of the boards the performance deteriorated, where in it won't boot Linux at all.

    2. However, upon further inspection I found the VDD_CORE - the PMIC was not able to supply the required amount of current (approx. 220mA). This caused the voltage rail to bounce about 300mV - which in turn caused the delay. When I provided 1.1V steady supply from an external source the delay disappeared.

    I was able to remove the voltage bounce, by reducing the inductor value from 8.2uH to 3.3uH. I have attached 2 images before and after, of the voltage rail. The reason for the change is not clear to me, the only thing I can think of is the change in operating frequency of the PMIC switcher at 1.1V with 8.2uH.

    Please do let me know if you have any thoughts on this one, and give me any pointers.

    Thank you for your help.

    Regards

    Santhosh