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

#include <common.h>
#include <bootstage.h>
#include <command.h>
#include <env.h>
#include <env_internal.h>
#include <flash.h>
#include <init.h>
#include <net.h>
#include <malloc.h>
#include <netdev.h>
#include <miiphy.h>
#include <spi.h>
#include <spi_flash.h>
#include <asm/arch/soc.h>
#include <asm/arch/cpu.h>
#include <asm/arch/mpp.h>
#include <asm/arch/gpio.h>
#include <linux/delay.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
	 */
	mvebu_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 = mvebu_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_env_get_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)
{
	printf("Entering rescue mode..\n");
	env_set("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
