/*
 * 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_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 */
