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

#include <common.h>
#include <dm/of.h>
#include <fdt_support.h>
#include <linux/ctype.h>
#include <linux/io.h>

#include "micro-support-card.h"

#define SMC911X_OFFSET			0x00000
#define LED_OFFSET			0x90000
#define NS16550A_OFFSET			0xb0000
#define MICRO_SUPPORT_CARD_RESET	0xd0034
#define MICRO_SUPPORT_CARD_REVISION	0xd00e0

static bool support_card_found;
static void __iomem *support_card_base;

static void support_card_detect(void)
{
	DECLARE_GLOBAL_DATA_PTR;
	const void *fdt = gd->fdt_blob;
	int offset;
	u64 addr, addr2;

	offset = fdt_node_offset_by_compatible(fdt, 0, "smsc,lan9118");
	if (offset < 0)
		return;

	addr = fdt_get_base_address(fdt, offset);
	if (addr == OF_BAD_ADDR)
		return;
	addr -= SMC911X_OFFSET;

	offset = fdt_node_offset_by_compatible(fdt, 0, "ns16550a");
	if (offset < 0)
		return;

	addr2 = fdt_get_base_address(fdt, offset);
	if (addr2 == OF_BAD_ADDR)
		return;
	addr2 -= NS16550A_OFFSET;

	/* sanity check */
	if (addr != addr2)
		return;

	support_card_base = ioremap(addr, 0x100000);

	support_card_found = true;
}

/*
 * 0: reset deassert, 1: reset
 *
 * bit[0]: LAN, I2C, LED
 * bit[1]: UART
 */
static void support_card_reset_deassert(void)
{
	writel(0x00010000, support_card_base + MICRO_SUPPORT_CARD_RESET);
}

static void support_card_reset(void)
{
	writel(0x00020003, support_card_base + MICRO_SUPPORT_CARD_RESET);
}

static int support_card_show_revision(void)
{
	u32 revision;

	revision = readl(support_card_base + MICRO_SUPPORT_CARD_REVISION);
	revision &= 0xff;

	/* revision 3.6.x card changed the revision format */
	printf("SC:    Micro Support Card (CPLD version %s%d.%d)\n",
	       revision >> 4 == 6 ? "3." : "",
	       revision >> 4, revision & 0xf);

	return 0;
}

void support_card_init(void)
{
	support_card_detect();

	if (!support_card_found)
		return;

	support_card_reset();
	/*
	 * After power on, we need to keep the LAN controller in reset state
	 * for a while. (200 usec)
	 */
	udelay(200);
	support_card_reset_deassert();

	support_card_show_revision();
}

#if defined(CONFIG_SMC911X)
#include <netdev.h>

int board_eth_init(bd_t *bis)
{
	if (!support_card_found)
		return 0;

	return smc911x_initialize(0, (unsigned long)support_card_base + SMC911X_OFFSET);
}
#endif

#if defined(CONFIG_MTD_NOR_FLASH)

#include <mtd/cfi_flash.h>

struct memory_bank {
	phys_addr_t base;
	unsigned long size;
};

static int mem_is_flash(const struct memory_bank *mem)
{
	const int loop = 128;
	u32 *scratch_addr;
	u32 saved_value;
	int ret = 1;
	int i;

	/* just in case, use the tail of the memory bank */
	scratch_addr = map_physmem(mem->base + mem->size - sizeof(u32) * loop,
				   sizeof(u32) * loop, MAP_NOCACHE);

	for (i = 0; i < loop; i++, scratch_addr++) {
		saved_value = readl(scratch_addr);
		writel(~saved_value, scratch_addr);
		if (readl(scratch_addr) != saved_value) {
			/* We assume no memory or SRAM here. */
			writel(saved_value, scratch_addr);
			ret = 0;
			break;
		}
	}

	unmap_physmem(scratch_addr, MAP_NOCACHE);

	return ret;
}

/* {address, size} */
static const struct memory_bank memory_banks[] = {
	{0x42000000, 0x01f00000},
};

static const struct memory_bank
*flash_banks_list[CONFIG_SYS_MAX_FLASH_BANKS_DETECT];

phys_addr_t cfi_flash_bank_addr(int i)
{
	return flash_banks_list[i]->base;
}

unsigned long cfi_flash_bank_size(int i)
{
	return flash_banks_list[i]->size;
}

static void detect_num_flash_banks(void)
{
	const struct memory_bank *memory_bank, *end;

	cfi_flash_num_flash_banks = 0;

	memory_bank = memory_banks;
	end = memory_bank + ARRAY_SIZE(memory_banks);

	for (; memory_bank < end; memory_bank++) {
		if (cfi_flash_num_flash_banks >=
		    CONFIG_SYS_MAX_FLASH_BANKS_DETECT)
			break;

		if (mem_is_flash(memory_bank)) {
			flash_banks_list[cfi_flash_num_flash_banks] =
								memory_bank;

			debug("flash bank found: base = 0x%lx, size = 0x%lx\n",
			      (unsigned long)memory_bank->base,
			      (unsigned long)memory_bank->size);
			cfi_flash_num_flash_banks++;
		}
	}

	debug("number of flash banks: %d\n", cfi_flash_num_flash_banks);
}
#else /* CONFIG_MTD_NOR_FLASH */
static void detect_num_flash_banks(void)
{
};
#endif /* CONFIG_MTD_NOR_FLASH */

void support_card_late_init(void)
{
	if (!support_card_found)
		return;

	detect_num_flash_banks();
}

static const u8 ledval_num[] = {
	0x7e, /* 0 */
	0x0c, /* 1 */
	0xb6, /* 2 */
	0x9e, /* 3 */
	0xcc, /* 4 */
	0xda, /* 5 */
	0xfa, /* 6 */
	0x4e, /* 7 */
	0xfe, /* 8 */
	0xde, /* 9 */
};

static const u8 ledval_alpha[] = {
	0xee, /* A */
	0xf8, /* B */
	0x72, /* C */
	0xbc, /* D */
	0xf2, /* E */
	0xe2, /* F */
	0x7a, /* G */
	0xe8, /* H */
	0x08, /* I */
	0x3c, /* J */
	0xea, /* K */
	0x70, /* L */
	0x6e, /* M */
	0xa8, /* N */
	0xb8, /* O */
	0xe6, /* P */
	0xce, /* Q */
	0xa0, /* R */
	0xc8, /* S */
	0x8c, /* T */
	0x7c, /* U */
	0x54, /* V */
	0xfc, /* W */
	0xec, /* X */
	0xdc, /* Y */
	0xa4, /* Z */
};

static u8 char2ledval(char c)
{
	if (isdigit(c))
		return ledval_num[c - '0'];
	else if (isalpha(c))
		return ledval_alpha[toupper(c) - 'A'];

	return 0;
}

void led_puts(const char *s)
{
	int i;
	u32 val = 0;

	if (!support_card_found)
		return;

	if (!s)
		return;

	for (i = 0; i < 4; i++) {
		val <<= 8;
		val |= char2ledval(*s);
		if (*s != '\0')
			s++;
	}

	writel(~val, support_card_base + LED_OFFSET);
}
