2 * Board functions for Gumstix Pepper and AM335x-based boards
4 * Copyright (C) 2014, Gumstix, Incorporated - http://www.gumstix.com/
5 * Based on board/ti/am335x/board.c from Texas Instruments, Inc.
7 * SPDX-License-Identifier: GPL-2.0+
13 #include <asm/arch/cpu.h>
14 #include <asm/arch/hardware.h>
15 #include <asm/arch/omap.h>
16 #include <asm/arch/ddr_defs.h>
17 #include <asm/arch/clock.h>
18 #include <asm/arch/gpio.h>
19 #include <asm/arch/mmc_host_def.h>
20 #include <asm/arch/sys_proto.h>
21 #include <asm/arch/mem.h>
28 #include <power/tps65217.h>
29 #include <environment.h>
33 DECLARE_GLOBAL_DATA_PTR
;
35 #ifdef CONFIG_SPL_BUILD
36 #define OSC (V_OSCK/1000000)
38 static const struct ddr_data ddr3_data
= {
39 .datardsratio0
= MT41K256M16HA125E_RD_DQS
,
40 .datawdsratio0
= MT41K256M16HA125E_WR_DQS
,
41 .datafwsratio0
= MT41K256M16HA125E_PHY_FIFO_WE
,
42 .datawrsratio0
= MT41K256M16HA125E_PHY_WR_DATA
,
45 static const struct cmd_control ddr3_cmd_ctrl_data
= {
46 .cmd0csratio
= MT41K256M16HA125E_RATIO
,
47 .cmd0iclkout
= MT41K256M16HA125E_INVERT_CLKOUT
,
49 .cmd1csratio
= MT41K256M16HA125E_RATIO
,
50 .cmd1iclkout
= MT41K256M16HA125E_INVERT_CLKOUT
,
52 .cmd2csratio
= MT41K256M16HA125E_RATIO
,
53 .cmd2iclkout
= MT41K256M16HA125E_INVERT_CLKOUT
,
56 static struct emif_regs ddr3_emif_reg_data
= {
57 .sdram_config
= MT41K256M16HA125E_EMIF_SDCFG
,
58 .ref_ctrl
= MT41K256M16HA125E_EMIF_SDREF
,
59 .sdram_tim1
= MT41K256M16HA125E_EMIF_TIM1
,
60 .sdram_tim2
= MT41K256M16HA125E_EMIF_TIM2
,
61 .sdram_tim3
= MT41K256M16HA125E_EMIF_TIM3
,
62 .zq_config
= MT41K256M16HA125E_ZQ_CFG
,
63 .emif_ddr_phy_ctlr_1
= MT41K256M16HA125E_EMIF_READ_LATENCY
,
66 const struct dpll_params dpll_ddr3
= {400, OSC
-1, 1, -1, -1, -1, -1};
68 const struct ctrl_ioregs ioregs_ddr3
= {
69 .cm0ioctl
= MT41K256M16HA125E_IOCTRL_VALUE
,
70 .cm1ioctl
= MT41K256M16HA125E_IOCTRL_VALUE
,
71 .cm2ioctl
= MT41K256M16HA125E_IOCTRL_VALUE
,
72 .dt0ioctl
= MT41K256M16HA125E_IOCTRL_VALUE
,
73 .dt1ioctl
= MT41K256M16HA125E_IOCTRL_VALUE
,
76 static const struct ddr_data ddr2_data
= {
77 .datardsratio0
= MT47H128M16RT25E_RD_DQS
,
78 .datafwsratio0
= MT47H128M16RT25E_PHY_FIFO_WE
,
79 .datawrsratio0
= MT47H128M16RT25E_PHY_WR_DATA
,
82 static const struct cmd_control ddr2_cmd_ctrl_data
= {
83 .cmd0csratio
= MT47H128M16RT25E_RATIO
,
85 .cmd1csratio
= MT47H128M16RT25E_RATIO
,
87 .cmd2csratio
= MT47H128M16RT25E_RATIO
,
90 static const struct emif_regs ddr2_emif_reg_data
= {
91 .sdram_config
= MT47H128M16RT25E_EMIF_SDCFG
,
92 .ref_ctrl
= MT47H128M16RT25E_EMIF_SDREF
,
93 .sdram_tim1
= MT47H128M16RT25E_EMIF_TIM1
,
94 .sdram_tim2
= MT47H128M16RT25E_EMIF_TIM2
,
95 .sdram_tim3
= MT47H128M16RT25E_EMIF_TIM3
,
96 .emif_ddr_phy_ctlr_1
= MT47H128M16RT25E_EMIF_READ_LATENCY
,
99 const struct dpll_params dpll_ddr2
= {266, OSC
-1, 1, -1, -1, -1, -1};
101 const struct ctrl_ioregs ioregs_ddr2
= {
102 .cm0ioctl
= MT47H128M16RT25E_IOCTRL_VALUE
,
103 .cm1ioctl
= MT47H128M16RT25E_IOCTRL_VALUE
,
104 .cm2ioctl
= MT47H128M16RT25E_IOCTRL_VALUE
,
105 .dt0ioctl
= MT47H128M16RT25E_IOCTRL_VALUE
,
106 .dt1ioctl
= MT47H128M16RT25E_IOCTRL_VALUE
,
109 static int read_eeprom(struct pepper_board_id
*header
)
111 if (i2c_probe(CONFIG_SYS_I2C_EEPROM_ADDR
)) {
115 if (i2c_read(CONFIG_SYS_I2C_EEPROM_ADDR
, 0, 1, (uchar
*)header
,
116 sizeof(struct pepper_board_id
))) {
123 const struct dpll_params
*get_dpll_ddr_params(void)
125 struct pepper_board_id header
;
127 enable_i2c0_pin_mux();
130 if (read_eeprom(&header
) < 0)
133 switch (header
.device_vendor
) {
136 case GUMSTIX_PEPPER_DVI
:
143 void sdram_init(void)
145 const struct dpll_params
*dpll
= get_dpll_ddr_params();
148 * Here we are assuming PLL clock reveals the type of RAM.
151 * Note that DDR3 is the default.
153 if (dpll
->m
== 266) {
154 config_ddr(dpll
->m
, &ioregs_ddr2
, &ddr2_data
,
155 &ddr2_cmd_ctrl_data
, &ddr2_emif_reg_data
, 0);
157 else if (dpll
->m
== 400) {
158 config_ddr(dpll
->m
, &ioregs_ddr3
, &ddr3_data
,
159 &ddr3_cmd_ctrl_data
, &ddr3_emif_reg_data
, 0);
163 #ifdef CONFIG_SPL_OS_BOOT
164 int spl_start_uboot(void)
166 /* break into full u-boot on 'c' */
167 return serial_tstc() && serial_getc() == 'c';
171 void set_uart_mux_conf(void)
173 enable_uart0_pin_mux();
176 void set_mux_conf_regs(void)
178 enable_board_pin_mux();
186 #if defined(CONFIG_HW_WATCHDOG)
190 gd
->bd
->bi_boot_params
= CONFIG_SYS_SDRAM_BASE
+ 0x100;
196 #if (defined(CONFIG_DRIVER_TI_CPSW) && !defined(CONFIG_SPL_BUILD)) || \
197 (defined(CONFIG_SPL_ETH_SUPPORT) && defined(CONFIG_SPL_BUILD))
198 static struct ctrl_dev
*cdev
= (struct ctrl_dev
*)CTRL_DEVICE_BASE
;
200 static void cpsw_control(int enabled
)
202 /* VTP can be added here */
207 static struct cpsw_slave_data cpsw_slaves
[] = {
209 .slave_reg_ofs
= 0x208,
210 .sliver_reg_ofs
= 0xd80,
212 .phy_if
= PHY_INTERFACE_MODE_RGMII
,
216 static struct cpsw_platform_data cpsw_data
= {
217 .mdio_base
= CPSW_MDIO_BASE
,
218 .cpsw_base
= CPSW_BASE
,
221 .cpdma_reg_ofs
= 0x800,
223 .slave_data
= cpsw_slaves
,
224 .ale_reg_ofs
= 0xd00,
226 .host_port_reg_ofs
= 0x108,
227 .hw_stats_reg_ofs
= 0x900,
228 .bd_ram_ofs
= 0x2000,
229 .mac_control
= (1 << 5),
230 .control
= cpsw_control
,
232 .version
= CPSW_CTRL_VERSION_2
,
235 int board_eth_init(bd_t
*bis
)
239 uint32_t mac_hi
, mac_lo
;
242 if (!eth_env_get_enetaddr("ethaddr", mac_addr
)) {
243 /* try reading mac address from efuse */
244 mac_lo
= readl(&cdev
->macid0l
);
245 mac_hi
= readl(&cdev
->macid0h
);
246 mac_addr
[0] = mac_hi
& 0xFF;
247 mac_addr
[1] = (mac_hi
& 0xFF00) >> 8;
248 mac_addr
[2] = (mac_hi
& 0xFF0000) >> 16;
249 mac_addr
[3] = (mac_hi
& 0xFF000000) >> 24;
250 mac_addr
[4] = mac_lo
& 0xFF;
251 mac_addr
[5] = (mac_lo
& 0xFF00) >> 8;
252 if (is_valid_ethaddr(mac_addr
))
253 eth_env_set_enetaddr("ethaddr", mac_addr
);
256 writel((RGMII_MODE_ENABLE
| RGMII_INT_DELAY
), &cdev
->miisel
);
258 rv
= cpsw_register(&cpsw_data
);
260 printf("Error %d registering CPSW switch\n", rv
);
266 * CPSW RGMII Internal Delay Mode is not supported in all PVT
267 * operating points. So we must set the TX clock delay feature
268 * in the KSZ9021 PHY. Since we only support a single ethernet
269 * device in U-Boot, we only do this for the current instance.
271 devname
= miiphy_get_current_dev();
272 /* max rx/tx clock delay, min rx/tx control delay */
273 miiphy_write(devname
, 0x0, 0x0b, 0x8104);
274 miiphy_write(devname
, 0x0, 0xc, 0xa0a0);
276 /* min rx data delay */
277 miiphy_write(devname
, 0x0, 0x0b, 0x8105);
278 miiphy_write(devname
, 0x0, 0x0c, 0x0000);
280 /* min tx data delay */
281 miiphy_write(devname
, 0x0, 0x0b, 0x8106);
282 miiphy_write(devname
, 0x0, 0x0c, 0x0000);