| /* | 
 |  * (C) Heiko Schocher, DENX Software Engineering, hs@denx.de. | 
 |  * Based on: | 
 |  * U-Boot:board/davinci/da8xxevm/da850evm.c | 
 |  * | 
 |  * Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com/ | 
 |  * | 
 |  * Based on da830evm.c. Original Copyrights follow: | 
 |  * | 
 |  * Copyright (C) 2009 Nick Thompson, GE Fanuc, Ltd. <nick.thompson@gefanuc.com> | 
 |  * Copyright (C) 2007 Sergey Kubushyn <ksi@koi8.net> | 
 |  * | 
 |  * SPDX-License-Identifier:	GPL-2.0+ | 
 |  */ | 
 |  | 
 | #include <common.h> | 
 | #include <i2c.h> | 
 | #include <net.h> | 
 | #include <netdev.h> | 
 | #include <spi.h> | 
 | #include <spi_flash.h> | 
 | #include <asm/arch/hardware.h> | 
 | #include <asm/ti-common/davinci_nand.h> | 
 | #include <asm/arch/emac_defs.h> | 
 | #include <asm/arch/pinmux_defs.h> | 
 | #include <asm/io.h> | 
 | #include <asm/arch/davinci_misc.h> | 
 | #include <asm/errno.h> | 
 | #include <asm/gpio.h> | 
 | #include <hwconfig.h> | 
 | #include <bootstage.h> | 
 |  | 
 | DECLARE_GLOBAL_DATA_PTR; | 
 |  | 
 | #ifdef CONFIG_DRIVER_TI_EMAC | 
 | #ifdef CONFIG_DRIVER_TI_EMAC_USE_RMII | 
 | #define HAS_RMII 1 | 
 | #else | 
 | #define HAS_RMII 0 | 
 | #endif | 
 | #endif /* CONFIG_DRIVER_TI_EMAC */ | 
 |  | 
 | void dsp_lpsc_on(unsigned domain, unsigned int id) | 
 | { | 
 | 	dv_reg_p mdstat, mdctl, ptstat, ptcmd; | 
 | 	struct davinci_psc_regs *psc_regs; | 
 |  | 
 | 	psc_regs = davinci_psc0_regs; | 
 | 	mdstat = &psc_regs->psc0.mdstat[id]; | 
 | 	mdctl = &psc_regs->psc0.mdctl[id]; | 
 | 	ptstat = &psc_regs->ptstat; | 
 | 	ptcmd = &psc_regs->ptcmd; | 
 |  | 
 | 	while (*ptstat & (0x1 << domain)) | 
 | 		; | 
 |  | 
 | 	if ((*mdstat & 0x1f) == 0x03) | 
 | 		return;                 /* Already on and enabled */ | 
 |  | 
 | 	*mdctl |= 0x03; | 
 |  | 
 | 	*ptcmd = 0x1 << domain; | 
 |  | 
 | 	while (*ptstat & (0x1 << domain)) | 
 | 		; | 
 | 	while ((*mdstat & 0x1f) != 0x03) | 
 | 		;		/* Probably an overkill... */ | 
 | } | 
 |  | 
 | static void dspwake(void) | 
 | { | 
 | 	unsigned *resetvect = (unsigned *)DAVINCI_L3CBARAM_BASE; | 
 | 	u32 val; | 
 |  | 
 | 	/* if the device is ARM only, return */ | 
 | 	if ((readl(CHIP_REV_ID_REG) & 0x3f) == 0x10) | 
 | 		return; | 
 |  | 
 | 	if (hwconfig_subarg_cmp_f("dsp", "wake", "no", NULL)) | 
 | 		return; | 
 |  | 
 | 	*resetvect++ = 0x1E000; /* DSP Idle */ | 
 | 	/* clear out the next 10 words as NOP */ | 
 | 	memset(resetvect, 0, sizeof(unsigned) * 10); | 
 |  | 
 | 	/* setup the DSP reset vector */ | 
 | 	writel(DAVINCI_L3CBARAM_BASE, HOST1CFG); | 
 |  | 
 | 	dsp_lpsc_on(1, DAVINCI_LPSC_GEM); | 
 | 	val = readl(PSC0_MDCTL + (15 * 4)); | 
 | 	val |= 0x100; | 
 | 	writel(val, (PSC0_MDCTL + (15 * 4))); | 
 | } | 
 |  | 
 | int misc_init_r(void) | 
 | { | 
 | 	dspwake(); | 
 | 	return 0; | 
 | } | 
 |  | 
 | static const struct pinmux_config gpio_pins[] = { | 
 | 	/* GP7[14] selects bootmode*/ | 
 | 	{ pinmux(16), 8, 3 },	/* GP7[14] */ | 
 | }; | 
 |  | 
 | const struct pinmux_resource pinmuxes[] = { | 
 | #ifdef CONFIG_DRIVER_TI_EMAC | 
 | 	PINMUX_ITEM(emac_pins_mdio), | 
 | #ifdef CONFIG_DRIVER_TI_EMAC_USE_RMII | 
 | 	PINMUX_ITEM(emac_pins_rmii), | 
 | #else | 
 | 	PINMUX_ITEM(emac_pins_mii), | 
 | #endif | 
 | #endif | 
 | 	PINMUX_ITEM(uart2_pins_txrx), | 
 | 	PINMUX_ITEM(uart2_pins_rtscts), | 
 | 	PINMUX_ITEM(uart0_pins_txrx), | 
 | 	PINMUX_ITEM(uart0_pins_rtscts), | 
 | #ifdef CONFIG_NAND_DAVINCI | 
 | 	PINMUX_ITEM(emifa_pins_cs3), | 
 | 	PINMUX_ITEM(emifa_pins_nand), | 
 | #endif | 
 | 	PINMUX_ITEM(gpio_pins), | 
 | }; | 
 |  | 
 | const int pinmuxes_size = ARRAY_SIZE(pinmuxes); | 
 |  | 
 | const struct lpsc_resource lpsc[] = { | 
 | 	{ DAVINCI_LPSC_AEMIF },	/* NAND, NOR */ | 
 | 	{ DAVINCI_LPSC_EMAC },	/* image download */ | 
 | 	{ DAVINCI_LPSC_UART2 },	/* console */ | 
 | 	{ DAVINCI_LPSC_UART0 },	/* console */ | 
 | 	{ DAVINCI_LPSC_GPIO }, | 
 | }; | 
 |  | 
 | const int lpsc_size = ARRAY_SIZE(lpsc); | 
 |  | 
 | #ifndef CONFIG_DA850_EVM_MAX_CPU_CLK | 
 | #define CONFIG_DA850_EVM_MAX_CPU_CLK	300000000 | 
 | #endif | 
 |  | 
 | #define REV_AM18X_EVM		0x100 | 
 |  | 
 | /* | 
 |  * get_board_rev() - setup to pass kernel board revision information | 
 |  * Returns: | 
 |  * bit[0-3]	Maximum cpu clock rate supported by onboard SoC | 
 |  *		0000b - 300 MHz | 
 |  *		0001b - 372 MHz | 
 |  *		0010b - 408 MHz | 
 |  *		0011b - 456 MHz | 
 |  */ | 
 | u32 get_board_rev(void) | 
 | { | 
 | 	char *s; | 
 | 	u32 maxcpuclk = CONFIG_DA850_EVM_MAX_CPU_CLK; | 
 | 	u32 rev = 0; | 
 |  | 
 | 	s = getenv("maxcpuclk"); | 
 | 	if (s) | 
 | 		maxcpuclk = simple_strtoul(s, NULL, 10); | 
 |  | 
 | 	if (maxcpuclk >= 456000000) | 
 | 		rev = 3; | 
 | 	else if (maxcpuclk >= 408000000) | 
 | 		rev = 2; | 
 | 	else if (maxcpuclk >= 372000000) | 
 | 		rev = 1; | 
 | #ifdef CONFIG_DA850_AM18X_EVM | 
 | 	rev |= REV_AM18X_EVM; | 
 | #endif | 
 | 	return rev; | 
 | } | 
 |  | 
 | int board_early_init_f(void) | 
 | { | 
 | 	/* | 
 | 	 * Power on required peripherals | 
 | 	 * ARM does not have access by default to PSC0 and PSC1 | 
 | 	 * assuming here that the DSP bootloader has set the IOPU | 
 | 	 * such that PSC access is available to ARM | 
 | 	 */ | 
 | 	if (da8xx_configure_lpsc_items(lpsc, ARRAY_SIZE(lpsc))) | 
 | 		return 1; | 
 |  | 
 | 	return 0; | 
 | } | 
 |  | 
 | int board_init(void) | 
 | { | 
 | #ifndef CONFIG_USE_IRQ | 
 | 	irq_init(); | 
 | #endif | 
 |  | 
 | 	/* arch number of the board */ | 
 | 	gd->bd->bi_arch_number = MACH_TYPE_DAVINCI_DA850_EVM; | 
 |  | 
 | 	/* address of boot parameters */ | 
 | 	gd->bd->bi_boot_params = LINUX_BOOT_PARAM_ADDR; | 
 |  | 
 | 	/* setup the SUSPSRC for ARM to control emulation suspend */ | 
 | 	writel(readl(&davinci_syscfg_regs->suspsrc) & | 
 | 	       ~(DAVINCI_SYSCFG_SUSPSRC_EMAC | DAVINCI_SYSCFG_SUSPSRC_I2C | | 
 | 		 DAVINCI_SYSCFG_SUSPSRC_SPI1 | DAVINCI_SYSCFG_SUSPSRC_TIMER0 | | 
 | 		 DAVINCI_SYSCFG_SUSPSRC_UART0), | 
 | 	       &davinci_syscfg_regs->suspsrc); | 
 |  | 
 | 	/* configure pinmux settings */ | 
 | 	if (davinci_configure_pin_mux_items(pinmuxes, ARRAY_SIZE(pinmuxes))) | 
 | 		return 1; | 
 |  | 
 | #ifdef CONFIG_DRIVER_TI_EMAC | 
 | 	davinci_emac_mii_mode_sel(HAS_RMII); | 
 | #endif /* CONFIG_DRIVER_TI_EMAC */ | 
 |  | 
 | 	/* enable the console UART */ | 
 | 	writel((DAVINCI_UART_PWREMU_MGMT_FREE | DAVINCI_UART_PWREMU_MGMT_URRST | | 
 | 		DAVINCI_UART_PWREMU_MGMT_UTRST), | 
 | #if (CONFIG_SYS_NS16550_COM1 == DAVINCI_UART0_BASE) | 
 | 	       &davinci_uart0_ctrl_regs->pwremu_mgmt); | 
 | #else | 
 | 	       &davinci_uart2_ctrl_regs->pwremu_mgmt); | 
 | #endif | 
 | 	return 0; | 
 | } | 
 |  | 
 | #ifdef CONFIG_DRIVER_TI_EMAC | 
 | /* | 
 |  * Initializes on-board ethernet controllers. | 
 |  */ | 
 | int board_eth_init(bd_t *bis) | 
 | { | 
 | 	if (!davinci_emac_initialize()) { | 
 | 		printf("Error: Ethernet init failed!\n"); | 
 | 		return -1; | 
 | 	} | 
 |  | 
 | 	return 0; | 
 | } | 
 | #endif /* CONFIG_DRIVER_TI_EMAC */ | 
 |  | 
 | static int init_led(int gpio, char *name, int val) | 
 | { | 
 | 	int ret; | 
 |  | 
 | 	ret = gpio_request(gpio, name); | 
 | 	if (ret) | 
 | 		return -1; | 
 | 	ret = gpio_direction_output(gpio, val); | 
 | 	if (ret) | 
 | 		return -1; | 
 |  | 
 | 	return gpio; | 
 | } | 
 |  | 
 | #define LED_ON	0 | 
 | #define LED_OFF	1 | 
 |  | 
 | #if !defined(CONFIG_SPL_BUILD) | 
 | #ifdef CONFIG_SHOW_BOOT_PROGRESS | 
 | void show_boot_progress(int status) | 
 | { | 
 | 	static int red; | 
 | 	static int green; | 
 |  | 
 | 	if (red == 0) | 
 | 		red = init_led(CONFIG_IPAM390_GPIO_LED_RED, "red", LED_ON); | 
 | 	if (red != CONFIG_IPAM390_GPIO_LED_RED) | 
 | 		return; | 
 | 	if (green == 0) | 
 | 		green = init_led(CONFIG_IPAM390_GPIO_LED_GREEN, "green", | 
 | 				 LED_OFF); | 
 | 	if (green != CONFIG_IPAM390_GPIO_LED_GREEN) | 
 | 		return; | 
 |  | 
 | 	switch (status) { | 
 | 	case BOOTSTAGE_ID_RUN_OS: | 
 | 		/* | 
 | 		 * set normal state | 
 | 		 * LED Red  : on | 
 | 		 * LED green: off | 
 | 		 */ | 
 | 		gpio_set_value(red, LED_ON); | 
 | 		gpio_set_value(green, LED_OFF); | 
 | 		break; | 
 | 	case BOOTSTAGE_ID_MAIN_LOOP: | 
 | 		/* | 
 | 		 * U-Boot operation | 
 | 		 * LED Red  : on | 
 | 		 * LED green: on | 
 | 		 */ | 
 | 		gpio_set_value(red, LED_ON); | 
 | 		gpio_set_value(green, LED_ON); | 
 | 		break; | 
 | 	} | 
 | } | 
 | #endif | 
 | #endif | 
 |  | 
 | #ifdef CONFIG_SPL_OS_BOOT | 
 | int spl_start_uboot(void) | 
 | { | 
 | 	int ret; | 
 | 	int bootmode = 0; | 
 |  | 
 | 	/* | 
 | 	 * GP7[14] selects bootmode: | 
 | 	 * 1: boot linux | 
 | 	 * 0: boot u-boot | 
 | 	 * if error accessing gpio boot U-Boot | 
 | 	 * | 
 | 	 * SPL bootmode | 
 | 	 * 0: boot linux | 
 | 	 * 1: boot u-boot | 
 | 	 */ | 
 | 	ret = gpio_request(CONFIG_IPAM390_GPIO_BOOTMODE , "bootmode"); | 
 | 	if (ret) | 
 | 		bootmode = 1; | 
 | 	if (!bootmode) { | 
 | 		ret = gpio_direction_input(CONFIG_IPAM390_GPIO_BOOTMODE); | 
 | 		if (ret) | 
 | 			bootmode = 1; | 
 | 	} | 
 | 	if (!bootmode) | 
 | 		ret = gpio_get_value(CONFIG_IPAM390_GPIO_BOOTMODE); | 
 | 	if (!bootmode) | 
 | 		if (ret == 0) | 
 | 			bootmode = 1; | 
 | 	/* | 
 | 	 * LED red  : on | 
 | 	 * LED green: off | 
 | 	 */ | 
 | 	init_led(CONFIG_IPAM390_GPIO_LED_RED, "red", LED_ON); | 
 | 	init_led(CONFIG_IPAM390_GPIO_LED_GREEN, "green", LED_OFF); | 
 | 	return bootmode; | 
 | } | 
 | #endif |