1ea7b96b6SMatt Porter /* 2ea7b96b6SMatt Porter * evm.c 3ea7b96b6SMatt Porter * 4ea7b96b6SMatt Porter * Board functions for TI814x EVM 5ea7b96b6SMatt Porter * 6ea7b96b6SMatt Porter * Copyright (C) 2011, Texas Instruments, Incorporated - http://www.ti.com/ 7ea7b96b6SMatt Porter * 8ea7b96b6SMatt Porter * This program is free software; you can redistribute it and/or 9ea7b96b6SMatt Porter * modify it under the terms of the GNU General Public License as 10ea7b96b6SMatt Porter * published by the Free Software Foundation; either version 2 of 11ea7b96b6SMatt Porter * the License, or (at your option) any later version. 12ea7b96b6SMatt Porter * 13ea7b96b6SMatt Porter * This program is distributed in the hope that it will be useful, 14ea7b96b6SMatt Porter * but WITHOUT ANY WARRANTY; without even the implied warranty of 15ea7b96b6SMatt Porter * MERCHANTABILITY or FITNESS FOR A PARTICULAR /PURPOSE. See the 16ea7b96b6SMatt Porter * GNU General Public License for more details. 17ea7b96b6SMatt Porter */ 18ea7b96b6SMatt Porter 19ea7b96b6SMatt Porter #include <common.h> 20*cd87464dSMatt Porter #include <cpsw.h> 21ea7b96b6SMatt Porter #include <errno.h> 22ea7b96b6SMatt Porter #include <spl.h> 23ea7b96b6SMatt Porter #include <asm/arch/cpu.h> 24ea7b96b6SMatt Porter #include <asm/arch/hardware.h> 25ea7b96b6SMatt Porter #include <asm/arch/omap.h> 26ea7b96b6SMatt Porter #include <asm/arch/ddr_defs.h> 27ea7b96b6SMatt Porter #include <asm/arch/clock.h> 28ea7b96b6SMatt Porter #include <asm/arch/gpio.h> 29ea7b96b6SMatt Porter #include <asm/arch/mmc_host_def.h> 30ea7b96b6SMatt Porter #include <asm/arch/sys_proto.h> 31ea7b96b6SMatt Porter #include <asm/io.h> 32ea7b96b6SMatt Porter #include <asm/emif.h> 33ea7b96b6SMatt Porter #include <asm/gpio.h> 34ea7b96b6SMatt Porter #include "evm.h" 35ea7b96b6SMatt Porter 36ea7b96b6SMatt Porter DECLARE_GLOBAL_DATA_PTR; 37ea7b96b6SMatt Porter 38ea7b96b6SMatt Porter #ifdef CONFIG_SPL_BUILD 39ea7b96b6SMatt Porter static struct wd_timer *wdtimer = (struct wd_timer *)WDT_BASE; 40ea7b96b6SMatt Porter static struct uart_sys *uart_base = (struct uart_sys *)DEFAULT_UART_BASE; 41ea7b96b6SMatt Porter #endif 42ea7b96b6SMatt Porter 43*cd87464dSMatt Porter static struct ctrl_dev *cdev = (struct ctrl_dev *)CTRL_DEVICE_BASE; 44*cd87464dSMatt Porter 45ea7b96b6SMatt Porter /* UART Defines */ 46ea7b96b6SMatt Porter #ifdef CONFIG_SPL_BUILD 47ea7b96b6SMatt Porter #define UART_RESET (0x1 << 1) 48ea7b96b6SMatt Porter #define UART_CLK_RUNNING_MASK 0x1 49ea7b96b6SMatt Porter #define UART_SMART_IDLE_EN (0x1 << 0x3) 50ea7b96b6SMatt Porter 51ea7b96b6SMatt Porter static void rtc32k_enable(void) 52ea7b96b6SMatt Porter { 53ea7b96b6SMatt Porter struct rtc_regs *rtc = (struct rtc_regs *)RTC_BASE; 54ea7b96b6SMatt Porter 55ea7b96b6SMatt Porter /* 56ea7b96b6SMatt Porter * Unlock the RTC's registers. For more details please see the 57ea7b96b6SMatt Porter * RTC_SS section of the TRM. In order to unlock we need to 58ea7b96b6SMatt Porter * write these specific values (keys) in this order. 59ea7b96b6SMatt Porter */ 60ea7b96b6SMatt Porter writel(0x83e70b13, &rtc->kick0r); 61ea7b96b6SMatt Porter writel(0x95a4f1e0, &rtc->kick1r); 62ea7b96b6SMatt Porter 63ea7b96b6SMatt Porter /* Enable the RTC 32K OSC by setting bits 3 and 6. */ 64ea7b96b6SMatt Porter writel((1 << 3) | (1 << 6), &rtc->osc); 65ea7b96b6SMatt Porter } 66ea7b96b6SMatt Porter 67ea7b96b6SMatt Porter static void uart_enable(void) 68ea7b96b6SMatt Porter { 69ea7b96b6SMatt Porter u32 regVal; 70ea7b96b6SMatt Porter 71ea7b96b6SMatt Porter /* UART softreset */ 72ea7b96b6SMatt Porter regVal = readl(&uart_base->uartsyscfg); 73ea7b96b6SMatt Porter regVal |= UART_RESET; 74ea7b96b6SMatt Porter writel(regVal, &uart_base->uartsyscfg); 75ea7b96b6SMatt Porter while ((readl(&uart_base->uartsyssts) & 76ea7b96b6SMatt Porter UART_CLK_RUNNING_MASK) != UART_CLK_RUNNING_MASK) 77ea7b96b6SMatt Porter ; 78ea7b96b6SMatt Porter 79ea7b96b6SMatt Porter /* Disable smart idle */ 80ea7b96b6SMatt Porter regVal = readl(&uart_base->uartsyscfg); 81ea7b96b6SMatt Porter regVal |= UART_SMART_IDLE_EN; 82ea7b96b6SMatt Porter writel(regVal, &uart_base->uartsyscfg); 83ea7b96b6SMatt Porter } 84ea7b96b6SMatt Porter 85ea7b96b6SMatt Porter static void wdt_disable(void) 86ea7b96b6SMatt Porter { 87ea7b96b6SMatt Porter writel(0xAAAA, &wdtimer->wdtwspr); 88ea7b96b6SMatt Porter while (readl(&wdtimer->wdtwwps) != 0x0) 89ea7b96b6SMatt Porter ; 90ea7b96b6SMatt Porter writel(0x5555, &wdtimer->wdtwspr); 91ea7b96b6SMatt Porter while (readl(&wdtimer->wdtwwps) != 0x0) 92ea7b96b6SMatt Porter ; 93ea7b96b6SMatt Porter } 94ea7b96b6SMatt Porter 95ea7b96b6SMatt Porter static const struct cmd_control evm_ddr2_cctrl_data = { 96ea7b96b6SMatt Porter .cmd0csratio = 0x80, 97ea7b96b6SMatt Porter .cmd0dldiff = 0x04, 98ea7b96b6SMatt Porter .cmd0iclkout = 0x00, 99ea7b96b6SMatt Porter 100ea7b96b6SMatt Porter .cmd1csratio = 0x80, 101ea7b96b6SMatt Porter .cmd1dldiff = 0x04, 102ea7b96b6SMatt Porter .cmd1iclkout = 0x00, 103ea7b96b6SMatt Porter 104ea7b96b6SMatt Porter .cmd2csratio = 0x80, 105ea7b96b6SMatt Porter .cmd2dldiff = 0x04, 106ea7b96b6SMatt Porter .cmd2iclkout = 0x00, 107ea7b96b6SMatt Porter }; 108ea7b96b6SMatt Porter 109ea7b96b6SMatt Porter static const struct emif_regs evm_ddr2_emif0_regs = { 110ea7b96b6SMatt Porter .sdram_config = 0x40801ab2, 111ea7b96b6SMatt Porter .ref_ctrl = 0x10000c30, 112ea7b96b6SMatt Porter .sdram_tim1 = 0x0aaaf552, 113ea7b96b6SMatt Porter .sdram_tim2 = 0x043631d2, 114ea7b96b6SMatt Porter .sdram_tim3 = 0x00000327, 115ea7b96b6SMatt Porter .emif_ddr_phy_ctlr_1 = 0x00000007 116ea7b96b6SMatt Porter }; 117ea7b96b6SMatt Porter 118ea7b96b6SMatt Porter static const struct emif_regs evm_ddr2_emif1_regs = { 119ea7b96b6SMatt Porter .sdram_config = 0x40801ab2, 120ea7b96b6SMatt Porter .ref_ctrl = 0x10000c30, 121ea7b96b6SMatt Porter .sdram_tim1 = 0x0aaaf552, 122ea7b96b6SMatt Porter .sdram_tim2 = 0x043631d2, 123ea7b96b6SMatt Porter .sdram_tim3 = 0x00000327, 124ea7b96b6SMatt Porter .emif_ddr_phy_ctlr_1 = 0x00000007 125ea7b96b6SMatt Porter }; 126ea7b96b6SMatt Porter 127ea7b96b6SMatt Porter const struct dmm_lisa_map_regs evm_lisa_map_regs = { 128ea7b96b6SMatt Porter .dmm_lisa_map_0 = 0x00000000, 129ea7b96b6SMatt Porter .dmm_lisa_map_1 = 0x00000000, 130ea7b96b6SMatt Porter .dmm_lisa_map_2 = 0x806c0300, 131ea7b96b6SMatt Porter .dmm_lisa_map_3 = 0x806c0300, 132ea7b96b6SMatt Porter }; 133ea7b96b6SMatt Porter 134ea7b96b6SMatt Porter static const struct ddr_data evm_ddr2_data = { 135ea7b96b6SMatt Porter .datardsratio0 = ((0x35<<10) | (0x35<<0)), 136ea7b96b6SMatt Porter .datawdsratio0 = ((0x20<<10) | (0x20<<0)), 137ea7b96b6SMatt Porter .datawiratio0 = ((0<<10) | (0<<0)), 138ea7b96b6SMatt Porter .datagiratio0 = ((0<<10) | (0<<0)), 139ea7b96b6SMatt Porter .datafwsratio0 = ((0x90<<10) | (0x90<<0)), 140ea7b96b6SMatt Porter .datawrsratio0 = ((0x50<<10) | (0x50<<0)), 141ea7b96b6SMatt Porter .datauserank0delay = 1, 142ea7b96b6SMatt Porter .datadldiff0 = 0x4, 143ea7b96b6SMatt Porter }; 144ea7b96b6SMatt Porter #endif 145ea7b96b6SMatt Porter 146ea7b96b6SMatt Porter /* 147ea7b96b6SMatt Porter * early system init of muxing and clocks. 148ea7b96b6SMatt Porter */ 149ea7b96b6SMatt Porter void s_init(void) 150ea7b96b6SMatt Porter { 151ea7b96b6SMatt Porter #ifdef CONFIG_SPL_BUILD 152ea7b96b6SMatt Porter /* WDT1 is already running when the bootloader gets control 153ea7b96b6SMatt Porter * Disable it to avoid "random" resets 154ea7b96b6SMatt Porter */ 155ea7b96b6SMatt Porter wdt_disable(); 156ea7b96b6SMatt Porter 157035d5639SMatt Porter /* Enable timer */ 158035d5639SMatt Porter timer_init(); 159035d5639SMatt Porter 160ea7b96b6SMatt Porter /* Setup the PLLs and the clocks for the peripherals */ 161ea7b96b6SMatt Porter pll_init(); 162ea7b96b6SMatt Porter 163ea7b96b6SMatt Porter /* Enable RTC32K clock */ 164ea7b96b6SMatt Porter rtc32k_enable(); 165ea7b96b6SMatt Porter 166ea7b96b6SMatt Porter /* Set UART pins */ 167ea7b96b6SMatt Porter enable_uart0_pin_mux(); 168ea7b96b6SMatt Porter 169ea7b96b6SMatt Porter /* Set MMC pins */ 170ea7b96b6SMatt Porter enable_mmc1_pin_mux(); 171ea7b96b6SMatt Porter 172*cd87464dSMatt Porter /* Set Ethernet pins */ 173*cd87464dSMatt Porter enable_enet_pin_mux(); 174*cd87464dSMatt Porter 175ea7b96b6SMatt Porter /* Enable UART */ 176ea7b96b6SMatt Porter uart_enable(); 177ea7b96b6SMatt Porter 178ea7b96b6SMatt Porter gd = &gdata; 179ea7b96b6SMatt Porter 180ea7b96b6SMatt Porter preloader_console_init(); 181ea7b96b6SMatt Porter 182ea7b96b6SMatt Porter config_dmm(&evm_lisa_map_regs); 183ea7b96b6SMatt Porter 184ea7b96b6SMatt Porter config_ddr(0, 0, &evm_ddr2_data, &evm_ddr2_cctrl_data, 185ea7b96b6SMatt Porter &evm_ddr2_emif0_regs, 0); 186ea7b96b6SMatt Porter config_ddr(0, 0, &evm_ddr2_data, &evm_ddr2_cctrl_data, 187ea7b96b6SMatt Porter &evm_ddr2_emif1_regs, 1); 188ea7b96b6SMatt Porter #endif 189ea7b96b6SMatt Porter } 190ea7b96b6SMatt Porter 191ea7b96b6SMatt Porter /* 192ea7b96b6SMatt Porter * Basic board specific setup. Pinmux has been handled already. 193ea7b96b6SMatt Porter */ 194ea7b96b6SMatt Porter int board_init(void) 195ea7b96b6SMatt Porter { 196ea7b96b6SMatt Porter gd->bd->bi_boot_params = PHYS_DRAM_1 + 0x100; 197ea7b96b6SMatt Porter return 0; 198ea7b96b6SMatt Porter } 199ea7b96b6SMatt Porter 200ea7b96b6SMatt Porter #if !defined(CONFIG_SPL_BUILD) && defined(CONFIG_GENERIC_MMC) 201ea7b96b6SMatt Porter int board_mmc_init(bd_t *bis) 202ea7b96b6SMatt Porter { 203ea7b96b6SMatt Porter omap_mmc_init(1, 0, 0, -1, -1); 204ea7b96b6SMatt Porter 205ea7b96b6SMatt Porter return 0; 206ea7b96b6SMatt Porter } 207ea7b96b6SMatt Porter #endif 208*cd87464dSMatt Porter 209*cd87464dSMatt Porter #ifdef CONFIG_DRIVER_TI_CPSW 210*cd87464dSMatt Porter static void cpsw_control(int enabled) 211*cd87464dSMatt Porter { 212*cd87464dSMatt Porter /* VTP can be added here */ 213*cd87464dSMatt Porter 214*cd87464dSMatt Porter return; 215*cd87464dSMatt Porter } 216*cd87464dSMatt Porter 217*cd87464dSMatt Porter static struct cpsw_slave_data cpsw_slaves[] = { 218*cd87464dSMatt Porter { 219*cd87464dSMatt Porter .slave_reg_ofs = 0x50, 220*cd87464dSMatt Porter .sliver_reg_ofs = 0x700, 221*cd87464dSMatt Porter .phy_id = 1, 222*cd87464dSMatt Porter }, 223*cd87464dSMatt Porter { 224*cd87464dSMatt Porter .slave_reg_ofs = 0x90, 225*cd87464dSMatt Porter .sliver_reg_ofs = 0x740, 226*cd87464dSMatt Porter .phy_id = 0, 227*cd87464dSMatt Porter }, 228*cd87464dSMatt Porter }; 229*cd87464dSMatt Porter 230*cd87464dSMatt Porter static struct cpsw_platform_data cpsw_data = { 231*cd87464dSMatt Porter .mdio_base = CPSW_MDIO_BASE, 232*cd87464dSMatt Porter .cpsw_base = CPSW_BASE, 233*cd87464dSMatt Porter .mdio_div = 0xff, 234*cd87464dSMatt Porter .channels = 8, 235*cd87464dSMatt Porter .cpdma_reg_ofs = 0x100, 236*cd87464dSMatt Porter .slaves = 1, 237*cd87464dSMatt Porter .slave_data = cpsw_slaves, 238*cd87464dSMatt Porter .ale_reg_ofs = 0x600, 239*cd87464dSMatt Porter .ale_entries = 1024, 240*cd87464dSMatt Porter .host_port_reg_ofs = 0x28, 241*cd87464dSMatt Porter .hw_stats_reg_ofs = 0x400, 242*cd87464dSMatt Porter .mac_control = (1 << 5), 243*cd87464dSMatt Porter .control = cpsw_control, 244*cd87464dSMatt Porter .host_port_num = 0, 245*cd87464dSMatt Porter .version = CPSW_CTRL_VERSION_1, 246*cd87464dSMatt Porter }; 247*cd87464dSMatt Porter #endif 248*cd87464dSMatt Porter 249*cd87464dSMatt Porter int board_eth_init(bd_t *bis) 250*cd87464dSMatt Porter { 251*cd87464dSMatt Porter uint8_t mac_addr[6]; 252*cd87464dSMatt Porter uint32_t mac_hi, mac_lo; 253*cd87464dSMatt Porter 254*cd87464dSMatt Porter if (!eth_getenv_enetaddr("ethaddr", mac_addr)) { 255*cd87464dSMatt Porter printf("<ethaddr> not set. Reading from E-fuse\n"); 256*cd87464dSMatt Porter /* try reading mac address from efuse */ 257*cd87464dSMatt Porter mac_lo = readl(&cdev->macid0l); 258*cd87464dSMatt Porter mac_hi = readl(&cdev->macid0h); 259*cd87464dSMatt Porter mac_addr[0] = mac_hi & 0xFF; 260*cd87464dSMatt Porter mac_addr[1] = (mac_hi & 0xFF00) >> 8; 261*cd87464dSMatt Porter mac_addr[2] = (mac_hi & 0xFF0000) >> 16; 262*cd87464dSMatt Porter mac_addr[3] = (mac_hi & 0xFF000000) >> 24; 263*cd87464dSMatt Porter mac_addr[4] = mac_lo & 0xFF; 264*cd87464dSMatt Porter mac_addr[5] = (mac_lo & 0xFF00) >> 8; 265*cd87464dSMatt Porter 266*cd87464dSMatt Porter if (is_valid_ether_addr(mac_addr)) 267*cd87464dSMatt Porter eth_setenv_enetaddr("ethaddr", mac_addr); 268*cd87464dSMatt Porter else 269*cd87464dSMatt Porter printf("Unable to read MAC address. Set <ethaddr>\n"); 270*cd87464dSMatt Porter } 271*cd87464dSMatt Porter 272*cd87464dSMatt Porter return cpsw_register(&cpsw_data); 273*cd87464dSMatt Porter } 274