uboot/board/vscom/baltos/board.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 * board.c
   4 *
   5 * Board functions for TI AM335X based boards
   6 *
   7 * Copyright (C) 2011, Texas Instruments, Incorporated - http://www.ti.com/
   8 */
   9
  10#include <common.h>
  11#include <env.h>
  12#include <errno.h>
  13#include <linux/libfdt.h>
  14#include <spl.h>
  15#include <asm/arch/cpu.h>
  16#include <asm/arch/hardware.h>
  17#include <asm/arch/omap.h>
  18#include <asm/arch/ddr_defs.h>
  19#include <asm/arch/clock.h>
  20#include <asm/arch/gpio.h>
  21#include <asm/arch/mmc_host_def.h>
  22#include <asm/arch/sys_proto.h>
  23#include <asm/arch/mem.h>
  24#include <asm/arch/mux.h>
  25#include <asm/io.h>
  26#include <asm/emif.h>
  27#include <asm/gpio.h>
  28#include <i2c.h>
  29#include <miiphy.h>
  30#include <cpsw.h>
  31#include <power/tps65910.h>
  32#include <watchdog.h>
  33#include "board.h"
  34
  35DECLARE_GLOBAL_DATA_PTR;
  36
  37/* GPIO that controls DIP switch and mPCIe slot */
  38#define DIP_S1                  44
  39#define MPCIE_SW                100
  40
  41static struct ctrl_dev *cdev = (struct ctrl_dev *)CTRL_DEVICE_BASE;
  42
  43static int baltos_set_console(void)
  44{
  45        int val, i, dips = 0;
  46        char buf[7];
  47
  48        for (i = 0; i < 4; i++) {
  49                sprintf(buf, "dip_s%d", i + 1);
  50
  51                if (gpio_request(DIP_S1 + i, buf)) {
  52                        printf("failed to export GPIO %d\n", DIP_S1 + i);
  53                        return 0;
  54                }
  55
  56                if (gpio_direction_input(DIP_S1 + i)) {
  57                        printf("failed to set GPIO %d direction\n", DIP_S1 + i);
  58                        return 0;
  59                }
  60
  61                val = gpio_get_value(DIP_S1 + i);
  62                dips |= val << i;
  63        }
  64
  65        printf("DIPs: 0x%1x\n", (~dips) & 0xf);
  66
  67        if ((dips & 0xf) == 0xe)
  68                env_set("console", "ttyUSB0,115200n8");
  69
  70        return 0;
  71}
  72
  73static int read_eeprom(BSP_VS_HWPARAM *header)
  74{
  75        i2c_set_bus_num(1);
  76
  77        /* Check if baseboard eeprom is available */
  78        if (i2c_probe(CONFIG_SYS_I2C_EEPROM_ADDR)) {
  79                puts("Could not probe the EEPROM; something fundamentally "
  80                        "wrong on the I2C bus.\n");
  81                return -ENODEV;
  82        }
  83
  84        /* read the eeprom using i2c */
  85        if (i2c_read(CONFIG_SYS_I2C_EEPROM_ADDR, 0, 1, (uchar *)header,
  86                     sizeof(BSP_VS_HWPARAM))) {
  87                puts("Could not read the EEPROM; something fundamentally"
  88                        " wrong on the I2C bus.\n");
  89                return -EIO;
  90        }
  91
  92        if (header->Magic != 0xDEADBEEF) {
  93
  94                printf("Incorrect magic number (0x%x) in EEPROM\n",
  95                                header->Magic);
  96
  97                /* fill default values */
  98                header->SystemId = 211;
  99                header->MAC1[0] = 0x00;
 100                header->MAC1[1] = 0x00;
 101                header->MAC1[2] = 0x00;
 102                header->MAC1[3] = 0x00;
 103                header->MAC1[4] = 0x00;
 104                header->MAC1[5] = 0x01;
 105
 106                header->MAC2[0] = 0x00;
 107                header->MAC2[1] = 0x00;
 108                header->MAC2[2] = 0x00;
 109                header->MAC2[3] = 0x00;
 110                header->MAC2[4] = 0x00;
 111                header->MAC2[5] = 0x02;
 112
 113                header->MAC3[0] = 0x00;
 114                header->MAC3[1] = 0x00;
 115                header->MAC3[2] = 0x00;
 116                header->MAC3[3] = 0x00;
 117                header->MAC3[4] = 0x00;
 118                header->MAC3[5] = 0x03;
 119        }
 120
 121        return 0;
 122}
 123
 124#if defined(CONFIG_SPL_BUILD) || defined(CONFIG_NOR_BOOT)
 125
 126static const struct ddr_data ddr3_baltos_data = {
 127        .datardsratio0 = MT41K256M16HA125E_RD_DQS,
 128        .datawdsratio0 = MT41K256M16HA125E_WR_DQS,
 129        .datafwsratio0 = MT41K256M16HA125E_PHY_FIFO_WE,
 130        .datawrsratio0 = MT41K256M16HA125E_PHY_WR_DATA,
 131};
 132
 133static const struct cmd_control ddr3_baltos_cmd_ctrl_data = {
 134        .cmd0csratio = MT41K256M16HA125E_RATIO,
 135        .cmd0iclkout = MT41K256M16HA125E_INVERT_CLKOUT,
 136
 137        .cmd1csratio = MT41K256M16HA125E_RATIO,
 138        .cmd1iclkout = MT41K256M16HA125E_INVERT_CLKOUT,
 139
 140        .cmd2csratio = MT41K256M16HA125E_RATIO,
 141        .cmd2iclkout = MT41K256M16HA125E_INVERT_CLKOUT,
 142};
 143
 144static struct emif_regs ddr3_baltos_emif_reg_data = {
 145        .sdram_config = MT41K256M16HA125E_EMIF_SDCFG,
 146        .ref_ctrl = MT41K256M16HA125E_EMIF_SDREF,
 147        .sdram_tim1 = MT41K256M16HA125E_EMIF_TIM1,
 148        .sdram_tim2 = MT41K256M16HA125E_EMIF_TIM2,
 149        .sdram_tim3 = MT41K256M16HA125E_EMIF_TIM3,
 150        .zq_config = MT41K256M16HA125E_ZQ_CFG,
 151        .emif_ddr_phy_ctlr_1 = MT41K256M16HA125E_EMIF_READ_LATENCY,
 152};
 153
 154#ifdef CONFIG_SPL_OS_BOOT
 155int spl_start_uboot(void)
 156{
 157        /* break into full u-boot on 'c' */
 158        return (serial_tstc() && serial_getc() == 'c');
 159}
 160#endif
 161
 162#define OSC     (V_OSCK/1000000)
 163const struct dpll_params dpll_ddr = {
 164                266, OSC-1, 1, -1, -1, -1, -1};
 165const struct dpll_params dpll_ddr_evm_sk = {
 166                303, OSC-1, 1, -1, -1, -1, -1};
 167const struct dpll_params dpll_ddr_baltos = {
 168                400, OSC-1, 1, -1, -1, -1, -1};
 169
 170void am33xx_spl_board_init(void)
 171{
 172        int mpu_vdd;
 173        int sil_rev;
 174
 175        /* Get the frequency */
 176        dpll_mpu_opp100.m = am335x_get_efuse_mpu_max_freq(cdev);
 177
 178        /*
 179         * The GP EVM, IDK and EVM SK use a TPS65910 PMIC.  For all
 180         * MPU frequencies we support we use a CORE voltage of
 181         * 1.1375V.  For MPU voltage we need to switch based on
 182         * the frequency we are running at.
 183         */
 184        i2c_set_bus_num(1);
 185
 186        printf("I2C speed: %d Hz\n", CONFIG_SYS_OMAP24_I2C_SPEED);
 187
 188        if (i2c_probe(TPS65910_CTRL_I2C_ADDR)) {
 189                puts("i2c: cannot access TPS65910\n");
 190                return;
 191        }
 192
 193        /*
 194         * Depending on MPU clock and PG we will need a different
 195         * VDD to drive at that speed.
 196         */
 197        sil_rev = readl(&cdev->deviceid) >> 28;
 198        mpu_vdd = am335x_get_tps65910_mpu_vdd(sil_rev,
 199                                              dpll_mpu_opp100.m);
 200
 201        /* Tell the TPS65910 to use i2c */
 202        tps65910_set_i2c_control();
 203
 204        /* First update MPU voltage. */
 205        if (tps65910_voltage_update(MPU, mpu_vdd))
 206                return;
 207
 208        /* Second, update the CORE voltage. */
 209        if (tps65910_voltage_update(CORE, TPS65910_OP_REG_SEL_1_1_3))
 210                return;
 211
 212        /* Set CORE Frequencies to OPP100 */
 213        do_setup_dpll(&dpll_core_regs, &dpll_core_opp100);
 214
 215        /* Set MPU Frequency to what we detected now that voltages are set */
 216        do_setup_dpll(&dpll_mpu_regs, &dpll_mpu_opp100);
 217
 218        writel(0x000010ff, PRM_DEVICE_INST + 4);
 219}
 220
 221const struct dpll_params *get_dpll_ddr_params(void)
 222{
 223        enable_i2c1_pin_mux();
 224        i2c_set_bus_num(1);
 225
 226        return &dpll_ddr_baltos;
 227}
 228
 229void set_uart_mux_conf(void)
 230{
 231        enable_uart0_pin_mux();
 232}
 233
 234void set_mux_conf_regs(void)
 235{
 236        enable_board_pin_mux();
 237}
 238
 239const struct ctrl_ioregs ioregs_baltos = {
 240        .cm0ioctl               = MT41K256M16HA125E_IOCTRL_VALUE,
 241        .cm1ioctl               = MT41K256M16HA125E_IOCTRL_VALUE,
 242        .cm2ioctl               = MT41K256M16HA125E_IOCTRL_VALUE,
 243        .dt0ioctl               = MT41K256M16HA125E_IOCTRL_VALUE,
 244        .dt1ioctl               = MT41K256M16HA125E_IOCTRL_VALUE,
 245};
 246
 247void sdram_init(void)
 248{
 249        config_ddr(400, &ioregs_baltos,
 250                   &ddr3_baltos_data,
 251                   &ddr3_baltos_cmd_ctrl_data,
 252                   &ddr3_baltos_emif_reg_data, 0);
 253}
 254#endif
 255
 256/*
 257 * Basic board specific setup.  Pinmux has been handled already.
 258 */
 259int board_init(void)
 260{
 261#if defined(CONFIG_HW_WATCHDOG)
 262        hw_watchdog_init();
 263#endif
 264
 265        gd->bd->bi_boot_params = CONFIG_SYS_SDRAM_BASE + 0x100;
 266#if defined(CONFIG_NOR) || defined(CONFIG_NAND)
 267        gpmc_init();
 268#endif
 269        return 0;
 270}
 271
 272int ft_board_setup(void *blob, bd_t *bd)
 273{
 274        int node, ret;
 275        unsigned char mac_addr[6];
 276        BSP_VS_HWPARAM header;
 277
 278        /* get production data */
 279        if (read_eeprom(&header))
 280                return 0;
 281
 282        /* setup MAC1 */
 283        mac_addr[0] = header.MAC1[0];
 284        mac_addr[1] = header.MAC1[1];
 285        mac_addr[2] = header.MAC1[2];
 286        mac_addr[3] = header.MAC1[3];
 287        mac_addr[4] = header.MAC1[4];
 288        mac_addr[5] = header.MAC1[5];
 289
 290
 291        node = fdt_path_offset(blob, "ethernet0");
 292        if (node < 0) {
 293                printf("no ethernet0 path offset\n");
 294                return -ENODEV;
 295        }
 296
 297        ret = fdt_setprop(blob, node, "mac-address", &mac_addr, 6);
 298        if (ret) {
 299                printf("error setting mac-address property\n");
 300                return -ENODEV;
 301        }
 302
 303        /* setup MAC2 */
 304        mac_addr[0] = header.MAC2[0];
 305        mac_addr[1] = header.MAC2[1];
 306        mac_addr[2] = header.MAC2[2];
 307        mac_addr[3] = header.MAC2[3];
 308        mac_addr[4] = header.MAC2[4];
 309        mac_addr[5] = header.MAC2[5];
 310
 311        node = fdt_path_offset(blob, "ethernet1");
 312        if (node < 0) {
 313                printf("no ethernet1 path offset\n");
 314                return -ENODEV;
 315        }
 316
 317        ret = fdt_setprop(blob, node, "mac-address", &mac_addr, 6);
 318        if (ret) {
 319                printf("error setting mac-address property\n");
 320                return -ENODEV;
 321        }
 322
 323        printf("\nFDT was successfully setup\n");
 324
 325        return 0;
 326}
 327
 328static struct module_pin_mux pcie_sw_pin_mux[] = {
 329        {OFFSET(mii1_rxdv), (MODE(7) | PULLUDEN )},     /* GPIO3_4 */
 330        {-1},
 331};
 332
 333static struct module_pin_mux dip_pin_mux[] = {
 334        {OFFSET(gpmc_ad12), (MODE(7) | RXACTIVE )},     /* GPIO1_12 */
 335        {OFFSET(gpmc_ad13), (MODE(7)  | RXACTIVE )},    /* GPIO1_13 */
 336        {OFFSET(gpmc_ad14), (MODE(7)  | RXACTIVE )},    /* GPIO1_14 */
 337        {OFFSET(gpmc_ad15), (MODE(7)  | RXACTIVE )},    /* GPIO1_15 */
 338        {-1},
 339};
 340
 341#ifdef CONFIG_BOARD_LATE_INIT
 342int board_late_init(void)
 343{
 344#ifdef CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG
 345        BSP_VS_HWPARAM header;
 346        char model[4];
 347
 348        /* get production data */
 349        if (read_eeprom(&header)) {
 350                strcpy(model, "211");
 351        } else {
 352                sprintf(model, "%d", header.SystemId);
 353                if (header.SystemId == 215) {
 354                        configure_module_pin_mux(dip_pin_mux);
 355                        baltos_set_console();
 356                }
 357        }
 358
 359        /* turn power for the mPCIe slot */
 360        configure_module_pin_mux(pcie_sw_pin_mux);
 361        if (gpio_request(MPCIE_SW, "mpcie_sw")) {
 362                printf("failed to export GPIO %d\n", MPCIE_SW);
 363                return -ENODEV;
 364        }
 365        if (gpio_direction_output(MPCIE_SW, 1)) {
 366                printf("failed to set GPIO %d direction\n", MPCIE_SW);
 367                return -ENODEV;
 368        }
 369
 370        env_set("board_name", model);
 371#endif
 372
 373        return 0;
 374}
 375#endif
 376
 377#if (defined(CONFIG_DRIVER_TI_CPSW) && !defined(CONFIG_SPL_BUILD)) || \
 378        (defined(CONFIG_SPL_ETH_SUPPORT) && defined(CONFIG_SPL_BUILD))
 379static void cpsw_control(int enabled)
 380{
 381        /* VTP can be added here */
 382
 383        return;
 384}
 385
 386static struct cpsw_slave_data cpsw_slaves[] = {
 387        {
 388                .slave_reg_ofs  = 0x208,
 389                .sliver_reg_ofs = 0xd80,
 390                .phy_addr       = 0,
 391        },
 392        {
 393                .slave_reg_ofs  = 0x308,
 394                .sliver_reg_ofs = 0xdc0,
 395                .phy_addr       = 7,
 396        },
 397};
 398
 399static struct cpsw_platform_data cpsw_data = {
 400        .mdio_base              = CPSW_MDIO_BASE,
 401        .cpsw_base              = CPSW_BASE,
 402        .mdio_div               = 0xff,
 403        .channels               = 8,
 404        .cpdma_reg_ofs          = 0x800,
 405        .slaves                 = 2,
 406        .slave_data             = cpsw_slaves,
 407        .active_slave           = 1,
 408        .ale_reg_ofs            = 0xd00,
 409        .ale_entries            = 1024,
 410        .host_port_reg_ofs      = 0x108,
 411        .hw_stats_reg_ofs       = 0x900,
 412        .bd_ram_ofs             = 0x2000,
 413        .mac_control            = (1 << 5),
 414        .control                = cpsw_control,
 415        .host_port_num          = 0,
 416        .version                = CPSW_CTRL_VERSION_2,
 417};
 418#endif
 419
 420#if ((defined(CONFIG_SPL_ETH_SUPPORT) || defined(CONFIG_SPL_USB_ETHER)) \
 421                && defined(CONFIG_SPL_BUILD)) || \
 422        ((defined(CONFIG_DRIVER_TI_CPSW) || \
 423          defined(CONFIG_USB_ETHER) && defined(CONFIG_USB_MUSB_GADGET)) && \
 424         !defined(CONFIG_SPL_BUILD))
 425int board_eth_init(bd_t *bis)
 426{
 427        int rv, n = 0;
 428        uint8_t mac_addr[6];
 429        uint32_t mac_hi, mac_lo;
 430
 431        /*
 432         * Note here that we're using CPSW1 since that has a 1Gbit PHY while
 433         * CSPW0 has a 100Mbit PHY.
 434         *
 435         * On product, CPSW1 maps to port labeled WAN.
 436         */
 437
 438        /* try reading mac address from efuse */
 439        mac_lo = readl(&cdev->macid1l);
 440        mac_hi = readl(&cdev->macid1h);
 441        mac_addr[0] = mac_hi & 0xFF;
 442        mac_addr[1] = (mac_hi & 0xFF00) >> 8;
 443        mac_addr[2] = (mac_hi & 0xFF0000) >> 16;
 444        mac_addr[3] = (mac_hi & 0xFF000000) >> 24;
 445        mac_addr[4] = mac_lo & 0xFF;
 446        mac_addr[5] = (mac_lo & 0xFF00) >> 8;
 447
 448#if (defined(CONFIG_DRIVER_TI_CPSW) && !defined(CONFIG_SPL_BUILD)) || \
 449        (defined(CONFIG_SPL_ETH_SUPPORT) && defined(CONFIG_SPL_BUILD))
 450        if (!env_get("ethaddr")) {
 451                printf("<ethaddr> not set. Validating first E-fuse MAC\n");
 452
 453                if (is_valid_ethaddr(mac_addr))
 454                        eth_env_set_enetaddr("ethaddr", mac_addr);
 455        }
 456
 457#ifdef CONFIG_DRIVER_TI_CPSW
 458        writel((GMII1_SEL_RMII | GMII2_SEL_RGMII | RGMII2_IDMODE), &cdev->miisel);
 459        cpsw_slaves[1].phy_if = PHY_INTERFACE_MODE_RGMII;
 460        rv = cpsw_register(&cpsw_data);
 461        if (rv < 0)
 462                printf("Error %d registering CPSW switch\n", rv);
 463        else
 464                n += rv;
 465#endif
 466
 467        /*
 468         *
 469         * CPSW RGMII Internal Delay Mode is not supported in all PVT
 470         * operating points.  So we must set the TX clock delay feature
 471         * in the AR8051 PHY.  Since we only support a single ethernet
 472         * device in U-Boot, we only do this for the first instance.
 473         */
 474#define AR8051_PHY_DEBUG_ADDR_REG       0x1d
 475#define AR8051_PHY_DEBUG_DATA_REG       0x1e
 476#define AR8051_DEBUG_RGMII_CLK_DLY_REG  0x5
 477#define AR8051_RGMII_TX_CLK_DLY         0x100
 478        const char *devname;
 479        devname = miiphy_get_current_dev();
 480
 481        miiphy_write(devname, 0x7, AR8051_PHY_DEBUG_ADDR_REG,
 482                        AR8051_DEBUG_RGMII_CLK_DLY_REG);
 483        miiphy_write(devname, 0x7, AR8051_PHY_DEBUG_DATA_REG,
 484                        AR8051_RGMII_TX_CLK_DLY);
 485#endif
 486        return n;
 487}
 488#endif
 489