Commit 48571ff0 authored by Sughosh Ganu's avatar Sughosh Ganu Committed by Sandeep Paulraj
Browse files

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: default avatarSughosh Ganu <urwithsughosh@gmail.com>
Signed-off-by: default avatarBen Gardiner <bengardiner@nanometrics.ca>
Signed-off-by: default avatarSandeep Paulraj <s-paulraj@ti.com>
parent 45b8679c
......@@ -853,6 +853,11 @@ Alex Z
lart SA1100
dnp1110 SA1110
Syed Mohammed Khasim <sm.khasim@gmail.com>
Sughosh Ganu <urwithsughosh@gmail.com>
hawkboard ARM926EJS (OMAP-L138)
-------------------------------------------------------------------------
Unknown / orphaned boards:
......
......@@ -19,6 +19,9 @@
#ifndef __COMMON_H
#define __COMMON_H
#define HAWKBOARD_KICK0_UNLOCK 0x83e70b13
#define HAWKBOARD_KICK1_UNLOCK 0x95a4f1e0
struct lpsc_resource {
const int lpsc_no;
};
......
......@@ -384,7 +384,10 @@ int clk_get(enum davinci_clk_ids id);
/* Boot config */
struct davinci_syscfg_regs {
dv_reg revid;
dv_reg rsvd[71];
dv_reg rsvd[13];
dv_reg kick0;
dv_reg kick1;
dv_reg rsvd1[56];
dv_reg pinmux[20];
dv_reg suspsrc;
dv_reg chipsig;
......
......@@ -29,7 +29,7 @@ endif
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))
......
/*
* 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;
}
......@@ -95,78 +95,3 @@ void davinci_sync_env_enetaddr(uint8_t *rom_enetaddr)
}
#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;
}
......@@ -30,6 +30,7 @@ LIB = $(obj)lib$(BOARD).o
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)
......
/*
* 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;
}
/*
* 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 (;;)
;
}
......@@ -76,6 +76,9 @@ pm9261 arm arm926ejs - ronetix
pm9263 arm arm926ejs - ronetix at91
da830evm arm arm926ejs da8xxevm davinci davinci
da850evm arm arm926ejs da8xxevm davinci davinci
hawkboard arm arm926ejs da8xxevm davinci davinci
hawkboard_nand arm arm926ejs da8xxevm davinci davinci hawkboard:NAND_U_BOOT
hawkboard_uart arm arm926ejs da8xxevm davinci davinci hawkboard:UART_U_BOOT
davinci_dm355evm arm arm926ejs dm355evm davinci davinci
davinci_dm355leopard arm arm926ejs dm355leopard davinci davinci
davinci_dm365evm arm arm926ejs dm365evm davinci davinci
......
Summary
=======
The README is for the boot procedure used for TI's OMAP-L138 based
hawkboard. The hawkboard comes with a 128MiB Nand flash and a 128MiB
DDR SDRAM along with a host of other controllers.
The hawkboard is booted in three stages. The initial bootloader which
executes upon reset is the Rom Boot Loader(RBL) which sits in the
internal ROM of the omap. The RBL initialises the memory and the nand
controller, and copies the image stored at a predefined location(block
1) of the nand flash. The image loaded by the RBL to the memory is the
AIS signed nand_spl image. This, in turns copies the u-boot binary
from the nand flash to the memory and jumps to the u-boot entry point.
AIS is an image format defined by TI for the images that are to be
loaded to memory by the RBL. The image is divided into a series of
sections and the image's entry point is specified. Each section comes
with meta data like the target address the section is to be copied to
and the size of the section, which is used by the RBL to load the
image. At the end of the image the RBL jumps to the image entry
point.
The secondary stage bootloader(nand_spl) which is loaded by the RBL
then loads the u-boot from a predefined location in the nand to the
memory and jumps to the u-boot entry point.
The reason a secondary stage bootloader is used is because the ECC
layout expected by the RBL is not the same as that used by
u-boot/linux. This also implies that for flashing the nand_spl image,
we need to use the u-boot which uses the ECC layout expected by the
RBL[1]. Booting u-boot over UART(UART boot) is explained here[2].
Compilation
===========
Three images might be needed
* nand_spl - This is the secondary bootloader which boots the u-boot
binary.
hawkboard_nand_config
The nand_spl ELF gets generated under nand_spl/u-boot-spl. This
needs to be processed with the AISGen tool for generating the AIS
signed image to be flashed. Steps for generating the AIS image are
explained here[3].
* u-boot binary - This is the image flashed to the nand and copied to
the memory by the nand_spl.
hawkboard_config
* u-boot for uart boot - This is same as the u-boot binary generated
above, with the sole difference of the CONFIG_SYS_TEXT_BASE being
0xc1080000, as expected by the RBL.
hawkboard_uart_config
Flashing the images to Nand
===========================
The nand_spl AIS image needs to be flashed to the block 1 of the
Nand flash, as that is the location the RBL expects the image[4]. For
flashing the nand_spl, boot over the u-boot specified in [1], and
flash the image
=> tftpboot 0xc0700000 <nand_spl_ais.bin>
=> nand erase 0x20000 0x20000
=> nand write.e 0xc0700000 0x20000 <nand_spl_size>
The u-boot binary is flashed at location 0xe0000(block 6) of the nand
flash. The nand_spl loader expects the u-boot at this location. For
flashing the u-boot binary
=> tftpboot 0xc0700000 u-boot.bin
=> nand erase 0xe0000 0x40000
=> nand write.e 0xc0700000 0xe0000 <u-boot-size>
Links
=====
[1]
http://code.google.com/p/hawkboard/downloads/detail?name=u-boot_uart_ais_v1.bin
[2]
http://elinux.org/Hawkboard#Booting_u-boot_over_UART
[3]
http://elinux.org/Hawkboard#Signing_u-boot_for_UART_boot
[4]
http://processors.wiki.ti.com/index.php/RBL_UBL_and_host_program#RBL_booting_from_NAND_and_ECC.2FBad_blocks
/*
* Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com/
*
* Based on davinci_dvevm.h. Original Copyrights follow:
*
* Copyright (C) 2007 Sergey Kubushyn <ksi@koi8.net>
*
* 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.
*/
#ifndef __CONFIG_H
#define __CONFIG_H
/*
* Board
*/
#define CONFIG_SYS_USE_NAND 1
/*
* SoC Configuration
*/
#define CONFIG_MACH_DAVINCI_HAWK
#define CONFIG_ARM926EJS /* arm926ejs CPU core */
#define CONFIG_SOC_DA8XX /* TI DA8xx SoC */
#define CONFIG_SYS_CLK_FREQ clk_get(DAVINCI_ARM_CLKID)
#define CONFIG_SYS_OSCIN_FREQ 24000000
#define CONFIG_SYS_TIMERBASE DAVINCI_TIMER0_BASE
#define CONFIG_SYS_HZ_CLOCK clk_get(DAVINCI_AUXCLK_CLKID)
#define CONFIG_SYS_HZ 1000
#define CONFIG_SKIP_LOWLEVEL_INIT
#define CONFIG_BOARD_EARLY_INIT_F
#if defined(CONFIG_NAND_U_BOOT) || defined(CONFIG_UART_U_BOOT)
#define CONFIG_SYS_TEXT_BASE 0xc1080000
#else