/*
 * Copyright (C) 2008 Yoshihiro Shimoda <shimoda.yoshihiro@renesas.com>
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; either version 2 of
 * the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 * MA 02111-1307 USA
 */

#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 *argv[])
{
	int i;
	unsigned char mac[6];
	char *s, *e;

	if (argc != 2) {
		printf("Usage:\n%s\n", cmdtp->usage);
		return 1;
	}

	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,
	"setmac - write MAC address for RTL8110SCL\n",
	"\n"
	"setmac <mac address> - write MAC address for RTL8110SCL\n"
);

int do_print_mac(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{
	if (argc != 1) {
		printf("Usage:\n%s\n", cmdtp->usage);
		return 1;
	}

	mac_read();

	return 0;
}

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

