/*
 * Copyright (C) 2015-2017 Socionext Inc.
 *   Author: Masahiro Yamada <yamada.masahiro@socionext.com>
 *
 * SPDX-License-Identifier:	GPL-2.0+
 */

#include <common.h>
#include <spl.h>
#include <linux/log2.h>

#include "../init.h"
#include "../sbc/sbc-regs.h"
#include "../sg-regs.h"
#include "../soc-info.h"
#include "boot-device.h"

struct uniphier_boot_device_info {
	unsigned int soc_id;
	unsigned int boot_device_sel_shift;
	const struct uniphier_boot_device *boot_device_table;
	const unsigned int *boot_device_count;
	int (*boot_device_is_usb)(u32 pinmon);
	unsigned int (*boot_device_fixup)(unsigned int mode);
	int have_internal_stm;
};

static const struct uniphier_boot_device_info uniphier_boot_device_info[] = {
#if defined(CONFIG_ARCH_UNIPHIER_SLD3)
	{
		.soc_id = UNIPHIER_SLD3_ID,
		.boot_device_sel_shift = 0,
		.boot_device_table = uniphier_sld3_boot_device_table,
		.boot_device_count = &uniphier_sld3_boot_device_count,
		.have_internal_stm = 0,
	},
#endif
#if defined(CONFIG_ARCH_UNIPHIER_LD4)
	{
		.soc_id = UNIPHIER_LD4_ID,
		.boot_device_sel_shift = 1,
		.boot_device_table = uniphier_ld4_boot_device_table,
		.boot_device_count = &uniphier_ld4_boot_device_count,
		.have_internal_stm = 1,
	},
#endif
#if defined(CONFIG_ARCH_UNIPHIER_PRO4)
	{
		.soc_id = UNIPHIER_PRO4_ID,
		.boot_device_sel_shift = 1,
		.boot_device_table = uniphier_ld4_boot_device_table,
		.boot_device_count = &uniphier_ld4_boot_device_count,
		.have_internal_stm = 0,
	},
#endif
#if defined(CONFIG_ARCH_UNIPHIER_SLD8)
	{
		.soc_id = UNIPHIER_SLD8_ID,
		.boot_device_sel_shift = 1,
		.boot_device_table = uniphier_ld4_boot_device_table,
		.boot_device_count = &uniphier_ld4_boot_device_count,
		.have_internal_stm = 1,
	},
#endif
#if defined(CONFIG_ARCH_UNIPHIER_PRO5)
	{
		.soc_id = UNIPHIER_PRO5_ID,
		.boot_device_sel_shift = 1,
		.boot_device_table = uniphier_pro5_boot_device_table,
		.boot_device_count = &uniphier_pro5_boot_device_count,
		.have_internal_stm = 0,
	},
#endif
#if defined(CONFIG_ARCH_UNIPHIER_PXS2)
	{
		.soc_id = UNIPHIER_PXS2_ID,
		.boot_device_sel_shift = 1,
		.boot_device_table = uniphier_pxs2_boot_device_table,
		.boot_device_count = &uniphier_pxs2_boot_device_count,
		.boot_device_is_usb = uniphier_pxs2_boot_device_is_usb,
		.boot_device_fixup = uniphier_pxs2_boot_device_fixup,
		.have_internal_stm = 0,
	},
#endif
#if defined(CONFIG_ARCH_UNIPHIER_LD6B)
	{
		.soc_id = UNIPHIER_LD6B_ID,
		.boot_device_sel_shift = 1,
		.boot_device_table = uniphier_pxs2_boot_device_table,
		.boot_device_count = &uniphier_pxs2_boot_device_count,
		.boot_device_is_usb = uniphier_pxs2_boot_device_is_usb,
		.boot_device_fixup = uniphier_pxs2_boot_device_fixup,
		.have_internal_stm = 1,	/* STM on A-chip */
	},
#endif
#if defined(CONFIG_ARCH_UNIPHIER_LD11)
	{
		.soc_id = UNIPHIER_LD11_ID,
		.boot_device_sel_shift = 1,
		.boot_device_table = uniphier_ld11_boot_device_table,
		.boot_device_count = &uniphier_ld11_boot_device_count,
		.boot_device_is_usb = uniphier_ld11_boot_device_is_usb,
		.boot_device_fixup = uniphier_ld11_boot_device_fixup,
		.have_internal_stm = 1,
	},
#endif
#if defined(CONFIG_ARCH_UNIPHIER_LD20)
	{
		.soc_id = UNIPHIER_LD20_ID,
		.boot_device_sel_shift = 1,
		.boot_device_table = uniphier_ld11_boot_device_table,
		.boot_device_count = &uniphier_ld11_boot_device_count,
		.boot_device_is_usb = uniphier_ld20_boot_device_is_usb,
		.boot_device_fixup = uniphier_ld11_boot_device_fixup,
		.have_internal_stm = 1,
	},
#endif
};
UNIPHIER_DEFINE_SOCDATA_FUNC(uniphier_get_boot_device_info,
			     uniphier_boot_device_info)

static unsigned int __uniphier_boot_device_raw(
				const struct uniphier_boot_device_info *info)
{
	u32 pinmon;
	unsigned int boot_sel;

	if (boot_is_swapped())
		return BOOT_DEVICE_NOR;

	pinmon = readl(SG_PINMON0);

	if (info->boot_device_is_usb && info->boot_device_is_usb(pinmon))
		return BOOT_DEVICE_USB;

	boot_sel = pinmon >> info->boot_device_sel_shift;

	BUG_ON(!is_power_of_2(*info->boot_device_count));
	boot_sel &= *info->boot_device_count - 1;

	return info->boot_device_table[boot_sel].boot_device;
}

unsigned int uniphier_boot_device_raw(void)
{
	const struct uniphier_boot_device_info *info;

	info = uniphier_get_boot_device_info();
	if (!info) {
		pr_err("unsupported SoC\n");
		return BOOT_DEVICE_NONE;
	}

	return __uniphier_boot_device_raw(info);
}

u32 spl_boot_device(void)
{
	const struct uniphier_boot_device_info *info;
	u32 raw_mode;

	info = uniphier_get_boot_device_info();
	if (!info) {
		pr_err("unsupported SoC\n");
		return BOOT_DEVICE_NONE;
	}

	raw_mode = __uniphier_boot_device_raw(info);

	return info->boot_device_fixup ?
				info->boot_device_fixup(raw_mode) : raw_mode;
}

int uniphier_have_internal_stm(void)
{
	const struct uniphier_boot_device_info *info;

	info = uniphier_get_boot_device_info();
	if (!info) {
		pr_err("unsupported SoC\n");
		return -ENOTSUPP;
	}

	return info->have_internal_stm;
}

int uniphier_boot_from_backend(void)
{
	return !!(readl(SG_PINMON0) & BIT(27));
}

#ifndef CONFIG_SPL_BUILD

static int do_pinmon(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
	const struct uniphier_boot_device_info *info;
	u32 pinmon;
	unsigned int boot_device_count, boot_sel;
	int i;

	info = uniphier_get_boot_device_info();
	if (!info) {
		pr_err("unsupported SoC\n");
		return CMD_RET_FAILURE;
	}

	if (uniphier_have_internal_stm())
		printf("STB Micon: %s\n",
		       uniphier_boot_from_backend() ? "OFF" : "ON");

	printf("Boot Swap: %s\n", boot_is_swapped() ? "ON" : "OFF");

	pinmon = readl(SG_PINMON0);

	if (info->boot_device_is_usb)
		printf("USB Boot:  %s\n",
		       info->boot_device_is_usb(pinmon) ? "ON" : "OFF");

	boot_device_count = *info->boot_device_count;

	boot_sel = pinmon >> info->boot_device_sel_shift;
	boot_sel &= boot_device_count - 1;

	printf("\nBoot Mode Sel:\n");
	for (i = 0; i < boot_device_count; i++)
		printf(" %c %02x %s\n", i == boot_sel ? '*' : ' ', i,
		       info->boot_device_table[i].desc);

	return CMD_RET_SUCCESS;
}

U_BOOT_CMD(
	pinmon,	1,	1,	do_pinmon,
	"pin monitor",
	""
);

#endif /* !CONFIG_SPL_BUILD */
