sh: ms7724se: Add sh_eth support

Signed-off-by: Kuninori Morimoto <morimoto.kuninori@renesas.com>
Signed-off-by: Paul Mundt <lethal@linux-sh.org>
diff --git a/arch/sh/boards/mach-se/7724/setup.c b/arch/sh/boards/mach-se/7724/setup.c
index 9cd04bd..21d1800 100644
--- a/arch/sh/boards/mach-se/7724/setup.c
+++ b/arch/sh/boards/mach-se/7724/setup.c
@@ -23,6 +23,8 @@
 #include <media/sh_mobile_ceu.h>
 #include <asm/io.h>
 #include <asm/heartbeat.h>
+#include <asm/sh_eth.h>
+#include <asm/clock.h>
 #include <asm/sh_keysc.h>
 #include <cpu/sh7724.h>
 #include <mach-se/mach/se7724.h>
@@ -272,6 +274,34 @@
 	},
 };
 
+/* SH Eth */
+static struct resource sh_eth_resources[] = {
+	[0] = {
+		.start = SH_ETH_ADDR,
+		.end   = SH_ETH_ADDR + 0x1FC,
+		.flags = IORESOURCE_MEM,
+	},
+	[1] = {
+		.start = 91,
+		.flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
+	},
+};
+
+struct sh_eth_plat_data sh_eth_plat = {
+	.phy = 0x1f, /* SMSC LAN8187 */
+	.edmac_endian = EDMAC_LITTLE_ENDIAN,
+};
+
+static struct platform_device sh_eth_device = {
+	.name = "sh-eth",
+	.id	= 0,
+	.dev = {
+		.platform_data = &sh_eth_plat,
+	},
+	.num_resources = ARRAY_SIZE(sh_eth_resources),
+	.resource = sh_eth_resources,
+};
+
 static struct platform_device *ms7724se_devices[] __initdata = {
 	&heartbeat_device,
 	&smc91x_eth_device,
@@ -280,8 +310,57 @@
 	&ceu0_device,
 	&ceu1_device,
 	&keysc_device,
+	&sh_eth_device,
 };
 
+#define EEPROM_OP   0xBA206000
+#define EEPROM_ADR  0xBA206004
+#define EEPROM_DATA 0xBA20600C
+#define EEPROM_STAT 0xBA206010
+#define EEPROM_STRT 0xBA206014
+static int __init sh_eth_is_eeprom_ready(void)
+{
+	int t = 10000;
+
+	while (t--) {
+		if (!ctrl_inw(EEPROM_STAT))
+			return 1;
+		cpu_relax();
+	}
+
+	printk(KERN_ERR "ms7724se can not access to eeprom\n");
+	return 0;
+}
+
+static void __init sh_eth_init(void)
+{
+	int i;
+	u16 mac[3];
+
+	/* check EEPROM status */
+	if (!sh_eth_is_eeprom_ready())
+		return;
+
+	/* read MAC addr from EEPROM */
+	for (i = 0 ; i < 3 ; i++) {
+		ctrl_outw(0x0, EEPROM_OP); /* read */
+		ctrl_outw(i*2, EEPROM_ADR);
+		ctrl_outw(0x1, EEPROM_STRT);
+		if (!sh_eth_is_eeprom_ready())
+			return;
+
+		mac[i] = ctrl_inw(EEPROM_DATA);
+		mac[i] = ((mac[i] & 0xFF) << 8) | (mac[i] >> 8); /* swap */
+	}
+
+	/* reset sh-eth */
+	ctrl_outl(0x1, SH_ETH_ADDR + 0x0);
+
+	/* set MAC addr */
+	ctrl_outl(((mac[0] << 16) | (mac[1])), SH_ETH_MAHR);
+	ctrl_outl((mac[2]), SH_ETH_MALR);
+}
+
 #define SW4140    0xBA201000
 #define FPGA_OUT  0xBA200400
 #define PORT_HIZA 0xA4050158
@@ -302,7 +381,8 @@
 	ctrl_outw(ctrl_inw(FPGA_OUT) &
 		  ~((1 << 1)  | /* LAN */
 		    (1 << 6)  | /* VIDEO DAC */
-		    (1 << 12)), /* USB0 */
+		    (1 << 12) | /* USB0 */
+		    (1 << 14)), /* RMII */
 		  FPGA_OUT);
 
 	/* enable IRQ 0,1,2 */
@@ -404,6 +484,28 @@
 	gpio_request(GPIO_FN_KEYOUT1,     NULL);
 	gpio_request(GPIO_FN_KEYOUT0,     NULL);
 
+	/*
+	 * enable SH-Eth
+	 *
+	 * please remove J33 pin from your board !!
+	 *
+	 * ms7724 board should not use GPIO_FN_LNKSTA pin
+	 * So, This time PTX5 is set to input pin
+	 */
+	gpio_request(GPIO_FN_RMII_RXD0,    NULL);
+	gpio_request(GPIO_FN_RMII_RXD1,    NULL);
+	gpio_request(GPIO_FN_RMII_TXD0,    NULL);
+	gpio_request(GPIO_FN_RMII_TXD1,    NULL);
+	gpio_request(GPIO_FN_RMII_REF_CLK, NULL);
+	gpio_request(GPIO_FN_RMII_TX_EN,   NULL);
+	gpio_request(GPIO_FN_RMII_RX_ER,   NULL);
+	gpio_request(GPIO_FN_RMII_CRS_DV,  NULL);
+	gpio_request(GPIO_FN_MDIO,         NULL);
+	gpio_request(GPIO_FN_MDC,          NULL);
+	gpio_request(GPIO_PTX5, NULL);
+	gpio_direction_input(GPIO_PTX5);
+	sh_eth_init();
+
 	if (sw & SW41_B) {
 		/* SVGA */
 		lcdc_info.ch[0].lcd_cfg.xres         = 800;
@@ -437,7 +539,7 @@
 	}
 
 	return platform_add_devices(ms7724se_devices,
-				ARRAY_SIZE(ms7724se_devices));
+				    ARRAY_SIZE(ms7724se_devices));
 }
 device_initcall(devices_setup);
 
diff --git a/arch/sh/include/mach-se/mach/se7724.h b/arch/sh/include/mach-se/mach/se7724.h
index 74164b6..29514a3 100644
--- a/arch/sh/include/mach-se/mach/se7724.h
+++ b/arch/sh/include/mach-se/mach/se7724.h
@@ -20,6 +20,11 @@
  */
 #include <asm/addrspace.h>
 
+/* SH Eth */
+#define SH_ETH_ADDR	(0xA4600000)
+#define SH_ETH_MAHR	(SH_ETH_ADDR + 0x1C0)
+#define SH_ETH_MALR	(SH_ETH_ADDR + 0x1C8)
+
 #define PA_LED		(0xba203000)	/* 8bit LED */
 #define IRQ_MODE	(0xba200010)
 #define IRQ0_SR		(0xba200014)