/*
 * Copyright (C) 2008 Yoshihiro Shimoda <shimoda.yoshihiro@renesas.com>
 *
 * SPDX-License-Identifier:	GPL-2.0+
 */

#include <common.h>
#include "rtl8169.h"

static unsigned char *PCI_MEMR;

static void mac_delay(unsigned int cnt)
{
	udelay(cnt);
}

static void mac_pci_setup(void)
{
	unsigned long pci_data;

	PCI_PAR = 0x00000010;
	PCI_PDR = 0x00001000;
	PCI_PAR = 0x00000004;
	pci_data = PCI_PDR;
	PCI_PDR = pci_data | 0x00000007;
	PCI_PAR = 0x00000010;

	PCI_MEMR = (unsigned char *)((PCI_PDR | 0xFE240050) & 0xFFFFFFF0);
}

static void EECS(int level)
{
	unsigned char data = *PCI_MEMR;

	if (level)
		*PCI_MEMR = data | 0x08;
	else
		*PCI_MEMR = data & 0xf7;
}

static void EECLK(int level)
{
	unsigned char data = *PCI_MEMR;

	if (level)
		*PCI_MEMR = data | 0x04;
	else
		*PCI_MEMR = data & 0xfb;
}

static void EEDI(int level)
{
	unsigned char data = *PCI_MEMR;

	if (level)
		*PCI_MEMR = data | 0x02;
	else
		*PCI_MEMR = data & 0xfd;
}

static inline void sh7785lcr_bitset(unsigned short bit)
{
	if (bit)
		EEDI(HIGH);
	else
		EEDI(LOW);

	EECLK(LOW);
	mac_delay(TIME1);
	EECLK(HIGH);
	mac_delay(TIME1);
	EEDI(LOW);
}

static inline unsigned char sh7785lcr_bitget(void)
{
	unsigned char bit;

	EECLK(LOW);
	mac_delay(TIME1);
	bit = *PCI_MEMR & 0x01;
	EECLK(HIGH);
	mac_delay(TIME1);

	return bit;
}

static inline void sh7785lcr_setcmd(unsigned char command)
{
	sh7785lcr_bitset(BIT_DUMMY);
	switch (command) {
	case MAC_EEP_READ:
		sh7785lcr_bitset(1);
		sh7785lcr_bitset(1);
		sh7785lcr_bitset(0);
		break;
	case MAC_EEP_WRITE:
		sh7785lcr_bitset(1);
		sh7785lcr_bitset(0);
		sh7785lcr_bitset(1);
		break;
	case MAC_EEP_ERACE:
		sh7785lcr_bitset(1);
		sh7785lcr_bitset(1);
		sh7785lcr_bitset(1);
		break;
	case MAC_EEP_EWEN:
		sh7785lcr_bitset(1);
		sh7785lcr_bitset(0);
		sh7785lcr_bitset(0);
		break;
	case MAC_EEP_EWDS:
		sh7785lcr_bitset(1);
		sh7785lcr_bitset(0);
		sh7785lcr_bitset(0);
		break;
	default:
		break;
	}
}

static inline unsigned short sh7785lcr_getdt(void)
{
	unsigned short data = 0;
	int i;

	sh7785lcr_bitget();			/* DUMMY */
	for (i = 0 ; i < 16 ; i++) {
		data <<= 1;
		data |= sh7785lcr_bitget();
	}
	return data;
}

static inline void sh7785lcr_setadd(unsigned short address)
{
	sh7785lcr_bitset(address & 0x0020);	/* A5 */
	sh7785lcr_bitset(address & 0x0010);	/* A4 */
	sh7785lcr_bitset(address & 0x0008);	/* A3 */
	sh7785lcr_bitset(address & 0x0004);	/* A2 */
	sh7785lcr_bitset(address & 0x0002);	/* A1 */
	sh7785lcr_bitset(address & 0x0001);	/* A0 */
}

static inline void sh7785lcr_setdata(unsigned short data)
{
	sh7785lcr_bitset(data & 0x8000);
	sh7785lcr_bitset(data & 0x4000);
	sh7785lcr_bitset(data & 0x2000);
	sh7785lcr_bitset(data & 0x1000);
	sh7785lcr_bitset(data & 0x0800);
	sh7785lcr_bitset(data & 0x0400);
	sh7785lcr_bitset(data & 0x0200);
	sh7785lcr_bitset(data & 0x0100);
	sh7785lcr_bitset(data & 0x0080);
	sh7785lcr_bitset(data & 0x0040);
	sh7785lcr_bitset(data & 0x0020);
	sh7785lcr_bitset(data & 0x0010);
	sh7785lcr_bitset(data & 0x0008);
	sh7785lcr_bitset(data & 0x0004);
	sh7785lcr_bitset(data & 0x0002);
	sh7785lcr_bitset(data & 0x0001);
}

static void sh7785lcr_datawrite(const unsigned short *data, unsigned short address,
			 unsigned int count)
{
	unsigned int i;

	for (i = 0; i < count; i++) {
		EECS(HIGH);
		EEDI(LOW);
		mac_delay(TIME1);

		sh7785lcr_setcmd(MAC_EEP_WRITE);
		sh7785lcr_setadd(address++);
		sh7785lcr_setdata(*(data + i));

		EECLK(LOW);
		EEDI(LOW);
		EECS(LOW);
		mac_delay(TIME2);
	}
}

static void sh7785lcr_macerase(void)
{
	unsigned int i;
	unsigned short pci_address = 7;

	for (i = 0; i < 3; i++) {
		EECS(HIGH);
		EEDI(LOW);
		mac_delay(TIME1);
		sh7785lcr_setcmd(MAC_EEP_ERACE);
		sh7785lcr_setadd(pci_address++);
		mac_delay(TIME1);
		EECLK(LOW);
		EEDI(LOW);
		EECS(LOW);
	}

	mac_delay(TIME2);

	printf("\n\nErace End\n");
	for (i = 0; i < 10; i++)
		mac_delay(TIME2);
}

static void sh7785lcr_macwrite(unsigned short *data)
{
	sh7785lcr_macerase();

	sh7785lcr_datawrite(EEPROM_W_Data_8169_A, 0x0000, 7);
	sh7785lcr_datawrite(data, PCI_EEP_ADDRESS, PCI_MAC_ADDRESS_SIZE);
	sh7785lcr_datawrite(EEPROM_W_Data_8169_B, 0x000a, 54);
}

void sh7785lcr_macdtrd(unsigned char *buf, unsigned short address, unsigned int count)
{
	unsigned int i;
	unsigned short wk;

	for (i = 0 ; i < count; i++) {
		EECS(HIGH);
		EEDI(LOW);
		mac_delay(TIME1);
		sh7785lcr_setcmd(MAC_EEP_READ);
		sh7785lcr_setadd(address++);
		wk = sh7785lcr_getdt();

		*buf++ = (unsigned char)(wk & 0xff);
		*buf++ = (unsigned char)((wk >> 8) & 0xff);
		EECLK(LOW);
		EEDI(LOW);
		EECS(LOW);
	}
}

static void sh7785lcr_macadrd(unsigned char *buf)
{
	*PCI_MEMR = PCI_PROG;

	sh7785lcr_macdtrd(buf, PCI_EEP_ADDRESS, PCI_MAC_ADDRESS_SIZE);
}

static void sh7785lcr_eepewen(void)
{
	*PCI_MEMR = PCI_PROG;
	mac_delay(TIME1);
	EECS(LOW);
	EECLK(LOW);
	EEDI(LOW);
	EECS(HIGH);
	mac_delay(TIME1);

	sh7785lcr_setcmd(MAC_EEP_EWEN);
	sh7785lcr_bitset(1);
	sh7785lcr_bitset(1);
	sh7785lcr_bitset(BIT_DUMMY);
	sh7785lcr_bitset(BIT_DUMMY);
	sh7785lcr_bitset(BIT_DUMMY);
	sh7785lcr_bitset(BIT_DUMMY);

	EECLK(LOW);
	EEDI(LOW);
	EECS(LOW);
	mac_delay(TIME1);
}

void mac_write(unsigned short *data)
{
	mac_pci_setup();
	sh7785lcr_eepewen();
	sh7785lcr_macwrite(data);
}

void mac_read(void)
{
	unsigned char data[6];

	mac_pci_setup();
	sh7785lcr_macadrd(data);
	printf("Mac = %02x:%02x:%02x:%02x:%02x:%02x\n",
		data[0], data[1], data[2], data[3], data[4], data[5]);
}

int do_set_mac(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
	int i;
	unsigned char mac[6];
	char *s, *e;

	if (argc != 2)
		return cmd_usage(cmdtp);

	s = argv[1];

	for (i = 0; i < 6; i++) {
		mac[i] = s ? simple_strtoul(s, &e, 16) : 0;
		if (s)
			s = (*e) ? e + 1 : e;
	}
	mac_write((unsigned short *)mac);

	return 0;
}

U_BOOT_CMD(
	setmac,	2,	1,	do_set_mac,
	"write MAC address for RTL8110SCL",
	"\n"
	"setmac <mac address> - write MAC address for RTL8110SCL"
);

int do_print_mac(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
	if (argc != 1)
		return cmd_usage(cmdtp);

	mac_read();

	return 0;
}

U_BOOT_CMD(
	printmac,	1,	1,	do_print_mac,
	"print MAC address for RTL8110",
	"\n"
	"    - print MAC address for RTL8110"
);
