// 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 "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
