/*
 * Copyright (C) 2011  Renesas Solutions Corp.
 *
 * SPDX-License-Identifier:	GPL-2.0+
 */

#include <common.h>
#include <malloc.h>
#include <asm/processor.h>
#include <asm/io.h>
#include <asm/mmc.h>
#include <spi.h>
#include <spi_flash.h>

int checkboard(void)
{
	puts("BOARD: R0P7757LC0030RL board\n");

	return 0;
}

static void init_gctrl(void)
{
	struct gctrl_regs *gctrl = GCTRL_BASE;
	unsigned long graofst;

	graofst = (SH7757LCR_SDRAM_PHYS_TOP + SH7757LCR_GRA_OFFSET) >> 24;
	writel(graofst | 0x20000f00, &gctrl->gracr3);
}

static int init_pcie_bridge_from_spi(void *buf, size_t size)
{
	struct spi_flash *spi;
	int ret;
	unsigned long pcie_addr;

	spi = spi_flash_probe(0, 0, 1000000, SPI_MODE_3);
	if (!spi) {
		printf("%s: spi_flash probe error.\n", __func__);
		return 1;
	}

	if (is_sh7757_b0())
		pcie_addr = SH7757LCR_PCIEBRG_ADDR_B0;
	else
		pcie_addr = SH7757LCR_PCIEBRG_ADDR;

	ret = spi_flash_read(spi, pcie_addr, size, buf);
	if (ret) {
		printf("%s: spi_flash read error.\n", __func__);
		spi_flash_free(spi);
		return 1;
	}
	spi_flash_free(spi);

	return 0;
}

static void init_pcie_bridge(void)
{
	struct pciebrg_regs *pciebrg = PCIEBRG_BASE;
	struct pcie_setup_regs *pcie_setup = PCIE_SETUP_BASE;
	int i;
	unsigned char *data;
	unsigned short tmp;
	unsigned long pcie_size;

	if (!(readw(&pciebrg->ctrl_h8s) & 0x0001))
		return;

	if (is_sh7757_b0())
		pcie_size = SH7757LCR_PCIEBRG_SIZE_B0;
	else
		pcie_size = SH7757LCR_PCIEBRG_SIZE;

	data = malloc(pcie_size);
	if (!data) {
		printf("%s: malloc error.\n", __func__);
		return;
	}
	if (init_pcie_bridge_from_spi(data, pcie_size)) {
		free(data);
		return;
	}

	if (data[0] == 0xff && data[1] == 0xff && data[2] == 0xff &&
	    data[3] == 0xff) {
		free(data);
		printf("%s: skipped initialization\n", __func__);
		return;
	}

	writew(0xa501, &pciebrg->ctrl_h8s);	/* reset */
	writew(0x0000, &pciebrg->cp_ctrl);
	writew(0x0000, &pciebrg->cp_addr);

	for (i = 0; i < pcie_size; i += 2) {
		tmp = (data[i] << 8) | data[i + 1];
		writew(tmp, &pciebrg->cp_data);
	}

	writew(0xa500, &pciebrg->ctrl_h8s);	/* start */
	if (!is_sh7757_b0())
		writel(0x00000001, &pcie_setup->pbictl3);

	free(data);
}

static void init_usb_phy(void)
{
	struct usb_common_regs *common0 = USB0_COMMON_BASE;
	struct usb_common_regs *common1 = USB1_COMMON_BASE;
	struct usb0_phy_regs *phy = USB0_PHY_BASE;
	struct usb1_port_regs *port = USB1_PORT_BASE;
	struct usb1_alignment_regs *align = USB1_ALIGNMENT_BASE;

	writew(0x0100, &phy->reset);		/* set reset */
	/* port0 = USB0, port1 = USB1 */
	writew(0x0002, &phy->portsel);
	writel(0x0001, &port->port1sel);	/* port1 = Host */
	writew(0x0111, &phy->reset);		/* clear reset */

	writew(0x4000, &common0->suspmode);
	writew(0x4000, &common1->suspmode);

#if defined(__LITTLE_ENDIAN)
	writel(0x00000000, &align->ehcidatac);
	writel(0x00000000, &align->ohcidatac);
#endif
}

static void set_mac_to_sh_eth_register(int channel, char *mac_string)
{
	struct ether_mac_regs *ether;
	unsigned char mac[6];
	unsigned long val;

	eth_parse_enetaddr(mac_string, mac);

	if (!channel)
		ether = ETHER0_MAC_BASE;
	else
		ether = ETHER1_MAC_BASE;

	val = (mac[0] << 24) | (mac[1] << 16) | (mac[2] << 8) | mac[3];
	writel(val, &ether->mahr);
	val = (mac[4] << 8) | mac[5];
	writel(val, &ether->malr);
}

static void set_mac_to_sh_giga_eth_register(int channel, char *mac_string)
{
	struct ether_mac_regs *ether;
	unsigned char mac[6];
	unsigned long val;

	eth_parse_enetaddr(mac_string, mac);

	if (!channel)
		ether = GETHER0_MAC_BASE;
	else
		ether = GETHER1_MAC_BASE;

	val = (mac[0] << 24) | (mac[1] << 16) | (mac[2] << 8) | mac[3];
	writel(val, &ether->mahr);
	val = (mac[4] << 8) | mac[5];
	writel(val, &ether->malr);
}

/*****************************************************************
 * This PMB must be set on this timing. The lowlevel_init is run on
 * Area 0(phys 0x00000000), so we have to map it.
 *
 * The new PMB table is following:
 * ent	virt		phys		v	sz	c	wt
 * 0	0xa0000000	0x40000000	1	128M	0	1
 * 1	0xa8000000	0x48000000	1	128M	0	1
 * 2	0xb0000000	0x50000000	1	128M	0	1
 * 3	0xb8000000	0x58000000	1	128M	0	1
 * 4	0x80000000	0x40000000	1	128M	1	1
 * 5	0x88000000	0x48000000	1	128M	1	1
 * 6	0x90000000	0x50000000	1	128M	1	1
 * 7	0x98000000	0x58000000	1	128M	1	1
 */
static void set_pmb_on_board_init(void)
{
	struct mmu_regs *mmu = MMU_BASE;

	/* clear ITLB */
	writel(0x00000004, &mmu->mmucr);

	/* delete PMB for SPIBOOT */
	writel(0, PMB_ADDR_BASE(0));
	writel(0, PMB_DATA_BASE(0));

	/* add PMB for SDRAM(0x40000000 - 0x47ffffff) */
	/*			ppn  ub v s1 s0  c  wt */
	writel(mk_pmb_addr_val(0xa0), PMB_ADDR_BASE(0));
	writel(mk_pmb_data_val(0x40, 1, 1, 1, 0, 0, 1), PMB_DATA_BASE(0));
	writel(mk_pmb_addr_val(0xb0), PMB_ADDR_BASE(2));
	writel(mk_pmb_data_val(0x50, 1, 1, 1, 0, 0, 1), PMB_DATA_BASE(2));
	writel(mk_pmb_addr_val(0xb8), PMB_ADDR_BASE(3));
	writel(mk_pmb_data_val(0x58, 1, 1, 1, 0, 0, 1), PMB_DATA_BASE(3));
	writel(mk_pmb_addr_val(0x80), PMB_ADDR_BASE(4));
	writel(mk_pmb_data_val(0x40, 0, 1, 1, 0, 1, 1), PMB_DATA_BASE(4));
	writel(mk_pmb_addr_val(0x90), PMB_ADDR_BASE(6));
	writel(mk_pmb_data_val(0x50, 0, 1, 1, 0, 1, 1), PMB_DATA_BASE(6));
	writel(mk_pmb_addr_val(0x98), PMB_ADDR_BASE(7));
	writel(mk_pmb_data_val(0x58, 0, 1, 1, 0, 1, 1), PMB_DATA_BASE(7));
}

int board_init(void)
{
	struct gether_control_regs *gether = GETHER_CONTROL_BASE;

	set_pmb_on_board_init();

	/* enable RMII's MDIO (disable GRMII's MDIO) */
	writel(0x00030000, &gether->gbecont);

	init_gctrl();
	init_usb_phy();

	return 0;
}

int dram_init(void)
{
	DECLARE_GLOBAL_DATA_PTR;

	gd->bd->bi_memstart = CONFIG_SYS_SDRAM_BASE;
	gd->bd->bi_memsize = CONFIG_SYS_SDRAM_SIZE;
	printf("DRAM:  %dMB\n", CONFIG_SYS_SDRAM_SIZE / (1024 * 1024));
	printf("    Physical address\n");
	printf("    0x%08x - 0x%08x : Accessible Space as ECC Area\n",
		SH7757LCR_SDRAM_PHYS_TOP,
		SH7757LCR_SDRAM_PHYS_TOP + SH7757LCR_SDRAM_SIZE - 1);
	printf("    0x%08x - 0x%08x : No Access Area\n",
		SH7757LCR_SDRAM_PHYS_TOP + SH7757LCR_SDRAM_SIZE,
		SH7757LCR_SDRAM_PHYS_TOP + SH7757LCR_SDRAM_SIZE * 2 - 1);
	printf("    0x%08x - 0x%08x : Non-ECC Area for DVC/AVC\n",
		SH7757LCR_SDRAM_PHYS_TOP + SH7757LCR_SDRAM_ECC_SETTING * 2,
		SH7757LCR_SDRAM_PHYS_TOP + SH7757LCR_SDRAM_ECC_SETTING * 2 +
			SH7757LCR_SDRAM_DVC_SIZE - 1);
	printf("    0x%08x - 0x%08x : Non-ECC Area for G200eR2\n",
		SH7757LCR_SDRAM_PHYS_TOP + SH7757LCR_GRA_OFFSET,
		SH7757LCR_SDRAM_PHYS_TOP + SH7757LCR_GRA_OFFSET + 0x00ffffff);

	return 0;
}

int board_mmc_init(bd_t *bis)
{
	return mmcif_mmc_init();
}

static int get_sh_eth_mac_raw(unsigned char *buf, int size)
{
	struct spi_flash *spi;
	int ret;

	spi = spi_flash_probe(0, 0, 1000000, SPI_MODE_3);
	if (spi == NULL) {
		printf("%s: spi_flash probe error.\n", __func__);
		return 1;
	}

	ret = spi_flash_read(spi, SH7757LCR_ETHERNET_MAC_BASE, size, buf);
	if (ret) {
		printf("%s: spi_flash read error.\n", __func__);
		spi_flash_free(spi);
		return 1;
	}
	spi_flash_free(spi);

	return 0;
}

static int get_sh_eth_mac(int channel, char *mac_string, unsigned char *buf)
{
	memcpy(mac_string, &buf[channel * (SH7757LCR_ETHERNET_MAC_SIZE + 1)],
		SH7757LCR_ETHERNET_MAC_SIZE);
	mac_string[SH7757LCR_ETHERNET_MAC_SIZE] = 0x00;	/* terminate */

	return 0;
}

static void init_ethernet_mac(void)
{
	char mac_string[64];
	char env_string[64];
	int i;
	unsigned char *buf;

	buf = malloc(256);
	if (!buf) {
		printf("%s: malloc error.\n", __func__);
		return;
	}
	get_sh_eth_mac_raw(buf, 256);

	/* Fast Ethernet */
	for (i = 0; i < SH7757LCR_ETHERNET_NUM_CH; i++) {
		get_sh_eth_mac(i, mac_string, buf);
		if (i == 0)
			setenv("ethaddr", mac_string);
		else {
			sprintf(env_string, "eth%daddr", i);
			setenv(env_string, mac_string);
		}

		set_mac_to_sh_eth_register(i, mac_string);
	}

	/* Gigabit Ethernet */
	for (i = 0; i < SH7757LCR_GIGA_ETHERNET_NUM_CH; i++) {
		get_sh_eth_mac(i + SH7757LCR_ETHERNET_NUM_CH, mac_string, buf);
		sprintf(env_string, "eth%daddr", i + SH7757LCR_ETHERNET_NUM_CH);
		setenv(env_string, mac_string);

		set_mac_to_sh_giga_eth_register(i, mac_string);
	}

	free(buf);
}

static void init_pcie(void)
{
	struct pcie_setup_regs *pcie_setup = PCIE_SETUP_BASE;
	struct pcie_system_bus_regs *pcie_sysbus = PCIE_SYSTEM_BUS_BASE;

	writel(0x00000ff2, &pcie_setup->ladmsk0);
	writel(0x00000001, &pcie_setup->barmap);
	writel(0xffcaa000, &pcie_setup->lad0);
	writel(0x00030000, &pcie_sysbus->endictl0);
	writel(0x00000003, &pcie_sysbus->endictl1);
	writel(0x00000004, &pcie_setup->pbictl2);
}

static void finish_spiboot(void)
{
	struct gctrl_regs *gctrl = GCTRL_BASE;
	/*
	 *  SH7757 B0 does not use LBSC.
	 *  So if we set SPIBOOTCAN to 1, SH7757 can not access Area0.
	 *  This setting is not cleared by manual reset, So we have to set it
	 *  to 0.
	 */
	writel(0x00000000, &gctrl->spibootcan);
}

int board_late_init(void)
{
	init_ethernet_mac();
	init_pcie_bridge();
	init_pcie();
	finish_spiboot();

	return 0;
}

int do_sh_g200(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
	struct gctrl_regs *gctrl = GCTRL_BASE;
	unsigned long graofst;

	writel(0xfedcba98, &gctrl->wprotect);
	graofst = (SH7757LCR_SDRAM_PHYS_TOP + SH7757LCR_GRA_OFFSET) >> 24;
	writel(graofst | 0xa0000f00, &gctrl->gracr3);

	return 0;
}

U_BOOT_CMD(
	sh_g200,	1,	1,	do_sh_g200,
	"enable sh-g200",
	"enable SH-G200 bus (disable PCIe-G200)"
);

int do_write_mac(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
	int i, ret;
	char mac_string[256];
	struct spi_flash *spi;
	unsigned char *buf;

	if (argc != 5) {
		buf = malloc(256);
		if (!buf) {
			printf("%s: malloc error.\n", __func__);
			return 1;
		}

		get_sh_eth_mac_raw(buf, 256);

		/* print current MAC address */
		for (i = 0; i < 4; i++) {
			get_sh_eth_mac(i, mac_string, buf);
			if (i < 2)
				printf(" ETHERC ch%d = %s\n", i, mac_string);
			else
				printf("GETHERC ch%d = %s\n", i-2, mac_string);
		}
		free(buf);
		return 0;
	}

	/* new setting */
	memset(mac_string, 0xff, sizeof(mac_string));
	sprintf(mac_string, "%s\t%s\t%s\t%s",
		argv[1], argv[2], argv[3], argv[4]);

	/* write MAC data to SPI rom */
	spi = spi_flash_probe(0, 0, 1000000, SPI_MODE_3);
	if (!spi) {
		printf("%s: spi_flash probe error.\n", __func__);
		return 1;
	}

	ret = spi_flash_erase(spi, SH7757LCR_ETHERNET_MAC_BASE_SPI,
				SH7757LCR_SPI_SECTOR_SIZE);
	if (ret) {
		printf("%s: spi_flash erase error.\n", __func__);
		return 1;
	}

	ret = spi_flash_write(spi, SH7757LCR_ETHERNET_MAC_BASE_SPI,
				sizeof(mac_string), mac_string);
	if (ret) {
		printf("%s: spi_flash write error.\n", __func__);
		spi_flash_free(spi);
		return 1;
	}
	spi_flash_free(spi);

	puts("The writing of the MAC address to SPI ROM was completed.\n");

	return 0;
}

U_BOOT_CMD(
	write_mac,	5,	1,	do_write_mac,
	"write MAC address for ETHERC/GETHERC",
	"[ETHERC ch0] [ETHERC ch1] [GETHERC ch0] [GETHERC ch1]\n"
);
