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.

AM4376: Customer PCB using AM4376 + 512MB DDR3 , without EEPROM mounted, we need a MLO customized.

Part Number: AM4376

Hi Champs:

Customer is using AM4376 + DDR3 512MB and they have no EEPROM, based on TI SK EVM design.

DDR3 is :MT41K128M16JT-125:K TR

May you give us a patch to have those 3 features?

A. Early print for MLO.

B. DDR3 512M

C. Skip EEPROM check.

THanks.

BR Rio

  • Hi Rio,

    Rio Chan said:
    A. Early print for MLO.

    Please refer to the early e2e thread on the same topic. My understanding is you were able to get this working on you setup?

    https://e2e.ti.com/support/processors/f/791/p/929728/3441869#3441869
    Rio Chan said:

    B. DDR3 512M

    C. Skip EEPROM check.

    Since the customer design is based on TI DK EVM, one recommendation is to make the following code change to skip EEPROM read, but “make” the customer board as “TI SK board”

    This will lead rest of board-dependent setup for DPLL, DDR etc… be based upon the predefined SK configurations.

    Hopefully it would bring up your board “live”. In case, there’re still discrepancy between “the customer board” vs “TI SK board”, you’ll be able to fine-tune them accordingly.

    in u-boot/board/ti/am43xx/board.h
    static inline int board_is_sk(void)
    {
            return 1;
    //	return board_ti_is("AM43__SK");
    }
    

    Best,

    -Hong

  • Hi Rio,

    Is the exact same DDR memory used in the customer’s previous board?

    a)       If yes, start with the working DDR parameters, and check if any discrepancy.

    b)       If not, EMIF tool can be used to generate the consolidated lists of DDR parameters such as EMIF Registers, DDR PHY registers, IO Control Registers.

    www.ti.com/.../sprac70a.pdf

    The AM43xx DDR parameters are defined and called all in <board/ti/am43xx/board.c>, where config_ddr() for SK board (closest one to customer board) is listed below, where &ioregs_ddr3, &ddr3_sk_emif_regs_400Mhz are all defined in the am43xx board file.

    void sdram_init(void)
    {
                  …
                  } else if (board_is_sk()) {
                                 config_ddr(400, &ioregs_ddr3, NULL, NULL,
                                                  &ddr3_sk_emif_regs_400Mhz, 0);
                  …
    }
    

    Best,

    -Hong

  • Hi Hong:

    #1. Thanks. I upload the c file and the DSS file I output here, please reveiw.

    2020_9_1_Rio_am33xx_ddr.c
    // SPDX-License-Identifier: GPL-2.0+
    /*
     * DDR Configuration for AM33xx devices.
     *
     * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
     */
    
    #include <asm/arch/cpu.h>
    #include <asm/arch/ddr_defs.h>
    #include <asm/arch/sys_proto.h>
    #include <asm/io.h>
    #include <asm/emif.h>
    
    /**
     * Base address for EMIF instances
     */
    static struct emif_reg_struct *emif_reg[2] = {
    				(struct emif_reg_struct *)EMIF4_0_CFG_BASE,
    				(struct emif_reg_struct *)EMIF4_1_CFG_BASE};
    
    /**
     * Base addresses for DDR PHY cmd/data regs
     */
    static struct ddr_cmd_regs *ddr_cmd_reg[2] = {
    				(struct ddr_cmd_regs *)DDR_PHY_CMD_ADDR,
    				(struct ddr_cmd_regs *)DDR_PHY_CMD_ADDR2};
    
    static struct ddr_data_regs *ddr_data_reg[2] = {
    				(struct ddr_data_regs *)DDR_PHY_DATA_ADDR,
    				(struct ddr_data_regs *)DDR_PHY_DATA_ADDR2};
    
    /**
     * Base address for ddr io control instances
     */
    static struct ddr_cmdtctrl *ioctrl_reg = {
    			(struct ddr_cmdtctrl *)DDR_CONTROL_BASE_ADDR};
    
    static inline u32 get_mr(int nr, u32 cs, u32 mr_addr)
    {
    	u32 mr;
    
    	mr_addr |= cs << EMIF_REG_CS_SHIFT;
    	writel(mr_addr, &emif_reg[nr]->emif_lpddr2_mode_reg_cfg);
    
    	mr = readl(&emif_reg[nr]->emif_lpddr2_mode_reg_data);
    	debug("get_mr: EMIF1 cs %d mr %08x val 0x%x\n", cs, mr_addr, mr);
    	if (((mr & 0x0000ff00) >>  8) == (mr & 0xff) &&
    	    ((mr & 0x00ff0000) >> 16) == (mr & 0xff) &&
    	    ((mr & 0xff000000) >> 24) == (mr & 0xff))
    		return mr & 0xff;
    	else
    		return mr;
    }
    
    static inline void set_mr(int nr, u32 cs, u32 mr_addr, u32 mr_val)
    {
    	mr_addr |= cs << EMIF_REG_CS_SHIFT;
    	writel(mr_addr, &emif_reg[nr]->emif_lpddr2_mode_reg_cfg);
    	writel(mr_val, &emif_reg[nr]->emif_lpddr2_mode_reg_data);
    }
    
    static void configure_mr(int nr, u32 cs)
    {
    	u32 mr_addr;
    
    	while (get_mr(nr, cs, LPDDR2_MR0) & LPDDR2_MR0_DAI_MASK)
    		;
    	set_mr(nr, cs, LPDDR2_MR10, 0x56);
    
    	set_mr(nr, cs, LPDDR2_MR1, 0x43);
    	set_mr(nr, cs, LPDDR2_MR2, 0x2);
    
    	mr_addr = LPDDR2_MR2 | EMIF_REG_REFRESH_EN_MASK;
    	set_mr(nr, cs, mr_addr, 0x2);
    }
    
    /*
     * Configure EMIF4D5 registers and MR registers For details about these magic
     * values please see the EMIF registers section of the TRM.
     */
    void config_sdram_emif4d5(const struct emif_regs *regs, int nr)
    {
    
    #if 1//Rio: From Brad Patch, for Simplo DDR
    #ifdef CONFIG_AM43XX
    	struct prm_device_inst *prm_device =
    			(struct prm_device_inst *)PRM_DEVICE_INST;
    #endif
    #endif
    
    	writel(0xA0, &emif_reg[nr]->emif_pwr_mgmt_ctrl);
    	writel(0xA0, &emif_reg[nr]->emif_pwr_mgmt_ctrl_shdw);
    	writel(regs->zq_config, &emif_reg[nr]->emif_zq_config);
    
    	writel(regs->temp_alert_config, &emif_reg[nr]->emif_temp_alert_config);
    	writel(regs->emif_rd_wr_lvl_rmp_win,
    	       &emif_reg[nr]->emif_rd_wr_lvl_rmp_win);
    	writel(regs->emif_rd_wr_lvl_rmp_ctl,
    	       &emif_reg[nr]->emif_rd_wr_lvl_rmp_ctl);
    	writel(regs->emif_rd_wr_lvl_ctl, &emif_reg[nr]->emif_rd_wr_lvl_ctl);
    	writel(regs->emif_rd_wr_exec_thresh,
    	       &emif_reg[nr]->emif_rd_wr_exec_thresh);
    
    	/*
    	 * for most SOCs these registers won't need to be changed so only
    	 * write to these registers if someone explicitly has set the
    	 * register's value.
    	 */
    	if(regs->emif_cos_config) {
    		writel(regs->emif_prio_class_serv_map, &emif_reg[nr]->emif_prio_class_serv_map);
    		writel(regs->emif_connect_id_serv_1_map, &emif_reg[nr]->emif_connect_id_serv_1_map);
    		writel(regs->emif_connect_id_serv_2_map, &emif_reg[nr]->emif_connect_id_serv_2_map);
    		writel(regs->emif_cos_config, &emif_reg[nr]->emif_cos_config);
    	}
    
    	/*
    	 * Sequence to ensure that the PHY is in a known state prior to
    	 * startting hardware leveling.  Also acts as to latch some state from
    	 * the EMIF into the PHY.
    	 */
    	writel(0x2011, &emif_reg[nr]->emif_iodft_tlgc);
    	writel(0x2411, &emif_reg[nr]->emif_iodft_tlgc);
    	writel(0x2011, &emif_reg[nr]->emif_iodft_tlgc);
    
    	clrbits_le32(&emif_reg[nr]->emif_sdram_ref_ctrl,
    			EMIF_REG_INITREF_DIS_MASK);
    
    	writel(regs->sdram_config, &emif_reg[nr]->emif_sdram_config);
    	writel(regs->sdram_config, &cstat->secure_emif_sdram_config);
    
    	/* Wait 1ms because of L3 timeout error */
    	udelay(1000);
    
    	writel(regs->ref_ctrl, &emif_reg[nr]->emif_sdram_ref_ctrl);
    	writel(regs->ref_ctrl, &emif_reg[nr]->emif_sdram_ref_ctrl_shdw);
    
    #if 1//Rio: From Brad Patch, for Simplo DDR
    #ifdef CONFIG_AM43XX
    	/*
    	 * Disable EMIF_DEVOFF
    	 * -> Cold Boot: This is just rewriting the default register value.
    	 * -> RTC Resume: Must disable DEVOFF before leveling.
    	 */
    	writel(0, &prm_device->emif_ctrl);
    #endif
    
    #endif
    	/* Perform hardware leveling for DDR3 */
    	if (emif_sdram_type(regs->sdram_config) == EMIF_SDRAM_TYPE_DDR3) {
    		writel(readl(&emif_reg[nr]->emif_ddr_ext_phy_ctrl_36) |
    		       0x100, &emif_reg[nr]->emif_ddr_ext_phy_ctrl_36);
    		writel(readl(&emif_reg[nr]->emif_ddr_ext_phy_ctrl_36_shdw) |
    		       0x100, &emif_reg[nr]->emif_ddr_ext_phy_ctrl_36_shdw);
    
    		writel(0x80000000, &emif_reg[nr]->emif_rd_wr_lvl_rmp_ctl);
    
    		/* Enable read leveling */
    		writel(0x80000000, &emif_reg[nr]->emif_rd_wr_lvl_ctl);
    
    #if 1//Rio: From Brad Patch, for Simplo DDR
    		/* Wait 1ms because of L3 timeout error */
    		udelay(1000);
    #endif
    
    		/*
    		 * Enable full read and write leveling.  Wait for read and write
    		 * leveling bit to clear RDWRLVLFULL_START bit 31
    		 */
    		while ((readl(&emif_reg[nr]->emif_rd_wr_lvl_ctl) & 0x80000000)
    		      != 0)
    			;
    
    		/* Check the timeout register to see if leveling is complete */
    		if ((readl(&emif_reg[nr]->emif_status) & 0x70) != 0)
    			puts("DDR3 H/W leveling incomplete with errors\n");
    
    	} else {
    		/* DDR2 */
    		configure_mr(nr, 0);
    		configure_mr(nr, 1);
    	}
    }
    
    /**
     * Configure SDRAM
     */
    void config_sdram(const struct emif_regs *regs, int nr)
    {
    #ifdef CONFIG_TI816X
    	writel(regs->sdram_config, &emif_reg[nr]->emif_sdram_config);
    	writel(regs->emif_ddr_phy_ctlr_1, &emif_reg[nr]->emif_ddr_phy_ctrl_1);
    	writel(regs->emif_ddr_phy_ctlr_1, &emif_reg[nr]->emif_ddr_phy_ctrl_1_shdw);
    	writel(0x0000613B, &emif_reg[nr]->emif_sdram_ref_ctrl);   /* initially a large refresh period */
    	writel(0x1000613B, &emif_reg[nr]->emif_sdram_ref_ctrl);   /* trigger initialization           */
    	writel(regs->ref_ctrl, &emif_reg[nr]->emif_sdram_ref_ctrl);
    #else
    	if (regs->zq_config) {
    		writel(regs->zq_config, &emif_reg[nr]->emif_zq_config);
    		writel(regs->sdram_config, &cstat->secure_emif_sdram_config);
    		writel(regs->sdram_config, &emif_reg[nr]->emif_sdram_config);
    
    		/* Trigger initialization */
    		writel(0x00003100, &emif_reg[nr]->emif_sdram_ref_ctrl);
    		/* Wait 1ms because of L3 timeout error */
    		udelay(1000);
    
    		/* Write proper sdram_ref_cref_ctrl value */
    		writel(regs->ref_ctrl, &emif_reg[nr]->emif_sdram_ref_ctrl);
    		writel(regs->ref_ctrl, &emif_reg[nr]->emif_sdram_ref_ctrl_shdw);
    	}
    	writel(regs->ref_ctrl, &emif_reg[nr]->emif_sdram_ref_ctrl);
    	writel(regs->ref_ctrl, &emif_reg[nr]->emif_sdram_ref_ctrl_shdw);
    	writel(regs->sdram_config, &emif_reg[nr]->emif_sdram_config);
    
    	/* Write REG_COS_COUNT_1, REG_COS_COUNT_2, and REG_PR_OLD_COUNT. */
    	if (regs->ocp_config)
    		writel(regs->ocp_config, &emif_reg[nr]->emif_l3_config);
    #endif
    }
    
    /**
     * Set SDRAM timings
     */
    void set_sdram_timings(const struct emif_regs *regs, int nr)
    {
    	writel(regs->sdram_tim1, &emif_reg[nr]->emif_sdram_tim_1);
    	writel(regs->sdram_tim1, &emif_reg[nr]->emif_sdram_tim_1_shdw);
    	writel(regs->sdram_tim2, &emif_reg[nr]->emif_sdram_tim_2);
    	writel(regs->sdram_tim2, &emif_reg[nr]->emif_sdram_tim_2_shdw);
    	writel(regs->sdram_tim3, &emif_reg[nr]->emif_sdram_tim_3);
    	writel(regs->sdram_tim3, &emif_reg[nr]->emif_sdram_tim_3_shdw);
    }
    
    /*
     * Configure EXT PHY registers for software leveling
     */
    static void ext_phy_settings_swlvl(const struct emif_regs *regs, int nr)
    {
    	u32 *ext_phy_ctrl_base = 0;
    	u32 *emif_ext_phy_ctrl_base = 0;
    	__maybe_unused const u32 *ext_phy_ctrl_const_regs;
    	u32 i = 0;
    	__maybe_unused u32 size;
    
    	ext_phy_ctrl_base = (u32 *)&(regs->emif_ddr_ext_phy_ctrl_1);
    	emif_ext_phy_ctrl_base =
    			(u32 *)&(emif_reg[nr]->emif_ddr_ext_phy_ctrl_1);
    
    	/* Configure external phy control timing registers */
    	for (i = 0; i < EMIF_EXT_PHY_CTRL_TIMING_REG; i++) {
    		writel(*ext_phy_ctrl_base, emif_ext_phy_ctrl_base++);
    		/* Update shadow registers */
    		writel(*ext_phy_ctrl_base++, emif_ext_phy_ctrl_base++);
    	}
    
    #ifdef CONFIG_AM43XX
    	/*
    	 * External phy 6-24 registers do not change with ddr frequency.
    	 * These only need to be set on DDR2 on AM43xx.
    	 */
    	emif_get_ext_phy_ctrl_const_regs(&ext_phy_ctrl_const_regs, &size);
    
    	if (!size)
    		return;
    
    	for (i = 0; i < size; i++) {
    		writel(ext_phy_ctrl_const_regs[i], emif_ext_phy_ctrl_base++);
    		/* Update shadow registers */
    		writel(ext_phy_ctrl_const_regs[i], emif_ext_phy_ctrl_base++);
    	}
    #endif
    }
    
    /*
     * Configure EXT PHY registers for hardware leveling
     */
    static void ext_phy_settings_hwlvl(const struct emif_regs *regs, int nr)
    {
    	/*
    	 * Enable hardware leveling on the EMIF.  For details about these
    	 * magic values please see the EMIF registers section of the TRM.
    	 */
    
    #if 0//Rio: From Brad Patch, for Simplo DDR
    
    	writel(0x08020080, &emif_reg[nr]->emif_ddr_ext_phy_ctrl_1);
    	writel(0x08020080, &emif_reg[nr]->emif_ddr_ext_phy_ctrl_1_shdw);
    #else
    	if (regs->emif_ddr_phy_ctlr_1 & 0x00040000) {
    		/* PHY_INVERT_CLKOUT = 1 */
    		writel(0x00040100, &emif_reg[nr]->emif_ddr_ext_phy_ctrl_1);
    		writel(0x00040100, &emif_reg[nr]->emif_ddr_ext_phy_ctrl_1_shdw);
    	} else {
    		/* PHY_INVERT_CLKOUT = 0 */
    		writel(0x08020080, &emif_reg[nr]->emif_ddr_ext_phy_ctrl_1);
    		writel(0x08020080, &emif_reg[nr]->emif_ddr_ext_phy_ctrl_1_shdw);
    	}
    
    #endif
    
    	writel(0x00000000, &emif_reg[nr]->emif_ddr_ext_phy_ctrl_22);
    	writel(0x00000000, &emif_reg[nr]->emif_ddr_ext_phy_ctrl_22_shdw);
    	writel(0x00600020, &emif_reg[nr]->emif_ddr_ext_phy_ctrl_23);
    	writel(0x00600020, &emif_reg[nr]->emif_ddr_ext_phy_ctrl_23_shdw);
    	writel(0x40010080, &emif_reg[nr]->emif_ddr_ext_phy_ctrl_24);
    	writel(0x40010080, &emif_reg[nr]->emif_ddr_ext_phy_ctrl_24_shdw);
    	writel(0x08102040, &emif_reg[nr]->emif_ddr_ext_phy_ctrl_25);
    	writel(0x08102040, &emif_reg[nr]->emif_ddr_ext_phy_ctrl_25_shdw);
    	writel(0x00200020, &emif_reg[nr]->emif_ddr_ext_phy_ctrl_26);
    	writel(0x00200020, &emif_reg[nr]->emif_ddr_ext_phy_ctrl_26_shdw);
    	writel(0x00200020, &emif_reg[nr]->emif_ddr_ext_phy_ctrl_27);
    	writel(0x00200020, &emif_reg[nr]->emif_ddr_ext_phy_ctrl_27_shdw);
    	writel(0x00200020, &emif_reg[nr]->emif_ddr_ext_phy_ctrl_28);
    	writel(0x00200020, &emif_reg[nr]->emif_ddr_ext_phy_ctrl_28_shdw);
    	writel(0x00200020, &emif_reg[nr]->emif_ddr_ext_phy_ctrl_29);
    	writel(0x00200020, &emif_reg[nr]->emif_ddr_ext_phy_ctrl_29_shdw);
    	writel(0x00200020, &emif_reg[nr]->emif_ddr_ext_phy_ctrl_30);
    	writel(0x00200020, &emif_reg[nr]->emif_ddr_ext_phy_ctrl_30_shdw);
    	writel(0x00000000, &emif_reg[nr]->emif_ddr_ext_phy_ctrl_31);
    	writel(0x00000000, &emif_reg[nr]->emif_ddr_ext_phy_ctrl_31_shdw);
    	writel(0x00000000, &emif_reg[nr]->emif_ddr_ext_phy_ctrl_32);
    	writel(0x00000000, &emif_reg[nr]->emif_ddr_ext_phy_ctrl_32_shdw);
    	writel(0x00000000, &emif_reg[nr]->emif_ddr_ext_phy_ctrl_33);
    	writel(0x00000000, &emif_reg[nr]->emif_ddr_ext_phy_ctrl_33_shdw);
    	writel(0x00000000, &emif_reg[nr]->emif_ddr_ext_phy_ctrl_34);
    	writel(0x00000000, &emif_reg[nr]->emif_ddr_ext_phy_ctrl_34_shdw);
    	writel(0x00000000, &emif_reg[nr]->emif_ddr_ext_phy_ctrl_35);
    	writel(0x00000000, &emif_reg[nr]->emif_ddr_ext_phy_ctrl_35_shdw);
    
    #if 0//Rio: From Brad Patch, for Simplo DDR
    	writel(0x000000FF, &emif_reg[nr]->emif_ddr_ext_phy_ctrl_36);
    	writel(0x000000FF, &emif_reg[nr]->emif_ddr_ext_phy_ctrl_36_shdw);
    #else
    	writel(0x00000077, &emif_reg[nr]->emif_ddr_ext_phy_ctrl_36);
    	writel(0x00000077, &emif_reg[nr]->emif_ddr_ext_phy_ctrl_36_shdw);
    #endif
    
    	/*
    	 * Sequence to ensure that the PHY is again in a known state after
    	 * hardware leveling.
    	 */
    	writel(0x2011, &emif_reg[nr]->emif_iodft_tlgc);
    	writel(0x2411, &emif_reg[nr]->emif_iodft_tlgc);
    	writel(0x2011, &emif_reg[nr]->emif_iodft_tlgc);
    }
    
    /**
     * Configure DDR PHY
     */
    void config_ddr_phy(const struct emif_regs *regs, int nr)
    {
    	/*
    	 * Disable initialization and refreshes for now until we finish
    	 * programming EMIF regs and set time between rising edge of
    	 * DDR_RESET to rising edge of DDR_CKE to > 500us per memory spec.
    	 * We currently hardcode a value based on a max expected frequency
    	 * of 400MHz.
    	 */
    	writel(EMIF_REG_INITREF_DIS_MASK | 0x3100,
    		&emif_reg[nr]->emif_sdram_ref_ctrl);
    
    	writel(regs->emif_ddr_phy_ctlr_1,
    		&emif_reg[nr]->emif_ddr_phy_ctrl_1);
    	writel(regs->emif_ddr_phy_ctlr_1,
    		&emif_reg[nr]->emif_ddr_phy_ctrl_1_shdw);
    
    	if (get_emif_rev((u32)emif_reg[nr]) == EMIF_4D5) {
    		if (emif_sdram_type(regs->sdram_config) == EMIF_SDRAM_TYPE_DDR3)
    			ext_phy_settings_hwlvl(regs, nr);
    		else
    			ext_phy_settings_swlvl(regs, nr);
    	}
    }
    
    /**
     * Configure DDR CMD control registers
     */
    void config_cmd_ctrl(const struct cmd_control *cmd, int nr)
    {
    	if (!cmd)
    		return;
    
    	writel(cmd->cmd0csratio, &ddr_cmd_reg[nr]->cm0csratio);
    	writel(cmd->cmd0iclkout, &ddr_cmd_reg[nr]->cm0iclkout);
    
    	writel(cmd->cmd1csratio, &ddr_cmd_reg[nr]->cm1csratio);
    	writel(cmd->cmd1iclkout, &ddr_cmd_reg[nr]->cm1iclkout);
    
    	writel(cmd->cmd2csratio, &ddr_cmd_reg[nr]->cm2csratio);
    	writel(cmd->cmd2iclkout, &ddr_cmd_reg[nr]->cm2iclkout);
    }
    
    /**
     * Configure DDR DATA registers
     */
    void config_ddr_data(const struct ddr_data *data, int nr)
    {
    	int i;
    
    	if (!data)
    		return;
    
    	for (i = 0; i < DDR_DATA_REGS_NR; i++) {
    		writel(data->datardsratio0,
    			&(ddr_data_reg[nr]+i)->dt0rdsratio0);
    		writel(data->datawdsratio0,
    			&(ddr_data_reg[nr]+i)->dt0wdsratio0);
    		writel(data->datawiratio0,
    			&(ddr_data_reg[nr]+i)->dt0wiratio0);
    		writel(data->datagiratio0,
    			&(ddr_data_reg[nr]+i)->dt0giratio0);
    		writel(data->datafwsratio0,
    			&(ddr_data_reg[nr]+i)->dt0fwsratio0);
    		writel(data->datawrsratio0,
    			&(ddr_data_reg[nr]+i)->dt0wrsratio0);
    	}
    }
    
    void config_io_ctrl(const struct ctrl_ioregs *ioregs)
    {
    	if (!ioregs)
    		return;
    
    	writel(ioregs->cm0ioctl, &ioctrl_reg->cm0ioctl);
    	writel(ioregs->cm1ioctl, &ioctrl_reg->cm1ioctl);
    	writel(ioregs->cm2ioctl, &ioctrl_reg->cm2ioctl);
    	writel(ioregs->dt0ioctl, &ioctrl_reg->dt0ioctl);
    	writel(ioregs->dt1ioctl, &ioctrl_reg->dt1ioctl);
    #ifdef CONFIG_AM43XX
    	writel(ioregs->dt2ioctrl, &ioctrl_reg->dt2ioctrl);
    	writel(ioregs->dt3ioctrl, &ioctrl_reg->dt3ioctrl);
    	writel(ioregs->emif_sdram_config_ext,
    	       &ioctrl_reg->emif_sdram_config_ext);
    #endif
    }
    2020_9_1_Rio_am43xx_board.c
    // SPDX-License-Identifier: GPL-2.0+
    /*
     * board.c
     *
     * Board functions for TI AM43XX based boards
     *
     * Copyright (C) 2013, Texas Instruments, Incorporated - http://www.ti.com/
     */
    
    #include <common.h>
    #include <environment.h>
    #include <i2c.h>
    #include <linux/errno.h>
    #include <spl.h>
    #include <usb.h>
    #include <asm/omap_sec_common.h>
    #include <asm/arch/clock.h>
    #include <asm/arch/sys_proto.h>
    #include <asm/arch/mux.h>
    #include <asm/arch/ddr_defs.h>
    #include <asm/arch/gpio.h>
    #include <asm/emif.h>
    #include <asm/omap_common.h>
    #include "../common/board_detect.h"
    #include "board.h"
    #include "fake_EEPROM.h"
    #include <power/pmic.h>
    #include <power/tps65218.h>
    #include <power/tps62362.h>
    #include <miiphy.h>
    #include <cpsw.h>
    #include <linux/usb/gadget.h>
    #include <dwc3-uboot.h>
    #include <dwc3-omap-uboot.h>
    #include <ti-usb-phy-uboot.h>
    
    //Rio: referencing LNC patch and here: https://lists.denx.de/pipermail/u-boot/2013-November/166174.html / https://lists.denx.de/pipermail/u-boot/2014-June/182762.html
    
    #if 0
    // Rio: below is in omap.h
    #define SRAM_SCRATCH_SPACE_ADDR	0x40337C00
    #define AM4372_BOARD_NAME_START	SRAM_SCRATCH_SPACE_ADDR
    #define AM4372_BOARD_NAME_END	SRAM_SCRATCH_SPACE_ADDR + 0xC
    #define AM4372_BOARD_VERSION_START	SRAM_SCRATCH_SPACE_ADDR + 0xD
    #define AM4372_BOARD_VERSION_END	SRAM_SCRATCH_SPACE_ADDR + 0x14
    
    // Rio: below is in board.h
    static char *const am43xx_board_name = (char *)AM4372_BOARD_NAME_START;
    static char *const am43xx_board_rev = (char *)AM4372_BOARD_VERSION_START;
    
    #define HDR_NO_OF_MAC_ADDR	3
    #define HDR_ETH_ALEN		6
    #define HDR_NAME_LEN		8
    
    struct am43xx_board_id {
    	unsigned int  magic;
    	char name[HDR_NAME_LEN];
    	char version[4];
    	char serial[12];
    	char config[32];
    	char mac_addr[HDR_NO_OF_MAC_ADDR][HDR_ETH_ALEN];
    };
    #endif
    
    DECLARE_GLOBAL_DATA_PTR;
    
    static struct ctrl_dev *cdev = (struct ctrl_dev *)CTRL_DEVICE_BASE;
    
    /* 
     * Read header information from EEPROM into global structure.
     */
    #ifdef CONFIG_TI_I2C_BOARD_DETECT
    void do_board_detect(void)
    {
    	/* Ensure I2C is initialized for EEPROM access*/
    	gpi2c_init();
    	if (ti_i2c_eeprom_am_get(CONFIG_EEPROM_BUS_ADDRESS,
    				 CONFIG_EEPROM_CHIP_ADDRESS))
    		printf("\n Rio_Debug: ti_i2c_eeprom_init failed !! \n");
    }
    #endif
    
    #ifndef CONFIG_SKIP_LOWLEVEL_INIT
    
    const struct dpll_params dpll_mpu[NUM_CRYSTAL_FREQ][NUM_OPPS] = {
    	{	/* 19.2 MHz */
    		{125, 3, 2, -1, -1, -1, -1},	/* OPP 50 */
    		{-1, -1, -1, -1, -1, -1, -1},	/* OPP RESERVED	*/
    		{125, 3, 1, -1, -1, -1, -1},	/* OPP 100 */
    		{150, 3, 1, -1, -1, -1, -1},	/* OPP 120 */
    		{125, 2, 1, -1, -1, -1, -1},	/* OPP TB */
    		{625, 11, 1, -1, -1, -1, -1}	/* OPP NT */
    	},
    	{	/* 24 MHz */
    		{300, 23, 1, -1, -1, -1, -1},	/* OPP 50 */
    		{-1, -1, -1, -1, -1, -1, -1},	/* OPP RESERVED	*/
    		{600, 23, 1, -1, -1, -1, -1},	/* OPP 100 */
    		{720, 23, 1, -1, -1, -1, -1},	/* OPP 120 */
    		{800, 23, 1, -1, -1, -1, -1},	/* OPP TB */
    		{1000, 23, 1, -1, -1, -1, -1}	/* OPP NT */
    	},
    	{	/* 25 MHz */
    		{300, 24, 1, -1, -1, -1, -1},	/* OPP 50 */
    		{-1, -1, -1, -1, -1, -1, -1},	/* OPP RESERVED	*/
    		{600, 24, 1, -1, -1, -1, -1},	/* OPP 100 */
    		{720, 24, 1, -1, -1, -1, -1},	/* OPP 120 */
    		{800, 24, 1, -1, -1, -1, -1},	/* OPP TB */
    		{1000, 24, 1, -1, -1, -1, -1}	/* OPP NT */
    	},
    	{	/* 26 MHz */
    		{300, 25, 1, -1, -1, -1, -1},	/* OPP 50 */
    		{-1, -1, -1, -1, -1, -1, -1},	/* OPP RESERVED	*/
    		{600, 25, 1, -1, -1, -1, -1},	/* OPP 100 */
    		{720, 25, 1, -1, -1, -1, -1},	/* OPP 120 */
    		{800, 25, 1, -1, -1, -1, -1},	/* OPP TB */
    		{1000, 25, 1, -1, -1, -1, -1}	/* OPP NT */
    	},
    };
    
    const struct dpll_params dpll_core[NUM_CRYSTAL_FREQ] = {
    		{625, 11, -1, -1, 10, 8, 4},	/* 19.2 MHz */
    		{1000, 23, -1, -1, 10, 8, 4},	/* 24 MHz */
    		{1000, 24, -1, -1, 10, 8, 4},	/* 25 MHz */
    		{1000, 25, -1, -1, 10, 8, 4}	/* 26 MHz */
    };
    
    const struct dpll_params dpll_per[NUM_CRYSTAL_FREQ] = {
    		{400, 7, 5, -1, -1, -1, -1},	/* 19.2 MHz */
    		{400, 9, 5, -1, -1, -1, -1},	/* 24 MHz */
    		{384, 9, 5, -1, -1, -1, -1},	/* 25 MHz */
    		{480, 12, 5, -1, -1, -1, -1}	/* 26 MHz */
    };
    
    const struct dpll_params epos_evm_dpll_ddr[NUM_CRYSTAL_FREQ] = {
    		{665, 47, 1, -1, 4, -1, -1}, /*19.2*/
    		{133, 11, 1, -1, 4, -1, -1}, /* 24 MHz */
    		{266, 24, 1, -1, 4, -1, -1}, /* 25 MHz */
    		{133, 12, 1, -1, 4, -1, -1}  /* 26 MHz */
    };
    
    const struct dpll_params gp_evm_dpll_ddr = {
    		50, 2, 1, -1, 2, -1, -1};
    
    static const struct dpll_params idk_dpll_ddr = {
    	400, 23, 1, -1, 2, -1, -1
    };
    
    static const u32 ext_phy_ctrl_const_base_lpddr2[] = {
    	0x00500050,
    	0x00350035,
    	0x00350035,
    	0x00350035,
    	0x00350035,
    	0x00350035,
    	0x00000000,
    	0x00000000,
    	0x00000000,
    	0x00000000,
    	0x00000000,
    	0x00000000,
    	0x00000000,
    	0x00000000,
    	0x00000000,
    	0x00000000,
    	0x00000000,
    	0x00000000,
    	0x40001000,
    	0x08102040
    };
    
    const struct ctrl_ioregs ioregs_lpddr2 = {
    	.cm0ioctl		= LPDDR2_ADDRCTRL_IOCTRL_VALUE,
    	.cm1ioctl		= LPDDR2_ADDRCTRL_WD0_IOCTRL_VALUE,
    	.cm2ioctl		= LPDDR2_ADDRCTRL_WD1_IOCTRL_VALUE,
    	.dt0ioctl		= LPDDR2_DATA0_IOCTRL_VALUE,
    	.dt1ioctl		= LPDDR2_DATA0_IOCTRL_VALUE,
    	.dt2ioctrl		= LPDDR2_DATA0_IOCTRL_VALUE,
    	.dt3ioctrl		= LPDDR2_DATA0_IOCTRL_VALUE,
    	.emif_sdram_config_ext	= 0x1,
    };
    
    const struct emif_regs emif_regs_lpddr2 = {
    	.sdram_config			= 0x808012BA,
    	.ref_ctrl			= 0x0000040D,
    	.sdram_tim1			= 0xEA86B411,
    	.sdram_tim2			= 0x103A094A,
    	.sdram_tim3			= 0x0F6BA37F,
    	.read_idle_ctrl			= 0x00050000,
    	.zq_config			= 0x50074BE4,
    	.temp_alert_config		= 0x0,
    	.emif_rd_wr_lvl_rmp_win		= 0x0,
    	.emif_rd_wr_lvl_rmp_ctl		= 0x0,
    	.emif_rd_wr_lvl_ctl		= 0x0,
    	.emif_ddr_phy_ctlr_1		= 0x0E284006,
    	.emif_rd_wr_exec_thresh		= 0x80000405,
    	.emif_ddr_ext_phy_ctrl_1	= 0x04010040,
    	.emif_ddr_ext_phy_ctrl_2	= 0x00500050,
    	.emif_ddr_ext_phy_ctrl_3	= 0x00500050,
    	.emif_ddr_ext_phy_ctrl_4	= 0x00500050,
    	.emif_ddr_ext_phy_ctrl_5	= 0x00500050,
    	.emif_prio_class_serv_map	= 0x80000001,
    	.emif_connect_id_serv_1_map	= 0x80000094,
    	.emif_connect_id_serv_2_map	= 0x00000000,
    	.emif_cos_config			= 0x000FFFFF
    };
    
    const struct ctrl_ioregs ioregs_ddr3 = {
    	.cm0ioctl		= DDR3_ADDRCTRL_IOCTRL_VALUE,
    	.cm1ioctl		= DDR3_ADDRCTRL_WD0_IOCTRL_VALUE,
    	.cm2ioctl		= DDR3_ADDRCTRL_WD1_IOCTRL_VALUE,
    	.dt0ioctl		= DDR3_DATA0_IOCTRL_VALUE,
    	.dt1ioctl		= DDR3_DATA0_IOCTRL_VALUE,
    	.dt2ioctrl		= DDR3_DATA0_IOCTRL_VALUE,
    	.dt3ioctrl		= DDR3_DATA0_IOCTRL_VALUE,
    	.emif_sdram_config_ext	= 0xc163,
    };
    
    const struct emif_regs ddr3_emif_regs_400Mhz = {
    #if 0//Origina
    	.sdram_config			= 0x638413B2,
    	.ref_ctrl			= 0x00000C30,
    	.sdram_tim1			= 0xEAAAD4DB,
    	.sdram_tim2			= 0x266B7FDA,
    	.sdram_tim3			= 0x107F8678,
    	.read_idle_ctrl			= 0x00050000,
    	.zq_config			= 0x50074BE4,
    	.temp_alert_config		= 0x0,
    	.emif_ddr_phy_ctlr_1		= 0x0E004008,
    	.emif_ddr_ext_phy_ctrl_1	= 0x08020080,
    	.emif_ddr_ext_phy_ctrl_2	= 0x00400040,
    	.emif_ddr_ext_phy_ctrl_3	= 0x00400040,
    	.emif_ddr_ext_phy_ctrl_4	= 0x00400040,
    	.emif_ddr_ext_phy_ctrl_5	= 0x00400040,
    	.emif_rd_wr_lvl_rmp_win		= 0x0,
    	.emif_rd_wr_lvl_rmp_ctl		= 0x0,
    	.emif_rd_wr_lvl_ctl		= 0x0,
    	.emif_rd_wr_exec_thresh		= 0x80000405,
    	.emif_prio_class_serv_map	= 0x80000001,
    	.emif_connect_id_serv_1_map	= 0x80000094,
    	.emif_connect_id_serv_2_map	= 0x00000000,
    	.emif_cos_config		= 0x000FFFFF
    #else
    	.sdram_config			= 0x61A00AB2,
    	.ref_ctrl			= 0x00000C30,
    	.sdram_tim1			= 0xE668B3DB,
    	.sdram_tim2			= 0x26337FDA,
    	.sdram_tim3			= 0x5F7F830F,
    	.read_idle_ctrl			= 0x00050000,
    	.zq_config			= 0x50074BE4,
    	.temp_alert_config		= 0x0,
    
    #if 0//Rio: From Brad Patch, for Simplo DDR
    	.emif_ddr_phy_ctlr_1		= 0x0E004008,
    #else
    	.emif_ddr_phy_ctlr_1		= 0x00048008,
    #endif
    
    #if 0//Rio: Original
    	.emif_ddr_ext_phy_ctrl_1	= 0x08020080,
    	.emif_ddr_ext_phy_ctrl_2	= 0x00400040,
    	.emif_ddr_ext_phy_ctrl_3	= 0x00400040,
    	.emif_ddr_ext_phy_ctrl_4	= 0x00400040,
    	.emif_ddr_ext_phy_ctrl_5	= 0x00400040,
    	.emif_rd_wr_lvl_rmp_win		= 0x0,
    	.emif_rd_wr_lvl_rmp_ctl		= 0x0,
    	.emif_rd_wr_lvl_ctl		= 0x0,
    	.emif_rd_wr_exec_thresh		= 0x80000405,
    	.emif_prio_class_serv_map	= 0x80000001,
    	.emif_connect_id_serv_1_map	= 0x80000094,
    	.emif_connect_id_serv_2_map	= 0x00000000,
    	.emif_cos_config		= 0x000FFFFF
    #else
    	.emif_ddr_ext_phy_ctrl_1	= 0x08020080,
    	.emif_ddr_ext_phy_ctrl_2	= 0x89,
    	.emif_ddr_ext_phy_ctrl_3	= 0x90,
    	.emif_ddr_ext_phy_ctrl_4	= 0x8e,
    	.emif_ddr_ext_phy_ctrl_5	= 0x8d,
    	.emif_rd_wr_lvl_rmp_win		= 0x0,
    	.emif_rd_wr_lvl_rmp_ctl		= 0x00000000,
    	.emif_rd_wr_lvl_ctl		= 0x00000000,
    	.emif_rd_wr_exec_thresh		= 0x80000000,
    	.emif_prio_class_serv_map	= 0x80000001,
    	.emif_connect_id_serv_1_map	= 0x80000094,
    	.emif_connect_id_serv_2_map	= 0x00000000,
    	.emif_cos_config		= 0x000FFFFF
    #endif
    
    #endif
    };
    
    /* EMIF DDR3 Configurations are different for beta AM43X GP EVMs */
    const struct emif_regs ddr3_emif_regs_400Mhz_beta = {
    	.sdram_config			= 0x638413B2,
    	.ref_ctrl			= 0x00000C30,
    	.sdram_tim1			= 0xEAAAD4DB,
    	.sdram_tim2			= 0x266B7FDA,
    	.sdram_tim3			= 0x107F8678,
    	.read_idle_ctrl			= 0x00050000,
    	.zq_config			= 0x50074BE4,
    	.temp_alert_config		= 0x0,
    	.emif_ddr_phy_ctlr_1		= 0x0E004008,
    	.emif_ddr_ext_phy_ctrl_1	= 0x08020080,
    	.emif_ddr_ext_phy_ctrl_2	= 0x00000065,
    	.emif_ddr_ext_phy_ctrl_3	= 0x00000091,
    	.emif_ddr_ext_phy_ctrl_4	= 0x000000B5,
    	.emif_ddr_ext_phy_ctrl_5	= 0x000000E5,
    	.emif_rd_wr_exec_thresh		= 0x80000405,
    	.emif_prio_class_serv_map	= 0x80000001,
    	.emif_connect_id_serv_1_map	= 0x80000094,
    	.emif_connect_id_serv_2_map	= 0x00000000,
    	.emif_cos_config		= 0x000FFFFF
    };
    
    /* EMIF DDR3 Configurations are different for production AM43X GP EVMs */
    const struct emif_regs ddr3_emif_regs_400Mhz_production = {
    	.sdram_config			= 0x638413B2,
    	.ref_ctrl			= 0x00000C30,
    	.sdram_tim1			= 0xEAAAD4DB,
    	.sdram_tim2			= 0x266B7FDA,
    	.sdram_tim3			= 0x107F8678,
    	.read_idle_ctrl			= 0x00050000,
    	.zq_config			= 0x50074BE4,
    	.temp_alert_config		= 0x0,
    	.emif_ddr_phy_ctlr_1		= 0x0E004008,
    	.emif_ddr_ext_phy_ctrl_1	= 0x08020080,
    	.emif_ddr_ext_phy_ctrl_2	= 0x00000066,
    	.emif_ddr_ext_phy_ctrl_3	= 0x00000091,
    	.emif_ddr_ext_phy_ctrl_4	= 0x000000B9,
    	.emif_ddr_ext_phy_ctrl_5	= 0x000000E6,
    	.emif_rd_wr_exec_thresh		= 0x80000405,
    	.emif_prio_class_serv_map	= 0x80000001,
    	.emif_connect_id_serv_1_map	= 0x80000094,
    	.emif_connect_id_serv_2_map	= 0x00000000,
    	.emif_cos_config		= 0x000FFFFF
    };
    
    static const struct emif_regs ddr3_sk_emif_regs_400Mhz = {
    	.sdram_config			= 0x61A00AB2,
    	.sdram_config2			= 0x00000000,
    	.ref_ctrl			= 0x00000c30,
    	.sdram_tim1			= 0xE668B3DB,
    	.sdram_tim2			= 0x26337FDA,
    	.sdram_tim3			= 0x5F7F830F,
    	.read_idle_ctrl			= 0x00050000,
    	.zq_config			= 0x50074be4,
    	.temp_alert_config		= 0x0,
    
    #if 0//Rio: From Brad Patch, for Simplo DDR
    	.emif_ddr_phy_ctlr_1		= 0x0E004008,
    #else
    	.emif_ddr_phy_ctlr_1		= 0x00048008,
    #endif
    	.emif_ddr_ext_phy_ctrl_1	= 0x08020080,
    	.emif_ddr_ext_phy_ctrl_2	= 0x89,
    	.emif_ddr_ext_phy_ctrl_3	= 0x90,
    	.emif_ddr_ext_phy_ctrl_4	= 0x8e,
    	.emif_ddr_ext_phy_ctrl_5	= 0x8d,
    	.emif_rd_wr_lvl_rmp_win		= 0x0,
    	.emif_rd_wr_lvl_rmp_ctl		= 0x00000000,
    	.emif_rd_wr_lvl_ctl		= 0x00000000,
    	.emif_rd_wr_exec_thresh		= 0x80000000,
    	.emif_prio_class_serv_map	= 0x80000001,
    	.emif_connect_id_serv_1_map	= 0x80000094,
    	.emif_connect_id_serv_2_map	= 0x00000000,
    	.emif_cos_config		= 0x000FFFFF
    };
    
    static const struct emif_regs ddr3_idk_emif_regs_400Mhz = {
    	.sdram_config			= 0x61a11b32,
    	.sdram_config2			= 0x00000000,
    	.ref_ctrl			= 0x00000c30,
    	.sdram_tim1			= 0xeaaad4db,
    	.sdram_tim2			= 0x266b7fda,
    	.sdram_tim3			= 0x107f8678,
    	.read_idle_ctrl			= 0x00050000,
    	.zq_config			= 0x50074be4,
    	.temp_alert_config		= 0x00000000,
    	.emif_ddr_phy_ctlr_1		= 0x00008009,
    	.emif_ddr_ext_phy_ctrl_1	= 0x08020080,
    	.emif_ddr_ext_phy_ctrl_2	= 0x00000040,
    	.emif_ddr_ext_phy_ctrl_3	= 0x0000003e,
    	.emif_ddr_ext_phy_ctrl_4	= 0x00000051,
    	.emif_ddr_ext_phy_ctrl_5	= 0x00000051,
    	.emif_rd_wr_lvl_rmp_win		= 0x00000000,
    	.emif_rd_wr_lvl_rmp_ctl		= 0x00000000,
    	.emif_rd_wr_lvl_ctl		= 0x00000000,
    	.emif_rd_wr_exec_thresh		= 0x00000405,
    	.emif_prio_class_serv_map	= 0x00000000,
    	.emif_connect_id_serv_1_map	= 0x00000000,
    	.emif_connect_id_serv_2_map	= 0x00000000,
    	.emif_cos_config		= 0x00ffffff
    };
    
    #if 1//Rio: Porting from LNC / AM437
    /*
     * Read header information from EEPROM into global structure.
     */
    static int read_eeprom(struct am43xx_board_id *header)
    {
    	//u32 u32i;
    
    #ifndef CONFIG_DM_I2C
    	/* Check if baseboard eeprom is available */
    	if (i2c_probe(CONFIG_SYS_I2C_EEPROM_ADDR)) {
    		printf("Could not probe the EEPROM at 0x%x\n",
    		       CONFIG_SYS_I2C_EEPROM_ADDR);
    		return -ENODEV;
    	}
    	else
    		printf("[JACK]i2c_probe ok\n");
    	/* read the eeprom using i2c */
    	#if 1
    		strncpy((char *)header, (char *)CAT24C256W, sizeof(struct am43xx_board_id));
    	#else
    		if (i2c_read(CONFIG_SYS_I2C_EEPROM_ADDR, 0, 2, (uchar *)header,
    			     sizeof(struct am43xx_board_id))) {
    			printf("Could not read the EEPROM\n");
    			return -EIO;
    		}
    		
    		printf("[JACK]i2c_read ok\n");
    	#endif
    	/*header->magic = 0xEE3355AA;
    	header->name  = "AM43__SK";
    	header->version = 0x41312E31;
    	header->serial = 0x32345034343131LL;
    	header->config = 
    	for (u32i=0;u32i<32;u32i++)
    		header->mac_addr[u32i] = 0xFF;*/
    
    	if (header->magic != 0xEE3355AA) {
    		/*
    		 * read the eeprom using i2c again,
    		 * but use only a 1 byte address
    		 */
    		if (i2c_read(CONFIG_SYS_I2C_EEPROM_ADDR, 0, 1, (uchar *)header,
    			     sizeof(struct am43xx_board_id))) {
    			printf("Could not read the EEPROM at 0x%x\n",
    			       CONFIG_SYS_I2C_EEPROM_ADDR);
    			return -EIO;
    		}
    
    		if (header->magic != 0xEE3355AA) {
    			printf("Incorrect magic number (0x%x) in EEPROM\n",
    			       header->magic);
    			return -EINVAL;
    		}
    	}
    
    	strncpy(am43xx_board_name, (char *)header->name, sizeof(header->name));
    	am43xx_board_name[sizeof(header->name)] = 0;
    
    	strncpy(am43xx_board_rev, (char *)header->version, sizeof(header->version));
    	am43xx_board_rev[sizeof(header->version)] = 0;
    
    	return 0;
    #endif
    }
    
    
    #endif //Rio: Porting from LNC / AM437
    
    void emif_get_ext_phy_ctrl_const_regs(const u32 **regs, u32 *size)
    {
    	if (board_is_eposevm()) {
    		*regs = ext_phy_ctrl_const_base_lpddr2;
    		*size = ARRAY_SIZE(ext_phy_ctrl_const_base_lpddr2);
    	}
    
    	return;
    }
    
    const struct dpll_params *get_dpll_ddr_params(void)
    {
    	int ind = get_sys_clk_index();
    
    	printf(" \n Rio_Debug: Entering get_dpll_ddr_params........................\n");
    
    	if (board_is_eposevm())
    	{
    	printf(" \n Rio_Debug: get_dpll_ddr_params with board_is_eposevm\n");
    		return &epos_evm_dpll_ddr[ind];
    	}
    	else if (board_is_evm() || board_is_sk())
    	{
    	printf(" \n Rio_Debug: get_dpll_ddr_params with board_is_evm or board_is_sk\n");
    		return &gp_evm_dpll_ddr;
    	}
    	else if (board_is_idk())
    	{
    	printf(" \n Rio_Debug: get_dpll_ddr_params with board_is_idk\n");
    		return &idk_dpll_ddr;
    	}
    
    #if 1//Rio: Original
    	else
    	{
    	printf(" Board '%s' not supported\n", board_ti_get_name());
    	return NULL;
    	}
    #else//Rio: Customer is using SK evm, so I assume is should be the same with GP, see above code.
    	else
    	{
    	printf(" \n Rio_Debug: Simpo PCB is SK EVM Board will be choosen as SK \n");
    	return &gp_evm_dpll_ddr;
    	}
    
    #endif
    }
    
    
    /*
     * get_opp_offset:
     * Returns the index for safest OPP of the device to boot.
     * max_off:	Index of the MAX OPP in DEV ATTRIBUTE register.
     * min_off:	Index of the MIN OPP in DEV ATTRIBUTE register.
     * This data is read from dev_attribute register which is e-fused.
     * A'1' in bit indicates OPP disabled and not available, a '0' indicates
     * OPP available. Lowest OPP starts with min_off. So returning the
     * bit with rightmost '0'.
     */
    static int get_opp_offset(int max_off, int min_off)
    {
    	struct ctrl_stat *ctrl = (struct ctrl_stat *)CTRL_BASE;
    	int opp, offset, i;
    
    	printf(" \n Rio_Debug: get_opp_offset\n");
    
    	/* Bits 0:11 are defined to be the MPU_MAX_FREQ */
    	opp = readl(&ctrl->dev_attr) & ~0xFFFFF000;
    
    	for (i = max_off; i >= min_off; i--) {
    		offset = opp & (1 << i);
    		if (!offset)
    			return i;
    	}
    
    	return min_off;
    }
    
    const struct dpll_params *get_dpll_mpu_params(void)
    {
    	int opp = get_opp_offset(DEV_ATTR_MAX_OFFSET, DEV_ATTR_MIN_OFFSET);
    	u32 ind = get_sys_clk_index();
    	printf("\n Rio_Debug: get_dpll_mpu_params\n");
    	return &dpll_mpu[ind][opp];
    }
    
    const struct dpll_params *get_dpll_core_params(void)
    {
    	int ind = get_sys_clk_index();
    	printf("\n Rio_Debug: get_dpll_core_params\n");
    	return &dpll_core[ind];
    }
    
    const struct dpll_params *get_dpll_per_params(void)
    {
    	int ind = get_sys_clk_index();
    #if 0
            printf("\n");
    	printf("\n Rio_Debug: get_dpll_per_params\n");
            printf("\n");
    #endif
    	return &dpll_per[ind];
    }
    
    void scale_vcores_generic(u32 m)
    {
    	int mpu_vdd, ddr_volt;
    
    	printf("\n Rio_Debug: scale_vcores_generic, checking TPS6521X\n");
    
    #ifndef CONFIG_DM_I2C
    	if (i2c_probe(TPS65218_CHIP_PM))
    		return;
    #else
    	if (power_tps65218_init(0))
    		return;
    #endif
    
    	switch (m) {
    	case 1000:
    		mpu_vdd = TPS65218_DCDC_VOLT_SEL_1330MV;
    		printf("\n Rio_Debug: scale_vcores_generic, checking TPS6521X, 1000Mhz\n");
    		break;
    	case 800:
    		mpu_vdd = TPS65218_DCDC_VOLT_SEL_1260MV;
    		printf("\n Rio_Debug: scale_vcores_generic, checking TPS6521X, 800Mhz\n");
    		break;
    	case 720:
    		mpu_vdd = TPS65218_DCDC_VOLT_SEL_1200MV;
    		printf("\n Rio_Debug: scale_vcores_generic, checking TPS6521X, 720Mhz\n");
    		break;
    	case 600:
    		mpu_vdd = TPS65218_DCDC_VOLT_SEL_1100MV;
    		printf("\n Rio_Debug: scale_vcores_generic, checking TPS6521X, 600Mhz\n");
    		break;
    	case 300:
    		mpu_vdd = TPS65218_DCDC_VOLT_SEL_0950MV;
    		printf("\n Rio_Debug: scale_vcores_generic, checking TPS6521X, 300Mhz\n");
    		break;
    	default:
    		puts("Unknown MPU clock, not scaling\n");
    		return;
    	}
    
    	/* Set DCDC1 (CORE) voltage to 1.1V */
    	if (tps65218_voltage_update(TPS65218_DCDC1,
    				    TPS65218_DCDC_VOLT_SEL_1100MV)) {
    		printf("%s failure\n", __func__);
    		printf("\n Rio_Debug: scale_vcores_generic, checking DCDC1 tps65218_voltage_update\n");
    
    		return;
    	}
    
    	/* Set DCDC2 (MPU) voltage */
    	if (tps65218_voltage_update(TPS65218_DCDC2, mpu_vdd)) {
    		printf("%s failure\n", __func__);
    		printf("\n Rio_Debug: scale_vcores_generic, checking DCDC2 tps65218_voltage_update\n");
    
    		return;
    	}
    
    	if (board_is_eposevm())
    		ddr_volt = TPS65218_DCDC3_VOLT_SEL_1200MV;
    	else
    		ddr_volt = TPS65218_DCDC3_VOLT_SEL_1350MV;
    
    	/* Set DCDC3 (DDR) voltage */
    	if (tps65218_voltage_update(TPS65218_DCDC3, ddr_volt)) {
    		printf(" \n Rio_Debug: scale_vcores_generic, checking DCDC3 tps65218_voltage_update\n");
    		printf("%s failure\n", __func__);
    		return;
    	}
    }
    
    void scale_vcores_idk(u32 m)
    {
    	int mpu_vdd;
    
    #ifndef CONFIG_DM_I2C
    	if (i2c_probe(TPS62362_I2C_ADDR))
    		return;
    #else
    	if (power_tps62362_init(0))
    		return;
    #endif
    
    	switch (m) {
    	case 1000:
    		mpu_vdd = TPS62362_DCDC_VOLT_SEL_1330MV;
    		break;
    	case 800:
    		mpu_vdd = TPS62362_DCDC_VOLT_SEL_1260MV;
    		break;
    	case 720:
    		mpu_vdd = TPS62362_DCDC_VOLT_SEL_1200MV;
    		break;
    	case 600:
    		mpu_vdd = TPS62362_DCDC_VOLT_SEL_1100MV;
    		break;
    	case 300:
    		mpu_vdd = TPS62362_DCDC_VOLT_SEL_1330MV;
    		break;
    	default:
    		puts("Unknown MPU clock, not scaling\n");
    		return;
    	}
    	/* Set VDD_MPU voltage */
    	if (tps62362_voltage_update(TPS62362_SET3, mpu_vdd)) {
    		printf("\n %s failure\n", __func__);
    		return;
    	}
    }
    void gpi2c_init(void)
    {
    	/* When needed to be invoked prior to BSS initialization */
    	static bool first_time = true;
    
    	printf(" \n Rio_Debug: gpi2c_init\n");
    
    	if (first_time) {
    		enable_i2c0_pin_mux();
    #ifndef CONFIG_DM_I2C
    		i2c_init(CONFIG_SYS_OMAP24_I2C_SPEED,
    			 CONFIG_SYS_OMAP24_I2C_SLAVE);
    #endif
    		first_time = false;
    	}
    }
    
    void scale_vcores(void)
    {
    	const struct dpll_params *mpu_params;
    
    #if 1//Rio
    	int mpu_vdd;
    	struct am43xx_board_id header;
    #endif
    	printf(" \n Rio_Debug: scale_vcores\n");
    	
    	/* Ensure I2C is initialized for PMIC configuration */
    	gpi2c_init();
    
    #ifndef CONFIG_DM_I2C//Rio
    	enable_i2c0_pin_mux();
    	i2c_init(CONFIG_SYS_OMAP24_I2C_SPEED, CONFIG_SYS_OMAP24_I2C_SLAVE);
    	if (read_eeprom(&header) < 0)
    		puts("Could not get board ID.\n");
    	else
    		printf("[JACK]get board ID ok\n");
            mdelay(3000);
    #endif
    
    	/* Get the frequency */
    	mpu_params = get_dpll_mpu_params();
    
    	if (board_is_idk())
    		scale_vcores_idk(mpu_params->m);
    	else
    		scale_vcores_generic(mpu_params->m);
    }
    
    void set_uart_mux_conf(void)
    {
    	enable_uart0_pin_mux();
    }
    
    void set_mux_conf_regs(void)
    {
    	enable_board_pin_mux();
    }
    
    static void enable_vtt_regulator(void)
    {
    	u32 temp;
    
    	printf(" \n Rio_Debug: enable_vtt_regulator\n");
    	/* enable module */
    	writel(GPIO_CTRL_ENABLEMODULE, AM33XX_GPIO5_BASE + OMAP_GPIO_CTRL);
    
    	/* enable output for GPIO5_7 */
    	writel(GPIO_SETDATAOUT(7),
    	       AM33XX_GPIO5_BASE + OMAP_GPIO_SETDATAOUT);
    	temp = readl(AM33XX_GPIO5_BASE + OMAP_GPIO_OE);
    	temp = temp & ~(GPIO_OE_ENABLE(7));
    	writel(temp, AM33XX_GPIO5_BASE + OMAP_GPIO_OE);
    }
    
    enum {
    	RTC_BOARD_EPOS = 1,
    	RTC_BOARD_EVM14,
    	RTC_BOARD_EVM12,
    	RTC_BOARD_GPEVM,
    	RTC_BOARD_SK,
    };
    
    /*
     * In the rtc_only+DRR in self-refresh boot path we have the board type info
     * in the rtc scratch pad register hence we bypass the costly i2c reads to
     * eeprom and directly programthe board name string
     */
    void rtc_only_update_board_type(u32 btype)
    {
    	const char *name = "";
    	const char *rev = "1.0";
    
    	printf(" \n Rio_Debug: rtc_only_update_board_type\n");
    
    	switch (btype) {
    	case RTC_BOARD_EPOS:
    		name = "AM43EPOS";
    		break;
    	case RTC_BOARD_EVM14:
    		name = "AM43__GP";
    		rev = "1.4";
    		break;
    	case RTC_BOARD_EVM12:
    		name = "AM43__GP";
    		rev = "1.2";
    		break;
    	case RTC_BOARD_GPEVM:
    		name = "AM43__GP";
    		break;
    	case RTC_BOARD_SK:
    		name = "AM43__SK";
    		break;
    	}
    	ti_i2c_eeprom_am_set(name, rev);
    }
    
    u32 rtc_only_get_board_type(void)
    {
    	printf(" \n Rio_Debug: rtc_only_get_board_type\n");
    
    	if (board_is_eposevm())
    		return RTC_BOARD_EPOS;
    	else if (board_is_evm_14_or_later())
    		return RTC_BOARD_EVM14;
    	else if (board_is_evm_12_or_later())
    		return RTC_BOARD_EVM12;
    	else if (board_is_gpevm())
    		return RTC_BOARD_GPEVM;
    	else if (board_is_sk())
    		return RTC_BOARD_SK;
    
    	return 0;
    }
    
    void sdram_init(void)
    {
    	/*
    	 * EPOS EVM has 1GB LPDDR2 connected to EMIF.
    	 * GP EMV has 1GB DDR3 connected to EMIF
    	 * along with VTT regulator.
    	 */
    
    	printf(" \n Rio_Debug: sdram_init\n");
    
    
    	if (board_is_eposevm()) 
    	{
    		printf(" \n Rio_Debug: sdram_init,board_is_eposevm \n");
    		config_ddr(0, &ioregs_lpddr2, NULL, NULL, &emif_regs_lpddr2, 0);
    	} 
    	else if (board_is_evm_14_or_later()) 
    	{
    		printf(" \n Rio_Debug: sdram_init,board_is_evm_14_or_later \n");
    		enable_vtt_regulator();
    		config_ddr(0, &ioregs_ddr3, NULL, NULL,
    			   &ddr3_emif_regs_400Mhz_production, 0);
    	} 
    	else if (board_is_evm_12_or_later()) 
    	{
    		printf(" \n Rio_Debug: sdram_init,board_is_evm_12_or_later \n");
    		enable_vtt_regulator();
    		config_ddr(0, &ioregs_ddr3, NULL, NULL,
    			   &ddr3_emif_regs_400Mhz_beta, 0);
    	} 
    	else if (board_is_evm()) 
    	{
    		printf(" \n Rio_Debug: sdram_init,board_is_evm \n");
    		enable_vtt_regulator();
    		config_ddr(0, &ioregs_ddr3, NULL, NULL,
    			   &ddr3_emif_regs_400Mhz, 0);
    	} 
    	else if (board_is_sk()) 
    	{
    		printf(" \n Rio_Debug: sdram_init,board_is_sk \n");
    		config_ddr(400, &ioregs_ddr3, NULL, NULL,
    			   &ddr3_sk_emif_regs_400Mhz, 0);
    	} 
    	else if (board_is_idk()) 
    	{
    		printf(" \n Rio_Debug: sdram_init,board_is_idk \n");
    		config_ddr(400, &ioregs_ddr3, NULL, NULL,
    			   &ddr3_idk_emif_regs_400Mhz, 0);
    	}
    }
    #endif
    
    /* setup board specific PMIC */
    int power_init_board(void)
    {
    	int rc;
    #ifndef CONFIG_DM_I2C
    	struct pmic *p = NULL;
    #endif
    	printf(" \n Rio_Debug: power_init_board\n");
    
    	if (board_is_idk()) {
    		rc = power_tps62362_init(0);
    		if (rc)
    			goto done;
    #ifndef CONFIG_DM_I2C
    		p = pmic_get("TPS62362");
    		if (!p || pmic_probe(p))
    			goto done;
    #endif
    		puts("PMIC:  TPS62362\n");
    	} else {
    		rc = power_tps65218_init(0);
    		if (rc)
    			goto done;
    #ifndef CONFIG_DM_I2C
    		p = pmic_get("TPS65218_PMIC");
    		if (!p || pmic_probe(p))
    			goto done;
    #endif
    		puts("PMIC:  TPS65218\n");
    	}
    done:
    	return 0;
    }
    
    int board_init(void)
    {
    	struct l3f_cfg_bwlimiter *bwlimiter = (struct l3f_cfg_bwlimiter *)L3F_CFG_BWLIMITER;
    	u32 mreqprio_0, mreqprio_1, modena_init0_bw_fractional,
    	    modena_init0_bw_integer, modena_init0_watermark_0;
    
    	printf(" \n Rio_Debug: board_init\n");
    
    	gd->bd->bi_boot_params = CONFIG_SYS_SDRAM_BASE + 0x100;
    	gpmc_init();
    
    	printf(" \n Rio_Debug: gpmc_init done\n");
    
    	/*
    	 * Call this to initialize *ctrl again
    	 */
    	hw_data_init();
    	printf(" \n Rio_Debug: hw_data_init done\n");
    
    	/* Clear all important bits for DSS errata that may need to be tweaked*/
    	mreqprio_0 = readl(&cdev->mreqprio_0) & MREQPRIO_0_SAB_INIT1_MASK &
    	                   MREQPRIO_0_SAB_INIT0_MASK;
    
    	mreqprio_1 = readl(&cdev->mreqprio_1) & MREQPRIO_1_DSS_MASK;
    
    	modena_init0_bw_fractional = readl(&bwlimiter->modena_init0_bw_fractional) &
    	                                   BW_LIMITER_BW_FRAC_MASK;
    
    	modena_init0_bw_integer = readl(&bwlimiter->modena_init0_bw_integer) &
    	                                BW_LIMITER_BW_INT_MASK;
    
    	modena_init0_watermark_0 = readl(&bwlimiter->modena_init0_watermark_0) &
    	                                 BW_LIMITER_BW_WATERMARK_MASK;
    
    	/* Setting MReq Priority of the DSS*/
    	mreqprio_0 |= 0x77;
    
    	/*
    	 * Set L3 Fast Configuration Register
    	 * Limiting bandwith for ARM core to 700 MBPS
    	 */
    	modena_init0_bw_fractional |= 0x10;
    	modena_init0_bw_integer |= 0x3;
    
    	writel(mreqprio_0, &cdev->mreqprio_0);
    	writel(mreqprio_1, &cdev->mreqprio_1);
    
    	writel(modena_init0_bw_fractional, &bwlimiter->modena_init0_bw_fractional);
    	writel(modena_init0_bw_integer, &bwlimiter->modena_init0_bw_integer);
    	writel(modena_init0_watermark_0, &bwlimiter->modena_init0_watermark_0);
    
    	return 0;
    }
    
    #ifdef CONFIG_BOARD_LATE_INIT
    #if CONFIG_IS_ENABLED(DM_USB) && CONFIG_IS_ENABLED(OF_CONTROL)
    static int device_okay(const char *path)
    {
    	int node;
    
    	node = fdt_path_offset(gd->fdt_blob, path);
    	printf(" \n Rio_Debug: device_okay\n");
    
    
    	if (node < 0)
    		return 0;
    
    	return fdtdec_get_is_enabled(gd->fdt_blob, node);
    }
    #endif
    
    int board_late_init(void)
    {
    	struct udevice *dev;
    #if 0//Rio: 
    	char safe_string[HDR_NAME_LEN+1];
    	struct am43xx_board_id header;
    
    	if (read_eeprom(&header) < 0)
    		puts("Could not get board ID.\n");
    
    	/* Now set variables based on the header. */
    	strncpy(safe_string, (char *)header.name, sizeof(header.name));
    	safe_string[sizeof(header.name)] = 0;
    	setenv("board_name", safe_string);
    
    	strncpy(safe_string, (char *)header.version, sizeof(header.version));
    	safe_string[sizeof(header.version)] = 0;
    	setenv("board_rev", safe_string);
    #endif
    
    #ifdef CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG
    	set_board_info_env(NULL);
    
    	printf(" \n Rio_Debug: board_late_init\n");
    
    	/*
    	 * Default FIT boot on HS devices. Non FIT images are not allowed
    	 * on HS devices.
    	 */
    	if (get_device_type() == HS_DEVICE)
    		env_set("boot_fit", "1");
    #endif
    
    #if CONFIG_IS_ENABLED(DM_USB) && CONFIG_IS_ENABLED(OF_CONTROL)
    	if (device_okay("/ocp/omap_dwc3@48380000"))
    		enable_usb_clocks(0);
    	if (device_okay("/ocp/omap_dwc3@483c0000"))
    		enable_usb_clocks(1);
    #endif
    
    	/* Just probe the potentially supported cdce913 device */
    	uclass_get_device(UCLASS_CLK, 0, &dev);
    
    	return 0;
    }
    #endif
    
    #if !CONFIG_IS_ENABLED(DM_USB_GADGET)
    #ifdef CONFIG_USB_DWC3
    static struct dwc3_device usb_otg_ss1 = {
    	.maximum_speed = USB_SPEED_HIGH,
    	.base = USB_OTG_SS1_BASE,
    	.tx_fifo_resize = false,
    	.index = 0,
    };
    
    static struct dwc3_omap_device usb_otg_ss1_glue = {
    	.base = (void *)USB_OTG_SS1_GLUE_BASE,
    	.utmi_mode = DWC3_OMAP_UTMI_MODE_SW,
    	.index = 0,
    };
    
    static struct ti_usb_phy_device usb_phy1_device = {
    	.usb2_phy_power = (void *)USB2_PHY1_POWER,
    	.index = 0,
    };
    
    static struct dwc3_device usb_otg_ss2 = {
    	.maximum_speed = USB_SPEED_HIGH,
    	.base = USB_OTG_SS2_BASE,
    	.tx_fifo_resize = false,
    	.index = 1,
    };
    
    static struct dwc3_omap_device usb_otg_ss2_glue = {
    	.base = (void *)USB_OTG_SS2_GLUE_BASE,
    	.utmi_mode = DWC3_OMAP_UTMI_MODE_SW,
    	.index = 1,
    };
    
    static struct ti_usb_phy_device usb_phy2_device = {
    	.usb2_phy_power = (void *)USB2_PHY2_POWER,
    	.index = 1,
    };
    
    int usb_gadget_handle_interrupts(int index)
    {
    	u32 status;
    
    	status = dwc3_omap_uboot_interrupt_status(index);
    	if (status)
    		dwc3_uboot_handle_interrupt(index);
    
    	return 0;
    }
    #endif /* CONFIG_USB_DWC3 */
    
    #if defined(CONFIG_USB_DWC3) || defined(CONFIG_USB_XHCI_OMAP)
    int board_usb_init(int index, enum usb_init_type init)
    {
    	enable_usb_clocks(index);
    #ifdef CONFIG_USB_DWC3
    	switch (index) {
    	case 0:
    		if (init == USB_INIT_DEVICE) {
    			usb_otg_ss1.dr_mode = USB_DR_MODE_PERIPHERAL;
    			usb_otg_ss1_glue.vbus_id_status = OMAP_DWC3_VBUS_VALID;
    			dwc3_omap_uboot_init(&usb_otg_ss1_glue);
    			ti_usb_phy_uboot_init(&usb_phy1_device);
    			dwc3_uboot_init(&usb_otg_ss1);
    		}
    		break;
    	case 1:
    		if (init == USB_INIT_DEVICE) {
    			usb_otg_ss2.dr_mode = USB_DR_MODE_PERIPHERAL;
    			usb_otg_ss2_glue.vbus_id_status = OMAP_DWC3_VBUS_VALID;
    			ti_usb_phy_uboot_init(&usb_phy2_device);
    			dwc3_omap_uboot_init(&usb_otg_ss2_glue);
    			dwc3_uboot_init(&usb_otg_ss2);
    		}
    		break;
    	default:
    		printf("Invalid Controller Index\n");
    	}
    #endif
    
    	return 0;
    }
    
    int board_usb_cleanup(int index, enum usb_init_type init)
    {
    #ifdef CONFIG_USB_DWC3
    	switch (index) {
    	case 0:
    	case 1:
    		if (init == USB_INIT_DEVICE) {
    			ti_usb_phy_uboot_exit(index);
    			dwc3_uboot_exit(index);
    			dwc3_omap_uboot_exit(index);
    		}
    		break;
    	default:
    		printf("Invalid Controller Index\n");
    	}
    #endif
    	disable_usb_clocks(index);
    
    	return 0;
    }
    #endif /* defined(CONFIG_USB_DWC3) || defined(CONFIG_USB_XHCI_OMAP) */
    #endif /* !CONFIG_IS_ENABLED(DM_USB_GADGET) */
    
    #ifdef CONFIG_DRIVER_TI_CPSW
    
    static void cpsw_control(int enabled)
    {
    	/* Additional controls can be added here */
    	return;
    }
    
    static struct cpsw_slave_data cpsw_slaves[] = {
    	{
    		.slave_reg_ofs	= 0x208,
    		.sliver_reg_ofs	= 0xd80,
    		.phy_addr	= 16,
    	},
    	{
    		.slave_reg_ofs	= 0x308,
    		.sliver_reg_ofs	= 0xdc0,
    		.phy_addr	= 1,
    	},
    };
    
    static struct cpsw_platform_data cpsw_data = {
    	.mdio_base		= CPSW_MDIO_BASE,
    	.cpsw_base		= CPSW_BASE,
    	.mdio_div		= 0xff,
    	.channels		= 8,
    	.cpdma_reg_ofs		= 0x800,
    	.slaves			= 1,
    	.slave_data		= cpsw_slaves,
    	.ale_reg_ofs		= 0xd00,
    	.ale_entries		= 1024,
    	.host_port_reg_ofs	= 0x108,
    	.hw_stats_reg_ofs	= 0x900,
    	.bd_ram_ofs		= 0x2000,
    	.mac_control		= (1 << 5),
    	.control		= cpsw_control,
    	.host_port_num		= 0,
    	.version		= CPSW_CTRL_VERSION_2,
    };
    
    int board_eth_init(bd_t *bis)
    {
    	int rv;
    	uint8_t mac_addr[6];
    	uint32_t mac_hi, mac_lo;
    
    	/* try reading mac address from efuse */
    	mac_lo = readl(&cdev->macid0l);
    	mac_hi = readl(&cdev->macid0h);
    	mac_addr[0] = mac_hi & 0xFF;
    	mac_addr[1] = (mac_hi & 0xFF00) >> 8;
    	mac_addr[2] = (mac_hi & 0xFF0000) >> 16;
    	mac_addr[3] = (mac_hi & 0xFF000000) >> 24;
    	mac_addr[4] = mac_lo & 0xFF;
    	mac_addr[5] = (mac_lo & 0xFF00) >> 8;
    
    	if (!env_get("ethaddr")) {
    		puts("<ethaddr> not set. Validating first E-fuse MAC\n");
    		if (is_valid_ethaddr(mac_addr))
    			eth_env_set_enetaddr("ethaddr", mac_addr);
    	}
    
    	mac_lo = readl(&cdev->macid1l);
    	mac_hi = readl(&cdev->macid1h);
    	mac_addr[0] = mac_hi & 0xFF;
    	mac_addr[1] = (mac_hi & 0xFF00) >> 8;
    	mac_addr[2] = (mac_hi & 0xFF0000) >> 16;
    	mac_addr[3] = (mac_hi & 0xFF000000) >> 24;
    	mac_addr[4] = mac_lo & 0xFF;
    	mac_addr[5] = (mac_lo & 0xFF00) >> 8;
    
    	if (!env_get("eth1addr")) {
    		if (is_valid_ethaddr(mac_addr))
    			eth_env_set_enetaddr("eth1addr", mac_addr);
    	}
    
    	if (board_is_eposevm()) {
    		writel(RMII_MODE_ENABLE | RMII_CHIPCKL_ENABLE, &cdev->miisel);
    		cpsw_slaves[0].phy_if = PHY_INTERFACE_MODE_RMII;
    		cpsw_slaves[0].phy_addr = 16;
    	} else if (board_is_sk()) {
    		writel(RGMII_MODE_ENABLE, &cdev->miisel);
    		cpsw_slaves[0].phy_if = PHY_INTERFACE_MODE_RGMII;
    		cpsw_slaves[0].phy_addr = 4;
    		cpsw_slaves[1].phy_addr = 5;
    	} else if (board_is_idk()) {
    		writel(RGMII_MODE_ENABLE, &cdev->miisel);
    		cpsw_slaves[0].phy_if = PHY_INTERFACE_MODE_RGMII;
    		cpsw_slaves[0].phy_addr = 0;
    	} else {
    		writel(RGMII_MODE_ENABLE, &cdev->miisel);
    		cpsw_slaves[0].phy_if = PHY_INTERFACE_MODE_RGMII;
    		cpsw_slaves[0].phy_addr = 0;
    	}
    
    	rv = cpsw_register(&cpsw_data);
    	if (rv < 0)
    		printf(" \n Error %d registering CPSW switch\n", rv);
    
    	return rv;
    }
    #endif
    
    #if defined(CONFIG_OF_LIBFDT) && defined(CONFIG_OF_BOARD_SETUP)
    int ft_board_setup(void *blob, bd_t *bd)
    {
    	ft_cpu_setup(blob, bd);
    
    	return 0;
    }
    #endif
    
    #if defined(CONFIG_SPL_LOAD_FIT) || defined(CONFIG_DTB_RESELECT)
    int board_fit_config_name_match(const char *name)
    {
    	printf(" \n Rio_Debug: board_fit_config_name_match\n");
    
    	bool eeprom_read = board_ti_was_eeprom_read();
    
    	if (!strcmp(name, "am4372-generic") && !eeprom_read)
    	{
    		printf(" \n Rio_Debug: board_fit_config_name_match -am4372-generic\n");
    		return 0;
    	}
    	else if (board_is_evm() && !strcmp(name, "am437x-gp-evm"))
    	{
    		printf(" \n Rio_Debug: board_fit_config_name_match -am437x-gp-evm\n");
    		return 0;
    	}
    	else if (board_is_sk() && !strcmp(name, "am437x-sk-evm"))
    	{
    		printf(" \n Rio_Debug: board_fit_config_name_match -am437x-sk-evm\n");
    		return 0;
    	}
    	else if (board_is_eposevm() && !strcmp(name, "am43x-epos-evm"))
    	{
    		printf(" \n Rio_Debug: board_fit_config_name_match -am437x-epos-evm\n");
    		return 0;
    	}
    	else if (board_is_idk() && !strcmp(name, "am437x-idk-evm"))
    	{
    		printf(" \n Rio_Debug: board_fit_config_name_match -am437x-idk-evm\n");
    		return 0;
    	}
    	else
    #if 1//Rio: Original
    		return -1;
    #else
    		return 0;
    #endif
    }
    #endif
    
    #ifdef CONFIG_DTB_RESELECT
    int embedded_dtb_select(void)
    {
    	do_board_detect();
    	fdtdec_setup();
    
    	return 0;
    }
    #endif
    
    #ifdef CONFIG_TI_SECURE_DEVICE
    void board_fit_image_post_process(void **p_image, size_t *p_size)
    {
    	secure_boot_verify_image(p_image, p_size);
    }
    
    void board_tee_image_process(ulong tee_image, size_t tee_size)
    {
    	secure_tee_install((u32)tee_image);
    }
    
    U_BOOT_FIT_LOADABLE_HANDLER(IH_TYPE_TEE, board_tee_image_process);
    #endif
    2020_9_1_Rio_Logs_on_SP_EVM_With_Brad_Patch.txt.txt
    <debug_uart>
     Rio_Debug: gpi2c_init
    
     Rio_Debug: Entering ti_i2c_eeprom_am_get
    
     Rio_Debug: Entering ti_i2c_eeprom_am_get, check point 1.
    
     Rio_Debug: Entering ti_i2c_eeprom_get
    OF: ** translation for device i2c@44e0b000 **
    OF: bus is default (na=1, ns=1) on ocp
    OF: parent bus is default (na=1, ns=1) on
    OF: no ranges, 1:1 translation
    OF: with offset: 1155575808
    OF: reached root node
    
     Rio_Debug: Entering ti_i2c_eeprom_am_get, check point 2.
    
     Rio_Debug: Entering ti_i2c_eeprom_am_get -> ti_i2c_eeprom_get
    
     Rio_Debug: Entering ti_i2c_eeprom_am_get, check point 3.
    
     Rio_Debug: Entering ti_i2c_eeprom_am_get, check point 3.3
    
     Rio_Debug: Entering ti_i2c_eeprom_am_get, check point 4.
    
     Rio_Debug: Entering ti_i2c_eeprom_am_get, final check point.
    
     Rio: Passed early_system_init()
    
     Rio_Debug: scale_vcores
    
     Rio_Debug: gpi2c_init
    
     Rio_Debug: get_opp_offset
    
     Rio_Debug: get_dpll_mpu_params
    
     Rio_Debug: Entering board_ti_is.............................
    
     Rio_Debug: Entering board_ti_is : ep->name = AM43__SK
    
     Rio_Debug: Entering board_ti_is : name_tag= AM43_IDK
    
     Rio_Debug: Entering board_ti_is : TI_EEPROM_HDR_NAME_LEN= 8
    
     Rio_Debug: scale_vcores_generic, checking TPS6521X
    
     Rio_Debug: scale_vcores_generic, checking TPS6521X, 1000Mhz
    
     Rio_Debug: Entering board_ti_is.............................
    
     Rio_Debug: Entering board_ti_is : ep->name = AM43__SK
    
     Rio_Debug: Entering board_ti_is : name_tag= AM43EPOS
    
     Rio_Debug: Entering board_ti_is : TI_EEPROM_HDR_NAME_LEN= 8
    
     Rio_Debug: get_dpll_core_params
    
     Rio_Debug: get_opp_offset
    
     Rio_Debug: get_dpll_mpu_params
    
     Rio_Debug: Entering get_dpll_ddr_params........................
    
     Rio_Debug: Entering board_ti_is.............................
    
     Rio_Debug: Entering board_ti_is : ep->name = AM43__SK
    
     Rio_Debug: Entering board_ti_is : name_tag= AM43EPOS
    
     Rio_Debug: Entering board_ti_is : TI_EEPROM_HDR_NAME_LEN= 8
    
     Rio_Debug: Entering board_ti_is.............................
    
     Rio_Debug: Entering board_ti_is : ep->name = AM43__SK
    
     Rio_Debug: Entering board_ti_is : name_tag= AM43__GP
    
     Rio_Debug: Entering board_ti_is : TI_EEPROM_HDR_NAME_LEN= 8
    
     Rio_Debug: Entering board_ti_is.............................
    
     Rio_Debug: Entering board_ti_is : ep->name = AM43__SK
    
     Rio_Debug: Entering board_ti_is : name_tag= AM43XXHS
    
     Rio_Debug: Entering board_ti_is : TI_EEPROM_HDR_NAME_LEN= 8
    
     Rio_Debug: get_dpll_ddr_params with board_is_evm or board_is_sk
    
     Rio_Debug: Entering board_ti_is.............................
    
     Rio_Debug: Entering board_ti_is : ep->name = AM43__SK
    
     Rio_Debug: Entering board_ti_is : name_tag= AM43__GP
    
     Rio_Debug: Entering board_ti_is : TI_EEPROM_HDR_NAME_LEN= 8
    
     Rio_Debug: Entering board_ti_is.............................
    
     Rio_Debug: Entering board_ti_is : ep->name = AM43__SK
    
     Rio_Debug: Entering board_ti_is : name_tag= AM43XXHS
    
     Rio_Debug: Entering board_ti_is : TI_EEPROM_HDR_NAME_LEN= 8
    Error: NAND flash not present on this board
    
     Rio: Passed board_early_init_f()
    
     Rio_Debug: sdram_init
    
     Rio_Debug: Entering board_ti_is.............................
    
     Rio_Debug: Entering board_ti_is : ep->name = AM43__SK
    
     Rio_Debug: Entering board_ti_is : name_tag= AM43EPOS
    
     Rio_Debug: Entering board_ti_is : TI_EEPROM_HDR_NAME_LEN= 8
    
     Rio_Debug: Entering board_ti_is.............................
    
     Rio_Debug: Entering board_ti_is : ep->name = AM43__SK
    
     Rio_Debug: Entering board_ti_is : name_tag= AM43__GP
    
     Rio_Debug: Entering board_ti_is : TI_EEPROM_HDR_NAME_LEN= 8
    
     Rio_Debug: Entering board_ti_is.............................
    
     Rio_Debug: Entering board_ti_is : ep->name = AM43__SK
    
     Rio_Debug: Entering board_ti_is : name_tag= AM43XXHS
    
     Rio_Debug: Entering board_ti_is : TI_EEPROM_HDR_NAME_LEN= 8
    
     Rio_Debug: Entering board_ti_is.............................
    
     Rio_Debug: Entering board_ti_is : ep->name = AM43__SK
    
     Rio_Debug: Entering board_ti_is : name_tag= AM43__GP
    
     Rio_Debug: Entering board_ti_is : TI_EEPROM_HDR_NAME_LEN= 8
    
     Rio_Debug: Entering board_ti_is.............................
    
     Rio_Debug: Entering board_ti_is : ep->name = AM43__SK
    
     Rio_Debug: Entering board_ti_is : name_tag= AM43XXHS
    
     Rio_Debug: Entering board_ti_is : TI_EEPROM_HDR_NAME_LEN= 8
    
     Rio_Debug: Entering board_ti_is.............................
    
     Rio_Debug: Entering board_ti_is : ep->name = AM43__SK
    
     Rio_Debug: Entering board_ti_is : name_tag= AM43__GP
    
     Rio_Debug: Entering board_ti_is : TI_EEPROM_HDR_NAME_LEN= 8
    
     Rio_Debug: Entering board_ti_is.............................
    
     Rio_Debug: Entering board_ti_is : ep->name = AM43__SK
    
     Rio_Debug: Entering board_ti_is : name_tag= AM43XXHS
    
     Rio_Debug: Entering board_ti_is : TI_EEPROM_HDR_NAME_LEN= 8
    
     Rio_Debug: sdram_init,board_is_sk
    
     Rio: Passed sdram_init()
    
     Rio: now entering-get_ram_size, simplo am437 is using 512MB 536870912
    <debug_uart>
     Rio_Debug: gpi2c_init
    
     Rio_Debug: Entering ti_i2c_eeprom_am_get
    
     Rio_Debug: Entering ti_i2c_eeprom_am_get, check point 1.
    
     Rio_Debug: Entering ti_i2c_eeprom_get
    OF: ** translation for device i2c@44e0b000 **
    OF: bus is default (na=1, ns=1) on ocp
    OF: parent bus is default (na=1, ns=1) on
    OF: no ranges, 1:1 translation
    OF: with offset: 1155575808
    OF: reached root node
    
     Rio_Debug: Entering ti_i2c_eeprom_am_get, check point 2.
    
     Rio_Debug: Entering ti_i2c_eeprom_am_get -> ti_i2c_eeprom_get
    
     Rio_Debug: Entering ti_i2c_eeprom_am_get, check point 3.
    
     Rio_Debug: Entering ti_i2c_eeprom_am_get, check point 3.3
    
     Rio_Debug: Entering ti_i2c_eeprom_am_get, check point 4.
    
     Rio_Debug: Entering ti_i2c_eeprom_am_get, final check point.
    
     Rio: Passed early_system_init()
    
     Rio_Debug: scale_vcores
    
     Rio_Debug: gpi2c_init
    
     Rio_Debug: get_opp_offset
    
     Rio_Debug: get_dpll_mpu_params
    
     Rio_Debug: Entering board_ti_is.............................
    
     Rio_Debug: Entering board_ti_is : ep->name = AM43__SK
    
     Rio_Debug: Entering board_ti_is : name_tag= AM43_IDK
    
     Rio_Debug: Entering board_ti_is : TI_EEPROM_HDR_NAME_LEN= 8
    
     Rio_Debug: scale_vcores_generic, checking TPS6521X
    
     Rio_Debug: scale_vcores_generic, checking TPS6521X, 1000Mhz
    
     Rio_Debug: Entering board_ti_is.............................
    
     Rio_Debug: Entering board_ti_is : ep->name = AM43__SK
    
     Rio_Debug: Entering board_ti_is : name_tag= AM43EPOS
    
     Rio_Debug: Entering board_ti_is : TI_EEPROM_HDR_NAME_LEN= 8
    
     Rio_Debug: get_dpll_core_params
    
     Rio_Debug: get_opp_offset
    
     Rio_Debug: get_dpll_mpu_params
    
     Rio_Debug: Entering get_dpll_ddr_params........................
    
     Rio_Debug: Entering board_ti_is.............................
    
     Rio_Debug: Entering board_ti_is : ep->name = AM43__SK
    
     Rio_Debug: Entering board_ti_is : name_tag= AM43EPOS
    
     Rio_Debug: Entering board_ti_is : TI_EEPROM_HDR_NAME_LEN= 8
    
     Rio_Debug: Entering board_ti_is.............................
    
     Rio_Debug: Entering board_ti_is : ep->name = AM43__SK
    
     Rio_Debug: Entering board_ti_is : name_tag= AM43__GP
    
     Rio_Debug: Entering board_ti_is : TI_EEPROM_HDR_NAME_LEN= 8
    
     Rio_Debug: Entering board_ti_is.............................
    
     Rio_Debug: Entering board_ti_is : ep->name = AM43__SK
    
     Rio_Debug: Entering board_ti_is : name_tag= AM43XXHS
    
     Rio_Debug: Entering board_ti_is : TI_EEPROM_HDR_NAME_LEN= 8
    
     Rio_Debug: get_dpll_ddr_params with board_is_evm or board_is_sk
    
     Rio_Debug: Entering board_ti_is.............................
    
     Rio_Debug: Entering board_ti_is : ep->name = AM43__SK
    
     Rio_Debug: Entering board_ti_is : name_tag= AM43__GP
    
     Rio_Debug: Entering board_ti_is : TI_EEPROM_HDR_NAME_LEN= 8
    
     Rio_Debug: Entering board_ti_is.............................
    
     Rio_Debug: Entering board_ti_is : ep->name = AM43__SK
    
     Rio_Debug: Entering board_ti_is : name_tag= AM43XXHS
    
     Rio_Debug: Entering board_ti_is : TI_EEPROM_HDR_NAME_LEN= 8
    Error: NAND flash not present on this board
    
     Rio: Passed board_early_init_f()
    
     Rio_Debug: sdram_init
    
     Rio_Debug: Entering board_ti_is.............................
    
     Rio_Debug: Entering board_ti_is : ep->name = AM43__SK
    
     Rio_Debug: Entering board_ti_is : name_tag= AM43EPOS
    
     Rio_Debug: Entering board_ti_is : TI_EEPROM_HDR_NAME_LEN= 8
    
     Rio_Debug: Entering board_ti_is.............................
    
     Rio_Debug: Entering board_ti_is : ep->name = AM43__SK
    
     Rio_Debug: Entering board_ti_is : name_tag= AM43__GP
    
     Rio_Debug: Entering board_ti_is : TI_EEPROM_HDR_NAME_LEN= 8
    
     Rio_Debug: Entering board_ti_is.............................
    
     Rio_Debug: Entering board_ti_is : ep->name = AM43__SK
    
     Rio_Debug: Entering board_ti_is : name_tag= AM43XXHS
    
     Rio_Debug: Entering board_ti_is : TI_EEPROM_HDR_NAME_LEN= 8
    
     Rio_Debug: Entering board_ti_is.............................
    
     Rio_Debug: Entering board_ti_is : ep->name = AM43__SK
    
     Rio_Debug: Entering board_ti_is : name_tag= AM43__GP
    
     Rio_Debug: Entering board_ti_is : TI_EEPROM_HDR_NAME_LEN= 8
    
     Rio_Debug: Entering board_ti_is.............................
    
     Rio_Debug: Entering board_ti_is : ep->name = AM43__SK
    
     Rio_Debug: Entering board_ti_is : name_tag= AM43XXHS
    
     Rio_Debug: Entering board_ti_is : TI_EEPROM_HDR_NAME_LEN= 8
    
     Rio_Debug: Entering board_ti_is.............................
    
     Rio_Debug: Entering board_ti_is : ep->name = AM43__SK
    
     Rio_Debug: Entering board_ti_is : name_tag= AM43__GP
    
     Rio_Debug: Entering board_ti_is : TI_EEPROM_HDR_NAME_LEN= 8
    
     Rio_Debug: Entering board_ti_is.............................
    
     Rio_Debug: Entering board_ti_is : ep->name = AM43__SK
    
     Rio_Debug: Entering board_ti_is : name_tag= AM43XXHS
    
     Rio_Debug: Entering board_ti_is : TI_EEPROM_HDR_NAME_LEN= 8
    
     Rio_Debug: sdram_init,board_is_sk
    
     Rio: Passed sdram_init()
    
     Rio: now entering-get_ram_size, simplo am437 is using 512MB 536870912
    <debug_uart>
     Rio_Debug: gpi2c_init
    
     Rio_Debug: Entering ti_i2c_eeprom_am_get
    
     Rio_Debug: Entering ti_i2c_eeprom_am_get, check point 1.
    
     Rio_Debug: Entering ti_i2c_eeprom_get
    OF: ** translation for device i2c@44e0b000 **
    OF: bus is default (na=1, ns=1) on ocp
    OF: parent bus is default (na=1, ns=1) on
    OF: no ranges, 1:1 translation
    OF: with offset: 1155575808
    OF: reached root node
    
     Rio_Debug: Entering ti_i2c_eeprom_am_get, check point 2.
    
     Rio_Debug: Entering ti_i2c_eeprom_am_get -> ti_i2c_eeprom_get
    
     Rio_Debug: Entering ti_i2c_eeprom_am_get, check point 3.
    
     Rio_Debug: Entering ti_i2c_eeprom_am_get, check point 3.3
    
     Rio_Debug: Entering ti_i2c_eeprom_am_get, check point 4.
    
     Rio_Debug: Entering ti_i2c_eeprom_am_get, final check point.
    
     Rio: Passed early_system_init()
    
     Rio_Debug: scale_vcores
    
     Rio_Debug: gpi2c_init
    
     Rio_Debug: get_opp_offset
    
     Rio_Debug: get_dpll_mpu_params
    
     Rio_Debug: Entering board_ti_is.............................
    
     Rio_Debug: Entering board_ti_is : ep->name = AM43__SK
    
     Rio_Debug: Entering board_ti_is : name_tag= AM43_IDK
    
     Rio_Debug: Entering board_ti_is : TI_EEPROM_HDR_NAME_LEN= 8
    
     Rio_Debug: scale_vcores_generic, checking TPS6521X
    
     Rio_Debug: scale_vcores_generic, checking TPS6521X, 1000Mhz
    
     Rio_Debug: Entering board_ti_is.............................
    
     Rio_Debug: Entering board_ti_is : ep->name = AM43__SK
    
     Rio_Debug: Entering board_ti_is : name_tag= AM43EPOS
    
     Rio_Debug: Entering board_ti_is : TI_EEPROM_HDR_NAME_LEN= 8
    
     Rio_Debug: get_dpll_core_params
    
     Rio_Debug: get_opp_offset
    
     Rio_Debug: get_dpll_mpu_params
    
     Rio_Debug: Entering get_dpll_ddr_params........................
    
     Rio_Debug: Entering board_ti_is.............................
    
     Rio_Debug: Entering board_ti_is : ep->name = AM43__SK
    
     Rio_Debug: Entering board_ti_is : name_tag= AM43EPOS
    
     Rio_Debug: Entering board_ti_is : TI_EEPROM_HDR_NAME_LEN= 8
    
     Rio_Debug: Entering board_ti_is.............................
    
     Rio_Debug: Entering board_ti_is : ep->name = AM43__SK
    
     Rio_Debug: Entering board_ti_is : name_tag= AM43__GP
    
     Rio_Debug: Entering board_ti_is : TI_EEPROM_HDR_NAME_LEN= 8
    
     Rio_Debug: Entering board_ti_is.............................
    
     Rio_Debug: Entering board_ti_is : ep->name = AM43__SK
    
     Rio_Debug: Entering board_ti_is : name_tag= AM43XXHS
    
     Rio_Debug: Entering board_ti_is : TI_EEPROM_HDR_NAME_LEN= 8
    
     Rio_Debug: get_dpll_ddr_params with board_is_evm or board_is_sk
    
     Rio_Debug: Entering board_ti_is.............................
    
     Rio_Debug: Entering board_ti_is : ep->name = AM43__SK
    
     Rio_Debug: Entering board_ti_is : name_tag= AM43__GP
    
     Rio_Debug: Entering board_ti_is : TI_EEPROM_HDR_NAME_LEN= 8
    
     Rio_Debug: Entering board_ti_is.............................
    
     Rio_Debug: Entering board_ti_is : ep->name = AM43__SK
    
     Rio_Debug: Entering board_ti_is : name_tag= AM43XXHS
    
     Rio_Debug: Entering board_ti_is : TI_EEPROM_HDR_NAME_LEN= 8
    Error: NAND flash not present on this board
    
     Rio: Passed board_early_init_f()
    
     Rio_Debug: sdram_init
    
     Rio_Debug: Entering board_ti_is.............................
    
     Rio_Debug: Entering board_ti_is : ep->name = AM43__SK
    
     Rio_Debug: Entering board_ti_is : name_tag= AM43EPOS
    
     Rio_Debug: Entering board_ti_is : TI_EEPROM_HDR_NAME_LEN= 8
    
     Rio_Debug: Entering board_ti_is.............................
    
     Rio_Debug: Entering board_ti_is : ep->name = AM43__SK
    
     Rio_Debug: Entering board_ti_is : name_tag= AM43__GP
    
     Rio_Debug: Entering board_ti_is : TI_EEPROM_HDR_NAME_LEN= 8
    
     Rio_Debug: Entering board_ti_is.............................
    
     Rio_Debug: Entering board_ti_is : ep->name = AM43__SK
    
     Rio_Debug: Entering board_ti_is : name_tag= AM43XXHS
    
     Rio_Debug: Entering board_ti_is : TI_EEPROM_HDR_NAME_LEN= 8
    
     Rio_Debug: Entering board_ti_is.............................
    
     Rio_Debug: Entering board_ti_is : ep->name = AM43__SK
    
     Rio_Debug: Entering board_ti_is : name_tag= AM43__GP
    
     Rio_Debug: Entering board_ti_is : TI_EEPROM_HDR_NAME_LEN= 8
    
     Rio_Debug: Entering board_ti_is.............................
    
     Rio_Debug: Entering board_ti_is : ep->name = AM43__SK
    
     Rio_Debug: Entering board_ti_is : name_tag= AM43XXHS
    
     Rio_Debug: Entering board_ti_is : TI_EEPROM_HDR_NAME_LEN= 8
    
     Rio_Debug: Entering board_ti_is.............................
    
     Rio_Debug: Entering board_ti_is : ep->name = AM43__SK
    
     Rio_Debug: Entering board_ti_is : name_tag= AM43__GP
    
     Rio_Debug: Entering board_ti_is : TI_EEPROM_HDR_NAME_LEN= 8
    
     Rio_Debug: Entering board_ti_is.............................
    
     Rio_Debug: Entering board_ti_is : ep->name = AM43__SK
    
     Rio_Debug: Entering board_ti_is : name_tag= AM43XXHS
    
     Rio_Debug: Entering board_ti_is : TI_EEPROM_HDR_NAME_LEN= 8
    
     Rio_Debug: sdram_init,board_is_sk
    DDR3 H/W leveling incomplete with errors
    
     Rio: Passed sdram_init()
    
     Rio: now entering-get_ram_size, simplo am437 is using 512MB 536870912
    
    
    am43xx-ddr-analysis_2020-09-01_151022.txt
    CONTROL: device_id = 0x2b98c02f
      * AM43xx family
      * Silicon Revision 1.2
    
    CONTROL: control_status = 0x02400338
      * Bit 26 (SYSBOOT18=0): Do not route EXTCLK to CLKOUT2
      * Bits 23:22 (SYSBOOT15:14=1): 24 MHz
    
    CM_CLKSEL_DPLL_DDR = 0x00003202
      * DPLL_MULT = 50 (x50)
      * DPLL_DIV = 2 (/3)
    
    CM_DIV_M2_DPLL_DDR = 0x00000221
      * CLKST = 1: M2 output clock enabled
      * DIVHS = 1 (/1)
    
    CM_DIV_M4_DPLL_DDR = 0x00000222
      * CLKST = 1: M4 output clock enabled
      * DIVHS = 2 (/2)
    
    DPLL_DDR Summary
     -> F_input = 24 MHz
     -> CLKOUT_M2 = DDR_PLL_CLKOUT = 400 MHz
     -> CLKOUT_M4 = DLL_CLKOUT = 400 MHz
    
    EMIF: SDRAM_CONFIG = 0x61a00ab2
      * SDRAM_TYPE = DDR3
      * Bits 26:24 (reg_ddr_term) set for RZQ/4 (001b)
      * Bits 19:18 (reg_sdram_drive) set for RZQ/6 (00b)
      * Bits 17:16 (cwl) set for 5 (00b)
      * NARROW_MODE=0 (32-bit wide)
      * Bits 13:10 (CL) set for 5
      * Bits 9:7 (ROWSIZE) set for 14 row bits
      * Bits 6:4 (IBANK) set for 8 banks
      * Bit 3 (EBANK) set for 1 chip select (CS0)
      * Bits 3:0 (PAGESIZE) set for 10 column bits
    
    EMIF: PWR_MGMT_CTRL = 0x000000a0
    
    DDR PHY: DDR_PHY_CTRL_1 = 0x00048008
      * PHY_INVERT_CLKOUT=1.
      * READ_LAT=8, (corresponds correctly with CL and PHY_INVERT_CLKOUT)
    
    DDR PHY: EXT_PHY_CTRL_1 = 0x00040100
    
    DDR PHY: EXT_PHY_CTRL_36 = 0x00000177
      * Configured as recommended.
    
    CTRL_DDR_ADDRCTRL_IOCTRL = 0x00000084
      * Bits 9:5 control ddr_ck and ddr_ckn
        - Slew fastest
        - Drive Strength 9 mA
      * Bits 4:0 control all other address/control pins
        - Slew fastest
        - Drive Strength 9 mA
    
    CTRL_DDR_ADDRCTRL_WD0_IOCTRL = 0x00000000
    CTRL_DDR_ADDRCTRL_WD1_IOCTRL = 0x00000000
      * [ddr_a0    ] Pullup/Pulldown disabled
      * [ddr_a1    ] Pullup/Pulldown disabled
      * [ddr_a2    ] Pullup/Pulldown disabled
      * [ddr_a3    ] Pullup/Pulldown disabled
      * [ddr_a4    ] Pullup/Pulldown disabled
      * [ddr_a5    ] Pullup/Pulldown disabled
      * [ddr_a6    ] Pullup/Pulldown disabled
      * [ddr_a7    ] Pullup/Pulldown disabled
      * [ddr_a8    ] Pullup/Pulldown disabled
      * [ddr_a9    ] Pullup/Pulldown disabled
      * [ddr_a10   ] Pullup/Pulldown disabled
      * [ddr_a11   ] Pullup/Pulldown disabled
      * [ddr_a12   ] Pullup/Pulldown disabled
      * [ddr_a13   ] Pullup/Pulldown disabled
      * [ddr_a14   ] Pullup/Pulldown disabled
      * [ddr_a15   ] Pullup/Pulldown disabled
      * [ddr_ba2   ] Pullup/Pulldown disabled
      * [ddr_ba1   ] Pullup/Pulldown disabled
      * [ddr_ba0   ] Pullup/Pulldown disabled
      * [ddr_wen   ] Pullup/Pulldown disabled
      * [ddr_rasn  ] Pullup/Pulldown disabled
      * [ddr_casn  ] Pullup/Pulldown disabled
      * [ddr_nck   ] Pullup/Pulldown disabled
      * [ddr_ck    ] Pullup/Pulldown disabled
      * [ddr_cke   ] Pullup/Pulldown disabled
      * [ddr_csn1  ] Pullup/Pulldown disabled
      * [ddr_csn0  ] Pullup/Pulldown disabled
      * [ddr_resetn] Pullup/Pulldown disabled
      * [ddr_odt1  ] Pullup/Pulldown disabled
      * [ddr_odt0  ] Pullup/Pulldown disabled
    
    CTRL_DDR_DATA0_IOCTRL = 0x00000084
      * ddr_d0 Pullup/Pulldown disabled
      * ddr_d1 Pullup/Pulldown disabled
      * ddr_d2 Pullup/Pulldown disabled
      * ddr_d3 Pullup/Pulldown disabled
      * ddr_d4 Pullup/Pulldown disabled
      * ddr_d5 Pullup/Pulldown disabled
      * ddr_d6 Pullup/Pulldown disabled
      * ddr_d7 Pullup/Pulldown disabled
      * ddr_dqm0 Pullup/Pulldown disabled
      * ddr_dqs0 and ddr_dqsn0 Pullup/Pulldown disabled
      * Bits 9:5 control ddr_dqs0, ddr_dqsn0
        - Slew fastest
        - Drive Strength 9 mA
      * Bits 4:0 control ddr_d[7:0], dqm0
        - Slew fastest
        - Drive Strength 9 mA
    
    CTRL_DDR_DATA1_IOCTRL = 0x00000084
      * ddr_d8 Pullup/Pulldown disabled
      * ddr_d9 Pullup/Pulldown disabled
      * ddr_d10 Pullup/Pulldown disabled
      * ddr_d11 Pullup/Pulldown disabled
      * ddr_d12 Pullup/Pulldown disabled
      * ddr_d13 Pullup/Pulldown disabled
      * ddr_d14 Pullup/Pulldown disabled
      * ddr_d15 Pullup/Pulldown disabled
      * ddr_dqm1 Pullup/Pulldown disabled
      * ddr_dqs1 and ddr_dqsn1 Pullup/Pulldown disabled
      * Bits 9:5 control ddr_dqs1, ddr_dqsn1
        - Slew fastest
        - Drive Strength 9 mA
      * Bits 4:0 control ddr_d[15:8], ddr_dqm1
        - Slew fastest
        - Drive Strength 9 mA
    
    CTRL_DDR_DATA2_IOCTRL = 0x00000084
      * ddr_d16 Pullup/Pulldown disabled
      * ddr_d17 Pullup/Pulldown disabled
      * ddr_d18 Pullup/Pulldown disabled
      * ddr_d19 Pullup/Pulldown disabled
      * ddr_d20 Pullup/Pulldown disabled
      * ddr_d21 Pullup/Pulldown disabled
      * ddr_d22 Pullup/Pulldown disabled
      * ddr_d23 Pullup/Pulldown disabled
      * ddr_dqm2 Pullup/Pulldown disabled
      * ddr_dqs2 and ddr_dqsn2 Pullup/Pulldown disabled
      * Bits 9:5 control ddr_dqs2, ddr_dqsn2
        - Slew fastest
        - Drive Strength 9 mA
      * Bits 4:0 control ddr_d[23:16], ddr_dqm2
        - Slew fastest
        - Drive Strength 9 mA
    
    CTRL_DDR_DATA3_IOCTRL = 0x00000084
      * ddr_d24 Pullup/Pulldown disabled
      * ddr_d25 Pullup/Pulldown disabled
      * ddr_d26 Pullup/Pulldown disabled
      * ddr_d27 Pullup/Pulldown disabled
      * ddr_d28 Pullup/Pulldown disabled
      * ddr_d29 Pullup/Pulldown disabled
      * ddr_d30 Pullup/Pulldown disabled
      * ddr_d31 Pullup/Pulldown disabled
      * ddr_dqm3 Pullup/Pulldown disabled
      * ddr_dqs3 and ddr_dqsn3 Pullup/Pulldown disabled
      * Bits 9:5 control ddr_dqs3, ddr_dqsn3
        - Slew fastest
        - Drive Strength 9 mA
      * Bits 4:0 control ddr_d[31:24], ddr_dqm3
        - Slew fastest
        - Drive Strength 9 mA
    
    CONTROL: CTRL_DDR_IO = 0x00000000
      * Bit 31: DDR_RESETn controlled by EMIF.
    
    CONTROL: CTRL_VTP = 0x00010167
      * VTP not disabled (expected in normal operation, but not DS0).
    
    CONTROL: CTRL_VREF = 0x00000000
      * VREF supplied externally (typical).
    
    CONTROL: CTRL_DDR_CKE = 0x0000000f
      * CKE0 controlled by EMIF (normal/ungated operation).
      * CKE1 controlled by EMIF (normal/ungated operation).
    
    CONTROL: CTRL_EMIF_SDRAM_CONFIG_EXT = 0x0000c163
      * Bit  17:    NARROW_ONLY = 0
      * Bits 15:14: phy_num_of_samples = 3 -> 128 samples, full leveling
      * Bit  13:    phy_sel_logic = 0 (Recommended)
      * Bit  12:    phy_all_dq_mpr_rd_resp = 0
      * Bits 11:09: phy_output_sts_select = 0
      * Bit   8:    dynamic_pwrdn_en = 1
      * Bits 06:05: phy_rd_local_odt = 3, Half Thevenin load
      * Bit   3:    dfi_clock_phase_ctrl = 0
      * Bit   1:    en_slice_1 = 1 (CMD PHY1)
      * Bit   0:    en_slice_0 = 1 (CMD PHY0)
    

    #2. Regarding your question in the off-line mail.

    Can we get my previous question answered. I asked for this based on you post on e2e “However, if we used the SDK2.0 (2015 version) , the console shows something,”

    1. Is the exact same DDR memory used in the customer’s previous board? (Rio: Yes.)

    a)      If yes, start with the working DDR parameters, and check if any discrepancy.

    b)      If not, EMIF tool can be used to generate the consolidated lists of DDR parameters such as EMIF Registers, DDR PHY registers, IO Control Registers.

            (Rio: As the attached DSS dumps, please review.

    Thank you very much.

    BR Rio

  • Hi Rio, 

    I had a quick review of your attached log file, and the boot flow seems ok.

    Since the boot log stops right after get_ram_size() call, it is worth to check EMIF registers configuration: 

    Rio Chan said:

    Is the exact same DDR memory used in the customer’s previous board? (Rio: Yes.)

    #1. I would recommend to use the working EMIF registers configurations on customer’s previous board as a reference, and compare it with the one captured on the new board with the newer SDK.

    EMIF configuration related registers to be compared includes EMIF registers, DDR PHY CTRL registers, IO Control registers, as calculated in Tab #6 Registers in AM437x EMIF tool xls sheet.

    #2. Alternatively, we can check DDR with JTAG. Add a spin loop in early SPL, connect JTAG to running board via JTAG “attach” (i.e. no intrusive operations from JTAG), break out the spin loop, and then break just after sdam_init(), where running ddr memory check to see if it is ok to peek/poke ddr memory successfully.

    In fact, for debugging board bring-up issue, JTAG would be useful to navigate through code flow, and save time comparing to adding printf’s. 

    Best,

    -Hong

  • Hi Hong:

    I have deeper looking into this issue.

    please see my attached:

    #1. I have narrowed down the DDR issue into those 2 C Files zip, board.c / ddr.c

    #2. I have tested my SDcard with those modification on TI AM437 SKEVM and the customer's PCB.

    #3. You can see the DSS output are the same, but if you compare the console logs.

          You will find the Customer Console logs showing the "DDR HW Leveling incomplete".

          With the same SDcard tested on the TI SK EVM, it shows "DDR HW Leveling completed"

    I know those 2 HWs having different size DDR, but my point is: TI SK EVM can finish the HW Leveling, but customer's PCB cannot.

    Can I say the Customer DDR HW Design has the issue that we cannot solve by SW?

    Can I say this firmly?

    please comment, thanks.

    BR Rio

    For_Hong.7z