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

#include <common.h>
#include <command.h>
#include <env.h>
#include <flash.h>
#include <init.h>
#include <malloc.h>
#include <net.h>
#include <asm/processor.h>
#include <asm/io.h>
#include <asm/mmc.h>
#include <spi.h>
#include <spi_flash.h>
#include <linux/delay.h>

int checkboard(void)
{
	puts("BOARD: SH7752 evaluation board (R0P7752C00000RZ)\n");

	return 0;
}

static void init_gpio(void)
{
	struct gpio_regs *gpio = GPIO_BASE;
	struct sermux_regs *sermux = SERMUX_BASE;

	/* GPIO */
	writew(0x0000, &gpio->pacr);	/* GETHER */
	writew(0x0001, &gpio->pbcr);	/* INTC */
	writew(0x0000, &gpio->pccr);	/* PWMU, INTC */
	writew(0xeaff, &gpio->pecr);	/* GPIO */
	writew(0x0000, &gpio->pfcr);	/* WDT */
	writew(0x0000, &gpio->phcr);	/* SPI1 */
	writew(0x0000, &gpio->picr);	/* SDHI */
	writew(0x0003, &gpio->pkcr);	/* SerMux */
	writew(0x0000, &gpio->plcr);	/* SerMux */
	writew(0x0000, &gpio->pmcr);	/* RIIC */
	writew(0x0000, &gpio->pncr);	/* USB, SGPIO */
	writew(0x0000, &gpio->pocr);	/* SGPIO */
	writew(0xd555, &gpio->pqcr);	/* GPIO */
	writew(0x0000, &gpio->prcr);	/* RIIC */
	writew(0x0000, &gpio->pscr);	/* RIIC */
	writeb(0x00, &gpio->pudr);
	writew(0x5555, &gpio->pucr);	/* Debug LED */
	writew(0x0000, &gpio->pvcr);	/* RSPI */
	writew(0x0000, &gpio->pwcr);	/* EVC */
	writew(0x0000, &gpio->pxcr);	/* LBSC */
	writew(0x0000, &gpio->pycr);	/* LBSC */
	writew(0x0000, &gpio->pzcr);	/* eMMC */
	writew(0xfe00, &gpio->psel0);
	writew(0xff00, &gpio->psel3);
	writew(0x771f, &gpio->psel4);
	writew(0x00ff, &gpio->psel6);
	writew(0xfc00, &gpio->psel7);

	writeb(0x10, &sermux->smr0);	/* SMR0: SerMux mode 0 */
}

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 init_gether_mdio(void)
{
	struct gpio_regs *gpio = GPIO_BASE;

	writew(readw(&gpio->pgcr) | 0x0004, &gpio->pgcr);
	writeb(readb(&gpio->pgdr) | 0x02, &gpio->pgdr);	/* Use ET0-MDIO */
}

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;

	string_to_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)
{
	init_gpio();
	set_pmb_on_board_init();

	init_usb_phy();
	init_gether_mdio();

	return 0;
}

int board_mmc_init(bd_t *bis)
{
	struct gpio_regs *gpio = GPIO_BASE;

	writew(readw(&gpio->pgcr) | 0x0040, &gpio->pgcr);
	writeb(readb(&gpio->pgdr) & ~0x08, &gpio->pgdr); /* Reset */
	udelay(1);
	writeb(readb(&gpio->pgdr) | 0x08, &gpio->pgdr);	/* Release reset */
	udelay(200);

	return mmcif_mmc_init();
}

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

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

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

	return 0;
}

static int get_sh_eth_mac(int channel, char *mac_string, unsigned char *buf)
{
	memcpy(mac_string, &buf[channel * (SH7752EVB_ETHERNET_MAC_SIZE + 1)],
		SH7752EVB_ETHERNET_MAC_SIZE);
	mac_string[SH7752EVB_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 failed.\n", __func__);
		return;
	}
	get_sh_eth_mac_raw(buf, 256);

	/* Gigabit Ethernet */
	for (i = 0; i < SH7752EVB_ETHERNET_NUM_CH; i++) {
		get_sh_eth_mac(i, mac_string, buf);
		if (i == 0)
			env_set("ethaddr", mac_string);
		else {
			sprintf(env_string, "eth%daddr", i);
			env_set(env_string, mac_string);
		}
		set_mac_to_sh_giga_eth_register(i, mac_string);
	}

	free(buf);
}

int board_late_init(void)
{
	init_ethernet_mac();

	return 0;
}

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

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

		get_sh_eth_mac_raw(buf, 256);

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

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

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

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

	ret = spi_flash_write(spi, SH7752EVB_ETHERNET_MAC_BASE_SPI,
				sizeof(mac_string), mac_string);
	if (ret) {
		printf("%s: spi_flash write failed.\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,	3,	1,	do_write_mac,
	"write MAC address for GETHERC",
	"[GETHERC ch0] [GETHERC ch1]\n"
);
#endif
