1 /* 2 * (C) Copyright 2004-2008 3 * Texas Instruments, <www.ti.com> 4 * 5 * Author : 6 * Sunil Kumar <sunilsaini05@gmail.com> 7 * Shashi Ranjan <shashiranjanmca05@gmail.com> 8 * 9 * (C) Copyright 2009 10 * Frederik Kriewitz <frederik@kriewitz.eu> 11 * 12 * Derived from Beagle Board and 3430 SDP code by 13 * Richard Woodruff <r-woodruff2@ti.com> 14 * Syed Mohammed Khasim <khasim@ti.com> 15 * 16 * 17 * SPDX-License-Identifier: GPL-2.0+ 18 */ 19 #include <common.h> 20 #include <dm.h> 21 #include <ns16550.h> 22 #include <twl4030.h> 23 #include <asm/io.h> 24 #include <asm/arch/mmc_host_def.h> 25 #include <asm/arch/mux.h> 26 #include <asm/arch/sys_proto.h> 27 #include <asm/arch/mem.h> 28 #include <asm/mach-types.h> 29 #include "devkit8000.h" 30 #include <asm/gpio.h> 31 #ifdef CONFIG_DRIVER_DM9000 32 #include <net.h> 33 #include <netdev.h> 34 #endif 35 36 DECLARE_GLOBAL_DATA_PTR; 37 38 static u32 gpmc_net_config[GPMC_MAX_REG] = { 39 NET_GPMC_CONFIG1, 40 NET_GPMC_CONFIG2, 41 NET_GPMC_CONFIG3, 42 NET_GPMC_CONFIG4, 43 NET_GPMC_CONFIG5, 44 NET_GPMC_CONFIG6, 45 0 46 }; 47 48 static const struct ns16550_platdata devkit8000_serial = { 49 .base = OMAP34XX_UART3, 50 .reg_shift = 2, 51 .clock = V_NS16550_CLK, 52 .fcr = UART_FCR_DEFVAL, 53 }; 54 55 U_BOOT_DEVICE(devkit8000_uart) = { 56 "ns16550_serial", 57 &devkit8000_serial 58 }; 59 60 /* 61 * Routine: board_init 62 * Description: Early hardware init. 63 */ 64 int board_init(void) 65 { 66 gpmc_init(); /* in SRAM or SDRAM, finish GPMC */ 67 /* board id for Linux */ 68 gd->bd->bi_arch_number = MACH_TYPE_DEVKIT8000; 69 /* boot param addr */ 70 gd->bd->bi_boot_params = (OMAP34XX_SDRC_CS0 + 0x100); 71 72 return 0; 73 } 74 75 /* Configure GPMC registers for DM9000 */ 76 static void gpmc_dm9000_config(void) 77 { 78 enable_gpmc_cs_config(gpmc_net_config, &gpmc_cfg->cs[6], 79 CONFIG_DM9000_BASE, GPMC_SIZE_16M); 80 } 81 82 /* 83 * Routine: misc_init_r 84 * Description: Configure board specific parts 85 */ 86 int misc_init_r(void) 87 { 88 struct ctrl_id *id_base = (struct ctrl_id *)OMAP34XX_ID_L4_IO_BASE; 89 #ifdef CONFIG_DRIVER_DM9000 90 uchar enetaddr[6]; 91 u32 die_id_0; 92 #endif 93 94 twl4030_power_init(); 95 #ifdef CONFIG_TWL4030_LED 96 twl4030_led_init(TWL4030_LED_LEDEN_LEDAON | TWL4030_LED_LEDEN_LEDBON); 97 #endif 98 99 #ifdef CONFIG_DRIVER_DM9000 100 /* Configure GPMC registers for DM9000 */ 101 enable_gpmc_cs_config(gpmc_net_config, &gpmc_cfg->cs[6], 102 CONFIG_DM9000_BASE, GPMC_SIZE_16M); 103 104 /* Use OMAP DIE_ID as MAC address */ 105 if (!eth_getenv_enetaddr("ethaddr", enetaddr)) { 106 printf("ethaddr not set, using Die ID\n"); 107 die_id_0 = readl(&id_base->die_id_0); 108 enetaddr[0] = 0x02; /* locally administered */ 109 enetaddr[1] = readl(&id_base->die_id_1) & 0xff; 110 enetaddr[2] = (die_id_0 & 0xff000000) >> 24; 111 enetaddr[3] = (die_id_0 & 0x00ff0000) >> 16; 112 enetaddr[4] = (die_id_0 & 0x0000ff00) >> 8; 113 enetaddr[5] = (die_id_0 & 0x000000ff); 114 eth_setenv_enetaddr("ethaddr", enetaddr); 115 } 116 #endif 117 118 omap_die_id_display(); 119 120 return 0; 121 } 122 123 /* 124 * Routine: set_muxconf_regs 125 * Description: Setting up the configuration Mux registers specific to the 126 * hardware. Many pins need to be moved from protect to primary 127 * mode. 128 */ 129 void set_muxconf_regs(void) 130 { 131 MUX_DEVKIT8000(); 132 } 133 134 #if defined(CONFIG_GENERIC_MMC) 135 int board_mmc_init(bd_t *bis) 136 { 137 return omap_mmc_init(0, 0, 0, -1, -1); 138 } 139 #endif 140 141 #if defined(CONFIG_GENERIC_MMC) 142 void board_mmc_power_init(void) 143 { 144 twl4030_power_mmc_init(0); 145 } 146 #endif 147 148 #if defined(CONFIG_DRIVER_DM9000) & !defined(CONFIG_SPL_BUILD) 149 /* 150 * Routine: board_eth_init 151 * Description: Setting up the Ethernet hardware. 152 */ 153 int board_eth_init(bd_t *bis) 154 { 155 return dm9000_initialize(bis); 156 } 157 #endif 158 159 #ifdef CONFIG_SPL_OS_BOOT 160 /* 161 * Do board specific preparation before SPL 162 * Linux boot 163 */ 164 void spl_board_prepare_for_linux(void) 165 { 166 gpmc_dm9000_config(); 167 } 168 169 /* 170 * devkit8000 specific implementation of spl_start_uboot() 171 * 172 * RETURN 173 * 0 if the button is not pressed 174 * 1 if the button is pressed 175 */ 176 int spl_start_uboot(void) 177 { 178 int val = 0; 179 if (!gpio_request(SPL_OS_BOOT_KEY, "U-Boot key")) { 180 gpio_direction_input(SPL_OS_BOOT_KEY); 181 val = gpio_get_value(SPL_OS_BOOT_KEY); 182 gpio_free(SPL_OS_BOOT_KEY); 183 } 184 return !val; 185 } 186 #endif 187 188 /* 189 * Routine: get_board_mem_timings 190 * Description: If we use SPL then there is no x-loader nor config header 191 * so we have to setup the DDR timings ourself on the first bank. This 192 * provides the timing values back to the function that configures 193 * the memory. We have either one or two banks of 128MB DDR. 194 */ 195 void get_board_mem_timings(struct board_sdrc_timings *timings) 196 { 197 /* General SDRC config */ 198 timings->mcfg = MICRON_V_MCFG_165(128 << 20); 199 timings->rfr_ctrl = SDP_3430_SDRC_RFR_CTRL_165MHz; 200 201 /* AC timings */ 202 timings->ctrla = MICRON_V_ACTIMA_165; 203 timings->ctrlb = MICRON_V_ACTIMB_165; 204 205 timings->mr = MICRON_V_MR_165; 206 } 207