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.

Ti811x: How add support for eMMC in uboot

We have an custom board based on J5 ti811x
NOR flash: 4MB
SD-card connected to MMC1 (0x481D8000)
eMMC 4GB connected to MMC2 (0x47810000)

ezsdk uboot version    :u-boot-2010.06-psp04.07.00.02
ezsdk kernel version    :linux-2.6.37-psp04.07.00.02

As per our booting scheme, we need to configure and copy uboot into NOR flash, kernel and RFS into eMMC. I have added support for eMMC in kernel and able to partition the eMMC. But to achieve booting scheme we need  eMMC support in uboot. But current uboot have only sd card support. I did some modification to bring up eMMC in uboot. But the information listed while using 'mmcinfo 1' is wrong. Actual capacity is 4 GB, but it shows some huge number. Also copied the changes which I did in uboot. Am I missing anything. Could someone help me to bring up eMMC in uboot.

TI811X_EVM#mmcinfo 1                                                            
Nid: mmc_init:                                                                  
Nid: mmc_init_setup: mmc_base: 0x47810100                                       
Nid: mmc_set_bus_width: bus width = 1                                           
Nid: mmc_set_ios: bus width set to 8                                            
Nid: mmc_set_ios: bus width set to 8                                            
Nid: mmc_startup:                                                               
Nid: mmc_startup: err=0                                                         
Nid: mmc_startup: its an MMC                                                    
Nid: mmc_startup: high capacity                                                 
Nid: mmc_startup: Capacity1: 0                                                  
Nid: mmc_startup: Capacity2: 0                                                  
Device: OMAP SD/MMC                                                             
Manufacturer ID: fe                                                             
OEM: 14e                                                                        
Name: MMC04                                                                     
Tran Speed: 25000000                                                            
Rd Block Len: 512                                                               
MMC version 4.0                                                                 
High Capacity: Yes                                                              
Capacity: 2199023255552                                                         
Bus Width: 1-bit     

Code change in uboot:
---------------------
modified:   board-support/u-boot-2010.06-psp04.07.00.02/arch/arm/include/asm/arch-ti81xx/mmc_host_def.h
    # define OMAP_HSMMC_BASE        0x481D8100
    +//Nid added to support MMC2
    +# define OMAP_HSMMC2_BASE        0x47810100 /* TI811X MMC/SD2 config base */
    #endif
---------------------------------------
modified:   board-support/u-boot-2010.06-psp04.07.00.02/arch/arm/include/asm/arch-ti81xx/cpu.h
    #ifdef CONFIG_TI814X
    #define CM_ALWON_HSMMC_CLKCTRL        (PRCM_BASE + 0x1620)
    +//Nid added to support eMMC
    +#define CM_ALWON_HSMMC_2_CLKCTRL    (PRCM_BASE + 0x1624)
    #endif
----------------------------------------------------

modified:   board-support/u-boot-2010.06-psp04.07.00.02/board/ti/ti811x/evm.c
    /* HSMMC */
    __raw_writel(0x2, CM_ALWON_HSMMC_CLKCTRL);
    while (__raw_readl(CM_ALWON_HSMMC_CLKCTRL) != 0x2)
    ;
    +/* Nid added to support eMMC */
    +__raw_writel(0x2, CM_ALWON_HSMMC_2_CLKCTRL);
    +while (__raw_readl(CM_ALWON_HSMMC_2_CLKCTRL) != 0x2)
-------------------------------------
modified:   board-support/u-boot-2010.06-psp04.07.00.02/drivers/mmc/omap_hsmmc.c
int omap_mmc_init(int dev_index)
{
    struct mmc *mmc;

    mmc = &hsmmc_dev[dev_index];

    sprintf(mmc->name, "OMAP SD/MMC");
    mmc->block_dev.removable = 1;
    mmc->send_cmd = mmc_send_cmd;
    mmc->set_ios = mmc_set_ios;
    mmc->init = mmc_init_setup;
    printf("Nid: %s: MMC:%d\n", __func__, dev_index);
#if !defined(CONFIG_TI81XX)
    switch (dev_index) {
    ------
    ----
    }
#else
    //Nid modified to support eMMC
    //mmc->priv = (hsmmc_t *)OMAP_HSMMC_BASE;
    switch (dev_index) {
    case 0:
        mmc->priv = (hsmmc_t *)OMAP_HSMMC_BASE;
        break;
    case 1:
        mmc->priv = (hsmmc_t *)OMAP_HSMMC2_BASE;
        printf("Nid: %s: mmc2: mmc_base: 0x%x\n", __func__, mmc->priv);
        break;    
    default:
        mmc->priv = (hsmmc_t *)OMAP_HSMMC_BASE;
        return 1;
    }
#endif
#if defined(CONFIG_TI81XX)
    if(dev_index){
        printf("Nid: %s: mmc2: \n", __func__);
        mmc->voltages = MMC_VDD_33_34;
        mmc->host_caps = MMC_MODE_8BIT | MMC_MODE_HS;
        mmc->block_dev.removable = 0;
        mmc->bus_width = 8;
    }else{
        mmc->voltages = MMC_VDD_32_33 | MMC_VDD_33_34 | MMC_VDD_165_195;
        mmc->host_caps = MMC_MODE_4BIT | MMC_MODE_HS_52MHz | MMC_MODE_HS;
    }
#else
    mmc->voltages = MMC_VDD_32_33 | MMC_VDD_33_34 | MMC_VDD_165_195;
    mmc->host_caps = MMC_MODE_4BIT | MMC_MODE_HS_52MHz | MMC_MODE_HS;
#endif
}
----------------------------------------------

  • Hi Abdul,

    I do not see eMMC/MMC2 pinmux added in your u-boot code base. In case you boot not from eMMC/MMC2, but from other source (NOR, MMC1, UART, etc) the ROM code will not make the MMC2 pinmux. See J5Eco TRM, section 5.6.4.8 Pin Used

    See also the below wiki:
    processors.wiki.ti.com/.../Linux_Core_U-Boot_User's_Guide

    BR
    Pavel

  • Also, I do not see eMMC/MMC2 interrupts and EDMA events added in your u-boot code base. You might also try add these.

    BR
    Pavel
  • Pavel,

    Pin muxing I have already added in mux.h file.
    Could you please tell me where can I add interrupt and edma event in uboot?
    Any references?

    BR/-
    Nihad
  • Pavel,

    Any update on this?

    BR/-
    Nihad
  • Can you attach the mux.h file?

    From what I understand you need to have MMC1 and MMC2 in u-boot. Do you add MMC2 init in evm.c?

    board/ti/ti811x/evm.c

    int board_mmc_init(bd_t *bis)
    {
    omap_mmc_init(0); //for MMC1, default
    omap_mmc_init(1); //add for MMC2
    return 0;
    }
  • Pavel,


    I have already did modification. But still not able to access.

    static void rsb_emmc_mux_init(void)
    {
        printf("%s for RSB\n",__func__);
        //printk("Enable MMCHS_2 clock\n");
        //__raw_writel(0x02, TI814X_CM_ALWON_MMCHS_2_CLKCTRL);
        
        PAD_CNTRL(113) = 0x00070001; //mmc2_dat7
        PAD_CNTRL(114) = 0x00070001; //mmc2_dat6
        PAD_CNTRL(115) = 0x00070001; //mmc2_dat5
        PAD_CNTRL(116) = 0x00070001; //mmc2_dat4
        PAD_CNTRL(117) = 0x00070001; //mmc2_dat3
        PAD_CNTRL(118) = 0x00070001; //mmc2_dat2
        PAD_CNTRL(119) = 0x00070001; //mmc2_dat1
        PAD_CNTRL(120) = 0x00070001; //mmc2_dat0
        PAD_CNTRL(121) = 0x00070001; //mmc2_clk
        PAD_CNTRL(126) = 0x00070002; //mmc2_cmd
        PAD_CNTRL(131) = 0x00050080; //EMMC_ON_N

        // PAD131, MMC_ON_N
            set_pin_direction(GPIO1_BASE, EMMC_ON_GPIO1_PIN, OUTPUT);
            set_pin_value(GPIO1_BASE, EMMC_ON_GPIO1_PIN, 0);

        __raw_writel(0x00050040, 0xFA140920);    /*PINCNTL73  - MMC2_SDCD*/        
        /*MMC2_SDCD is enabled only to satisfy the host controller
        implementation.    This pin is not used in case of eMMC device
        but is enabled with pulled-up high to satisfy controller.*/
    }

    int board_mmc_init(bd_t *bis)
    {
        rsb_emmc_mux_init();
        omap_mmc_init(0);
        /*eMMC in RSB*/
        omap_mmc_init(1);
        return 0;
    }

    6747.evm.c
    /*
     * Copyright (C) 2009, Texas Instruments, Incorporated
     *
     * See file CREDITS for list of people who contributed to this
     * project.
     *
     * 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 <config.h>
    #include <common.h>
    #include <asm/cache.h>
    #include <asm/arch/cpu.h>
    #include <asm/arch/ddr_defs.h>
    #include <asm/arch/hardware.h>
    #include <asm/arch/sys_proto.h>
    #include <asm/arch/mmc_host_def.h>
    #include <asm/arch/clock.h>
    #include <asm/arch/mem.h>
    #include <asm/arch/nand.h>
    #include <linux/mtd/nand.h>
    #include <nand.h>
    #include <net.h>
    #include <miiphy.h>
    #include <netdev.h>
    #include <i2c.h>
    #include "bcm89811phy.h"
    
    #ifdef CONFIG_TI811X_CONFIG_DDR
    static void config_ti811x_ddr(void);
    #endif
    
    DECLARE_GLOBAL_DATA_PTR;
    
    #ifdef CONFIG_TI811X_CONFIG_DDR
    static void cmd_macro_config(u32 ddr_phy, u32 inv_clk_out,
    			 u32 ctrl_slave_ratio_cs0, u32 cmd_dll_lock_diff)
    {
    	u32 ddr_phy_base = DDR0_PHY_BASE_ADDR;
    
    	__raw_writel(inv_clk_out,
    		 ddr_phy_base + CMD1_REG_PHY_INVERT_CLKOUT_0);
    	__raw_writel(inv_clk_out,
    		 ddr_phy_base + CMD0_REG_PHY_INVERT_CLKOUT_0);
    	__raw_writel(inv_clk_out,
    		 ddr_phy_base + CMD2_REG_PHY_INVERT_CLKOUT_0);
    
    	__raw_writel(((ctrl_slave_ratio_cs0 << 10) | ctrl_slave_ratio_cs0),
    		ddr_phy_base + CMD0_REG_PHY_CTRL_SLAVE_RATIO_0);
    	__raw_writel(((ctrl_slave_ratio_cs0 << 10) | ctrl_slave_ratio_cs0),
    		ddr_phy_base + CMD1_REG_PHY_CTRL_SLAVE_RATIO_0);
    	__raw_writel(((ctrl_slave_ratio_cs0 << 10) | ctrl_slave_ratio_cs0),
    		 ddr_phy_base + CMD2_REG_PHY_CTRL_SLAVE_RATIO_0);
    
    	__raw_writel(cmd_dll_lock_diff,
    		 ddr_phy_base + CMD0_REG_PHY_DLL_LOCK_DIFF_0);
    	__raw_writel(cmd_dll_lock_diff,
    		 ddr_phy_base + CMD1_REG_PHY_DLL_LOCK_DIFF_0);
    	__raw_writel(cmd_dll_lock_diff,
    		 ddr_phy_base + CMD2_REG_PHY_DLL_LOCK_DIFF_0);
    }
    
    static void data_macro_config(u32 macro_num, u32 emif, u32 rd_dqs_cs0,
    		u32 wr_dqs_cs0, u32 fifo_we_cs0, u32 wr_data_cs0)
    {
    	/* 0xA4 is size of each data macro mmr region.
    	 * phy1 is at offset 0x400 from phy0
    	 */
    	u32 base = (macro_num * 0xA4) + (emif * 0x400);
    
    	__raw_writel(((rd_dqs_cs0 << 10) | rd_dqs_cs0),
    		(DATA0_REG_PHY0_RD_DQS_SLAVE_RATIO_0 + base));
    	__raw_writel(((wr_dqs_cs0 << 10) | wr_dqs_cs0),
    		(DATA0_REG_PHY0_WR_DQS_SLAVE_RATIO_0 + base));
    	__raw_writel(((PHY_WRLVL_INIT_CS1_DEFINE << 10) |
    		PHY_WRLVL_INIT_CS0_DEFINE),
    		(DATA0_REG_PHY0_WRLVL_INIT_RATIO_0 + base));
    	__raw_writel(((PHY_GATELVL_INIT_CS1_DEFINE << 10) |
    		PHY_GATELVL_INIT_CS0_DEFINE),
    		(DATA0_REG_PHY0_GATELVL_INIT_RATIO_0 + base));
    	__raw_writel(((fifo_we_cs0 << 10) | fifo_we_cs0),
    		(DATA0_REG_PHY0_FIFO_WE_SLAVE_RATIO_0 + base));
    	__raw_writel(((wr_data_cs0 << 10) | wr_data_cs0),
    		(DATA0_REG_PHY0_WR_DATA_SLAVE_RATIO_0 + base));
    	__raw_writel(PHY_DLL_LOCK_DIFF_DEFINE,
    		(DATA0_REG_PHY0_DLL_LOCK_DIFF_0 + base));
    }
    #endif
    
    #ifdef CONFIG_SETUP_PLL
    static u32 pll_dco_freq_sel(u32 clk_in, u32 n, u32 m);
    static void pll_config(u32, u32, u32, u32, u32);
    static void audio_pll_config(void);
    static void sata_pll_config(void);
    static void modena_pll_config(void);
    static void l3_pll_config(void);
    static void ddr_pll_config(void);
    static void iss_pll_config(void);
    static void dsp_pll_config(void);
    static void usb_pll_config(void);
    #endif
    static void unlock_pll_control_mmr(void);
    #ifdef CONFIG_DRIVER_TI_CPSW
    static void cpsw_pad_config(void);
    #endif
    static void nor_pad_config_mux(void);
    /*
     * spinning delay to use before udelay works
     */
    static inline void delay(unsigned long loops)
    {
    	__asm__ volatile ("1:\n" "subs %0, %1, #1\n"
    		"bne 1b" : "=r" (loops) : "0"(loops));
    }
    
    # define CONFIG_AMP_I2C_SPEED		400000
    # define CONFIG_DIRANA_I2C_SPEED	400000
    /* i2c0(bus1) <--> Dirana3 I/F */
    # define CONFIG_DIRANA_I2C_SLAVE	1
    /* i2c2(bus3) <--> Amplifier I/F */
    # define CONFIG_AMP_I2C_SLAVE		3
    //i2c3(bus4) <--> EEPROM I/F */
    # define CONFIG_EEPROM_I2C_SLAVE	4
    
    u32 rsb_i2c_init(void)
    {
        //int status;
        //u32 val, val_pincntl263, val_pincntl264;
          
        /* Setup the PADCNTL Registers for I2C0 */
        //val_pincntl263 = __raw_readl(0x48140C18);
        //val = (val_pincntl263 & ~0x7FF) | 0x001;
        //__raw_writel(val, 0x48140C18);
        //val_pincntl264 = __raw_readl(0x48140C1C);
        //val = (val_pincntl264 & ~0x7FF) | 0x001;
        //__raw_writel(val, 0x48140C1C);
        
        /* Init i2c2(bus3) for Amplifier */
        i2c_init (CONFIG_AMP_I2C_SPEED, CONFIG_AMP_I2C_SLAVE);
    
        /* Init i2c0(bus1) for Dirana3 r */
        i2c_init (CONFIG_DIRANA_I2C_SPEED, CONFIG_DIRANA_I2C_SLAVE);
    
    }
    
    /*
     * Basic board specific setup
     */
    int board_init(void)
    {
    	u32 regVal;
    
    	/* Do the required pin-muxing before modules are setup */
    	set_muxconf_regs();
    	
    	/* Enable LVCMOS mode for MLBP_SIGN and MLBP_SIGP IO buffers. Enable receivers for GPIO input functionality. */
    	__raw_writel(0x3F, MLBP_SIG_IO_CTRL);
    	/* Enable LVCMOS mode for MLBP_DATN and MLBP_DATP IO buffers. Enable receivers for GPIO input functionality. */
    	__raw_writel(0x3F, MLBP_DAT_IO_CTRL);
    
    
    	nor_pad_config_mux();
    	rsb_i2c_init();
    #if 0
    	/* setup RMII_REFCLK to be sourced from audio_pll */
    	__raw_writel(0x30004, RMII_REFCLK_SRC);
    
    	/*program GMII_SEL register for RGMII mode */
    	__raw_writel(0x30a, GMII_SEL);
    #else //RSB
    	/* setup RMII_REFCLK .its an input from external src */
    	__raw_writel(0x30005, RMII_REFCLK_SRC);
    	
    	/*program GMII_SEL register for RMII mode */
    	//__raw_writel(0x305, GMII_SEL); //with internal delay
    	__raw_writel(0x335, GMII_SEL); //no internal delay
    #endif
    
    	/* Get Timer and UART out of reset */
    	/* UART softreset */
    	regVal = __raw_readl(UART_SYSCFG);
    	regVal |= 0x2;
    	__raw_writel(regVal, UART_SYSCFG);
    	while ((__raw_readl(UART_SYSSTS) & 0x1) != 0x1)
    		;
    
    	/* Disable smart idle */
    	regVal = __raw_readl(UART_SYSCFG);
    	regVal |= (1<<3);
    	__raw_writel(regVal, UART_SYSCFG);
    
    	/* mach type passed to kernel */
    	gd->bd->bi_arch_number = MACH_TYPE_TI811XEVM;
    
    	/* address of boot parameters */
    	gd->bd->bi_boot_params = PHYS_DRAM_1 + 0x100;
    	gpmc_init();
    
    #ifndef CONFIG_NOR
    	/* GPMC will come up with default buswidth configuration,
    	 * we will override it based on BW pin CONFIG_STATUS register.
    	 * This is currently required only for NAND/NOR to
    	 * support 8/16 bit NAND/NOR part. Also we always use chipselect 0
    	 * for NAND/NOR boot.
    	 *
    	 * NOTE: This code is DM8168 EVM specific, hence we are using CS 0.
    	 * NOTE: This code is DM8168 EVM specific, hence we are using CS 0.
    	 * Also, even for other boot modes user is expected to
    	 * on/off the BW pin on the EVM.
    	 */
    	gpmc_set_cs_buswidth(0, get_sysboot_bw());
    #endif
    	return 0;
    }
    
    /*
     * sets uboots idea of sdram size
     */
    int dram_init(void)
    {
    	/* Fill up board info */
    	gd->bd->bi_dram[0].start = PHYS_DRAM_1;
    	gd->bd->bi_dram[0].size = PHYS_DRAM_1_SIZE;
    
    	return 0;
    }
    
    #ifdef CONFIG_SERIAL_TAG
    /*  *********************************************************
     *  * get_board_serial() - setup to pass kernel board serial
     *  * returns: board serial number
     *  **********************************************************
     */
    void get_board_serial(struct tag_serialnr *serialnr)
    {
    	/* ToDo: read eeprom and return*/
    	serialnr->high = 0x0;
    	serialnr->low = 0x0;
    
    }
    #endif
    
    /**********************************************************
     * * get_board_rev() - setup to pass kernel board revision
     * * returns: revision
     * ********************************************************
     */
    u32 get_board_rev(void)
    {
        int status;
        u32 val, val_pincntl263, val_pincntl264;
    
        struct EEPROM_ID_T
        {
            uint32_t    header;
            uint8_t     board_name[16];
            uint16_t    version_major;
            uint16_t    version_minor;
            uint32_t    config_option;
        }
        eeprom_id;
        
        /* Setup the PADCNTL Registers for I2C0 */
        val_pincntl263 = __raw_readl(0x48140C18);
        val = (val_pincntl263 & ~0x7FF) | 0x001;
        __raw_writel(val, 0x48140C18);
        val_pincntl264 = __raw_readl(0x48140C1C);
        val = (val_pincntl264 & ~0x7FF) | 0x001;
        __raw_writel(val, 0x48140C1C);
        
        /* Init the I2C0 peripheral */
        i2c_init (CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
    
        /* Read from bytes from start of EEPROM at bus address 0x50 */
        status = i2c_read( CONFIG_SYS_I2C_EEPROM_ADDR, 0x0, 
                           CONFIG_SYS_I2C_EEPROM_ADDR_LEN, (uint8_t *) &eeprom_id, 
                           sizeof(eeprom_id));
        
        /* Return the PADCNTL registers to their original states */
        __raw_writel(val_pincntl263, 0x48140C18);
        __raw_writel(val_pincntl264, 0x48140C1C);
        
        /* Check if the EEPROM read failed */
        if (status != 0)
        {
            puts ("Error: EEPROM read failed.\n");
            return 0x0;
        }
        
        /* Check for magic number in EEPROM data */
        if (0xaa5533ee != eeprom_id.header)
        {
            puts ("Warning: Board ID missing. Defaulting to Rev D and earlier.\n");
            return 0x0;
        }
        
        return eeprom_id.version_major;
    }
    
    int misc_init_r(void)
    {
    	#ifdef CONFIG_TI811X_MIN_CONFIG
        u32 rev = get_board_rev();
    
        if (rev != 0x0) {
            /* Major revision numbers should be 1 for A, 2 for B, and so on */    
            printf("Info: Detected board revison %c.\n",(char)(0x40+rev));
        } else {
            printf("Warning: Board revision detection failed.\n");
        }
        
    	printf("The 2nd stage U-Boot will now be auto-loaded\n");
    	printf("Please do not interrupt the countdown till "
    		"TI811X_EVM prompt if 2nd stage is already flashed\n");
    	#endif
    
    #ifdef CONFIG_TI811X_ASCIIART
    	int i = 0, j = 0;
    
    	char ti811x[22][67] = {
    "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@",
    "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@",
    "@@                                                               @@",
    "@@                                                               @@",
    "@@                                                               @@",
    "@@                                                               @@",
    "@@                                                               @@",
    "@@     88888888888 8888888 .d8888b.   d888    d888               @@",
    "@@         888       888  d88P  Y88b d8888   d8888               @@",
    "@@         888       888  Y88b. d88P   888     888               @@",
    "@@         888       888    Y88888     888     888    888  888   @@",
    "@@         888       888  .d8P88Y8b.   888     888      Y8 8P    @@",
    "@@         888       888  888    888   888     888       88      @@",
    "@@         888       888  Y88b  d88P   888     888     .d8 8b.   @@",
    "@@         888     8888888  Y8888P  8888888  8888888   888 888   @@",
    "@@                                                               @@",
    "@@                                                               @@",
    "@@                                                               @@",
    "@@                                                               @@",
    "@@                                                               @@",
    "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@",
    "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@",};
    
    	for (i = 0; i < 22; i++) {
    		for (j = 0; j < 67; j++)
    			printf("%c", ti811x[i][j]);
    			printf("\n");
    	}
    	printf("\n");
    #endif
    	return 0;
    }
    #ifdef CONFIG_TI811X_CONFIG_DDR
    static void config_ti811x_ddr(void)
    {
    	int macro;
    
    	/* Enable the Power Domain Transition of L3 Fast Domain Peripheral */
    	__raw_writel(0x2, CM_DEFAULT_FW_CLKCTRL);
    	/* Enable the Power Domain Transition of L3 Fast Domain Peripheral */
    	__raw_writel(0x2, CM_DEFAULT_L3_FAST_CLKSTCTRL);
    	__raw_writel(0x2, CM_DEFAULT_EMIF_0_CLKCTRL); /* Enable EMIF0 Clock */
    
    	/* Poll for L3_FAST_GCLK  & DDR_GCLK  are active */
    	while ((__raw_readl(CM_DEFAULT_L3_FAST_CLKSTCTRL) & 0x300) != 0x300)
    		;
    	/* Poll for Module is functional */
    	while ((__raw_readl(CM_DEFAULT_EMIF_0_CLKCTRL)) != 0x2)
    		;
    
    	cmd_macro_config(DDR_PHY0, DDR3_PHY_INVERT_CLKOUT_OFF,
    			DDR3_PHY_CTRL_SLAVE_RATIO_CS0_DEFINE,
    			PHY_CMD0_DLL_LOCK_DIFF_DEFINE);
    
    	for (macro = 0; macro <= DATA_MACRO_3; macro++) {
    		data_macro_config(macro, DDR_PHY0,
    			DDR3_PHY_RD_DQS_CS0_DEFINE,
    			DDR3_PHY_WR_DQS_CS0_DEFINE,
    			DDR3_PHY_RD_DQS_GATE_CS0_DEFINE,
    			DDR3_PHY_WR_DATA_CS0_DEFINE);
    	}
    
    	/* DDR IO CTRL config */
    	__raw_writel(DDR0_IO_CTRL_DEFINE, DDR0_IO_CTRL);
    
    	__raw_writel(__raw_readl(VTP0_CTRL_REG) | 0x00000040 , VTP0_CTRL_REG);
    
    	/* Write 0 to CLRZ bit */
    	__raw_writel(__raw_readl(VTP0_CTRL_REG) & 0xfffffffe , VTP0_CTRL_REG);
    
    	/* Write 1 to CLRZ bit */
    	__raw_writel(__raw_readl(VTP0_CTRL_REG) | 0x00000001 , VTP0_CTRL_REG);
    
    	/* Read VTP control registers & check READY bits */
    	while ((__raw_readl(VTP0_CTRL_REG) & 0x00000020) != 0x20)
    		;
    	
    
    	/* Program EMIF0 CFG Registers */
        if (get_board_rev() >= 0x5)
        {
            __raw_writel(DDR3_EMIF_READ_LATENCY_REV_E, EMIF4_0_DDR_PHY_CTRL_1);
            __raw_writel(DDR3_EMIF_READ_LATENCY_REV_E, EMIF4_0_DDR_PHY_CTRL_1_SHADOW);
            __raw_writel(DDR3_EMIF_TIM1_REV_E, EMIF4_0_SDRAM_TIM_1);
            __raw_writel(DDR3_EMIF_TIM1_REV_E, EMIF4_0_SDRAM_TIM_1_SHADOW);
            __raw_writel(DDR3_EMIF_TIM2_REV_E, EMIF4_0_SDRAM_TIM_2);
            __raw_writel(DDR3_EMIF_TIM2_REV_E, EMIF4_0_SDRAM_TIM_2_SHADOW);
            __raw_writel(DDR3_EMIF_TIM3_REV_E, EMIF4_0_SDRAM_TIM_3);
            __raw_writel(DDR3_EMIF_TIM3_REV_E, EMIF4_0_SDRAM_TIM_3_SHADOW);
            __raw_writel(DDR3_EMIF_SDRAM_CONFIG_REV_E, EMIF4_0_SDRAM_CONFIG);
    
            __raw_writel(DDR_EMIF_REF_CTRL | DDR_EMIF_REF_TRIGGER,
                             EMIF4_0_SDRAM_REF_CTRL);
            __raw_writel(DDR_EMIF_REF_CTRL, EMIF4_0_SDRAM_REF_CTRL_SHADOW);
            __raw_writel(DDR3_EMIF_SDRAM_ZQCR_REV_E, EMIF4_0_SDRAM_ZQCR);
            __raw_writel(DDR_EMIF_REF_CTRL, EMIF4_0_SDRAM_REF_CTRL);
            __raw_writel(DDR_EMIF_REF_CTRL, EMIF4_0_SDRAM_REF_CTRL_SHADOW);
    
            __raw_writel(DDR3_EMIF_REF_CTRL_REV_E, EMIF4_0_SDRAM_REF_CTRL);
            __raw_writel(DDR3_EMIF_REF_CTRL_REV_E, EMIF4_0_SDRAM_REF_CTRL_SHADOW);    
        }
        else
        {
            __raw_writel(DDR3_EMIF_READ_LATENCY, EMIF4_0_DDR_PHY_CTRL_1);
            __raw_writel(DDR3_EMIF_READ_LATENCY, EMIF4_0_DDR_PHY_CTRL_1_SHADOW);
            __raw_writel(DDR3_EMIF_TIM1, EMIF4_0_SDRAM_TIM_1);
            __raw_writel(DDR3_EMIF_TIM1, EMIF4_0_SDRAM_TIM_1_SHADOW);
            __raw_writel(DDR3_EMIF_TIM2, EMIF4_0_SDRAM_TIM_2);
            __raw_writel(DDR3_EMIF_TIM2, EMIF4_0_SDRAM_TIM_2_SHADOW);
            __raw_writel(DDR3_EMIF_TIM3, EMIF4_0_SDRAM_TIM_3);
            __raw_writel(DDR3_EMIF_TIM3, EMIF4_0_SDRAM_TIM_3_SHADOW);
            __raw_writel(DDR3_EMIF_SDRAM_CONFIG, EMIF4_0_SDRAM_CONFIG);
    
            __raw_writel(DDR_EMIF_REF_CTRL | DDR_EMIF_REF_TRIGGER,
                             EMIF4_0_SDRAM_REF_CTRL);
            __raw_writel(DDR_EMIF_REF_CTRL, EMIF4_0_SDRAM_REF_CTRL_SHADOW);
            __raw_writel(DDR3_EMIF_SDRAM_ZQCR, EMIF4_0_SDRAM_ZQCR);
            __raw_writel(DDR_EMIF_REF_CTRL, EMIF4_0_SDRAM_REF_CTRL);
            __raw_writel(DDR_EMIF_REF_CTRL, EMIF4_0_SDRAM_REF_CTRL_SHADOW);
    
            __raw_writel(DDR3_EMIF_REF_CTRL, EMIF4_0_SDRAM_REF_CTRL);
            __raw_writel(DDR3_EMIF_REF_CTRL, EMIF4_0_SDRAM_REF_CTRL_SHADOW);
        }
    }
    #endif
    
    #ifdef CONFIG_SETUP_PLL
    static void audio_pll_config()
    {
    	pll_config(AUDIO_PLL_BASE,
    			AUDIO_N, AUDIO_M,
    			AUDIO_M2, AUDIO_CLKCTRL);
    }
    
    #if 0
    static void pcie_pll_config()
    {
    	/* Powerdown both reclkp/n single ended receiver */
    	__raw_writel(0x00000002, SERDES_REFCLK_CTRL);
    
    	__raw_writel(0x00000000, PCIE_PLLCFG0);
    
    	/* PCIe(2.5GHz) mode, 100MHz refclk, MDIVINT = 25,
    	 * disable (50,100,125M) clks
    	 */
    	__raw_writel(0x00640000, PCIE_PLLCFG1);
    
    	/* SSC Mantissa and exponent = 0 */
    	__raw_writel(0x00000000, PCIE_PLLCFG2);
    
    	/* TBD */
    	__raw_writel(0x004008E0, PCIE_PLLCFG3);
    
    	/* TBD */
    	__raw_writel(0x0000609C, PCIE_PLLCFG4);
    
    	/* pcie_serdes_cfg_misc */
    	/* TODO: verify the address over here
    	 * (CTRL_BASE + 0x6FC = 0x481406FC ???)
    	 */
    	/* __raw_writel(0x00000E7B, 0x48141318); */
    	delay(3);
    
    	/* Enable PLL LDO */
    	__raw_writel(0x00000004, PCIE_PLLCFG0);
    	delay(3);
    
    	/* Enable DIG LDO, PLL LD0 */
    	__raw_writel(0x00000014, PCIE_PLLCFG0);
    	delay(3);
    
    	/* Enable DIG LDO, ENBGSC_REF, PLL LDO */
    	__raw_writel(0x00000016, PCIE_PLLCFG0);
    	delay(3);
    	__raw_writel(0x30000016, PCIE_PLLCFG0);
    	delay(3);
    	__raw_writel(0x70000016, PCIE_PLLCFG0);
    	delay(3);
    
    	/* Enable DIG LDO, SELSC, ENBGSC_REF, PLL LDO */
    	__raw_writel(0x70000017, PCIE_PLLCFG0);
    	delay(3);
    
    	/* wait for ADPLL lock */
    	while (__raw_readl(PCIE_PLLSTATUS) != 0x1)
    		;
    
    }
    #endif
    
    static void sata_pll_config()
    {
    	__raw_writel(0xC12C003C, SATA_PLLCFG1);
    	__raw_writel(0x004008E0, SATA_PLLCFG3);
    	delay(0xFFFF);
    
    	__raw_writel(0x80000004, SATA_PLLCFG0);
    	delay(0xFFFF);
    
    	/* Enable PLL LDO */
    	__raw_writel(0x80000014, SATA_PLLCFG0);
    	delay(0xFFFF);
    
    	/* Enable DIG LDO, ENBGSC_REF, PLL LDO */
    	__raw_writel(0x80000016, SATA_PLLCFG0);
    	delay(0xFFFF);
    
    	__raw_writel(0xC0000017, SATA_PLLCFG0);
    	delay(0xFFFF);
    
    	/* wait for ADPLL lock */
    	while (((__raw_readl(SATA_PLLSTATUS) & 0x01) == 0x0))
    		;
    
    }
    
    static void usb_pll_config()
    {
    	pll_config(USB_PLL_BASE,
    			USB_N, USB_M,
    			USB_M2, USB_CLKCTRL);
    }
    
    static void modena_pll_config()
    {
    	pll_config(MODENA_PLL_BASE,
    			MODENA_N, MODENA_M,
    			MODENA_M2, MODENA_CLKCTRL);
    }
    
    static void l3_pll_config()
    {
    	pll_config(L3_PLL_BASE,
    			L3_N, L3_M,
    			L3_M2, L3_CLKCTRL);
    }
    
    static void ddr_pll_config()
    {
    	pll_config(DDR_PLL_BASE,
    			DDR_N, DDR_M,
    			DDR_M2, DDR_CLKCTRL);
    }
    static void dsp_pll_config()
    {
    	pll_config(DSP_PLL_BASE,
    			DSP_N, DSP_M, DSP_M2,
    			DSP_CLKCTRL);
    }
    static void iss_pll_config()
    {
    	pll_config(ISS_PLL_BASE,
    			ISS_N, ISS_M,
    			ISS_M2, ISS_CLKCTRL);
    }
    #if 0
    static void iva_pll_config()
    {
    	pll_config(IVA_PLL_BASE,
    			IVA_N, IVA_M,
    			IVA_M2, IVA_CLKCTRL);
    }
    #endif
    
    /*
     * select the HS1 or HS2 for DCO Freq
     * return : CLKCTRL
     */
    static u32 pll_dco_freq_sel(u32 clk_in, u32 n, u32 m)
    {
    	u32 dco_clk = 0;
    
    	dco_clk = (clk_in / (n+1)) * m ;
    	if (dco_clk >= DCO_HS2_MIN && dco_clk < DCO_HS2_MAX)
    		return SELFREQDCO_HS2;
    	else if (dco_clk >= DCO_HS1_MIN && dco_clk < DCO_HS1_MAX)
    		return SELFREQDCO_HS1;
    	else
    		return -1;
    
    }
    
    /*
     * configure individual ADPLLJ
     */
    static void pll_config(u32 base, u32 n, u32 m, u32 m2, u32 clkctrl_val)
    {
    	u32 m2nval, mn2val, read_clkctrl = 0;
    
    	/* select DCO freq range for ADPLL_J */
    	if (MODENA_PLL_BASE != base)
    		clkctrl_val |= pll_dco_freq_sel(OSC_0_FREQ, n, m);
    
    	m2nval = (m2 << 16) | n;
    	mn2val = m;
    
    	/* by-pass pll */
    	read_clkctrl = __raw_readl(base + ADPLLJ_CLKCTRL);
    	__raw_writel((read_clkctrl | 0x00800000), (base + ADPLLJ_CLKCTRL));
    	while ((__raw_readl(base + ADPLLJ_STATUS) & 0x101) != 0x101)
    		;
    	read_clkctrl = __raw_readl(base + ADPLLJ_CLKCTRL);
    	__raw_writel((read_clkctrl & 0xfffffffe), (base + ADPLLJ_CLKCTRL));
    
    
    	/*
    	 * ref_clk = 20/(n + 1);
    	 * clkout_dco = ref_clk * m;
    	 * clk_out = clkout_dco/m2;
    	*/
    
    	__raw_writel(m2nval, (base + ADPLLJ_M2NDIV));
    	__raw_writel(mn2val, (base + ADPLLJ_MN2DIV));
    
    	/* Load M2, N2 dividers of ADPLL */
    	__raw_writel(0x1, (base + ADPLLJ_TENABLEDIV));
    	__raw_writel(0x0, (base + ADPLLJ_TENABLEDIV));
    
    	/* Loda M, N dividers of ADPLL */
    	__raw_writel(0x1, (base + ADPLLJ_TENABLE));
    	__raw_writel(0x0, (base + ADPLLJ_TENABLE));
    
    	read_clkctrl = __raw_readl(base + ADPLLJ_CLKCTRL);
    
    	if (MODENA_PLL_BASE == base)
    		__raw_writel((read_clkctrl & 0xff7fffff) | clkctrl_val,
    			base + ADPLLJ_CLKCTRL);
    	else
    		__raw_writel((read_clkctrl & 0xff7fe3ff) | clkctrl_val,
    			base + ADPLLJ_CLKCTRL);
    	/* Wait for phase and freq lock */
    	while ((__raw_readl(base + ADPLLJ_STATUS) & 0x600) != 0x600)
    		;
    
    }
    #endif
    
    /*
     * Enable the clks & power for perifs (TIMER1, UART0,...)
     */
    void per_clocks_enable(void)
    {
    	u32 temp;
    
    	__raw_writel(0x2, CM_ALWON_L3_SLOW_CLKSTCTRL);
    
    #if 0
    	/* TIMER 1 */
    	__raw_writel(0x2, CM_ALWON_TIMER_1_CLKCTRL);
    #endif
    	/* Selects OSC0 (20MHz) for DMTIMER1 */
    	temp = __raw_readl(DMTIMER_CLKSRC);
    	temp &= ~(0x7 << 4);
    	temp |= (0x4 << 4);
    	__raw_writel(temp, DMTIMER_CLKSRC);
    
    #if 0
    	while (((__raw_readl(CM_ALWON_L3_SLOW_CLKSTCTRL) & (0x80000<<1)) >>
    			(19+1)) != 1)
    		;
    	while (((__raw_readl(CM_ALWON_TIMER_1_CLKCTRL) & 0x30000)>>16) != 0)
    		;
    #endif
    	__raw_writel(0x2, (DM_TIMER1_BASE + 0x54));
    	while (__raw_readl(DM_TIMER1_BASE + 0x10) & 1)
    		;
    
    	__raw_writel(0x1, (DM_TIMER1_BASE + 0x38));
    
    	/* UARTs */
    	__raw_writel(0x2, CM_ALWON_UART_0_CLKCTRL);
    	while (__raw_readl(CM_ALWON_UART_0_CLKCTRL) != 0x2)
    		;
    
    	__raw_writel(0x2, CM_ALWON_UART_1_CLKCTRL);
    	while (__raw_readl(CM_ALWON_UART_1_CLKCTRL) != 0x2)
    		;
    
    	__raw_writel(0x2, CM_ALWON_UART_2_CLKCTRL);
    	while (__raw_readl(CM_ALWON_UART_2_CLKCTRL) != 0x2)
    		;
    
    	while ((__raw_readl(CM_ALWON_L3_SLOW_CLKSTCTRL) & 0x2100) != 0x2100)
    		;
    
    	/* SPI */
    	__raw_writel(0x2, CM_ALWON_SPI_CLKCTRL);
    	while (__raw_readl(CM_ALWON_SPI_CLKCTRL) != 0x2)
    		;
    
    	/* I2C0 and I2C2 */
    	__raw_writel(0x2, CM_ALWON_I2C_0_CLKCTRL);
    	while (__raw_readl(CM_ALWON_I2C_0_CLKCTRL) != 0x2)
    		;
    
    	/* I2C1 and I2C3 */
    	__raw_writel(0x2, CM_ALWON_I2C_1_CLKCTRL);
    	while (__raw_readl(CM_ALWON_I2C_1_CLKCTRL) != 0x2)
    		;
    
    	/*Enable GPIO0 clock*/	
    	__raw_writel(0x102, CM_ALWON_GPIO_0_CLKCTRL);
    	while(__raw_readl(CM_ALWON_GPIO_0_CLKCTRL) != 0x102)
    		;
    	 
    	/*Enable GPIO1, GPIO2, GPIO3, GPIO4, GPIO5 clock*/
    	__raw_writel(0x102, CM_ALWON_GPIO_1_CLKCTRL); 
    	while(__raw_readl(CM_ALWON_GPIO_1_CLKCTRL) != 0x102)
    		;
    
    	/* Ethernet */
    	__raw_writel(0x2, CM_ETHERNET_CLKSTCTRL);
    	__raw_writel(0x2, CM_ALWON_ETHERNET_0_CLKCTRL);
    	while ((__raw_readl(CM_ALWON_ETHERNET_0_CLKCTRL) & 0x30000) != 0)
    		;
    	__raw_writel(0x2, CM_ALWON_ETHERNET_1_CLKCTRL);
    	/* HSMMC */
    	__raw_writel(0x2, CM_ALWON_HSMMC_CLKCTRL);
    	while (__raw_readl(CM_ALWON_HSMMC_CLKCTRL) != 0x2)
    		;
    	/* Nid added to support eMMC */
    	__raw_writel(0x2, CM_ALWON_HSMMC_2_CLKCTRL);
    	while (__raw_readl(CM_ALWON_HSMMC_2_CLKCTRL) != 0x2)
    		;
    
    	/*
    	 * McASP2
    	 * select mcasp2 clk from sys_clk_22 (OSC 0)
    	 * so that audio clk (sys_clk_20) can be used for RMII
    	 * ToDo :
    	 * This can be removed once kernel exports set_parent()
    	 */
    
    	 
    	__raw_writel(0x0, CM_SYSCLK20_CLKSEL);
    	while (__raw_readl(CM_SYSCLK20_CLKSEL) != 0x0);
    
    	__raw_writel(0x0, CM_AUDIOCLK_MCASP2_CLKSEL);
    	while (__raw_readl(CM_AUDIOCLK_MCASP2_CLKSEL) != 0x0);
    
    	__raw_writel(0x0, CM_AUDIOCLK_MCASP0_CLKSEL);
    	while (__raw_readl(CM_AUDIOCLK_MCASP0_CLKSEL) != 0x0);
    
    	__raw_writel(0x00000300, McASP345_AUX_CLKSRC);
    	while (__raw_readl(McASP345_AUX_CLKSRC) != 0x00000300);
    
    	/* McASP2 AHCLKX source from OSC1
    	__raw_writel(0x00030000, McASP_AHCLK_CLKSRC);
    	while (__raw_readl(McASP_AHCLK_CLKSRC) != 0x00030000)
    		;*/
    
    	/* McASP2 AHCLKX source from AUDIO_CLKIN_0*/
    	__raw_writel(0x00000000, McASP_AHCLK_CLKSRC);
    	while (__raw_readl(McASP_AHCLK_CLKSRC) != 0x00000000);
    
    	/* select OSC1 as clock out*/
    	__raw_writel(0x00070000, CLKOUT_MUX);
    	while (__raw_readl(CLKOUT_MUX) != 0x00070000);
    
    
    	/* WDT */
    	/* For WDT to be functional, it needs to be first stopped by writing
    	 * the pattern 0xAAAA followed by 0x5555 in the WDT start/stop register.
    	 * After that a write-once register in Control module needs to be
    	 * configured to unfreeze the timer.
    	 * Note: It is important to stop the watchdog before unfreezing it
    	*/
    	__raw_writel(0xAAAA, WDT_WSPR);
    	while (__raw_readl(WDT_WWPS) != 0x0)
    		;
    	__raw_writel(0x5555, WDT_WSPR);
    	while (__raw_readl(WDT_WWPS) != 0x0)
    		;
    
    	/* Unfreeze WDT */
    	__raw_writel(0x13, WDT_UNFREEZE);
    }
    
    /*
     * inits clocks for PRCM as defined in clocks.h
     */
    void prcm_init(u32 in_ddr)
    {
    	/* Enable the control module */
    	__raw_writel(0x2, CM_ALWON_CONTROL_CLKCTRL);
    
    #ifdef CONFIG_SETUP_PLL
    	/* Setup the various plls */
    	audio_pll_config();
    	modena_pll_config();
    	ddr_pll_config();
    	dsp_pll_config();
    	iss_pll_config();
    
    	usb_pll_config();
    	/*  With clk freqs setup to desired values,
    	 *  enable the required peripherals
    	 */
    	per_clocks_enable();
    #endif
    }
    
    #ifdef CONFIG_DRIVER_TI_CPSW
    
    #define PADCTRL_BASE 0x48140000
    
    #if (1)
    #define PAD_CNTRL(num)  (*(volatile u32*)(PADCTRL_BASE + 0x800 + (num-1)*4))
    #else
    #define PAD58_CNTRL   (*(volatile unsigned int *)(PADCTRL_BASE + 0x08E4))
    #define PAD140_CNTRL  (*(volatile unsigned int *)(PADCTRL_BASE + 0x0A2C))
    #define PAD230_CNTRL  (*(volatile unsigned int *)(PADCTRL_BASE + 0x0B94))
    
    #define PAD204_CNTRL  (*(volatile unsigned int *)(PADCTRL_BASE + 0x0B2c))
    #define PAD205_CNTRL  (*(volatile unsigned int *)(PADCTRL_BASE + 0x0B30))
    #define PAD206_CNTRL  (*(volatile unsigned int *)(PADCTRL_BASE + 0x0B34))
    #define PAD207_CNTRL  (*(volatile unsigned int *)(PADCTRL_BASE + 0x0B38))
    #define PAD208_CNTRL  (*(volatile unsigned int *)(PADCTRL_BASE + 0x0B3c))
    #define PAD209_CNTRL  (*(volatile unsigned int *)(PADCTRL_BASE + 0x0B40))
    #define PAD210_CNTRL  (*(volatile unsigned int *)(PADCTRL_BASE + 0x0B44))
    #define PAD211_CNTRL  (*(volatile unsigned int *)(PADCTRL_BASE + 0x0B48))
    #define PAD212_CNTRL  (*(volatile unsigned int *)(PADCTRL_BASE + 0x0B4c))
    #define PAD213_CNTRL  (*(volatile unsigned int *)(PADCTRL_BASE + 0x0B50))
    #define PAD214_CNTRL  (*(volatile unsigned int *)(PADCTRL_BASE + 0x0B54))
    #define PAD215_CNTRL  (*(volatile unsigned int *)(PADCTRL_BASE + 0x0B58))
    #define PAD216_CNTRL  (*(volatile unsigned int *)(PADCTRL_BASE + 0x0B5c))
    #define PAD217_CNTRL  (*(volatile unsigned int *)(PADCTRL_BASE + 0x0B60))
    #define PAD218_CNTRL  (*(volatile unsigned int *)(PADCTRL_BASE + 0x0B64))
    #define PAD219_CNTRL  (*(volatile unsigned int *)(PADCTRL_BASE + 0x0B68))
    #define PAD220_CNTRL  (*(volatile unsigned int *)(PADCTRL_BASE + 0x0B6c))
    #define PAD221_CNTRL  (*(volatile unsigned int *)(PADCTRL_BASE + 0x0B70))
    #define PAD222_CNTRL  (*(volatile unsigned int *)(PADCTRL_BASE + 0x0B74))
    #define PAD223_CNTRL  (*(volatile unsigned int *)(PADCTRL_BASE + 0x0B78))
    #define PAD224_CNTRL  (*(volatile unsigned int *)(PADCTRL_BASE + 0x0B7c))
    #define PAD225_CNTRL  (*(volatile unsigned int *)(PADCTRL_BASE + 0x0B80))
    #define PAD226_CNTRL  (*(volatile unsigned int *)(PADCTRL_BASE + 0x0B84))
    #define PAD227_CNTRL  (*(volatile unsigned int *)(PADCTRL_BASE + 0x0B88))
    
    #define PAD232_CNTRL  (*(volatile unsigned int *)(PADCTRL_BASE + 0x0B9C))
    #define PAD233_CNTRL  (*(volatile unsigned int *)(PADCTRL_BASE + 0x0BA0))
    #define PAD234_CNTRL  (*(volatile unsigned int *)(PADCTRL_BASE + 0x0BA4))
    #define PAD235_CNTRL  (*(volatile unsigned int *)(PADCTRL_BASE + 0x0BA8))
    #define PAD236_CNTRL  (*(volatile unsigned int *)(PADCTRL_BASE + 0x0BAC))
    #define PAD237_CNTRL  (*(volatile unsigned int *)(PADCTRL_BASE + 0x0BB0))
    #define PAD238_CNTRL  (*(volatile unsigned int *)(PADCTRL_BASE + 0x0BB4))
    #define PAD239_CNTRL  (*(volatile unsigned int *)(PADCTRL_BASE + 0x0BB8))
    #define PAD240_CNTRL  (*(volatile unsigned int *)(PADCTRL_BASE + 0x0BBC))
    #define PAD241_CNTRL  (*(volatile unsigned int *)(PADCTRL_BASE + 0x0BC0))
    #define PAD242_CNTRL  (*(volatile unsigned int *)(PADCTRL_BASE + 0x0BC4))
    #define PAD243_CNTRL  (*(volatile unsigned int *)(PADCTRL_BASE + 0x0BC8))
    #define PAD244_CNTRL  (*(volatile unsigned int *)(PADCTRL_BASE + 0x0BCC))
    #define PAD245_CNTRL  (*(volatile unsigned int *)(PADCTRL_BASE + 0x0BD0))
    #define PAD246_CNTRL  (*(volatile unsigned int *)(PADCTRL_BASE + 0x0BD4))
    #define PAD247_CNTRL  (*(volatile unsigned int *)(PADCTRL_BASE + 0x0BD8))
    #define PAD248_CNTRL  (*(volatile unsigned int *)(PADCTRL_BASE + 0x0BDC))
    #define PAD249_CNTRL  (*(volatile unsigned int *)(PADCTRL_BASE + 0x0BE0))
    #define PAD250_CNTRL  (*(volatile unsigned int *)(PADCTRL_BASE + 0x0BE4))
    #define PAD251_CNTRL  (*(volatile unsigned int *)(PADCTRL_BASE + 0x0BE8))
    #define PAD252_CNTRL  (*(volatile unsigned int *)(PADCTRL_BASE + 0x0BEC))
    #define PAD253_CNTRL  (*(volatile unsigned int *)(PADCTRL_BASE + 0x0BF0))
    #define PAD254_CNTRL  (*(volatile unsigned int *)(PADCTRL_BASE + 0x0BF4))
    #define PAD255_CNTRL  (*(volatile unsigned int *)(PADCTRL_BASE + 0x0BF8))
    #define PAD256_CNTRL  (*(volatile unsigned int *)(PADCTRL_BASE + 0x0BFC))
    #define PAD257_CNTRL  (*(volatile unsigned int *)(PADCTRL_BASE + 0x0C00))
    #define PAD258_CNTRL  (*(volatile unsigned int *)(PADCTRL_BASE + 0x0C04))
    #endif
    
    #if 0
    static void cpsw_pad_config()
    {
    	volatile u32 val = 0;
    
    	/*configure pin mux for rmii_refclk,mdio_clk,mdio_d */
    	val = PAD232_CNTRL;
    	PAD232_CNTRL = (volatile unsigned int) (BIT(18) | BIT(0));
    	val = PAD233_CNTRL;
    	PAD233_CNTRL = (volatile unsigned int) (BIT(19) | BIT(17) | BIT(0));
    	val = PAD234_CNTRL;
    	PAD234_CNTRL = (volatile unsigned int) (BIT(19) | BIT(18) | BIT(17) |
    			BIT(0));
    
    	/*setup rgmii0/rgmii1 pins here*/
    	/* In this case we enable rgmii_en bit in GMII_SEL register and
    	 * still program the pins in gmii mode: gmii0 pins in mode 1*/
    	val = PAD235_CNTRL; /*rgmii0_rxc*/
    	PAD235_CNTRL = (volatile unsigned int) (BIT(18) | BIT(0));
    	val = PAD236_CNTRL; /*rgmii0_rxctl*/
    	PAD236_CNTRL = (volatile unsigned int) (BIT(18) | BIT(0));
    	val = PAD237_CNTRL; /*rgmii0_rxd[2]*/
    	PAD237_CNTRL = (volatile unsigned int) (BIT(18) | BIT(0));
    	val = PAD238_CNTRL; /*rgmii0_txctl*/
    	PAD238_CNTRL = (volatile unsigned int) BIT(0);
    	val = PAD239_CNTRL; /*rgmii0_txc*/
    	PAD239_CNTRL = (volatile unsigned int) BIT(0);
    	val = PAD240_CNTRL; /*rgmii0_txd[0]*/
    	PAD240_CNTRL = (volatile unsigned int) BIT(0);
    	val = PAD241_CNTRL; /*rgmii0_rxd[0]*/
    	PAD241_CNTRL = (volatile unsigned int) (BIT(18) | BIT(0));
    	val = PAD242_CNTRL; /*rgmii0_rxd[1]*/
    	PAD242_CNTRL = (volatile unsigned int) (BIT(18) | BIT(0));
    	val = PAD243_CNTRL; /*rgmii1_rxctl*/
    	PAD243_CNTRL = (volatile unsigned int) (BIT(18) | BIT(0));
    	val = PAD244_CNTRL; /*rgmii0_rxd[3]*/
    	PAD244_CNTRL = (volatile unsigned int) (BIT(18) | BIT(0));
    	val = PAD245_CNTRL; /*rgmii0_txd[3]*/
    	PAD245_CNTRL = (volatile unsigned int) BIT(0);
    	val = PAD246_CNTRL; /*rgmii0_txd[2]*/
    	PAD246_CNTRL = (volatile unsigned int) BIT(0);
    	val = PAD247_CNTRL; /*rgmii0_txd[1]*/
    	PAD247_CNTRL = (volatile unsigned int) BIT(0);
    	val = PAD248_CNTRL; /*rgmii1_rxd[1]*/
    	PAD248_CNTRL = (volatile unsigned int) (BIT(18) | BIT(0));
    	val = PAD249_CNTRL; /*rgmii1_rxc*/
    	PAD249_CNTRL = (volatile unsigned int) (BIT(18) | BIT(0));
    	val = PAD250_CNTRL; /*rgmii1_rxd[3]*/
    	PAD250_CNTRL = (volatile unsigned int) (BIT(18) | BIT(0));
    	val = PAD251_CNTRL; /*rgmii1_txd[1]*/
    	PAD251_CNTRL = (volatile unsigned int) (BIT(0));
    	val = PAD252_CNTRL; /*rgmii1_txctl*/
    	PAD252_CNTRL = (volatile unsigned int) (BIT(0));
    	val = PAD253_CNTRL; /*rgmii1_txd[0]*/
    	PAD253_CNTRL = (volatile unsigned int) (BIT(0));
    	val = PAD254_CNTRL; /*rgmii1_txd[2]*/
    	PAD254_CNTRL = (volatile unsigned int) (BIT(0));
    	val = PAD255_CNTRL; /*rgmii1_txc*/
    	PAD255_CNTRL = (volatile unsigned int) (BIT(0));
    	val = PAD256_CNTRL; /*rgmii1_rxd[0]*/
    	PAD256_CNTRL = (volatile unsigned int) (BIT(18) | BIT(0));
    	val = PAD257_CNTRL; /*rgmii1_txd[3]*/
    	PAD257_CNTRL = (volatile unsigned int) (BIT(0));
    	val = PAD258_CNTRL; /*rgmii1_rxd[2]*/
    	PAD258_CNTRL = (volatile unsigned int) (BIT(18) | BIT(0));
    }
    
    #else
    #define INPUT	1
    #define OUTPUT	0
    #define PHY_RESET_GPIO0_PIN	28
    #define PHY_EN_GPIO3_PIN	23
    #define PHY_WAKE_GPIO3_PIN	16
    
    static void enable_gpio_clk(void)
    {
    	printf("Enable GPIO_0 clock\n");
    	//Enable GPIO0 clock	
    	//printf("Writing CM_ALWON_GPIO_0_CLKCTRL:0x%x with 0x%x\n",CM_ALWON_GPIO_0_CLKCTRL, GPIO_CLKCTRL_VAL);
    	__raw_writel(GPIO_CLKCTRL_VAL, CM_ALWON_GPIO_0_CLKCTRL);
    	//printf("Validating CM_ALWON_GPIO_0_CLKCTRL reg write\n");
    	while(__raw_readl(CM_ALWON_GPIO_0_CLKCTRL) != GPIO_CLKCTRL_VAL);
    	 
    	printf("Enable GPIO_1 clock\n");
    	//Enable GPIO1, GPIO2, GPIO3, GPIO4, GPIO5 clock
    	//printf("Writing CM_ALWON_GPIO_1_CLKCTRL:0x%x with 0x%x\n",CM_ALWON_GPIO_1_CLKCTRL, GPIO_CLKCTRL_VAL);
    	__raw_writel(GPIO_CLKCTRL_VAL, CM_ALWON_GPIO_1_CLKCTRL); 
    	//printf("Validating CM_ALWON_GPIO_1_CLKCTRL reg write\n");
    	while(__raw_readl(CM_ALWON_GPIO_1_CLKCTRL) != GPIO_CLKCTRL_VAL);
    }
    
    static void set_pin_direction(unsigned int bank, unsigned int gpio, unsigned int is_input)
    {
    	printf("Setting gpio%d as: %s\n",gpio, ((is_input==INPUT)? "input":"output"));
    	unsigned int regAddr=bank+OMAP4_GPIO_OE;
    	unsigned int value = 0;
    	//printf("Reading register: %x\n",regAddr);
    	value = __raw_readl(regAddr);
    	if (is_input)
    		value |= 1 << gpio;
    	else
    		value &= ~(1 << gpio);
    	//printf("writing register: %x with %x\n",regAddr, value);
    	__raw_writel(value, regAddr);
    }
    
    static void set_pin_value(unsigned int bank, unsigned int gpio, unsigned int value)
    {
    	printf("Setting gpio%d with %d\n", gpio, value);
    	unsigned int regAddr=bank;
    	if (value)
    		regAddr += OMAP4_GPIO_SETDATAOUT;
    	else
    		regAddr += OMAP4_GPIO_CLEARDATAOUT;
    	value = 1 << gpio;
    	__raw_writel(value, regAddr);
    }
    #if 0
    static void config_phy_gpio( void )
    {
    	set_pin_direction(GPIO0_BASE, PHY_RESET_GPIO0_PIN, OUTPUT);
    	set_pin_direction(GPIO3_BASE, PHY_EN_GPIO3_PIN, OUTPUT);
    	set_pin_direction(GPIO3_BASE, PHY_WAKE_GPIO3_PIN, OUTPUT);
    }
    #endif
    static void reset_bcm89811_phy(void )
    {
    	set_pin_direction(GPIO0_BASE, PHY_RESET_GPIO0_PIN, OUTPUT);
        	set_pin_value(GPIO0_BASE, PHY_RESET_GPIO0_PIN, 0);
        	udelay(10000);
        	set_pin_value(GPIO0_BASE, PHY_RESET_GPIO0_PIN, 1);
    }
    #if 0
    static void cpsw_pad_config()
    {
    	volatile u32 val = 0;
    	printf("Ethernet pad muxing for RSB\n");
    	enable_gpio_clk();
    	/*configure pin mux for rmii_refclk,mdio_clk,mdio_d */
    	//E_GTXCLK. 50 MHz RMII Ref clock is an input to j5-prime and BCM89811. Its an external clock from oscilator
    	val = PAD232_CNTRL;
    	PAD232_CNTRL = (volatile unsigned int) (BIT(18) | BIT(0));
    	//E_MDC
    	val = PAD233_CNTRL;
    	PAD233_CNTRL = (volatile unsigned int) (BIT(19) | BIT(17) | BIT(0));
      	//E_MDIO
    	val = PAD234_CNTRL;
    	PAD234_CNTRL = (volatile unsigned int) (BIT(19) | BIT(18) | BIT(17) |
    			BIT(0));
    
    	/*setup rmii0/rmii1 pins here*/
    	/* In this case we enable rgmii_en bit in GMII_SEL register and
    	 * still program the pins in gmii mode: gmii0 pins in mode 2 */
    
    	
    	val = PAD236_CNTRL; /*E0_RXD0*/ 
    	PAD236_CNTRL = (volatile unsigned int) (BIT(19) | BIT(18) | BIT(2));
    	val = PAD237_CNTRL; /*E0_RXD1*/ //sample this pin to assign RMII mode RXD1 should be 1 during reset RXD[2]=0
    	PAD237_CNTRL = (volatile unsigned int) (BIT(19) | BIT(18) | BIT(17) | BIT(2));
    	val = PAD238_CNTRL; /*RMRXER*/ //PullDown 
    	PAD238_CNTRL = (volatile unsigned int) (BIT(19) | BIT(18) | BIT(2));
    	val = PAD239_CNTRL; /*E0_RXDV*/  //sample this pin to assign phy address 0x00000 or 0x00001 during reset
    	PAD239_CNTRL = (volatile unsigned int) (BIT(19) | BIT(18) | BIT(2));
    	val = PAD240_CNTRL; /*E0_TXD0*/ 
    	PAD240_CNTRL = (volatile unsigned int) (/*BIT(18) |*/ BIT(2));
    	val = PAD241_CNTRL; /*E0_TXD1*/ 
    	PAD241_CNTRL = (volatile unsigned int) (/*BIT(18) |*/ BIT(2));
    	val = PAD242_CNTRL; /*E0_TXEN*/ 
    	PAD242_CNTRL = (volatile unsigned int) (/*BIT(18) |*/ BIT(2));
    
    	val = PAD235_CNTRL; /*E0_PHY_EN--OUT*/ //set to 1
    	PAD235_CNTRL = (volatile unsigned int) (BIT(18) | /*BIT(17) |*/ BIT(7));
    	set_pin_direction(GPIO3_BASE, PHY_EN_GPIO3_PIN, OUTPUT);
    	set_pin_value(GPIO3_BASE, PHY_EN_GPIO3_PIN, 1);
    
    	val = PAD230_CNTRL; /*E0_PHY_INT_N*/
    	PAD230_CNTRL = (volatile unsigned int) (BIT(18) | BIT(7));
    
    	val = PAD224_CNTRL; /*E0_PHY_WAKE--OUT*/
    	PAD224_CNTRL = (volatile unsigned int) (BIT(18) | BIT(7));
    
            printf("Configuring PAD58_CNTRL for E0_RESET_N \n ");
    	val = PAD58_CNTRL; /*GP0[28]E0_RESET_N--OUT*/ //set to 1
    	PAD58_CNTRL = (volatile unsigned int) (BIT(18) |  /*BIT(17) |*/ BIT(7));
    
    	set_pin_direction(GPIO0_BASE, PHY_RESET_GPIO0_PIN, OUTPUT);
    	set_pin_value(GPIO0_BASE, PHY_RESET_GPIO0_PIN, 1);
    	printf("In loop\n");	
    	//while(1);
    	printf("Out loop\n");
    	val = PAD140_CNTRL; /*ETH0_INH_N*/
    	PAD140_CNTRL = (volatile unsigned int) (BIT(18) | BIT(7));	
    
    	unsigned int regAddr=0;
    	printf("Reading gpio register values back\n");
    	//PINCNTL58/
    	regAddr=0x481408E4;	
    	val = __raw_readl(regAddr);
    	printf("Reading register: 0x%x =value: 0x%x\n",regAddr, val);
    
    	//CM_ALWON_GPIO_0_CLKCTRL/
    	regAddr=0x4818155C;	
    	val = __raw_readl(regAddr);
    	printf("Reading register: 0x%x =value: 0x%x\n",regAddr, val);
    
    	//GPIO0.GPIO_CTRL/
    	regAddr=0x48032130;	
    	val = __raw_readl(regAddr);
    	printf("Reading register: 0x%x =value: 0x%x\n",regAddr, val);
    
    	//GPIO0.GPIO_OE/
    	regAddr=0x48032134;	
    	val = __raw_readl(regAddr);
    	printf("Reading register: 0x%x =value: 0x%x\n",regAddr, val);
    
    	//GPIO0.GPIO_DATAIN/
    	regAddr=0x48032138;	
    	val = __raw_readl(regAddr);
    	printf("Reading register: 0x%x =value: 0x%x\n",regAddr, val);
    
    	//GPIO0.GPIO_DATAOUT/
    	regAddr=0x4803213C;	
    	val = __raw_readl(regAddr);
    	printf("Reading register: 0x%x =value: 0x%x\n",regAddr, val);	
    }
    #else
    static void cpsw_pad_config()
    {
        printf("Ethernet pad muxing for RSB\n");
        enable_gpio_clk();
        /*configure pin mux for rmii_refclk,mdio_clk,mdio_d */
        //E_GTXCLK. 50 MHz RMII Ref clock is an input to j5-prime and BCM89811. Its an external clock from oscilator
        // refer to spreadsheet: 1_6_VW_RSB_HWAPP_J5_GPIO_2015_0924_05.xlsx
    
        PAD_CNTRL( 58) = 0xd0080;  // E0_reset_n, gpio0
        PAD_CNTRL(140) = 0xd0080;  // E0_inh_n,   gpio
        PAD_CNTRL(224) = 0x50080;  // E0_phy_wake
        PAD_CNTRL(230) = 0x70080;  // E0_phy_int
    
        PAD_CNTRL(232) = 0x50001;  // E0_gtxclk
        PAD_CNTRL(233) = 0xf0001;  // E0_mdc
        PAD_CNTRL(234) = 0xf0001;  // E0_mdio
        PAD_CNTRL(235) = 0xd0080;  // E0_phy_en, gpio3
        PAD_CNTRL(236) = 0xd0004;  // E0_rxd0
        PAD_CNTRL(237) = 0xd0004;  // E0_rxd1
        PAD_CNTRL(238) = 0xd0004;  // pulldown
        PAD_CNTRL(239) = 0xd0004;  // E0_RXDV
        PAD_CNTRL(240) = 0x50004;  // E0_TXD0
        PAD_CNTRL(241) = 0x50004;  // E0_TXD1
        PAD_CNTRL(242) = 0x50004;  // E0_TXEN
    
        // PAD235, phy en
        set_pin_direction(GPIO3_BASE, PHY_EN_GPIO3_PIN, OUTPUT);
        set_pin_value(GPIO3_BASE, PHY_EN_GPIO3_PIN, 1);
    
        // PAD58, reset
        reset_bcm89811_phy();
    
        // PAD140, inh ??
    }
    #endif
    #endif
    #endif /* CONFIG_DRIVER_TI_CPSW */
    
    struct nor_pad_config {
    	unsigned int offset;
    	unsigned int value;
    };
    
    static struct nor_pad_config nor_pad_cfg[] = {
    		{GPMC_D0, MODE(1) | INPUT_EN | PULL_DIS},
    		{GPMC_D1, MODE(1) | INPUT_EN | PULL_DIS},
    		{GPMC_D2, MODE(1) | INPUT_EN | PULL_DIS},
    		{GPMC_D3, MODE(1) | INPUT_EN | PULL_DIS},
    		{GPMC_D4, MODE(1) | INPUT_EN | PULL_DIS},
    		{GPMC_D5, MODE(1) | INPUT_EN | PULL_DIS},
    		{GPMC_D6, MODE(1) | INPUT_EN | PULL_DIS},
    		{GPMC_D7, MODE(1) | INPUT_EN | PULL_DIS},
    		{GPMC_D8, MODE(1) | INPUT_EN | PULL_DIS},
    		{GPMC_D9, MODE(1) | INPUT_EN | PULL_DIS},
    		{GPMC_D10, MODE(1) | INPUT_EN | PULL_DIS},
    		{GPMC_D11, MODE(1) | INPUT_EN | PULL_DIS},
    		{GPMC_D12, MODE(1) | INPUT_EN | PULL_DIS},
    		{GPMC_D13, MODE(1) | INPUT_EN | PULL_DIS},
    		{GPMC_D14, MODE(1) | INPUT_EN | PULL_DIS},
    		{GPMC_D15, MODE(1) | INPUT_EN | PULL_DIS},
    		{GPMC_A1, MODE(5) | PULL_UP_EN},
    		{GPMC_A2, MODE(5) | PULL_UP_EN},
    		{GPMC_A3, MODE(5) | PULL_UP_EN},
    		{GPMC_A4, MODE(5) | PULL_UP_EN},
    		{GPMC_A5, MODE(5) | PULL_UP_EN},
    		{GPMC_A6, MODE(5)},
    		{GPMC_A7, MODE(5)},
    		{GPMC_A8, MODE(5)},
    		{GPMC_A9, MODE(5)},
    		{GPMC_A10, MODE(5) | PULL_UP_EN},
    		{GPMC_A11, MODE(5)},
    		{GPMC_A12, MODE(5)},
    		{GPMC_A13, MODE(5) | PULL_UP_EN},
    		{GPMC_A14, MODE(5) | PULL_UP_EN},
    		{GPMC_A15, MODE(5)},
    		{GPMC_A16, MODE(1)},
    		{GPMC_A17, MODE(1)},
    		{GPMC_A18, MODE(1)},
    		{GPMC_A19, MODE(1)},
    		{GPMC_A20, MODE(1) | PULL_UP_EN},
    		//{GPMC_A26, MODE(4) | PULL_UP_EN}, //Nid added configured as GPMC_A26
    		{GPMC_A26, MODE(5) | PULL_UP_EN}, //Nid added configured as GPMC_A0
    #if 0 //Not used in RSB
    		{GPMC_A21, MODE(1)},
    		{GPMC_A22, MODE(1) | PULL_UP_EN},
    		{GPMC_A23, MODE(1)},
    		{GPMC_A24, MODE(2) | PULL_UP_EN},
    		{GPMC_A25, MODE(2)},
    		{GPMC_A27, MODE(8) | PULL_UP_EN},
    #endif
    		{GPMC_CS0_REG, MODE(1) | PULL_UP_EN},
    		{GPMC_OEN, MODE(1) | PULL_UP_EN},
    		{GPMC_WEN, MODE(1) | PULL_UP_EN},
    		{0},
    };
    
    /*********************************************************************
     *
     * nor_pad_config_mux - configure the pin mux for NOR
     *
     *********************************************************************/
    static void nor_pad_config_mux(void)
    {
    	u8 i = 0;
    
    	while (nor_pad_cfg[i].offset != 0x0) {
    		*(volatile u32 *)(nor_pad_cfg[i].offset) =
    			nor_pad_cfg[i].value;
    		i++;
    	}
    }
    
    /*
     * baord specific muxing of pins
     */
    void set_muxconf_regs(void)
    {
    	u32 i, add, val;
    	u32 pad_conf[] = {
    #include "mux.h"
    	};
    
    	for (i = 0; i < N_PINS; i++) {
    		add = PIN_CTRL_BASE + (i*4);
    		val = __raw_readl(add);
    		val |= pad_conf[i];
    		__raw_writel(val, add);
    	}
    	/* MMC/SD pull-down enable */
    	__raw_writel(0x000C0040, 0x48140928);
    	/*Nidd added for eMMC: PINCNTL73  - MMC2_SDCD*/
    	__raw_writel(0x00050040, 0x48140920);	
    }
    
    void unlock_pll_control_mmr()
    {
    	/* ??? */
    	__raw_writel(0x1EDA4C3D, 0x481C5040);
    	__raw_writel(0x2FF1AC2B, 0x48140060);
    	__raw_writel(0xF757FDC0, 0x48140064);
    	__raw_writel(0xE2BC3A6D, 0x48140068);
    	__raw_writel(0x1EBF131D, 0x4814006c);
    	__raw_writel(0x6F361E05, 0x48140070);
    
    }
    
    /*
     * early system init of muxing and clocks.
     */
    void s_init(u32 in_ddr)
    {
    	/* TODO: Revisit enabling of I/D-cache in 1st stage */
    #if 0
    	icache_enable();
    	dcache_enable();
    #endif
    
    	/*
    	 * Disable Write Allocate on miss to avoid starvation of other masters
    	 * (than A8).
    	 *
    	 * Ref TI811X Erratum: TODO
    	 */
    	l2_disable_wa();
    
    	/* Can be removed as A8 comes up with L2 enabled */
    	l2_cache_enable();
    	unlock_pll_control_mmr();
    	/* Setup the PLLs and the clocks for the peripherals */
    	prcm_init(in_ddr);
    #ifdef CONFIG_TI811X_CONFIG_DDR
    	if (!in_ddr)
    		config_ti811x_ddr();	/* Do DDR settings */
    #endif
    }
    
    /*
     * Reset the board
     */
    void reset_cpu(ulong addr)
    {
    	addr = __raw_readl(PRM_DEVICE_RSTCTRL);
    	addr &= ~BIT(1);
    	addr |= BIT(1);
    	__raw_writel(addr, PRM_DEVICE_RSTCTRL);
    }
    
    #ifdef CONFIG_DRIVER_TI_CPSW
    
    #if 0
    /* TODO : Check for the board specific PHY */
    static void phy_init(char *name, int addr)
    {
    	unsigned short val;
    	unsigned int   cntr = 0;
    
    	miiphy_reset(name, addr);
    
    	udelay(100000);
    
    	/* Enable Autonegotiation */
    	if (miiphy_read(name, addr, PHY_BMCR, &val) != 0) {
    		printf("failed to read bmcr\n");
    		return;
    	}
    	val |= PHY_BMCR_DPLX | PHY_BMCR_AUTON | PHY_BMCR_100_MBPS;
    	if (miiphy_write(name, addr, PHY_BMCR, val) != 0) {
    		printf("failed to write bmcr\n");
    		return;
    	}
    	miiphy_read(name, addr, PHY_BMCR, &val);
    
    	/* Setup GIG advertisement */
    	miiphy_read(name, addr, PHY_1000BTCR, &val);
    	val |= PHY_1000BTCR_1000FD;
    	val &= ~PHY_1000BTCR_1000HD;
    	miiphy_write(name, addr, PHY_1000BTCR, val);
    	miiphy_read(name, addr, PHY_1000BTCR, &val);
    
    	/* Setup general advertisement */
    	if (miiphy_read(name, addr, PHY_ANAR, &val) != 0) {
    		printf("failed to read anar\n");
    		return;
    	}
    	val |= (PHY_ANLPAR_10 | PHY_ANLPAR_10FD | PHY_ANLPAR_TX |
    		PHY_ANLPAR_TXFD);
    	if (miiphy_write(name, addr, PHY_ANAR, val) != 0) {
    		printf("failed to write anar\n");
    		return;
    	}
    	miiphy_read(name, addr, PHY_ANAR, &val);
    
    	/* Restart auto negotiation*/
    	miiphy_read(name, addr, PHY_BMCR, &val);
    	val |= PHY_BMCR_RST_NEG;
    	miiphy_write(name, addr, PHY_BMCR, val);
    
    	/*check AutoNegotiate complete - it can take upto 3 secs*/
    	do {
    		udelay(40000);
    		cntr++;
    
    		if (!miiphy_read(name, addr, PHY_BMSR, &val)) {
    			if (val & PHY_BMSR_AUTN_COMP)
    				break;
    		}
    	} while (cntr < 250);
    
    	if (!miiphy_read(name, addr, PHY_BMSR, &val)) {
    		if (!(val & PHY_BMSR_AUTN_COMP))
    			printf("Auto negotitation failed\n");
    	}
    }
    #else
    //bcm89811_phy_init()
    static void phy_init(char *name, int addr)
    {
    	u16 data=0;
    	u32 timeout = 0;
        	u32 phyid;
    
        static int onetime_init = 0;
    
        if (onetime_init)
            return;
    
        miiphy_read(name, addr, ETH_TRCV_PHY_ID1_REG, &data);
        phyid = (u32)data << 16;
        miiphy_read(name, addr, ETH_TRCV_PHY_ID2_REG, &data);
        phyid |= data;
    
        printf("Initializing BCM89811 Eth Phy: Driver:%s addr:%d phyid:%08lx\n",name, addr, phyid);
    
        miiphy_read(name, addr, ETH_TRCV_CTRL_REG, &data);
    #if 1
    	//printf("/*******************begin EMI optimization portion*********************************/\n"); 
      		//App.WrMii PORT, MIICTL, &H8000&     ' reset
    	miiphy_write(name, addr, ETH_BCM89811_REG_MIICTL, ETH_TRCV_CTRL_RESET_ENABLE);
    
      	udelay(100000);
    	miiphy_read(name, addr, ETH_TRCV_CTRL_REG, &data);
      	/* self clearing bit */
      	while((data & ETH_TRCV_CTRL_RESET_ENABLE) != RESET)
      	{
    	    miiphy_read(name, addr, ETH_TRCV_CTRL_REG,&data);
    	    printf("waiting to release phy from reset: ETH_TRCV_CTRL_REG: %x\n", data);	
      	}
    	//printf("ETH_TRCV_CTRL_REG: 0x%x\n", data);
     	//App.WrMii PORT, &H001E&, &H0028&   '
     	//App.WrMii PORT, &H001F&, &H0C00&  
    	miiphy_write(name, addr, ETH_BCM89811_REG_RDPADDR, 0x0028);
    	miiphy_write(name, addr, ETH_BCM89811_REG_RDPRW, 0x0C00);
    
      	//App.WrMii PORT, &H001E&, &H0312&   '
      	//App.WrMii PORT, &H001F&, &H030b&   '
    	miiphy_write(name, addr, ETH_BCM89811_REG_RDPADDR, 0x0312);
    	miiphy_write(name, addr, ETH_BCM89811_REG_RDPRW, 0x030b);
      
      	//App.WrMii PORT, &H001E&, &H030A&   '
      	//App.WrMii PORT, &H001F&, &H34C0& 
    	miiphy_write(name, addr, ETH_BCM89811_REG_RDPADDR, 0x030A);
    	miiphy_write(name, addr, ETH_BCM89811_REG_RDPRW, 0x34C0);
      
      	//App.WrMii PORT, &H001E&, &H0166&   '
      	//App.WrMii PORT, &H001F&, &H0020&  
    	miiphy_write(name, addr, ETH_BCM89811_REG_RDPADDR, 0x0166);
    	miiphy_write(name, addr, ETH_BCM89811_REG_RDPRW, 0x0020);
    	
      	//App.WrMii PORT, &H001E&, &H012D&   '
      	//App.WrMii PORT, &H001F&, &H9B52&   '
    	miiphy_write(name, addr, ETH_BCM89811_REG_RDPADDR, 0x012D);
    	miiphy_write(name, addr, ETH_BCM89811_REG_RDPRW, 0x9B52);   
      
    	//App.WrMii PORT, &H001E&, &H012E&   '
      	//App.WrMii PORT, &H001F&, &HA04D&   '
    	miiphy_write(name, addr, ETH_BCM89811_REG_RDPADDR, 0x012E);
    	miiphy_write(name, addr, ETH_BCM89811_REG_RDPRW, 0xA04D);
    
      	//App.WrMii PORT, &H001E&, &H0123&   '
      	//App.WrMii PORT, &H001F&, &H00C0& 
    	miiphy_write(name, addr, ETH_BCM89811_REG_RDPADDR, 0x0123);
    	miiphy_write(name, addr, ETH_BCM89811_REG_RDPRW, 0x00C0); 
    
      	//App.WrMii PORT, &H001E&, &H0154&   '
      	//App.WrMii PORT, &H001F&, &H81c4&  
    	miiphy_write(name, addr, ETH_BCM89811_REG_RDPADDR, 0x0154);
    	miiphy_write(name, addr, ETH_BCM89811_REG_RDPRW, 0x81c4);
    
      	//data = (ETH_BCM89811_MII_PAD_SETTING * 2048); //0x0000
      	//App.WrMii PORT, &H001E&, &H0811&   '
      	//App.WrMii PORT, &H001F&, v   '
    	//miiphy_write(name, addr, ETH_BCM89811_REG_RDPADDR, 0x0811);
    	//miiphy_write(name, addr, ETH_BCM89811_REG_RDPRW, data);
    
      	//data = 0x0064; 
      	//App.WrMii PORT, &H001E&, &H01D3&   '
      	//App.WrMii PORT, &H001F&, v   '
    	miiphy_write(name, addr, ETH_BCM89811_REG_RDPADDR, 0x01D3);
    	miiphy_write(name, addr, ETH_BCM89811_REG_RDPRW, 0x0064);
    
      	//App.WrMii PORT, &H001E&, &H01C1&   ' 
      	//App.WrMii PORT, &H001F&, &HA5F7& 
    	miiphy_write(name, addr, ETH_BCM89811_REG_RDPADDR, 0x01C1);
    	miiphy_write(name, addr, ETH_BCM89811_REG_RDPRW, 0xA5F7); 
    
      	//App.WrMii PORT, &H001E&, &H0028&   '
      	//App.WrMii PORT, &H001F&, &H0400& 
    	miiphy_write(name, addr, ETH_BCM89811_REG_RDPADDR, 0x0028);
    	miiphy_write(name, addr, ETH_BCM89811_REG_RDPRW, 0x0400); 
    /**************************END EMI optimization portion****************************/ 
    #endif
    
    /**************************begin LED setup portion*********************************/ 
    
      	//App.WrMii PORT, &H001E&, &H001D&   '
      	//App.WrMii PORT, &H001F&, &H3411&   '
    	miiphy_write(name, addr, ETH_BCM89811_REG_RDPADDR, 0x001D);
    	miiphy_write(name, addr, ETH_BCM89811_REG_RDPRW, 0x3411);
    
      	//App.WrMii PORT, &H001E&, &H0820&   '
      	//App.WrMii PORT, &H001F&, &H0401&   '
    	miiphy_write(name, addr, ETH_BCM89811_REG_RDPADDR, 0x0820);
    	miiphy_write(name, addr, ETH_BCM89811_REG_RDPRW, 0x0401);
    
    /**************************END LED setup portion***********************************/ 
    #if 0
    /**************************begin MACconfiguration portion**************************/ 
      	//If  RGMII_Cnfg Then  ' if RGMII_Config is set, configure as RGMII
    	if(ETH_BCM89811_RGMII_Cnfg){
        		//App.WrMii PORT, &H001E&, &H0045&   ' unset MII reverse
        		//App.WrMii PORT, &H001F&, &H0000& 
    		miiphy_write(name, addr, ETH_BCM89811_REG_RDPADDR, 0x0045);
    		miiphy_write(name, addr, ETH_BCM89811_REG_RDPRW, 0x0000);  
         
        		//App.WrMii PORT, &H001E&, &H002F&   ' turn On RGMII mode 
        		//App.WrMii PORT, &H001F&, &HF1E7&   '
    		miiphy_write(name, addr, ETH_BCM89811_REG_RDPADDR, 0x002F);
    		miiphy_write(name, addr, ETH_BCM89811_REG_RDPRW, 0xF1E7);
     	
        		printf("Setting Phy Address 0x%x into RGMII mode\n",ETH_BCM89811_PORT);
        
        	}else if(ETH_BCM89811_MII_Reverse_Cnfg){
    		 
        		//App.WrMii PORT, &H001E&, &H002F&   ' turn off RGMII mode 
        		//App.WrMii PORT, &H001F&, &HF167&  
    		miiphy_write(name, addr, ETH_BCM89811_REG_RDPADDR, 0x002F);
    		miiphy_write(name, addr, ETH_BCM89811_REG_RDPRW, 0xF167); 
    
        		//App.WrMii PORT, &H001E&, &H0045&   'set MII reverse
        		//App.WrMii PORT, &H001F&, &H0700&  
    		miiphy_write(name, addr, ETH_BCM89811_REG_RDPADDR, 0x0045);
    		miiphy_write(name, addr, ETH_BCM89811_REG_RDPRW, 0x0700);  
    
    		printf("Setting Phy address 0x%x into RvMII mode\n",ETH_BCM89811_PORT);
      	}else{
    		//Else  ' otherwise, set to MII_LITE
        		//App.WrMii PORT, &H001E&, &H002F&   ' turn off RGMII mode 
        		//App.WrMii PORT, &H001F&, &HF167& 
    		miiphy_write(name, addr, ETH_BCM89811_REG_RDPADDR, 0x002F);
    		miiphy_write(name, addr, ETH_BCM89811_REG_RDPRW, 0xF167);  
        		//App.WrMii PORT, &H001E&, &H0045&   ' unset MII reverse
        		//App.WrMii PORT, &H001F&, &H0000&  
    		miiphy_write(name, addr, ETH_BCM89811_REG_RDPADDR, 0x0045);
    		miiphy_write(name, addr, ETH_BCM89811_REG_RDPRW, 0x0000); 
    		printf("Setting Phy Address 0x%x into MII Lite mode\n",ETH_BCM89811_PORT);
    	}
    /**************************end MACconfiguration portion***************************/ 
    #endif
    /**************************begin mdi configuration portion************************/ 
      
    		if(ETH_BCM89811_MasterConfig){
    			printf("Setting PORT 0:0%d to 100Mbps 1Pair Master\n",ETH_BCM89811_PORT);
      			//App.WrMii PORT, MIICTL, &H0208&   ' set phy to 100M1P, Master
    			miiphy_write(name, addr, ETH_BCM89811_REG_MIICTL, 0x0208);
      		}else{                                     
           			printf("Setting PORT 0:0%d to 100Mbps 1Pair Slave\n",ETH_BCM89811_PORT);
    			//App.WrMii PORT, MIICTL, &H0200&   ' set phy to 100M1P, Slave
    			miiphy_write(name, addr, ETH_BCM89811_REG_MIICTL, 0x0200);
      		}
    
    /**************************end mdi configuration portion**************************/ 
    
    		if(ETH_BCM89811_Kill_PORT == ETH_BCM89811_PORT)
    		{
        			printf("Disabling PHY PORT 0:0%d \n",ETH_BCM89811_PORT);
      			if (ETH_BCM89811_RGMII_Cnfg)
    			{
        				//App.WrMii PORT, &H001E&, &H0300&   '
        				//App.WrMii PORT, &H001F&, &H0000&   '
    				miiphy_write(name, addr, ETH_BCM89811_REG_RDPADDR, 0x0300);
    				miiphy_write(name, addr, ETH_BCM89811_REG_RDPRW, 0x0000);
    
        				//App.WrMii PORT, MIICTL, &H0A00&    ' superisolate and ONLY
    				miiphy_write(name, addr, ETH_BCM89811_REG_MIICTL, 0x0A00);
        				//App.WrMii PORT, &H001E&, &H0300&   '
        				//App.WrMii PORT, &H001F&, &H00001&   '
    				miiphy_write(name, addr, ETH_BCM89811_REG_RDPADDR, 0x0300);
    				miiphy_write(name, addr, ETH_BCM89811_REG_RDPRW, 0x0001);
    
        				printf("Setting PHY PORT 0:0%d in internal loopback\n",ETH_BCM89811_PORT);
        				//App.WrMii PORT, &H00&, &H4A00& 
    				miiphy_write(name, addr, ETH_BCM89811_REG_MIICTL, 0x4A00);
      			}else{ 
        				//App.WrMii PORT, MIICTL, &H0E00&    ' isolate and super isolate
        				miiphy_write(name, addr, ETH_BCM89811_REG_MIICTL, 0x0E00);
    
        				//App.WrMii PORT, &H001E&, &H00FC&   '
        				//App.WrMii PORT, &H001F&, &H0140&   '
    				miiphy_write(name, addr, ETH_BCM89811_REG_RDPADDR, 0x00FC);
    				miiphy_write(name, addr, ETH_BCM89811_REG_RDPRW, 0x0140);
    
        				//App.WrMii PORT, &H001E&, &H0300&   '
        				//App.WrMii PORT, &H001F&, &H0000&   '
    				miiphy_write(name, addr, ETH_BCM89811_REG_RDPADDR, 0x0300);
    				miiphy_write(name, addr, ETH_BCM89811_REG_RDPRW, 0x0000);
    
        				//App.WrMii PORT, MIICTL, &H2D00&    ' isolate and super isolate
    				miiphy_write(name, addr, ETH_BCM89811_REG_MIICTL, 0x2D00);
    
        				//App.WrMii PORT, &H001E&, &H0300&   '
        				//App.WrMii PORT, &H001F&, &H0001&   '
    				miiphy_write(name, addr, ETH_BCM89811_REG_RDPADDR, 0x0300);
    				miiphy_write(name, addr, ETH_BCM89811_REG_RDPRW, 0x0001);
      			} 
    		}
    		/* check link status */
      		timeout = 0;
    		data = 0;
        		miiphy_read(name, addr,ETH_TRCV_STATUS_REG,&data);
         
        		while(!(data & ETH_TRCV_STATUS_LINK_STATUS_PASS) && (timeout < ETH_TRCV_PHY_READ_TO))
        		{
           			miiphy_read(name, addr,ETH_TRCV_STATUS_REG,&data);
          			timeout++;
        		}
        		//printf("ETH_TRCV_STATUS_REG: 0x%x\n", data);
        		if(timeout == ETH_TRCV_PHY_READ_TO)
        		{
          			printf("link status failed\n");
          			return;	
        		}
      		//EthTrcvDriverState = ETHTRCV_STATE_ACTIVE;
    		
            onetime_init = 1;
      		printf("link status active: ");
    		if(data & ETH_TRCV_STATUS_100M_1PAIR)
    			printf("1 Pair 100 Mbps\n ");
    		else
    			printf("\n");
      		return; 
    
    }
    
    #endif
    static void cpsw_control(int enabled)
    {
    	/* nothing for now */
    	/* TODO : VTP was here before */
    }
    
    static struct cpsw_slave_data cpsw_slaves[] = {
    	{
    		.slave_reg_ofs	= 0x208,
    		.sliver_reg_ofs	= 0xd80,
    		//.phy_id		= 0,
    		.phy_id		= 1,
    	},
    	{
    		.slave_reg_ofs	= 0x308,
    		.sliver_reg_ofs	= 0xdc0,
    		//.phy_id		= 1,
    		.phy_id		= 2, //to avoid conflict with EMAC0
    	},
    };
    
    static struct cpsw_platform_data cpsw_data = {
    	.mdio_base		= TI811X_CPSW_MDIO_BASE,
    	.cpsw_base		= TI814X_CPSW_BASE,
    	.mdio_div		= 0xff,
    	.channels		= 8,
    	.cpdma_reg_ofs		= 0x800,
    	.cpdma_sram_ofs		= 0xa00,
    	.slaves			= 1,
    	.slave_data		= cpsw_slaves,
    	.ale_reg_ofs		= 0xd00,
    	.ale_entries		= 1024,
    	.host_port_reg_ofs	= 0x108,
    	.hw_stats_reg_ofs	= 0x900,
    	.mac_control		= (BIT(15) | BIT(5) | BIT(0)),/* BIT(15)RMII/RGMII Gasket Control */  /*BIT(0)Full Duplex*/ /*BIT(5) MIIEN */
    	.control		= cpsw_control,
    	.phy_init		= phy_init,
    	.host_port_num		= 0,
    	.bd_ram_ofs		= 0x2000,
    };
    
    extern void cpsw_eth_set_mac_addr(const u_int8_t *addr);
    
    int board_eth_init(bd_t *bis)
    {
    	u_int8_t mac_addr[6];
    	u_int32_t mac_hi, mac_lo;
    	u_int32_t eth_clock_config;
    
    #ifdef CONFIG_DRIVER_TI_CPSW
    	cpsw_pad_config();
    #endif
    
    	eth_clock_config = __raw_readl(SMA1);
    	printf("Ethernet clocking: 0x%x\n", eth_clock_config);
    
    	if (!eth_getenv_enetaddr("ethaddr", mac_addr)) {
    		char mac_addr_env[20];
    
    		printf("<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;
    		/* set the ethaddr variable with MACID detected */
    		sprintf(mac_addr_env, "%02x:%02x:%02x:%02x:%02x:%02x",
    			mac_addr[0], mac_addr[1], mac_addr[2],
    			mac_addr[3], mac_addr[4], mac_addr[5]);
    		eth_setenv_enetaddr("ethaddr", (unsigned char *)mac_addr_env);
    	}
    
    	if (is_valid_ether_addr(mac_addr)) {
    		printf("Detected MACID:%x:%x:%x:%x:%x:%x\n", mac_addr[0],
    			mac_addr[1], mac_addr[2], mac_addr[3],
    			mac_addr[4], mac_addr[5]);
    		cpsw_eth_set_mac_addr(mac_addr);
    	} else {
    		printf("Caution:using static MACID!! Set <ethaddr> variable\n");
    	}
    
    	return cpsw_register(&cpsw_data);
    }
    #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 *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 */
    
    #ifdef CONFIG_GENERIC_MMC
    int board_mmc_init(bd_t *bis)
    {
    	omap_mmc_init(0);
    	/*eMMC in RSB*/
    	omap_mmc_init(1);
    	return 0;
    }
    #endif
    

    mux.h

  • Nihad,

    Can you provide me full u-boot console log?

    I do not see rsb_emmc_mux_init() in your evm.c file, can you comment on that point?

    Are you able to access/read/write the MMC2/eMMC?

    See also if the below pointers will help:
    e2e.ti.com/.../259685
    e2e.ti.com/.../368701
    e2e.ti.com/.../299255

    BR
    Pavel
  • Pavel,

    Sorry I have shared wrong evm.c. See the attachment.

    U-Boot 2010.06-00011-g234d700-dirty (Nov 10 2015 - 20:47:05)                    

    TI811X-GP rev 1.1                                                              

    ARM clk: 600MHz                                                                

    DDR clk: 333MHz                                                                

    I2C:   ready                                                                    

    DRAM:  1 GiB                                                                    

    NAND:  HW ECC BCH8 Selected                                                    

    No NAND device found!!!                                                        

    0 MiB                                                                          

    MMC:   Nid: mmc_initialize: board_mmc_init                                      

    rsb_emmc_mux_init for RSB                                                      

    Setting gpio29 as: output                                                      

    Setting gpio29 with 0                                                          

    Nid: omap_mmc_init: MMC:0                                                      

    Nid: omap_mmc_init: registering mmc0                                            

    Nid: omap_mmc_init: MMC:1                                                      

    Nid: omap_mmc_init: mmc2: mmc_base: 0x47810100                                  

    Nid: omap_mmc_init: mmc2:                                                      

    Nid: omap_mmc_init: registering mmc1                                            

    Nid11: OMAP SD/MMC: 0, Nid11: OMAP SD/MMC: 1                                    

    Nid: mmc_init:                                                                  

    Nid: mmc_init_setup: mmc_base: 0x481d8100                                      

    Nid: mmc_set_bus_width: bus width = 1                                          

    Nid: mmc_startup:                                                              

    Nid: mmc_startup: err=0                                                        

    Nid: mmc_startup: its an SD card                                                

    Nid: mmc_startup: high capacity                                                

    Nid: mmc_startup: Capacity1: 31257600                                          

    Nid: mmc_startup: Capacity2: -1175977984                                        

    Nid2: mmc_startup: SD card                                                      

    Nid: mmc_set_bus_width: bus width = 4                                          

    *** Warning - bad CRC or MMC, using default environment                        

    @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@            

    @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@            

    @@                                                               @@            

    @@                                                               @@            

    @@                                                               @@            

    @@                                                               @@            

    @@                                                               @@            

    @@     88888888888 8888888 .d8888b.   d888    d888               @@            

    @@         888       888  d88P  Y88b d8888   d8888               @@            

    @@         888       888  Y88b. d88P   888     888               @@            

    @@         888       888    Y88888     888     888    888  888   @@            

    @@         888       888  .d8P88Y8b.   888     888      Y8 8P    @@            

    @@         888       888  888    888   888     888       88      @@            

    @@         888       888  Y88b  d88P   888     888     .d8 8b.   @@            

    @@         888     8888888  Y8888P  8888888  8888888   888 888   @@            

    @@                                                               @@            

    @@                                                               @@            

    @@                                                               @@            

    @@                                                               @@            

    @@                                                               @@            

    @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@            

    @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@            

    Net:   Ethernet pad muxing for RSB                                              

    Enable GPIO_0 clock                                                            

    Enable GPIO_1 clock                                                            

    Setting gpio23 as: output                                                      

    Setting gpio23 with 1                                                          

    Setting gpio28 as: output                                                      

    Setting gpio28 with 0                                                          

    Setting gpio28 with 1                                                          

    Ethernet clocking: 0x0                                                          

    <ethaddr> not set. Reading from E-fuse                                          

    Detected MACID:ec:11:27:d5:f2:c4                                                

    cpsw                                                                            

    Hit any key to stop autoboot:  0                                                

    TI811X_EVM#mmcinfo 1                                                            

    Nid: mmc_init:                                                                  

    Nid: mmc_init_setup: mmc_base: 0x47810100                                      

    Nid: mmc_set_bus_width: bus width = 1                                          

    Nid: mmc_set_ios: bus width set to 8                                            

    Nid: mmc_set_ios: bus width set to 8                                            

    Nid: mmc_startup:                                                              

    Nid: mmc_startup: err=0                                                        

    Nid: mmc_startup: its an MMC                                                    

    Nid: mmc_startup: high capacity                                                

    Nid: mmc_startup: Capacity1: 0                                                  

    Nid: mmc_startup: Capacity2: 0                                                  

    Device: OMAP SD/MMC                                                            

    Manufacturer ID: fe                                                            

    OEM: 14e                                                                        

    Name: MMC04                                                                    

    Tran Speed: 25000000                                                            

    Rd Block Len: 512                                                              

    MMC version 4.0                                                                

    High Capacity: Yes                                                              

    Capacity: 2199023255552                                                        

    Bus Width: 1-bit                                                                

    TI811X_EVM#

    3833.evm.c
    /*
     * Copyright (C) 2009, Texas Instruments, Incorporated
     *
     * See file CREDITS for list of people who contributed to this
     * project.
     *
     * 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 <config.h>
    #include <common.h>
    #include <asm/cache.h>
    #include <asm/arch/cpu.h>
    #include <asm/arch/ddr_defs.h>
    #include <asm/arch/hardware.h>
    #include <asm/arch/sys_proto.h>
    #include <asm/arch/mmc_host_def.h>
    #include <asm/arch/clock.h>
    #include <asm/arch/mem.h>
    #include <asm/arch/nand.h>
    #include <linux/mtd/nand.h>
    #include <nand.h>
    #include <net.h>
    #include <miiphy.h>
    #include <netdev.h>
    #include <i2c.h>
    #include "bcm89811phy.h"
    
    #ifdef CONFIG_TI811X_CONFIG_DDR
    static void config_ti811x_ddr(void);
    #endif
    
    DECLARE_GLOBAL_DATA_PTR;
    
    #define PADCTRL_BASE 0x48140000
    
    #if (1)
    #define PAD_CNTRL(num)  (*(volatile u32*)(PADCTRL_BASE + 0x800 + (num-1)*4))
    #else
    #define PAD58_CNTRL   (*(volatile unsigned int *)(PADCTRL_BASE + 0x08E4))
    #define PAD140_CNTRL  (*(volatile unsigned int *)(PADCTRL_BASE + 0x0A2C))
    #define PAD230_CNTRL  (*(volatile unsigned int *)(PADCTRL_BASE + 0x0B94))
    
    #define PAD204_CNTRL  (*(volatile unsigned int *)(PADCTRL_BASE + 0x0B2c))
    #define PAD205_CNTRL  (*(volatile unsigned int *)(PADCTRL_BASE + 0x0B30))
    #define PAD206_CNTRL  (*(volatile unsigned int *)(PADCTRL_BASE + 0x0B34))
    #define PAD207_CNTRL  (*(volatile unsigned int *)(PADCTRL_BASE + 0x0B38))
    #define PAD208_CNTRL  (*(volatile unsigned int *)(PADCTRL_BASE + 0x0B3c))
    #define PAD209_CNTRL  (*(volatile unsigned int *)(PADCTRL_BASE + 0x0B40))
    #define PAD210_CNTRL  (*(volatile unsigned int *)(PADCTRL_BASE + 0x0B44))
    #define PAD211_CNTRL  (*(volatile unsigned int *)(PADCTRL_BASE + 0x0B48))
    #define PAD212_CNTRL  (*(volatile unsigned int *)(PADCTRL_BASE + 0x0B4c))
    #define PAD213_CNTRL  (*(volatile unsigned int *)(PADCTRL_BASE + 0x0B50))
    #define PAD214_CNTRL  (*(volatile unsigned int *)(PADCTRL_BASE + 0x0B54))
    #define PAD215_CNTRL  (*(volatile unsigned int *)(PADCTRL_BASE + 0x0B58))
    #define PAD216_CNTRL  (*(volatile unsigned int *)(PADCTRL_BASE + 0x0B5c))
    #define PAD217_CNTRL  (*(volatile unsigned int *)(PADCTRL_BASE + 0x0B60))
    #define PAD218_CNTRL  (*(volatile unsigned int *)(PADCTRL_BASE + 0x0B64))
    #define PAD219_CNTRL  (*(volatile unsigned int *)(PADCTRL_BASE + 0x0B68))
    #define PAD220_CNTRL  (*(volatile unsigned int *)(PADCTRL_BASE + 0x0B6c))
    #define PAD221_CNTRL  (*(volatile unsigned int *)(PADCTRL_BASE + 0x0B70))
    #define PAD222_CNTRL  (*(volatile unsigned int *)(PADCTRL_BASE + 0x0B74))
    #define PAD223_CNTRL  (*(volatile unsigned int *)(PADCTRL_BASE + 0x0B78))
    #define PAD224_CNTRL  (*(volatile unsigned int *)(PADCTRL_BASE + 0x0B7c))
    #define PAD225_CNTRL  (*(volatile unsigned int *)(PADCTRL_BASE + 0x0B80))
    #define PAD226_CNTRL  (*(volatile unsigned int *)(PADCTRL_BASE + 0x0B84))
    #define PAD227_CNTRL  (*(volatile unsigned int *)(PADCTRL_BASE + 0x0B88))
    
    #define PAD232_CNTRL  (*(volatile unsigned int *)(PADCTRL_BASE + 0x0B9C))
    #define PAD233_CNTRL  (*(volatile unsigned int *)(PADCTRL_BASE + 0x0BA0))
    #define PAD234_CNTRL  (*(volatile unsigned int *)(PADCTRL_BASE + 0x0BA4))
    #define PAD235_CNTRL  (*(volatile unsigned int *)(PADCTRL_BASE + 0x0BA8))
    #define PAD236_CNTRL  (*(volatile unsigned int *)(PADCTRL_BASE + 0x0BAC))
    #define PAD237_CNTRL  (*(volatile unsigned int *)(PADCTRL_BASE + 0x0BB0))
    #define PAD238_CNTRL  (*(volatile unsigned int *)(PADCTRL_BASE + 0x0BB4))
    #define PAD239_CNTRL  (*(volatile unsigned int *)(PADCTRL_BASE + 0x0BB8))
    #define PAD240_CNTRL  (*(volatile unsigned int *)(PADCTRL_BASE + 0x0BBC))
    #define PAD241_CNTRL  (*(volatile unsigned int *)(PADCTRL_BASE + 0x0BC0))
    #define PAD242_CNTRL  (*(volatile unsigned int *)(PADCTRL_BASE + 0x0BC4))
    #define PAD243_CNTRL  (*(volatile unsigned int *)(PADCTRL_BASE + 0x0BC8))
    #define PAD244_CNTRL  (*(volatile unsigned int *)(PADCTRL_BASE + 0x0BCC))
    #define PAD245_CNTRL  (*(volatile unsigned int *)(PADCTRL_BASE + 0x0BD0))
    #define PAD246_CNTRL  (*(volatile unsigned int *)(PADCTRL_BASE + 0x0BD4))
    #define PAD247_CNTRL  (*(volatile unsigned int *)(PADCTRL_BASE + 0x0BD8))
    #define PAD248_CNTRL  (*(volatile unsigned int *)(PADCTRL_BASE + 0x0BDC))
    #define PAD249_CNTRL  (*(volatile unsigned int *)(PADCTRL_BASE + 0x0BE0))
    #define PAD250_CNTRL  (*(volatile unsigned int *)(PADCTRL_BASE + 0x0BE4))
    #define PAD251_CNTRL  (*(volatile unsigned int *)(PADCTRL_BASE + 0x0BE8))
    #define PAD252_CNTRL  (*(volatile unsigned int *)(PADCTRL_BASE + 0x0BEC))
    #define PAD253_CNTRL  (*(volatile unsigned int *)(PADCTRL_BASE + 0x0BF0))
    #define PAD254_CNTRL  (*(volatile unsigned int *)(PADCTRL_BASE + 0x0BF4))
    #define PAD255_CNTRL  (*(volatile unsigned int *)(PADCTRL_BASE + 0x0BF8))
    #define PAD256_CNTRL  (*(volatile unsigned int *)(PADCTRL_BASE + 0x0BFC))
    #define PAD257_CNTRL  (*(volatile unsigned int *)(PADCTRL_BASE + 0x0C00))
    #define PAD258_CNTRL  (*(volatile unsigned int *)(PADCTRL_BASE + 0x0C04))
    #endif
    
    #define INPUT	1
    #define OUTPUT	0
    #define PHY_RESET_GPIO0_PIN	28
    #define PHY_EN_GPIO3_PIN	23
    #define PHY_WAKE_GPIO3_PIN	16
    #define EMMC_ON_GPIO1_PIN	29
    
    static void enable_gpio_clk(void)
    {
    	printf("Enable GPIO_0 clock\n");
    	//Enable GPIO0 clock	
    	//printf("Writing CM_ALWON_GPIO_0_CLKCTRL:0x%x with 0x%x\n",CM_ALWON_GPIO_0_CLKCTRL, GPIO_CLKCTRL_VAL);
    	__raw_writel(GPIO_CLKCTRL_VAL, CM_ALWON_GPIO_0_CLKCTRL);
    	//printf("Validating CM_ALWON_GPIO_0_CLKCTRL reg write\n");
    	while(__raw_readl(CM_ALWON_GPIO_0_CLKCTRL) != GPIO_CLKCTRL_VAL);
    	 
    	printf("Enable GPIO_1 clock\n");
    	//Enable GPIO1, GPIO2, GPIO3, GPIO4, GPIO5 clock
    	//printf("Writing CM_ALWON_GPIO_1_CLKCTRL:0x%x with 0x%x\n",CM_ALWON_GPIO_1_CLKCTRL, GPIO_CLKCTRL_VAL);
    	__raw_writel(GPIO_CLKCTRL_VAL, CM_ALWON_GPIO_1_CLKCTRL); 
    	//printf("Validating CM_ALWON_GPIO_1_CLKCTRL reg write\n");
    	while(__raw_readl(CM_ALWON_GPIO_1_CLKCTRL) != GPIO_CLKCTRL_VAL);
    }
    
    static void set_pin_direction(unsigned int bank, unsigned int gpio, unsigned int is_input)
    {
    	printf("Setting gpio%d as: %s\n",gpio, ((is_input==INPUT)? "input":"output"));
    	unsigned int regAddr=bank+OMAP4_GPIO_OE;
    	unsigned int value = 0;
    	//printf("Reading register: %x\n",regAddr);
    	value = __raw_readl(regAddr);
    	if (is_input)
    		value |= 1 << gpio;
    	else
    		value &= ~(1 << gpio);
    	//printf("writing register: %x with %x\n",regAddr, value);
    	__raw_writel(value, regAddr);
    }
    
    static void set_pin_value(unsigned int bank, unsigned int gpio, unsigned int value)
    {
    	printf("Setting gpio%d with %d\n", gpio, value);
    	unsigned int regAddr=bank;
    	if (value)
    		regAddr += OMAP4_GPIO_SETDATAOUT;
    	else
    		regAddr += OMAP4_GPIO_CLEARDATAOUT;
    	value = 1 << gpio;
    	__raw_writel(value, regAddr);
    }
    
    #ifdef CONFIG_TI811X_CONFIG_DDR
    static void cmd_macro_config(u32 ddr_phy, u32 inv_clk_out,
    			 u32 ctrl_slave_ratio_cs0, u32 cmd_dll_lock_diff)
    {
    	u32 ddr_phy_base = DDR0_PHY_BASE_ADDR;
    
    	__raw_writel(inv_clk_out,
    		 ddr_phy_base + CMD1_REG_PHY_INVERT_CLKOUT_0);
    	__raw_writel(inv_clk_out,
    		 ddr_phy_base + CMD0_REG_PHY_INVERT_CLKOUT_0);
    	__raw_writel(inv_clk_out,
    		 ddr_phy_base + CMD2_REG_PHY_INVERT_CLKOUT_0);
    
    	__raw_writel(((ctrl_slave_ratio_cs0 << 10) | ctrl_slave_ratio_cs0),
    		ddr_phy_base + CMD0_REG_PHY_CTRL_SLAVE_RATIO_0);
    	__raw_writel(((ctrl_slave_ratio_cs0 << 10) | ctrl_slave_ratio_cs0),
    		ddr_phy_base + CMD1_REG_PHY_CTRL_SLAVE_RATIO_0);
    	__raw_writel(((ctrl_slave_ratio_cs0 << 10) | ctrl_slave_ratio_cs0),
    		 ddr_phy_base + CMD2_REG_PHY_CTRL_SLAVE_RATIO_0);
    
    	__raw_writel(cmd_dll_lock_diff,
    		 ddr_phy_base + CMD0_REG_PHY_DLL_LOCK_DIFF_0);
    	__raw_writel(cmd_dll_lock_diff,
    		 ddr_phy_base + CMD1_REG_PHY_DLL_LOCK_DIFF_0);
    	__raw_writel(cmd_dll_lock_diff,
    		 ddr_phy_base + CMD2_REG_PHY_DLL_LOCK_DIFF_0);
    }
    
    static void data_macro_config(u32 macro_num, u32 emif, u32 rd_dqs_cs0,
    		u32 wr_dqs_cs0, u32 fifo_we_cs0, u32 wr_data_cs0)
    {
    	/* 0xA4 is size of each data macro mmr region.
    	 * phy1 is at offset 0x400 from phy0
    	 */
    	u32 base = (macro_num * 0xA4) + (emif * 0x400);
    
    	__raw_writel(((rd_dqs_cs0 << 10) | rd_dqs_cs0),
    		(DATA0_REG_PHY0_RD_DQS_SLAVE_RATIO_0 + base));
    	__raw_writel(((wr_dqs_cs0 << 10) | wr_dqs_cs0),
    		(DATA0_REG_PHY0_WR_DQS_SLAVE_RATIO_0 + base));
    	__raw_writel(((PHY_WRLVL_INIT_CS1_DEFINE << 10) |
    		PHY_WRLVL_INIT_CS0_DEFINE),
    		(DATA0_REG_PHY0_WRLVL_INIT_RATIO_0 + base));
    	__raw_writel(((PHY_GATELVL_INIT_CS1_DEFINE << 10) |
    		PHY_GATELVL_INIT_CS0_DEFINE),
    		(DATA0_REG_PHY0_GATELVL_INIT_RATIO_0 + base));
    	__raw_writel(((fifo_we_cs0 << 10) | fifo_we_cs0),
    		(DATA0_REG_PHY0_FIFO_WE_SLAVE_RATIO_0 + base));
    	__raw_writel(((wr_data_cs0 << 10) | wr_data_cs0),
    		(DATA0_REG_PHY0_WR_DATA_SLAVE_RATIO_0 + base));
    	__raw_writel(PHY_DLL_LOCK_DIFF_DEFINE,
    		(DATA0_REG_PHY0_DLL_LOCK_DIFF_0 + base));
    }
    #endif
    
    #ifdef CONFIG_SETUP_PLL
    static u32 pll_dco_freq_sel(u32 clk_in, u32 n, u32 m);
    static void pll_config(u32, u32, u32, u32, u32);
    static void audio_pll_config(void);
    static void sata_pll_config(void);
    static void modena_pll_config(void);
    static void l3_pll_config(void);
    static void ddr_pll_config(void);
    static void iss_pll_config(void);
    static void dsp_pll_config(void);
    static void usb_pll_config(void);
    #endif
    static void unlock_pll_control_mmr(void);
    #ifdef CONFIG_DRIVER_TI_CPSW
    static void cpsw_pad_config(void);
    #endif
    static void nor_pad_config_mux(void);
    /*
     * spinning delay to use before udelay works
     */
    static inline void delay(unsigned long loops)
    {
    	__asm__ volatile ("1:\n" "subs %0, %1, #1\n"
    		"bne 1b" : "=r" (loops) : "0"(loops));
    }
    
    # define CONFIG_AMP_I2C_SPEED		400000
    # define CONFIG_DIRANA_I2C_SPEED	400000
    /* i2c0(bus1) <--> Dirana3 I/F */
    # define CONFIG_DIRANA_I2C_SLAVE	1
    /* i2c2(bus3) <--> Amplifier I/F */
    # define CONFIG_AMP_I2C_SLAVE		3
    //i2c3(bus4) <--> EEPROM I/F */
    # define CONFIG_EEPROM_I2C_SLAVE	4
    
    u32 rsb_i2c_init(void)
    {
        //int status;
        //u32 val, val_pincntl263, val_pincntl264;
          
        /* Setup the PADCNTL Registers for I2C0 */
        //val_pincntl263 = __raw_readl(0x48140C18);
        //val = (val_pincntl263 & ~0x7FF) | 0x001;
        //__raw_writel(val, 0x48140C18);
        //val_pincntl264 = __raw_readl(0x48140C1C);
        //val = (val_pincntl264 & ~0x7FF) | 0x001;
        //__raw_writel(val, 0x48140C1C);
        
        /* Init i2c2(bus3) for Amplifier */
        i2c_init (CONFIG_AMP_I2C_SPEED, CONFIG_AMP_I2C_SLAVE);
    
        /* Init i2c0(bus1) for Dirana3 r */
        i2c_init (CONFIG_DIRANA_I2C_SPEED, CONFIG_DIRANA_I2C_SLAVE);
    
    }
    
    /*
     * Basic board specific setup
     */
    int board_init(void)
    {
    	u32 regVal;
    
    	/* Do the required pin-muxing before modules are setup */
    	set_muxconf_regs();
    	
    	/* Enable LVCMOS mode for MLBP_SIGN and MLBP_SIGP IO buffers. Enable receivers for GPIO input functionality. */
    	__raw_writel(0x3F, MLBP_SIG_IO_CTRL);
    	/* Enable LVCMOS mode for MLBP_DATN and MLBP_DATP IO buffers. Enable receivers for GPIO input functionality. */
    	__raw_writel(0x3F, MLBP_DAT_IO_CTRL);
    
    
    	nor_pad_config_mux();
    	rsb_i2c_init();
    #if 0
    	/* setup RMII_REFCLK to be sourced from audio_pll */
    	__raw_writel(0x30004, RMII_REFCLK_SRC);
    
    	/*program GMII_SEL register for RGMII mode */
    	__raw_writel(0x30a, GMII_SEL);
    #else //RSB
    	/* setup RMII_REFCLK .its an input from external src */
    	__raw_writel(0x30005, RMII_REFCLK_SRC);
    	
    	/*program GMII_SEL register for RMII mode */
    	//__raw_writel(0x305, GMII_SEL); //with internal delay
    	__raw_writel(0x335, GMII_SEL); //no internal delay
    #endif
    
    	/* Get Timer and UART out of reset */
    	/* UART softreset */
    	regVal = __raw_readl(UART_SYSCFG);
    	regVal |= 0x2;
    	__raw_writel(regVal, UART_SYSCFG);
    	while ((__raw_readl(UART_SYSSTS) & 0x1) != 0x1)
    		;
    
    	/* Disable smart idle */
    	regVal = __raw_readl(UART_SYSCFG);
    	regVal |= (1<<3);
    	__raw_writel(regVal, UART_SYSCFG);
    
    	/* mach type passed to kernel */
    	gd->bd->bi_arch_number = MACH_TYPE_TI811XEVM;
    
    	/* address of boot parameters */
    	gd->bd->bi_boot_params = PHYS_DRAM_1 + 0x100;
    	gpmc_init();
    
    #ifndef CONFIG_NOR
    	/* GPMC will come up with default buswidth configuration,
    	 * we will override it based on BW pin CONFIG_STATUS register.
    	 * This is currently required only for NAND/NOR to
    	 * support 8/16 bit NAND/NOR part. Also we always use chipselect 0
    	 * for NAND/NOR boot.
    	 *
    	 * NOTE: This code is DM8168 EVM specific, hence we are using CS 0.
    	 * NOTE: This code is DM8168 EVM specific, hence we are using CS 0.
    	 * Also, even for other boot modes user is expected to
    	 * on/off the BW pin on the EVM.
    	 */
    	gpmc_set_cs_buswidth(0, get_sysboot_bw());
    #endif
    	return 0;
    }
    
    /*
     * sets uboots idea of sdram size
     */
    int dram_init(void)
    {
    	/* Fill up board info */
    	gd->bd->bi_dram[0].start = PHYS_DRAM_1;
    	gd->bd->bi_dram[0].size = PHYS_DRAM_1_SIZE;
    
    	return 0;
    }
    
    #ifdef CONFIG_SERIAL_TAG
    /*  *********************************************************
     *  * get_board_serial() - setup to pass kernel board serial
     *  * returns: board serial number
     *  **********************************************************
     */
    void get_board_serial(struct tag_serialnr *serialnr)
    {
    	/* ToDo: read eeprom and return*/
    	serialnr->high = 0x0;
    	serialnr->low = 0x0;
    
    }
    #endif
    
    /**********************************************************
     * * get_board_rev() - setup to pass kernel board revision
     * * returns: revision
     * ********************************************************
     */
    u32 get_board_rev(void)
    {
        int status;
        u32 val, val_pincntl263, val_pincntl264;
    
        struct EEPROM_ID_T
        {
            uint32_t    header;
            uint8_t     board_name[16];
            uint16_t    version_major;
            uint16_t    version_minor;
            uint32_t    config_option;
        }
        eeprom_id;
        
        /* Setup the PADCNTL Registers for I2C0 */
        val_pincntl263 = __raw_readl(0x48140C18);
        val = (val_pincntl263 & ~0x7FF) | 0x001;
        __raw_writel(val, 0x48140C18);
        val_pincntl264 = __raw_readl(0x48140C1C);
        val = (val_pincntl264 & ~0x7FF) | 0x001;
        __raw_writel(val, 0x48140C1C);
        
        /* Init the I2C0 peripheral */
        i2c_init (CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
    
        /* Read from bytes from start of EEPROM at bus address 0x50 */
        status = i2c_read( CONFIG_SYS_I2C_EEPROM_ADDR, 0x0, 
                           CONFIG_SYS_I2C_EEPROM_ADDR_LEN, (uint8_t *) &eeprom_id, 
                           sizeof(eeprom_id));
        
        /* Return the PADCNTL registers to their original states */
        __raw_writel(val_pincntl263, 0x48140C18);
        __raw_writel(val_pincntl264, 0x48140C1C);
        
        /* Check if the EEPROM read failed */
        if (status != 0)
        {
            puts ("Error: EEPROM read failed.\n");
            return 0x0;
        }
        
        /* Check for magic number in EEPROM data */
        if (0xaa5533ee != eeprom_id.header)
        {
            puts ("Warning: Board ID missing. Defaulting to Rev D and earlier.\n");
            return 0x0;
        }
        
        return eeprom_id.version_major;
    }
    
    int misc_init_r(void)
    {
    	#ifdef CONFIG_TI811X_MIN_CONFIG
        u32 rev = get_board_rev();
    
        if (rev != 0x0) {
            /* Major revision numbers should be 1 for A, 2 for B, and so on */    
            printf("Info: Detected board revison %c.\n",(char)(0x40+rev));
        } else {
            printf("Warning: Board revision detection failed.\n");
        }
        
    	printf("The 2nd stage U-Boot will now be auto-loaded\n");
    	printf("Please do not interrupt the countdown till "
    		"TI811X_EVM prompt if 2nd stage is already flashed\n");
    	#endif
    
    #ifdef CONFIG_TI811X_ASCIIART
    	int i = 0, j = 0;
    
    	char ti811x[22][67] = {
    "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@",
    "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@",
    "@@                                                               @@",
    "@@                                                               @@",
    "@@                                                               @@",
    "@@                                                               @@",
    "@@                                                               @@",
    "@@     88888888888 8888888 .d8888b.   d888    d888               @@",
    "@@         888       888  d88P  Y88b d8888   d8888               @@",
    "@@         888       888  Y88b. d88P   888     888               @@",
    "@@         888       888    Y88888     888     888    888  888   @@",
    "@@         888       888  .d8P88Y8b.   888     888      Y8 8P    @@",
    "@@         888       888  888    888   888     888       88      @@",
    "@@         888       888  Y88b  d88P   888     888     .d8 8b.   @@",
    "@@         888     8888888  Y8888P  8888888  8888888   888 888   @@",
    "@@                                                               @@",
    "@@                                                               @@",
    "@@                                                               @@",
    "@@                                                               @@",
    "@@                                                               @@",
    "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@",
    "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@",};
    
    	for (i = 0; i < 22; i++) {
    		for (j = 0; j < 67; j++)
    			printf("%c", ti811x[i][j]);
    			printf("\n");
    	}
    	printf("\n");
    #endif
    	return 0;
    }
    #ifdef CONFIG_TI811X_CONFIG_DDR
    static void config_ti811x_ddr(void)
    {
    	int macro;
    
    	/* Enable the Power Domain Transition of L3 Fast Domain Peripheral */
    	__raw_writel(0x2, CM_DEFAULT_FW_CLKCTRL);
    	/* Enable the Power Domain Transition of L3 Fast Domain Peripheral */
    	__raw_writel(0x2, CM_DEFAULT_L3_FAST_CLKSTCTRL);
    	__raw_writel(0x2, CM_DEFAULT_EMIF_0_CLKCTRL); /* Enable EMIF0 Clock */
    
    	/* Poll for L3_FAST_GCLK  & DDR_GCLK  are active */
    	while ((__raw_readl(CM_DEFAULT_L3_FAST_CLKSTCTRL) & 0x300) != 0x300)
    		;
    	/* Poll for Module is functional */
    	while ((__raw_readl(CM_DEFAULT_EMIF_0_CLKCTRL)) != 0x2)
    		;
    
    	cmd_macro_config(DDR_PHY0, DDR3_PHY_INVERT_CLKOUT_OFF,
    			DDR3_PHY_CTRL_SLAVE_RATIO_CS0_DEFINE,
    			PHY_CMD0_DLL_LOCK_DIFF_DEFINE);
    
    	for (macro = 0; macro <= DATA_MACRO_3; macro++) {
    		data_macro_config(macro, DDR_PHY0,
    			DDR3_PHY_RD_DQS_CS0_DEFINE,
    			DDR3_PHY_WR_DQS_CS0_DEFINE,
    			DDR3_PHY_RD_DQS_GATE_CS0_DEFINE,
    			DDR3_PHY_WR_DATA_CS0_DEFINE);
    	}
    
    	/* DDR IO CTRL config */
    	__raw_writel(DDR0_IO_CTRL_DEFINE, DDR0_IO_CTRL);
    
    	__raw_writel(__raw_readl(VTP0_CTRL_REG) | 0x00000040 , VTP0_CTRL_REG);
    
    	/* Write 0 to CLRZ bit */
    	__raw_writel(__raw_readl(VTP0_CTRL_REG) & 0xfffffffe , VTP0_CTRL_REG);
    
    	/* Write 1 to CLRZ bit */
    	__raw_writel(__raw_readl(VTP0_CTRL_REG) | 0x00000001 , VTP0_CTRL_REG);
    
    	/* Read VTP control registers & check READY bits */
    	while ((__raw_readl(VTP0_CTRL_REG) & 0x00000020) != 0x20)
    		;
    	
    
    	/* Program EMIF0 CFG Registers */
        if (get_board_rev() >= 0x5)
        {
            __raw_writel(DDR3_EMIF_READ_LATENCY_REV_E, EMIF4_0_DDR_PHY_CTRL_1);
            __raw_writel(DDR3_EMIF_READ_LATENCY_REV_E, EMIF4_0_DDR_PHY_CTRL_1_SHADOW);
            __raw_writel(DDR3_EMIF_TIM1_REV_E, EMIF4_0_SDRAM_TIM_1);
            __raw_writel(DDR3_EMIF_TIM1_REV_E, EMIF4_0_SDRAM_TIM_1_SHADOW);
            __raw_writel(DDR3_EMIF_TIM2_REV_E, EMIF4_0_SDRAM_TIM_2);
            __raw_writel(DDR3_EMIF_TIM2_REV_E, EMIF4_0_SDRAM_TIM_2_SHADOW);
            __raw_writel(DDR3_EMIF_TIM3_REV_E, EMIF4_0_SDRAM_TIM_3);
            __raw_writel(DDR3_EMIF_TIM3_REV_E, EMIF4_0_SDRAM_TIM_3_SHADOW);
            __raw_writel(DDR3_EMIF_SDRAM_CONFIG_REV_E, EMIF4_0_SDRAM_CONFIG);
    
            __raw_writel(DDR_EMIF_REF_CTRL | DDR_EMIF_REF_TRIGGER,
                             EMIF4_0_SDRAM_REF_CTRL);
            __raw_writel(DDR_EMIF_REF_CTRL, EMIF4_0_SDRAM_REF_CTRL_SHADOW);
            __raw_writel(DDR3_EMIF_SDRAM_ZQCR_REV_E, EMIF4_0_SDRAM_ZQCR);
            __raw_writel(DDR_EMIF_REF_CTRL, EMIF4_0_SDRAM_REF_CTRL);
            __raw_writel(DDR_EMIF_REF_CTRL, EMIF4_0_SDRAM_REF_CTRL_SHADOW);
    
            __raw_writel(DDR3_EMIF_REF_CTRL_REV_E, EMIF4_0_SDRAM_REF_CTRL);
            __raw_writel(DDR3_EMIF_REF_CTRL_REV_E, EMIF4_0_SDRAM_REF_CTRL_SHADOW);    
        }
        else
        {
            __raw_writel(DDR3_EMIF_READ_LATENCY, EMIF4_0_DDR_PHY_CTRL_1);
            __raw_writel(DDR3_EMIF_READ_LATENCY, EMIF4_0_DDR_PHY_CTRL_1_SHADOW);
            __raw_writel(DDR3_EMIF_TIM1, EMIF4_0_SDRAM_TIM_1);
            __raw_writel(DDR3_EMIF_TIM1, EMIF4_0_SDRAM_TIM_1_SHADOW);
            __raw_writel(DDR3_EMIF_TIM2, EMIF4_0_SDRAM_TIM_2);
            __raw_writel(DDR3_EMIF_TIM2, EMIF4_0_SDRAM_TIM_2_SHADOW);
            __raw_writel(DDR3_EMIF_TIM3, EMIF4_0_SDRAM_TIM_3);
            __raw_writel(DDR3_EMIF_TIM3, EMIF4_0_SDRAM_TIM_3_SHADOW);
            __raw_writel(DDR3_EMIF_SDRAM_CONFIG, EMIF4_0_SDRAM_CONFIG);
    
            __raw_writel(DDR_EMIF_REF_CTRL | DDR_EMIF_REF_TRIGGER,
                             EMIF4_0_SDRAM_REF_CTRL);
            __raw_writel(DDR_EMIF_REF_CTRL, EMIF4_0_SDRAM_REF_CTRL_SHADOW);
            __raw_writel(DDR3_EMIF_SDRAM_ZQCR, EMIF4_0_SDRAM_ZQCR);
            __raw_writel(DDR_EMIF_REF_CTRL, EMIF4_0_SDRAM_REF_CTRL);
            __raw_writel(DDR_EMIF_REF_CTRL, EMIF4_0_SDRAM_REF_CTRL_SHADOW);
    
            __raw_writel(DDR3_EMIF_REF_CTRL, EMIF4_0_SDRAM_REF_CTRL);
            __raw_writel(DDR3_EMIF_REF_CTRL, EMIF4_0_SDRAM_REF_CTRL_SHADOW);
        }
    }
    #endif
    
    #ifdef CONFIG_SETUP_PLL
    static void audio_pll_config()
    {
    	pll_config(AUDIO_PLL_BASE,
    			AUDIO_N, AUDIO_M,
    			AUDIO_M2, AUDIO_CLKCTRL);
    }
    
    #if 0
    static void pcie_pll_config()
    {
    	/* Powerdown both reclkp/n single ended receiver */
    	__raw_writel(0x00000002, SERDES_REFCLK_CTRL);
    
    	__raw_writel(0x00000000, PCIE_PLLCFG0);
    
    	/* PCIe(2.5GHz) mode, 100MHz refclk, MDIVINT = 25,
    	 * disable (50,100,125M) clks
    	 */
    	__raw_writel(0x00640000, PCIE_PLLCFG1);
    
    	/* SSC Mantissa and exponent = 0 */
    	__raw_writel(0x00000000, PCIE_PLLCFG2);
    
    	/* TBD */
    	__raw_writel(0x004008E0, PCIE_PLLCFG3);
    
    	/* TBD */
    	__raw_writel(0x0000609C, PCIE_PLLCFG4);
    
    	/* pcie_serdes_cfg_misc */
    	/* TODO: verify the address over here
    	 * (CTRL_BASE + 0x6FC = 0x481406FC ???)
    	 */
    	/* __raw_writel(0x00000E7B, 0x48141318); */
    	delay(3);
    
    	/* Enable PLL LDO */
    	__raw_writel(0x00000004, PCIE_PLLCFG0);
    	delay(3);
    
    	/* Enable DIG LDO, PLL LD0 */
    	__raw_writel(0x00000014, PCIE_PLLCFG0);
    	delay(3);
    
    	/* Enable DIG LDO, ENBGSC_REF, PLL LDO */
    	__raw_writel(0x00000016, PCIE_PLLCFG0);
    	delay(3);
    	__raw_writel(0x30000016, PCIE_PLLCFG0);
    	delay(3);
    	__raw_writel(0x70000016, PCIE_PLLCFG0);
    	delay(3);
    
    	/* Enable DIG LDO, SELSC, ENBGSC_REF, PLL LDO */
    	__raw_writel(0x70000017, PCIE_PLLCFG0);
    	delay(3);
    
    	/* wait for ADPLL lock */
    	while (__raw_readl(PCIE_PLLSTATUS) != 0x1)
    		;
    
    }
    #endif
    
    static void sata_pll_config()
    {
    	__raw_writel(0xC12C003C, SATA_PLLCFG1);
    	__raw_writel(0x004008E0, SATA_PLLCFG3);
    	delay(0xFFFF);
    
    	__raw_writel(0x80000004, SATA_PLLCFG0);
    	delay(0xFFFF);
    
    	/* Enable PLL LDO */
    	__raw_writel(0x80000014, SATA_PLLCFG0);
    	delay(0xFFFF);
    
    	/* Enable DIG LDO, ENBGSC_REF, PLL LDO */
    	__raw_writel(0x80000016, SATA_PLLCFG0);
    	delay(0xFFFF);
    
    	__raw_writel(0xC0000017, SATA_PLLCFG0);
    	delay(0xFFFF);
    
    	/* wait for ADPLL lock */
    	while (((__raw_readl(SATA_PLLSTATUS) & 0x01) == 0x0))
    		;
    
    }
    
    static void usb_pll_config()
    {
    	pll_config(USB_PLL_BASE,
    			USB_N, USB_M,
    			USB_M2, USB_CLKCTRL);
    }
    
    static void modena_pll_config()
    {
    	pll_config(MODENA_PLL_BASE,
    			MODENA_N, MODENA_M,
    			MODENA_M2, MODENA_CLKCTRL);
    }
    
    static void l3_pll_config()
    {
    	pll_config(L3_PLL_BASE,
    			L3_N, L3_M,
    			L3_M2, L3_CLKCTRL);
    }
    
    static void ddr_pll_config()
    {
    	pll_config(DDR_PLL_BASE,
    			DDR_N, DDR_M,
    			DDR_M2, DDR_CLKCTRL);
    }
    static void dsp_pll_config()
    {
    	pll_config(DSP_PLL_BASE,
    			DSP_N, DSP_M, DSP_M2,
    			DSP_CLKCTRL);
    }
    static void iss_pll_config()
    {
    	pll_config(ISS_PLL_BASE,
    			ISS_N, ISS_M,
    			ISS_M2, ISS_CLKCTRL);
    }
    #if 0
    static void iva_pll_config()
    {
    	pll_config(IVA_PLL_BASE,
    			IVA_N, IVA_M,
    			IVA_M2, IVA_CLKCTRL);
    }
    #endif
    
    /*
     * select the HS1 or HS2 for DCO Freq
     * return : CLKCTRL
     */
    static u32 pll_dco_freq_sel(u32 clk_in, u32 n, u32 m)
    {
    	u32 dco_clk = 0;
    
    	dco_clk = (clk_in / (n+1)) * m ;
    	if (dco_clk >= DCO_HS2_MIN && dco_clk < DCO_HS2_MAX)
    		return SELFREQDCO_HS2;
    	else if (dco_clk >= DCO_HS1_MIN && dco_clk < DCO_HS1_MAX)
    		return SELFREQDCO_HS1;
    	else
    		return -1;
    
    }
    
    /*
     * configure individual ADPLLJ
     */
    static void pll_config(u32 base, u32 n, u32 m, u32 m2, u32 clkctrl_val)
    {
    	u32 m2nval, mn2val, read_clkctrl = 0;
    
    	/* select DCO freq range for ADPLL_J */
    	if (MODENA_PLL_BASE != base)
    		clkctrl_val |= pll_dco_freq_sel(OSC_0_FREQ, n, m);
    
    	m2nval = (m2 << 16) | n;
    	mn2val = m;
    
    	/* by-pass pll */
    	read_clkctrl = __raw_readl(base + ADPLLJ_CLKCTRL);
    	__raw_writel((read_clkctrl | 0x00800000), (base + ADPLLJ_CLKCTRL));
    	while ((__raw_readl(base + ADPLLJ_STATUS) & 0x101) != 0x101)
    		;
    	read_clkctrl = __raw_readl(base + ADPLLJ_CLKCTRL);
    	__raw_writel((read_clkctrl & 0xfffffffe), (base + ADPLLJ_CLKCTRL));
    
    
    	/*
    	 * ref_clk = 20/(n + 1);
    	 * clkout_dco = ref_clk * m;
    	 * clk_out = clkout_dco/m2;
    	*/
    
    	__raw_writel(m2nval, (base + ADPLLJ_M2NDIV));
    	__raw_writel(mn2val, (base + ADPLLJ_MN2DIV));
    
    	/* Load M2, N2 dividers of ADPLL */
    	__raw_writel(0x1, (base + ADPLLJ_TENABLEDIV));
    	__raw_writel(0x0, (base + ADPLLJ_TENABLEDIV));
    
    	/* Loda M, N dividers of ADPLL */
    	__raw_writel(0x1, (base + ADPLLJ_TENABLE));
    	__raw_writel(0x0, (base + ADPLLJ_TENABLE));
    
    	read_clkctrl = __raw_readl(base + ADPLLJ_CLKCTRL);
    
    	if (MODENA_PLL_BASE == base)
    		__raw_writel((read_clkctrl & 0xff7fffff) | clkctrl_val,
    			base + ADPLLJ_CLKCTRL);
    	else
    		__raw_writel((read_clkctrl & 0xff7fe3ff) | clkctrl_val,
    			base + ADPLLJ_CLKCTRL);
    	/* Wait for phase and freq lock */
    	while ((__raw_readl(base + ADPLLJ_STATUS) & 0x600) != 0x600)
    		;
    
    }
    #endif
    
    /*
     * Enable the clks & power for perifs (TIMER1, UART0,...)
     */
    void per_clocks_enable(void)
    {
    	u32 temp;
    
    	__raw_writel(0x2, CM_ALWON_L3_SLOW_CLKSTCTRL);
    
    #if 0
    	/* TIMER 1 */
    	__raw_writel(0x2, CM_ALWON_TIMER_1_CLKCTRL);
    #endif
    	/* Selects OSC0 (20MHz) for DMTIMER1 */
    	temp = __raw_readl(DMTIMER_CLKSRC);
    	temp &= ~(0x7 << 4);
    	temp |= (0x4 << 4);
    	__raw_writel(temp, DMTIMER_CLKSRC);
    
    #if 0
    	while (((__raw_readl(CM_ALWON_L3_SLOW_CLKSTCTRL) & (0x80000<<1)) >>
    			(19+1)) != 1)
    		;
    	while (((__raw_readl(CM_ALWON_TIMER_1_CLKCTRL) & 0x30000)>>16) != 0)
    		;
    #endif
    	__raw_writel(0x2, (DM_TIMER1_BASE + 0x54));
    	while (__raw_readl(DM_TIMER1_BASE + 0x10) & 1)
    		;
    
    	__raw_writel(0x1, (DM_TIMER1_BASE + 0x38));
    
    	/* UARTs */
    	__raw_writel(0x2, CM_ALWON_UART_0_CLKCTRL);
    	while (__raw_readl(CM_ALWON_UART_0_CLKCTRL) != 0x2)
    		;
    
    	__raw_writel(0x2, CM_ALWON_UART_1_CLKCTRL);
    	while (__raw_readl(CM_ALWON_UART_1_CLKCTRL) != 0x2)
    		;
    
    	__raw_writel(0x2, CM_ALWON_UART_2_CLKCTRL);
    	while (__raw_readl(CM_ALWON_UART_2_CLKCTRL) != 0x2)
    		;
    
    	while ((__raw_readl(CM_ALWON_L3_SLOW_CLKSTCTRL) & 0x2100) != 0x2100)
    		;
    
    	/* SPI */
    	__raw_writel(0x2, CM_ALWON_SPI_CLKCTRL);
    	while (__raw_readl(CM_ALWON_SPI_CLKCTRL) != 0x2)
    		;
    
    	/* I2C0 and I2C2 */
    	__raw_writel(0x2, CM_ALWON_I2C_0_CLKCTRL);
    	while (__raw_readl(CM_ALWON_I2C_0_CLKCTRL) != 0x2)
    		;
    
    	/* I2C1 and I2C3 */
    	__raw_writel(0x2, CM_ALWON_I2C_1_CLKCTRL);
    	while (__raw_readl(CM_ALWON_I2C_1_CLKCTRL) != 0x2)
    		;
    
    	/*Enable GPIO0 clock*/	
    	__raw_writel(0x102, CM_ALWON_GPIO_0_CLKCTRL);
    	while(__raw_readl(CM_ALWON_GPIO_0_CLKCTRL) != 0x102)
    		;
    	 
    	/*Enable GPIO1, GPIO2, GPIO3, GPIO4, GPIO5 clock*/
    	__raw_writel(0x102, CM_ALWON_GPIO_1_CLKCTRL); 
    	while(__raw_readl(CM_ALWON_GPIO_1_CLKCTRL) != 0x102)
    		;
    
    	/* Ethernet */
    	__raw_writel(0x2, CM_ETHERNET_CLKSTCTRL);
    	__raw_writel(0x2, CM_ALWON_ETHERNET_0_CLKCTRL);
    	while ((__raw_readl(CM_ALWON_ETHERNET_0_CLKCTRL) & 0x30000) != 0)
    		;
    	__raw_writel(0x2, CM_ALWON_ETHERNET_1_CLKCTRL);
    	/* HSMMC */
    	__raw_writel(0x2, CM_ALWON_HSMMC_CLKCTRL);
    	while (__raw_readl(CM_ALWON_HSMMC_CLKCTRL) != 0x2)
    		;
    	/* Nid added to support eMMC */
    	__raw_writel(0x2, CM_ALWON_HSMMC_2_CLKCTRL);
    	while (__raw_readl(CM_ALWON_HSMMC_2_CLKCTRL) != 0x2)
    		;
    
    	/*
    	 * McASP2
    	 * select mcasp2 clk from sys_clk_22 (OSC 0)
    	 * so that audio clk (sys_clk_20) can be used for RMII
    	 * ToDo :
    	 * This can be removed once kernel exports set_parent()
    	 */
    
    	 
    	__raw_writel(0x0, CM_SYSCLK20_CLKSEL);
    	while (__raw_readl(CM_SYSCLK20_CLKSEL) != 0x0);
    
    	__raw_writel(0x0, CM_AUDIOCLK_MCASP2_CLKSEL);
    	while (__raw_readl(CM_AUDIOCLK_MCASP2_CLKSEL) != 0x0);
    
    	__raw_writel(0x0, CM_AUDIOCLK_MCASP0_CLKSEL);
    	while (__raw_readl(CM_AUDIOCLK_MCASP0_CLKSEL) != 0x0);
    
    	__raw_writel(0x00000300, McASP345_AUX_CLKSRC);
    	while (__raw_readl(McASP345_AUX_CLKSRC) != 0x00000300);
    
    	/* McASP2 AHCLKX source from OSC1
    	__raw_writel(0x00030000, McASP_AHCLK_CLKSRC);
    	while (__raw_readl(McASP_AHCLK_CLKSRC) != 0x00030000)
    		;*/
    
    	/* McASP2 AHCLKX source from AUDIO_CLKIN_0*/
    	__raw_writel(0x00000000, McASP_AHCLK_CLKSRC);
    	while (__raw_readl(McASP_AHCLK_CLKSRC) != 0x00000000);
    
    	/* select OSC1 as clock out*/
    	__raw_writel(0x00070000, CLKOUT_MUX);
    	while (__raw_readl(CLKOUT_MUX) != 0x00070000);
    
    
    	/* WDT */
    	/* For WDT to be functional, it needs to be first stopped by writing
    	 * the pattern 0xAAAA followed by 0x5555 in the WDT start/stop register.
    	 * After that a write-once register in Control module needs to be
    	 * configured to unfreeze the timer.
    	 * Note: It is important to stop the watchdog before unfreezing it
    	*/
    	__raw_writel(0xAAAA, WDT_WSPR);
    	while (__raw_readl(WDT_WWPS) != 0x0)
    		;
    	__raw_writel(0x5555, WDT_WSPR);
    	while (__raw_readl(WDT_WWPS) != 0x0)
    		;
    
    	/* Unfreeze WDT */
    	__raw_writel(0x13, WDT_UNFREEZE);
    }
    
    /*
     * inits clocks for PRCM as defined in clocks.h
     */
    void prcm_init(u32 in_ddr)
    {
    	/* Enable the control module */
    	__raw_writel(0x2, CM_ALWON_CONTROL_CLKCTRL);
    
    #ifdef CONFIG_SETUP_PLL
    	/* Setup the various plls */
    	audio_pll_config();
    	modena_pll_config();
    	ddr_pll_config();
    	dsp_pll_config();
    	iss_pll_config();
    
    	usb_pll_config();
    	/*  With clk freqs setup to desired values,
    	 *  enable the required peripherals
    	 */
    	per_clocks_enable();
    #endif
    }
    
    #ifdef CONFIG_DRIVER_TI_CPSW
    
    #if 0
    static void cpsw_pad_config()
    {
    	volatile u32 val = 0;
    
    	/*configure pin mux for rmii_refclk,mdio_clk,mdio_d */
    	val = PAD232_CNTRL;
    	PAD232_CNTRL = (volatile unsigned int) (BIT(18) | BIT(0));
    	val = PAD233_CNTRL;
    	PAD233_CNTRL = (volatile unsigned int) (BIT(19) | BIT(17) | BIT(0));
    	val = PAD234_CNTRL;
    	PAD234_CNTRL = (volatile unsigned int) (BIT(19) | BIT(18) | BIT(17) |
    			BIT(0));
    
    	/*setup rgmii0/rgmii1 pins here*/
    	/* In this case we enable rgmii_en bit in GMII_SEL register and
    	 * still program the pins in gmii mode: gmii0 pins in mode 1*/
    	val = PAD235_CNTRL; /*rgmii0_rxc*/
    	PAD235_CNTRL = (volatile unsigned int) (BIT(18) | BIT(0));
    	val = PAD236_CNTRL; /*rgmii0_rxctl*/
    	PAD236_CNTRL = (volatile unsigned int) (BIT(18) | BIT(0));
    	val = PAD237_CNTRL; /*rgmii0_rxd[2]*/
    	PAD237_CNTRL = (volatile unsigned int) (BIT(18) | BIT(0));
    	val = PAD238_CNTRL; /*rgmii0_txctl*/
    	PAD238_CNTRL = (volatile unsigned int) BIT(0);
    	val = PAD239_CNTRL; /*rgmii0_txc*/
    	PAD239_CNTRL = (volatile unsigned int) BIT(0);
    	val = PAD240_CNTRL; /*rgmii0_txd[0]*/
    	PAD240_CNTRL = (volatile unsigned int) BIT(0);
    	val = PAD241_CNTRL; /*rgmii0_rxd[0]*/
    	PAD241_CNTRL = (volatile unsigned int) (BIT(18) | BIT(0));
    	val = PAD242_CNTRL; /*rgmii0_rxd[1]*/
    	PAD242_CNTRL = (volatile unsigned int) (BIT(18) | BIT(0));
    	val = PAD243_CNTRL; /*rgmii1_rxctl*/
    	PAD243_CNTRL = (volatile unsigned int) (BIT(18) | BIT(0));
    	val = PAD244_CNTRL; /*rgmii0_rxd[3]*/
    	PAD244_CNTRL = (volatile unsigned int) (BIT(18) | BIT(0));
    	val = PAD245_CNTRL; /*rgmii0_txd[3]*/
    	PAD245_CNTRL = (volatile unsigned int) BIT(0);
    	val = PAD246_CNTRL; /*rgmii0_txd[2]*/
    	PAD246_CNTRL = (volatile unsigned int) BIT(0);
    	val = PAD247_CNTRL; /*rgmii0_txd[1]*/
    	PAD247_CNTRL = (volatile unsigned int) BIT(0);
    	val = PAD248_CNTRL; /*rgmii1_rxd[1]*/
    	PAD248_CNTRL = (volatile unsigned int) (BIT(18) | BIT(0));
    	val = PAD249_CNTRL; /*rgmii1_rxc*/
    	PAD249_CNTRL = (volatile unsigned int) (BIT(18) | BIT(0));
    	val = PAD250_CNTRL; /*rgmii1_rxd[3]*/
    	PAD250_CNTRL = (volatile unsigned int) (BIT(18) | BIT(0));
    	val = PAD251_CNTRL; /*rgmii1_txd[1]*/
    	PAD251_CNTRL = (volatile unsigned int) (BIT(0));
    	val = PAD252_CNTRL; /*rgmii1_txctl*/
    	PAD252_CNTRL = (volatile unsigned int) (BIT(0));
    	val = PAD253_CNTRL; /*rgmii1_txd[0]*/
    	PAD253_CNTRL = (volatile unsigned int) (BIT(0));
    	val = PAD254_CNTRL; /*rgmii1_txd[2]*/
    	PAD254_CNTRL = (volatile unsigned int) (BIT(0));
    	val = PAD255_CNTRL; /*rgmii1_txc*/
    	PAD255_CNTRL = (volatile unsigned int) (BIT(0));
    	val = PAD256_CNTRL; /*rgmii1_rxd[0]*/
    	PAD256_CNTRL = (volatile unsigned int) (BIT(18) | BIT(0));
    	val = PAD257_CNTRL; /*rgmii1_txd[3]*/
    	PAD257_CNTRL = (volatile unsigned int) (BIT(0));
    	val = PAD258_CNTRL; /*rgmii1_rxd[2]*/
    	PAD258_CNTRL = (volatile unsigned int) (BIT(18) | BIT(0));
    }
    
    #else
    
    #if 0
    static void config_phy_gpio( void )
    {
    	set_pin_direction(GPIO0_BASE, PHY_RESET_GPIO0_PIN, OUTPUT);
    	set_pin_direction(GPIO3_BASE, PHY_EN_GPIO3_PIN, OUTPUT);
    	set_pin_direction(GPIO3_BASE, PHY_WAKE_GPIO3_PIN, OUTPUT);
    }
    #endif
    static void reset_bcm89811_phy(void )
    {
    	set_pin_direction(GPIO0_BASE, PHY_RESET_GPIO0_PIN, OUTPUT);
        	set_pin_value(GPIO0_BASE, PHY_RESET_GPIO0_PIN, 0);
        	udelay(10000);
        	set_pin_value(GPIO0_BASE, PHY_RESET_GPIO0_PIN, 1);
    }
    #if 0
    static void cpsw_pad_config()
    {
    	volatile u32 val = 0;
    	printf("Ethernet pad muxing for RSB\n");
    	enable_gpio_clk();
    	/*configure pin mux for rmii_refclk,mdio_clk,mdio_d */
    	//E_GTXCLK. 50 MHz RMII Ref clock is an input to j5-prime and BCM89811. Its an external clock from oscilator
    	val = PAD232_CNTRL;
    	PAD232_CNTRL = (volatile unsigned int) (BIT(18) | BIT(0));
    	//E_MDC
    	val = PAD233_CNTRL;
    	PAD233_CNTRL = (volatile unsigned int) (BIT(19) | BIT(17) | BIT(0));
      	//E_MDIO
    	val = PAD234_CNTRL;
    	PAD234_CNTRL = (volatile unsigned int) (BIT(19) | BIT(18) | BIT(17) |
    			BIT(0));
    
    	/*setup rmii0/rmii1 pins here*/
    	/* In this case we enable rgmii_en bit in GMII_SEL register and
    	 * still program the pins in gmii mode: gmii0 pins in mode 2 */
    
    	
    	val = PAD236_CNTRL; /*E0_RXD0*/ 
    	PAD236_CNTRL = (volatile unsigned int) (BIT(19) | BIT(18) | BIT(2));
    	val = PAD237_CNTRL; /*E0_RXD1*/ //sample this pin to assign RMII mode RXD1 should be 1 during reset RXD[2]=0
    	PAD237_CNTRL = (volatile unsigned int) (BIT(19) | BIT(18) | BIT(17) | BIT(2));
    	val = PAD238_CNTRL; /*RMRXER*/ //PullDown 
    	PAD238_CNTRL = (volatile unsigned int) (BIT(19) | BIT(18) | BIT(2));
    	val = PAD239_CNTRL; /*E0_RXDV*/  //sample this pin to assign phy address 0x00000 or 0x00001 during reset
    	PAD239_CNTRL = (volatile unsigned int) (BIT(19) | BIT(18) | BIT(2));
    	val = PAD240_CNTRL; /*E0_TXD0*/ 
    	PAD240_CNTRL = (volatile unsigned int) (/*BIT(18) |*/ BIT(2));
    	val = PAD241_CNTRL; /*E0_TXD1*/ 
    	PAD241_CNTRL = (volatile unsigned int) (/*BIT(18) |*/ BIT(2));
    	val = PAD242_CNTRL; /*E0_TXEN*/ 
    	PAD242_CNTRL = (volatile unsigned int) (/*BIT(18) |*/ BIT(2));
    
    	val = PAD235_CNTRL; /*E0_PHY_EN--OUT*/ //set to 1
    	PAD235_CNTRL = (volatile unsigned int) (BIT(18) | /*BIT(17) |*/ BIT(7));
    	set_pin_direction(GPIO3_BASE, PHY_EN_GPIO3_PIN, OUTPUT);
    	set_pin_value(GPIO3_BASE, PHY_EN_GPIO3_PIN, 1);
    
    	val = PAD230_CNTRL; /*E0_PHY_INT_N*/
    	PAD230_CNTRL = (volatile unsigned int) (BIT(18) | BIT(7));
    
    	val = PAD224_CNTRL; /*E0_PHY_WAKE--OUT*/
    	PAD224_CNTRL = (volatile unsigned int) (BIT(18) | BIT(7));
    
            printf("Configuring PAD58_CNTRL for E0_RESET_N \n ");
    	val = PAD58_CNTRL; /*GP0[28]E0_RESET_N--OUT*/ //set to 1
    	PAD58_CNTRL = (volatile unsigned int) (BIT(18) |  /*BIT(17) |*/ BIT(7));
    
    	set_pin_direction(GPIO0_BASE, PHY_RESET_GPIO0_PIN, OUTPUT);
    	set_pin_value(GPIO0_BASE, PHY_RESET_GPIO0_PIN, 1);
    	printf("In loop\n");	
    	//while(1);
    	printf("Out loop\n");
    	val = PAD140_CNTRL; /*ETH0_INH_N*/
    	PAD140_CNTRL = (volatile unsigned int) (BIT(18) | BIT(7));	
    
    	unsigned int regAddr=0;
    	printf("Reading gpio register values back\n");
    	//PINCNTL58/
    	regAddr=0x481408E4;	
    	val = __raw_readl(regAddr);
    	printf("Reading register: 0x%x =value: 0x%x\n",regAddr, val);
    
    	//CM_ALWON_GPIO_0_CLKCTRL/
    	regAddr=0x4818155C;	
    	val = __raw_readl(regAddr);
    	printf("Reading register: 0x%x =value: 0x%x\n",regAddr, val);
    
    	//GPIO0.GPIO_CTRL/
    	regAddr=0x48032130;	
    	val = __raw_readl(regAddr);
    	printf("Reading register: 0x%x =value: 0x%x\n",regAddr, val);
    
    	//GPIO0.GPIO_OE/
    	regAddr=0x48032134;	
    	val = __raw_readl(regAddr);
    	printf("Reading register: 0x%x =value: 0x%x\n",regAddr, val);
    
    	//GPIO0.GPIO_DATAIN/
    	regAddr=0x48032138;	
    	val = __raw_readl(regAddr);
    	printf("Reading register: 0x%x =value: 0x%x\n",regAddr, val);
    
    	//GPIO0.GPIO_DATAOUT/
    	regAddr=0x4803213C;	
    	val = __raw_readl(regAddr);
    	printf("Reading register: 0x%x =value: 0x%x\n",regAddr, val);	
    }
    #else
    static void cpsw_pad_config()
    {
        printf("Ethernet pad muxing for RSB\n");
        enable_gpio_clk();
        /*configure pin mux for rmii_refclk,mdio_clk,mdio_d */
        //E_GTXCLK. 50 MHz RMII Ref clock is an input to j5-prime and BCM89811. Its an external clock from oscilator
        // refer to spreadsheet: 1_6_VW_RSB_HWAPP_J5_GPIO_2015_0924_05.xlsx
    
        PAD_CNTRL( 58) = 0xd0080;  // E0_reset_n, gpio0
        PAD_CNTRL(140) = 0xd0080;  // E0_inh_n,   gpio
        PAD_CNTRL(224) = 0x50080;  // E0_phy_wake
        PAD_CNTRL(230) = 0x70080;  // E0_phy_int
    
        PAD_CNTRL(232) = 0x50001;  // E0_gtxclk
        PAD_CNTRL(233) = 0xf0001;  // E0_mdc
        PAD_CNTRL(234) = 0xf0001;  // E0_mdio
        PAD_CNTRL(235) = 0xd0080;  // E0_phy_en, gpio3
        PAD_CNTRL(236) = 0xd0004;  // E0_rxd0
        PAD_CNTRL(237) = 0xd0004;  // E0_rxd1
        PAD_CNTRL(238) = 0xd0004;  // pulldown
        PAD_CNTRL(239) = 0xd0004;  // E0_RXDV
        PAD_CNTRL(240) = 0x50004;  // E0_TXD0
        PAD_CNTRL(241) = 0x50004;  // E0_TXD1
        PAD_CNTRL(242) = 0x50004;  // E0_TXEN
    
        // PAD235, phy en
        set_pin_direction(GPIO3_BASE, PHY_EN_GPIO3_PIN, OUTPUT);
        set_pin_value(GPIO3_BASE, PHY_EN_GPIO3_PIN, 1);
    
        // PAD58, reset
        reset_bcm89811_phy();
    
        // PAD140, inh ??
    }
    #endif
    #endif
    #endif /* CONFIG_DRIVER_TI_CPSW */
    
    struct nor_pad_config {
    	unsigned int offset;
    	unsigned int value;
    };
    
    static struct nor_pad_config nor_pad_cfg[] = {
    		{GPMC_D0, MODE(1) | INPUT_EN | PULL_DIS},
    		{GPMC_D1, MODE(1) | INPUT_EN | PULL_DIS},
    		{GPMC_D2, MODE(1) | INPUT_EN | PULL_DIS},
    		{GPMC_D3, MODE(1) | INPUT_EN | PULL_DIS},
    		{GPMC_D4, MODE(1) | INPUT_EN | PULL_DIS},
    		{GPMC_D5, MODE(1) | INPUT_EN | PULL_DIS},
    		{GPMC_D6, MODE(1) | INPUT_EN | PULL_DIS},
    		{GPMC_D7, MODE(1) | INPUT_EN | PULL_DIS},
    		{GPMC_D8, MODE(1) | INPUT_EN | PULL_DIS},
    		{GPMC_D9, MODE(1) | INPUT_EN | PULL_DIS},
    		{GPMC_D10, MODE(1) | INPUT_EN | PULL_DIS},
    		{GPMC_D11, MODE(1) | INPUT_EN | PULL_DIS},
    		{GPMC_D12, MODE(1) | INPUT_EN | PULL_DIS},
    		{GPMC_D13, MODE(1) | INPUT_EN | PULL_DIS},
    		{GPMC_D14, MODE(1) | INPUT_EN | PULL_DIS},
    		{GPMC_D15, MODE(1) | INPUT_EN | PULL_DIS},
    		{GPMC_A1, MODE(5) | PULL_UP_EN},
    		{GPMC_A2, MODE(5) | PULL_UP_EN},
    		{GPMC_A3, MODE(5) | PULL_UP_EN},
    		{GPMC_A4, MODE(5) | PULL_UP_EN},
    		{GPMC_A5, MODE(5) | PULL_UP_EN},
    		{GPMC_A6, MODE(5)},
    		{GPMC_A7, MODE(5)},
    		{GPMC_A8, MODE(5)},
    		{GPMC_A9, MODE(5)},
    		{GPMC_A10, MODE(5) | PULL_UP_EN},
    		{GPMC_A11, MODE(5)},
    		{GPMC_A12, MODE(5)},
    		{GPMC_A13, MODE(5) | PULL_UP_EN},
    		{GPMC_A14, MODE(5) | PULL_UP_EN},
    		{GPMC_A15, MODE(5)},
    		{GPMC_A16, MODE(1)},
    		{GPMC_A17, MODE(1)},
    		{GPMC_A18, MODE(1)},
    		{GPMC_A19, MODE(1)},
    		{GPMC_A20, MODE(1) | PULL_UP_EN},
    		//{GPMC_A26, MODE(4) | PULL_UP_EN}, //Nid added configured as GPMC_A26
    		{GPMC_A26, MODE(5) | PULL_UP_EN}, //Nid added configured as GPMC_A0
    #if 0 //Not used in RSB
    		{GPMC_A21, MODE(1)},
    		{GPMC_A22, MODE(1) | PULL_UP_EN},
    		{GPMC_A23, MODE(1)},
    		{GPMC_A24, MODE(2) | PULL_UP_EN},
    		{GPMC_A25, MODE(2)},
    		{GPMC_A27, MODE(8) | PULL_UP_EN},
    #endif
    		{GPMC_CS0_REG, MODE(1) | PULL_UP_EN},
    		{GPMC_OEN, MODE(1) | PULL_UP_EN},
    		{GPMC_WEN, MODE(1) | PULL_UP_EN},
    		{0},
    };
    
    /*********************************************************************
     *
     * nor_pad_config_mux - configure the pin mux for NOR
     *
     *********************************************************************/
    static void nor_pad_config_mux(void)
    {
    	u8 i = 0;
    
    	while (nor_pad_cfg[i].offset != 0x0) {
    		*(volatile u32 *)(nor_pad_cfg[i].offset) =
    			nor_pad_cfg[i].value;
    		i++;
    	}
    }
    
    /*
     * baord specific muxing of pins
     */
    void set_muxconf_regs(void)
    {
    	u32 i, add, val;
    	u32 pad_conf[] = {
    #include "mux.h"
    	};
    
    	for (i = 0; i < N_PINS; i++) {
    		add = PIN_CTRL_BASE + (i*4);
    		val = __raw_readl(add);
    		val |= pad_conf[i];
    		__raw_writel(val, add);
    	}
    	/* MMC/SD pull-down enable */
    	__raw_writel(0x000C0040, 0x48140928);
    	/*Nidd added for eMMC: PINCNTL73  - MMC2_SDCD*/
    	__raw_writel(0x00050040, 0x48140920);	
    }
    
    void unlock_pll_control_mmr()
    {
    	/* ??? */
    	__raw_writel(0x1EDA4C3D, 0x481C5040);
    	__raw_writel(0x2FF1AC2B, 0x48140060);
    	__raw_writel(0xF757FDC0, 0x48140064);
    	__raw_writel(0xE2BC3A6D, 0x48140068);
    	__raw_writel(0x1EBF131D, 0x4814006c);
    	__raw_writel(0x6F361E05, 0x48140070);
    
    }
    
    /*
     * early system init of muxing and clocks.
     */
    void s_init(u32 in_ddr)
    {
    	/* TODO: Revisit enabling of I/D-cache in 1st stage */
    #if 0
    	icache_enable();
    	dcache_enable();
    #endif
    
    	/*
    	 * Disable Write Allocate on miss to avoid starvation of other masters
    	 * (than A8).
    	 *
    	 * Ref TI811X Erratum: TODO
    	 */
    	l2_disable_wa();
    
    	/* Can be removed as A8 comes up with L2 enabled */
    	l2_cache_enable();
    	unlock_pll_control_mmr();
    	/* Setup the PLLs and the clocks for the peripherals */
    	prcm_init(in_ddr);
    #ifdef CONFIG_TI811X_CONFIG_DDR
    	if (!in_ddr)
    		config_ti811x_ddr();	/* Do DDR settings */
    #endif
    }
    
    /*
     * Reset the board
     */
    void reset_cpu(ulong addr)
    {
    	addr = __raw_readl(PRM_DEVICE_RSTCTRL);
    	addr &= ~BIT(1);
    	addr |= BIT(1);
    	__raw_writel(addr, PRM_DEVICE_RSTCTRL);
    }
    
    #ifdef CONFIG_DRIVER_TI_CPSW
    
    #if 0
    /* TODO : Check for the board specific PHY */
    static void phy_init(char *name, int addr)
    {
    	unsigned short val;
    	unsigned int   cntr = 0;
    
    	miiphy_reset(name, addr);
    
    	udelay(100000);
    
    	/* Enable Autonegotiation */
    	if (miiphy_read(name, addr, PHY_BMCR, &val) != 0) {
    		printf("failed to read bmcr\n");
    		return;
    	}
    	val |= PHY_BMCR_DPLX | PHY_BMCR_AUTON | PHY_BMCR_100_MBPS;
    	if (miiphy_write(name, addr, PHY_BMCR, val) != 0) {
    		printf("failed to write bmcr\n");
    		return;
    	}
    	miiphy_read(name, addr, PHY_BMCR, &val);
    
    	/* Setup GIG advertisement */
    	miiphy_read(name, addr, PHY_1000BTCR, &val);
    	val |= PHY_1000BTCR_1000FD;
    	val &= ~PHY_1000BTCR_1000HD;
    	miiphy_write(name, addr, PHY_1000BTCR, val);
    	miiphy_read(name, addr, PHY_1000BTCR, &val);
    
    	/* Setup general advertisement */
    	if (miiphy_read(name, addr, PHY_ANAR, &val) != 0) {
    		printf("failed to read anar\n");
    		return;
    	}
    	val |= (PHY_ANLPAR_10 | PHY_ANLPAR_10FD | PHY_ANLPAR_TX |
    		PHY_ANLPAR_TXFD);
    	if (miiphy_write(name, addr, PHY_ANAR, val) != 0) {
    		printf("failed to write anar\n");
    		return;
    	}
    	miiphy_read(name, addr, PHY_ANAR, &val);
    
    	/* Restart auto negotiation*/
    	miiphy_read(name, addr, PHY_BMCR, &val);
    	val |= PHY_BMCR_RST_NEG;
    	miiphy_write(name, addr, PHY_BMCR, val);
    
    	/*check AutoNegotiate complete - it can take upto 3 secs*/
    	do {
    		udelay(40000);
    		cntr++;
    
    		if (!miiphy_read(name, addr, PHY_BMSR, &val)) {
    			if (val & PHY_BMSR_AUTN_COMP)
    				break;
    		}
    	} while (cntr < 250);
    
    	if (!miiphy_read(name, addr, PHY_BMSR, &val)) {
    		if (!(val & PHY_BMSR_AUTN_COMP))
    			printf("Auto negotitation failed\n");
    	}
    }
    #else
    //bcm89811_phy_init()
    static void phy_init(char *name, int addr)
    {
    	u16 data=0;
    	u32 timeout = 0;
        	u32 phyid;
    
        static int onetime_init = 0;
    
        if (onetime_init)
            return;
    
        miiphy_read(name, addr, ETH_TRCV_PHY_ID1_REG, &data);
        phyid = (u32)data << 16;
        miiphy_read(name, addr, ETH_TRCV_PHY_ID2_REG, &data);
        phyid |= data;
    
        printf("Initializing BCM89811 Eth Phy: Driver:%s addr:%d phyid:%08lx\n",name, addr, phyid);
    
        miiphy_read(name, addr, ETH_TRCV_CTRL_REG, &data);
    #if 1
    	//printf("/*******************begin EMI optimization portion*********************************/\n"); 
      		//App.WrMii PORT, MIICTL, &H8000&     ' reset
    	miiphy_write(name, addr, ETH_BCM89811_REG_MIICTL, ETH_TRCV_CTRL_RESET_ENABLE);
    
      	udelay(100000);
    	miiphy_read(name, addr, ETH_TRCV_CTRL_REG, &data);
      	/* self clearing bit */
      	while((data & ETH_TRCV_CTRL_RESET_ENABLE) != RESET)
      	{
    	    miiphy_read(name, addr, ETH_TRCV_CTRL_REG,&data);
    	    printf("waiting to release phy from reset: ETH_TRCV_CTRL_REG: %x\n", data);	
      	}
    	//printf("ETH_TRCV_CTRL_REG: 0x%x\n", data);
     	//App.WrMii PORT, &H001E&, &H0028&   '
     	//App.WrMii PORT, &H001F&, &H0C00&  
    	miiphy_write(name, addr, ETH_BCM89811_REG_RDPADDR, 0x0028);
    	miiphy_write(name, addr, ETH_BCM89811_REG_RDPRW, 0x0C00);
    
      	//App.WrMii PORT, &H001E&, &H0312&   '
      	//App.WrMii PORT, &H001F&, &H030b&   '
    	miiphy_write(name, addr, ETH_BCM89811_REG_RDPADDR, 0x0312);
    	miiphy_write(name, addr, ETH_BCM89811_REG_RDPRW, 0x030b);
      
      	//App.WrMii PORT, &H001E&, &H030A&   '
      	//App.WrMii PORT, &H001F&, &H34C0& 
    	miiphy_write(name, addr, ETH_BCM89811_REG_RDPADDR, 0x030A);
    	miiphy_write(name, addr, ETH_BCM89811_REG_RDPRW, 0x34C0);
      
      	//App.WrMii PORT, &H001E&, &H0166&   '
      	//App.WrMii PORT, &H001F&, &H0020&  
    	miiphy_write(name, addr, ETH_BCM89811_REG_RDPADDR, 0x0166);
    	miiphy_write(name, addr, ETH_BCM89811_REG_RDPRW, 0x0020);
    	
      	//App.WrMii PORT, &H001E&, &H012D&   '
      	//App.WrMii PORT, &H001F&, &H9B52&   '
    	miiphy_write(name, addr, ETH_BCM89811_REG_RDPADDR, 0x012D);
    	miiphy_write(name, addr, ETH_BCM89811_REG_RDPRW, 0x9B52);   
      
    	//App.WrMii PORT, &H001E&, &H012E&   '
      	//App.WrMii PORT, &H001F&, &HA04D&   '
    	miiphy_write(name, addr, ETH_BCM89811_REG_RDPADDR, 0x012E);
    	miiphy_write(name, addr, ETH_BCM89811_REG_RDPRW, 0xA04D);
    
      	//App.WrMii PORT, &H001E&, &H0123&   '
      	//App.WrMii PORT, &H001F&, &H00C0& 
    	miiphy_write(name, addr, ETH_BCM89811_REG_RDPADDR, 0x0123);
    	miiphy_write(name, addr, ETH_BCM89811_REG_RDPRW, 0x00C0); 
    
      	//App.WrMii PORT, &H001E&, &H0154&   '
      	//App.WrMii PORT, &H001F&, &H81c4&  
    	miiphy_write(name, addr, ETH_BCM89811_REG_RDPADDR, 0x0154);
    	miiphy_write(name, addr, ETH_BCM89811_REG_RDPRW, 0x81c4);
    
      	//data = (ETH_BCM89811_MII_PAD_SETTING * 2048); //0x0000
      	//App.WrMii PORT, &H001E&, &H0811&   '
      	//App.WrMii PORT, &H001F&, v   '
    	//miiphy_write(name, addr, ETH_BCM89811_REG_RDPADDR, 0x0811);
    	//miiphy_write(name, addr, ETH_BCM89811_REG_RDPRW, data);
    
      	//data = 0x0064; 
      	//App.WrMii PORT, &H001E&, &H01D3&   '
      	//App.WrMii PORT, &H001F&, v   '
    	miiphy_write(name, addr, ETH_BCM89811_REG_RDPADDR, 0x01D3);
    	miiphy_write(name, addr, ETH_BCM89811_REG_RDPRW, 0x0064);
    
      	//App.WrMii PORT, &H001E&, &H01C1&   ' 
      	//App.WrMii PORT, &H001F&, &HA5F7& 
    	miiphy_write(name, addr, ETH_BCM89811_REG_RDPADDR, 0x01C1);
    	miiphy_write(name, addr, ETH_BCM89811_REG_RDPRW, 0xA5F7); 
    
      	//App.WrMii PORT, &H001E&, &H0028&   '
      	//App.WrMii PORT, &H001F&, &H0400& 
    	miiphy_write(name, addr, ETH_BCM89811_REG_RDPADDR, 0x0028);
    	miiphy_write(name, addr, ETH_BCM89811_REG_RDPRW, 0x0400); 
    /**************************END EMI optimization portion****************************/ 
    #endif
    
    /**************************begin LED setup portion*********************************/ 
    
      	//App.WrMii PORT, &H001E&, &H001D&   '
      	//App.WrMii PORT, &H001F&, &H3411&   '
    	miiphy_write(name, addr, ETH_BCM89811_REG_RDPADDR, 0x001D);
    	miiphy_write(name, addr, ETH_BCM89811_REG_RDPRW, 0x3411);
    
      	//App.WrMii PORT, &H001E&, &H0820&   '
      	//App.WrMii PORT, &H001F&, &H0401&   '
    	miiphy_write(name, addr, ETH_BCM89811_REG_RDPADDR, 0x0820);
    	miiphy_write(name, addr, ETH_BCM89811_REG_RDPRW, 0x0401);
    
    /**************************END LED setup portion***********************************/ 
    #if 0
    /**************************begin MACconfiguration portion**************************/ 
      	//If  RGMII_Cnfg Then  ' if RGMII_Config is set, configure as RGMII
    	if(ETH_BCM89811_RGMII_Cnfg){
        		//App.WrMii PORT, &H001E&, &H0045&   ' unset MII reverse
        		//App.WrMii PORT, &H001F&, &H0000& 
    		miiphy_write(name, addr, ETH_BCM89811_REG_RDPADDR, 0x0045);
    		miiphy_write(name, addr, ETH_BCM89811_REG_RDPRW, 0x0000);  
         
        		//App.WrMii PORT, &H001E&, &H002F&   ' turn On RGMII mode 
        		//App.WrMii PORT, &H001F&, &HF1E7&   '
    		miiphy_write(name, addr, ETH_BCM89811_REG_RDPADDR, 0x002F);
    		miiphy_write(name, addr, ETH_BCM89811_REG_RDPRW, 0xF1E7);
     	
        		printf("Setting Phy Address 0x%x into RGMII mode\n",ETH_BCM89811_PORT);
        
        	}else if(ETH_BCM89811_MII_Reverse_Cnfg){
    		 
        		//App.WrMii PORT, &H001E&, &H002F&   ' turn off RGMII mode 
        		//App.WrMii PORT, &H001F&, &HF167&  
    		miiphy_write(name, addr, ETH_BCM89811_REG_RDPADDR, 0x002F);
    		miiphy_write(name, addr, ETH_BCM89811_REG_RDPRW, 0xF167); 
    
        		//App.WrMii PORT, &H001E&, &H0045&   'set MII reverse
        		//App.WrMii PORT, &H001F&, &H0700&  
    		miiphy_write(name, addr, ETH_BCM89811_REG_RDPADDR, 0x0045);
    		miiphy_write(name, addr, ETH_BCM89811_REG_RDPRW, 0x0700);  
    
    		printf("Setting Phy address 0x%x into RvMII mode\n",ETH_BCM89811_PORT);
      	}else{
    		//Else  ' otherwise, set to MII_LITE
        		//App.WrMii PORT, &H001E&, &H002F&   ' turn off RGMII mode 
        		//App.WrMii PORT, &H001F&, &HF167& 
    		miiphy_write(name, addr, ETH_BCM89811_REG_RDPADDR, 0x002F);
    		miiphy_write(name, addr, ETH_BCM89811_REG_RDPRW, 0xF167);  
        		//App.WrMii PORT, &H001E&, &H0045&   ' unset MII reverse
        		//App.WrMii PORT, &H001F&, &H0000&  
    		miiphy_write(name, addr, ETH_BCM89811_REG_RDPADDR, 0x0045);
    		miiphy_write(name, addr, ETH_BCM89811_REG_RDPRW, 0x0000); 
    		printf("Setting Phy Address 0x%x into MII Lite mode\n",ETH_BCM89811_PORT);
    	}
    /**************************end MACconfiguration portion***************************/ 
    #endif
    /**************************begin mdi configuration portion************************/ 
      
    		if(ETH_BCM89811_MasterConfig){
    			printf("Setting PORT 0:0%d to 100Mbps 1Pair Master\n",ETH_BCM89811_PORT);
      			//App.WrMii PORT, MIICTL, &H0208&   ' set phy to 100M1P, Master
    			miiphy_write(name, addr, ETH_BCM89811_REG_MIICTL, 0x0208);
      		}else{                                     
           			printf("Setting PORT 0:0%d to 100Mbps 1Pair Slave\n",ETH_BCM89811_PORT);
    			//App.WrMii PORT, MIICTL, &H0200&   ' set phy to 100M1P, Slave
    			miiphy_write(name, addr, ETH_BCM89811_REG_MIICTL, 0x0200);
      		}
    
    /**************************end mdi configuration portion**************************/ 
    
    		if(ETH_BCM89811_Kill_PORT == ETH_BCM89811_PORT)
    		{
        			printf("Disabling PHY PORT 0:0%d \n",ETH_BCM89811_PORT);
      			if (ETH_BCM89811_RGMII_Cnfg)
    			{
        				//App.WrMii PORT, &H001E&, &H0300&   '
        				//App.WrMii PORT, &H001F&, &H0000&   '
    				miiphy_write(name, addr, ETH_BCM89811_REG_RDPADDR, 0x0300);
    				miiphy_write(name, addr, ETH_BCM89811_REG_RDPRW, 0x0000);
    
        				//App.WrMii PORT, MIICTL, &H0A00&    ' superisolate and ONLY
    				miiphy_write(name, addr, ETH_BCM89811_REG_MIICTL, 0x0A00);
        				//App.WrMii PORT, &H001E&, &H0300&   '
        				//App.WrMii PORT, &H001F&, &H00001&   '
    				miiphy_write(name, addr, ETH_BCM89811_REG_RDPADDR, 0x0300);
    				miiphy_write(name, addr, ETH_BCM89811_REG_RDPRW, 0x0001);
    
        				printf("Setting PHY PORT 0:0%d in internal loopback\n",ETH_BCM89811_PORT);
        				//App.WrMii PORT, &H00&, &H4A00& 
    				miiphy_write(name, addr, ETH_BCM89811_REG_MIICTL, 0x4A00);
      			}else{ 
        				//App.WrMii PORT, MIICTL, &H0E00&    ' isolate and super isolate
        				miiphy_write(name, addr, ETH_BCM89811_REG_MIICTL, 0x0E00);
    
        				//App.WrMii PORT, &H001E&, &H00FC&   '
        				//App.WrMii PORT, &H001F&, &H0140&   '
    				miiphy_write(name, addr, ETH_BCM89811_REG_RDPADDR, 0x00FC);
    				miiphy_write(name, addr, ETH_BCM89811_REG_RDPRW, 0x0140);
    
        				//App.WrMii PORT, &H001E&, &H0300&   '
        				//App.WrMii PORT, &H001F&, &H0000&   '
    				miiphy_write(name, addr, ETH_BCM89811_REG_RDPADDR, 0x0300);
    				miiphy_write(name, addr, ETH_BCM89811_REG_RDPRW, 0x0000);
    
        				//App.WrMii PORT, MIICTL, &H2D00&    ' isolate and super isolate
    				miiphy_write(name, addr, ETH_BCM89811_REG_MIICTL, 0x2D00);
    
        				//App.WrMii PORT, &H001E&, &H0300&   '
        				//App.WrMii PORT, &H001F&, &H0001&   '
    				miiphy_write(name, addr, ETH_BCM89811_REG_RDPADDR, 0x0300);
    				miiphy_write(name, addr, ETH_BCM89811_REG_RDPRW, 0x0001);
      			} 
    		}
    		/* check link status */
      		timeout = 0;
    		data = 0;
        		miiphy_read(name, addr,ETH_TRCV_STATUS_REG,&data);
         
        		while(!(data & ETH_TRCV_STATUS_LINK_STATUS_PASS) && (timeout < ETH_TRCV_PHY_READ_TO))
        		{
           			miiphy_read(name, addr,ETH_TRCV_STATUS_REG,&data);
          			timeout++;
        		}
        		//printf("ETH_TRCV_STATUS_REG: 0x%x\n", data);
        		if(timeout == ETH_TRCV_PHY_READ_TO)
        		{
          			printf("link status failed\n");
          			return;	
        		}
      		//EthTrcvDriverState = ETHTRCV_STATE_ACTIVE;
    		
            onetime_init = 1;
      		printf("link status active: ");
    		if(data & ETH_TRCV_STATUS_100M_1PAIR)
    			printf("1 Pair 100 Mbps\n ");
    		else
    			printf("\n");
      		return; 
    
    }
    
    #endif
    static void cpsw_control(int enabled)
    {
    	/* nothing for now */
    	/* TODO : VTP was here before */
    }
    
    static struct cpsw_slave_data cpsw_slaves[] = {
    	{
    		.slave_reg_ofs	= 0x208,
    		.sliver_reg_ofs	= 0xd80,
    		//.phy_id		= 0,
    		.phy_id		= 1,
    	},
    	{
    		.slave_reg_ofs	= 0x308,
    		.sliver_reg_ofs	= 0xdc0,
    		//.phy_id		= 1,
    		.phy_id		= 2, //to avoid conflict with EMAC0
    	},
    };
    
    static struct cpsw_platform_data cpsw_data = {
    	.mdio_base		= TI811X_CPSW_MDIO_BASE,
    	.cpsw_base		= TI814X_CPSW_BASE,
    	.mdio_div		= 0xff,
    	.channels		= 8,
    	.cpdma_reg_ofs		= 0x800,
    	.cpdma_sram_ofs		= 0xa00,
    	.slaves			= 1,
    	.slave_data		= cpsw_slaves,
    	.ale_reg_ofs		= 0xd00,
    	.ale_entries		= 1024,
    	.host_port_reg_ofs	= 0x108,
    	.hw_stats_reg_ofs	= 0x900,
    	.mac_control		= (BIT(15) | BIT(5) | BIT(0)),/* BIT(15)RMII/RGMII Gasket Control */  /*BIT(0)Full Duplex*/ /*BIT(5) MIIEN */
    	.control		= cpsw_control,
    	.phy_init		= phy_init,
    	.host_port_num		= 0,
    	.bd_ram_ofs		= 0x2000,
    };
    
    extern void cpsw_eth_set_mac_addr(const u_int8_t *addr);
    
    int board_eth_init(bd_t *bis)
    {
    	u_int8_t mac_addr[6];
    	u_int32_t mac_hi, mac_lo;
    	u_int32_t eth_clock_config;
    
    #ifdef CONFIG_DRIVER_TI_CPSW
    	cpsw_pad_config();
    #endif
    
    	eth_clock_config = __raw_readl(SMA1);
    	printf("Ethernet clocking: 0x%x\n", eth_clock_config);
    
    	if (!eth_getenv_enetaddr("ethaddr", mac_addr)) {
    		char mac_addr_env[20];
    
    		printf("<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;
    		/* set the ethaddr variable with MACID detected */
    		sprintf(mac_addr_env, "%02x:%02x:%02x:%02x:%02x:%02x",
    			mac_addr[0], mac_addr[1], mac_addr[2],
    			mac_addr[3], mac_addr[4], mac_addr[5]);
    		eth_setenv_enetaddr("ethaddr", (unsigned char *)mac_addr_env);
    	}
    
    	if (is_valid_ether_addr(mac_addr)) {
    		printf("Detected MACID:%x:%x:%x:%x:%x:%x\n", mac_addr[0],
    			mac_addr[1], mac_addr[2], mac_addr[3],
    			mac_addr[4], mac_addr[5]);
    		cpsw_eth_set_mac_addr(mac_addr);
    	} else {
    		printf("Caution:using static MACID!! Set <ethaddr> variable\n");
    	}
    
    	return cpsw_register(&cpsw_data);
    }
    #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 *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 */
    
    #ifdef CONFIG_GENERIC_MMC
    static void rsb_emmc_mux_init(void)
    {
    	printf("%s for RSB\n",__func__);
    	//printk("Enable MMCHS_2 clock\n");
    	//__raw_writel(0x02, TI814X_CM_ALWON_MMCHS_2_CLKCTRL);
    	
    	PAD_CNTRL(113) = 0x00070001; //mmc2_dat7
    	PAD_CNTRL(114) = 0x00070001; //mmc2_dat6
    	PAD_CNTRL(115) = 0x00070001; //mmc2_dat5
    	PAD_CNTRL(116) = 0x00070001; //mmc2_dat4
    	PAD_CNTRL(117) = 0x00070001; //mmc2_dat3
    	PAD_CNTRL(118) = 0x00070001; //mmc2_dat2
    	PAD_CNTRL(119) = 0x00070001; //mmc2_dat1
    	PAD_CNTRL(120) = 0x00070001; //mmc2_dat0
    	PAD_CNTRL(121) = 0x00070001; //mmc2_clk
    	PAD_CNTRL(126) = 0x00070002; //mmc2_cmd
    	PAD_CNTRL(131) = 0x00050080; //EMMC_ON_N
    
    	// PAD131, MMC_ON_N
        	set_pin_direction(GPIO1_BASE, EMMC_ON_GPIO1_PIN, OUTPUT);
        	set_pin_value(GPIO1_BASE, EMMC_ON_GPIO1_PIN, 0);
    
    	__raw_writel(0x00050040, 0xFA140920);	/*PINCNTL73  - MMC2_SDCD*/		
    	/*MMC2_SDCD is enabled only to satisfy the host controller 
    	implementation.	This pin is not used in case of eMMC device 
    	but is enabled with pulled-up high to satisfy controller.*/
    }
    
    int board_mmc_init(bd_t *bis)
    {
    	rsb_emmc_mux_init();
    	omap_mmc_init(0);
    	/*eMMC in RSB*/
    	omap_mmc_init(1);
    	return 0;
    }
    #endif
    

    BR/-

    Nihad

  • Nihad,

    Are you using 1-bit, 4-bit or 8-bit mode?

    Can you provide me also the values of the below registers:

    SD2_CLK/PINCNTL121/0x481409E0
    SD2_CMD/PINCNTL126/0x481409F4
    SD2_DAT[0]/PINCNTL120/0x481409DC
    SD2_DAT[1]_SDIRQ/PINCNTL119/0x481409D8
    SD2_DAT[2]_SDRW/PINCNTL118/0x481409D4
    SD2_DAT[3]/PINCNTL117/0x481409D0
    SD2_SDCD/PINCNTL73/0x48140920

    Get these values after u-boot is up, with md command.

    See also the below e2e thread:

    https://e2e.ti.com/support/arm/sitara_arm/f/791/p/259004/1140810#1140810

    BR
    Pavel

  • Pavel,

    I am using 8 bit mode

    TI811X_EVM#md 0x481409E0 1
    481409e0: 00070001 ....
    TI811X_EVM#md 0x481409F4 1
    481409f4: 00070002 ....
    TI811X_EVM#md 0x481409DC 1
    481409dc: 00070001 ....
    TI811X_EVM#md 0x481409D8 1
    481409d8: 00070001 ....
    TI811X_EVM#md 0x481409D4 1
    481409d4: 00070001 ....
    TI811X_EVM#md 0x481409D0 1
    481409d0: 00070001 ....
    TI811X_EVM#md 0x48140920 1
    48140920: 00050040 @...
    TI811X_EVM#

    BR/-
    Nihad
  • Abdul VK said:
    I am using 8 bit mode

    Then can you also provide the below values:

    SD2_DAT[4]/PINCNTL116/0x481409CC
    SD2_DAT[5]/PINCNTL115/0x481409C8
    SD2_DAT[6]/PINCNTL114/0x481409C4
    SD2_DAT[7]/PINCNTL113/0x481409C0


    You state that MMC2/eMMC works fine in linux kernel. Can you compare pinmux values between u-boot (checked with md) and kernel (checked with devmem2), are they the same?

    Can you compare the MMC2/eMMC registers between u-boot and linux kernel, do they have the same values?


    Can you try also to enable/register first MMC2/eMMC then MMC1, in this case will MMC2/eMMC work fine, but MMC1 fail? I mean to reverse the MMC enable order in u-boot.

    BR
    Pavel

  • Pavel,

    In uboot
    --------
    0x481409C0 : 00070001
    0x481409C4 : 00070001
    0x481409C8 : 00070001
    0x481409CC : 00070001
    0x481409D0 : 00070001
    0x481409D4 : 00070001
    0x481409D8 : 00070001
    0x481409DC : 00070001
    0x481409E0 : 00070001
    0x481409F4 : 00070002
    0x48140920 : 00050040

    In Linux
    ------------
    0x481409C0 : 0x00060001
    0x481409C4 : 0x00060001
    0x481409C8 : 0x00060001
    0x481409CC : 0x00060001
    0x481409D0 : 0x00060001
    0x481409D4 : 0x00060001
    0x481409D8 : 0x00060001
    0x481409DC : 0x00060001
    0x481409E0 : 0x00050001
    0x481409F4 : 0x00060002
    0x48140920 : 0x00050040

    I have reversed the MMC enable order in u-boot. boot failed. see the log below.

    U-Boot 2010.06-00011-g234d700-dirty (Nov 10 2015 - 22:05:34)

    TI811X-GP rev 1.1

    ARM clk: 600MHz
    DDR clk: 333MHz

    I2C: ready
    DRAM: 1 GiB
    MMC: Nid: mmc_initialize: board_mmc_init
    rsb_emmc_mux_init for RSB
    Setting gpio29 as: output
    Setting gpio29 with 0
    Nid: omap_mmc_init: MMC:1
    Nid: omap_mmc_init: mmc2: mmc_base: 0x47810100
    Nid: omap_mmc_init: mmc2:
    Nid: omap_mmc_init: registering mmc1
    Nid: omap_mmc_init: MMC:0
    Nid: omap_mmc_init: registering mmc0
    Nid11: OMAP SD/MMC: 0, Nid11: OMAP SD/MMC: 1
    Using default environment

    Error: EEPROM read failed.
    Warning: Board revision detection failed.
    The 2nd stage U-Boot will now be auto-loaded
    Please do not interrupt the countdown till TI811X_EVM prompt if 2nd stage is alr
    eady flashed
    Hit any key to stop autoboot: 0
    Nid: mmc_init:
    Nid: mmc_init_setup: mmc_base: 0x47810100
    Nid: mmc_set_bus_width: bus width = 1
    Nid: mmc_set_ios: bus width set to 8
    Nid: mmc_set_ios: bus width set to 8
    Nid: mmc_startup:
    Nid: mmc_startup: err=0
    Nid: mmc_startup: its an MMC
    Nid: mmc_startup: high capacity
    Nid: mmc_startup: Capacity1: 0
    Nid: mmc_startup: Capacity2: 0
    ** Can't read from device 0 **

    ** Unable to use mmc 0:1 for fatload **
    ## Starting application at 0x80800000 ...
  • Nihad,

    Abdul VK said:
    In uboot
    --------
    0x481409C0 : 00070001
    0x481409C4 : 00070001
    0x481409C8 : 00070001
    0x481409CC : 00070001
    0x481409D0 : 00070001
    0x481409D4 : 00070001
    0x481409D8 : 00070001
    0x481409DC : 00070001
    0x481409E0 : 00070001
    0x481409F4 : 00070002
    0x48140920 : 00050040

    In Linux
    ------------
    0x481409C0 : 0x00060001
    0x481409C4 : 0x00060001
    0x481409C8 : 0x00060001
    0x481409CC : 0x00060001
    0x481409D0 : 0x00060001
    0x481409D4 : 0x00060001
    0x481409D8 : 0x00060001
    0x481409DC : 0x00060001
    0x481409E0 : 0x00050001
    0x481409F4 : 0x00060002
    0x48140920 : 0x00050040

    I see there are some differences between pinmux in u-boot and in linux. Can you apply the linux values in u-boot, will be there any difference?

    BR
    Pavel

  • Pavel,

    No difference even after change the pin value.
    Why it fails when I reverse the init?

    BR/-
    Nihad
  • Are you able to access/read/write the MMC2/eMMC in u-boot prompt?

    Can you compare the MMC2/eMMC registers between u-boot and linux kernel, do they have the same values?
  • Abdul VK said:
    Why it fails when I reverse the init?

    Most probably because you miss s.th. when making the reverse

  • Pavel,

    Could you please share commands used to read/write eMMC from uboot.
    Could you please tell me which all registers i need to compare?
    What do you mean by "miss s.th"

    int board_mmc_init(bd_t *bis)
    {
    rsb_emmc_mux_init();
    /*eMMC in RSB*/
    omap_mmc_init(1);
    /*SD card*/
    omap_mmc_init(0);
    return 0;
    }

    BR/-
    Nihad
  • Abdul VK said:
    Could you please share commands used to read/write eMMC from uboot.

    Try to read from MMC2/eMMC with:

    TI811X_EVM#fatload mmc 1 0x82000000 <file that is located in eMMC>

    Abdul VK said:
    Could you please tell me which all registers i need to compare?

    Try with all. MMCHS_HL_REV/0x47810000 to MMCHS_REV/0x478102FC


  • Pavel,

    Does uboot support fat 32 and fat 16 partition?

    BR/-
    Nihad
  • Yes, this is what I have for MMC1:

    TI811X_EVM#fatload mmc 0 0x83000000 u-boot.bin
    reading u-boot.bin

    210408 bytes read

    Note also that your bus width report is also wrong. By default it is 4-bit:

    TI811X_EVM#mmcinfo 0
    Device: OMAP SD/MMC
    Manufacturer ID: 3
    OEM: 5344
    Name: SU04G
    Tran Speed: 25000000
    Rd Block Len: 512
    SD version 2.0
    High Capacity: Yes
    Capacity: 3965190144
    Bus Width: 4-bit

    While you are using 8-bit, but your u-boot report 1-bit. If you disable MMC1 at all, and only enable MMC2/eMMC, will u-boot detect it correctly?



    BR
    Pavel

  • Pavel,

    Not able to read/write eMMC from uboot

    TI811X_EVM#mmcinfo 1
    Nid: mmc_init:
    Nid: mmc_init_setup: mmc_base: 0x47810100
    Nid: mmc_set_bus_width: bus width = 1
    Nid: mmc_set_ios: bus width set to 8
    Nid: mmc_set_ios: bus width set to 8
    mmc_set_ios: dsor: 250
    Nid: mmc_startup:
    Nid: mmc_startup: err=0
    Nid: mmc_startup: its an MMC
    Nid: mmc_startup: high capacity
    Nid: mmc_startup: Capacity1: 0
    Nid: mmc_startup: Capacity2: 0
    Device: OMAP SD/MMC
    Manufacturer ID: fe
    OEM: 14e
    Name: MMC04
    Tran Speed: 25000000
    Rd Block Len: 512
    MMC version 4.0
    High Capacity: Yes
    Capacity: 2199023255552
    Bus Width: 1-bit
    TI811X_EVM#fatls mmc 1:1
    ** Can't read from device 1 **

    ** Unable to use mmc 1:1 for fatls **
    TI811X_EVM#mmc rescan 1
    Nid: mmc_init:
    Nid: mmc_init_setup: mmc_base: 0x47810100
    Nid: mmc_set_bus_width: bus width = 1
    Nid: mmc_set_ios: bus width set to 8
    mmc_set_ios: dsor: 250
    Nid: mmc_set_ios: bus width set to 8
    mmc_set_ios: dsor: 250
    Nid: mmc_startup:
    Nid: mmc_startup: err=0
    Nid: mmc_startup: its an MMC
    Nid: mmc_startup: high capacity
    Nid: mmc_startup: Capacity1: 0
    Nid: mmc_startup: Capacity2: 0
    TI811X_EVM#fatload mmc 1 0x82000000 uImage
    ** Can't read from device 1 **

    ** Unable to use mmc 1:1 for fatload **
    TI811X_EVM#


    --------------------------
    Kernel space
    --------------------------
    root@c6a811x-evm:~# cat /proc/partitions
    major minor #blocks name

    179 0 15628800 mmcblk0
    179 1 72261 mmcblk0p1
    179 2 15550920 mmcblk0p2
    179 8 3842048 mmcblk1
    179 9 72261 mmcblk1p1
    179 10 1847475 mmcblk1p2
    179 11 1911735 mmcblk1p3
    root@c6a811x-evm:~# mount -t vfat /dev/mmcblk1p1 boot/
    root@c6a811x-evm:~# dd if=uImage of=boot/uImage bs=1k
    2665+1 records in
    2665+1 records out
    root@c6a811x-evm:~# ls -la boot/
    drwxr-xr-x 2 root root 16384 Nov 27 21:22 .
    drwxrwsrwx 4 1000 root 4096 Nov 10 2015 ..
    -rwxr-xr-x 1 root root 2729264 Nov 27 21:22 uImage
    root@c6a811x-evm:~# fdisk /dev/mmcblk1

    Command (m for help): p

    Disk /dev/mmcblk1: 3934 MB, 3934257152 bytes
    255 heads, 63 sectors/track, 478 cylinders
    Units = cylinders of 16065 * 512 = 8225280 bytes
    Sector size (logical/physical): 512 bytes / 512 bytes
    Disk identifier: 0x00000000

    Device Boot Start End Blocks Id System
    /dev/mmcblk1p1 * 1 9 72261 c W95 FAT32 (LBA)
    /dev/mmcblk1p2 11 240 1847475 83 Linux
    /dev/mmcblk1p3 241 478 1911735 83 Linux

    Command (m for help): q

    root@c6a811x-evm:~#
  • Pavel,

    Below is the dump of registers in uboot and linux

    In uboot
    ----------
    0x47810110 : 00002015
    0x47810114 : 00000001
    0x4781012C : 00000620
    0x47810204 : 00000200
    0x47810208 : 03b90100
    0x4781020C : 061b0000
    0x47810210 : 00000900
    0x47810214 : ffffffe7
    0x47810218 : 0f5913ff
    0x4781021C : d04f0132
    0x47810220 : fefefefe
    0x47810228 : 00000d00
    0x4781022C : 000e3e87
    0x47810230 : 20018002
    0x47810234 : 307f0033
    0x47810238 : 00000000
    0x47810240 : 06e10080
    0x47810224 : 01f70001

    In linux
    --------
    0x47810110 : 0x00002015
    0x47810114 : 0x00000001
    0x4781012C : 0x00000720
    0x47810204 : 0x00000000
    0x47810208 : 0x00010000
    0x4781020C : 0x0D020001
    0x47810210 : 0x00000900
    0x47810214 : 0xFFFFFFE7
    0x47810218 : 0x0F5913FF
    0x4781021C : 0xD04F0132
    0x47810220 : 0x00000000
    0x47810228 : 0x00000B00
    0x4781022C : 0x000E0107
    0x47810230 : 0x00000000
    0x47810234 : 0x000000C0
    0x47810238 : 0x000000C0
    0x47810240 : 0x04E10080
    0x47810224 : 0x01FF0000

    BR/-
    Nihad
  • Nihad,

    There are differences in these register settings. I would recommend you to align u-boot settings with linux settings (as you stated that MMC2/eMMC works fine under linux).

    BR
    Pavel
  • Pavel,

    I have calculated address as 0x47810100 + Register offset
    For example
    HSMMC_BASE 0x47810100 +
    OMAP_HSMMC_HCTL 0x0128
    --------------------------------------------------------
    0x47810228

    Are you Ok with the address calculation.
    If I want to align linux and uboot register value, I need to rework on uboot-xxx/driver/mmc/omap_hsmmc.c. MMC is an standard interface, do we really need to do modification on the driver?. If the existing driver won't support addition of new mmc, Then What is the purpose of this driver?.
    How will I know that what value need to go to each register. Aligning register value is a bigger job. What i understood from the driver is, register value is set based on the some conditions. If I modify this, Will it damage working of SD card, since SD card also using same driver?. There is something else is missing. Could you please review the omap_hsmmc.c in linux and uboot. why it is not working in uboot?
  • Nihad,

    Abdul VK said:
    modified:   board-support/u-boot-2010.06-psp04.07.00.02/drivers/mmc/omap_hsmmc.c
    int omap_mmc_init(int dev_index)
    {
        struct mmc *mmc;

        mmc = &hsmmc_dev[dev_index];

        sprintf(mmc->name, "OMAP SD/MMC");
        mmc->block_dev.removable = 1;
        mmc->send_cmd = mmc_send_cmd;
        mmc->set_ios = mmc_set_ios;
        mmc->init = mmc_init_setup;
        printf("Nid: %s: MMC:%d\n", __func__, dev_index);
    #if !defined(CONFIG_TI81XX)
        switch (dev_index) {
        ------
        ----
        }
    #else
        //Nid modified to support eMMC
        //mmc->priv = (hsmmc_t *)OMAP_HSMMC_BASE;
        switch (dev_index) {
        case 0:
            mmc->priv = (hsmmc_t *)OMAP_HSMMC_BASE;
            break;
        case 1:
            mmc->priv = (hsmmc_t *)OMAP_HSMMC2_BASE;
            printf("Nid: %s: mmc2: mmc_base: 0x%x\n", __func__, mmc->priv);
            break;    
        default:
            mmc->priv = (hsmmc_t *)OMAP_HSMMC_BASE;
            return 1;
        }
    #endif
    #if defined(CONFIG_TI81XX)
        if(dev_index){
            printf("Nid: %s: mmc2: \n", __func__);
            mmc->voltages = MMC_VDD_33_34;
            mmc->host_caps = MMC_MODE_8BIT | MMC_MODE_HS;
            mmc->block_dev.removable = 0;
            mmc->bus_width = 8;
        }else{
            mmc->voltages = MMC_VDD_32_33 | MMC_VDD_33_34 | MMC_VDD_165_195;
            mmc->host_caps = MMC_MODE_4BIT | MMC_MODE_HS_52MHz | MMC_MODE_HS;
        }
    #else
        mmc->voltages = MMC_VDD_32_33 | MMC_VDD_33_34 | MMC_VDD_165_195;
        mmc->host_caps = MMC_MODE_4BIT | MMC_MODE_HS_52MHz | MMC_MODE_HS;
    #endif
    }

    Revising your omap_hsmmc.c code, it seems to me that you set bus_width to 8 for MMC2 (index 1), after the bus width initialization (mmc->set_ios = mmc_set_ios;)

    Can you put print in function mmc_set_ios() to verify that your flow enters in case 8 when for MMC2 (index 1)?

    BR
    Pavel

  • Pavel,

    eMMC before modification
    -----------------------------------------
    TI811X_EVM#mmc rescan 1
    Nid: mmc_init:
    Nid: mmc_init_setup: mmc_base: 0x47810100
    Nid: mmc_set_bus_width: bus width = 1
    Nid: mmc_set_ios: actual bus width = 1
    Nid: mmc_set_ios: con and hctl set bus width = 1
    mmc_set_ios: dsor: 4
    Nid: mmc_set_ios: actual bus width = 1
    Nid: mmc_set_ios: con and hctl set bus width = 1
    mmc_set_ios: dsor: 250
    Nid: mmc_startup:
    Nid: mmc_startup: err=0
    Nid: mmc_startup: its an MMC
    Nid: mmc_startup: high capacity
    Nid: mmc_startup: Capacity1: 0
    Nid: mmc_startup: Capacity2: 0
    Nid3: mmc_startup: MMC
    Nid: mmc_set_ios: actual bus width = 1
    Nid: mmc_set_ios: con and hctl set bus width = 1
    mmc_set_ios: dsor: 4
    TI811X_EVM#


    eMMC after modification
    -----------------------------------------

    TI811X_EVM#mmc rescan 1
    Nid: mmc_init:
    Nid: mmc_init_setup: mmc_base: 0x47810100
    Nid: mmc_set_bus_width: bus width = 1
    Nid: mmc_set_ios: actual bus width = 1
    Nid: mmc_set_ios: bus width set to 8
    Nid: mmc_set_ios: con and hctl set bus width = 8
    mmc_set_ios: dsor: 250
    Nid: mmc_set_ios: actual bus width = 8
    Nid: mmc_set_ios: bus width set to 8
    Nid: mmc_set_ios: con and hctl set bus width = 8
    mmc_set_ios: dsor: 250
    Nid: mmc_startup:
    Nid: mmc_startup: err=0
    Nid: mmc_startup: its an MMC
    Nid: mmc_startup: high capacity
    Nid: mmc_startup: Capacity1: 0
    Nid: mmc_startup: Capacity2: 0

    SD card
    ------------
    TI811X_EVM#mmc rescan 0
    Nid: mmc_init:
    Nid: mmc_init_setup: mmc_base: 0x481d8100
    Nid: mmc_set_bus_width: bus width = 1
    Nid: mmc_set_ios: actual bus width = 1
    Nid: mmc_set_ios: con and hctl set bus width = 1
    mmc_set_ios: dsor: 4
    Nid: mmc_set_ios: actual bus width = 1
    Nid: mmc_set_ios: con and hctl set bus width = 1
    mmc_set_ios: dsor: 480
    Nid: mmc_startup:
    Nid: mmc_startup: err=0
    Nid: mmc_startup: its an SD card
    Nid: mmc_startup: high capacity
    Nid: mmc_startup: Capacity1: 31257600
    Nid: mmc_startup: Capacity2: -1175977984
    Nid2: mmc_startup: SD card
    Nid: mmc_set_bus_width: bus width = 4
    Nid: mmc_set_ios: actual bus width = 4
    Nid: mmc_set_ios: con and hctl set bus width = 4
    mmc_set_ios: dsor: 480
    Nid: mmc_set_ios: actual bus width = 4
    Nid: mmc_set_ios: con and hctl set bus width = 4
    mmc_set_ios: dsor: 4

    For eMMC not able to calculate capacity. it returns zero.

    BR/-
    Nihad
  • Nihad,

    I will check for the capacity, but I see also the below from your initial post:

    TI811X_EVM#mmcinfo 1
    ...
    Bus Width: 1-bit

    Bus width is reported as 1-bit, not 8-bit.

    BR
    Pavel
  • pavel,

    Bus width = 1 is another issue.
    Initially driver start communication in 1 bit mode. After enough negotiation it will calculate capacity and set the actual bus width i.e 4 or 8 bit.
    In SD card it is 4 bit. in eMMC it should be 8 bit.
    So my doubt is negotiation with SD card was success, but somehow eMMC is not done successfully. Thats why it is not able to calculate the capacity, subsequently it fails other items also.
    So here driver behavior is different for SD card and eMMC. This is what we need to tackle.

    In linux we can populate below structure and pass to driver. But there is no such option in uboot
    static struct omap2_hsmmc_info mmc[] = {
    {
    .mmc = 1,
    .caps = MMC_CAP_4_BIT_DATA,
    .gpio_cd = -EINVAL,/* Dedicated pins for CD and WP */
    .gpio_wp = -EINVAL,
    .ocr_mask = MMC_VDD_33_34,
    },
    {
    .mmc = 2,
    .caps = MMC_CAP_8_BIT_DATA, //MMC_CAP_NONREMOVABLE | MMC_CAP_ERASE | MMC_CAP_MMC_HIGHSPEED | MMC_CAP_8_BIT_DATA,
    .transceiver = false,
    .nonremovable = true,
    .gpio_cd = -EINVAL,/* Dedicated pins for CD and WP */
    .gpio_wp = -EINVAL,
    .ocr_mask = MMC_VDD_33_34,
    },

    {} /* Terminator */
    };

    BR/-
    Nihad
  • Nihad,

    Regarding the capacity, can you try the below change in u-boot/common/cmd_mmc.c

    static void print_mmcinfo(struct mmc *mmc)

    printf("High Capacity: %s\n", mmc->high_capacity ? "Yes" : "No");
    - printf("Capacity: %lld\n", mmc->capacity);
    + puts("Capacity: ");
    + print_size(mmc->capacity, "\n");

    printf("Bus Width: %d-bit\n", mmc->bus_width);
    }
  • Pavel,

    it shows 2TB eMMC. actual size is 4 GB

    TI811X_EVM#mmcinfo 0
    Nid: mmc_init:
    Nid: mmc_init_setup: mmc_base: 0x481d8100
    Nid: mmc_set_bus_width: bus width = 1
    Nid: mmc_set_ios: actual bus width = 1
    Nid: mmc_set_ios: con and hctl set bus width = 1
    mmc_set_ios: dsor: 4
    Nid: mmc_set_ios: actual bus width = 1
    Nid: mmc_set_ios: con and hctl set bus width = 1
    mmc_set_ios: dsor: 480
    Nid: mmc_startup:
    Nid: mmc_startup: err=0
    Nid: mmc_startup: its an SD card
    Nid: mmc_startup: high capacity
    Nid: mmc_startup: Capacity1: 31257600
    Nid: mmc_startup: Capacity2: -1175977984
    Nid2: mmc_startup: SD card
    Nid: mmc_set_bus_width: bus width = 4
    Nid: mmc_set_ios: actual bus width = 4
    Nid: mmc_set_ios: con and hctl set bus width = 4
    mmc_set_ios: dsor: 480
    Nid: mmc_set_ios: actual bus width = 4
    Nid: mmc_set_ios: con and hctl set bus width = 4
    mmc_set_ios: dsor: 4
    Device: OMAP SD/MMC
    Manufacturer ID: 1b
    OEM: 534d
    Name: 00000
    Tran Speed: 25000000
    Rd Block Len: 512
    SD version 2.0
    High Capacity: Yes
    Capacity: 14.9 GiB
    Bus Width: 4-bit
    TI811X_EVM#
    Unknown command '' - try 'help'
    TI811X_EVM#mmcinfo 1
    Nid: mmc_init:
    Nid: mmc_init_setup: mmc_base: 0x47810100
    Nid: mmc_set_bus_width: bus width = 1
    Nid: mmc_set_ios: actual bus width = 1
    Nid: mmc_set_ios: con and hctl set bus width = 1
    Nid: mmc_set_ios: actual bus width = 1
    Nid: mmc_set_ios: con and hctl set bus width = 1
    mmc_set_ios: dsor: 250
    Nid: mmc_startup:
    Nid: mmc_startup: err=0
    Nid: mmc_startup: its an MMC
    Nid: mmc_startup: high capacity
    Nid: mmc_startup: Capacity1: 0
    Nid: mmc_startup: Capacity2: 0
    Nid3: mmc_startup: MMC
    Nid: mmc_set_ios: actual bus width = 1
    Nid: mmc_set_ios: con and hctl set bus width = 1
    mmc_set_ios: dsor: 4
    Device: OMAP SD/MMC
    Manufacturer ID: fe
    OEM: 14e
    Name: MMC04
    Tran Speed: 25000000
    Rd Block Len: 512
    MMC version 4.0
    High Capacity: Yes
    Capacity: 2 TiB
    Bus Width: 1-bit
    TI811X_EVM#
  • Pavel,

    Any update on this issue. Did you got any solution?

    BR/-
    Nihad
  • Nihad,

    Let me update this thread with the info from RK:

    Issue#1 When printed mmcinfo the bus width is set to 1 bit – expected is 8bit
    Issue#2: Capacity is shown as 2TiB – actual is 4GB

    For Issue#1:
    In omap_mmc_init() function of drivers/mmc/omap_hsmmc.c,
    make sure mmc->host_caps are updated with MMC_MODE_8BIT.

    For Issue#2:

    This is due to wrong size calculation, the calculation of size has changed for eMMC >=4.0 , it’s now based on sector size. Capacity -= sector size * block length, new u-boot driver has these changes it can be found here:

    git.omapzoom.org/.../

    refer to drivers/mmc/mmc.c
    drivers/mmc/omap_hsmmc.c

    Refer to board/ti/dra7xx/evm.c, it supports eMMC (MMC2 instance, devindex=1)


    - To read mmcinfo in kernel
    Mount –t debugfs debugfs /sys/kernel/debug
    Cat /sys/kernel/debug/mmc<x>/ios

    - Would also recommend referring to latest kernel mmc driver for proper implementation and bug fixes
    git.omapzoom.org/.../

    BR
    Pavel
  • RK and Pavel,

    Just to close this thread i am updating my status.

    As i mentioned in the call, Now I am able to boot kernel and RFS from eMMC. To fix the issue I have integrated few changes of omap_hsmmc.c file from mainline uboot. attached omap-hsmmc.file
    6170.omap_hsmmc.c
    /*
     * (C) Copyright 2008
     * Texas Instruments, <www.ti.com>
     * Sukumar Ghorai <s-ghorai@ti.com>
     *
     * See file CREDITS for list of people who contributed to this
     * project.
     *
     * 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's version 2 of
     * the License.
     *
     * This program is distributed in the hope that it will be useful,
     * but WITHOUT ANY WARRANTY; without even the implied warranty of
     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     * GNU General Public License for more details.
     *
     * You should have received a copy of the GNU General Public License
     * along with this program; if not, write to the Free Software
     * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
     * MA 02111-1307 USA
     */
    
    #include <config.h>
    #include <common.h>
    #include <mmc.h>
    #include <part.h>
    #include <i2c.h>
    #include <twl4030.h>
    #include <asm/io.h>
    #include <asm/arch/mmc_host_def.h>
    
    /* common definitions for all OMAPs */
    #define SYSCTL_SRC	(1 << 25)
    #define SYSCTL_SRD	(1 << 26)
    
    /* If we fail after 1 second wait, something is really bad */
    #define MAX_RETRY_MS	1000
    
    static int mmc_read_data(hsmmc_t *mmc_base, char *buf, unsigned int size);
    static int mmc_write_data(hsmmc_t *mmc_base, const char *buf, unsigned int siz);
    static struct mmc hsmmc_dev[2];
    unsigned char mmc_board_init(hsmmc_t *mmc_base)
    {
    #if defined(CONFIG_TWL4030_POWER)
    	twl4030_power_mmc_init();
    #endif
    
    #if defined(CONFIG_OMAP34XX)
    	t2_t *t2_base = (t2_t *)T2_BASE;
    	struct prcm *prcm_base = (struct prcm *)PRCM_BASE;
    
    	writel(readl(&t2_base->pbias_lite) | PBIASLITEPWRDNZ1 |
    		PBIASSPEEDCTRL0 | PBIASLITEPWRDNZ0,
    		&t2_base->pbias_lite);
    
    	writel(readl(&t2_base->devconf0) | MMCSDIO1ADPCLKISEL,
    		&t2_base->devconf0);
    
    	writel(readl(&t2_base->devconf1) | MMCSDIO2ADPCLKISEL,
    		&t2_base->devconf1);
    
    	writel(readl(&prcm_base->fclken1_core) |
    		EN_MMC1 | EN_MMC2 | EN_MMC3,
    		&prcm_base->fclken1_core);
    
    	writel(readl(&prcm_base->iclken1_core) |
    		EN_MMC1 | EN_MMC2 | EN_MMC3,
    		&prcm_base->iclken1_core);
    #endif
    
    /* TODO add appropriate OMAP4 init - none currently necessary */
    
    	return 0;
    }
    
    void mmc_init_stream(hsmmc_t *mmc_base)
    {
    	ulong start;
    
    	writel(readl(&mmc_base->con) | INIT_INITSTREAM, &mmc_base->con);
    
    	writel(MMC_CMD0, &mmc_base->cmd);
    	start = get_timer(0);
    	while (!(readl(&mmc_base->stat) & CC_MASK)) {
    		if (get_timer(0) - start > MAX_RETRY_MS) {
    			printf("%s: timedout waiting for cc!\n", __func__);
    			return;
    		}
    	}
    	writel(CC_MASK, &mmc_base->stat)
    		;
    	writel(MMC_CMD0, &mmc_base->cmd)
    		;
    	start = get_timer(0);
    	while (!(readl(&mmc_base->stat) & CC_MASK)) {
    		if (get_timer(0) - start > MAX_RETRY_MS) {
    			printf("%s: timedout waiting for cc2!\n", __func__);
    			return;
    		}
    	}
    	writel(readl(&mmc_base->con) & ~INIT_INITSTREAM, &mmc_base->con);
    }
    
    
    static int mmc_init_setup(struct mmc *mmc)
    {
    	hsmmc_t *mmc_base = (hsmmc_t *)mmc->priv;
    	unsigned int reg_val;
    	unsigned int dsor;
    	ulong start;
    	printf("%s: mmc_base: 0x%x\n", __func__, (unsigned int)mmc_base);
    	mmc_board_init(mmc_base);
    
    	writel(readl(&mmc_base->sysconfig) | MMC_SOFTRESET,
    		&mmc_base->sysconfig);
    	start = get_timer(0);
    	while ((readl(&mmc_base->sysstatus) & RESETDONE) == 0) {
    		if (get_timer(0) - start > MAX_RETRY_MS) {
    			printf("%s: timedout waiting for cc2!\n", __func__);
    			return TIMEOUT;
    		}
    	}
    	writel(readl(&mmc_base->sysctl) | SOFTRESETALL, &mmc_base->sysctl);
    	start = get_timer(0);
    	while ((readl(&mmc_base->sysctl) & SOFTRESETALL) != 0x0) {
    		if (get_timer(0) - start > MAX_RETRY_MS) {
    			printf("%s: timedout waiting for softresetall!\n",
    				__func__);
    			return TIMEOUT;
    		}
    	}
    	writel(DTW_1_BITMODE | SDBP_PWROFF | SDVS_3V0, &mmc_base->hctl);
    	writel(readl(&mmc_base->capa) | VS30_3V0SUP | VS18_1V8SUP,
    		&mmc_base->capa);
    
    	reg_val = readl(&mmc_base->con) & RESERVED_MASK;
    
    	writel(CTPL_MMC_SD | reg_val | WPP_ACTIVEHIGH | CDP_ACTIVEHIGH |
    		MIT_CTO | DW8_1_4BITMODE | MODE_FUNC | STR_BLOCK |
    		HR_NOHOSTRESP | INIT_NOINIT | NOOPENDRAIN, &mmc_base->con);
    
    	dsor = 240;
    	mmc_reg_out(&mmc_base->sysctl, (ICE_MASK | DTO_MASK | CEN_MASK),
    		(ICE_STOP | DTO_15THDTO | CEN_DISABLE));
    	mmc_reg_out(&mmc_base->sysctl, ICE_MASK | CLKD_MASK,
    		(dsor << CLKD_OFFSET) | ICE_OSCILLATE);
    	start = get_timer(0);
    	while ((readl(&mmc_base->sysctl) & ICS_MASK) == ICS_NOTREADY) {
    		if (get_timer(0) - start > MAX_RETRY_MS) {
    			printf("%s: timedout waiting for ics!\n", __func__);
    			return TIMEOUT;
    		}
    	}
    	writel(readl(&mmc_base->sysctl) | CEN_ENABLE, &mmc_base->sysctl);
    
    	writel(readl(&mmc_base->hctl) | SDBP_PWRON, &mmc_base->hctl);
    
    	writel(IE_BADA | IE_CERR | IE_DEB | IE_DCRC | IE_DTO | IE_CIE |
    		IE_CEB | IE_CCRC | IE_CTO | IE_BRR | IE_BWR | IE_TC | IE_CC,
    		&mmc_base->ie);
    
    	mmc_init_stream(mmc_base);
    
    	return 0;
    }
    
    /*
     * MMC controller internal finite state machine reset
     *
     * Used to reset command or data internal state machines, using respectively
     * SRC or SRD bit of SYSCTL register
     */
    static void mmc_reset_controller_fsm(hsmmc_t *mmc_base, u32 bit)
    {
    	ulong start;
    
    	mmc_reg_out(&mmc_base->sysctl, bit, bit);
    
    	/*
    	 * CMD(DAT) lines reset procedures are slightly different
    	 * for OMAP3 and OMAP4(AM335x,OMAP5,DRA7xx).
    	 * According to OMAP3 TRM:
    	 * Set SRC(SRD) bit in MMCHS_SYSCTL register to 0x1 and wait until it
    	 * returns to 0x0.
    	 * According to OMAP4(AM335x,OMAP5,DRA7xx) TRMs, CMD(DATA) lines reset
    	 * procedure steps must be as follows:
    	 * 1. Initiate CMD(DAT) line reset by writing 0x1 to SRC(SRD) bit in
    	 *    MMCHS_SYSCTL register (SD_SYSCTL for AM335x).
    	 * 2. Poll the SRC(SRD) bit until it is set to 0x1.
    	 * 3. Wait until the SRC (SRD) bit returns to 0x0
    	 *    (reset procedure is completed).
    	 */
    #if defined(CONFIG_OMAP44XX) || defined(CONFIG_OMAP54XX) || \
    	defined(CONFIG_AM33XX) || defined(CONFIG_AM43XX)
    	if (!(readl(&mmc_base->sysctl) & bit)) {
    		start = get_timer(0);
    		while (!(readl(&mmc_base->sysctl) & bit)) {
    			if (get_timer(0) - start > MAX_RETRY_MS)
    				return;
    		}
    	}
    #endif
    	start = get_timer(0);
    	while ((readl(&mmc_base->sysctl) & bit) != 0) {
    		if (get_timer(0) - start > MAX_RETRY_MS) {
    			printf("%s: timedout waiting for sysctl %x to clear\n",
    				__func__, bit);
    			return;
    		}
    	}
    }
    
    static int mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd,
    			struct mmc_data *data)
    {
    	hsmmc_t *mmc_base = (hsmmc_t *)mmc->priv;
    	unsigned int flags, mmc_stat;
    	ulong start;
    
    	start = get_timer(0);
    	while ((readl(&mmc_base->pstate) & DATI_MASK) == DATI_CMDDIS) {
    		if (get_timer(0) - start > MAX_RETRY_MS) {
    			printf("%s: timedout waiting for cmddis!\n", __func__);
    			return TIMEOUT;
    		}
    	}
    	writel(0xFFFFFFFF, &mmc_base->stat);
    	start = get_timer(0);
    	while (readl(&mmc_base->stat)) {
    		if (get_timer(0) - start > MAX_RETRY_MS) {
    			printf("%s: timedout waiting for stat!\n", __func__);
    			return TIMEOUT;
    		}
    	}
    	/*
    	 * CMDREG
    	 * CMDIDX[13:8]	: Command index
    	 * DATAPRNT[5]	: Data Present Select
    	 * ENCMDIDX[4]	: Command Index Check Enable
    	 * ENCMDCRC[3]	: Command CRC Check Enable
    	 * RSPTYP[1:0]
    	 *	00 = No Response
    	 *	01 = Length 136
    	 *	10 = Length 48
    	 *	11 = Length 48 Check busy after response
    	 */
    	/* Delay added before checking the status of frq change
    	 * retry not supported by mmc.c(core file)
    	 */
    	if (cmd->cmdidx == SD_CMD_APP_SEND_SCR)
    		udelay(50000); /* wait 50 ms */
    
    	if (!(cmd->resp_type & MMC_RSP_PRESENT))
    		flags = 0;
    	else if (cmd->resp_type & MMC_RSP_136)
    		flags = RSP_TYPE_LGHT136 | CICE_NOCHECK;
    	else if (cmd->resp_type & MMC_RSP_BUSY)
    		flags = RSP_TYPE_LGHT48B;
    	else
    		flags = RSP_TYPE_LGHT48;
    
    	/* enable default flags */
    	flags =	flags | (CMD_TYPE_NORMAL | CICE_NOCHECK | CCCE_NOCHECK |
    			MSBS_SGLEBLK | ACEN_DISABLE | BCE_DISABLE | DE_DISABLE);
    
    	if (cmd->resp_type & MMC_RSP_CRC)
    		flags |= CCCE_CHECK;
    	if (cmd->resp_type & MMC_RSP_OPCODE)
    		flags |= CICE_CHECK;
    
    	if (data) {
    		if ((cmd->cmdidx == MMC_CMD_READ_MULTIPLE_BLOCK) ||
    			 (cmd->cmdidx == MMC_CMD_WRITE_MULTIPLE_BLOCK)) {
    			flags |= (MSBS_MULTIBLK | BCE_ENABLE);
    			data->blocksize = 512;
    			writel(data->blocksize | (data->blocks << 16),
    							&mmc_base->blk);
    		} else
    			writel(data->blocksize | NBLK_STPCNT, &mmc_base->blk);
    
    		if (data->flags & MMC_DATA_READ)
    			flags |= (DP_DATA | DDIR_READ);
    		else
    			flags |= (DP_DATA | DDIR_WRITE);
    	}
    
    	writel(cmd->cmdarg, &mmc_base->arg);
    	udelay(20);		/* To fix "No status update" error on eMMC */
    	writel((cmd->cmdidx << 24) | flags, &mmc_base->cmd);
    
    	start = get_timer(0);
    	do {
    		mmc_stat = readl(&mmc_base->stat);
    		if (get_timer(0) - start > MAX_RETRY_MS) {
    			printf("%s : timeout: No status update\n", __func__);
    			return TIMEOUT;
    		}
    	} while (!mmc_stat);
    
    	if ((mmc_stat & IE_CTO) != 0) {
    		mmc_reset_controller_fsm(mmc_base, SYSCTL_SRC);
    		return TIMEOUT;
    	} else if ((mmc_stat & ERRI_MASK) != 0)
    		return -1;
    
    	if (mmc_stat & CC_MASK) {
    		writel(CC_MASK, &mmc_base->stat);
    		if (cmd->resp_type & MMC_RSP_PRESENT) {
    			if (cmd->resp_type & MMC_RSP_136) {
    				/* response type 2 */
    				cmd->response[3] = readl(&mmc_base->rsp10);
    				cmd->response[2] = readl(&mmc_base->rsp32);
    				cmd->response[1] = readl(&mmc_base->rsp54);
    				cmd->response[0] = readl(&mmc_base->rsp76);
    			} else
    				/* response types 1, 1b, 3, 4, 5, 6 */
    				cmd->response[0] = readl(&mmc_base->rsp10);
    		}
    	}
    
    	if (data && (data->flags & MMC_DATA_READ)) {
    		mmc_read_data(mmc_base,	data->dest,
    				data->blocksize * data->blocks);
    	} else if (data && (data->flags & MMC_DATA_WRITE)) {
    		mmc_write_data(mmc_base, data->src,
    				data->blocksize * data->blocks);
    	}
    	return 0;
    }
    
    static int mmc_read_data(hsmmc_t *mmc_base, char *buf, unsigned int size)
    {
    	unsigned int *output_buf = (unsigned int *)buf;
    	unsigned int mmc_stat;
    	unsigned int count;
    
    	/*
    	 * Start Polled Read
    	 */
    	count = (size > MMCSD_SECTOR_SIZE) ? MMCSD_SECTOR_SIZE : size;
    	count /= 4;
    
    	while (size) {
    		ulong start = get_timer(0);
    		do {
    			mmc_stat = readl(&mmc_base->stat);
    			if (get_timer(0) - start > MAX_RETRY_MS) {
    				printf("%s: timedout waiting for status!\n",
    						__func__);
    				return TIMEOUT;
    			}
    		} while (mmc_stat == 0);
    		//Nid added
    		if ((mmc_stat & (IE_DTO | IE_DCRC | IE_DEB)) != 0)
    			mmc_reset_controller_fsm(mmc_base, SYSCTL_SRD);
    
    		if ((mmc_stat & ERRI_MASK) != 0)
    			return 1;
    
    		if (mmc_stat & BRR_MASK) {
    			unsigned int k;
    
    			writel(readl(&mmc_base->stat) | BRR_MASK,
    				&mmc_base->stat);
    			for (k = 0; k < count; k++) {
    				*output_buf = readl(&mmc_base->data);
    				output_buf++;
    			}
    			size -= (count*4);
    		}
    
    		if (mmc_stat & BWR_MASK)
    			writel(readl(&mmc_base->stat) | BWR_MASK,
    				&mmc_base->stat);
    
    		if (mmc_stat & TC_MASK) {
    			writel(readl(&mmc_base->stat) | TC_MASK,
    				&mmc_base->stat);
    			break;
    		}
    	}
    	return 0;
    }
    
    static int mmc_write_data(hsmmc_t *mmc_base, const char *buf, unsigned int size)
    {
    	unsigned int *input_buf = (unsigned int *)buf;
    	unsigned int mmc_stat;
    	unsigned int count;
    
    	/*
    	 * Start Polled Write
    	 */
    	count = (size > MMCSD_SECTOR_SIZE) ? MMCSD_SECTOR_SIZE : size;
    	count /= 4;
    
    	while (size) {
    		ulong start = get_timer(0);
    		do {
    			mmc_stat = readl(&mmc_base->stat);
    			if (get_timer(0) - start > MAX_RETRY_MS) {
    				printf("%s: timedout waiting for status!\n",
    						__func__);
    				return TIMEOUT;
    			}
    		} while (mmc_stat == 0);
    		//Nid added
    		if ((mmc_stat & (IE_DTO | IE_DCRC | IE_DEB)) != 0)
    			mmc_reset_controller_fsm(mmc_base, SYSCTL_SRD);
    
    		if ((mmc_stat & ERRI_MASK) != 0)
    			return 1;
    
    		if (mmc_stat & BWR_MASK) {
    			unsigned int k;
    
    			writel(readl(&mmc_base->stat) | BWR_MASK,
    					&mmc_base->stat);
    			for (k = 0; k < count; k++) {
    				writel(*input_buf, &mmc_base->data);
    				input_buf++;
    			}
    			size -= (count*4);
    		}
    
    		if (mmc_stat & BRR_MASK)
    			writel(readl(&mmc_base->stat) | BRR_MASK,
    				&mmc_base->stat);
    
    		if (mmc_stat & TC_MASK) {
    			writel(readl(&mmc_base->stat) | TC_MASK,
    				&mmc_base->stat);
    			break;
    		}
    	}
    	return 0;
    }
    
    static void mmc_set_ios(struct mmc *mmc)
    {
    	hsmmc_t *mmc_base = (hsmmc_t *)mmc->priv;
    	unsigned int dsor = 0;
    	ulong start;
    	unsigned int busWidth = mmc->bus_width;
    	printf("%s: bus width = %d\n",__func__,mmc->bus_width);
    	//if ((unsigned int)mmc_base == OMAP_HSMMC2_BASE){
    	//	mmc->bus_width = 8;
    	//	printf("Nid: %s: bus width set to %d\n", __func__,mmc->bus_width);
    	//}
    	/* configue bus width */
    	switch (mmc->bus_width) {
    	case 8:
    		writel(readl(&mmc_base->con) | DTW_8_BITMODE,
    			&mmc_base->con);
    		//Nid added
    		writel(readl(&mmc_base->hctl) | DTW_8_BITMODE,
    			&mmc_base->hctl);
    		//printf("Nid: %s: con and hctl set bus width = %d\n",__func__,mmc->bus_width);
    		break;
    
    	case 4:
    		writel(readl(&mmc_base->con) & ~DTW_8_BITMODE,
    			&mmc_base->con);
    		writel(readl(&mmc_base->hctl) | DTW_4_BITMODE,
    			&mmc_base->hctl);
    		//printf("Nid: %s: con and hctl set bus width = %d\n",__func__,mmc->bus_width);
    		break;
    
    	case 1:
    	default:
    		writel(readl(&mmc_base->con) & ~DTW_8_BITMODE,
    			&mmc_base->con);
    		writel(readl(&mmc_base->hctl) & ~DTW_4_BITMODE,
    			&mmc_base->hctl);
    		//printf("Nid: %s: con and hctl set bus width = %d\n",__func__,mmc->bus_width);
    		break;
    	}
    
    	/* configure clock with 96Mhz system clock.
    	 */
    	if (mmc->clock != 0) {
    		dsor = (MMC_CLOCK_REFERENCE * 1000000 / mmc->clock);
    		if (dsor < 1)
    			dsor = 1;
    
    		if ((MMC_CLOCK_REFERENCE * 1000000) / dsor > mmc->clock)
    			dsor++;
    		//Nid: Added to support eMMC
    		//defined(CONFIG_TI814X)
    		if ((unsigned int)mmc_base == OMAP_HSMMC2_BASE) { 
    			if (dsor > 250)
    				dsor = 250;
    		}
    		//printf("%s: dsor: %d\n",__func__,dsor);
    		//-----------------------
    	}
    
    	mmc_reg_out(&mmc_base->sysctl, (ICE_MASK | DTO_MASK | CEN_MASK),
    				(ICE_STOP | DTO_15THDTO | CEN_DISABLE));
    
    	mmc_reg_out(&mmc_base->sysctl, ICE_MASK | CLKD_MASK,
    				(dsor << CLKD_OFFSET) | ICE_OSCILLATE);
    
    	start = get_timer(0);
    	while ((readl(&mmc_base->sysctl) & ICS_MASK) == ICS_NOTREADY) {
    		if (get_timer(0) - start > MAX_RETRY_MS) {
    			printf("%s: timedout waiting for ics!\n", __func__);
    			return;
    		}
    	}
    	writel(readl(&mmc_base->sysctl) | CEN_ENABLE, &mmc_base->sysctl);
    	//mmc->bus_width = busWidth;
    }
    
    int omap_mmc_init(int dev_index)
    {
    	struct mmc *mmc;
    
    	mmc = &hsmmc_dev[dev_index];
    
    	sprintf(mmc->name, "OMAP SD/MMC");
    	mmc->block_dev.removable = 1;
    	mmc->send_cmd = mmc_send_cmd;
    	mmc->set_ios = mmc_set_ios;
    	mmc->init = mmc_init_setup;
    	//printf("Nid: %s: MMC:%d\n", __func__, dev_index);
    #if !defined(CONFIG_TI81XX)
    	switch (dev_index) {
    	case 0:
    		mmc->priv = (hsmmc_t *)OMAP_HSMMC1_BASE;
    		break;
    	case 1:
    		mmc->priv = (hsmmc_t *)OMAP_HSMMC2_BASE;
    		break;
    	case 2:
    		mmc->priv = (hsmmc_t *)OMAP_HSMMC3_BASE;
    		break;
    	default:
    		mmc->priv = (hsmmc_t *)OMAP_HSMMC1_BASE;
    		return 1;
    	}
    #else
    	//Nid modified to support eMMC
    	//mmc->priv = (hsmmc_t *)OMAP_HSMMC_BASE;
    	switch (dev_index) {
    	case 0:
    		mmc->priv = (hsmmc_t *)OMAP_HSMMC_BASE;
    		break;
    	case 1:
    		mmc->priv = (hsmmc_t *)OMAP_HSMMC2_BASE;
    		//printf("%s: mmc_base: 0x%x\n", __func__, (unsigned int)mmc->priv);
    		break;	
    	default:
    		mmc->priv = (hsmmc_t *)OMAP_HSMMC_BASE;
    		return 1;
    	}
    #endif
    #if defined(CONFIG_TI81XX)
    	if(dev_index){
    		mmc->voltages = MMC_VDD_32_33 | MMC_VDD_33_34;
    		mmc->host_caps = MMC_MODE_8BIT | MMC_MODE_HS_52MHz | MMC_MODE_HS;
    		mmc->block_dev.removable = 0;
    		mmc->bus_width = 8;
    	}else{
    		mmc->voltages = MMC_VDD_32_33 | MMC_VDD_33_34 | MMC_VDD_165_195;
    		mmc->host_caps = MMC_MODE_4BIT | MMC_MODE_HS_52MHz | MMC_MODE_HS;
    	}
    #else
    	mmc->voltages = MMC_VDD_32_33 | MMC_VDD_33_34 | MMC_VDD_165_195;
    	mmc->host_caps = MMC_MODE_4BIT | MMC_MODE_HS_52MHz | MMC_MODE_HS;
    #endif
    	mmc->f_min = 400000;
    	mmc->f_max = 52000000;
    	printf("%s: registering mmc%d\n", __func__, dev_index);
    	mmc_register(mmc);
    
    	return 0;
    }
    
    
    below is my booting sequence.

    1) Boot mode set to NOR.
    2) Uboot started from NOR
    3) Uboot run boot.scr which is stored in eMMC
    4) boot.scr started kernel which is stored in eMMC
    5) Kernel mounted RFS from eMMC
    6) boot finished and got prompt.

    below is the details of mmc from kernel which you have asked.

    root@c6a811x-evm:~# cat /sys/kernel/debug/mmc0/ios    

                             
    clock:          50000000 Hz                                                    
    vdd:            21 (3.3 ~ 3.4 V)                                               
    bus mode:       2 (push-pull)                                                  
    chip select:    0 (don't care)                                                 
    power mode:     2 (on)                                                         
    bus width:      2 (4 bits)                                                     
    timing spec:    2 (sd high-speed)                                              
    root@c6a811x-evm:~# cat /sys/kernel/debug/mmc1/ios                             
    clock:          52000000 Hz                                                    
    vdd:            21 (3.3 ~ 3.4 V)                                               
    bus mode:       2 (push-pull)                                                  
    chip select:    0 (don't care)                                                 
    power mode:     2 (on)                                                         
    bus width:      3 (8 bits)                                                     
    timing spec:    1 (mmc high-speed)                                             
    root@c6a811x-evm:~#
  • Nihad,

    Let me update the thread with the performance Q&A:

    We are facing one issue with the performance of eMMC. Below describe the issue. Let me know what is your suggestion for this issue.

    1) Boot from Sd card or eMMC

    We are able to running below two scripts without any performance issue with priority set using nice command

    nice -n -3 aud_route.sh &

    nice -n -3 rtp_player.sh &

    2) In SD boot mode there is no performance issue when we replace nice with chrt. But in eMMC boot mode complete system got slow down. even system is very slow when we try to input some commands from terminal. Do you have any idea, why RFS boot from eMMC show this performance hit when we use chrt?. Is there any performance issue with eMMC driver?. At the same time there is no performance issue when we boot from SD card.

    chrt -f 81 aud_route.sh &

    chrt -f 81 rtp_player.sh &

     

    There could be multiple reasons for system being slow..
    1.       Check if your bootargs remained same in both boot modes. And check uImage and other binaries are same as this could impact  System speed, opp, voltage configuration
     
    2.       Run filesystem check for partition errors, fsck
     
    Can you share the output of “mount”?
     
    3.       Also you may try mounting the FS as sync
    #mount –o async **
     
    4.       To check throughput it’s usually advised to us “dd” and do a raw test to avoid filesystem over heads
    a.       Example write, dd if=/dev/urandom of=/dev/mmcblk0p2 bs=10M count=1
    b.      Example read, dd if=/dev/mmcblk0p2 of=/dev/null bs=10M count=1

     

  • Dear RK/Pavel,

    Answer for your question in lined

    1) Check if your bootargs remained same in both boot modes. And check uImage and other binaries are same as this could impact  System speed, opp, voltage configuration

    Ans: Attached boot.scr used for Sd boot and eMMC boot for your reference could you please check if anything wrong?

    boot_sd.scr.txt
    setenv bootargs 'console=ttyO0,115200n8 rootwait root=/dev/mmcblk0p2 rw mem=256M earlyprintk ip=192.168.1.20:::255.255.255.0::eth0:off noinitrd'
    fatload mmc 0 0x82000000 uImage
    bootm 0x82000000
    

    boot_eMMC.scr.txt
    setenv bootargs 'console=ttyO0,115200n8 rootwait root=/dev/mmcblk0p2 rw mem=256M earlyprintk ip=192.168.1.20:::255.255.255.0::eth0:off noinitrd'
    fatload mmc 1 0x82000000 uImage
    bootm 0x82000000
    
    
    

    2.       Run filesystem check for partition errors, fsck. Can you share the output of “mount”?

    Attached log of fsck for your reference

    fsck.log
    root@c6a811x-evm:~# fsck.ext3 -v -c /dev/mmcblk0p2 
    e2fsck 1.41.14 (22-Dec-2010)
    /dev/mmcblk0p2 is mounted.  
    
    WARNING!!!  The filesystem is mounted.   If you continue you ***WILL***
    cause ***SEVERE*** filesystem damage.
    
    Do you really want to continue (y/n)? yes
    
    /dev/mmcblk0p2: recovering journal
    Checking for bad blocks (read-only test): done                                
    /dev/mmcblk0p2: Updating bad block inode.
    Pass 1: Checking inodes, blocks, and sizes
    Pass 2: Checking directory structure
    Pass 3: Checking directory connectivity
    Pass 4: Checking reference counts
    Pass 5: Checking group summary information
    
    /dev/mmcblk0p2: ***** FILE SYSTEM WAS MODIFIED *****
    
       29989 inodes used (58.46%)
         911 non-contiguous files (3.0%)
           8 non-contiguous directories (0.0%)
             # of inodes with ind/dind/tind blocks: 901/20/0
      191125 blocks used (93.32%)
           0 bad blocks
           1 large file
    
       22795 regular files
        3703 directories
          38 character device files
          40 block device files
           1 fifo
           0 links
        3403 symbolic links (3401 fast symbolic links)
           0 sockets
    --------
       29980 files
    
    root@c6a811x-evm:~# fsck.vfat -v -t /dev/mmcblk0p1
    dosfsck 2.11 (12 Mar 2005)
    -t and -w require -a or -r
    root@c6a811x-evm:~# fsck.vfat -a -v -t /dev/mmcblk0p1
    dosfsck 2.11 (12 Mar 2005)
    dosfsck 2.11, 12 Mar 2005, FAT32, LFN
    Checking we can access the last sector of the filesystem
    Boot sector contents:
    System ID "mkdosfs"
    Media byte 0xf8 (hard disk)
           512 bytes per logical sector
          2048 bytes per cluster
             1 reserved sector
    First FAT starts at byte 512 (sector 1)
             2 FATs, 16 bit entries
         72192 bytes per FAT (= 141 sectors)
    Root directory starts at byte 144896 (sector 283)
           512 root directory entries
    Data area starts at byte 161280 (sector 315)
         36051 data clusters (73832448 bytes)
    16 sectors/track, 4 heads
             0 hidden sectors
        144522 sectors total
    Checking for bad clusters.
    Reclaiming unconnected clusters.
    /dev/mmcblk0p1: 2 files, 1333/36051 clusters
    root@c6a811x-evm:~# fsck.vfat -v -V /dev/mmcblk0p1   
    dosfsck 2.11 (12 Mar 2005)
    dosfsck 2.11, 12 Mar 2005, FAT32, LFN
    Checking we can access the last sector of the filesystem
    Boot sector contents:
    System ID "mkdosfs"
    Media byte 0xf8 (hard disk)
           512 bytes per logical sector
          2048 bytes per cluster
             1 reserved sector
    First FAT starts at byte 512 (sector 1)
             2 FATs, 16 bit entries
         72192 bytes per FAT (= 141 sectors)
    Root directory starts at byte 144896 (sector 283)
           512 root directory entries
    Data area starts at byte 161280 (sector 315)
         36051 data clusters (73832448 bytes)
    16 sectors/track, 4 heads
             0 hidden sectors
        144522 sectors total
    Starting check/repair pass.
    Checking for unused clusters.
    Starting verification pass.
    Checking for unused clusters.
    /dev/mmcblk0p1: 4 files, 1333/36051 clusters
    root@c6a811x-evm:~# 
    
    

    root@c6a811x-evm:~# mount

    rootfs on / type rootfs (rw)

    /dev/root on / type ext3 (rw,relatime,errors=continue,user_xattr,acl,barrier=0,data=writeback)

    devtmpfs on /dev type devtmpfs (rw,relatime,size=29012k,nr_inodes=7253,mode=755)

    proc on /proc type proc (rw,relatime)

    tmpfs on /mnt/.splash type tmpfs (rw,relatime,size=40k)

    sysfs on /sys type sysfs (rw,relatime)

    none on /dev type tmpfs (rw,relatime,size=1024k,nr_inodes=8192,mode=755)

    /dev/mmcblk0p2 on /media/mmcblk0p2 type ext3 (rw,relatime,errors=continue,user_xattr,acl,barrier=0,data=writeback)

    /dev/mmcblk0p1 on /media/mmcblk0p1 type vfat (rw,relatime,fmask=0022,dmask=0022,codepage=cp437,iocharset=iso8859-1,shortname=mixed,errors=remount-ro)

    /dev/mmcblk0p3 on /media/mmcblk0p3 type ext3 (rw,relatime,errors=continue,barrier=0,data=writeback)

    devpts on /dev/pts type devpts (rw,relatime,gid=5,mode=620)

    usbfs on /proc/bus/usb type usbfs (rw,relatime)

    tmpfs on /var/volatile type tmpfs (rw,relatime,size=16384k)

    tmpfs on /dev/shm type tmpfs (rw,relatime,mode=777)

    tmpfs on /media/ram type tmpfs (rw,relatime,size=16384k)

    tmpfs on /mnt/rdisk type tmpfs (rw,relatime,size=2048k,mode=777)

    root@c6a811x-evm:~#

    3.       Also you may try mounting the FS as sync

    #mount –o async **

    Ans: Will it mount with async, if I made bootarg like below,

    setenv bootargs 'console=ttyO0,115200n8 rootwait rootflags=async rootfstype=ext3 root=/dev/mmcblk0p2 rw mem=256M earlyprintk ip=192.168.1.20:::255.255.255.0::eth0:off noinitrd'

    4.       To check throughput it’s usually advised to us “dd” and do a raw test to avoid filesystem over heads

    a.       Example write, dd if=/dev/urandom of=/dev/mmcblk0p2 bs=10M count=1

    b.      Example read, dd if=/dev/mmcblk0p2 of=/dev/null bs=10M count=1

    Ans: I didn't understand this?.

    I got below when i run dd read

    root@c6a811x-evm:~# dd if=/dev/mmcblk0p2 of=/dev/null bs=10M count=1

    1+0 records in

    1+0 records out

    root@c6a811x-evm:~#

  • Abdul,

    Let me update the e2e thread with the latest status.

    The memory issue has been fixed by increasing mem=256M in boot.scr

    3.       Also you may try mounting the FS as sync

    #mount –o async **

    Will it mount with async, if I made bootarg like below,

    setenv bootargs 'console=ttyO0,115200n8 rootwait rootflags=async rootfstype=ext3 root=/dev/mmcblk0p2 rw mem=256M earlyprintk ip=192.168.1.20:::255.255.255.0::eth0:off noinitrd'

    [RK] Ideally it should, just check if this is printed in the log displayed by “mount” if it’s not you can do a “mount –o remount,rw,async”

    4.       To check throughput it’s usually advised to us “dd” and do a raw test to avoid filesystem over heads
    a.       Example write, dd if=/dev/urandom of=/dev/mmcblk0p2 bs=10M count=1
    b.
          Example read, dd if=/dev/mmcblk0p2 of=/dev/null bs=10M count=1
    [RK] run , the read /write command with time option will give you a rough time estimate
    time “dd if=/dev/urandom of=/dev/mmcblk0p2 bs=10M count=1”
    time “dd if=/dev/mmcblk0p2 of=/dev/null bs=10M count=1”
    Using ext4 will give you a better performance too.

     

  • hi:
    I use dm8148 mmc0 emmc, I can't identify to the kernel, I use emmc version 5.0,size 8GB, without any print in the process of start
    static struct omap2_hsmmc_info mmc[] = {
    {
    //.name ="eMMC"
    .mmc = 1,
    .caps = MMC_CAP_4_BIT_DATA ,//| MMC_CAP_POWER_OFF_CARD,
    .gpio_cd = -EINVAL, /* Dedicated pins for CD and WP */
    .gpio_wp = -EINVAL,
    .ocr_mask = MMC_VDD_165_195 | MMC_VDD_32_33 | MMC_VDD_33_34,
    .nonremovable = true,
    },
    {
    .mmc = 2,
    .caps = MMC_CAP_4_BIT_DATA,
    .gpio_cd = -EINVAL, /* Dedicated pins for CD and WP */
    .gpio_wp = -EINVAL,
    .ocr_mask = MMC_VDD_33_34,
    },
    Could you tell me how do you add? thank you
    I use in the uboot mmcinfo 1, the information below
    TI8148_EVM#mmcinfo 0
    mmc_read_data: timedout waiting for status!
    mmc_send_cmd: timedout waiting for cmddis!
    Device: OMAP SD/MMC
    Manufacturer ID: 13
    OEM: 14e
    Name: Q2J55
    Tran Speed: 25000000
    Rd Block Len: 512
    MMC version 4.0
    High Capacity: Yes
    Capacity: 2199023255552
    Bus Width: 4-bit
  • Hi user4190929,

    Please open new e2e thread regarding your issue.

    Regards,
    Pavel