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