Add board support for hawkboard

The patch adds basic board support for TI's OMAP-L138 based
Hawkboard. This board is pretty similar to the da850 EVM. Support for
nand and network access is added in this version.

The following bootup procedure is used.

At reset, the Rom Boot Loader(RBL), initialises the ddr and the nand
controllers and copies the second stage bootloader(nand_spl) to
RAM. The secondary bootloader then copies u-boot from a predefined
location in the nand flash to the RAM, and passes control to the
u-boot image.

Three config options are supported
* hawkboard_config - Used to create the u-boot.bin. Tftp the
 u-boot.bin image to the RAM from u-boot, and flash to the nand flash
 at address 0xe0000.

* hawkboard_nand_config - Used to generate the secondary
 bootloader(nand_spl) image. This creates an elf file u-boot-spl
 under nand_spl/. Create an AIS signed image using this file, and
 flash it to the nand flash at address 0x20000. The ais file should
 fit in one block.

* hawkboard_uart_config - This is same as the first image, but with
 the TEXT_BASE as expected by the RBL(0xc1080000). Create the AIS

Signed-off-by: Sughosh Ganu <urwithsughosh@gmail.com>
Signed-off-by: Ben Gardiner <bengardiner@nanometrics.ca>
Signed-off-by: Sandeep Paulraj <s-paulraj@ti.com>
diff --git a/board/davinci/common/Makefile b/board/davinci/common/Makefile
index 5ddb564..a1d3de2 100644
--- a/board/davinci/common/Makefile
+++ b/board/davinci/common/Makefile
@@ -29,7 +29,7 @@
 
 LIB	= $(obj)lib$(VENDOR).o
 
-COBJS	:= misc.o
+COBJS	:= misc.o davinci_pinmux.o
 
 SRCS	:= $(SOBJS:.o=.S) $(COBJS:.o=.c)
 OBJS	:= $(addprefix $(obj),$(COBJS))
diff --git a/board/davinci/common/davinci_pinmux.c b/board/davinci/common/davinci_pinmux.c
new file mode 100644
index 0000000..ce58f71
--- /dev/null
+++ b/board/davinci/common/davinci_pinmux.c
@@ -0,0 +1,105 @@
+/*
+ * DaVinci pinmux functions.
+ *
+ * Copyright (C) 2009 Nick Thompson, GE Fanuc Ltd, <nick.thompson@gefanuc.com>
+ * Copyright (C) 2007 Sergey Kubushyn <ksi@koi8.net>
+ * Copyright (C) 2008 Lyrtech <www.lyrtech.com>
+ * Copyright (C) 2004 Texas Instruments.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <common.h>
+#include <asm/arch/hardware.h>
+#include <asm/io.h>
+#include <asm/arch/davinci_misc.h>
+
+/*
+ * Change the setting of a pin multiplexer field.
+ *
+ * Takes an array of pinmux settings similar to:
+ *
+ * struct pinmux_config uart_pins[] = {
+ *	{ &davinci_syscfg_regs->pinmux[8], 2, 7 },
+ *	{ &davinci_syscfg_regs->pinmux[9], 2, 0 }
+ * };
+ *
+ * Stepping through the array, each pinmux[n] register has the given value
+ * set in the pin mux field specified.
+ *
+ * The number of pins in the array must be passed (ARRAY_SIZE can provide
+ * this value conveniently).
+ *
+ * Returns 0 if all field numbers and values are in the correct range,
+ * else returns -1.
+ */
+int davinci_configure_pin_mux(const struct pinmux_config *pins,
+			      const int n_pins)
+{
+	int i;
+
+	/* check for invalid pinmux values */
+	for (i = 0; i < n_pins; i++) {
+		if (pins[i].field >= PIN_MUX_NUM_FIELDS ||
+		    (pins[i].value & ~PIN_MUX_FIELD_MASK) != 0)
+			return -1;
+	}
+
+	/* configure the pinmuxes */
+	for (i = 0; i < n_pins; i++) {
+		const int offset = pins[i].field * PIN_MUX_FIELD_SIZE;
+		const unsigned int value = pins[i].value << offset;
+		const unsigned int mask = PIN_MUX_FIELD_MASK << offset;
+		const dv_reg *mux = pins[i].mux;
+
+		writel(value | (readl(mux) & (~mask)), mux);
+	}
+
+	return 0;
+}
+
+/*
+ * Configure multiple pinmux resources.
+ *
+ * Takes an pinmux_resource array of pinmux_config and pin counts:
+ *
+ * const struct pinmux_resource pinmuxes[] = {
+ *	PINMUX_ITEM(uart_pins),
+ *	PINMUX_ITEM(i2c_pins),
+ * };
+ *
+ * The number of items in the array must be passed (ARRAY_SIZE can provide
+ * this value conveniently).
+ *
+ * Each item entry is configured in the defined order. If configuration
+ * of any item fails, -1 is returned and none of the following items are
+ * configured. On success, 0 is returned.
+ */
+int davinci_configure_pin_mux_items(const struct pinmux_resource *item,
+				    const int n_items)
+{
+	int i;
+
+	for (i = 0; i < n_items; i++) {
+		if (davinci_configure_pin_mux(item[i].pins,
+					      item[i].n_pins) != 0)
+			return -1;
+	}
+
+	return 0;
+}
diff --git a/board/davinci/common/misc.c b/board/davinci/common/misc.c
index a30047b..f25ad7e 100644
--- a/board/davinci/common/misc.c
+++ b/board/davinci/common/misc.c
@@ -95,78 +95,3 @@
 }
 
 #endif	/* DAVINCI_EMAC */
-
-/*
- * Change the setting of a pin multiplexer field.
- *
- * Takes an array of pinmux settings similar to:
- *
- * struct pinmux_config uart_pins[] = {
- *	{ &davinci_syscfg_regs->pinmux[8], 2, 7 },
- *	{ &davinci_syscfg_regs->pinmux[9], 2, 0 }
- * };
- *
- * Stepping through the array, each pinmux[n] register has the given value
- * set in the pin mux field specified.
- *
- * The number of pins in the array must be passed (ARRAY_SIZE can provide
- * this value conveniently).
- *
- * Returns 0 if all field numbers and values are in the correct range,
- * else returns -1.
- */
-int davinci_configure_pin_mux(const struct pinmux_config *pins,
-			      const int n_pins)
-{
-	int i;
-
-	/* check for invalid pinmux values */
-	for (i = 0; i < n_pins; i++) {
-		if (pins[i].field >= PIN_MUX_NUM_FIELDS ||
-		    (pins[i].value & ~PIN_MUX_FIELD_MASK) != 0)
-			return -1;
-	}
-
-	/* configure the pinmuxes */
-	for (i = 0; i < n_pins; i++) {
-		const int offset = pins[i].field * PIN_MUX_FIELD_SIZE;
-		const unsigned int value = pins[i].value << offset;
-		const unsigned int mask = PIN_MUX_FIELD_MASK << offset;
-		const dv_reg *mux = pins[i].mux;
-
-		writel(value | (readl(mux) & (~mask)), mux);
-	}
-
-	return 0;
-}
-
-/*
- * Configure multiple pinmux resources.
- *
- * Takes an pinmux_resource array of pinmux_config and pin counts:
- *
- * const struct pinmux_resource pinmuxes[] = {
- *	PINMUX_ITEM(uart_pins),
- *	PINMUX_ITEM(i2c_pins),
- * };
- *
- * The number of items in the array must be passed (ARRAY_SIZE can provide
- * this value conveniently).
- *
- * Each item entry is configured in the defined order. If configuration
- * of any item fails, -1 is returned and none of the following items are
- * configured. On success, 0 is returned.
- */
-int davinci_configure_pin_mux_items(const struct pinmux_resource *item,
-				    const int n_items)
-{
-	int i;
-
-	for (i = 0; i < n_items; i++) {
-		if (davinci_configure_pin_mux(item[i].pins,
-					      item[i].n_pins) != 0)
-			return -1;
-	}
-
-	return 0;
-}
diff --git a/board/davinci/da8xxevm/Makefile b/board/davinci/da8xxevm/Makefile
index 88fee50..1816368 100644
--- a/board/davinci/da8xxevm/Makefile
+++ b/board/davinci/da8xxevm/Makefile
@@ -30,6 +30,7 @@
 COBJS-y	+= common.o
 COBJS-$(CONFIG_MACH_DAVINCI_DA830_EVM)	+= da830evm.o
 COBJS-$(CONFIG_MACH_DAVINCI_DA850_EVM)	+= da850evm.o
+COBJS-$(CONFIG_MACH_DAVINCI_HAWK)	+= hawkboard.o
 
 COBJS   := $(COBJS-y)
 
diff --git a/board/davinci/da8xxevm/hawkboard.c b/board/davinci/da8xxevm/hawkboard.c
new file mode 100644
index 0000000..b672c9d
--- /dev/null
+++ b/board/davinci/da8xxevm/hawkboard.c
@@ -0,0 +1,69 @@
+/*
+ * Modified for Hawkboard - Syed Mohammed Khasim <khasim@beagleboard.org>
+ *
+ * Copyright (C) 2008 Sekhar Nori, Texas Instruments, Inc.  <nsekhar@ti.com>
+ * Copyright (C) 2007 Sergey Kubushyn <ksi@koi8.net>
+ * Copyright (C) 2004 Texas Instruments.
+ *
+ * ----------------------------------------------------------------------------
+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ * ----------------------------------------------------------------------------
+ */
+
+#include <common.h>
+#include <asm/errno.h>
+#include <asm/arch/hardware.h>
+#include <asm/io.h>
+#include <asm/arch/davinci_misc.h>
+#include <ns16550.h>
+#include <asm/arch/da8xx_common.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+int board_init(void)
+{
+	/* arch number of the board */
+	gd->bd->bi_arch_number = MACH_TYPE_OMAPL138_HAWKBOARD;
+
+	/* address of boot parameters */
+	gd->bd->bi_boot_params = LINUX_BOOT_PARAM_ADDR;
+
+	return 0;
+}
+
+int board_early_init_f(void)
+{
+	/*
+	 * Kick Registers need to be set to allow access to Pin Mux registers
+	 */
+	writel(HAWKBOARD_KICK0_UNLOCK, &davinci_syscfg_regs->kick0);
+	writel(HAWKBOARD_KICK1_UNLOCK, &davinci_syscfg_regs->kick1);
+
+	/* set cfgchip3 to select mii */
+	writel(readl(&davinci_syscfg_regs->cfgchip3) &
+	       ~(1 << 8), &davinci_syscfg_regs->cfgchip3);
+
+	return 0;
+}
+
+int misc_init_r(void)
+{
+	char buf[32];
+
+	printf("ARM Clock : %s MHz\n",
+	       strmhz(buf, clk_get(DAVINCI_ARM_CLKID)));
+
+	return 0;
+}
diff --git a/board/davinci/da8xxevm/hawkboard_nand_spl.c b/board/davinci/da8xxevm/hawkboard_nand_spl.c
new file mode 100644
index 0000000..74eec13
--- /dev/null
+++ b/board/davinci/da8xxevm/hawkboard_nand_spl.c
@@ -0,0 +1,158 @@
+/*
+ * Modified for Hawkboard - Syed Mohammed Khasim <khasim@beagleboard.org>
+ *
+ * Copyright (C) 2008 Sekhar Nori, Texas Instruments, Inc.  <nsekhar@ti.com>
+ * Copyright (C) 2007 Sergey Kubushyn <ksi@koi8.net>
+ * Copyright (C) 2004 Texas Instruments.
+ *
+ * ----------------------------------------------------------------------------
+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ * ----------------------------------------------------------------------------
+ */
+
+#include <common.h>
+#include <asm/errno.h>
+#include <asm/arch/hardware.h>
+#include <asm/io.h>
+#include <asm/arch/davinci_misc.h>
+#include <ns16550.h>
+#include <asm/arch/da8xx_common.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#define pinmux(x)			(&davinci_syscfg_regs->pinmux[x])
+
+static const struct pinmux_config mii_pins[] = {
+	{ pinmux(2), 8, 1 },
+	{ pinmux(2), 8, 2 },
+	{ pinmux(2), 8, 3 },
+	{ pinmux(2), 8, 4 },
+	{ pinmux(2), 8, 5 },
+	{ pinmux(2), 8, 6 },
+	{ pinmux(2), 8, 7 }
+};
+
+static const struct pinmux_config mdio_pins[] = {
+	{ pinmux(4), 8, 0 },
+	{ pinmux(4), 8, 1 }
+};
+
+static const struct pinmux_config nand_pins[] = {
+	{ pinmux(7), 1, 1 },
+	{ pinmux(7), 1, 2 },
+	{ pinmux(7), 1, 4 },
+	{ pinmux(7), 1, 5 },
+	{ pinmux(9), 1, 0 },
+	{ pinmux(9), 1, 1 },
+	{ pinmux(9), 1, 2 },
+	{ pinmux(9), 1, 3 },
+	{ pinmux(9), 1, 4 },
+	{ pinmux(9), 1, 5 },
+	{ pinmux(9), 1, 6 },
+	{ pinmux(9), 1, 7 },
+	{ pinmux(12), 1, 5 },
+	{ pinmux(12), 1, 6 }
+};
+
+static const struct pinmux_config uart2_pins[] = {
+	{ pinmux(0), 4, 6 },
+	{ pinmux(0), 4, 7 },
+	{ pinmux(4), 2, 4 },
+	{ pinmux(4), 2, 5 }
+};
+
+static const struct pinmux_config i2c_pins[] = {
+	{ pinmux(4), 2, 4 },
+	{ pinmux(4), 2, 5 }
+};
+
+static const struct pinmux_resource pinmuxes[] = {
+	PINMUX_ITEM(mii_pins),
+	PINMUX_ITEM(mdio_pins),
+	PINMUX_ITEM(i2c_pins),
+	PINMUX_ITEM(nand_pins),
+	PINMUX_ITEM(uart2_pins),
+};
+
+static const struct lpsc_resource lpsc[] = {
+	{ DAVINCI_LPSC_AEMIF },	/* NAND, NOR */
+	{ DAVINCI_LPSC_SPI1 },	/* Serial Flash */
+	{ DAVINCI_LPSC_EMAC },	/* image download */
+	{ DAVINCI_LPSC_UART2 },	/* console */
+	{ DAVINCI_LPSC_GPIO },
+};
+
+void board_init_f(ulong bootflag)
+{
+	/*
+	 * Kick Registers need to be set to allow access to Pin Mux registers
+	 */
+	writel(HAWKBOARD_KICK0_UNLOCK, &davinci_syscfg_regs->kick0);
+	writel(HAWKBOARD_KICK1_UNLOCK, &davinci_syscfg_regs->kick1);
+
+	/* setup the SUSPSRC for ARM to control emulation suspend */
+	writel(readl(&davinci_syscfg_regs->suspsrc) &
+	       ~(DAVINCI_SYSCFG_SUSPSRC_EMAC | DAVINCI_SYSCFG_SUSPSRC_I2C |
+		 DAVINCI_SYSCFG_SUSPSRC_SPI1 | DAVINCI_SYSCFG_SUSPSRC_TIMER0 |
+		 DAVINCI_SYSCFG_SUSPSRC_UART2), &davinci_syscfg_regs->suspsrc);
+
+	/* Power on required peripherals
+	 * ARM does not have acess by default to PSC0 and PSC1
+	 * assuming here that the DSP bootloader has set the IOPU
+	 * such that PSC access is available to ARM
+	 */
+	da8xx_configure_lpsc_items(lpsc, ARRAY_SIZE(lpsc));
+
+	/* configure pinmux settings */
+	davinci_configure_pin_mux_items(pinmuxes,
+					ARRAY_SIZE(pinmuxes));
+
+	writel(readl(&davinci_uart2_ctrl_regs->pwremu_mgmt) |
+	       (DAVINCI_UART_PWREMU_MGMT_FREE) |
+	       (DAVINCI_UART_PWREMU_MGMT_URRST) |
+	       (DAVINCI_UART_PWREMU_MGMT_UTRST),
+	       &davinci_uart2_ctrl_regs->pwremu_mgmt);
+
+	NS16550_init((NS16550_t)(DAVINCI_UART2_BASE),
+			CONFIG_SYS_NS16550_CLK / 16 / CONFIG_BAUDRATE);
+
+	puts("Nand boot...\n");
+
+	nand_boot();
+}
+
+void puts(const char *str)
+{
+	while (*str)
+		putc(*str++);
+}
+
+void putc(char c)
+{
+	if (gd->flags & GD_FLG_SILENT)
+		return;
+
+	if (c == '\n')
+		NS16550_putc((NS16550_t)(DAVINCI_UART2_BASE), '\r');
+
+	NS16550_putc((NS16550_t)(DAVINCI_UART2_BASE), c);
+}
+
+void hang(void)
+{
+	puts("### ERROR ### Please RESET the board ###\n");
+	for (;;)
+		;
+}