[U-Boot] [PATCH] ARM: Add support for edb93xx boards
Wolfgang Denk
wd at denx.de
Mon Dec 7 20:46:29 CET 2009
Dear Matthias Kaehlcke,
In message <20091206145444.GE22689 at darwin> you wrote:
> Add support for the Cirrus EP93xx platform and EDB93xx boards
In addition to Tom's comments:
> @@ -2429,6 +2429,42 @@ TQM834x_config: unconfig
> vme8349_config: unconfig
> @$(MKCONFIG) $(@:_config=) ppc mpc83xx vme8349 esd
>
> +edb93xx_config \
> +edb9301_config \
> +edb9302_config \
> +edb9302a_config \
> +edb9307_config \
> +edb9307a_config \
> +edb9315a_config: unconfig
Keep all such lists sorted!
> + @if [ "$(findstring 01_,$@)" ] ; then \
> + echo "#define CONFIG_EDB9301" >> $(obj)include/config.h ; \
> + elif [ "$(findstring 02_,$@)" ] ; then \
> + echo "#define CONFIG_EDB9302" >> $(obj)include/config.h ; \
> + elif [ "$(findstring 02a_,$@)" ] ; then \
> + echo "#define CONFIG_EDB9302A" >> $(obj)include/config.h ; \
> + elif [ "$(findstring 07_,$@)" ] ; then \
> + echo "#define CONFIG_EDB9307" >> $(obj)include/config.h ; \
> + elif [ "$(findstring 07a_,$@)" ] ; then \
> + echo "#define CONFIG_EDB9307A" >> $(obj)include/config.h ; \
> + elif [ "$(findstring 12_,$@)" ] ; then \
> + echo "#define CONFIG_EDB9312" >> $(obj)include/config.h ; \
> + elif [ "$(findstring 15_,$@)" ] ; then \
> + echo "#define CONFIG_EDB9315" >> $(obj)include/config.h ; \
> + elif [ "$(findstring 15a_,$@)" ] ; then \
> + echo "#define CONFIG_EDB9315A" >> $(obj)include/config.h ; \
> + fi ;
Please don't do scripting in the Makefile. Move this logic into your
board config file instead.
> + @$(MKCONFIG) -a edb93xx arm arm920t edb93xx NULL ep93xx
> + @if [ "$(findstring 01_,$@)" ] || [ "$(findstring 02_,$@)" ]; then \
> + echo "TEXT_BASE = 0x05400000" >> $(obj)include/config.mk ; \
> + elif [ "$(findstring 02a_,$@)" ]; then \
> + echo "TEXT_BASE = 0xc5400000" >> $(obj)include/config.mk ; \
> + elif [ "$(findstring 07_,$@)" ] || [ "$(findstring 12_,$@)" ] || [ "$(findstring 15_,$@)" ]; then \
> + echo "TEXT_BASE = 0x01f00000" >> $(obj)include/config.mk ; \
> + elif [ "$(findstring 07a_,$@)" ] || [ "$(findstring 15a_,$@)" ]; then \
> + echo "TEXT_BASE = 0xc1f00000" >> $(obj)include/config.mk ; \
> + fi ;
Ditto.
> + /* Machine number, as defined in linux/arch/arm/tools/mach-types
> + */
> +#ifdef CONFIG_EDB9301
> + gd->bd->bi_arch_number = 462;
> +#elif defined(CONFIG_EDB9302)
> + gd->bd->bi_arch_number = 538;
> +#elif defined(CONFIG_EDB9302A)
> + gd->bd->bi_arch_number = 1127;
> +#elif (defined CONFIG_EDB9307)
> + gd->bd->bi_arch_number = 607;
> +#elif (defined CONFIG_EDB9307A)
> + gd->bd->bi_arch_number = 1128;
> +#elif defined(CONFIG_EDB9312)
> + gd->bd->bi_arch_number = 451;
> +#elif defined(CONFIG_EDB9315)
> + gd->bd->bi_arch_number = 463;
> +#elif defined(CONFIG_EDB9315A)
> + gd->bd->bi_arch_number = 772;
> +#endif
Please use symbolic constants from <asm/mach-types.h>, and move the
logic into your board config file.
> +int dram_init(void)
> +{
> + DECLARE_GLOBAL_DATA_PTR;
> + unsigned int *src, *dst;
> + int i;
> +
> + gd->bd->bi_dram[0].start = PHYS_SDRAM_1;
> + gd->bd->bi_dram[0].size = PHYS_SDRAM_SIZE_1;
> +
> +#ifdef PHYS_SDRAM_2
> + gd->bd->bi_dram[1].start = PHYS_SDRAM_2;
> + gd->bd->bi_dram[1].size = PHYS_SDRAM_SIZE_2;
> +#endif
> +
> +#ifdef PHYS_SDRAM_3
> + gd->bd->bi_dram[2].start = PHYS_SDRAM_3;
> + gd->bd->bi_dram[2].size = PHYS_SDRAM_SIZE_3;
> +#endif
> +
> +#ifdef PHYS_SDRAM_4
> + gd->bd->bi_dram[3].start = PHYS_SDRAM_4;
> + gd->bd->bi_dram[3].size = PHYS_SDRAM_SIZE_4;
> +#endif
Make sure to use get_ram_size() on all banks for checking and
auto-sizing.
> diff --git a/board/edb93xx/flash_cfg.S b/board/edb93xx/flash_cfg.S
> new file mode 100644
> index 0000000..aa61a3c
> --- /dev/null
> +++ b/board/edb93xx/flash_cfg.S
...
> +.globl flash_cfg
> +flash_cfg:
> + /* configure smc bank 6 (Intel TE28F128J3D75 Strata Flash)
> + * ebibrkdis: 0, mw: 0x1 (16 bit), pme: 0, wp: 0, wst2: 2(+1),
> + * wst1: 5(+1), rble: 1, idcy: 2(+1)
> + * TODO: we don't enable page mode for now
> + */
> + ldr r0, =SMC_BCR6
> +
> + ldr r1, =(2 << SMC_BCR_IDCY_SHIFT | 5 << SMC_BCR_WST1_SHIFT | \
> + SMC_BCR_BLE | 2 << SMC_BCR_WST2_SHIFT | 1 << SMC_BCR_MW_SHIFT)
> +
> + str r1, [r0]
> +
> + mov pc, lr
Why is this written in assembler? Please rewrite in C.
> diff --git a/board/edb93xx/pll_cfg.S b/board/edb93xx/pll_cfg.S
> new file mode 100644
> index 0000000..ae69a7d
> --- /dev/null
> +++ b/board/edb93xx/pll_cfg.S
> @@ -0,0 +1,93 @@
...
> + /* the user's guide recommends to wait at least 1 ms for PLL2 to
> + * stabilize, but Cirrus' Redboot doesn't do that, either
> + */
> +
> + mov pc, lr
Why don't you write this as C code? And why do you copy bad (or at
least not recommended behaviour, even if it seems to work for you?
Adding a "udelay(1000);" seems so trivial that I wonder why you don;t
follow the docs?
> diff --git a/board/edb93xx/sdram_cfg.S b/board/edb93xx/sdram_cfg.S
> new file mode 100644
> index 0000000..752bb72
> --- /dev/null
> +++ b/board/edb93xx/sdram_cfg.S
Stop here. Why again assembler?
U-Boot uses assembler only when ther eis no reasonable way to
implement the code in C, and I don't see any such justification here.
Please rewrite all this in C.
> diff --git a/board/edb93xx/u-boot.lds b/board/edb93xx/u-boot.lds
> new file mode 100644
> index 0000000..76caef3
> --- /dev/null
> +++ b/board/edb93xx/u-boot.lds
This looks pretty generic. Please explain why exactly you think you
need a board specific linker script here, instead of using the generic
one?
> diff --git a/cpu/arm920t/ep93xx/Makefile b/cpu/arm920t/ep93xx/Makefile
> new file mode 100644
> index 0000000..9763e15
> --- /dev/null
> +++ b/cpu/arm920t/ep93xx/Makefile
> @@ -0,0 +1,55 @@
> +# vim: set ts=8 sw=8 noet:
> +#
> +# Cirrus Logic EP93xx CPU-specific Makefile
> +#
> +# Copyright (C) 2004, 2005
> +# Cory T. Tusar, Videon Central, Inc., <ctusar at videon-central.com>
> +#
> +# Copyright (C) 2006
> +# Dominic Rath <Dominic.Rath at gmx.de>
Hm... Your signed-off-by: line does not mention Cory Tusar nor Dominic
Rath, so which part exactly do these have in the code you are
submitting here?
> diff --git a/cpu/arm920t/ep93xx/cpu.c b/cpu/arm920t/ep93xx/cpu.c
> new file mode 100644
> index 0000000..3989ee8
> --- /dev/null
> +++ b/cpu/arm920t/ep93xx/cpu.c
...
> +#include <common.h>
> +
> +#if defined(CONFIG_EP93XX)
In which cases would this #define be needed? Your Makefiles should
only build files which are needed in the first place - such a #define
here seems wrong to me.
> +/* All EP93xx variants have 16 KiB I-cache. */
> +extern int checkicache(void)
> +{
> + return 16 << 10;
> +}
> +
> +
> +/* All EP93xx variants have 16 KiB D-cache. */
> +extern int checkdcache(void)
> +{
> + return 16 << 10;
> +}
If you need something like this, then provide it as static inline
functions in the respective header file.
> +/* This is a nop on ARM, and is included here for completeness only. */
> +extern void upmconfig(unsigned int upm, unsigned int *table, unsigned int size)
> +{
> + /* nop */
> +}
Get rid of unused crap, please.
> +
> +/* We reset the CPU by generating a 1-->0 transition on DeviceCfg bit 31. */
> +extern void reset_cpu(ulong addr)
> +{
> + uint32_t value;
> +
> + /* Unlock DeviceCfg and set SWRST */
> + writel(0xAA, SYSCON_SYSSWLOCK);
> + value = readl(SYSCON_DEVICECFG);
> + value |= SYSCON_DEVICECFG_SWRST;
> + writel(value, SYSCON_DEVICECFG);
> +
> + /* Unlock DeviceCfg and clear SWRST */
> + writel(0xAA, SYSCON_SYSSWLOCK);
> + value = readl(SYSCON_DEVICECFG);
> + value &= ~SYSCON_DEVICECFG_SWRST;
> + writel(value, SYSCON_DEVICECFG);
> +
> + /* Dying... */
> + while (1)
> + ; /* nop */
> +}
> +
> +
> +#endif /* defined(CONFIG_EP93XX) */
> diff --git a/cpu/arm920t/ep93xx/eth.c b/cpu/arm920t/ep93xx/eth.c
> new file mode 100644
> index 0000000..513c221
> --- /dev/null
> +++ b/cpu/arm920t/ep93xx/eth.c
...
> +/**
> + * Send a trace message to the terminal.
> + */
> +#if 0
...
Here and elsewhere: please do not add dead code.
> +struct rx_status {
> + union {
> + uint32_t word1;
> +
> + struct {
> + unsigned:8;
> + unsigned hti:6;
> + unsigned:1;
> + unsigned crci:1;
> + unsigned crce:1;
> + unsigned edata:1;
> + unsigned runt:1;
> + unsigned fe:1;
> + unsigned oe:1;
> + unsigned rx_err:1;
> + unsigned am:2;
> + unsigned:4;
> + unsigned eob:1;
> + unsigned eof:1;
> + unsigned rwe:1;
> + unsigned rfp:1;
> + };
> + };
Do not use bit fields. These are unportable and a major PITA in any
case.
> + union {
> + uint32_t word2;
> +
> + struct {
> + unsigned frame_length:16;
> + unsigned buffer_index:15;
> + unsigned rfp:1;
> + };
> + };
> +} __attribute__((packed));
> +
> +
> +/**
> + * Transmit descriptor queue entry
> + */
> +struct tx_descriptor {
I think this whole declarations stuff belongs to some separate header
file.
> +/**
> + * Dump ep93xx_mac values to the terminal.
> + */
> +inline void dump_dev(void)
> +{
> +#if defined(EP93XX_MAC_DEBUG)
Don't compile the function at all when debug is not selected. Ditto
for the other debug functions.
> diff --git a/cpu/arm920t/ep93xx/speed.c b/cpu/arm920t/ep93xx/speed.c
> new file mode 100644
> index 0000000..cc32ec7
> --- /dev/null
> +++ b/cpu/arm920t/ep93xx/speed.c
...
> +/* ------------------------------------------------------------------------- */
> +/* NOTE: This describes the proper use of this file.
This line just adds bloat.
> diff --git a/cpu/arm920t/ep93xx/timer.c b/cpu/arm920t/ep93xx/timer.c
> new file mode 100644
> index 0000000..28660d0
> --- /dev/null
> +++ b/cpu/arm920t/ep93xx/timer.c
> @@ -0,0 +1,163 @@
> +/* vim: set ts=8 sw=8 noet:
> + *
> + * Cirrus Logic EP93xx interrupt support.
Why is the file name "timer.c" when it's interrupt support actually?
> +int timer_init(void)
> +{
> + /* use timer 1 with 2KHz and free running */
> + writel(0x00, TIMER1_CONTROL);
> + if (timer_load_val == 0) {
> + /*
> + * for 10 ms clock period @ PCLK with 4 bit divider = 1/2
> + * (default) and prescaler = 16. Should be 10390
> + * @33.25MHz and 15625 @ 50 MHz
> + */
> +
> + /* set to constant just now, until I resolve clocking issues */
> + timer_load_val = 21;
> + }
> + /* auto load, manual update of Timer 1 */
> + lastdec = timer_load_val;
> + writel(timer_load_val, TIMER1_LOAD);
> +
> + /* Enable the timer and periodic mode */
> + writel(0xC0, TIMER1_CONTROL);
> +
> + return 0;
> +}
> +
> +/*
> + * timer without interrupts
> + */
> +
> +void reset_timer(void)
> +{
> + reset_timer_masked();
> +}
> +
> +ulong get_timer(ulong base)
> +{
> + return get_timer_masked() - base;
> +}
Hm.... does not seem to be too much of interrupt support, so please
fix the comments!
> +void udelay(unsigned long usec)
This needs to be adapted to the current implementation. Make this
__udelay() here.
> diff --git a/include/asm-arm/arch-ep93xx/ep93xx.h b/include/asm-arm/arch-ep93xx/ep93xx.h
> new file mode 100644
> index 0000000..47e2a21
> --- /dev/null
> +++ b/include/asm-arm/arch-ep93xx/ep93xx.h
...
> +#define DMAMP_TX_0_CONTROL (DMA_BASE + 0x0000)
> +#define DMAMP_TX_0_INTERRUPT (DMA_BASE + 0x0004)
> +#define DMAMP_TX_0_PPALLOC (DMA_BASE + 0x0008)
> +#define DMAMP_TX_0_STATUS (DMA_BASE + 0x000C)
> +#define DMAMP_TX_0_REMAIN (DMA_BASE + 0x0014)
> +#define DMAMP_TX_0_MAXCNT0 (DMA_BASE + 0x0020)
> +#define DMAMP_TX_0_BASE0 (DMA_BASE + 0x0024)
> +#define DMAMP_TX_0_CURRENT0 (DMA_BASE + 0x0028)
> +#define DMAMP_TX_0_MAXCNT1 (DMA_BASE + 0x0030)
> +#define DMAMP_TX_0_BASE1 (DMA_BASE + 0x0034)
> +#define DMAMP_TX_0_CURRENT1 (DMA_BASE + 0x0038)
Get rid of all this address / offset based register accesses. Turn
this into a C struct instead. Please fix globally.
> diff --git a/include/configs/edb93xx.h b/include/configs/edb93xx.h
> new file mode 100644
> index 0000000..6c4576b
> --- /dev/null
> +++ b/include/configs/edb93xx.h
...
> +/* Initial environment and monitor configuration options. */
> +#define CONFIG_ETHADDR 08:00:3E:26:0A:5B
> +#define CONFIG_NETMASK 255.255.255.0
> +#define CONFIG_IPADDR 192.168.99.225
> +#define CONFIG_SERVERIP 192.168.99.1
> +#define CONFIG_GATEWAYIP 192.168.99.1
NAK. We don't allow board specific settings like these.
Also note that the MAC address seems to be hijacked - it actually
belongs to the codex corporation. Please make sure to get your own set
of MAC addresses.
> +#define CONFIG_SYS_CLK_FREQ 14745600 /* EP93xx has a 14.7456 clock */
> +#define CONFIG_SYS_HZ 2048 /* Timer 3 set for 2KHz */
CONFIG_SYS_HZ must always and everywhere be 1000.
> +#define CONFIG_SYS_CLKS_IN_HZ /* Everything in Hz */
This was removed a long time ago. Don't re-introduce it.
> +#if 0
> +#undef CONFIG_CMD_BDI
> +#endif
See above - don;t add dead code.
> +#elif defined(CONFIG_EDB9302A)
> +#define CONFIG_NR_DRAM_BANKS 4 /* EDB9302a has 4 banks of SDRAM */
> +#define PHYS_SDRAM_1 0xc0000000 /* consisting of 1x Samsung */
> +#define PHYS_SDRAM_SIZE_1 0x00800000 /* K4S561632E-TC75 256 Mbit */
> +#define PHYS_SDRAM_2 0xc1000000 /* SDRAM on a 16-bit data bus, */
> +#define PHYS_SDRAM_SIZE_2 0x00800000 /* for a total of 32MB of SDRAM. */
> +#define PHYS_SDRAM_3 0xc4000000 /* We set the SROMLL bit on the */
> +#define PHYS_SDRAM_SIZE_3 0x00800000 /* processor, resulting in this */
> +#define PHYS_SDRAM_4 0xc5000000 /* non-contiguous memory map. */
The comment is all single line comments, so it is supposed to refer to
the actual code in the same line. This is obviously not the case.
Please fix.
> +#define CONFIG_EDB93XX_SDCS0
> +#define CONFIG_SYS_MEMTEST_START 0xc0000000
> +#define CONFIG_SYS_MEMTEST_END 0xc0800000
Has this actually been tested?
> +#define CONFIG_ENV_ADDR 0x60040000
> +#if (defined(CONFIG_EDB9301) || defined(CONFIG_EDB9302) ||\
> + defined(CONFIG_EDB9302A))
> +#define CONFIG_ENV_SECT_SIZE 0x00020000
> +#elif (defined(CONFIG_EDB9307) || defined(CONFIG_EDB9307A) ||\
> + defined(CONFIG_EDB9312) || defined(CONFIG_EDB9315) ||\
> + defined(CONFIG_EDB9315A))
> +#define CONFIG_ENV_SECT_SIZE 0x00040000
> +#endif
> +#define CONFIG_ENV_ADDR_REDUND (CONFIG_ENV_ADDR + CONFIG_ENV_SECT_SIZE)
> +
> +#define CONFIG_ENV_SIZE CONFIG_ENV_SECT_SIZE
> +#define CONFIG_ENV_SIZE_REDUND CONFIG_ENV_SIZE
> +
> +#define CONFIG_SYS_JFFS2_FIRST_BANK 0
> +#if (defined(CONFIG_EDB9301) || defined(CONFIG_EDB9302) ||\
> + defined(CONFIG_EDB9302A))
> +#define CONFIG_SYS_JFFS2_FIRST_SECTOR 28
> +#elif (defined(CONFIG_EDB9307) || defined(CONFIG_EDB9307A) ||\
> + defined(CONFIG_EDB9312) || defined(CONFIG_EDB9315) ||\
> + defined(CONFIG_EDB9315A))
> +#define CONFIG_SYS_JFFS2_FIRST_SECTOR 14
> +#endif
Hm... this looks very much like being completely unmaintainable.
Please simplify the code - in your own interest.
Best regards,
Wolfgang Denk
--
DENX Software Engineering GmbH, MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd at denx.de
Save energy: Drive a smaller shell.
More information about the U-Boot
mailing list