/*
 * Common board functions for siemens AM335X based boards
 * (C) Copyright 2013 Siemens Schweiz AG
 * (C) Heiko Schocher, DENX Software Engineering, hs@denx.de.
 *
 * Based on:
 * U-Boot file:/board/ti/am335x/board.c
 * Copyright (C) 2011, Texas Instruments, Incorporated - http://www.ti.com/
 *
 * SPDX-License-Identifier:	GPL-2.0+
 */

#include <common.h>
#include <errno.h>
#include <spl.h>
#include <asm/arch/cpu.h>
#include <asm/arch/hardware.h>
#include <asm/arch/omap.h>
#include <asm/arch/ddr_defs.h>
#include <asm/arch/clock.h>
#include <asm/arch/gpio.h>
#include <asm/arch/mmc_host_def.h>
#include <asm/arch/sys_proto.h>
#include <asm/io.h>
#include <asm/emif.h>
#include <asm/gpio.h>
#include <i2c.h>
#include <miiphy.h>
#include <cpsw.h>
#include <watchdog.h>
#include "../common/factoryset.h"

DECLARE_GLOBAL_DATA_PTR;

#ifdef CONFIG_SPL_BUILD
void set_uart_mux_conf(void)
{
	enable_uart0_pin_mux();
}

void set_mux_conf_regs(void)
{
	/* Initalize the board header */
	enable_i2c0_pin_mux();
	i2c_set_bus_num(0);

	/* enable early the console */
	gd->baudrate = CONFIG_BAUDRATE;
	serial_init();
	gd->have_console = 1;
	if (read_eeprom() < 0)
		puts("Could not get board ID.\n");

	enable_board_pin_mux();
}

void sdram_init(void)
{
	spl_siemens_board_init();
	board_init_ddr();

	return;
}
#endif /* #ifdef CONFIG_SPL_BUILD */

#ifndef CONFIG_SPL_BUILD
/*
 * Basic board specific setup.  Pinmux has been handled already.
 */
int board_init(void)
{
#if defined(CONFIG_HW_WATCHDOG)
	hw_watchdog_init();
#endif /* defined(CONFIG_HW_WATCHDOG) */
	i2c_set_bus_num(0);
	if (read_eeprom() < 0)
		puts("Could not get board ID.\n");
#ifdef CONFIG_MACH_TYPE
	gd->bd->bi_arch_number = CONFIG_MACH_TYPE;
#endif
	gd->bd->bi_boot_params = CONFIG_SYS_SDRAM_BASE + 0x100;

#ifdef CONFIG_FACTORYSET
	factoryset_read_eeprom(CONFIG_SYS_I2C_EEPROM_ADDR);
#endif

	gpmc_init();

#ifdef CONFIG_NAND_CS_INIT
	board_nand_cs_init();
#endif
#ifdef CONFIG_VIDEO
	board_video_init();
#endif

	return 0;
}
#endif /* #ifndef CONFIG_SPL_BUILD */

#define OSC	(V_OSCK/1000000)
const struct dpll_params dpll_ddr = {
		DDR_PLL_FREQ, OSC-1, 1, -1, -1, -1, -1};

const struct dpll_params *get_dpll_ddr_params(void)
{
	return &dpll_ddr;
}

#ifndef CONFIG_SPL_BUILD

#define MAX_NR_LEDS	10
#define MAX_PIN_NUMBER	128
#define STARTUP	0

#if defined(BOARD_DFU_BUTTON_GPIO)
unsigned char get_button_state(char * const envname, unsigned char def)
{
	int button = 0;
	int gpio;
	char *ptr_env;

	/* If button is not found we take default */
	ptr_env = getenv(envname);
	if (NULL == ptr_env) {
		gpio = def;
	} else {
		gpio = (unsigned char)simple_strtoul(ptr_env, NULL, 0);
		if (gpio > MAX_PIN_NUMBER)
			gpio = def;
	}

	gpio_request(gpio, "");
	gpio_direction_input(gpio);
	if (gpio_get_value(gpio))
		button = 1;
	else
		button = 0;

	gpio_free(gpio);

	return button;
}
/**
 * This command returns the status of the user button on
 * Input - none
 * Returns -	1 if button is held down
 *		0 if button is not held down
 */
static int
do_userbutton(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
	int button = 0;
	button = get_button_state("button_dfu0", BOARD_DFU_BUTTON_GPIO);
	button |= get_button_state("button_dfu1", BOARD_DFU_BUTTON_GPIO);
	return button;
}

U_BOOT_CMD(
	dfubutton, CONFIG_SYS_MAXARGS, 1, do_userbutton,
	"Return the status of the DFU button",
	""
);
#endif

static int
do_usertestwdt(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
	printf("\n\n\n Go into infinite loop\n\n\n");
	while (1)
		;
	return 0;
};

U_BOOT_CMD(
	testwdt, CONFIG_SYS_MAXARGS, 1,	do_usertestwdt,
	"Sends U-Boot into infinite loop",
	""
);

/**
 * Get led gpios from env and set them.
 * The led define in environment need to need to be of the form ledN=NN,S0,S1
 * where N is an unsigned integer from 0 to 9 and S0 and S1 is 0 or 1. S0
 * defines the startup state of the led, S1 the special state of the led when
 * it enters e.g. dfu mode.
 */
void set_env_gpios(unsigned char state)
{
	char *ptr_env;
	char str_tmp[5];	/* must contain "ledX"*/
	char num[1];
	unsigned char i, idx, pos1, pos2, ccount;
	unsigned char gpio_n, gpio_s0, gpio_s1;

	for (i = 0; i < MAX_NR_LEDS; i++) {
		strcpy(str_tmp, "led");
		sprintf(num, "%d", i);
		strcat(str_tmp, num);

		/* If env var is not found we stop */
		ptr_env = getenv(str_tmp);
		if (NULL == ptr_env)
			break;

		/* Find sperators position */
		pos1 = 0;
		pos2 = 0;
		ccount = 0;
		for (idx = 0; ptr_env[idx] != '\0'; idx++) {
			if (ptr_env[idx] == ',') {
				if (ccount++ < 1)
					pos1 = idx;
				else
					pos2 = idx;
			}
		}
		/* Bad led description skip this definition */
		if (pos2 <= pos1 || ccount > 2)
			continue;

		/* Get pin number and request gpio */
		memset(str_tmp, 0, sizeof(str_tmp));
		strncpy(str_tmp, ptr_env, pos1*sizeof(char));
		gpio_n = (unsigned char)simple_strtoul(str_tmp, NULL, 0);

		/* Invalid gpio number skip definition */
		if (gpio_n > MAX_PIN_NUMBER)
			continue;

		gpio_request(gpio_n, "");

		if (state == STARTUP) {
			/* get pin state 0 and set */
			memset(str_tmp, 0, sizeof(str_tmp));
			strncpy(str_tmp, ptr_env+pos1+1,
				(pos2-pos1-1)*sizeof(char));
			gpio_s0 = (unsigned char)simple_strtoul(str_tmp, NULL,
								0);

			gpio_direction_output(gpio_n, gpio_s0);

		} else {
			/* get pin state 1 and set */
			memset(str_tmp, 0, sizeof(str_tmp));
			strcpy(str_tmp, ptr_env+pos2+1);
			gpio_s1 = (unsigned char)simple_strtoul(str_tmp, NULL,
								0);
			gpio_direction_output(gpio_n, gpio_s1);
		}
	} /* loop through defined led in environment */
}

static int do_board_led(cmd_tbl_t *cmdtp, int flag, int argc,
			   char *const argv[])
{
	if (argc != 2)
		return CMD_RET_USAGE;
	if ((unsigned char)simple_strtoul(argv[1], NULL, 0) == STARTUP)
		set_env_gpios(0);
	else
		set_env_gpios(1);
	return 0;
};

U_BOOT_CMD(
	draco_led, CONFIG_SYS_MAXARGS, 2,	do_board_led,
	"Set LEDs defined in environment",
	"<0|1>"
);
#endif /* !CONFIG_SPL_BUILD */
