/*
 * Copyright (c) 2012 Michael Walle
 * Michael Walle <michael@walle.cc>
 *
 * Based on sheevaplug/sheevaplug.c by
 *   Marvell Semiconductor <www.marvell.com>
 *
 * SPDX-License-Identifier:	GPL-2.0+
 */

#include <common.h>
#include <net.h>
#include <malloc.h>
#include <netdev.h>
#include <miiphy.h>
#include <asm/arch/kirkwood.h>
#include <asm/arch/cpu.h>
#include <asm/arch/mpp.h>
#include <asm/arch/gpio.h>
#include <spi_flash.h>

#include "lsxl.h"

/*
 * Rescue mode
 *
 * Selected by holding the push button for 3 seconds, while powering on
 * the device.
 *
 * These linkstations don't have a (populated) serial port. There is no
 * way to access an (unmodified) board other than using the netconsole. If
 * you want to recover from a bad environment setting or an empty environment,
 * you can do this only with a working network connection. Therefore, a random
 * ethernet address is generated if none is set and a DHCP request is sent.
 * After a successful DHCP response is received, the network settings are
 * configured and the ncip is unset. Therefore, all netconsole packets are
 * broadcasted.
 * Additionally, the bootsource is set to 'rescue'.
 */

#ifndef CONFIG_ENV_OVERWRITE
# error "You need to set CONFIG_ENV_OVERWRITE"
#endif

DECLARE_GLOBAL_DATA_PTR;

int board_early_init_f(void)
{
	/*
	 * default gpio configuration
	 * There are maximum 64 gpios controlled through 2 sets of registers
	 * the below configuration configures mainly initial LED status
	 */
	kw_config_gpio(LSXL_OE_VAL_LOW,
			LSXL_OE_VAL_HIGH,
			LSXL_OE_LOW, LSXL_OE_HIGH);

	/*
	 * Multi-Purpose Pins Functionality configuration
	 * These strappings are taken from the original vendor uboot port.
	 */
	static const u32 kwmpp_config[] = {
		MPP0_SPI_SCn,
		MPP1_SPI_MOSI,
		MPP2_SPI_SCK,
		MPP3_SPI_MISO,
		MPP4_UART0_RXD,
		MPP5_UART0_TXD,
		MPP6_SYSRST_OUTn,
		MPP7_GPO,
		MPP8_GPIO,
		MPP9_GPIO,
		MPP10_GPO,		/* HDD power */
		MPP11_GPIO,		/* USB Vbus enable */
		MPP12_SD_CLK,
		MPP13_SD_CMD,
		MPP14_SD_D0,
		MPP15_SD_D1,
		MPP16_SD_D2,
		MPP17_SD_D3,
		MPP18_GPO,		/* fan speed high */
		MPP19_GPO,		/* fan speed low */
		MPP20_GE1_0,
		MPP21_GE1_1,
		MPP22_GE1_2,
		MPP23_GE1_3,
		MPP24_GE1_4,
		MPP25_GE1_5,
		MPP26_GE1_6,
		MPP27_GE1_7,
		MPP28_GPIO,
		MPP29_GPIO,
		MPP30_GE1_10,
		MPP31_GE1_11,
		MPP32_GE1_12,
		MPP33_GE1_13,
		MPP34_GPIO,
		MPP35_GPIO,
		MPP36_GPIO,		/* function LED */
		MPP37_GPIO,		/* alarm LED */
		MPP38_GPIO,		/* info LED */
		MPP39_GPIO,		/* power LED */
		MPP40_GPIO,		/* fan alarm */
		MPP41_GPIO,		/* funtion button */
		MPP42_GPIO,		/* power switch */
		MPP43_GPIO,		/* power auto switch */
		MPP44_GPIO,
		MPP45_GPIO,
		MPP46_GPIO,
		MPP47_GPIO,
		MPP48_GPIO,		/* function red LED */
		MPP49_GPIO,
		0
	};

	kirkwood_mpp_conf(kwmpp_config, NULL);

	return 0;
}

#define LED_OFF             0
#define LED_ALARM_ON        1
#define LED_ALARM_BLINKING  2
#define LED_POWER_ON        3
#define LED_POWER_BLINKING  4
#define LED_INFO_ON         5
#define LED_INFO_BLINKING   6

static void __set_led(int blink_alarm, int blink_info, int blink_power,
		int value_alarm, int value_info, int value_power)
{
	kw_gpio_set_blink(GPIO_ALARM_LED, blink_alarm);
	kw_gpio_set_blink(GPIO_INFO_LED, blink_info);
	kw_gpio_set_blink(GPIO_POWER_LED, blink_power);
	kw_gpio_set_value(GPIO_ALARM_LED, value_alarm);
	kw_gpio_set_value(GPIO_INFO_LED, value_info);
	kw_gpio_set_value(GPIO_POWER_LED, value_power);
}

static void set_led(int state)
{
	switch (state) {
	case LED_OFF:
		__set_led(0, 0, 0, 1, 1, 1);
		break;
	case LED_ALARM_ON:
		__set_led(0, 0, 0, 0, 1, 1);
		break;
	case LED_ALARM_BLINKING:
		__set_led(1, 0, 0, 1, 1, 1);
		break;
	case LED_INFO_ON:
		__set_led(0, 0, 0, 1, 0, 1);
		break;
	case LED_INFO_BLINKING:
		__set_led(0, 1, 0, 1, 1, 1);
		break;
	case LED_POWER_ON:
		__set_led(0, 0, 0, 1, 1, 0);
		break;
	case LED_POWER_BLINKING:
		__set_led(0, 0, 1, 1, 1, 1);
		break;
	}
}

int board_init(void)
{
	/* address of boot parameters */
	gd->bd->bi_boot_params = kw_sdram_bar(0) + 0x100;

	set_led(LED_POWER_BLINKING);

	return 0;
}

#ifdef CONFIG_MISC_INIT_R
static void check_power_switch(void)
{
	if (kw_gpio_get_value(GPIO_POWER_SWITCH)) {
		/* turn off fan, HDD and USB power */
		kw_gpio_set_value(GPIO_HDD_POWER, 0);
		kw_gpio_set_value(GPIO_USB_VBUS, 0);
		kw_gpio_set_value(GPIO_FAN_HIGH, 1);
		kw_gpio_set_value(GPIO_FAN_LOW, 1);
		set_led(LED_OFF);

		/* loop until released */
		while (kw_gpio_get_value(GPIO_POWER_SWITCH))
			;

		/* turn power on again */
		kw_gpio_set_value(GPIO_HDD_POWER, 1);
		kw_gpio_set_value(GPIO_USB_VBUS, 1);
		kw_gpio_set_value(GPIO_FAN_HIGH, 0);
		kw_gpio_set_value(GPIO_FAN_LOW, 0);
		set_led(LED_POWER_BLINKING);
	}
}

void check_enetaddr(void)
{
	uchar enetaddr[6];

	if (!eth_getenv_enetaddr("ethaddr", enetaddr)) {
		/* signal unset/invalid ethaddr to user */
		set_led(LED_INFO_BLINKING);
	}
}

static void erase_environment(void)
{
	struct spi_flash *flash;

	printf("Erasing environment..\n");
	flash = spi_flash_probe(0, 0, 1000000, SPI_MODE_3);
	if (!flash) {
		printf("Erasing flash failed\n");
		return;
	}

	spi_flash_erase(flash, CONFIG_ENV_OFFSET, CONFIG_ENV_SIZE);
	spi_flash_free(flash);
	do_reset(NULL, 0, 0, NULL);
}

static void rescue_mode(void)
{
	uchar enetaddr[6];

	printf("Entering rescue mode..\n");
#ifdef CONFIG_RANDOM_MACADDR
	if (!eth_getenv_enetaddr("ethaddr", enetaddr)) {
		eth_random_enetaddr(enetaddr);
		if (eth_setenv_enetaddr("ethaddr", enetaddr)) {
			printf("Failed to set ethernet address\n");
				set_led(LED_ALARM_BLINKING);
			return;
		}
	}
#endif
	setenv("bootsource", "rescue");
}

static void check_push_button(void)
{
	int i = 0;

	while (!kw_gpio_get_value(GPIO_FUNC_BUTTON)) {
		udelay(100000);
		i++;

		if (i == 10)
			set_led(LED_INFO_ON);

		if (i >= 100) {
			set_led(LED_INFO_BLINKING);
			break;
		}
	}

	if (i >= 100)
		erase_environment();
	else if (i >= 10)
		rescue_mode();
}

int misc_init_r(void)
{
	check_power_switch();
	check_enetaddr();
	check_push_button();

	return 0;
}
#endif

#ifdef CONFIG_SHOW_BOOT_PROGRESS
void show_boot_progress(int progress)
{
	if (progress > 0)
		return;

	/* this is not an error, eg. bootp with autoload=no will trigger this */
	if (progress == -BOOTSTAGE_ID_NET_LOADED)
		return;

	set_led(LED_ALARM_BLINKING);
}
#endif
