1*0fdebc5eSThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only
29dd0b194SLennert Buytenhek /*
39dd0b194SLennert Buytenhek  * arch/arm/mach-orion5x/kurobox_pro-setup.c
49dd0b194SLennert Buytenhek  *
59dd0b194SLennert Buytenhek  * Maintainer: Ronen Shitrit <rshitrit@marvell.com>
69dd0b194SLennert Buytenhek  */
72f8163baSRussell King #include <linux/gpio.h>
89dd0b194SLennert Buytenhek #include <linux/kernel.h>
99dd0b194SLennert Buytenhek #include <linux/init.h>
109dd0b194SLennert Buytenhek #include <linux/platform_device.h>
119dd0b194SLennert Buytenhek #include <linux/pci.h>
129dd0b194SLennert Buytenhek #include <linux/irq.h>
13a0087f2fSSylver Bruneau #include <linux/delay.h>
149dd0b194SLennert Buytenhek #include <linux/mtd/physmap.h>
15d4092d76SBoris Brezillon #include <linux/mtd/rawnand.h>
169dd0b194SLennert Buytenhek #include <linux/mv643xx_eth.h>
179dd0b194SLennert Buytenhek #include <linux/i2c.h>
18a0087f2fSSylver Bruneau #include <linux/serial_reg.h>
199dd0b194SLennert Buytenhek #include <linux/ata_platform.h>
209dd0b194SLennert Buytenhek #include <asm/mach-types.h>
219dd0b194SLennert Buytenhek #include <asm/mach/arch.h>
229dd0b194SLennert Buytenhek #include <asm/mach/pci.h>
23c02cecb9SArnd Bergmann #include <linux/platform_data/mtd-orion_nand.h>
249dd0b194SLennert Buytenhek #include "common.h"
2519cfd5c0SLennert Buytenhek #include "mpp.h"
26c22c2c60SArnd Bergmann #include "orion5x.h"
279dd0b194SLennert Buytenhek 
289dd0b194SLennert Buytenhek /*****************************************************************************
299dd0b194SLennert Buytenhek  * KUROBOX-PRO Info
309dd0b194SLennert Buytenhek  ****************************************************************************/
319dd0b194SLennert Buytenhek 
329dd0b194SLennert Buytenhek /*
339dd0b194SLennert Buytenhek  * 256K NOR flash Device bus boot chip select
349dd0b194SLennert Buytenhek  */
359dd0b194SLennert Buytenhek 
369dd0b194SLennert Buytenhek #define KUROBOX_PRO_NOR_BOOT_BASE	0xf4000000
379dd0b194SLennert Buytenhek #define KUROBOX_PRO_NOR_BOOT_SIZE	SZ_256K
389dd0b194SLennert Buytenhek 
399dd0b194SLennert Buytenhek /*
409dd0b194SLennert Buytenhek  * 256M NAND flash on Device bus chip select 1
419dd0b194SLennert Buytenhek  */
429dd0b194SLennert Buytenhek 
439dd0b194SLennert Buytenhek #define KUROBOX_PRO_NAND_BASE		0xfc000000
449dd0b194SLennert Buytenhek #define KUROBOX_PRO_NAND_SIZE		SZ_2M
459dd0b194SLennert Buytenhek 
469dd0b194SLennert Buytenhek /*****************************************************************************
479dd0b194SLennert Buytenhek  * 256MB NAND Flash on Device bus CS0
489dd0b194SLennert Buytenhek  ****************************************************************************/
499dd0b194SLennert Buytenhek 
509dd0b194SLennert Buytenhek static struct mtd_partition kurobox_pro_nand_parts[] = {
519dd0b194SLennert Buytenhek 	{
529dd0b194SLennert Buytenhek 		.name	= "uImage",
539dd0b194SLennert Buytenhek 		.offset	= 0,
549dd0b194SLennert Buytenhek 		.size	= SZ_4M,
55e7068ad3SLennert Buytenhek 	}, {
569dd0b194SLennert Buytenhek 		.name	= "rootfs",
579dd0b194SLennert Buytenhek 		.offset	= SZ_4M,
589dd0b194SLennert Buytenhek 		.size	= SZ_64M,
59e7068ad3SLennert Buytenhek 	}, {
609dd0b194SLennert Buytenhek 		.name	= "extra",
619dd0b194SLennert Buytenhek 		.offset	= SZ_4M + SZ_64M,
629dd0b194SLennert Buytenhek 		.size	= SZ_256M - (SZ_4M + SZ_64M),
639dd0b194SLennert Buytenhek 	},
649dd0b194SLennert Buytenhek };
659dd0b194SLennert Buytenhek 
669dd0b194SLennert Buytenhek static struct resource kurobox_pro_nand_resource = {
679dd0b194SLennert Buytenhek 	.flags		= IORESOURCE_MEM,
689dd0b194SLennert Buytenhek 	.start		= KUROBOX_PRO_NAND_BASE,
699dd0b194SLennert Buytenhek 	.end		= KUROBOX_PRO_NAND_BASE + KUROBOX_PRO_NAND_SIZE - 1,
709dd0b194SLennert Buytenhek };
719dd0b194SLennert Buytenhek 
729dd0b194SLennert Buytenhek static struct orion_nand_data kurobox_pro_nand_data = {
739dd0b194SLennert Buytenhek 	.parts		= kurobox_pro_nand_parts,
749dd0b194SLennert Buytenhek 	.nr_parts	= ARRAY_SIZE(kurobox_pro_nand_parts),
759dd0b194SLennert Buytenhek 	.cle		= 0,
769dd0b194SLennert Buytenhek 	.ale		= 1,
779dd0b194SLennert Buytenhek 	.width		= 8,
789dd0b194SLennert Buytenhek };
799dd0b194SLennert Buytenhek 
809dd0b194SLennert Buytenhek static struct platform_device kurobox_pro_nand_flash = {
819dd0b194SLennert Buytenhek 	.name		= "orion_nand",
829dd0b194SLennert Buytenhek 	.id		= -1,
839dd0b194SLennert Buytenhek 	.dev		= {
849dd0b194SLennert Buytenhek 		.platform_data	= &kurobox_pro_nand_data,
859dd0b194SLennert Buytenhek 	},
869dd0b194SLennert Buytenhek 	.resource	= &kurobox_pro_nand_resource,
879dd0b194SLennert Buytenhek 	.num_resources	= 1,
889dd0b194SLennert Buytenhek };
899dd0b194SLennert Buytenhek 
909dd0b194SLennert Buytenhek /*****************************************************************************
919dd0b194SLennert Buytenhek  * 256KB NOR Flash on BOOT Device
929dd0b194SLennert Buytenhek  ****************************************************************************/
939dd0b194SLennert Buytenhek 
949dd0b194SLennert Buytenhek static struct physmap_flash_data kurobox_pro_nor_flash_data = {
959dd0b194SLennert Buytenhek 	.width		= 1,
969dd0b194SLennert Buytenhek };
979dd0b194SLennert Buytenhek 
989dd0b194SLennert Buytenhek static struct resource kurobox_pro_nor_flash_resource = {
999dd0b194SLennert Buytenhek 	.flags			= IORESOURCE_MEM,
1009dd0b194SLennert Buytenhek 	.start			= KUROBOX_PRO_NOR_BOOT_BASE,
1019dd0b194SLennert Buytenhek 	.end			= KUROBOX_PRO_NOR_BOOT_BASE + KUROBOX_PRO_NOR_BOOT_SIZE - 1,
1029dd0b194SLennert Buytenhek };
1039dd0b194SLennert Buytenhek 
1049dd0b194SLennert Buytenhek static struct platform_device kurobox_pro_nor_flash = {
1059dd0b194SLennert Buytenhek 	.name			= "physmap-flash",
1069dd0b194SLennert Buytenhek 	.id			= 0,
1079dd0b194SLennert Buytenhek 	.dev		= {
1089dd0b194SLennert Buytenhek 		.platform_data	= &kurobox_pro_nor_flash_data,
1099dd0b194SLennert Buytenhek 	},
1109dd0b194SLennert Buytenhek 	.num_resources		= 1,
1119dd0b194SLennert Buytenhek 	.resource		= &kurobox_pro_nor_flash_resource,
1129dd0b194SLennert Buytenhek };
1139dd0b194SLennert Buytenhek 
1149dd0b194SLennert Buytenhek /*****************************************************************************
1159dd0b194SLennert Buytenhek  * PCI
1169dd0b194SLennert Buytenhek  ****************************************************************************/
1179dd0b194SLennert Buytenhek 
kurobox_pro_pci_map_irq(const struct pci_dev * dev,u8 slot,u8 pin)118d5341942SRalf Baechle static int __init kurobox_pro_pci_map_irq(const struct pci_dev *dev, u8 slot,
119d5341942SRalf Baechle 	u8 pin)
1209dd0b194SLennert Buytenhek {
12192b913b0SLennert Buytenhek 	int irq;
12292b913b0SLennert Buytenhek 
12392b913b0SLennert Buytenhek 	/*
12492b913b0SLennert Buytenhek 	 * Check for devices with hard-wired IRQs.
12592b913b0SLennert Buytenhek 	 */
12692b913b0SLennert Buytenhek 	irq = orion5x_pci_map_irq(dev, slot, pin);
12792b913b0SLennert Buytenhek 	if (irq != -1)
12892b913b0SLennert Buytenhek 		return irq;
12992b913b0SLennert Buytenhek 
1309dd0b194SLennert Buytenhek 	/*
1319dd0b194SLennert Buytenhek 	 * PCI isn't used on the Kuro
1329dd0b194SLennert Buytenhek 	 */
1339dd0b194SLennert Buytenhek 	return -1;
1349dd0b194SLennert Buytenhek }
1359dd0b194SLennert Buytenhek 
1369dd0b194SLennert Buytenhek static struct hw_pci kurobox_pro_pci __initdata = {
137bbdf1c1eSLennert Buytenhek 	.nr_controllers	= 2,
1389dd0b194SLennert Buytenhek 	.setup		= orion5x_pci_sys_setup,
1399dd0b194SLennert Buytenhek 	.scan		= orion5x_pci_sys_scan_bus,
1409dd0b194SLennert Buytenhek 	.map_irq	= kurobox_pro_pci_map_irq,
1419dd0b194SLennert Buytenhek };
1429dd0b194SLennert Buytenhek 
kurobox_pro_pci_init(void)1439dd0b194SLennert Buytenhek static int __init kurobox_pro_pci_init(void)
1449dd0b194SLennert Buytenhek {
1457a6bb262SPer Andersson 	if (machine_is_kurobox_pro()) {
1467a6bb262SPer Andersson 		orion5x_pci_disable();
1479dd0b194SLennert Buytenhek 		pci_common_init(&kurobox_pro_pci);
1487a6bb262SPer Andersson 	}
1499dd0b194SLennert Buytenhek 
1509dd0b194SLennert Buytenhek 	return 0;
1519dd0b194SLennert Buytenhek }
1529dd0b194SLennert Buytenhek 
1539dd0b194SLennert Buytenhek subsys_initcall(kurobox_pro_pci_init);
1549dd0b194SLennert Buytenhek 
1559dd0b194SLennert Buytenhek /*****************************************************************************
1569dd0b194SLennert Buytenhek  * Ethernet
1579dd0b194SLennert Buytenhek  ****************************************************************************/
1589dd0b194SLennert Buytenhek 
1599dd0b194SLennert Buytenhek static struct mv643xx_eth_platform_data kurobox_pro_eth_data = {
160ac840605SLennert Buytenhek 	.phy_addr	= MV643XX_ETH_PHY_ADDR(8),
1619dd0b194SLennert Buytenhek };
1629dd0b194SLennert Buytenhek 
1639dd0b194SLennert Buytenhek /*****************************************************************************
1649dd0b194SLennert Buytenhek  * RTC 5C372a on I2C bus
1659dd0b194SLennert Buytenhek  ****************************************************************************/
1669dd0b194SLennert Buytenhek static struct i2c_board_info __initdata kurobox_pro_i2c_rtc = {
1673760f736SJean Delvare 	I2C_BOARD_INFO("rs5c372a", 0x32),
1689dd0b194SLennert Buytenhek };
1699dd0b194SLennert Buytenhek 
1709dd0b194SLennert Buytenhek /*****************************************************************************
1719dd0b194SLennert Buytenhek  * SATA
1729dd0b194SLennert Buytenhek  ****************************************************************************/
1739dd0b194SLennert Buytenhek static struct mv_sata_platform_data kurobox_pro_sata_data = {
1749dd0b194SLennert Buytenhek 	.n_ports	= 2,
1759dd0b194SLennert Buytenhek };
1769dd0b194SLennert Buytenhek 
1779dd0b194SLennert Buytenhek /*****************************************************************************
178a0087f2fSSylver Bruneau  * Kurobox Pro specific power off method via UART1-attached microcontroller
179a0087f2fSSylver Bruneau  ****************************************************************************/
180a0087f2fSSylver Bruneau 
181a0087f2fSSylver Bruneau #define UART1_REG(x)	(UART1_VIRT_BASE + ((UART_##x) << 2))
182a0087f2fSSylver Bruneau 
kurobox_pro_miconread(unsigned char * buf,int count)183a0087f2fSSylver Bruneau static int kurobox_pro_miconread(unsigned char *buf, int count)
184a0087f2fSSylver Bruneau {
185a0087f2fSSylver Bruneau 	int i;
186a0087f2fSSylver Bruneau 	int timeout;
187a0087f2fSSylver Bruneau 
188a0087f2fSSylver Bruneau 	for (i = 0; i < count; i++) {
189a0087f2fSSylver Bruneau 		timeout = 10;
190a0087f2fSSylver Bruneau 
191a0087f2fSSylver Bruneau 		while (!(readl(UART1_REG(LSR)) & UART_LSR_DR)) {
192a0087f2fSSylver Bruneau 			if (--timeout == 0)
193a0087f2fSSylver Bruneau 				break;
194a0087f2fSSylver Bruneau 			udelay(1000);
195a0087f2fSSylver Bruneau 		}
196a0087f2fSSylver Bruneau 
197a0087f2fSSylver Bruneau 		if (timeout == 0)
198a0087f2fSSylver Bruneau 			break;
199a0087f2fSSylver Bruneau 		buf[i] = readl(UART1_REG(RX));
200a0087f2fSSylver Bruneau 	}
201a0087f2fSSylver Bruneau 
202a0087f2fSSylver Bruneau 	/* return read bytes */
203a0087f2fSSylver Bruneau 	return i;
204a0087f2fSSylver Bruneau }
205a0087f2fSSylver Bruneau 
kurobox_pro_miconwrite(const unsigned char * buf,int count)206a0087f2fSSylver Bruneau static int kurobox_pro_miconwrite(const unsigned char *buf, int count)
207a0087f2fSSylver Bruneau {
208a0087f2fSSylver Bruneau 	int i = 0;
209a0087f2fSSylver Bruneau 
210a0087f2fSSylver Bruneau 	while (count--) {
211a0087f2fSSylver Bruneau 		while (!(readl(UART1_REG(LSR)) & UART_LSR_THRE))
212a0087f2fSSylver Bruneau 			barrier();
213a0087f2fSSylver Bruneau 		writel(buf[i++], UART1_REG(TX));
214a0087f2fSSylver Bruneau 	}
215a0087f2fSSylver Bruneau 
216a0087f2fSSylver Bruneau 	return 0;
217a0087f2fSSylver Bruneau }
218a0087f2fSSylver Bruneau 
kurobox_pro_miconsend(const unsigned char * data,int count)219a0087f2fSSylver Bruneau static int kurobox_pro_miconsend(const unsigned char *data, int count)
220a0087f2fSSylver Bruneau {
221a0087f2fSSylver Bruneau 	int i;
222a0087f2fSSylver Bruneau 	unsigned char checksum = 0;
223a0087f2fSSylver Bruneau 	unsigned char recv_buf[40];
224a0087f2fSSylver Bruneau 	unsigned char send_buf[40];
225a0087f2fSSylver Bruneau 	unsigned char correct_ack[3];
226a0087f2fSSylver Bruneau 	int retry = 2;
227a0087f2fSSylver Bruneau 
228a0087f2fSSylver Bruneau 	/* Generate checksum */
229a0087f2fSSylver Bruneau 	for (i = 0; i < count; i++)
230a0087f2fSSylver Bruneau 		checksum -=  data[i];
231a0087f2fSSylver Bruneau 
232a0087f2fSSylver Bruneau 	do {
233a0087f2fSSylver Bruneau 		/* Send data */
234a0087f2fSSylver Bruneau 		kurobox_pro_miconwrite(data, count);
235a0087f2fSSylver Bruneau 
236a0087f2fSSylver Bruneau 		/* send checksum */
237a0087f2fSSylver Bruneau 		kurobox_pro_miconwrite(&checksum, 1);
238a0087f2fSSylver Bruneau 
239a0087f2fSSylver Bruneau 		if (kurobox_pro_miconread(recv_buf, sizeof(recv_buf)) <= 3) {
240a0087f2fSSylver Bruneau 			printk(KERN_ERR ">%s: receive failed.\n", __func__);
241a0087f2fSSylver Bruneau 
242a0087f2fSSylver Bruneau 			/* send preamble to clear the receive buffer */
243a0087f2fSSylver Bruneau 			memset(&send_buf, 0xff, sizeof(send_buf));
244a0087f2fSSylver Bruneau 			kurobox_pro_miconwrite(send_buf, sizeof(send_buf));
245a0087f2fSSylver Bruneau 
246a0087f2fSSylver Bruneau 			/* make dummy reads */
247a0087f2fSSylver Bruneau 			mdelay(100);
248a0087f2fSSylver Bruneau 			kurobox_pro_miconread(recv_buf, sizeof(recv_buf));
249a0087f2fSSylver Bruneau 		} else {
250a0087f2fSSylver Bruneau 			/* Generate expected ack */
251a0087f2fSSylver Bruneau 			correct_ack[0] = 0x01;
252a0087f2fSSylver Bruneau 			correct_ack[1] = data[1];
253a0087f2fSSylver Bruneau 			correct_ack[2] = 0x00;
254a0087f2fSSylver Bruneau 
255a0087f2fSSylver Bruneau 			/* checksum Check */
256a0087f2fSSylver Bruneau 			if ((recv_buf[0] + recv_buf[1] + recv_buf[2] +
257a0087f2fSSylver Bruneau 			     recv_buf[3]) & 0xFF) {
258a0087f2fSSylver Bruneau 				printk(KERN_ERR ">%s: Checksum Error : "
259a0087f2fSSylver Bruneau 					"Received data[%02x, %02x, %02x, %02x]"
260a0087f2fSSylver Bruneau 					"\n", __func__, recv_buf[0],
261a0087f2fSSylver Bruneau 					recv_buf[1], recv_buf[2], recv_buf[3]);
262a0087f2fSSylver Bruneau 			} else {
263a0087f2fSSylver Bruneau 				/* Check Received Data */
264a0087f2fSSylver Bruneau 				if (correct_ack[0] == recv_buf[0] &&
265a0087f2fSSylver Bruneau 				    correct_ack[1] == recv_buf[1] &&
266a0087f2fSSylver Bruneau 				    correct_ack[2] == recv_buf[2]) {
267a0087f2fSSylver Bruneau 					/* Interval for next command */
268a0087f2fSSylver Bruneau 					mdelay(10);
269a0087f2fSSylver Bruneau 
270a0087f2fSSylver Bruneau 					/* Receive ACK */
271a0087f2fSSylver Bruneau 					return 0;
272a0087f2fSSylver Bruneau 				}
273a0087f2fSSylver Bruneau 			}
274a0087f2fSSylver Bruneau 			/* Received NAK or illegal Data */
275a0087f2fSSylver Bruneau 			printk(KERN_ERR ">%s: Error : NAK or Illegal Data "
276a0087f2fSSylver Bruneau 					"Received\n", __func__);
277a0087f2fSSylver Bruneau 		}
278a0087f2fSSylver Bruneau 	} while (retry--);
279a0087f2fSSylver Bruneau 
280a0087f2fSSylver Bruneau 	/* Interval for next command */
281a0087f2fSSylver Bruneau 	mdelay(10);
282a0087f2fSSylver Bruneau 
283a0087f2fSSylver Bruneau 	return -1;
284a0087f2fSSylver Bruneau }
285a0087f2fSSylver Bruneau 
kurobox_pro_power_off(void)286a0087f2fSSylver Bruneau static void kurobox_pro_power_off(void)
287a0087f2fSSylver Bruneau {
288a0087f2fSSylver Bruneau 	const unsigned char watchdogkill[]	= {0x01, 0x35, 0x00};
289a0087f2fSSylver Bruneau 	const unsigned char shutdownwait[]	= {0x00, 0x0c};
290a0087f2fSSylver Bruneau 	const unsigned char poweroff[]		= {0x00, 0x06};
291a0087f2fSSylver Bruneau 	/* 38400 baud divisor */
292ebe35affSLennert Buytenhek 	const unsigned divisor = ((orion5x_tclk + (8 * 38400)) / (16 * 38400));
293a0087f2fSSylver Bruneau 
294a0087f2fSSylver Bruneau 	pr_info("%s: triggering power-off...\n", __func__);
295a0087f2fSSylver Bruneau 
296a0087f2fSSylver Bruneau 	/* hijack uart1 and reset into sane state (38400,8n1,even parity) */
297a0087f2fSSylver Bruneau 	writel(0x83, UART1_REG(LCR));
298a0087f2fSSylver Bruneau 	writel(divisor & 0xff, UART1_REG(DLL));
299a0087f2fSSylver Bruneau 	writel((divisor >> 8) & 0xff, UART1_REG(DLM));
300a0087f2fSSylver Bruneau 	writel(0x1b, UART1_REG(LCR));
301a0087f2fSSylver Bruneau 	writel(0x00, UART1_REG(IER));
302a0087f2fSSylver Bruneau 	writel(0x07, UART1_REG(FCR));
303a0087f2fSSylver Bruneau 	writel(0x00, UART1_REG(MCR));
304a0087f2fSSylver Bruneau 
305a0087f2fSSylver Bruneau 	/* Send the commands to shutdown the Kurobox Pro */
306a0087f2fSSylver Bruneau 	kurobox_pro_miconsend(watchdogkill, sizeof(watchdogkill)) ;
307a0087f2fSSylver Bruneau 	kurobox_pro_miconsend(shutdownwait, sizeof(shutdownwait)) ;
308a0087f2fSSylver Bruneau 	kurobox_pro_miconsend(poweroff, sizeof(poweroff));
309a0087f2fSSylver Bruneau }
310a0087f2fSSylver Bruneau 
311a0087f2fSSylver Bruneau /*****************************************************************************
3129dd0b194SLennert Buytenhek  * General Setup
3139dd0b194SLennert Buytenhek  ****************************************************************************/
314554cdaefSAndrew Lunn static unsigned int kurobox_pro_mpp_modes[] __initdata = {
315554cdaefSAndrew Lunn 	MPP0_UNUSED,
316554cdaefSAndrew Lunn 	MPP1_UNUSED,
317554cdaefSAndrew Lunn 	MPP2_GPIO,		/* GPIO Micon */
318554cdaefSAndrew Lunn 	MPP3_GPIO,		/* GPIO Rtc */
319554cdaefSAndrew Lunn 	MPP4_UNUSED,
320554cdaefSAndrew Lunn 	MPP5_UNUSED,
321554cdaefSAndrew Lunn 	MPP6_NAND,		/* NAND Flash REn */
322554cdaefSAndrew Lunn 	MPP7_NAND,		/* NAND Flash WEn */
323554cdaefSAndrew Lunn 	MPP8_UNUSED,
324554cdaefSAndrew Lunn 	MPP9_UNUSED,
325554cdaefSAndrew Lunn 	MPP10_UNUSED,
326554cdaefSAndrew Lunn 	MPP11_UNUSED,
327554cdaefSAndrew Lunn 	MPP12_SATA_LED,		/* SATA 0 presence */
328554cdaefSAndrew Lunn 	MPP13_SATA_LED,		/* SATA 1 presence */
329554cdaefSAndrew Lunn 	MPP14_SATA_LED,		/* SATA 0 active */
330554cdaefSAndrew Lunn 	MPP15_SATA_LED,		/* SATA 1 active */
331554cdaefSAndrew Lunn 	MPP16_UART,		/* UART1 RXD */
332554cdaefSAndrew Lunn 	MPP17_UART,		/* UART1 TXD */
333554cdaefSAndrew Lunn 	MPP18_UART,		/* UART1 CTSn */
334554cdaefSAndrew Lunn 	MPP19_UART,		/* UART1 RTSn */
335554cdaefSAndrew Lunn 	0,
33619cfd5c0SLennert Buytenhek };
3379dd0b194SLennert Buytenhek 
kurobox_pro_init(void)3389dd0b194SLennert Buytenhek static void __init kurobox_pro_init(void)
3399dd0b194SLennert Buytenhek {
3409dd0b194SLennert Buytenhek 	/*
3419dd0b194SLennert Buytenhek 	 * Setup basic Orion functions. Need to be called early.
3429dd0b194SLennert Buytenhek 	 */
3439dd0b194SLennert Buytenhek 	orion5x_init();
3449dd0b194SLennert Buytenhek 
34519cfd5c0SLennert Buytenhek 	orion5x_mpp_conf(kurobox_pro_mpp_modes);
3469dd0b194SLennert Buytenhek 
347044f6c7cSLennert Buytenhek 	/*
348044f6c7cSLennert Buytenhek 	 * Configure peripherals.
349044f6c7cSLennert Buytenhek 	 */
350044f6c7cSLennert Buytenhek 	orion5x_ehci0_init();
351044f6c7cSLennert Buytenhek 	orion5x_ehci1_init();
3529dd0b194SLennert Buytenhek 	orion5x_eth_init(&kurobox_pro_eth_data);
353044f6c7cSLennert Buytenhek 	orion5x_i2c_init();
3549dd0b194SLennert Buytenhek 	orion5x_sata_init(&kurobox_pro_sata_data);
355044f6c7cSLennert Buytenhek 	orion5x_uart0_init();
3569e956850SSylver Bruneau 	orion5x_uart1_init();
3571d5a1a6eSSaeed Bishara 	orion5x_xor_init();
358044f6c7cSLennert Buytenhek 
3594ca2c040SThomas Petazzoni 	mvebu_mbus_add_window_by_id(ORION_MBUS_DEVBUS_BOOT_TARGET,
3604ca2c040SThomas Petazzoni 				    ORION_MBUS_DEVBUS_BOOT_ATTR,
3614ca2c040SThomas Petazzoni 				    KUROBOX_PRO_NOR_BOOT_BASE,
362044f6c7cSLennert Buytenhek 				    KUROBOX_PRO_NOR_BOOT_SIZE);
363044f6c7cSLennert Buytenhek 	platform_device_register(&kurobox_pro_nor_flash);
364044f6c7cSLennert Buytenhek 
365044f6c7cSLennert Buytenhek 	if (machine_is_kurobox_pro()) {
3664ca2c040SThomas Petazzoni 		mvebu_mbus_add_window_by_id(ORION_MBUS_DEVBUS_TARGET(0),
3674ca2c040SThomas Petazzoni 					    ORION_MBUS_DEVBUS_ATTR(0),
3684ca2c040SThomas Petazzoni 					    KUROBOX_PRO_NAND_BASE,
369044f6c7cSLennert Buytenhek 					    KUROBOX_PRO_NAND_SIZE);
370044f6c7cSLennert Buytenhek 		platform_device_register(&kurobox_pro_nand_flash);
371044f6c7cSLennert Buytenhek 	}
372044f6c7cSLennert Buytenhek 
373044f6c7cSLennert Buytenhek 	i2c_register_board_info(0, &kurobox_pro_i2c_rtc, 1);
374a0087f2fSSylver Bruneau 
375a0087f2fSSylver Bruneau 	/* register Kurobox Pro specific power-off method */
376a0087f2fSSylver Bruneau 	pm_power_off = kurobox_pro_power_off;
3779dd0b194SLennert Buytenhek }
3789dd0b194SLennert Buytenhek 
37987549251SByron Bradley #ifdef CONFIG_MACH_KUROBOX_PRO
3809dd0b194SLennert Buytenhek MACHINE_START(KUROBOX_PRO, "Buffalo/Revogear Kurobox Pro")
3819dd0b194SLennert Buytenhek 	/* Maintainer: Ronen Shitrit <rshitrit@marvell.com> */
38265aa1b1eSNicolas Pitre 	.atag_offset	= 0x100,
3835cdbe5d2SArnd Bergmann 	.nr_irqs	= ORION5X_NR_IRQS,
3849dd0b194SLennert Buytenhek 	.init_machine	= kurobox_pro_init,
3859dd0b194SLennert Buytenhek 	.map_io		= orion5x_map_io,
3864ee1f6b5SLennert Buytenhek 	.init_early	= orion5x_init_early,
3879dd0b194SLennert Buytenhek 	.init_irq	= orion5x_init_irq,
3886bb27d73SStephen Warren 	.init_time	= orion5x_timer_init,
3899dd0b194SLennert Buytenhek 	.fixup		= tag_fixup_mem32,
390764cbcc2SRussell King 	.restart	= orion5x_restart,
3919dd0b194SLennert Buytenhek MACHINE_END
39287549251SByron Bradley #endif
39387549251SByron Bradley 
39487549251SByron Bradley #ifdef CONFIG_MACH_LINKSTATION_PRO
39587549251SByron Bradley MACHINE_START(LINKSTATION_PRO, "Buffalo Linkstation Pro/Live")
39687549251SByron Bradley 	/* Maintainer: Byron Bradley <byron.bbradley@gmail.com> */
39765aa1b1eSNicolas Pitre 	.atag_offset	= 0x100,
3985cdbe5d2SArnd Bergmann 	.nr_irqs	= ORION5X_NR_IRQS,
39987549251SByron Bradley 	.init_machine	= kurobox_pro_init,
40087549251SByron Bradley 	.map_io		= orion5x_map_io,
4014ee1f6b5SLennert Buytenhek 	.init_early	= orion5x_init_early,
40287549251SByron Bradley 	.init_irq	= orion5x_init_irq,
4036bb27d73SStephen Warren 	.init_time	= orion5x_timer_init,
40487549251SByron Bradley 	.fixup		= tag_fixup_mem32,
405764cbcc2SRussell King 	.restart	= orion5x_restart,
40687549251SByron Bradley MACHINE_END
40787549251SByron Bradley #endif
408