uboot/board/davinci/da8xxevm/da850evm.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 * Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com/
   4 *
   5 * Based on da830evm.c. Original Copyrights follow:
   6 *
   7 * Copyright (C) 2009 Nick Thompson, GE Fanuc, Ltd. <nick.thompson@gefanuc.com>
   8 * Copyright (C) 2007 Sergey Kubushyn <ksi@koi8.net>
   9 */
  10
  11#include <common.h>
  12#include <dm.h>
  13#include <env.h>
  14#include <i2c.h>
  15#include <init.h>
  16#include <net.h>
  17#include <spi.h>
  18#include <spi_flash.h>
  19#include <asm/arch/hardware.h>
  20#include <asm/ti-common/davinci_nand.h>
  21#include <asm/arch/emac_defs.h>
  22#include <asm/arch/pinmux_defs.h>
  23#include <asm/io.h>
  24#include <asm/arch/davinci_misc.h>
  25#include <linux/errno.h>
  26#include <hwconfig.h>
  27#include <asm/mach-types.h>
  28#include <asm/gpio.h>
  29
  30#ifdef CONFIG_MMC_DAVINCI
  31#include <mmc.h>
  32#include <asm/arch/sdmmc_defs.h>
  33#endif
  34
  35DECLARE_GLOBAL_DATA_PTR;
  36
  37#ifdef CONFIG_DRIVER_TI_EMAC
  38#ifdef CONFIG_DRIVER_TI_EMAC_USE_RMII
  39#define HAS_RMII 1
  40#else
  41#define HAS_RMII 0
  42#endif
  43#endif /* CONFIG_DRIVER_TI_EMAC */
  44
  45#define CFG_MAC_ADDR_SPI_BUS    0
  46#define CFG_MAC_ADDR_SPI_CS     0
  47#define CFG_MAC_ADDR_SPI_MAX_HZ CONFIG_SF_DEFAULT_SPEED
  48#define CFG_MAC_ADDR_SPI_MODE   SPI_MODE_3
  49
  50#define CFG_MAC_ADDR_OFFSET     (flash->size - SZ_64K)
  51
  52#ifdef CONFIG_MAC_ADDR_IN_SPIFLASH
  53static int get_mac_addr(u8 *addr)
  54{
  55        struct spi_flash *flash;
  56        int ret;
  57
  58        flash = spi_flash_probe(CFG_MAC_ADDR_SPI_BUS, CFG_MAC_ADDR_SPI_CS,
  59                        CFG_MAC_ADDR_SPI_MAX_HZ, CFG_MAC_ADDR_SPI_MODE);
  60        if (!flash) {
  61                printf("Error - unable to probe SPI flash.\n");
  62                return -1;
  63        }
  64
  65        ret = spi_flash_read(flash, (CFG_MAC_ADDR_OFFSET), 6, addr);
  66        if (ret) {
  67                printf("Error - unable to read MAC address from SPI flash.\n");
  68                return -1;
  69        }
  70
  71        return ret;
  72}
  73#endif
  74
  75void dsp_lpsc_on(unsigned domain, unsigned int id)
  76{
  77        dv_reg_p mdstat, mdctl, ptstat, ptcmd;
  78        struct davinci_psc_regs *psc_regs;
  79
  80        psc_regs = davinci_psc0_regs;
  81        mdstat = &psc_regs->psc0.mdstat[id];
  82        mdctl = &psc_regs->psc0.mdctl[id];
  83        ptstat = &psc_regs->ptstat;
  84        ptcmd = &psc_regs->ptcmd;
  85
  86        while (*ptstat & (0x1 << domain))
  87                ;
  88
  89        if ((*mdstat & 0x1f) == 0x03)
  90                return;                 /* Already on and enabled */
  91
  92        *mdctl |= 0x03;
  93
  94        *ptcmd = 0x1 << domain;
  95
  96        while (*ptstat & (0x1 << domain))
  97                ;
  98        while ((*mdstat & 0x1f) != 0x03)
  99                ;               /* Probably an overkill... */
 100}
 101
 102static void dspwake(void)
 103{
 104        unsigned *resetvect = (unsigned *)DAVINCI_L3CBARAM_BASE;
 105        u32 val;
 106
 107        /* if the device is ARM only, return */
 108        if ((readl(CHIP_REV_ID_REG) & 0x3f) == 0x10)
 109                return;
 110
 111        if (hwconfig_subarg_cmp_f("dsp", "wake", "no", NULL))
 112                return;
 113
 114        *resetvect++ = 0x1E000; /* DSP Idle */
 115        /* clear out the next 10 words as NOP */
 116        memset(resetvect, 0, sizeof(unsigned) *10);
 117
 118        /* setup the DSP reset vector */
 119        writel(DAVINCI_L3CBARAM_BASE, HOST1CFG);
 120
 121        dsp_lpsc_on(1, DAVINCI_LPSC_GEM);
 122        val = readl(PSC0_MDCTL + (15 * 4));
 123        val |= 0x100;
 124        writel(val, (PSC0_MDCTL + (15 * 4)));
 125}
 126
 127int misc_init_r(void)
 128{
 129        dspwake();
 130
 131#if defined(CONFIG_MAC_ADDR_IN_SPIFLASH) || defined(CONFIG_MAC_ADDR_IN_EEPROM)
 132
 133        uchar env_enetaddr[6];
 134        int enetaddr_found;
 135
 136        enetaddr_found = eth_env_get_enetaddr("ethaddr", env_enetaddr);
 137
 138#endif
 139
 140#ifdef CONFIG_MAC_ADDR_IN_SPIFLASH
 141        int spi_mac_read;
 142        uchar buff[6];
 143
 144        spi_mac_read = get_mac_addr(buff);
 145        buff[0] = 0;
 146
 147        /*
 148         * MAC address not present in the environment
 149         * try and read the MAC address from SPI flash
 150         * and set it.
 151         */
 152        if (!enetaddr_found) {
 153                if (!spi_mac_read) {
 154                        if (is_valid_ethaddr(buff)) {
 155                                if (eth_env_set_enetaddr("ethaddr", buff)) {
 156                                        printf("Warning: Failed to "
 157                                        "set MAC address from SPI flash\n");
 158                                }
 159                        } else {
 160                                        printf("Warning: Invalid "
 161                                        "MAC address read from SPI flash\n");
 162                        }
 163                }
 164        } else {
 165                /*
 166                 * MAC address present in environment compare it with
 167                 * the MAC address in SPI flash and warn on mismatch
 168                 */
 169                if (!spi_mac_read && is_valid_ethaddr(buff) &&
 170                    memcmp(env_enetaddr, buff, 6))
 171                        printf("Warning: MAC address in SPI flash don't match "
 172                                        "with the MAC address in the environment\n");
 173                printf("Default using MAC address from environment\n");
 174        }
 175
 176#elif defined(CONFIG_MAC_ADDR_IN_EEPROM)
 177        uint8_t enetaddr[8];
 178        int eeprom_mac_read;
 179
 180        /* Read Ethernet MAC address from EEPROM */
 181        eeprom_mac_read = dvevm_read_mac_address(enetaddr);
 182
 183        /*
 184         * MAC address not present in the environment
 185         * try and read the MAC address from EEPROM flash
 186         * and set it.
 187         */
 188        if (!enetaddr_found) {
 189                if (eeprom_mac_read)
 190                        /* Set Ethernet MAC address from EEPROM */
 191                        davinci_sync_env_enetaddr(enetaddr);
 192        } else {
 193                /*
 194                 * MAC address present in environment compare it with
 195                 * the MAC address in EEPROM and warn on mismatch
 196                 */
 197                if (eeprom_mac_read && memcmp(enetaddr, env_enetaddr, 6))
 198                        printf("Warning: MAC address in EEPROM don't match "
 199                                        "with the MAC address in the environment\n");
 200                printf("Default using MAC address from environment\n");
 201        }
 202
 203#endif
 204        return 0;
 205}
 206
 207static const struct pinmux_config gpio_pins[] = {
 208#ifdef CONFIG_MTD_NOR_FLASH
 209        /* GP0[11] is required for NOR to work on Rev 3 EVMs */
 210        { pinmux(0), 8, 4 },    /* GP0[11] */
 211#endif
 212#ifdef CONFIG_MMC_DAVINCI
 213        /* GP0[11] is required for SD to work on Rev 3 EVMs */
 214        { pinmux(0),  8, 4 },   /* GP0[11] */
 215#endif
 216};
 217
 218const struct pinmux_resource pinmuxes[] = {
 219#ifdef CONFIG_DRIVER_TI_EMAC
 220        PINMUX_ITEM(emac_pins_mdio),
 221#ifdef CONFIG_DRIVER_TI_EMAC_USE_RMII
 222        PINMUX_ITEM(emac_pins_rmii),
 223#else
 224        PINMUX_ITEM(emac_pins_mii),
 225#endif
 226#endif
 227#ifdef CONFIG_SPI_FLASH
 228        PINMUX_ITEM(spi1_pins_base),
 229        PINMUX_ITEM(spi1_pins_scs0),
 230#endif
 231        PINMUX_ITEM(uart2_pins_txrx),
 232        PINMUX_ITEM(uart2_pins_rtscts),
 233        PINMUX_ITEM(i2c0_pins),
 234#ifdef CONFIG_NAND_DAVINCI
 235        PINMUX_ITEM(emifa_pins_cs3),
 236        PINMUX_ITEM(emifa_pins_cs4),
 237        PINMUX_ITEM(emifa_pins_nand),
 238#elif defined(CONFIG_MTD_NOR_FLASH)
 239        PINMUX_ITEM(emifa_pins_cs2),
 240        PINMUX_ITEM(emifa_pins_nor),
 241#endif
 242        PINMUX_ITEM(gpio_pins),
 243#ifdef CONFIG_MMC_DAVINCI
 244        PINMUX_ITEM(mmc0_pins),
 245#endif
 246};
 247
 248const int pinmuxes_size = ARRAY_SIZE(pinmuxes);
 249
 250const struct lpsc_resource lpsc[] = {
 251        { DAVINCI_LPSC_AEMIF }, /* NAND, NOR */
 252        { DAVINCI_LPSC_SPI1 },  /* Serial Flash */
 253        { DAVINCI_LPSC_EMAC },  /* image download */
 254        { DAVINCI_LPSC_UART2 }, /* console */
 255        { DAVINCI_LPSC_GPIO },
 256#ifdef CONFIG_MMC_DAVINCI
 257        { DAVINCI_LPSC_MMC_SD },
 258#endif
 259};
 260
 261const int lpsc_size = ARRAY_SIZE(lpsc);
 262
 263#ifndef CONFIG_DA850_EVM_MAX_CPU_CLK
 264#define CONFIG_DA850_EVM_MAX_CPU_CLK    300000000
 265#endif
 266
 267#define REV_AM18X_EVM           0x100
 268
 269/*
 270 * get_board_rev() - setup to pass kernel board revision information
 271 * Returns:
 272 * bit[0-3]     Maximum cpu clock rate supported by onboard SoC
 273 *              0000b - 300 MHz
 274 *              0001b - 372 MHz
 275 *              0010b - 408 MHz
 276 *              0011b - 456 MHz
 277 */
 278u32 get_board_rev(void)
 279{
 280        char *s;
 281        u32 maxcpuclk = CONFIG_DA850_EVM_MAX_CPU_CLK;
 282        u32 rev = 0;
 283
 284        s = env_get("maxcpuclk");
 285        if (s)
 286                maxcpuclk = simple_strtoul(s, NULL, 10);
 287
 288        if (maxcpuclk >= 456000000)
 289                rev = 3;
 290        else if (maxcpuclk >= 408000000)
 291                rev = 2;
 292        else if (maxcpuclk >= 372000000)
 293                rev = 1;
 294        return rev;
 295}
 296
 297int board_early_init_f(void)
 298{
 299        /*
 300         * Power on required peripherals
 301         * ARM does not have access by default to PSC0 and PSC1
 302         * assuming here that the DSP bootloader has set the IOPU
 303         * such that PSC access is available to ARM
 304         */
 305        if (da8xx_configure_lpsc_items(lpsc, ARRAY_SIZE(lpsc)))
 306                return 1;
 307
 308        return 0;
 309}
 310
 311int board_init(void)
 312{
 313        irq_init();
 314
 315#ifdef CONFIG_NAND_DAVINCI
 316        /*
 317         * NAND CS setup - cycle counts based on da850evm NAND timings in the
 318         * Linux kernel @ 25MHz EMIFA
 319         */
 320        writel((DAVINCI_ABCR_WSETUP(2) |
 321                DAVINCI_ABCR_WSTROBE(2) |
 322                DAVINCI_ABCR_WHOLD(1) |
 323                DAVINCI_ABCR_RSETUP(1) |
 324                DAVINCI_ABCR_RSTROBE(4) |
 325                DAVINCI_ABCR_RHOLD(0) |
 326                DAVINCI_ABCR_TA(1) |
 327                DAVINCI_ABCR_ASIZE_8BIT),
 328               &davinci_emif_regs->ab2cr); /* CS3 */
 329#endif
 330
 331        /* arch number of the board */
 332        gd->bd->bi_arch_number = MACH_TYPE_DAVINCI_DA850_EVM;
 333
 334        /* address of boot parameters */
 335        gd->bd->bi_boot_params = LINUX_BOOT_PARAM_ADDR;
 336
 337        /* setup the SUSPSRC for ARM to control emulation suspend */
 338        writel(readl(&davinci_syscfg_regs->suspsrc) &
 339               ~(DAVINCI_SYSCFG_SUSPSRC_EMAC | DAVINCI_SYSCFG_SUSPSRC_I2C |
 340                 DAVINCI_SYSCFG_SUSPSRC_SPI1 | DAVINCI_SYSCFG_SUSPSRC_TIMER0 |
 341                 DAVINCI_SYSCFG_SUSPSRC_UART2),
 342               &davinci_syscfg_regs->suspsrc);
 343
 344#ifdef CONFIG_MTD_NOR_FLASH
 345        /* Set the GPIO direction as output */
 346        clrbits_le32((u32 *)GPIO_BANK0_REG_DIR_ADDR, (0x01 << 11));
 347
 348        /* Set the output as low */
 349        writel(0x01 << 11, GPIO_BANK0_REG_CLR_ADDR);
 350#endif
 351
 352#ifdef CONFIG_MMC_DAVINCI
 353        /* Set the GPIO direction as output */
 354        clrbits_le32((u32 *)GPIO_BANK0_REG_DIR_ADDR, (0x01 << 11));
 355
 356        /* Set the output as high */
 357        writel(0x01 << 11, GPIO_BANK0_REG_SET_ADDR);
 358#endif
 359
 360#ifdef CONFIG_DRIVER_TI_EMAC
 361        davinci_emac_mii_mode_sel(HAS_RMII);
 362#endif /* CONFIG_DRIVER_TI_EMAC */
 363
 364        return 0;
 365}
 366
 367#ifdef CONFIG_DRIVER_TI_EMAC
 368
 369#ifdef CONFIG_DRIVER_TI_EMAC_USE_RMII
 370/**
 371 * rmii_hw_init
 372 *
 373 * DA850/OMAP-L138 EVM can interface to a daughter card for
 374 * additional features. This card has an I2C GPIO Expander TCA6416
 375 * to select the required functions like camera, RMII Ethernet,
 376 * character LCD, video.
 377 *
 378 * Initialization of the expander involves configuring the
 379 * polarity and direction of the ports. P07-P05 are used here.
 380 * These ports are connected to a Mux chip which enables only one
 381 * functionality at a time.
 382 *
 383 * For RMII phy to respond, the MII MDIO clock has to be  disabled
 384 * since both the PHY devices have address as zero. The MII MDIO
 385 * clock is controlled via GPIO2[6].
 386 *
 387 * This code is valid for Beta version of the hardware
 388 */
 389int rmii_hw_init(void)
 390{
 391        const struct pinmux_config gpio_pins[] = {
 392                { pinmux(6), 8, 1 }
 393        };
 394        u_int8_t buf[2];
 395        unsigned int temp;
 396        int ret;
 397
 398        /* PinMux for GPIO */
 399        if (davinci_configure_pin_mux(gpio_pins, ARRAY_SIZE(gpio_pins)) != 0)
 400                return 1;
 401
 402        /* I2C Exapnder configuration */
 403        /* Set polarity to non-inverted */
 404        buf[0] = 0x0;
 405        buf[1] = 0x0;
 406        ret = i2c_write(CONFIG_SYS_I2C_EXPANDER_ADDR, 4, 1, buf, 2);
 407        if (ret) {
 408                printf("\nExpander @ 0x%02x write FAILED!!!\n",
 409                                CONFIG_SYS_I2C_EXPANDER_ADDR);
 410                return ret;
 411        }
 412
 413        /* Configure P07-P05 as outputs */
 414        buf[0] = 0x1f;
 415        buf[1] = 0xff;
 416        ret = i2c_write(CONFIG_SYS_I2C_EXPANDER_ADDR, 6, 1, buf, 2);
 417        if (ret) {
 418                printf("\nExpander @ 0x%02x write FAILED!!!\n",
 419                                CONFIG_SYS_I2C_EXPANDER_ADDR);
 420        }
 421
 422        /* For Ethernet RMII selection
 423         * P07(SelA)=0
 424         * P06(SelB)=1
 425         * P05(SelC)=1
 426         */
 427        if (i2c_read(CONFIG_SYS_I2C_EXPANDER_ADDR, 2, 1, buf, 1)) {
 428                printf("\nExpander @ 0x%02x read FAILED!!!\n",
 429                                CONFIG_SYS_I2C_EXPANDER_ADDR);
 430        }
 431
 432        buf[0] &= 0x1f;
 433        buf[0] |= (0 << 7) | (1 << 6) | (1 << 5);
 434        if (i2c_write(CONFIG_SYS_I2C_EXPANDER_ADDR, 2, 1, buf, 1)) {
 435                printf("\nExpander @ 0x%02x write FAILED!!!\n",
 436                                CONFIG_SYS_I2C_EXPANDER_ADDR);
 437        }
 438
 439        /* Set the output as high */
 440        temp = REG(GPIO_BANK2_REG_SET_ADDR);
 441        temp |= (0x01 << 6);
 442        REG(GPIO_BANK2_REG_SET_ADDR) = temp;
 443
 444        /* Set the GPIO direction as output */
 445        temp = REG(GPIO_BANK2_REG_DIR_ADDR);
 446        temp &= ~(0x01 << 6);
 447        REG(GPIO_BANK2_REG_DIR_ADDR) = temp;
 448
 449        return 0;
 450}
 451#endif /* CONFIG_DRIVER_TI_EMAC_USE_RMII */
 452
 453/*
 454 * Initializes on-board ethernet controllers.
 455 */
 456int board_eth_init(struct bd_info *bis)
 457{
 458#ifdef CONFIG_DRIVER_TI_EMAC_USE_RMII
 459        /* Select RMII fucntion through the expander */
 460        if (rmii_hw_init())
 461                printf("RMII hardware init failed!!!\n");
 462#endif
 463        return 0;
 464}
 465#endif /* CONFIG_DRIVER_TI_EMAC */
 466