xref: /rk3399_rockchip-uboot/board/ti/am335x/board.c (revision 94d77fb656d49f2b0efe2de5605a52c5145d2c3b)
1e363426eSPeter Korsgaard /*
2e363426eSPeter Korsgaard  * board.c
3e363426eSPeter Korsgaard  *
4e363426eSPeter Korsgaard  * Board functions for TI AM335X based boards
5e363426eSPeter Korsgaard  *
6e363426eSPeter Korsgaard  * Copyright (C) 2011, Texas Instruments, Incorporated - http://www.ti.com/
7e363426eSPeter Korsgaard  *
81a459660SWolfgang Denk  * SPDX-License-Identifier:	GPL-2.0+
9e363426eSPeter Korsgaard  */
10e363426eSPeter Korsgaard 
11e363426eSPeter Korsgaard #include <common.h>
12e363426eSPeter Korsgaard #include <errno.h>
13e363426eSPeter Korsgaard #include <spl.h>
14e363426eSPeter Korsgaard #include <asm/arch/cpu.h>
15e363426eSPeter Korsgaard #include <asm/arch/hardware.h>
16e363426eSPeter Korsgaard #include <asm/arch/omap.h>
17e363426eSPeter Korsgaard #include <asm/arch/ddr_defs.h>
18e363426eSPeter Korsgaard #include <asm/arch/clock.h>
19e363426eSPeter Korsgaard #include <asm/arch/gpio.h>
20e363426eSPeter Korsgaard #include <asm/arch/mmc_host_def.h>
21e363426eSPeter Korsgaard #include <asm/arch/sys_proto.h>
22cd8845d7SSteve Kipisz #include <asm/arch/mem.h>
23e363426eSPeter Korsgaard #include <asm/io.h>
24e363426eSPeter Korsgaard #include <asm/emif.h>
25e363426eSPeter Korsgaard #include <asm/gpio.h>
26e363426eSPeter Korsgaard #include <i2c.h>
27e363426eSPeter Korsgaard #include <miiphy.h>
28e363426eSPeter Korsgaard #include <cpsw.h>
29e363426eSPeter Korsgaard #include "board.h"
30e363426eSPeter Korsgaard 
31e363426eSPeter Korsgaard DECLARE_GLOBAL_DATA_PTR;
32e363426eSPeter Korsgaard 
33e363426eSPeter Korsgaard static struct wd_timer *wdtimer = (struct wd_timer *)WDT_BASE;
34e363426eSPeter Korsgaard 
35e363426eSPeter Korsgaard /* MII mode defines */
36e363426eSPeter Korsgaard #define MII_MODE_ENABLE		0x0
37cfd4ff6fSYegor Yefremov #define RGMII_MODE_ENABLE	0x3A
38e363426eSPeter Korsgaard 
39e363426eSPeter Korsgaard /* GPIO that controls power to DDR on EVM-SK */
40e363426eSPeter Korsgaard #define GPIO_DDR_VTT_EN		7
41e363426eSPeter Korsgaard 
42e363426eSPeter Korsgaard static struct ctrl_dev *cdev = (struct ctrl_dev *)CTRL_DEVICE_BASE;
43e363426eSPeter Korsgaard 
44e363426eSPeter Korsgaard /*
45e363426eSPeter Korsgaard  * Read header information from EEPROM into global structure.
46e363426eSPeter Korsgaard  */
47ace4275eSTom Rini static int read_eeprom(struct am335x_baseboard_id *header)
48e363426eSPeter Korsgaard {
49e363426eSPeter Korsgaard 	/* Check if baseboard eeprom is available */
50e363426eSPeter Korsgaard 	if (i2c_probe(CONFIG_SYS_I2C_EEPROM_ADDR)) {
51e363426eSPeter Korsgaard 		puts("Could not probe the EEPROM; something fundamentally "
52e363426eSPeter Korsgaard 			"wrong on the I2C bus.\n");
53e363426eSPeter Korsgaard 		return -ENODEV;
54e363426eSPeter Korsgaard 	}
55e363426eSPeter Korsgaard 
56e363426eSPeter Korsgaard 	/* read the eeprom using i2c */
57ace4275eSTom Rini 	if (i2c_read(CONFIG_SYS_I2C_EEPROM_ADDR, 0, 2, (uchar *)header,
58ace4275eSTom Rini 		     sizeof(struct am335x_baseboard_id))) {
59e363426eSPeter Korsgaard 		puts("Could not read the EEPROM; something fundamentally"
60e363426eSPeter Korsgaard 			" wrong on the I2C bus.\n");
61e363426eSPeter Korsgaard 		return -EIO;
62e363426eSPeter Korsgaard 	}
63e363426eSPeter Korsgaard 
64ace4275eSTom Rini 	if (header->magic != 0xEE3355AA) {
65e363426eSPeter Korsgaard 		/*
66e363426eSPeter Korsgaard 		 * read the eeprom using i2c again,
67e363426eSPeter Korsgaard 		 * but use only a 1 byte address
68e363426eSPeter Korsgaard 		 */
69ace4275eSTom Rini 		if (i2c_read(CONFIG_SYS_I2C_EEPROM_ADDR, 0, 1, (uchar *)header,
70ace4275eSTom Rini 			     sizeof(struct am335x_baseboard_id))) {
71e363426eSPeter Korsgaard 			puts("Could not read the EEPROM; something "
72e363426eSPeter Korsgaard 				"fundamentally wrong on the I2C bus.\n");
73e363426eSPeter Korsgaard 			return -EIO;
74e363426eSPeter Korsgaard 		}
75e363426eSPeter Korsgaard 
76ace4275eSTom Rini 		if (header->magic != 0xEE3355AA) {
77e363426eSPeter Korsgaard 			printf("Incorrect magic number (0x%x) in EEPROM\n",
78ace4275eSTom Rini 					header->magic);
79e363426eSPeter Korsgaard 			return -EINVAL;
80e363426eSPeter Korsgaard 		}
81e363426eSPeter Korsgaard 	}
82e363426eSPeter Korsgaard 
83e363426eSPeter Korsgaard 	return 0;
84e363426eSPeter Korsgaard }
85e363426eSPeter Korsgaard 
86c5c7a7c3SSteve Kipisz #if defined(CONFIG_SPL_BUILD) || defined(CONFIG_NOR_BOOT)
87c00f69dbSPeter Korsgaard static const struct ddr_data ddr2_data = {
88c7d35befSPeter Korsgaard 	.datardsratio0 = ((MT47H128M16RT25E_RD_DQS<<30) |
89c7d35befSPeter Korsgaard 			  (MT47H128M16RT25E_RD_DQS<<20) |
90c7d35befSPeter Korsgaard 			  (MT47H128M16RT25E_RD_DQS<<10) |
91c7d35befSPeter Korsgaard 			  (MT47H128M16RT25E_RD_DQS<<0)),
92c7d35befSPeter Korsgaard 	.datawdsratio0 = ((MT47H128M16RT25E_WR_DQS<<30) |
93c7d35befSPeter Korsgaard 			  (MT47H128M16RT25E_WR_DQS<<20) |
94c7d35befSPeter Korsgaard 			  (MT47H128M16RT25E_WR_DQS<<10) |
95c7d35befSPeter Korsgaard 			  (MT47H128M16RT25E_WR_DQS<<0)),
96c7d35befSPeter Korsgaard 	.datawiratio0 = ((MT47H128M16RT25E_PHY_WRLVL<<30) |
97c7d35befSPeter Korsgaard 			 (MT47H128M16RT25E_PHY_WRLVL<<20) |
98c7d35befSPeter Korsgaard 			 (MT47H128M16RT25E_PHY_WRLVL<<10) |
99c7d35befSPeter Korsgaard 			 (MT47H128M16RT25E_PHY_WRLVL<<0)),
100c7d35befSPeter Korsgaard 	.datagiratio0 = ((MT47H128M16RT25E_PHY_GATELVL<<30) |
101c7d35befSPeter Korsgaard 			 (MT47H128M16RT25E_PHY_GATELVL<<20) |
102c7d35befSPeter Korsgaard 			 (MT47H128M16RT25E_PHY_GATELVL<<10) |
103c7d35befSPeter Korsgaard 			 (MT47H128M16RT25E_PHY_GATELVL<<0)),
104c7d35befSPeter Korsgaard 	.datafwsratio0 = ((MT47H128M16RT25E_PHY_FIFO_WE<<30) |
105c7d35befSPeter Korsgaard 			  (MT47H128M16RT25E_PHY_FIFO_WE<<20) |
106c7d35befSPeter Korsgaard 			  (MT47H128M16RT25E_PHY_FIFO_WE<<10) |
107c7d35befSPeter Korsgaard 			  (MT47H128M16RT25E_PHY_FIFO_WE<<0)),
108c7d35befSPeter Korsgaard 	.datawrsratio0 = ((MT47H128M16RT25E_PHY_WR_DATA<<30) |
109c7d35befSPeter Korsgaard 			  (MT47H128M16RT25E_PHY_WR_DATA<<20) |
110c7d35befSPeter Korsgaard 			  (MT47H128M16RT25E_PHY_WR_DATA<<10) |
111c7d35befSPeter Korsgaard 			  (MT47H128M16RT25E_PHY_WR_DATA<<0)),
112c7d35befSPeter Korsgaard 	.datauserank0delay = MT47H128M16RT25E_PHY_RANK0_DELAY,
113c00f69dbSPeter Korsgaard 	.datadldiff0 = PHY_DLL_LOCK_DIFF,
114c00f69dbSPeter Korsgaard };
115c00f69dbSPeter Korsgaard 
116c00f69dbSPeter Korsgaard static const struct cmd_control ddr2_cmd_ctrl_data = {
117c7d35befSPeter Korsgaard 	.cmd0csratio = MT47H128M16RT25E_RATIO,
118c7d35befSPeter Korsgaard 	.cmd0dldiff = MT47H128M16RT25E_DLL_LOCK_DIFF,
119c7d35befSPeter Korsgaard 	.cmd0iclkout = MT47H128M16RT25E_INVERT_CLKOUT,
120c00f69dbSPeter Korsgaard 
121c7d35befSPeter Korsgaard 	.cmd1csratio = MT47H128M16RT25E_RATIO,
122c7d35befSPeter Korsgaard 	.cmd1dldiff = MT47H128M16RT25E_DLL_LOCK_DIFF,
123c7d35befSPeter Korsgaard 	.cmd1iclkout = MT47H128M16RT25E_INVERT_CLKOUT,
124c00f69dbSPeter Korsgaard 
125c7d35befSPeter Korsgaard 	.cmd2csratio = MT47H128M16RT25E_RATIO,
126c7d35befSPeter Korsgaard 	.cmd2dldiff = MT47H128M16RT25E_DLL_LOCK_DIFF,
127c7d35befSPeter Korsgaard 	.cmd2iclkout = MT47H128M16RT25E_INVERT_CLKOUT,
128c00f69dbSPeter Korsgaard };
129c00f69dbSPeter Korsgaard 
130c00f69dbSPeter Korsgaard static const struct emif_regs ddr2_emif_reg_data = {
131c7d35befSPeter Korsgaard 	.sdram_config = MT47H128M16RT25E_EMIF_SDCFG,
132c7d35befSPeter Korsgaard 	.ref_ctrl = MT47H128M16RT25E_EMIF_SDREF,
133c7d35befSPeter Korsgaard 	.sdram_tim1 = MT47H128M16RT25E_EMIF_TIM1,
134c7d35befSPeter Korsgaard 	.sdram_tim2 = MT47H128M16RT25E_EMIF_TIM2,
135c7d35befSPeter Korsgaard 	.sdram_tim3 = MT47H128M16RT25E_EMIF_TIM3,
136c7d35befSPeter Korsgaard 	.emif_ddr_phy_ctlr_1 = MT47H128M16RT25E_EMIF_READ_LATENCY,
137c00f69dbSPeter Korsgaard };
138c00f69dbSPeter Korsgaard 
139c00f69dbSPeter Korsgaard static const struct ddr_data ddr3_data = {
140c7d35befSPeter Korsgaard 	.datardsratio0 = MT41J128MJT125_RD_DQS,
141c7d35befSPeter Korsgaard 	.datawdsratio0 = MT41J128MJT125_WR_DQS,
142c7d35befSPeter Korsgaard 	.datafwsratio0 = MT41J128MJT125_PHY_FIFO_WE,
143c7d35befSPeter Korsgaard 	.datawrsratio0 = MT41J128MJT125_PHY_WR_DATA,
144c00f69dbSPeter Korsgaard 	.datadldiff0 = PHY_DLL_LOCK_DIFF,
145c00f69dbSPeter Korsgaard };
146c00f69dbSPeter Korsgaard 
147c7ba18adSTom Rini static const struct ddr_data ddr3_beagleblack_data = {
148c7ba18adSTom Rini 	.datardsratio0 = MT41K256M16HA125E_RD_DQS,
149c7ba18adSTom Rini 	.datawdsratio0 = MT41K256M16HA125E_WR_DQS,
150c7ba18adSTom Rini 	.datafwsratio0 = MT41K256M16HA125E_PHY_FIFO_WE,
151c7ba18adSTom Rini 	.datawrsratio0 = MT41K256M16HA125E_PHY_WR_DATA,
152c7ba18adSTom Rini 	.datadldiff0 = PHY_DLL_LOCK_DIFF,
153c7ba18adSTom Rini };
154c7ba18adSTom Rini 
15513526f71SJeff Lance static const struct ddr_data ddr3_evm_data = {
15613526f71SJeff Lance 	.datardsratio0 = MT41J512M8RH125_RD_DQS,
15713526f71SJeff Lance 	.datawdsratio0 = MT41J512M8RH125_WR_DQS,
15813526f71SJeff Lance 	.datafwsratio0 = MT41J512M8RH125_PHY_FIFO_WE,
15913526f71SJeff Lance 	.datawrsratio0 = MT41J512M8RH125_PHY_WR_DATA,
16013526f71SJeff Lance 	.datadldiff0 = PHY_DLL_LOCK_DIFF,
16113526f71SJeff Lance };
16213526f71SJeff Lance 
163c00f69dbSPeter Korsgaard static const struct cmd_control ddr3_cmd_ctrl_data = {
164c7d35befSPeter Korsgaard 	.cmd0csratio = MT41J128MJT125_RATIO,
165c7d35befSPeter Korsgaard 	.cmd0dldiff = MT41J128MJT125_DLL_LOCK_DIFF,
166c7d35befSPeter Korsgaard 	.cmd0iclkout = MT41J128MJT125_INVERT_CLKOUT,
167c00f69dbSPeter Korsgaard 
168c7d35befSPeter Korsgaard 	.cmd1csratio = MT41J128MJT125_RATIO,
169c7d35befSPeter Korsgaard 	.cmd1dldiff = MT41J128MJT125_DLL_LOCK_DIFF,
170c7d35befSPeter Korsgaard 	.cmd1iclkout = MT41J128MJT125_INVERT_CLKOUT,
171c00f69dbSPeter Korsgaard 
172c7d35befSPeter Korsgaard 	.cmd2csratio = MT41J128MJT125_RATIO,
173c7d35befSPeter Korsgaard 	.cmd2dldiff = MT41J128MJT125_DLL_LOCK_DIFF,
174c7d35befSPeter Korsgaard 	.cmd2iclkout = MT41J128MJT125_INVERT_CLKOUT,
175c00f69dbSPeter Korsgaard };
176c00f69dbSPeter Korsgaard 
177c7ba18adSTom Rini static const struct cmd_control ddr3_beagleblack_cmd_ctrl_data = {
178c7ba18adSTom Rini 	.cmd0csratio = MT41K256M16HA125E_RATIO,
179c7ba18adSTom Rini 	.cmd0dldiff = MT41K256M16HA125E_DLL_LOCK_DIFF,
180c7ba18adSTom Rini 	.cmd0iclkout = MT41K256M16HA125E_INVERT_CLKOUT,
181c7ba18adSTom Rini 
182c7ba18adSTom Rini 	.cmd1csratio = MT41K256M16HA125E_RATIO,
183c7ba18adSTom Rini 	.cmd1dldiff = MT41K256M16HA125E_DLL_LOCK_DIFF,
184c7ba18adSTom Rini 	.cmd1iclkout = MT41K256M16HA125E_INVERT_CLKOUT,
185c7ba18adSTom Rini 
186c7ba18adSTom Rini 	.cmd2csratio = MT41K256M16HA125E_RATIO,
187c7ba18adSTom Rini 	.cmd2dldiff = MT41K256M16HA125E_DLL_LOCK_DIFF,
188c7ba18adSTom Rini 	.cmd2iclkout = MT41K256M16HA125E_INVERT_CLKOUT,
189c7ba18adSTom Rini };
190c7ba18adSTom Rini 
19113526f71SJeff Lance static const struct cmd_control ddr3_evm_cmd_ctrl_data = {
19213526f71SJeff Lance 	.cmd0csratio = MT41J512M8RH125_RATIO,
19313526f71SJeff Lance 	.cmd0dldiff = MT41J512M8RH125_DLL_LOCK_DIFF,
19413526f71SJeff Lance 	.cmd0iclkout = MT41J512M8RH125_INVERT_CLKOUT,
19513526f71SJeff Lance 
19613526f71SJeff Lance 	.cmd1csratio = MT41J512M8RH125_RATIO,
19713526f71SJeff Lance 	.cmd1dldiff = MT41J512M8RH125_DLL_LOCK_DIFF,
19813526f71SJeff Lance 	.cmd1iclkout = MT41J512M8RH125_INVERT_CLKOUT,
19913526f71SJeff Lance 
20013526f71SJeff Lance 	.cmd2csratio = MT41J512M8RH125_RATIO,
20113526f71SJeff Lance 	.cmd2dldiff = MT41J512M8RH125_DLL_LOCK_DIFF,
20213526f71SJeff Lance 	.cmd2iclkout = MT41J512M8RH125_INVERT_CLKOUT,
20313526f71SJeff Lance };
20413526f71SJeff Lance 
205c00f69dbSPeter Korsgaard static struct emif_regs ddr3_emif_reg_data = {
206c7d35befSPeter Korsgaard 	.sdram_config = MT41J128MJT125_EMIF_SDCFG,
207c7d35befSPeter Korsgaard 	.ref_ctrl = MT41J128MJT125_EMIF_SDREF,
208c7d35befSPeter Korsgaard 	.sdram_tim1 = MT41J128MJT125_EMIF_TIM1,
209c7d35befSPeter Korsgaard 	.sdram_tim2 = MT41J128MJT125_EMIF_TIM2,
210c7d35befSPeter Korsgaard 	.sdram_tim3 = MT41J128MJT125_EMIF_TIM3,
211c7d35befSPeter Korsgaard 	.zq_config = MT41J128MJT125_ZQ_CFG,
21259dcf970SVaibhav Hiremath 	.emif_ddr_phy_ctlr_1 = MT41J128MJT125_EMIF_READ_LATENCY |
21359dcf970SVaibhav Hiremath 				PHY_EN_DYN_PWRDN,
214c00f69dbSPeter Korsgaard };
21513526f71SJeff Lance 
216c7ba18adSTom Rini static struct emif_regs ddr3_beagleblack_emif_reg_data = {
217c7ba18adSTom Rini 	.sdram_config = MT41K256M16HA125E_EMIF_SDCFG,
218c7ba18adSTom Rini 	.ref_ctrl = MT41K256M16HA125E_EMIF_SDREF,
219c7ba18adSTom Rini 	.sdram_tim1 = MT41K256M16HA125E_EMIF_TIM1,
220c7ba18adSTom Rini 	.sdram_tim2 = MT41K256M16HA125E_EMIF_TIM2,
221c7ba18adSTom Rini 	.sdram_tim3 = MT41K256M16HA125E_EMIF_TIM3,
222c7ba18adSTom Rini 	.zq_config = MT41K256M16HA125E_ZQ_CFG,
223c7ba18adSTom Rini 	.emif_ddr_phy_ctlr_1 = MT41K256M16HA125E_EMIF_READ_LATENCY,
224c7ba18adSTom Rini };
225c7ba18adSTom Rini 
22613526f71SJeff Lance static struct emif_regs ddr3_evm_emif_reg_data = {
22713526f71SJeff Lance 	.sdram_config = MT41J512M8RH125_EMIF_SDCFG,
22813526f71SJeff Lance 	.ref_ctrl = MT41J512M8RH125_EMIF_SDREF,
22913526f71SJeff Lance 	.sdram_tim1 = MT41J512M8RH125_EMIF_TIM1,
23013526f71SJeff Lance 	.sdram_tim2 = MT41J512M8RH125_EMIF_TIM2,
23113526f71SJeff Lance 	.sdram_tim3 = MT41J512M8RH125_EMIF_TIM3,
23213526f71SJeff Lance 	.zq_config = MT41J512M8RH125_ZQ_CFG,
23359dcf970SVaibhav Hiremath 	.emif_ddr_phy_ctlr_1 = MT41J512M8RH125_EMIF_READ_LATENCY |
23459dcf970SVaibhav Hiremath 				PHY_EN_DYN_PWRDN,
23513526f71SJeff Lance };
23612d7a474SPeter Korsgaard 
23712d7a474SPeter Korsgaard #ifdef CONFIG_SPL_OS_BOOT
23812d7a474SPeter Korsgaard int spl_start_uboot(void)
23912d7a474SPeter Korsgaard {
24012d7a474SPeter Korsgaard 	/* break into full u-boot on 'c' */
24112d7a474SPeter Korsgaard 	return (serial_tstc() && serial_getc() == 'c');
24212d7a474SPeter Korsgaard }
24312d7a474SPeter Korsgaard #endif
24412d7a474SPeter Korsgaard 
245*94d77fb6SLokesh Vutla #define OSC	(V_OSCK/1000000)
246*94d77fb6SLokesh Vutla const struct dpll_params dpll_ddr = {
247*94d77fb6SLokesh Vutla 		266, OSC-1, 1, -1, -1, -1, -1};
248*94d77fb6SLokesh Vutla const struct dpll_params dpll_ddr_evm_sk = {
249*94d77fb6SLokesh Vutla 		303, OSC-1, 1, -1, -1, -1, -1};
250*94d77fb6SLokesh Vutla const struct dpll_params dpll_ddr_bone_black = {
251*94d77fb6SLokesh Vutla 		400, OSC-1, 1, -1, -1, -1, -1};
252*94d77fb6SLokesh Vutla 
253*94d77fb6SLokesh Vutla const struct dpll_params *get_dpll_ddr_params(void)
254*94d77fb6SLokesh Vutla {
255*94d77fb6SLokesh Vutla 	struct am335x_baseboard_id header;
256*94d77fb6SLokesh Vutla 
257*94d77fb6SLokesh Vutla 	enable_i2c0_pin_mux();
258*94d77fb6SLokesh Vutla 	i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
259*94d77fb6SLokesh Vutla 	if (read_eeprom(&header) < 0)
260*94d77fb6SLokesh Vutla 		puts("Could not get board ID.\n");
261*94d77fb6SLokesh Vutla 
262*94d77fb6SLokesh Vutla 	if (board_is_evm_sk(&header))
263*94d77fb6SLokesh Vutla 		return &dpll_ddr_evm_sk;
264*94d77fb6SLokesh Vutla 	else if (board_is_bone_lt(&header))
265*94d77fb6SLokesh Vutla 		return &dpll_ddr_bone_black;
266*94d77fb6SLokesh Vutla 	else if (board_is_evm_15_or_later(&header))
267*94d77fb6SLokesh Vutla 		return &dpll_ddr_evm_sk;
268*94d77fb6SLokesh Vutla 	else
269*94d77fb6SLokesh Vutla 		return &dpll_ddr;
270*94d77fb6SLokesh Vutla }
271*94d77fb6SLokesh Vutla 
272e363426eSPeter Korsgaard #endif
273e363426eSPeter Korsgaard 
274e363426eSPeter Korsgaard /*
275e363426eSPeter Korsgaard  * early system init of muxing and clocks.
276e363426eSPeter Korsgaard  */
277e363426eSPeter Korsgaard void s_init(void)
278e363426eSPeter Korsgaard {
279c5c7a7c3SSteve Kipisz 	__maybe_unused struct am335x_baseboard_id header;
280ace4275eSTom Rini 
2814596dcc1STom Rini 	/*
282c5c7a7c3SSteve Kipisz 	 * The ROM will only have set up sufficient pinmux to allow for the
283c5c7a7c3SSteve Kipisz 	 * first 4KiB NOR to be read, we must finish doing what we know of
284c5c7a7c3SSteve Kipisz 	 * the NOR mux in this space in order to continue.
285c5c7a7c3SSteve Kipisz 	 */
286c5c7a7c3SSteve Kipisz #ifdef CONFIG_NOR_BOOT
287c5c7a7c3SSteve Kipisz 	asm("stmfd      sp!, {r2 - r4}");
288c5c7a7c3SSteve Kipisz 	asm("movw       r4, #0x8A4");
289c5c7a7c3SSteve Kipisz 	asm("movw       r3, #0x44E1");
290c5c7a7c3SSteve Kipisz 	asm("orr        r4, r4, r3, lsl #16");
291c5c7a7c3SSteve Kipisz 	asm("mov        r2, #9");
292c5c7a7c3SSteve Kipisz 	asm("mov        r3, #8");
293c5c7a7c3SSteve Kipisz 	asm("gpmc_mux:  str     r2, [r4], #4");
294c5c7a7c3SSteve Kipisz 	asm("subs       r3, r3, #1");
295c5c7a7c3SSteve Kipisz 	asm("bne        gpmc_mux");
296c5c7a7c3SSteve Kipisz 	asm("ldmfd      sp!, {r2 - r4}");
297c5c7a7c3SSteve Kipisz #endif
298c5c7a7c3SSteve Kipisz 
299c5c7a7c3SSteve Kipisz #ifdef CONFIG_SPL_BUILD
300c5c7a7c3SSteve Kipisz 	/*
3014596dcc1STom Rini 	 * Save the boot parameters passed from romcode.
3024596dcc1STom Rini 	 * We cannot delay the saving further than this,
3034596dcc1STom Rini 	 * to prevent overwrites.
3044596dcc1STom Rini 	 */
3054596dcc1STom Rini 	save_omap_boot_params();
3064596dcc1STom Rini #endif
3074596dcc1STom Rini 
308e363426eSPeter Korsgaard 	/* WDT1 is already running when the bootloader gets control
309e363426eSPeter Korsgaard 	 * Disable it to avoid "random" resets
310e363426eSPeter Korsgaard 	 */
311e363426eSPeter Korsgaard 	writel(0xAAAA, &wdtimer->wdtwspr);
312e363426eSPeter Korsgaard 	while (readl(&wdtimer->wdtwwps) != 0x0)
313e363426eSPeter Korsgaard 		;
314e363426eSPeter Korsgaard 	writel(0x5555, &wdtimer->wdtwspr);
315e363426eSPeter Korsgaard 	while (readl(&wdtimer->wdtwwps) != 0x0)
316e363426eSPeter Korsgaard 		;
317e363426eSPeter Korsgaard 
318c5c7a7c3SSteve Kipisz #if defined(CONFIG_SPL_BUILD) || defined(CONFIG_NOR_BOOT)
319e363426eSPeter Korsgaard 	/* Setup the PLLs and the clocks for the peripherals */
320e363426eSPeter Korsgaard 	pll_init();
321e363426eSPeter Korsgaard 
322e363426eSPeter Korsgaard 	/* Enable RTC32K clock */
323e363426eSPeter Korsgaard 	rtc32k_enable();
324e363426eSPeter Korsgaard 
3256422b70bSAndrew Bradford #ifdef CONFIG_SERIAL1
326e363426eSPeter Korsgaard 	enable_uart0_pin_mux();
3276422b70bSAndrew Bradford #endif /* CONFIG_SERIAL1 */
3286422b70bSAndrew Bradford #ifdef CONFIG_SERIAL2
3296422b70bSAndrew Bradford 	enable_uart1_pin_mux();
3306422b70bSAndrew Bradford #endif /* CONFIG_SERIAL2 */
3316422b70bSAndrew Bradford #ifdef CONFIG_SERIAL3
3326422b70bSAndrew Bradford 	enable_uart2_pin_mux();
3336422b70bSAndrew Bradford #endif /* CONFIG_SERIAL3 */
3346422b70bSAndrew Bradford #ifdef CONFIG_SERIAL4
3356422b70bSAndrew Bradford 	enable_uart3_pin_mux();
3366422b70bSAndrew Bradford #endif /* CONFIG_SERIAL4 */
3376422b70bSAndrew Bradford #ifdef CONFIG_SERIAL5
3386422b70bSAndrew Bradford 	enable_uart4_pin_mux();
3396422b70bSAndrew Bradford #endif /* CONFIG_SERIAL5 */
3406422b70bSAndrew Bradford #ifdef CONFIG_SERIAL6
3416422b70bSAndrew Bradford 	enable_uart5_pin_mux();
3426422b70bSAndrew Bradford #endif /* CONFIG_SERIAL6 */
343e363426eSPeter Korsgaard 
3447ea7f689SHeiko Schocher 	uart_soft_reset();
345e363426eSPeter Korsgaard 
346c5c7a7c3SSteve Kipisz #if defined(CONFIG_NOR_BOOT)
347c5c7a7c3SSteve Kipisz 	/* We want our console now. */
348c5c7a7c3SSteve Kipisz 	gd->baudrate = CONFIG_BAUDRATE;
349c5c7a7c3SSteve Kipisz 	serial_init();
350c5c7a7c3SSteve Kipisz 	gd->have_console = 1;
351c5c7a7c3SSteve Kipisz #else
352e363426eSPeter Korsgaard 	gd = &gdata;
353e363426eSPeter Korsgaard 
354e363426eSPeter Korsgaard 	preloader_console_init();
355c5c7a7c3SSteve Kipisz #endif
356e363426eSPeter Korsgaard 
357e363426eSPeter Korsgaard 	/* Initalize the board header */
358e363426eSPeter Korsgaard 	enable_i2c0_pin_mux();
359e363426eSPeter Korsgaard 	i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
360ace4275eSTom Rini 	if (read_eeprom(&header) < 0)
361e363426eSPeter Korsgaard 		puts("Could not get board ID.\n");
362e363426eSPeter Korsgaard 
363e363426eSPeter Korsgaard 	enable_board_pin_mux(&header);
364ace4275eSTom Rini 	if (board_is_evm_sk(&header)) {
365e363426eSPeter Korsgaard 		/*
366e363426eSPeter Korsgaard 		 * EVM SK 1.2A and later use gpio0_7 to enable DDR3.
367e363426eSPeter Korsgaard 		 * This is safe enough to do on older revs.
368e363426eSPeter Korsgaard 		 */
369e363426eSPeter Korsgaard 		gpio_request(GPIO_DDR_VTT_EN, "ddr_vtt_en");
370e363426eSPeter Korsgaard 		gpio_direction_output(GPIO_DDR_VTT_EN, 1);
371e363426eSPeter Korsgaard 	}
372e363426eSPeter Korsgaard 
373ace4275eSTom Rini 	if (board_is_evm_sk(&header))
374c7d35befSPeter Korsgaard 		config_ddr(303, MT41J128MJT125_IOCTRL_VALUE, &ddr3_data,
3753ba65f97SMatt Porter 			   &ddr3_cmd_ctrl_data, &ddr3_emif_reg_data, 0);
376ace4275eSTom Rini 	else if (board_is_bone_lt(&header))
377b996a3e9STom Rini 		config_ddr(400, MT41K256M16HA125E_IOCTRL_VALUE,
378c7ba18adSTom Rini 			   &ddr3_beagleblack_data,
379c7ba18adSTom Rini 			   &ddr3_beagleblack_cmd_ctrl_data,
380c7ba18adSTom Rini 			   &ddr3_beagleblack_emif_reg_data, 0);
381ace4275eSTom Rini 	else if (board_is_evm_15_or_later(&header))
38213526f71SJeff Lance 		config_ddr(303, MT41J512M8RH125_IOCTRL_VALUE, &ddr3_evm_data,
3833ba65f97SMatt Porter 			   &ddr3_evm_cmd_ctrl_data, &ddr3_evm_emif_reg_data, 0);
384c00f69dbSPeter Korsgaard 	else
385c7d35befSPeter Korsgaard 		config_ddr(266, MT47H128M16RT25E_IOCTRL_VALUE, &ddr2_data,
3863ba65f97SMatt Porter 			   &ddr2_cmd_ctrl_data, &ddr2_emif_reg_data, 0);
387e363426eSPeter Korsgaard #endif
388e363426eSPeter Korsgaard }
389e363426eSPeter Korsgaard 
390e363426eSPeter Korsgaard /*
391e363426eSPeter Korsgaard  * Basic board specific setup.  Pinmux has been handled already.
392e363426eSPeter Korsgaard  */
393e363426eSPeter Korsgaard int board_init(void)
394e363426eSPeter Korsgaard {
395cd8845d7SSteve Kipisz #ifdef CONFIG_NOR
396cd8845d7SSteve Kipisz 	const u32 gpmc_nor[GPMC_MAX_REG] = { STNOR_GPMC_CONFIG1,
397cd8845d7SSteve Kipisz 		STNOR_GPMC_CONFIG2, STNOR_GPMC_CONFIG3, STNOR_GPMC_CONFIG4,
398cd8845d7SSteve Kipisz 		STNOR_GPMC_CONFIG5, STNOR_GPMC_CONFIG6, STNOR_GPMC_CONFIG7 };
399cd8845d7SSteve Kipisz #endif
400cd8845d7SSteve Kipisz 
401e363426eSPeter Korsgaard 	gd->bd->bi_boot_params = PHYS_DRAM_1 + 0x100;
402e363426eSPeter Korsgaard 
40398b5c269SIlya Yanok 	gpmc_init();
40498b5c269SIlya Yanok 
405cd8845d7SSteve Kipisz #ifdef CONFIG_NOR
406cd8845d7SSteve Kipisz 	/* Reconfigure CS0 for NOR instead of NAND. */
407cd8845d7SSteve Kipisz 	enable_gpmc_cs_config(gpmc_nor, &gpmc_cfg->cs[0],
408cd8845d7SSteve Kipisz 			      CONFIG_SYS_FLASH_BASE, GPMC_SIZE_16M);
409cd8845d7SSteve Kipisz #endif
410cd8845d7SSteve Kipisz 
411e363426eSPeter Korsgaard 	return 0;
412e363426eSPeter Korsgaard }
413e363426eSPeter Korsgaard 
414044fc14bSTom Rini #ifdef CONFIG_BOARD_LATE_INIT
415044fc14bSTom Rini int board_late_init(void)
416044fc14bSTom Rini {
417044fc14bSTom Rini #ifdef CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG
418044fc14bSTom Rini 	char safe_string[HDR_NAME_LEN + 1];
419ace4275eSTom Rini 	struct am335x_baseboard_id header;
420ace4275eSTom Rini 
421ace4275eSTom Rini 	if (read_eeprom(&header) < 0)
422ace4275eSTom Rini 		puts("Could not get board ID.\n");
423044fc14bSTom Rini 
424044fc14bSTom Rini 	/* Now set variables based on the header. */
425044fc14bSTom Rini 	strncpy(safe_string, (char *)header.name, sizeof(header.name));
426044fc14bSTom Rini 	safe_string[sizeof(header.name)] = 0;
427044fc14bSTom Rini 	setenv("board_name", safe_string);
428044fc14bSTom Rini 
429044fc14bSTom Rini 	strncpy(safe_string, (char *)header.version, sizeof(header.version));
430044fc14bSTom Rini 	safe_string[sizeof(header.version)] = 0;
431044fc14bSTom Rini 	setenv("board_rev", safe_string);
432044fc14bSTom Rini #endif
433044fc14bSTom Rini 
434044fc14bSTom Rini 	return 0;
435044fc14bSTom Rini }
436044fc14bSTom Rini #endif
437044fc14bSTom Rini 
438c0e66793SIlya Yanok #if (defined(CONFIG_DRIVER_TI_CPSW) && !defined(CONFIG_SPL_BUILD)) || \
439c0e66793SIlya Yanok 	(defined(CONFIG_SPL_ETH_SUPPORT) && defined(CONFIG_SPL_BUILD))
440e363426eSPeter Korsgaard static void cpsw_control(int enabled)
441e363426eSPeter Korsgaard {
442e363426eSPeter Korsgaard 	/* VTP can be added here */
443e363426eSPeter Korsgaard 
444e363426eSPeter Korsgaard 	return;
445e363426eSPeter Korsgaard }
446e363426eSPeter Korsgaard 
447e363426eSPeter Korsgaard static struct cpsw_slave_data cpsw_slaves[] = {
448e363426eSPeter Korsgaard 	{
449e363426eSPeter Korsgaard 		.slave_reg_ofs	= 0x208,
450e363426eSPeter Korsgaard 		.sliver_reg_ofs	= 0xd80,
451e363426eSPeter Korsgaard 		.phy_id		= 0,
452e363426eSPeter Korsgaard 	},
453e363426eSPeter Korsgaard 	{
454e363426eSPeter Korsgaard 		.slave_reg_ofs	= 0x308,
455e363426eSPeter Korsgaard 		.sliver_reg_ofs	= 0xdc0,
456e363426eSPeter Korsgaard 		.phy_id		= 1,
457e363426eSPeter Korsgaard 	},
458e363426eSPeter Korsgaard };
459e363426eSPeter Korsgaard 
460e363426eSPeter Korsgaard static struct cpsw_platform_data cpsw_data = {
46181df2babSMatt Porter 	.mdio_base		= CPSW_MDIO_BASE,
46281df2babSMatt Porter 	.cpsw_base		= CPSW_BASE,
463e363426eSPeter Korsgaard 	.mdio_div		= 0xff,
464e363426eSPeter Korsgaard 	.channels		= 8,
465e363426eSPeter Korsgaard 	.cpdma_reg_ofs		= 0x800,
466e363426eSPeter Korsgaard 	.slaves			= 1,
467e363426eSPeter Korsgaard 	.slave_data		= cpsw_slaves,
468e363426eSPeter Korsgaard 	.ale_reg_ofs		= 0xd00,
469e363426eSPeter Korsgaard 	.ale_entries		= 1024,
470e363426eSPeter Korsgaard 	.host_port_reg_ofs	= 0x108,
471e363426eSPeter Korsgaard 	.hw_stats_reg_ofs	= 0x900,
4722bf36ac6SMugunthan V N 	.bd_ram_ofs		= 0x2000,
473e363426eSPeter Korsgaard 	.mac_control		= (1 << 5),
474e363426eSPeter Korsgaard 	.control		= cpsw_control,
475e363426eSPeter Korsgaard 	.host_port_num		= 0,
476e363426eSPeter Korsgaard 	.version		= CPSW_CTRL_VERSION_2,
477e363426eSPeter Korsgaard };
478d2aa1154SIlya Yanok #endif
479e363426eSPeter Korsgaard 
480d2aa1154SIlya Yanok #if defined(CONFIG_DRIVER_TI_CPSW) || \
481d2aa1154SIlya Yanok 	(defined(CONFIG_USB_ETHER) && defined(CONFIG_MUSB_GADGET))
482e363426eSPeter Korsgaard int board_eth_init(bd_t *bis)
483e363426eSPeter Korsgaard {
484d2aa1154SIlya Yanok 	int rv, n = 0;
485e363426eSPeter Korsgaard 	uint8_t mac_addr[6];
486e363426eSPeter Korsgaard 	uint32_t mac_hi, mac_lo;
487ace4275eSTom Rini 	__maybe_unused struct am335x_baseboard_id header;
488e363426eSPeter Korsgaard 
489e363426eSPeter Korsgaard 	/* try reading mac address from efuse */
490e363426eSPeter Korsgaard 	mac_lo = readl(&cdev->macid0l);
491e363426eSPeter Korsgaard 	mac_hi = readl(&cdev->macid0h);
492e363426eSPeter Korsgaard 	mac_addr[0] = mac_hi & 0xFF;
493e363426eSPeter Korsgaard 	mac_addr[1] = (mac_hi & 0xFF00) >> 8;
494e363426eSPeter Korsgaard 	mac_addr[2] = (mac_hi & 0xFF0000) >> 16;
495e363426eSPeter Korsgaard 	mac_addr[3] = (mac_hi & 0xFF000000) >> 24;
496e363426eSPeter Korsgaard 	mac_addr[4] = mac_lo & 0xFF;
497e363426eSPeter Korsgaard 	mac_addr[5] = (mac_lo & 0xFF00) >> 8;
498e363426eSPeter Korsgaard 
499c0e66793SIlya Yanok #if (defined(CONFIG_DRIVER_TI_CPSW) && !defined(CONFIG_SPL_BUILD)) || \
500c0e66793SIlya Yanok 	(defined(CONFIG_SPL_ETH_SUPPORT) && defined(CONFIG_SPL_BUILD))
501c0e66793SIlya Yanok 	if (!getenv("ethaddr")) {
502c0e66793SIlya Yanok 		printf("<ethaddr> not set. Validating first E-fuse MAC\n");
503c0e66793SIlya Yanok 
504e363426eSPeter Korsgaard 		if (is_valid_ether_addr(mac_addr))
505e363426eSPeter Korsgaard 			eth_setenv_enetaddr("ethaddr", mac_addr);
506e363426eSPeter Korsgaard 	}
507e363426eSPeter Korsgaard 
508a662e0c3SJoel A Fernandes #ifdef CONFIG_DRIVER_TI_CPSW
509ace4275eSTom Rini 	if (read_eeprom(&header) < 0)
510ace4275eSTom Rini 		puts("Could not get board ID.\n");
511ace4275eSTom Rini 
512ace4275eSTom Rini 	if (board_is_bone(&header) || board_is_bone_lt(&header) ||
513ace4275eSTom Rini 	    board_is_idk(&header)) {
514e363426eSPeter Korsgaard 		writel(MII_MODE_ENABLE, &cdev->miisel);
515e363426eSPeter Korsgaard 		cpsw_slaves[0].phy_if = cpsw_slaves[1].phy_if =
516e363426eSPeter Korsgaard 				PHY_INTERFACE_MODE_MII;
517e363426eSPeter Korsgaard 	} else {
518e363426eSPeter Korsgaard 		writel(RGMII_MODE_ENABLE, &cdev->miisel);
519e363426eSPeter Korsgaard 		cpsw_slaves[0].phy_if = cpsw_slaves[1].phy_if =
520e363426eSPeter Korsgaard 				PHY_INTERFACE_MODE_RGMII;
521e363426eSPeter Korsgaard 	}
522e363426eSPeter Korsgaard 
523d2aa1154SIlya Yanok 	rv = cpsw_register(&cpsw_data);
524d2aa1154SIlya Yanok 	if (rv < 0)
525d2aa1154SIlya Yanok 		printf("Error %d registering CPSW switch\n", rv);
526d2aa1154SIlya Yanok 	else
527d2aa1154SIlya Yanok 		n += rv;
528a662e0c3SJoel A Fernandes #endif
5291634e969STom Rini 
5301634e969STom Rini 	/*
5311634e969STom Rini 	 *
5321634e969STom Rini 	 * CPSW RGMII Internal Delay Mode is not supported in all PVT
5331634e969STom Rini 	 * operating points.  So we must set the TX clock delay feature
5341634e969STom Rini 	 * in the AR8051 PHY.  Since we only support a single ethernet
5351634e969STom Rini 	 * device in U-Boot, we only do this for the first instance.
5361634e969STom Rini 	 */
5371634e969STom Rini #define AR8051_PHY_DEBUG_ADDR_REG	0x1d
5381634e969STom Rini #define AR8051_PHY_DEBUG_DATA_REG	0x1e
5391634e969STom Rini #define AR8051_DEBUG_RGMII_CLK_DLY_REG	0x5
5401634e969STom Rini #define AR8051_RGMII_TX_CLK_DLY		0x100
5411634e969STom Rini 
542ace4275eSTom Rini 	if (board_is_evm_sk(&header) || board_is_gp_evm(&header)) {
5431634e969STom Rini 		const char *devname;
5441634e969STom Rini 		devname = miiphy_get_current_dev();
5451634e969STom Rini 
5461634e969STom Rini 		miiphy_write(devname, 0x0, AR8051_PHY_DEBUG_ADDR_REG,
5471634e969STom Rini 				AR8051_DEBUG_RGMII_CLK_DLY_REG);
5481634e969STom Rini 		miiphy_write(devname, 0x0, AR8051_PHY_DEBUG_DATA_REG,
5491634e969STom Rini 				AR8051_RGMII_TX_CLK_DLY);
5501634e969STom Rini 	}
551d2aa1154SIlya Yanok #endif
552c0e66793SIlya Yanok #if defined(CONFIG_USB_ETHER) && \
553c0e66793SIlya Yanok 	(!defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_USBETH_SUPPORT))
554c0e66793SIlya Yanok 	if (is_valid_ether_addr(mac_addr))
555c0e66793SIlya Yanok 		eth_setenv_enetaddr("usbnet_devaddr", mac_addr);
556c0e66793SIlya Yanok 
557d2aa1154SIlya Yanok 	rv = usb_eth_initialize(bis);
558d2aa1154SIlya Yanok 	if (rv < 0)
559d2aa1154SIlya Yanok 		printf("Error %d registering USB_ETHER\n", rv);
560d2aa1154SIlya Yanok 	else
561d2aa1154SIlya Yanok 		n += rv;
562d2aa1154SIlya Yanok #endif
563d2aa1154SIlya Yanok 	return n;
564e363426eSPeter Korsgaard }
565e363426eSPeter Korsgaard #endif
566