12d92ba84SAsh Charles /*
22d92ba84SAsh Charles * Board functions for Gumstix Pepper and AM335x-based boards
32d92ba84SAsh Charles *
42d92ba84SAsh Charles * Copyright (C) 2014, Gumstix, Incorporated - http://www.gumstix.com/
52d92ba84SAsh Charles * Based on board/ti/am335x/board.c from Texas Instruments, Inc.
62d92ba84SAsh Charles *
72d92ba84SAsh Charles * SPDX-License-Identifier: GPL-2.0+
82d92ba84SAsh Charles */
92d92ba84SAsh Charles
102d92ba84SAsh Charles #include <common.h>
112d92ba84SAsh Charles #include <errno.h>
122d92ba84SAsh Charles #include <spl.h>
132d92ba84SAsh Charles #include <asm/arch/cpu.h>
142d92ba84SAsh Charles #include <asm/arch/hardware.h>
152d92ba84SAsh Charles #include <asm/arch/omap.h>
162d92ba84SAsh Charles #include <asm/arch/ddr_defs.h>
172d92ba84SAsh Charles #include <asm/arch/clock.h>
182d92ba84SAsh Charles #include <asm/arch/gpio.h>
192d92ba84SAsh Charles #include <asm/arch/mmc_host_def.h>
202d92ba84SAsh Charles #include <asm/arch/sys_proto.h>
212d92ba84SAsh Charles #include <asm/arch/mem.h>
222d92ba84SAsh Charles #include <asm/io.h>
232d92ba84SAsh Charles #include <asm/emif.h>
242d92ba84SAsh Charles #include <asm/gpio.h>
252d92ba84SAsh Charles #include <i2c.h>
262d92ba84SAsh Charles #include <miiphy.h>
272d92ba84SAsh Charles #include <cpsw.h>
282d92ba84SAsh Charles #include <power/tps65217.h>
292d92ba84SAsh Charles #include <environment.h>
302d92ba84SAsh Charles #include <watchdog.h>
312d92ba84SAsh Charles #include "board.h"
322d92ba84SAsh Charles
332d92ba84SAsh Charles DECLARE_GLOBAL_DATA_PTR;
342d92ba84SAsh Charles
352d92ba84SAsh Charles #ifdef CONFIG_SPL_BUILD
365e90470aSAdam YH Lee #define OSC (V_OSCK/1000000)
375e90470aSAdam YH Lee
385e90470aSAdam YH Lee static const struct ddr_data ddr3_data = {
395e90470aSAdam YH Lee .datardsratio0 = MT41K256M16HA125E_RD_DQS,
405e90470aSAdam YH Lee .datawdsratio0 = MT41K256M16HA125E_WR_DQS,
415e90470aSAdam YH Lee .datafwsratio0 = MT41K256M16HA125E_PHY_FIFO_WE,
425e90470aSAdam YH Lee .datawrsratio0 = MT41K256M16HA125E_PHY_WR_DATA,
435e90470aSAdam YH Lee };
445e90470aSAdam YH Lee
455e90470aSAdam YH Lee static const struct cmd_control ddr3_cmd_ctrl_data = {
465e90470aSAdam YH Lee .cmd0csratio = MT41K256M16HA125E_RATIO,
475e90470aSAdam YH Lee .cmd0iclkout = MT41K256M16HA125E_INVERT_CLKOUT,
485e90470aSAdam YH Lee
495e90470aSAdam YH Lee .cmd1csratio = MT41K256M16HA125E_RATIO,
505e90470aSAdam YH Lee .cmd1iclkout = MT41K256M16HA125E_INVERT_CLKOUT,
515e90470aSAdam YH Lee
525e90470aSAdam YH Lee .cmd2csratio = MT41K256M16HA125E_RATIO,
535e90470aSAdam YH Lee .cmd2iclkout = MT41K256M16HA125E_INVERT_CLKOUT,
545e90470aSAdam YH Lee };
555e90470aSAdam YH Lee
565e90470aSAdam YH Lee static struct emif_regs ddr3_emif_reg_data = {
575e90470aSAdam YH Lee .sdram_config = MT41K256M16HA125E_EMIF_SDCFG,
585e90470aSAdam YH Lee .ref_ctrl = MT41K256M16HA125E_EMIF_SDREF,
595e90470aSAdam YH Lee .sdram_tim1 = MT41K256M16HA125E_EMIF_TIM1,
605e90470aSAdam YH Lee .sdram_tim2 = MT41K256M16HA125E_EMIF_TIM2,
615e90470aSAdam YH Lee .sdram_tim3 = MT41K256M16HA125E_EMIF_TIM3,
625e90470aSAdam YH Lee .zq_config = MT41K256M16HA125E_ZQ_CFG,
635e90470aSAdam YH Lee .emif_ddr_phy_ctlr_1 = MT41K256M16HA125E_EMIF_READ_LATENCY,
645e90470aSAdam YH Lee };
655e90470aSAdam YH Lee
665e90470aSAdam YH Lee const struct dpll_params dpll_ddr3 = {400, OSC-1, 1, -1, -1, -1, -1};
675e90470aSAdam YH Lee
685e90470aSAdam YH Lee const struct ctrl_ioregs ioregs_ddr3 = {
695e90470aSAdam YH Lee .cm0ioctl = MT41K256M16HA125E_IOCTRL_VALUE,
705e90470aSAdam YH Lee .cm1ioctl = MT41K256M16HA125E_IOCTRL_VALUE,
715e90470aSAdam YH Lee .cm2ioctl = MT41K256M16HA125E_IOCTRL_VALUE,
725e90470aSAdam YH Lee .dt0ioctl = MT41K256M16HA125E_IOCTRL_VALUE,
735e90470aSAdam YH Lee .dt1ioctl = MT41K256M16HA125E_IOCTRL_VALUE,
745e90470aSAdam YH Lee };
755e90470aSAdam YH Lee
762d92ba84SAsh Charles static const struct ddr_data ddr2_data = {
77c4f80f50STom Rini .datardsratio0 = MT47H128M16RT25E_RD_DQS,
78c4f80f50STom Rini .datafwsratio0 = MT47H128M16RT25E_PHY_FIFO_WE,
79c4f80f50STom Rini .datawrsratio0 = MT47H128M16RT25E_PHY_WR_DATA,
802d92ba84SAsh Charles };
812d92ba84SAsh Charles
822d92ba84SAsh Charles static const struct cmd_control ddr2_cmd_ctrl_data = {
832d92ba84SAsh Charles .cmd0csratio = MT47H128M16RT25E_RATIO,
842d92ba84SAsh Charles
852d92ba84SAsh Charles .cmd1csratio = MT47H128M16RT25E_RATIO,
862d92ba84SAsh Charles
872d92ba84SAsh Charles .cmd2csratio = MT47H128M16RT25E_RATIO,
882d92ba84SAsh Charles };
892d92ba84SAsh Charles
902d92ba84SAsh Charles static const struct emif_regs ddr2_emif_reg_data = {
912d92ba84SAsh Charles .sdram_config = MT47H128M16RT25E_EMIF_SDCFG,
922d92ba84SAsh Charles .ref_ctrl = MT47H128M16RT25E_EMIF_SDREF,
932d92ba84SAsh Charles .sdram_tim1 = MT47H128M16RT25E_EMIF_TIM1,
942d92ba84SAsh Charles .sdram_tim2 = MT47H128M16RT25E_EMIF_TIM2,
952d92ba84SAsh Charles .sdram_tim3 = MT47H128M16RT25E_EMIF_TIM3,
962d92ba84SAsh Charles .emif_ddr_phy_ctlr_1 = MT47H128M16RT25E_EMIF_READ_LATENCY,
972d92ba84SAsh Charles };
982d92ba84SAsh Charles
995e90470aSAdam YH Lee const struct dpll_params dpll_ddr2 = {266, OSC-1, 1, -1, -1, -1, -1};
1005e90470aSAdam YH Lee
1015e90470aSAdam YH Lee const struct ctrl_ioregs ioregs_ddr2 = {
1025e90470aSAdam YH Lee .cm0ioctl = MT47H128M16RT25E_IOCTRL_VALUE,
1035e90470aSAdam YH Lee .cm1ioctl = MT47H128M16RT25E_IOCTRL_VALUE,
1045e90470aSAdam YH Lee .cm2ioctl = MT47H128M16RT25E_IOCTRL_VALUE,
1055e90470aSAdam YH Lee .dt0ioctl = MT47H128M16RT25E_IOCTRL_VALUE,
1065e90470aSAdam YH Lee .dt1ioctl = MT47H128M16RT25E_IOCTRL_VALUE,
1075e90470aSAdam YH Lee };
1085e90470aSAdam YH Lee
read_eeprom(struct pepper_board_id * header)1095e90470aSAdam YH Lee static int read_eeprom(struct pepper_board_id *header)
1105e90470aSAdam YH Lee {
1115e90470aSAdam YH Lee if (i2c_probe(CONFIG_SYS_I2C_EEPROM_ADDR)) {
1125e90470aSAdam YH Lee return -ENODEV;
1135e90470aSAdam YH Lee }
1145e90470aSAdam YH Lee
1155e90470aSAdam YH Lee if (i2c_read(CONFIG_SYS_I2C_EEPROM_ADDR, 0, 1, (uchar *)header,
1165e90470aSAdam YH Lee sizeof(struct pepper_board_id))) {
1175e90470aSAdam YH Lee return -EIO;
1185e90470aSAdam YH Lee }
1195e90470aSAdam YH Lee
1205e90470aSAdam YH Lee return 0;
1215e90470aSAdam YH Lee }
1225e90470aSAdam YH Lee
get_dpll_ddr_params(void)1235e90470aSAdam YH Lee const struct dpll_params *get_dpll_ddr_params(void)
1245e90470aSAdam YH Lee {
1255e90470aSAdam YH Lee struct pepper_board_id header;
1265e90470aSAdam YH Lee
1275e90470aSAdam YH Lee enable_i2c0_pin_mux();
1285e90470aSAdam YH Lee i2c_set_bus_num(0);
1295e90470aSAdam YH Lee
1305e90470aSAdam YH Lee if (read_eeprom(&header) < 0)
1315e90470aSAdam YH Lee return &dpll_ddr3;
1325e90470aSAdam YH Lee
1335e90470aSAdam YH Lee switch (header.device_vendor) {
1345e90470aSAdam YH Lee case GUMSTIX_PEPPER:
1355e90470aSAdam YH Lee return &dpll_ddr2;
1365e90470aSAdam YH Lee case GUMSTIX_PEPPER_DVI:
1375e90470aSAdam YH Lee return &dpll_ddr3;
1385e90470aSAdam YH Lee default:
1395e90470aSAdam YH Lee return &dpll_ddr3;
1405e90470aSAdam YH Lee }
1415e90470aSAdam YH Lee }
1425e90470aSAdam YH Lee
sdram_init(void)1435e90470aSAdam YH Lee void sdram_init(void)
1445e90470aSAdam YH Lee {
1455e90470aSAdam YH Lee const struct dpll_params *dpll = get_dpll_ddr_params();
1465e90470aSAdam YH Lee
1475e90470aSAdam YH Lee /*
1485e90470aSAdam YH Lee * Here we are assuming PLL clock reveals the type of RAM.
1495e90470aSAdam YH Lee * DDR2 = 266
1505e90470aSAdam YH Lee * DDR3 = 400
1515e90470aSAdam YH Lee * Note that DDR3 is the default.
1525e90470aSAdam YH Lee */
1535e90470aSAdam YH Lee if (dpll->m == 266) {
1545e90470aSAdam YH Lee config_ddr(dpll->m, &ioregs_ddr2, &ddr2_data,
1555e90470aSAdam YH Lee &ddr2_cmd_ctrl_data, &ddr2_emif_reg_data, 0);
1565e90470aSAdam YH Lee }
1575e90470aSAdam YH Lee else if (dpll->m == 400) {
1585e90470aSAdam YH Lee config_ddr(dpll->m, &ioregs_ddr3, &ddr3_data,
1595e90470aSAdam YH Lee &ddr3_cmd_ctrl_data, &ddr3_emif_reg_data, 0);
1605e90470aSAdam YH Lee }
1615e90470aSAdam YH Lee }
1625e90470aSAdam YH Lee
1632d92ba84SAsh Charles #ifdef CONFIG_SPL_OS_BOOT
spl_start_uboot(void)1642d92ba84SAsh Charles int spl_start_uboot(void)
1652d92ba84SAsh Charles {
1662d92ba84SAsh Charles /* break into full u-boot on 'c' */
1672d92ba84SAsh Charles return serial_tstc() && serial_getc() == 'c';
1682d92ba84SAsh Charles }
1692d92ba84SAsh Charles #endif
1702d92ba84SAsh Charles
set_uart_mux_conf(void)1712d92ba84SAsh Charles void set_uart_mux_conf(void)
1722d92ba84SAsh Charles {
1732d92ba84SAsh Charles enable_uart0_pin_mux();
1742d92ba84SAsh Charles }
1752d92ba84SAsh Charles
set_mux_conf_regs(void)1762d92ba84SAsh Charles void set_mux_conf_regs(void)
1772d92ba84SAsh Charles {
1782d92ba84SAsh Charles enable_board_pin_mux();
1792d92ba84SAsh Charles }
1802d92ba84SAsh Charles
1812d92ba84SAsh Charles
1822d92ba84SAsh Charles #endif
1832d92ba84SAsh Charles
board_init(void)1842d92ba84SAsh Charles int board_init(void)
1852d92ba84SAsh Charles {
1862d92ba84SAsh Charles #if defined(CONFIG_HW_WATCHDOG)
1872d92ba84SAsh Charles hw_watchdog_init();
1882d92ba84SAsh Charles #endif
1892d92ba84SAsh Charles
1902d92ba84SAsh Charles gd->bd->bi_boot_params = CONFIG_SYS_SDRAM_BASE + 0x100;
1912d92ba84SAsh Charles gpmc_init();
1922d92ba84SAsh Charles
1932d92ba84SAsh Charles return 0;
1942d92ba84SAsh Charles }
1952d92ba84SAsh Charles
1962d92ba84SAsh Charles #if (defined(CONFIG_DRIVER_TI_CPSW) && !defined(CONFIG_SPL_BUILD)) || \
1972d92ba84SAsh Charles (defined(CONFIG_SPL_ETH_SUPPORT) && defined(CONFIG_SPL_BUILD))
1982d92ba84SAsh Charles static struct ctrl_dev *cdev = (struct ctrl_dev *)CTRL_DEVICE_BASE;
1992d92ba84SAsh Charles
cpsw_control(int enabled)2002d92ba84SAsh Charles static void cpsw_control(int enabled)
2012d92ba84SAsh Charles {
2022d92ba84SAsh Charles /* VTP can be added here */
2032d92ba84SAsh Charles
2042d92ba84SAsh Charles return;
2052d92ba84SAsh Charles }
2062d92ba84SAsh Charles
2072d92ba84SAsh Charles static struct cpsw_slave_data cpsw_slaves[] = {
2082d92ba84SAsh Charles {
2092d92ba84SAsh Charles .slave_reg_ofs = 0x208,
2102d92ba84SAsh Charles .sliver_reg_ofs = 0xd80,
2112d92ba84SAsh Charles .phy_addr = 0,
2122d92ba84SAsh Charles .phy_if = PHY_INTERFACE_MODE_RGMII,
2132d92ba84SAsh Charles },
2142d92ba84SAsh Charles };
2152d92ba84SAsh Charles
2162d92ba84SAsh Charles static struct cpsw_platform_data cpsw_data = {
2172d92ba84SAsh Charles .mdio_base = CPSW_MDIO_BASE,
2182d92ba84SAsh Charles .cpsw_base = CPSW_BASE,
2192d92ba84SAsh Charles .mdio_div = 0xff,
2202d92ba84SAsh Charles .channels = 8,
2212d92ba84SAsh Charles .cpdma_reg_ofs = 0x800,
2222d92ba84SAsh Charles .slaves = 1,
2232d92ba84SAsh Charles .slave_data = cpsw_slaves,
2242d92ba84SAsh Charles .ale_reg_ofs = 0xd00,
2252d92ba84SAsh Charles .ale_entries = 1024,
2262d92ba84SAsh Charles .host_port_reg_ofs = 0x108,
2272d92ba84SAsh Charles .hw_stats_reg_ofs = 0x900,
2282d92ba84SAsh Charles .bd_ram_ofs = 0x2000,
2292d92ba84SAsh Charles .mac_control = (1 << 5),
2302d92ba84SAsh Charles .control = cpsw_control,
2312d92ba84SAsh Charles .host_port_num = 0,
2322d92ba84SAsh Charles .version = CPSW_CTRL_VERSION_2,
2332d92ba84SAsh Charles };
2342d92ba84SAsh Charles
board_eth_init(bd_t * bis)2352d92ba84SAsh Charles int board_eth_init(bd_t *bis)
2362d92ba84SAsh Charles {
2372d92ba84SAsh Charles int rv, n = 0;
2382d92ba84SAsh Charles uint8_t mac_addr[6];
2392d92ba84SAsh Charles uint32_t mac_hi, mac_lo;
2402d92ba84SAsh Charles const char *devname;
2412d92ba84SAsh Charles
242*35affd7aSSimon Glass if (!eth_env_get_enetaddr("ethaddr", mac_addr)) {
2432d92ba84SAsh Charles /* try reading mac address from efuse */
2442d92ba84SAsh Charles mac_lo = readl(&cdev->macid0l);
2452d92ba84SAsh Charles mac_hi = readl(&cdev->macid0h);
2462d92ba84SAsh Charles mac_addr[0] = mac_hi & 0xFF;
2472d92ba84SAsh Charles mac_addr[1] = (mac_hi & 0xFF00) >> 8;
2482d92ba84SAsh Charles mac_addr[2] = (mac_hi & 0xFF0000) >> 16;
2492d92ba84SAsh Charles mac_addr[3] = (mac_hi & 0xFF000000) >> 24;
2502d92ba84SAsh Charles mac_addr[4] = mac_lo & 0xFF;
2512d92ba84SAsh Charles mac_addr[5] = (mac_lo & 0xFF00) >> 8;
2520adb5b76SJoe Hershberger if (is_valid_ethaddr(mac_addr))
253fd1e959eSSimon Glass eth_env_set_enetaddr("ethaddr", mac_addr);
2542d92ba84SAsh Charles }
2552d92ba84SAsh Charles
2562d92ba84SAsh Charles writel((RGMII_MODE_ENABLE | RGMII_INT_DELAY), &cdev->miisel);
2572d92ba84SAsh Charles
2582d92ba84SAsh Charles rv = cpsw_register(&cpsw_data);
2592d92ba84SAsh Charles if (rv < 0)
2602d92ba84SAsh Charles printf("Error %d registering CPSW switch\n", rv);
2612d92ba84SAsh Charles else
2622d92ba84SAsh Charles n += rv;
2632d92ba84SAsh Charles
2642d92ba84SAsh Charles /*
2652d92ba84SAsh Charles *
2662d92ba84SAsh Charles * CPSW RGMII Internal Delay Mode is not supported in all PVT
2672d92ba84SAsh Charles * operating points. So we must set the TX clock delay feature
2682d92ba84SAsh Charles * in the KSZ9021 PHY. Since we only support a single ethernet
2692d92ba84SAsh Charles * device in U-Boot, we only do this for the current instance.
2702d92ba84SAsh Charles */
2712d92ba84SAsh Charles devname = miiphy_get_current_dev();
2722d92ba84SAsh Charles /* max rx/tx clock delay, min rx/tx control delay */
2732d92ba84SAsh Charles miiphy_write(devname, 0x0, 0x0b, 0x8104);
2742d92ba84SAsh Charles miiphy_write(devname, 0x0, 0xc, 0xa0a0);
2752d92ba84SAsh Charles
2762d92ba84SAsh Charles /* min rx data delay */
2772d92ba84SAsh Charles miiphy_write(devname, 0x0, 0x0b, 0x8105);
2782d92ba84SAsh Charles miiphy_write(devname, 0x0, 0x0c, 0x0000);
2792d92ba84SAsh Charles
2802d92ba84SAsh Charles /* min tx data delay */
2812d92ba84SAsh Charles miiphy_write(devname, 0x0, 0x0b, 0x8106);
2822d92ba84SAsh Charles miiphy_write(devname, 0x0, 0x0c, 0x0000);
2832d92ba84SAsh Charles
2842d92ba84SAsh Charles return n;
2852d92ba84SAsh Charles }
2862d92ba84SAsh Charles #endif
287