[U-Boot] [patch V2] U-Boot Firetux board support

Jean-Christophe PLAGNIOL-VILLARD plagnioj at jcrosoft.com
Thu Nov 6 21:53:29 CET 2008


On 12:48 Wed 05 Nov     , Juergen Schoew wrote:
> Hi U-Boot mailling list,
> 
> This patchset adds a new ARM board with the NXP PNX8181 cpu to u-boot.
> The PNX8181 is an ARM926ej with an internal DSP (mostly used for Audio
> processing and VOIP codecs) and a baseband processor (used for DECT). The
> chip also features dual ethernet, digital to analog interface, spi, i2c and
> other SOC peripherals.
> 
> These boards have been build by NXP Semiconductors GmbH, Nuremberg, Germany
> and are now build by DSPG Technologies GmbH, Nuremberg, Germany.
> 
> 
> Signed-off-by: Jürgen Schöw <js at emlix.com>
> Signed-off-by: Sebastian Hess <sh at emlix.com>
> Signed-off-by: Matthias Mwenzel <nxp at mazzoo.de>
> Signed-off-by: Dirk Hörner <dirk.hoerner at dspg.com>
> Signed-off-by: Andreas Weißel <andreas.weissel at dspg.com>
> ---
> 
> Here is the next round of the patch. Thanks for the comments so far. I tried
> to change the code to meet your requirements. Following changes have been
> done:
> 
>  - use writex/readx for register accesses
>  - use pointer in readx/writex
>  - whitespace fixes (use tabs)
>  - add Maintainer field
>  - adjust comments to common style
>  - use conditional settings
>  - relocate.S bug fixes
>  - network reworks
> 
> I did not move the ethernet driver to drivers/net/ because a lot of hardware
> dependencies are in that driver to work. This IP-Core is not used very often
> by NXP processors (I don't have numbers) so it may not need to be moved. This
> driver does not not use the a struct to save the parameters as suggested
> from Jean-Christophe PLAGNIOL-VILLARD. Sorry but time was too short to fix it
> right now.
> 
> Regards
> 
> Jürgen Schöw
> -- 
> Dipl.-Ing. Jürgen Schöw, emlix GmbH, http://www.emlix.com, mailto:js at emlix.com
> Fon +49 551 30664-0, Fax -11, Bahnhofsallee 1b, 37081 Göttingen, Germany
> Geschäftsführung: Dr. Uwe Kracke, Dr. Cord Seele, Ust-IdNr.: DE 205 198 055
> Sitz der Gesellschaft: Göttingen, Amtsgericht Göttingen HR B 3160
> 
> emlix - your embedded linux partner
> 
> 
>  MAKEALL                       |    1 +
>  Makefile                      |    7 +
>  board/firetux/Makefile        |   59 +++
>  board/firetux/config.mk       |   44 ++
>  board/firetux/ethernet.c      |  954 +++++++++++++++++++++++++++++++++++++++++
>  board/firetux/ethernet.h      |  213 +++++++++
>  board/firetux/firetux.c       |  619 ++++++++++++++++++++++++++
>  board/firetux/firetux.h       |  109 +++++
>  board/firetux/lowlevel_init.S |  404 +++++++++++++++++
>  board/firetux/memsetup.S      |  381 ++++++++++++++++
>  board/firetux/nand.c          |   68 +++
>  board/firetux/relocate.S      |  252 +++++++++++
>  board/firetux/u-boot.lds      |   57 +++
>  drivers/i2c/Makefile          |    1 +
>  drivers/i2c/pnx8181_i2c.c     |  302 +++++++++++++
>  include/configs/firetux.h     |  460 ++++++++++++++++++++
>  net/bootp.c                   |   11 +
>  net/eth.c                     |    7 +
>  18 files changed, 3949 insertions(+), 0 deletions(-)

First some general comments

As you anwser it's a NXP board so please create a vendor directory
please use tab instead of space for code alignement and indentation
please a blank line when you write block of code and comment to make it more
readable
please and whitespace before and after "<<" & co

in the code their is a lot of hard code value please use Macro or specify why
you can not do it

please only one blank line consecutive
> 
> 
> 
> diff --git a/MAKEALL b/MAKEALL
> index 9ccb9ac..0ba8e4d 100755
> --- a/MAKEALL
> +++ b/MAKEALL
> @@ -480,6 +480,7 @@ LIST_ARM9="			\
>  	cp926ejs		\
>  	cp946es			\
>  	cp966			\
> +	firetux			\
>  	lpd7a400		\
>  	mx1ads			\
>  	mx1fs2			\
> diff --git a/Makefile b/Makefile
> index 9a132f7..f747759 100644
> --- a/Makefile
> +++ b/Makefile
> @@ -2683,6 +2683,13 @@ voiceblue_config:	unconfig
>  	@$(MKCONFIG) $(@:_config=) arm arm925t voiceblue
>  
>  #########################################################################
> +## NXP PNX8181 "firetux"
> +#########################################################################
> +
> +firetux_config:unconfig
> +	@$(MKCONFIG) $(@:_config=) arm arm926ejs firetux
> +
> +#########################################################################
>  ## S3C44B0 Systems
>  #########################################################################
>  
> diff --git a/board/firetux/Makefile b/board/firetux/Makefile
> new file mode 100644
> index 0000000..bf1afec
> --- /dev/null
> +++ b/board/firetux/Makefile
> @@ -0,0 +1,59 @@
> +# firetux makefile
> +#
> +# (C) Copyright 2007-2008, emlix GmbH, Germany
> +# Juergen Schoew <js at emlix.com>
> +#
> +# (C) Copyright 2008, DSPG Technologies GmbH, Germany
> +# (C) Copyright 2007, NXP Semiconductors Germany GmbH
> +# Matthias Wenzel, <nxp at mazzoo.de>
> +#
> +# 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., 59 Temple Place, Suite 330, Boston,
> +# MA 02111-1307 USA
> +#
> +
> +include $(TOPDIR)/config.mk
> +
> +LIB	= $(obj)lib$(BOARD).a
> +
> +COBJS-y	+= firetux.o ethernet.o
as ask by Ben and I move this to drivers/net
> +COBJS-$(CONFIG_CMD_NAND)	+= nand.o
> +SOBJS-y	+= lowlevel_init.o memsetup.o relocate.o
> +
> +SRCS	:= $(SOBJS-y:.o=.S) $(COBJS-y:.o=.c)
> +OBJS	:= $(addprefix $(obj),$(COBJS-y))
> +SOBJS	:= $(addprefix $(obj),$(SOBJS-y))
> +
> +all:	$(LIB)
> +
> +$(LIB):	$(obj).depend $(OBJS) $(SOBJS)
> +	$(AR) $(ARFLAGS) $@ $(OBJS) $(SOBJS)
> +
> +clean:
> +	rm -f $(SOBJS) $(OBJS)
> +
> +distclean:	clean
> +	rm -f $(LIB) core *.bak .depend
> +
> +#########################################################################
> +
> +# defines $(obj).depend target
> +include $(SRCTREE)/rules.mk
> +
> +sinclude $(obj).depend
> +
> +#########################################################################
> diff --git a/board/firetux/config.mk b/board/firetux/config.mk
> new file mode 100644
> index 0000000..4c8ab29
> --- /dev/null
> +++ b/board/firetux/config.mk
> @@ -0,0 +1,44 @@
> +# firetux compiler config
> +#
> +# (C) Copyright 2007-2008, emlix GmbH, Germany
> +# Juergen Schoew <js at emlix.com>
> +#
> +# (C) Copyright 2008, DSPG Technologies GmbH, Germany
> +# (C) Copyright 2007, NXP Semiconductors Germany GmbH
> +# Matthias Wenzel, <nxp at mazzoo.de>
> +#
> +# 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., 59 Temple Place, Suite 330, Boston,
> +# MA 02111-1307 USA
> +#
> +
> +
> +ifndef CONFIG_SYS_PSRAM
> +# SDRAM
> +TEXT_BASE = 0x20780000
> +else
> +# mobile pSRAM
> +TEXT_BASE = 0x90700000
> +endif
> +
> +PLATFORM_CPPFLAGS += -fPIC -fPIE -fno-jump-tables # -msingle-pic-base
> +
> +ifneq ($(OBJTREE),$(SRCTREE))
> +# We are building u-boot in a separate directory, use generated
> +# .lds script from OBJTREE directory.
> +LDSCRIPT := $(OBJTREE)/board/$(BOARDDIR)/u-boot.lds
> +endif
> diff --git a/board/firetux/ethernet.c b/board/firetux/ethernet.c
> new file mode 100644
> index 0000000..a4c1bc2
> --- /dev/null
> +++ b/board/firetux/ethernet.c
> @@ -0,0 +1,954 @@
> +/*
> + * pnx8181 ethernet driver (ip3912)
> + *
> + * (C) Copyright 2007-2008, emlix GmbH, Germany
> + * Juergen Schoew <js at emlix.com>
> + *
> + * (C) Copyright 2008, DSPG Technologies GmbH, Germany
> + * (C) Copyright 2007, NXP Semiconductors Germany GmbH
> + * Matthias Wenzel, <nxp at mazzoo.de>
> + *
> + * 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., 59 Temple Place, Suite 330, Boston,
> + * MA 02111-1307 USA
> + */
> +
> +#include <common.h>
> +#include <net.h>
> +#include <malloc.h>
> +
> +#include <asm/io.h>
> +
> +#include "ethernet.h"
> +#include <miiphy.h>
> +
> +extern unsigned int boardrevision;
> +
> +int firetux_miiphy_initialize(bd_t *bis);
> +int mii_discover_phy(void);
> +int mii_negotiate_phy(void);
> +
> +#define ALIGN8	static __attribute__ ((aligned(8)))
> +#define ALIGN4	static __attribute__ ((aligned(4)))
IMHO this make more sense
#define align8 __attribute__ ((aligned(8))
> +
> +#define PNX8181_SCON_SYSPAD0	0xc2204034
> +#define PNX8181_SCON_SYSPAD4	0xc2204044
> +#define PNX8181_SCON_SYSMUX0	0xc220400c
> +#define PNX8181_GPIOA_PINS	0xc2104000
> +#define PNX8181_GPIOA_OR	0xc2104004
> +#define PNX8181_GPIOA_DR	0xc2104008
> +
> +/* globals */
> +/* ETN1 rx */
> +ALIGN8 rx_descriptor_t	etn1_rxdescriptor[CONFIG_SYS_ETN_RX_DESCRIPTOR_NUMBER];
> +ALIGN8 rx_status_t	etn1_rxstatus[CONFIG_SYS_ETN_RX_DESCRIPTOR_NUMBER];
> +
> +/* ETN1 tx */
> +ALIGN8 tx_descriptor_t	etn1_txdescriptor[CONFIG_SYS_ETN_TX_DESCRIPTOR_NUMBER];
> +ALIGN4 tx_status_t	etn1_txstatus[CONFIG_SYS_ETN_TX_DESCRIPTOR_NUMBER];
> +
> +/* ETN2 rx */
> +ALIGN8 rx_descriptor_t	etn2_rxdescriptor[CONFIG_SYS_ETN_RX_DESCRIPTOR_NUMBER];
> +ALIGN8 rx_status_t	etn2_rxstatus[CONFIG_SYS_ETN_RX_DESCRIPTOR_NUMBER];
> +
> +/* ETN2 tx */
> +ALIGN8 tx_descriptor_t	etn2_txdescriptor[CONFIG_SYS_ETN_TX_DESCRIPTOR_NUMBER];
> +ALIGN4 tx_status_t	etn2_txstatus[CONFIG_SYS_ETN_TX_DESCRIPTOR_NUMBER];
> +
> +/* in the code we use the following descriptors which are either */
> +/* set to the etn1 or the etn2 descriptors, depending on ethact  */
> +ALIGN8 rx_descriptor_t	*etn_rxdescriptor	= etn1_rxdescriptor;
> +ALIGN8 rx_status_t	*etn_rxstatus		= etn1_rxstatus;
> +ALIGN8 tx_descriptor_t	*etn_txdescriptor	= etn1_txdescriptor;
> +ALIGN8 tx_status_t	*etn_txstatus		= etn1_txstatus;
> +
> +
> +/* which interface to be currently work on           */
> +/* default can be set by environment variable ethact */
> +static int firetux_eth = 0;
> +unsigned short etn1_phy_addr, etn2_phy_addr;
> +
> +/* also the base address is switched for etn1 and etn2,          */
> +/* except for the MII registers etn1_m* which are only available */
> +/* on etn1 */
> +unsigned int etn_base = ETN1_BASE;
> +
> +/* we first try Vega Platform III-a settings */
> +unsigned short firetux_phy_addr = PHYADDR_TO_REG(0x01);
> +
> +
> +/* set all pointer to the right intferace */
> +static void firetux_set_ethact(int act, int hardwarerevision)
> +{
> +	switch (hardwarerevision) {
> +	/* EZ_MCP, Vega_pnx8181_basestation Platform III-a */
> +	case 1:
> +	case 2:
> +		etn1_phy_addr = PHYADDR_TO_REG(0x01);
> +		etn2_phy_addr = PHYADDR_TO_REG(0x02);
> +		break;
> +	/* Vega_pnx8181_basestation Platform III-b, III-c */
> +	case 3:
> +	case 4:
> +	default:
> +		etn1_phy_addr = PHYADDR_TO_REG(0x1E);
> +		etn2_phy_addr = PHYADDR_TO_REG(0x1D);
> +		break;
> +	}
> +	if (act) {
> +		etn_rxdescriptor = etn2_rxdescriptor;
> +		etn_rxstatus     = etn2_rxstatus;
                            ^^^^^
please use tab instead of space on all
> +		etn_txdescriptor = etn2_txdescriptor;
> +		etn_txstatus     = etn2_txstatus;
> +		etn_base         = ETN2_BASE;
> +		firetux_phy_addr = (unsigned short) etn2_phy_addr;
> +	} else {
> +		etn_rxdescriptor = etn1_rxdescriptor;
> +		etn_rxstatus     = etn1_rxstatus;
> +		etn_txdescriptor = etn1_txdescriptor;
> +		etn_txstatus     = etn1_txstatus;
> +		etn_base         = ETN1_BASE;
> +		firetux_phy_addr = (unsigned short) etn1_phy_addr;
> +	}
> +}
> +
> +/* phy routines */
> +
> +/* hardware reset with gpio */
> +static void firetux_reset_phy(int hardwareversion)
> +{
> +	switch (hardwareversion) {
> +	case 1:
> +	case 2:
> +	case 3:
> +		/* set GPIOa12 direction to output */
> +		writel((readl((void *)PNX8181_GPIOA_DR)
> +			& 0xffffefff) | 0x00001000, (void *)PNX8181_GPIOA_DR);
> +		/* ETH_RESET_N */
> +		writel(readl((void *)PNX8181_GPIOA_OR) & 0xffffefff,
> +						(void *)PNX8181_GPIOA_OR);
> +		udelay(120);		/* min 100us */
> +		writel(readl((void *)PNX8181_GPIOA_OR) | 0x00001000,
> +						(void *)PNX8181_GPIOA_OR);
> +		udelay(1);		/* max 800ns */
> +		break;
> +	case 4:
> +		writel((readl((void *)PNX8181_SCON_SYSPAD4) & 0xf7f5755f)
> +				| 0x080a8aa0, (void *)PNX8181_SCON_SYSPAD4);
> +		writel(readl((void *)PNX8181_SCON_SYSMUX0) & 0xffffff3f,
> +						(void *)PNX8181_SCON_SYSMUX0);
> +		/* set GPIOa3 direction to output */
> +		writel((readl((void *)PNX8181_GPIOA_DR) & 0xfffffff7)
> +				| 0x00000008, (void *)PNX8181_GPIOA_DR);
> +		/* ETH_RESET_N */
> +		writel(readl((void *)PNX8181_GPIOA_OR) & 0xfffffff7,
> +						(void *)PNX8181_GPIOA_OR);
> +		udelay(120);		/* min 100us */
> +		writel(readl((void *)PNX8181_GPIOA_OR) | 0x00000008,
> +						(void *)PNX8181_GPIOA_OR);
> +		udelay(1);		/* max 800ns */
> +		break;
> +	default:
> +		puts("Unknown Board, can't reset network phy\n");
> +		break;
> +	}
> +}
> +
> +static void firetux_phy_write(unsigned short reg, unsigned short data)
> +{
> +	int status = 1;
> +	int i = 0;
> +
> +	reg &= 0x001f; /* 5 bit PHY register address */
> +
> +	writel(firetux_phy_addr | reg, (void *)(ETN1_BASE + ETN_MADR));
> +	writel(data, (void *)(ETN1_BASE + ETN_MWTD));
> +
> +	/* poll for done */
> +	while (status && i < 1000000) {
> +		status = readl((void *)(ETN1_BASE + ETN_MIND)) & 0x7;
> +		i++;
> +	}
> +
> +	switch (addr) {
> +	case  1:
> +	case 30:
> +		firetux_eth = 0;
> +		break;
> +	case  2:
> +	case 29:
> +		firetux_eth = 1;
> +		break;
> +	default:
> +		return -1;
> +		break;
> +	}
> +	firetux_phy_addr = PHYADDR_TO_REG(addr);
> +	firetux_phy_write(reg, value);
> +	firetux_eth = saved_eth;
> +	firetux_phy_addr = saved_phy_addr;
> +
> +	return 0;
> +}
> +
> +int mii_negotiate_phy(void)
> +{
> +	char *mode;
> +	int speed = 0, duplex = 0, autonegotiate = 0, status, i;
> +
> +
> +	/* only set phy if exists */
> +	if (firetux_phy_read(PHY_PHYIDR1) == 0xffff)
> +		return -1;
> +
> +	/* get mode from environment */
> +	mode = getenv("phymode");
> +	if (mode  != NULL) {
please use if (mode)
> +		if (0 == strcmp(mode, "auto")) {
please invert the condition an so on
		if (strcmp(mode, "auto")) == 0) {
> +			autonegotiate = 1;
> +			speed = 100;
> +			duplex = 1;


> +		/* set advertise mode */
> +		firetux_phy_write(ETN_PHY_AUTONEG_ADV, (i|1));
> +		/* we set the phy parameter */
> +		firetux_phy_write(ETN_PHY_BASIC_CONTROL, ((duplex ? (1<<8) : 0)
> +				| (1 << 9) | ((speed == 100) ? (1 << 13) : 0)));
> +	}
> +
> +	/* wait for negotiation finished (max 3.5s) */
> +	i = 0;
> +	while (((firetux_phy_read(ETN_PHY_BASIC_STATUS) & (1 << 5)) == 0)
> +								&& (i < 350)) {
> +		udelay(10000);
> +		i++;
> +	}
> +	if (i == 350)
> +		puts("link negotiation timed out\n");
> +
> +
> +	/* check for link */
> +	if (firetux_phy_read(ETN_PHY_BASIC_STATUS) & (1 << 2)) {
> +		/* OK link present */
> +		status = firetux_phy_read(ETN_PHY_SPECIAL_MODE_CONTROL_STATUS);
> +		speed = (status & (1 << 2)) ? 10 : 100;
> +		duplex = (status & (1 << 4)) ? 1 : 0;
> +	}
> +
> +	/* program the mac */
> +	writel((readl((void *)(etn_base + ETN_SUPP)) & 0x000018fb) |
> +					((speed == 100) ? (1 << 8) : 0),
> +						(void *)(etn_base + ETN_SUPP));
> +	writel((readl((void *)(etn_base + ETN_MAC2)) & 0x000073fe) | duplex,
> +						(void *)(etn_base + ETN_MAC2));
> +	/*
> +	 * release rx-path, tx-path, host registers reset
> +	 * set Duplex, enable RMII, enable rx+tx
> +	 * no flow control, no frames<64b
> +	 */
> +	writel(0x00000283 | (duplex ? (1 << 10) : 0),
> +					(void *)(etn_base + ETN_COMMAND));
> +
> +	udelay(100000);		/* the mac still needs some time to settle */
> +	status = firetux_phy_read(ETN_PHY_SPECIAL_MODE_CONTROL_STATUS);
> +	printf(" ETN%d %s negotiation", (firetux_eth + 1),
> +				(status & (1 << 12)) ? "Auto" : "Manual");
> +	printf(" (10%s Mbit", (status & (1 << 3)) ? "0" : "");
> +	printf(" %sD", (status & (1 << 4)) ? "F" : "H");
> +	status = firetux_phy_read(ETN_PHY_BASIC_STATUS);
> +	printf(" (%s)\n", (status & 1<<2)
> +			? "Link detected" : "No Link detected, trying anyway");
> +
> +
> +void firetux_gpio_init_A(void);
> +void firetux_gpio_init_B(void);
> +void firetux_timer_init(void);
> +int firetux_keystatus(int key);
> +void firetux_set_led(int led, int brightness);
> +void firetux_check_bootkey(void);
> +#ifdef CONFIG_NANDFLASH
> +void firetux_nandflash_init(void);
> +#else
> +void firetux_norflash_init(void);
> +#endif
> +void firetux_irq_disable(void);
> +void firetux_ether_init(void);
> +void peripheral_power_enable(void);
> +
> +unsigned int boardrevision = 0;
> +
> +extern int firetux_eth_check_vega_phy(void);
> +
> +#ifdef CONFIG_SHOW_BOOT_PROGRESS
> +void show_boot_progress(int progress)
> +{
> +	printf("Boot reached stage %d\n", progress);
> +}
> +#endif
> +
> +/*
> + * Miscellaneous platform dependent initialisations
> + */
> +
> +int board_init(void)
> +{
> +	int cgu_sccon;
> +
> +	/* arch number of Firetux Platform Boards */
> +	gd->bd->bi_arch_number = MACH_TYPE_PNX8181;
> +
> +	/* adress of boot parameters / atags */
> +	gd->bd->bi_boot_params = PHYS_SDRAM_1 + 0x100;
> +
> +	writel(readw((void *)PNX8181_WDRUCON) | 0x0009, (void *)PNX8181_WDRUCON);
> +	writel(0x0079,(void *)PNX8181_DAIF_RVDDC);
> +
> +	firetux_gpio_init_A();		/* first part */
> +
> +	/* simple board detection */
> +	cgu_sccon = readw((void *)PNX8181_REG_CGU_SCCON);
> +	cgu_sccon = ((cgu_sccon >> 3) & 0x3f);
> +	if (cgu_sccon == 11) {
> +		/* ez_mcp_pnx8181 */
> +		boardrevision = 1;
> +	} else if (cgu_sccon == 14) {
> +		/*
> +		 * vega_pnx8181_basestation Platform III a, b, c
> +		 * we need futher inevestigation by network test
> +		 */
> +		boardrevision = 2;
> +	}
> +
> +	firetux_timer_init();
> +
> +	firetux_ether_init();
> +
> +	firetux_gpio_init_B();		/* we need correct boardversion first */
> +
> +	icache_enable();
> +	dcache_enable();
> +
> +#ifdef CONFIG_CMD_NAND
> +	firetux_nandflash_init();
> +#else
> +	firetux_norflash_init();
> +#endif
> +
> +	firetux_irq_disable();
> +
> +	return 0;
> +}
> +
> +
> +int misc_init_r(void)
> +{
> +	if (boardrevision > 1)		/* ez_mcp_pnx8181 has no keys */
> +		firetux_check_bootkey();
> +
> +	setenv("verify", "n");
> +	return 0;
> +}
> +
> +void firetux_gpio_init_A(void)
> +{
> +	/* select TXD2 for GPIOa11 and select RXD2 for GPIOa1 */
> +	writel(((readl((void *)(PNX8181_SCON_BASE + PNX8181_SYSMUX0))
> +						& 0xff3ffff3) | 0x00400004),
> +				(void *)(PNX8181_SCON_BASE + PNX8181_SYSMUX0));
> +	/* select ETN for GPIOc0-16 */
> +	writel(readl((void *)(PNX8181_SCON_BASE + PNX8181_SYSMUX5))
> +								& 0xfffffffc,
> +				(void *)(PNX8181_SCON_BASE + PNX8181_SYSMUX5));
> +	writel(readl((void *)(PNX8181_SCON_BASE + PNX8181_SYSMUX4))
> +								& 0x30000000,
> +				(void *)(PNX8181_SCON_BASE + PNX8181_SYSMUX4));
> +
> +	/* use clk26m and fract-n for UART2 */
> +	writew(((1 << 7) | (1 << 1)),
> +			(void *)(PNX8181_UART2_BASE + PNX8181_UART_FDIV_CTRL));
> +	writew(0x5F37, (void *)(PNX8181_UART2_BASE + PNX8181_UART_FDIV_M));
> +	writew(0x32C8, (void *)(PNX8181_UART2_BASE + PNX8181_UART_FDIV_N));
> +}
> +
> 
IMHO please use deferent function for each hardware revision
it will allow to make it more readable and to reduce the u-boot when compiling
it for specific revision
> +void firetux_gpio_init_B(void)
> +{
> +	if (boardrevision < 2)		/* EZ_MCP has no leds or keys */
> +		return;
> +
> +	/* set GPIOA10 and GPIOA2 for key input */
> +	writel(readl((void *)(PNX8181_SCON_BASE + PNX8181_SYSMUX0))
> +								& 0xffcfffcf,
> +				(void *)(PNX8181_SCON_BASE + PNX8181_SYSMUX0));
> +	writel(readl((void *)PNX8181_GPIOA_PAD_LOW) & 0xffcfffcf,
> +						(void *)PNX8181_GPIOA_PAD_LOW);
> +	writel(readl((void *)PNX8181_GPIOA_DIRECTION) & ~((1 << 2) | (1 << 10)),
> +					(void *)PNX8181_GPIOA_DIRECTION);
> +
> +	/* set GPIOA9 and GPIOA0 for LED output */
> +	if (boardrevision > 2) {
> +		writel(readl((void *)(PNX8181_SCON_BASE + PNX8181_SYSMUX0))
> +								& 0xfff3fffc,
> +				(void *)(PNX8181_SCON_BASE + PNX8181_SYSMUX0));
> +		writel(readl((void *)PNX8181_GPIOA_DIRECTION)
> +							| ((1 << 9) | (1 << 0)),
> +				(void *)PNX8181_GPIOA_DIRECTION);
> +		writel(readl((void *)PNX8181_GPIOA_OUTPUT)
> +							| ((1 << 9) | (1 << 0)),
> +				(void *)PNX8181_GPIOA_OUTPUT);
> +	} else {    /* Baseboard IIIa */
> +		writel(readl((void *)(PNX8181_SCON_BASE + PNX8181_SYSMUX0))
> +								& 0xfff3ff3f,
> +				(void *)(PNX8181_SCON_BASE + PNX8181_SYSMUX0));
> +		writel(readl((void *)(PNX8181_SCON_BASE + PNX8181_SYSMUX1))
> +								& 0x3ffffffc,
> +				(void *)(PNX8181_SCON_BASE + PNX8181_SYSMUX1));
> +		writel(readl((void *)PNX8181_GPIOA_DIRECTION)
> +				| ((1 << 9) | (1 << 31) | (1 << 16) | (1 << 3)),
> +				(void *)PNX8181_GPIOA_DIRECTION);
> +		writel(readl((void *)PNX8181_GPIOA_OUTPUT)
> +				| ((1 << 9) | (1 << 31) | (1 << 16) | (1 << 3)),
> +				(void *)PNX8181_GPIOA_OUTPUT);
> +	}
> +}
> +
if possible split it in multiple file to avoid ifdef in the code at maximun
note we will move in the futur to Kconfig to manage it
and it's the same for the asm
> +
> +#ifdef CONFIG_CMD_NAND
> +void firetux_nandflash_init(void)
> +{
> +	/*
> +	 * Hardware configuration
> +	 * setup GPIOB18 / FMP40 to GPIO input with internal pullup
> +	 */
> +	writel(readl((void *)(PNX8181_SCON_BASE + PNX8181_SYSMUX3)) & ~(0x30),
> +				(void *)(PNX8181_SCON_BASE + PNX8181_SYSMUX3));
> +	/* set FPM40 to GPIOb18 */
> +	writel(readl((void *)(PNX8181_SCON_BASE + PNX8181_SYSMUX3)) |= 0x10,
> +				(void *)(PNX8181_SCON_BASE + PNX8181_SYSMUX3));
> +	/* set to input */
> +	writel(readl((void *)PNX8181_GPIOB_DIRECTION)
> +					& ~(1 << CONFIG_SYS_NAND_RB_BIT),
> +					(void *)PNX8181_GPIOB_DIRECTION);
> +	/* set pull up */
> +	writel(readl((void *)(PNX8181_SCON_BASE + PNX8181_SYSPAD2))
> +								& ~(3 << 20),
> +				(void *)(PNX8181_SCON_BASE + PNX8181_SYSPAD2));
> +
> +	/* setup access timing for CS0 / 16bit */
> +	writel(0x0001, (void *)(PNX8181_REG_EBI1_CS0 + PNX8181_EBI_MAIN_OFF));
> +	writel(0x1FFFF, (void *)(PNX8181_REG_EBI1_CS0 + PNX8181_EBI_READ_OFF));
> +	writel(0x1FFFF, (void *)(PNX8181_REG_EBI1_CS0 + PNX8181_EBI_WRITE_OFF));
> +	writel(0x0CF8, (void *)(PNX8181_REG_EBI1_CS0 + PNX8181_EBI_BURST_OFF));
> +}
> +#else
> +void firetux_norflash_init(void)
> +{
> +#ifdef CONFIG_SYS_OPTIMIZE_NORFLASH
> +	/* optimize access speed */
> +	writel(0x9, (void *)(PNX8181_REG_EBI1_CS0 + PNX8181_EBI_MAIN_OFF));
> +	writel(0x22D88, (void *)(PNX8181_REG_EBI1_CS0 + PNX8181_EBI_READ_OFF));
> +	writel(0x22D88, (void *)(PNX8181_REG_EBI1_CS0 + PNX8181_EBI_WRITE_OFF));
> +	writel(0x0000, (void *)(PNX8181_REG_EBI1_CS0 + PNX8181_EBI_BURST_OFF));
> +#endif
> +}
> +#endif
> +
> +void firetux_irq_disable(void)
> +{
> +	int i;
> +
> +	writel(31, (void *)PNX8181_INTC_PRIOMASK_IRQ);
> +	writel(31, (void *)PNX8181_INTC_PRIOMASK_FIQ);
> +
> +	for (i = 1; i < 67; i++)
> +		PNX8181_DISABLEIRQ(i);
> +
> +	writel(readl((void *)PNX8181_CGU_GATESC) & 0xfdd7becd,
> +						(void *)PNX8181_CGU_GATESC);
> +}
> +
 +	}
> +
> +	return ret;
> +}
> +
> +
please create a led.c
> +void firetux_set_led(int led, int brightness)
> +{
> +	/* check for boardrevision, EZ_MCP does not have leds */
> +	if (boardrevision < 2)
> +		return;
> +
> +	switch (led) {
> +	case 1:	/* GPIOA9 */
> +		if (brightness)
> +			writel(readl((void *)PNX8181_GPIOA_OUTPUT) & ~(1 << 9),
> +					(void *)PNX8181_GPIOA_OUTPUT);
> +		else
> +			writel(readl((void *)PNX8181_GPIOA_OUTPUT) | (1 << 9),
> +					(void *)PNX8181_GPIOA_OUTPUT);
> +		break;
> +	case 2:	/* GPIOA0 or GPIOA31 */
> +		if (boardrevision > 2) {
> +			if (brightness)
> +				writel(readl((void *)PNX8181_GPIOA_OUTPUT)
> +								& ~(1 << 0),
> +						(void *)PNX8181_GPIOA_OUTPUT);
> +			else
> +				writel(readl((void *)PNX8181_GPIOA_OUTPUT)
> +								| (1 << 0),
> +						(void *)PNX8181_GPIOA_OUTPUT);
> +		} else {
> +			if (brightness)
> +				writel(readl((void *)PNX8181_GPIOA_OUTPUT)
> +								& ~(1 << 31),
> +						(void *)PNX8181_GPIOA_OUTPUT);
> +			else
> +				writel(readl((void *)PNX8181_GPIOA_OUTPUT)
> +								| (1 << 31),
> +						(void *)PNX8181_GPIOA_OUTPUT);
> +		}
> +		break;
> +	case 3:	/* GPIOA16 */
> +		if (boardrevision == 2) {
> +			if (brightness)
> +				writel(readl((void *)PNX8181_GPIOA_OUTPUT)
> +								& ~(1 << 16),
> +						(void *)PNX8181_GPIOA_OUTPUT);
> +			else
> +				writel(readl((void *)PNX8181_GPIOA_OUTPUT)
> +								| (1 << 16),
> +						(void *)PNX8181_GPIOA_OUTPUT);
> +		}
> +		break;
> +	case 4: /* GPIOA3 */
> +		if (boardrevision == 2) {
> +			if (brightness)
> +				writel(readl((void *)PNX8181_GPIOA_OUTPUT)
> +								& ~(1 << 3),
> +						(void *)PNX8181_GPIOA_OUTPUT);
> +			else
> +				writel(readl((void *)PNX8181_GPIOA_OUTPUT)
> +								|= (1 << 3),
> +						(void *)PNX8181_GPIOA_OUTPUT);
> +		}
> +		break;
> +	default:
> +		break;
> +	}
> +}
> +
> +
> +void __led_toggle(led_id_t mask)
> +{
> +	/* check for boardrevision, EZ_MCP does not have leds */
> +	if (boardrevision < 2)
> +		return;
> +
> +	switch (mask) {
> +	case 1:
> +		if (readl((void *)PNX8181_GPIOA_OUTPUT) & (1 << 9))
> +			firetux_set_led(1, 0);
> +		else
> +			firetux_set_led(1, 1);
> +		break;
> +	case 2:
> +		if (boardrevision > 2) {
> +		if (readl((void *)PNX8181_GPIOA_OUTPUT) & (1 << 0))
> +			firetux_set_led(2, 0);
> +		else
> +			firetux_set_led(2, 1);
> +		} else {
> +		if (readl((void *)PNX8181_GPIOA_OUTPUT) & (1 << 31))
> +			firetux_set_led(2, 0);
> +		else
> +			firetux_set_led(2, 1);
> +		}
> +		break;
> +	case 3:
> +		if (boardrevision == 2) {
> +		if (readl((void *)PNX8181_GPIOA_OUTPUT) & (1 << 16))
> +			firetux_set_led(3, 0);
> +		else
> +			firetux_set_led(3, 1);
> +		}
> +		break;
> +	case 4:
> +		if (boardrevision == 2) {
> +		if (readl((void *)PNX8181_GPIOA_OUTPUT) & (1 << 3))
> +			firetux_set_led(4, 0);
> +		else
> +			firetux_set_led(4, 1);
> +		}
> +		break;
> +	default:
> +		break;
> +	}
> +}
> +
> +
> +void __led_init(led_id_t mask, int state)
> +{
> +}
> +
> +
> +void __led_set(led_id_t mask, int state)
> +{
> +	firetux_set_led(mask, state);
> +}
> +
> +
> +void firetux_check_bootkey(void)
> +{
> +	int i = 0, abort = 0;
> +
> +	while ((abort == 0) && (i < 500)) {
> +		if (firetux_keystatus(2) == 1) {
> +			setenv("bootcmd", "run bootcmd1");
> +			firetux_set_led(2, 0);
> +			abort = 1;
> +		}
> +		i++;
> +		udelay(10000);
> +	}
> +	if (abort == 0) {
> +		setenv("bootcmd", "run bootcmd2");
> +		puts("using alternative bootcmd\n");
> +		firetux_set_led(2, 1);
> +	}
> +}
> +
> +
> +int interrupt_init(void)
> +{
> +	return 0;
> +}
> +
> +/*
> + * timer without interrupts
> + */
> +
> +
> +/*
> + * U-Boot expects a 32 bit timer, running at CONFIG_SYS_HZ
> + * Keep total timer count to avoid losing decrements < div_timer
> + */
> +
is your timer is board specific or soc specific??
> +/* U-Boot ticks since startup */
> +static ulong timestamp;
> +static ulong last_timer_read;
> +
> +/*
> + * starts up a counter
> + */
> +void firetux_timer_init(void)
> +{
> +	/* set prescaler to have timer run at 64 kHz */
> +	writeb(0x00, (void *)(PNX8181_SCTU1_BASE + PNX8181_SCTU_TIMxPR));
> +
> +	/* timer reload value = 0xffff - 13824, overflow @ 1kHz */
> +	writew(0xca00, (void *)(PNX8181_SCTU1_BASE + PNX8181_SCTU_TIMxRR));
> +
> +	/* timer has no interrupt, run */
> +	writew(0x0001, (void *)(PNX8181_SCTU1_BASE + PNX8181_SCTU_TIMxCR));
> +
> +	/* init the timestamp */
> +	reset_timer_masked();
> +}
> +
> +ulong get_timer(ulong base_ticks)
> +{
> +	return get_timer_masked() - base_ticks;
> +}
> +
> +/*
> + * converts the timer reading to U-Boot ticks
> + * the timestamp is the number of ticks since reset
> + */
> +ulong get_timer_masked(void)
> +{
> +	/* get current count */
> +	ulong now = readw((void *)(PNX8181_SCTU1_BASE + PNX8181_SCTU_TIMxWR));
> +
> +	if (now < last_timer_read)
> +		timestamp += 13824;
> +	last_timer_read = now;
> +
> +	/*
> +	 * FIXME	this value is empirical!
> +	 *		for some reason the calculated values are way to fast
> +	 */
> +	return (timestamp + now) / 64;
> +}
> +
> +/*
> + * timer without interrupts
> + */
> +void reset_timer(void)
> +{
> +	reset_timer_masked();
> +}
> +
> +
> +/* busy-loop spin-delay */
> +void sdelay(unsigned long usec)
> +{
> +	ulong i, tmp;
> +	tmp = 42;
> +	for (i = 0 ; i < usec*3 ; i++)
> +		/* avoid compiler optimisation */
> +		tmp = -tmp;
> +}
> +
> +/* delay usec useconds */
> +void udelay(unsigned long usec)
> +{
> +	ulong tmo, tmp;
> +
> +	/* Convert to U-Boot ticks */
> +	tmo  = usec / 1500;
> +
> +	tmp  = get_timer_masked();	/* get current timestamp */
> +	tmo += tmp;			/* form target timestamp */
> +
> +	/* loop till event */
> +	while (get_timer_masked() < tmo) {
> +		/*NOP*/;
> +	}
> +}
> +
> +void reset_timer_masked(void)
> +{
> +	/* start "advancing" time stamp from 0 */
> +	timestamp = 0L;
> +}
> +
> +int timer_init(void)
> +{
> +	return 0;
> +}
  
>  COBJS	:= $(COBJS-y)
>  SRCS	:= $(COBJS:.o=.c)
> diff --git a/drivers/i2c/pnx8181_i2c.c b/drivers/i2c/pnx8181_i2c.c
> new file mode 100644
> index 0000000..9979ebe
> --- /dev/null
> +++ b/drivers/i2c/pnx8181_i2c.c
> @@ -0,0 +1,302 @@
> +/*
> + * (C) Copyright 2008 emlix GmbH
> + * Author: Juergen Schoew <js at emlix.com>
> + *
> + * 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., 59 Temple Place, Suite 330, Boston,
> + * MA 02111-1307 USA
> + *
> + */
> +
> +#include <config.h>
> +#include <common.h>
> +
> +#if defined(CONFIG_CMD_I2C) && defined(CONFIG_FIRETUX)
please move to Makefile
> +
> +#undef  DEBUG_I2C
> +
> +#ifdef DEBUG_I2C
> +#define DPRINT(args...)		printf(args)
> +#else
> +#define DPRINT(args...)
> +#endif
> +
> +#define ARM_VPB1_BASE_ADDR	0xC2000000
> +#define ARM_VPB3_BASE_ADDR	0xC2200000
> +#define ARM_VPB_SIZE_SHIFT	12
> +#define SCON_BASE_ADDR		(ARM_VPB3_BASE_ADDR + (4<<ARM_VPB_SIZE_SHIFT))
> +#define SCON_BASE		SCON_BASE_ADDR
> +#define SCON_SYSMUX1_OFFSET	(0x010)
> +#define SCON_SYSMUX1_REG	(*(vu_long *)(SCON_BASE + SCON_SYSMUX1_OFFSET))
> +#define SCON_GPIOA27_MUX_SHIFT	22
> +#define SCON_GPIOA27_MUX_FIELD	(0xFFFFFFFF-(3<<SCON_GPIOA27_MUX_SHIFT))
> +#define SCON_GPIOA27_SCL	(1<<SCON_GPIOA27_MUX_SHIFT)
> +#define SCON_GPIOA28_MUX_SHIFT	24
> +#define SCON_GPIOA28_MUX_FIELD	(0xFFFFFFFF-(3<<SCON_GPIOA28_MUX_SHIFT))
> +#define SCON_GPIOA28_SDA	(1<<SCON_GPIOA28_MUX_SHIFT)
> +#define CGU_BASE_ADDR		(ARM_VPB3_BASE_ADDR + (0<<ARM_VPB_SIZE_SHIFT))
> +#define CGU_BASE		(CGU_BASE_ADDR)
> +#define CGU_GATESC_OFFSET	(0x008)
> +#define CGU_GATESC_REG		(*(vu_long *)(CGU_BASE + CGU_GATESC_OFFSET))
> +#define CGU_I2C1EN		0x00000020
> +#define CGU_I2CEN		CGU_I2C1EN
> +#define I2C1_BASE_ADDR		(ARM_VPB1_BASE_ADDR + (1<<ARM_VPB_SIZE_SHIFT))
> +#define I2C1_BASE		I2C1_BASE_ADDR
> +#define I2C1_RX_REG		(*(vu_long *)(I2C1_BASE + I2C_RX_OFFSET))
> +#define I2C_CLKHI_OFFSET	(0x00C)
> +#define I2C_CLKHI_REG		(*(vu_long *)(I2C1_BASE + I2C_CLKHI_OFFSET))
> +#define I2C_CLKLO_OFFSET	(0x010)
> +#define I2C_CLKLO_REG		(*(vu_long *)(I2C1_BASE + I2C_CLKLO_OFFSET))
> +#define I2C_ADR_OFFSET		(0x014)
> +#define I2C1_ADR_REG            (*(vu_long *)(I2C1_BASE + I2C_ADR_OFFSET))
> +#define I2C_ADR_REG             (*(vu_long *)(I2C1_BASE + I2C_ADR_OFFSET))
> +#define I2C_SADDR_FIELD         0xFFFFFF80
> +#define I2C_HOLDDAT_OFFSET	(0x018)
> +#define I2C_HOLDDAT_REG		(*(vu_long *)(I2C1_BASE + I2C_HOLDDAT_OFFSET))
> +#define I2C_CLKDIV_FIELD	0xFFFFFC00
> +#define I2C_STS_OFFSET		(0x004)
> +#define I2C_STS_REG		(*(vu_long *)(I2C1_BASE + I2C_STS_OFFSET))
> +#define I2C_CTL_OFFSET		(0x008)
> +#define I2C_CTL_REG		(*(vu_long *)(I2C1_BASE + I2C_CTL_OFFSET))
> +#define I2C_TX_OFFSET		(0x000)
> +#define I2C_TX_REG		(*(vu_long *)(I2C1_BASE + I2C_TX_OFFSET))
> +#define I2C_RX_OFFSET		(0x000)
> +#define I2C1_RX_REG		(*(vu_long *)(I2C1_BASE + I2C_RX_OFFSET))
> +#define I2C_RX_REG		(*(vu_long *)(I2C1_BASE + I2C_RX_OFFSET))
> +#define I2C_TDI			0x00000001
> +#define I2C_AFI			0x00000002
> +#define I2C_NAI			0x00000004
> +#define I2C_DRMI		0x00000008
> +#define I2C_DRSI		0x00000010
> +#define I2C_ACTIVE		0x00000020
> +#define I2C_SCL			0x00000040
> +#define I2C_SDA			0x00000080
> +#define I2C_RFF			0x00000100
> +#define I2C_RFE			0x00000200
> +#define I2C_TFF			0x00000400
> +#define I2C_TFE			0x00000800
> +#define I2C_TFFS		0x00001000
> +#define I2C_TFES		0x00002000
> +#define I2C_MAST		0x00004000
> +
> +#define I2C_RESET		0x00000100
> +
> +#define I2C_TIMEOUT		10000
> +#define I2C_DELAY		10
> +
> +
> +#define SEND_I2C_DEVICE_ADDRESS_START_STOP(addr)	\
> +					I2C_TX_REG = (((0x80+addr)<<1) + 0x200);
> +#define SEND_I2C_START_ADDRESS(addr)	I2C_TX_REG = ((0x80+addr)<<1);
> +#define SEND_I2C_STOP_DATA(data)	I2C_TX_REG = (0x200+data);
> +#define SEND_I2C_READ_ADDRESS(addr)	I2C_TX_REG = (((0x80+addr)<<1)+1);
> +#define SOFT_I2C_RESET			I2C_CTL_REG |= I2C_RESET ;
> +
> +int eeprom_write_enable(unsigned dev_addr, int state)
> +{
> +	/* nothing to be done here */
> +	return 0;
> +}
> +
> +void i2c_init(int speed, int slaveadd)
> +{
> +	unsigned long timeout;
> +
> +	SCON_SYSMUX1_REG &= SCON_GPIOA27_MUX_FIELD & SCON_GPIOA28_MUX_FIELD;
> +	SCON_SYSMUX1_REG |= SCON_GPIOA27_SCL | SCON_GPIOA28_SDA;
> +	CGU_GATESC_REG |= CGU_I2CEN;
> +	if (speed == 400000) {
?????
> +	} else {
> +		speed = 100000;
> +		/* here the registers are set in order to have a 100KHz clk
> +		 * for a pclk1 of 23Mhz */
> +		I2C_CLKHI_REG   = I2C_CLKDIV_FIELD  | 0x50;
> +		I2C_CLKLO_REG   = I2C_CLKDIV_FIELD  | 0x96;
> +		I2C_HOLDDAT_REG = 0x10;
> +	}
> +	I2C_ADR_REG = slaveadd & ~I2C_SADDR_FIELD;
> +	SOFT_I2C_RESET;
> +	timeout = 0;
> +	while ((I2C_ACTIVE & I2C_STS_REG) == I2C_ACTIVE) {
> +		if (timeout > I2C_TIMEOUT)
> +			break;
> +		timeout++;
> +		udelay(I2C_DELAY);
> +	}
> +	DPRINT("%s: speed: %d\n", __func__, speed);
please use debug()
> +}
> +
> +
> +int i2c_probe(uchar chip)
> +{
> +	unsigned long timeout;
> +
> +	SEND_I2C_DEVICE_ADDRESS_START_STOP(chip);
> +	timeout = 0;
> +	while ((I2C_TDI & I2C_STS_REG) != I2C_TDI) {
> +		if (timeout > I2C_TIMEOUT)
> +			return -1;
> +		timeout++;
> +		udelay(I2C_DELAY);
> +	}
> +	I2C_STS_REG |= I2C_TDI;
> +	if ((I2C_NAI & I2C_STS_REG) == I2C_NAI)
> +		return -1;
> +	return 0;
> +}
> +
> +static int i2c_read_byte(u8 chip, u16 addr, u8 *byte)
> +{
> +	unsigned long timeout;
> +
> +	timeout = 0;
> +	while ((I2C_ACTIVE & I2C_STS_REG) == I2C_ACTIVE) {
> +		if (timeout > I2C_TIMEOUT)
> +			return -1;
> +		timeout++;
> +		udelay(I2C_DELAY);
> +	}
> +	SEND_I2C_START_ADDRESS(chip);
> +	/* loop if scl=1, active=0 or drmi=0 */
> +	timeout = 0;
> +	while (((I2C_SCL & I2C_STS_REG)      == I2C_SCL)    ||
> +		((I2C_ACTIVE & I2C_STS_REG)  != I2C_ACTIVE) ||
> +		((I2C_DRMI & I2C_STS_REG)    != I2C_DRMI))
> +		if (timeout > I2C_TIMEOUT) {
> +			return -1;
> +		timeout++;
> +		udelay(I2C_DELAY);
> +	}
> +	I2C_TX_REG = ((addr & 0xFF00) >> 8);		/* ADDRESS_MODE16 */
> +	I2C_TX_REG = ((addr & 0x00FF) >> 0);
> +	SEND_I2C_READ_ADDRESS(chip);			/* Dev Sel to Read */
> +	SEND_I2C_STOP_DATA(0x00);			/* dummy write */
> +	timeout = 0;
> +	while (((I2C_NAI & I2C_STS_REG)     == I2C_NAI)     ||
> +		((I2C_TDI & I2C_STS_REG)    != I2C_TDI)     ||
> +		((I2C_SCL & I2C_STS_REG)    != I2C_SCL)     ||
> +		((I2C_ACTIVE & I2C_STS_REG) == I2C_ACTIVE)  ||
> +		((I2C_DRMI & I2C_STS_REG)   == I2C_DRMI))
> +		if (timeout > I2C_TIMEOUT) {
> +			return -1;
> +		timeout++;
> +		udelay(I2C_DELAY);
> +	}
> +	I2C_STS_REG |= I2C_TDI;
> +	timeout = 0;
> +	while ((I2C_TDI & I2C_STS_REG) == I2C_TDI) {
> +		if (timeout > I2C_TIMEOUT)
> +			return -1;
> +		timeout++;
> +		udelay(I2C_DELAY);
> +	}
> +	*byte = I2C_RX_REG & 0xff;
> +	return 0;
> +}
> +
> +static int i2c_write_byte(u8 chip, u16 addr, u8 *byte)
> +{
> +	u8 dummy;
> +	unsigned long timeout;
> +
> +	/* wait until data is written and eeprom back again */
> +	timeout = 0;
> +	dummy = 1;
> +	while ((timeout < I2C_TIMEOUT) && (dummy != 0)) {
> +		dummy = -i2c_probe(chip);
> +		timeout++;
> +		udelay(I2C_DELAY);
> +	}
> +	timeout = 0;
> +	while ((I2C_ACTIVE & I2C_STS_REG) == I2C_ACTIVE) {
> +		if (timeout > I2C_TIMEOUT)
> +			return -1;
> +		timeout++;
> +		udelay(I2C_DELAY);
> +	}
> +	SEND_I2C_START_ADDRESS(chip);
> +	/* loop if scl=1, active=0 or drmi=0 */
> +	timeout = 0;
> +	while (((I2C_SCL & I2C_STS_REG)      == I2C_SCL)    ||
> +		  ((I2C_ACTIVE & I2C_STS_REG)  != I2C_ACTIVE) ||
> +		  ((I2C_DRMI & I2C_STS_REG)    != I2C_DRMI)) {
> +		if (timeout > I2C_TIMEOUT)
> +			return -2;
> +		timeout++;
> +		udelay(I2C_DELAY);
> +	}
> +	I2C_TX_REG = ((addr & 0xFF00) >> 8);		/* ADDRESS_MODE16 */
> +	I2C_TX_REG = ((addr & 0x00FF) >> 0);
> +	SEND_I2C_STOP_DATA(*byte);
> +	timeout = 0;
> +	while (((I2C_NAI & I2C_STS_REG)      == I2C_NAI)     ||
> +		((I2C_TDI & I2C_STS_REG)     != I2C_TDI)     ||
> +		((I2C_SCL & I2C_STS_REG)     != I2C_SCL)     ||
> +		((I2C_ACTIVE & I2C_STS_REG)  == I2C_ACTIVE)  ||
> +		((I2C_DRMI & I2C_STS_REG)    == I2C_DRMI)) {
> +		if (timeout > I2C_TIMEOUT)
> +			return -3;
> +		timeout++;
> +		udelay(I2C_DELAY);
> +	}
> +	I2C_STS_REG |= I2C_TDI;
> +	timeout = 0;
> +	while ((I2C_TDI & I2C_STS_REG) == I2C_TDI) {
> +		if (timeout > I2C_TIMEOUT)
> +			return -4;
> +		timeout++;
> +		udelay(I2C_DELAY);
> +	}
> +	dummy = I2C_RX_REG & 0xff;
> +	return 0;
> +}
> +
> +int i2c_read(uchar chip, uint addr, int alen, uchar *buf, int len)
> +{
> +	int ret;
> +	u8 byte;
> +
> +	DPRINT("%s chip: 0x%02x addr: 0x%04x alen: %d len: %d\n",
> +		__func__, chip, addr, alen, len);
> +	while (len--) {
> +		ret = i2c_read_byte(chip, addr, &byte);
> +		if (ret < 0)
> +			return -1;
> +		*buf++ = byte;
> +		addr++;
> +	}
> +	return 0;
> +}
> +
> +int i2c_write(uchar chip, uint addr, int alen, uchar *buf, int len)
> +{
> +	int ret;
> +
> +	DPRINT("%s chip: 0x%02x addr: 0x%04x alen: %d len: %d\n",
> +		__func__, chip, addr, alen, len);
> +	while (len--) {
> +		ret = i2c_write_byte(chip, addr++, buf++);
> +		if (ret) {
> +			printf("i2c_write failed chip: 0x%x addr: "
> +				"0x%04x error %d\n", chip, addr, ret);
> +			return -1;
> +		}
> +	}
> +	return 0;
> +}
> +
> +#endif
> diff --git a/include/configs/firetux.h b/include/configs/firetux.h
> new file mode 100644
> index 0000000..efa27af
> --- /dev/null
> +++ b/include/configs/firetux.h
> @@ -0,0 +1,460 @@
> +/*
> + * firetux board configuration
> + *
> + * (C) Copyright 2007-2008 emlix GmbH
> + * Juergen Schoew <js at emlix.com>
> + *
> + * (C) Copyright 2008, DSPG Technologies GmbH, Germany
> + * (C) Copyright 2007, NXP Semiconductors Germany GmbH
> + * Matthias Wenzel, <nxp at mazzoo.de>
> + *
> + * 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., 59 Temple Place, Suite 330, Boston,
> + * MA 02111-1307 USA
> + */
> +
> +#ifndef __CONFIG_H
> +#define __CONFIG_H
> +
> +#define CONFIG_FIRETUX			1
> +#define CONFIG_ARCH_FIRETUX		1
> +#define CONFIG_ARM926EJS		1
> +
> +/* we can have nand _or_ nor flash */
> +/* #define CONFIG_NANDFLASH		1 */
> +
> +/* #define CONFIG_SHOW_BOOT_PROGRESS	1 */
please no dead code
> +#define CONFIG_DISPLAY_CPUINFO		1
> +#define CONFIG_DISPLAY_BOARDINFO	1
> +
> +#define CONFIG_BOOT_LINUX		1
> +
> +/* #define CONFIG_USE_IRQ		1 */
> +
> +/* #define CONFIG_SKIP_LOWLEVEL_INIT	1 */
> +/* #define CONFIG_SKIP_RELOCATE_UBOOT	1 */
> +
> +#define CONFIG_SYS_ARM_DEBUG_MEM	1
> +
> +/* MWe has a buggy piece of silicon */
> +/* #define CONFIG_FIRETUX_HAS_CGU_SCCON_MSC_BUG	1 */
> +
> +/*
> + * High Level Configuration Options
> + * (easy to change)
> + */
> +/* Timer 1 is clocked at 1Mhz */
> +#define CONFIG_SYS_HZ			1000000
> +
> +/* enable passing of ATAGs  */
> +#define CONFIG_CMDLINE_TAG		1
> +#define CONFIG_SETUP_MEMORY_TAGS	1
> +/* call misc_init_r during start up */
> +#define CONFIG_MISC_INIT_R		1
> +#define CONFIG_INITRD_TAG		1
> +/* mount rootfs read-only */
> +#define CONFIG_ROOT_RDONLY		1
> +#define CONFIG_STATUS_LED		1
> +#define CONFIG_BOARD_SPECIFIC_LED	1
> +#define STATUS_LED_BIT			1
> +#define STATUS_LED_PERIOD		(CONFIG_SYS_HZ / 2)
> +#define STATUS_LED_STATE		STATUS_LED_BLINKING
> +#define STATUS_LED_ACTIVE		1
> +#define STATUS_LED_BOOT			1
> +
> +/* BZIP2 needs 4MB Malloc Size */
> +/* #define CONFIG_BZIP2			1 */
> +#define CONFIG_LZMA			1
> +
v> +/*
> + * Boardrevisions:
> + *  0: unknown PNX8181 board
> + *  1: EZ_MCP_PNX8181
> + *  2: Vega_PNX8181_BaseStation Platform III-a
> + *  3: Vega_PNX8181_BaseStation Platform III-b
> + *  4: Vega_PNX8181_BaseStation Platform III-c
> + */
> +#define CONFIG_MAX_BOARDREVISIONS	4
> +
> +/*
> + * ethernet
> + */
> +

Best Regards,
J.


More information about the U-Boot mailing list