mirror of
https://source.denx.de/u-boot/u-boot.git
synced 2026-06-13 15:03:58 +03:00
Compare commits
86 Commits
v2012.04-r
...
v2012.04
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2790bf69dc | ||
|
|
34921d04b8 | ||
|
|
0d24de9d55 | ||
|
|
0d62032e5b | ||
|
|
146bec7905 | ||
|
|
90579fdd41 | ||
|
|
896bbb5316 | ||
|
|
82f45866ee | ||
|
|
1432c763f8 | ||
|
|
fb14b6b2f6 | ||
|
|
8262e61df5 | ||
|
|
77fe6e773a | ||
|
|
f8abfdefcb | ||
|
|
03f3587822 | ||
|
|
f5cdc11775 | ||
|
|
db39f24151 | ||
|
|
2694bb9bcc | ||
|
|
c6201553ba | ||
|
|
2f002eceae | ||
|
|
fbf4a074e0 | ||
|
|
38fcc71cc5 | ||
|
|
e87ca8c049 | ||
|
|
96666a39ae | ||
|
|
d71c9c9fc0 | ||
|
|
be28255462 | ||
|
|
8d28c211f3 | ||
|
|
a9407f2bc5 | ||
|
|
4cc76c609f | ||
|
|
d0f5600f54 | ||
|
|
9ed5dfa852 | ||
|
|
0792a36efb | ||
|
|
81b1c9ebe1 | ||
|
|
c8d9ceaf06 | ||
|
|
219872c8fe | ||
|
|
f4ac6cb6af | ||
|
|
b6e80e2485 | ||
|
|
66b4170b29 | ||
|
|
4d422fe2dc | ||
|
|
c415919d57 | ||
|
|
1482410531 | ||
|
|
607dfdf568 | ||
|
|
419ea2d84a | ||
|
|
008ec95054 | ||
|
|
36f3aab2dd | ||
|
|
07277e740b | ||
|
|
385488dc1b | ||
|
|
aae58b954b | ||
|
|
c8da405c85 | ||
|
|
b64c2420e0 | ||
|
|
4d675ae6e7 | ||
|
|
1ebff63fb9 | ||
|
|
3786980dd3 | ||
|
|
35897c86b9 | ||
|
|
3f0675d1a5 | ||
|
|
2c734cd932 | ||
|
|
691288e14d | ||
|
|
5c877b1ae0 | ||
|
|
8ec57a9dc1 | ||
|
|
35cf5fe510 | ||
|
|
cafabe1995 | ||
|
|
20a5dde149 | ||
|
|
e25c90b45c | ||
|
|
13edd1706c | ||
|
|
aa51005c3f | ||
|
|
024333c96f | ||
|
|
97a6caa6e5 | ||
|
|
c7f6dbe736 | ||
|
|
a08a649d70 | ||
|
|
e26fd3d3bf | ||
|
|
3ceecef14e | ||
|
|
20637888df | ||
|
|
8422a35e9b | ||
|
|
df48265036 | ||
|
|
8f9c249836 | ||
|
|
6b3967bbbb | ||
|
|
1295f08c7e | ||
|
|
6937664426 | ||
|
|
cc79697c96 | ||
|
|
f4cdde4019 | ||
|
|
6cb461b4f1 | ||
|
|
979cfeaf36 | ||
|
|
71919cf153 | ||
|
|
33d7b71322 | ||
|
|
bb60db634c | ||
|
|
7bd7b31574 | ||
|
|
8875833a86 |
@@ -669,10 +669,6 @@ Igor Grinberg <grinberg@compulab.co.il>
|
||||
|
||||
cm-t35 ARM ARMV7 (OMAP3xx Soc)
|
||||
|
||||
Kshitij Gupta <kshitij@ti.com>
|
||||
|
||||
omap1510inn ARM925T
|
||||
|
||||
Stefan Herbrechtsmeier <stefan@code.herbrechtsmeier.net>
|
||||
|
||||
dns325 ARM926EJS (Kirkwood SoC)
|
||||
@@ -941,6 +937,9 @@ Sughosh Ganu <urwithsughosh@gmail.com>
|
||||
Unknown / orphaned boards:
|
||||
Board CPU Last known maintainer / Comment
|
||||
.........................................................................
|
||||
|
||||
omap1510inn ARM925T Kshitij Gupta <kshitij@ti.com>
|
||||
|
||||
lubbock xscale/pxa Kyle Harris <kharris@nexus-tech.net> / dead address
|
||||
|
||||
imx31_phycore_eet i.MX31 Guennadi Liakhovetski <g.liakhovetski@gmx.de> / resigned
|
||||
|
||||
2
Makefile
2
Makefile
@@ -24,7 +24,7 @@
|
||||
VERSION = 2012
|
||||
PATCHLEVEL = 04
|
||||
SUBLEVEL =
|
||||
EXTRAVERSION = -rc1
|
||||
EXTRAVERSION =
|
||||
ifneq "$(SUBLEVEL)" ""
|
||||
U_BOOT_VERSION = $(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
|
||||
else
|
||||
|
||||
14
README
14
README
@@ -374,6 +374,12 @@ The following options need to be configured:
|
||||
Defines the string to utilize when trying to match PCIe device
|
||||
tree nodes for the given platform.
|
||||
|
||||
- Generic CPU options:
|
||||
CONFIG_SYS_BIG_ENDIAN, CONFIG_SYS_LITTLE_ENDIAN
|
||||
|
||||
Defines the endianess of the CPU. Implementation of those
|
||||
values is arch specific.
|
||||
|
||||
- Intel Monahans options:
|
||||
CONFIG_SYS_MONAHANS_RUN_MODE_OSC_RATIO
|
||||
|
||||
@@ -3493,7 +3499,7 @@ is done by typing:
|
||||
make NAME_config
|
||||
|
||||
where "NAME_config" is the name of one of the existing configu-
|
||||
rations; see the main Makefile for supported names.
|
||||
rations; see boards.cfg for supported names.
|
||||
|
||||
Note: for some board special configuration names may exist; check if
|
||||
additional information is available from the board vendor; for
|
||||
@@ -3548,10 +3554,8 @@ to port U-Boot to your hardware platform. To do this, follow these
|
||||
steps:
|
||||
|
||||
1. Add a new configuration option for your board to the toplevel
|
||||
"Makefile" and to the "MAKEALL" script, using the existing
|
||||
entries as examples. Note that here and at many other places
|
||||
boards and other names are listed in alphabetical sort order. Please
|
||||
keep this order.
|
||||
"boards.cfg" file, using the existing entries as examples.
|
||||
Follow the instructions there to keep the boards in order.
|
||||
2. Create a new directory to hold your board specific code. Add any
|
||||
files you need. In your board directory, you will need at least
|
||||
the "Makefile", a "<board>.c", "flash.c" and "u-boot.lds".
|
||||
|
||||
@@ -70,8 +70,105 @@ int cleanup_before_linux (void)
|
||||
static void cache_flush(void)
|
||||
{
|
||||
unsigned long i = 0;
|
||||
|
||||
asm ("mcr p15, 0, %0, c7, c10, 0": :"r" (i)); /* clean entire data cache */
|
||||
asm ("mcr p15, 0, %0, c7, c7, 0": :"r" (i)); /* invalidate both caches and flush btb */
|
||||
asm ("mcr p15, 0, %0, c7, c10, 4": :"r" (i)); /* mem barrier to sync things */
|
||||
/* clean entire data cache */
|
||||
asm volatile("mcr p15, 0, %0, c7, c10, 0" : : "r" (i));
|
||||
/* invalidate both caches and flush btb */
|
||||
asm volatile("mcr p15, 0, %0, c7, c7, 0" : : "r" (i));
|
||||
/* mem barrier to sync things */
|
||||
asm volatile("mcr p15, 0, %0, c7, c10, 4" : : "r" (i));
|
||||
}
|
||||
|
||||
#ifndef CONFIG_SYS_DCACHE_OFF
|
||||
|
||||
#ifndef CONFIG_SYS_CACHELINE_SIZE
|
||||
#define CONFIG_SYS_CACHELINE_SIZE 32
|
||||
#endif
|
||||
|
||||
void invalidate_dcache_all(void)
|
||||
{
|
||||
asm volatile("mcr p15, 0, %0, c7, c6, 0" : : "r" (0));
|
||||
}
|
||||
|
||||
void flush_dcache_all(void)
|
||||
{
|
||||
asm volatile("mcr p15, 0, %0, c7, c10, 0" : : "r" (0));
|
||||
asm volatile("mcr p15, 0, %0, c7, c10, 4" : : "r" (0));
|
||||
}
|
||||
|
||||
static inline int bad_cache_range(unsigned long start, unsigned long stop)
|
||||
{
|
||||
int ok = 1;
|
||||
|
||||
if (start & (CONFIG_SYS_CACHELINE_SIZE - 1))
|
||||
ok = 0;
|
||||
|
||||
if (stop & (CONFIG_SYS_CACHELINE_SIZE - 1))
|
||||
ok = 0;
|
||||
|
||||
if (!ok)
|
||||
debug("CACHE: Misaligned operation at range [%08lx, %08lx]\n",
|
||||
start, stop);
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
||||
void invalidate_dcache_range(unsigned long start, unsigned long stop)
|
||||
{
|
||||
if (bad_cache_range(start, stop))
|
||||
return;
|
||||
|
||||
while (start < stop) {
|
||||
asm volatile("mcr p15, 0, %0, c7, c6, 1" : : "r" (start));
|
||||
start += CONFIG_SYS_CACHELINE_SIZE;
|
||||
}
|
||||
}
|
||||
|
||||
void flush_dcache_range(unsigned long start, unsigned long stop)
|
||||
{
|
||||
if (bad_cache_range(start, stop))
|
||||
return;
|
||||
|
||||
while (start < stop) {
|
||||
asm volatile("mcr p15, 0, %0, c7, c14, 1" : : "r" (start));
|
||||
start += CONFIG_SYS_CACHELINE_SIZE;
|
||||
}
|
||||
|
||||
asm volatile("mcr p15, 0, %0, c7, c10, 4" : : "r" (0));
|
||||
}
|
||||
|
||||
void flush_cache(unsigned long start, unsigned long size)
|
||||
{
|
||||
flush_dcache_range(start, start + size);
|
||||
}
|
||||
|
||||
void enable_caches(void)
|
||||
{
|
||||
#ifndef CONFIG_SYS_ICACHE_OFF
|
||||
icache_enable();
|
||||
#endif
|
||||
#ifndef CONFIG_SYS_DCACHE_OFF
|
||||
dcache_enable();
|
||||
#endif
|
||||
}
|
||||
|
||||
#else /* #ifndef CONFIG_SYS_DCACHE_OFF */
|
||||
void invalidate_dcache_all(void)
|
||||
{
|
||||
}
|
||||
|
||||
void flush_dcache_all(void)
|
||||
{
|
||||
}
|
||||
|
||||
void invalidate_dcache_range(unsigned long start, unsigned long stop)
|
||||
{
|
||||
}
|
||||
|
||||
void flush_dcache_range(unsigned long start, unsigned long stop)
|
||||
{
|
||||
}
|
||||
|
||||
void flush_cache(unsigned long start, unsigned long size)
|
||||
{
|
||||
}
|
||||
#endif /* #ifndef CONFIG_SYS_DCACHE_OFF */
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
|
||||
void invalidate_dcache_all(void)
|
||||
{
|
||||
asm volatile("mcr p15, 0, %0, c7, c6, 0\n"::"r"(0));
|
||||
asm volatile("mcr p15, 0, %0, c7, c6, 0\n" : : "r"(0));
|
||||
}
|
||||
|
||||
void flush_dcache_all(void)
|
||||
@@ -40,7 +40,7 @@ void flush_dcache_all(void)
|
||||
"mrc p15, 0, r15, c7, c14, 3\n"
|
||||
"bne 0b\n"
|
||||
"mcr p15, 0, %0, c7, c10, 4\n"
|
||||
::"r"(0):"memory"
|
||||
: : "r"(0) : "memory"
|
||||
);
|
||||
}
|
||||
|
||||
@@ -55,7 +55,7 @@ static int check_cache_range(unsigned long start, unsigned long stop)
|
||||
ok = 0;
|
||||
|
||||
if (!ok)
|
||||
printf("CACHE: Misaligned operation at range [%08lx, %08lx]\n",
|
||||
debug("CACHE: Misaligned operation at range [%08lx, %08lx]\n",
|
||||
start, stop);
|
||||
|
||||
return ok;
|
||||
@@ -67,7 +67,7 @@ void invalidate_dcache_range(unsigned long start, unsigned long stop)
|
||||
return;
|
||||
|
||||
while (start < stop) {
|
||||
asm volatile("mcr p15, 0, %0, c7, c6, 1\n"::"r"(start));
|
||||
asm volatile("mcr p15, 0, %0, c7, c6, 1\n" : : "r"(start));
|
||||
start += CONFIG_SYS_CACHELINE_SIZE;
|
||||
}
|
||||
}
|
||||
@@ -78,11 +78,11 @@ void flush_dcache_range(unsigned long start, unsigned long stop)
|
||||
return;
|
||||
|
||||
while (start < stop) {
|
||||
asm volatile("mcr p15, 0, %0, c7, c14, 1\n"::"r"(start));
|
||||
asm volatile("mcr p15, 0, %0, c7, c14, 1\n" : : "r"(start));
|
||||
start += CONFIG_SYS_CACHELINE_SIZE;
|
||||
}
|
||||
|
||||
asm("mcr p15, 0, %0, c7, c10, 4\n"::"r"(0));
|
||||
asm volatile("mcr p15, 0, %0, c7, c10, 4\n" : : "r"(0));
|
||||
}
|
||||
|
||||
void flush_cache(unsigned long start, unsigned long size)
|
||||
@@ -114,8 +114,7 @@ void flush_cache(unsigned long start, unsigned long size)
|
||||
/*
|
||||
* Stub implementations for l2 cache operations
|
||||
*/
|
||||
void __l2_cache_disable(void)
|
||||
{
|
||||
}
|
||||
void __l2_cache_disable(void) {}
|
||||
|
||||
void l2_cache_disable(void)
|
||||
__attribute__((weak, alias("__l2_cache_disable")));
|
||||
__attribute__((weak, alias("__l2_cache_disable")));
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
#include <asm/errno.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/arch/clock.h>
|
||||
#include <asm/arch/dma.h>
|
||||
#include <asm/arch/gpio.h>
|
||||
#include <asm/arch/iomux.h>
|
||||
#include <asm/arch/imx-regs.h>
|
||||
@@ -172,6 +173,11 @@ int arch_cpu_init(void)
|
||||
*/
|
||||
mxs_gpio_init();
|
||||
|
||||
#ifdef CONFIG_APBH_DMA
|
||||
/* Start APBH DMA */
|
||||
mxs_dma_init();
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -31,3 +31,6 @@ PLATFORM_CPPFLAGS += -march=armv5
|
||||
# =========================================================================
|
||||
PF_RELFLAGS_SLB_AT := $(call cc-option,-mshort-load-bytes,$(call cc-option,-malignment-traps,))
|
||||
PLATFORM_RELFLAGS += $(PF_RELFLAGS_SLB_AT)
|
||||
ifneq ($(CONFIG_IMX_CONFIG),)
|
||||
ALL-y += $(obj)u-boot.imx
|
||||
endif
|
||||
|
||||
@@ -85,6 +85,14 @@ int arch_cpu_init(void)
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_SYS_DCACHE_OFF
|
||||
void enable_caches(void)
|
||||
{
|
||||
/* Enable D-cache. I-cache is already enabled in start.S */
|
||||
dcache_enable();
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_FEC_MXC)
|
||||
void imx_get_mac_from_fuse(int dev_id, unsigned char *mac)
|
||||
{
|
||||
|
||||
@@ -140,6 +140,8 @@ void mxs_dma_desc_free(struct mxs_dma_desc *);
|
||||
int mxs_dma_desc_append(int channel, struct mxs_dma_desc *pdesc);
|
||||
|
||||
int mxs_dma_go(int chan);
|
||||
int mxs_dma_init(void);
|
||||
void mxs_dma_init(void);
|
||||
int mxs_dma_init_channel(int chan);
|
||||
int mxs_dma_release(int chan);
|
||||
|
||||
#endif /* __DMA_H__ */
|
||||
|
||||
@@ -84,8 +84,6 @@
|
||||
GPIO_NUM_PIN) + ((pin >> MUX_IO_I) &\
|
||||
((1 << (MUX_IO_P - MUX_IO_I)) - 1)))
|
||||
#define IOMUX_TO_IRQ(pin) (MXC_GPIO_INT_BASE + IOMUX_TO_GPIO(pin))
|
||||
#define GPIO_TO_PORT(n) (n / GPIO_NUM_PIN)
|
||||
#define GPIO_TO_INDEX(n) (n % GPIO_NUM_PIN)
|
||||
|
||||
#define NON_GPIO_I 0x7
|
||||
#define PIN_TO_MUX_MASK ((1<<(PAD_I - MUX_I)) - 1)
|
||||
|
||||
@@ -78,8 +78,6 @@
|
||||
GPIO_NUM_PIN) + ((pin >> MUX_IO_I) &\
|
||||
((1 << (MUX_IO_P - MUX_IO_I)) - 1)))
|
||||
#define IOMUX_TO_IRQ(pin) (MXC_GPIO_INT_BASE + IOMUX_TO_GPIO(pin))
|
||||
#define GPIO_TO_PORT(n) (n / GPIO_NUM_PIN)
|
||||
#define GPIO_TO_INDEX(n) (n % GPIO_NUM_PIN)
|
||||
|
||||
#define NON_GPIO_PORT 0x7
|
||||
#define PIN_TO_MUX_MASK ((1 << (PAD_I - MUX_I)) - 1)
|
||||
|
||||
@@ -19,6 +19,8 @@
|
||||
#ifndef __ASM_ARCH_MX6_IMX_REGS_H__
|
||||
#define __ASM_ARCH_MX6_IMX_REGS_H__
|
||||
|
||||
#define CONFIG_SYS_CACHELINE_SIZE 32
|
||||
|
||||
#define ROMCP_ARB_BASE_ADDR 0x00000000
|
||||
#define ROMCP_ARB_END_ADDR 0x000FFFFF
|
||||
#define CAAM_ARB_BASE_ADDR 0x00100000
|
||||
@@ -168,8 +170,6 @@
|
||||
#define FEC_QUIRK_ENET_MAC
|
||||
|
||||
#define GPIO_NUMBER(port, index) ((((port)-1)*32)+((index)&31))
|
||||
#define GPIO_TO_PORT(number) (((number)/32)+1)
|
||||
#define GPIO_TO_INDEX(number) ((number)&31)
|
||||
|
||||
#if !(defined(__KERNEL_STRICT_NAMES) || defined(__ASSEMBLY__))
|
||||
#include <asm/types.h>
|
||||
|
||||
@@ -30,6 +30,10 @@
|
||||
#include <asm/addrspace.h>
|
||||
#include <asm/cacheops.h>
|
||||
|
||||
#ifndef CONFIG_SYS_MIPS_CACHE_MODE
|
||||
#define CONFIG_SYS_MIPS_CACHE_MODE CONF_CM_CACHABLE_NONCOHERENT
|
||||
#endif
|
||||
|
||||
#define RA t8
|
||||
|
||||
/*
|
||||
@@ -224,7 +228,7 @@ LEAF(dcache_enable)
|
||||
mfc0 t0, CP0_CONFIG
|
||||
ori t0, CONF_CM_CMASK
|
||||
xori t0, CONF_CM_CMASK
|
||||
ori t0, CONF_CM_CACHABLE_NONCOHERENT
|
||||
ori t0, CONFIG_SYS_MIPS_CACHE_MODE
|
||||
mtc0 t0, CP0_CONFIG
|
||||
jr ra
|
||||
END(dcache_enable)
|
||||
|
||||
@@ -27,14 +27,23 @@
|
||||
# Note: Toolchains with binutils prior to v2.16
|
||||
# are no longer supported by U-Boot MIPS tree!
|
||||
#
|
||||
MIPSFLAGS = -march=mips32r2
|
||||
MIPSFLAGS := -march=mips32r2
|
||||
|
||||
# Handle special prefix in ELDK 4.0 toolchain
|
||||
ifneq (,$(findstring 4KCle,$(CROSS_COMPILE)))
|
||||
ENDIANNESS = -EL
|
||||
else
|
||||
ENDIANNESS = -EB
|
||||
ENDIANNESS := -EL
|
||||
endif
|
||||
|
||||
MIPSFLAGS += $(ENDIANNESS)
|
||||
ifdef CONFIG_SYS_LITTLE_ENDIAN
|
||||
ENDIANNESS := -EL
|
||||
endif
|
||||
|
||||
PLATFORM_CPPFLAGS += $(MIPSFLAGS)
|
||||
ifdef CONFIG_SYS_BIG_ENDIAN
|
||||
ENDIANNESS := -EB
|
||||
endif
|
||||
|
||||
# Default to EB if no endianess is configured
|
||||
ENDIANNESS ?= -EB
|
||||
|
||||
PLATFORM_CPPFLAGS += $(MIPSFLAGS) $(ENDIANNESS)
|
||||
PLATFORM_LDFLAGS += $(ENDIANNESS)
|
||||
|
||||
@@ -294,15 +294,19 @@ void board_init_r(gd_t *id, ulong dest_addr)
|
||||
/* configure available FLASH banks */
|
||||
size = flash_init();
|
||||
display_flash_config(size);
|
||||
bd->bi_flashsize = size;
|
||||
#endif
|
||||
|
||||
bd->bi_flashstart = CONFIG_SYS_FLASH_BASE;
|
||||
bd->bi_flashsize = size;
|
||||
|
||||
#if CONFIG_SYS_MONITOR_BASE == CONFIG_SYS_FLASH_BASE
|
||||
bd->bi_flashoffset = monitor_flash_len; /* reserved area for U-Boot */
|
||||
#else
|
||||
bd->bi_flashoffset = 0;
|
||||
#endif
|
||||
#else
|
||||
bd->bi_flashstart = 0;
|
||||
bd->bi_flashsize = 0;
|
||||
bd->bi_flashoffset = 0;
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_CMD_NAND
|
||||
puts("NAND: ");
|
||||
|
||||
@@ -98,6 +98,27 @@ ulong get_timer (ulong base)
|
||||
return (timestamp - base);
|
||||
}
|
||||
|
||||
/*
|
||||
* This function is derived from Blackfin code (read timebase as long long).
|
||||
* On Nios2 it just returns the timer value.
|
||||
*/
|
||||
unsigned long long get_ticks(void)
|
||||
{
|
||||
return get_timer(0);
|
||||
}
|
||||
|
||||
/*
|
||||
* This function is derived from Blackfin code.
|
||||
* On Nios2 it returns the number of timer ticks per second.
|
||||
*/
|
||||
ulong get_tbclk(void)
|
||||
{
|
||||
ulong tbclk;
|
||||
|
||||
tbclk = CONFIG_SYS_HZ;
|
||||
return tbclk;
|
||||
}
|
||||
|
||||
/* The board must handle this interrupt if a timer is not
|
||||
* provided.
|
||||
*/
|
||||
|
||||
@@ -48,6 +48,16 @@ flush_icache:
|
||||
bltu r4, r5, 1b
|
||||
ret
|
||||
|
||||
.global flush_dcache_range
|
||||
|
||||
flush_dcache_range:
|
||||
movhi r8, %hi(CONFIG_SYS_DCACHELINE_SIZE)
|
||||
ori r8, r8, %lo(CONFIG_SYS_DCACHELINE_SIZE)
|
||||
0: flushd 0(r4)
|
||||
add r4, r4, r8
|
||||
bltu r4, r5, 0b
|
||||
ret
|
||||
|
||||
.global flush_cache
|
||||
|
||||
flush_cache:
|
||||
|
||||
@@ -15,4 +15,3 @@
|
||||
int mmcif_mmc_init(void);
|
||||
|
||||
#endif /* _SH_MMC_H_ */
|
||||
|
||||
|
||||
@@ -356,16 +356,17 @@ static void reset_net_chip(void)
|
||||
{
|
||||
/* Set GPIO1 of TPS65930 as output */
|
||||
twl4030_i2c_write_u8(TWL4030_CHIP_GPIO, 0x02,
|
||||
TWL4030_BASEADD_GPIO+0x03);
|
||||
TWL4030_BASEADD_GPIO + 0x03);
|
||||
/* Send a pulse on the GPIO pin */
|
||||
twl4030_i2c_write_u8(TWL4030_CHIP_GPIO, 0x02,
|
||||
TWL4030_BASEADD_GPIO+0x0C);
|
||||
TWL4030_BASEADD_GPIO + 0x0C);
|
||||
udelay(1);
|
||||
twl4030_i2c_write_u8(TWL4030_CHIP_GPIO, 0x02,
|
||||
TWL4030_BASEADD_GPIO+0x09);
|
||||
udelay(1);
|
||||
TWL4030_BASEADD_GPIO + 0x09);
|
||||
mdelay(40);
|
||||
twl4030_i2c_write_u8(TWL4030_CHIP_GPIO, 0x02,
|
||||
TWL4030_BASEADD_GPIO+0x0C);
|
||||
TWL4030_BASEADD_GPIO + 0x0C);
|
||||
mdelay(1);
|
||||
}
|
||||
#else
|
||||
static inline void reset_net_chip(void) {}
|
||||
|
||||
@@ -178,11 +178,6 @@ void show_boot_progress(int val)
|
||||
|
||||
int last_stage_init(void)
|
||||
{
|
||||
int minor;
|
||||
int major;
|
||||
|
||||
major = minor = 0;
|
||||
|
||||
outb(0x00, LED_LATCH_ADDRESS);
|
||||
|
||||
register_timer_isr(enet_timer_isr);
|
||||
|
||||
@@ -71,19 +71,11 @@ int board_early_init_f(void)
|
||||
return 0;
|
||||
}
|
||||
|
||||
void enable_caches(void)
|
||||
{
|
||||
icache_enable();
|
||||
dcache_enable();
|
||||
}
|
||||
|
||||
int board_init(void)
|
||||
{
|
||||
/* adress of boot parameters */
|
||||
gd->bd->bi_boot_params = PHYS_SDRAM_1 + 0x100;
|
||||
|
||||
enable_caches();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -258,17 +258,6 @@ int board_late_init(void)
|
||||
val |= 0x80;
|
||||
mc9sdz60_reg_write(MC9SDZ60_REG_RESET_1, val);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int checkboard(void)
|
||||
{
|
||||
/*
|
||||
* Be sure that I2C is initialized to check
|
||||
* the board revision
|
||||
*/
|
||||
i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
|
||||
|
||||
/* Print board revision */
|
||||
printf("Board: MX35 PDK %d.0\n", ((get_board_rev() >> 8) + 1) & 0x0F);
|
||||
|
||||
|
||||
@@ -91,6 +91,6 @@ DATA 4 0x63fd901c 0x00028039
|
||||
DATA 4 0x63fd901c 0x05208138
|
||||
DATA 4 0x63fd901c 0x04008048
|
||||
DATA 4 0x63fd9020 0x00005800
|
||||
DATA 4 0x63fd9040 0x04b80003
|
||||
DATA 4 0x63fd9040 0x05380003
|
||||
DATA 4 0x63fd9058 0x00022227
|
||||
DATA 4 0x63fd901C 0x00000000
|
||||
|
||||
@@ -108,5 +108,5 @@ DATA 4 0x63fd901c 0x00448039
|
||||
DATA 4 0x63fd9020 0x00005800
|
||||
DATA 4 0x63fd9058 0x00033335
|
||||
DATA 4 0x63fd901c 0x00000000
|
||||
DATA 4 0x63fd9040 0x04b80003
|
||||
DATA 4 0x63fd9040 0x05380003
|
||||
DATA 4 0x53fa8004 0x00194005
|
||||
|
||||
@@ -91,6 +91,6 @@ DATA 4 0x63fd901c 0x00028039
|
||||
DATA 4 0x63fd901c 0x05208138
|
||||
DATA 4 0x63fd901c 0x04008048
|
||||
DATA 4 0x63fd9020 0x00005800
|
||||
DATA 4 0x63fd9040 0x04b80003
|
||||
DATA 4 0x63fd9040 0x05380003
|
||||
DATA 4 0x63fd9058 0x00022227
|
||||
DATA 4 0x63fd901c 0x00000000
|
||||
|
||||
@@ -91,6 +91,6 @@ DATA 4 0x63fd901c 0x00028039
|
||||
DATA 4 0x63fd901c 0x05208138
|
||||
DATA 4 0x63fd901c 0x04008048
|
||||
DATA 4 0x63fd9020 0x00005800
|
||||
DATA 4 0x63fd9040 0x04b80003
|
||||
DATA 4 0x63fd9040 0x05380003
|
||||
DATA 4 0x63fd9058 0x00022227
|
||||
DATA 4 0x63fd901C 0x00000000
|
||||
|
||||
@@ -165,3 +165,9 @@ DATA 4 0x020c4074 0x3FF00000
|
||||
DATA 4 0x020c4078 0x00FFF300
|
||||
DATA 4 0x020c407c 0x0F0000C3
|
||||
DATA 4 0x020c4080 0x000003FF
|
||||
|
||||
# enable AXI cache for VDOA/VPU/IPU
|
||||
DATA 4 0x020e0010 0xF00000FF
|
||||
# set IPU AXI-id0 Qos=0xf(bypass) AXI-id1 Qos=0x7
|
||||
DATA 4 0x020e0018 0x007F007F
|
||||
DATA 4 0x020e001c 0x007F007F
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
*
|
||||
* 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
|
||||
* 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
|
||||
@@ -34,16 +34,16 @@
|
||||
#include <netdev.h>
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
#define UART_PAD_CTRL (PAD_CTL_PKE | PAD_CTL_PUE | \
|
||||
PAD_CTL_PUS_100K_UP | PAD_CTL_SPEED_MED | \
|
||||
#define UART_PAD_CTRL (PAD_CTL_PKE | PAD_CTL_PUE | \
|
||||
PAD_CTL_PUS_100K_UP | PAD_CTL_SPEED_MED | \
|
||||
PAD_CTL_DSE_40ohm | PAD_CTL_SRE_FAST | PAD_CTL_HYS)
|
||||
|
||||
#define USDHC_PAD_CTRL (PAD_CTL_PKE | PAD_CTL_PUE | \
|
||||
PAD_CTL_PUS_47K_UP | PAD_CTL_SPEED_LOW | \
|
||||
#define USDHC_PAD_CTRL (PAD_CTL_PKE | PAD_CTL_PUE | \
|
||||
PAD_CTL_PUS_47K_UP | PAD_CTL_SPEED_LOW | \
|
||||
PAD_CTL_DSE_80ohm | PAD_CTL_SRE_FAST | PAD_CTL_HYS)
|
||||
|
||||
#define ENET_PAD_CTRL (PAD_CTL_PKE | PAD_CTL_PUE | \
|
||||
PAD_CTL_PUS_100K_UP | PAD_CTL_SPEED_MED | \
|
||||
PAD_CTL_PUS_100K_UP | PAD_CTL_SPEED_MED | \
|
||||
PAD_CTL_DSE_40ohm | PAD_CTL_HYS)
|
||||
|
||||
#define SPI_PAD_CTRL (PAD_CTL_HYS | \
|
||||
@@ -176,11 +176,11 @@ int board_mmc_getcd(struct mmc *mmc)
|
||||
int ret;
|
||||
|
||||
if (cfg->esdhc_base == USDHC3_BASE_ADDR) {
|
||||
gpio_direction_input(192); /*GPIO7_0*/
|
||||
ret = !gpio_get_value(192);
|
||||
gpio_direction_input(192); /*GPIO7_0*/
|
||||
ret = !gpio_get_value(192);
|
||||
} else {
|
||||
gpio_direction_input(38); /*GPIO2_6*/
|
||||
ret = !gpio_get_value(38);
|
||||
gpio_direction_input(38); /*GPIO2_6*/
|
||||
ret = !gpio_get_value(38);
|
||||
}
|
||||
|
||||
return ret;
|
||||
@@ -192,23 +192,23 @@ int board_mmc_init(bd_t *bis)
|
||||
u32 index = 0;
|
||||
|
||||
for (index = 0; index < CONFIG_SYS_FSL_USDHC_NUM; ++index) {
|
||||
switch (index) {
|
||||
case 0:
|
||||
imx_iomux_v3_setup_multiple_pads(
|
||||
usdhc3_pads, ARRAY_SIZE(usdhc3_pads));
|
||||
break;
|
||||
case 1:
|
||||
imx_iomux_v3_setup_multiple_pads(
|
||||
usdhc4_pads, ARRAY_SIZE(usdhc4_pads));
|
||||
break;
|
||||
default:
|
||||
printf("Warning: you configured more USDHC controllers"
|
||||
"(%d) then supported by the board (%d)\n",
|
||||
index + 1, CONFIG_SYS_FSL_USDHC_NUM);
|
||||
return status;
|
||||
}
|
||||
switch (index) {
|
||||
case 0:
|
||||
imx_iomux_v3_setup_multiple_pads(
|
||||
usdhc3_pads, ARRAY_SIZE(usdhc3_pads));
|
||||
break;
|
||||
case 1:
|
||||
imx_iomux_v3_setup_multiple_pads(
|
||||
usdhc4_pads, ARRAY_SIZE(usdhc4_pads));
|
||||
break;
|
||||
default:
|
||||
printf("Warning: you configured more USDHC controllers"
|
||||
"(%d) then supported by the board (%d)\n",
|
||||
index + 1, CONFIG_SYS_FSL_USDHC_NUM);
|
||||
return status;
|
||||
}
|
||||
|
||||
status |= fsl_esdhc_initialize(bis, &usdhc_cfg[index]);
|
||||
status |= fsl_esdhc_initialize(bis, &usdhc_cfg[index]);
|
||||
}
|
||||
|
||||
return status;
|
||||
@@ -250,7 +250,7 @@ int board_phy_config(struct phy_device *phydev)
|
||||
MII_KSZ9021_EXT_RGMII_CLOCK_SKEW, 0xf0f0);
|
||||
if (phydev->drv->config)
|
||||
phydev->drv->config(phydev);
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -185,7 +185,7 @@ CS0WCR_D: .long 0x00000B41
|
||||
CS0BCR_A: .long 0xFFFC0004
|
||||
CS0BCR_D: .long 0x10000400
|
||||
PJCR0_A: .long 0xFFFE390E
|
||||
PJCR0_D: .word 0x0300
|
||||
PJCR0_D: .word 0x3300
|
||||
.align 2
|
||||
CS2WCR_A: .long 0xFFFC0030
|
||||
CS2WCR_D: .long 0x00000B01
|
||||
|
||||
@@ -33,4 +33,5 @@ void onenand_board_init(struct mtd_info *mtd)
|
||||
|
||||
this->base = (void *)CONFIG_SYS_ONENAND_BASE;
|
||||
this->options |= ONENAND_RUNTIME_BADBLOCK_CHECK;
|
||||
this->chip_probe = s5pc110_chip_probe;
|
||||
}
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
#include <common.h>
|
||||
#include <linux/mtd/mtd.h>
|
||||
#include <linux/mtd/onenand.h>
|
||||
#include <linux/mtd/samsung_onenand.h>
|
||||
|
||||
void onenand_board_init(struct mtd_info *mtd)
|
||||
{
|
||||
@@ -31,4 +32,5 @@ void onenand_board_init(struct mtd_info *mtd)
|
||||
|
||||
this->base = (void *)CONFIG_SYS_ONENAND_BASE;
|
||||
this->options |= ONENAND_RUNTIME_BADBLOCK_CHECK;
|
||||
this->chip_probe = s5pc210_chip_probe;
|
||||
}
|
||||
|
||||
@@ -507,58 +507,3 @@ int ehci_hcd_stop(void)
|
||||
}
|
||||
|
||||
#endif /* CONFIG_USB_EHCI */
|
||||
|
||||
#ifndef CONFIG_SPL_BUILD
|
||||
/*
|
||||
* This command returns the status of the user button on beagle xM
|
||||
* Input - none
|
||||
* Returns - 1 if button is held down
|
||||
* 0 if button is not held down
|
||||
*/
|
||||
int do_userbutton(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
|
||||
{
|
||||
int button = 0;
|
||||
int gpio;
|
||||
|
||||
/*
|
||||
* pass address parameter as argv[0] (aka command name),
|
||||
* and all remaining args
|
||||
*/
|
||||
switch (get_board_revision()) {
|
||||
case REVISION_AXBX:
|
||||
case REVISION_CX:
|
||||
case REVISION_C4:
|
||||
gpio = 7;
|
||||
break;
|
||||
case REVISION_XM_A:
|
||||
case REVISION_XM_B:
|
||||
case REVISION_XM_C:
|
||||
default:
|
||||
gpio = 4;
|
||||
break;
|
||||
}
|
||||
gpio_request(gpio, "");
|
||||
gpio_direction_input(gpio);
|
||||
printf("The user button is currently ");
|
||||
if (gpio_get_value(gpio))
|
||||
{
|
||||
button = 1;
|
||||
printf("PRESSED.\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
button = 0;
|
||||
printf("NOT pressed.\n");
|
||||
}
|
||||
|
||||
return !button;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
|
||||
U_BOOT_CMD(
|
||||
userbutton, CONFIG_SYS_MAXARGS, 1, do_userbutton,
|
||||
"Return the status of the BeagleBoard USER button",
|
||||
""
|
||||
);
|
||||
#endif
|
||||
|
||||
@@ -21,8 +21,10 @@
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
# MA 02111-1307 USA
|
||||
#
|
||||
# CAUTION: This file is automatically generated by libgen.
|
||||
# Version: Xilinx EDK 6.3 EDK_Gmm.12.3
|
||||
# CAUTION: This file is a faked configuration !!!
|
||||
# There is no real target for the microblaze-generic
|
||||
# configuration. You have to replace this file with
|
||||
# the generated file from your Xilinx design flow.
|
||||
#
|
||||
|
||||
CONFIG_SYS_TEXT_BASE = 0x29000000
|
||||
|
||||
@@ -90,5 +90,41 @@ int board_eth_init(bd_t *bis)
|
||||
ret |= xilinx_emaclite_initialize(bis, XILINX_EMACLITE_BASEADDR,
|
||||
txpp, rxpp);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_XILINX_LL_TEMAC
|
||||
# ifdef XILINX_LLTEMAC_BASEADDR
|
||||
# ifdef XILINX_LLTEMAC_FIFO_BASEADDR
|
||||
ret |= xilinx_ll_temac_eth_init(bis, XILINX_LLTEMAC_BASEADDR,
|
||||
XILINX_LL_TEMAC_M_FIFO, XILINX_LLTEMAC_FIFO_BASEADDR);
|
||||
# elif XILINX_LLTEMAC_SDMA_CTRL_BASEADDR
|
||||
# if XILINX_LLTEMAC_SDMA_USE_DCR == 1
|
||||
ret |= xilinx_ll_temac_eth_init(bis, XILINX_LLTEMAC_BASEADDR,
|
||||
XILINX_LL_TEMAC_M_SDMA_DCR,
|
||||
XILINX_LLTEMAC_SDMA_CTRL_BASEADDR);
|
||||
# else
|
||||
ret |= xilinx_ll_temac_eth_init(bis, XILINX_LLTEMAC_BASEADDR,
|
||||
XILINX_LL_TEMAC_M_SDMA_PLB,
|
||||
XILINX_LLTEMAC_SDMA_CTRL_BASEADDR);
|
||||
# endif
|
||||
# endif
|
||||
# endif
|
||||
# ifdef XILINX_LLTEMAC_BASEADDR1
|
||||
# ifdef XILINX_LLTEMAC_FIFO_BASEADDR1
|
||||
ret |= xilinx_ll_temac_eth_init(bis, XILINX_LLTEMAC_BASEADDR1,
|
||||
XILINX_LL_TEMAC_M_FIFO, XILINX_LLTEMAC_FIFO_BASEADDR1);
|
||||
# elif XILINX_LLTEMAC_SDMA_CTRL_BASEADDR1
|
||||
# if XILINX_LLTEMAC_SDMA_USE_DCR == 1
|
||||
ret |= xilinx_ll_temac_eth_init(bis, XILINX_LLTEMAC_BASEADDR1,
|
||||
XILINX_LL_TEMAC_M_SDMA_DCR,
|
||||
XILINX_LLTEMAC_SDMA_CTRL_BASEADDR1);
|
||||
# else
|
||||
ret |= xilinx_ll_temac_eth_init(bis, XILINX_LLTEMAC_BASEADDR1,
|
||||
XILINX_LL_TEMAC_M_SDMA_PLB,
|
||||
XILINX_LLTEMAC_SDMA_CTRL_BASEADDR1);
|
||||
# endif
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -21,8 +21,10 @@
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
* MA 02111-1307 USA
|
||||
*
|
||||
* CAUTION: This file is automatically generated by libgen.
|
||||
* Version: Xilinx EDK 8.2.02 EDK_Im_Sp2.4
|
||||
* CAUTION: This file is a faked configuration !!!
|
||||
* There is no real target for the microblaze-generic
|
||||
* configuration. You have to replace this file with
|
||||
* the generated file from your Xilinx design flow.
|
||||
*/
|
||||
|
||||
#define XILINX_BOARD_NAME microblaze-generic
|
||||
@@ -69,3 +71,9 @@
|
||||
|
||||
/* Ethernet controller is Ethernet_MAC */
|
||||
#define XILINX_EMACLITE_BASEADDR 0x40C00000
|
||||
|
||||
/* LL_TEMAC Ethernet controller */
|
||||
#define XILINX_LLTEMAC_BASEADDR 0x44000000
|
||||
#define XILINX_LLTEMAC_SDMA_CTRL_BASEADDR 0x42000180
|
||||
#define XILINX_LLTEMAC_BASEADDR1 0x44200000
|
||||
#define XILINX_LLTEMAC_FIFO_BASEADDR1 0x42100000
|
||||
|
||||
@@ -360,7 +360,7 @@ dbau1000 mips mips32 dbau1x00 -
|
||||
dbau1100 mips mips32 dbau1x00 - au1x00 dbau1x00:DBAU1100
|
||||
dbau1500 mips mips32 dbau1x00 - au1x00 dbau1x00:DBAU1500
|
||||
dbau1550 mips mips32 dbau1x00 - au1x00 dbau1x00:DBAU1550
|
||||
dbau1550_el mips mips32 dbau1x00 - au1x00 dbau1x00:DBAU1550
|
||||
dbau1550_el mips mips32 dbau1x00 - au1x00 dbau1x00:DBAU1550,SYS_LITTLE_ENDIAN
|
||||
gth2 mips mips32 - - au1x00
|
||||
pb1000 mips mips32 pb1x00 - au1x00 pb1x00:PB1000
|
||||
incaip mips mips32 incaip - incaip
|
||||
|
||||
@@ -156,3 +156,20 @@ void bootstage_report(void)
|
||||
"- please increase CONFIG_BOOTSTAGE_USER_COUNT\n",
|
||||
next_id - BOOTSTAGE_ID_COUNT);
|
||||
}
|
||||
|
||||
ulong __timer_get_boot_us(void)
|
||||
{
|
||||
static ulong base_time;
|
||||
|
||||
/*
|
||||
* We can't implement this properly. Return 0 on the first call and
|
||||
* larger values after that.
|
||||
*/
|
||||
if (base_time)
|
||||
return get_timer(base_time) * 1000;
|
||||
base_time = get_timer(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
ulong timer_get_boot_us(void)
|
||||
__attribute__((weak, alias("__timer_get_boot_us")));
|
||||
|
||||
@@ -186,6 +186,7 @@ static void boot_start_lmb(bootm_headers_t *images)
|
||||
board_lmb_reserve(&images->lmb);
|
||||
}
|
||||
#else
|
||||
#define lmb_reserve(lmb, base, size)
|
||||
static inline void boot_start_lmb(bootm_headers_t *images) { }
|
||||
#endif
|
||||
|
||||
|
||||
219
doc/README.m28
219
doc/README.m28
@@ -1,224 +1,13 @@
|
||||
DENX M28EVK
|
||||
===========
|
||||
|
||||
This document describes the DENX M28/M28EVK U-Boot port. This document mostly
|
||||
covers topics related to making the module/board bootable.
|
||||
|
||||
Terminology
|
||||
-----------
|
||||
|
||||
The dollar symbol ($) introduces a snipped of shell code. This shall be typed
|
||||
into the unix command prompt in U-Boot source code root directory.
|
||||
|
||||
The (=>) introduces a snipped of code that should by typed into U-Boot command
|
||||
prompt.
|
||||
|
||||
Contents
|
||||
--------
|
||||
|
||||
0) Files of the M28/M28EVK port
|
||||
1) Prerequisites
|
||||
2) Compiling U-Boot for M28
|
||||
3) Installation of U-Boot for M28EVK to SD card
|
||||
4) Installation of U-Boot for M28 to NAND flash
|
||||
|
||||
0) Files of the M28/M28EVK port
|
||||
-------------------------------
|
||||
Files of the M28/M28EVK port
|
||||
----------------------------
|
||||
|
||||
arch/arm/cpu/arm926ejs/mx28/ - The CPU support code for the Freescale i.MX28
|
||||
arch/arm/include/asm/arch-mx28/ - Header files for the Freescale i.MX28
|
||||
board/denx/m28evk/ - M28EVK board specific files
|
||||
include/configs/m28evk.h - M28EVK configuration file
|
||||
|
||||
1) Prerequisites
|
||||
----------------
|
||||
|
||||
To make the M28 module or the M28 module or M28EVK board bootable, some tools
|
||||
are necessary. The first one is the "elftosb" tool distributed by Freescale
|
||||
Semiconductor. The other tool is the "mxsboot" tool found in U-Boot source tree.
|
||||
|
||||
Firstly, obtain the elftosb archive from the following location:
|
||||
|
||||
http://foss.doredevelopment.dk/mirrors/imx/elftosb-10.12.01.tar.gz
|
||||
|
||||
We use a $VER variable here to denote the current version. At the time of
|
||||
writing of this document, that is "10.12.01". To obtain the file from command
|
||||
line, use:
|
||||
|
||||
$ VER="10.12.01"
|
||||
$ wget http://foss.doredevelopment.dk/mirrors/imx/elftosb-${VER}.tar.gz
|
||||
|
||||
Extract the file:
|
||||
|
||||
$ tar xzf elftosb-${VER}.tar.gz
|
||||
|
||||
Compile the file. We need to manually tell the linker to use also libm:
|
||||
|
||||
$ cd elftosb-${VER}/
|
||||
$ make LIBS="-lstdc++ -lm" elftosb
|
||||
|
||||
Optionally, remove debugging symbols from elftosb:
|
||||
|
||||
$ strip bld/linux/elftosb
|
||||
|
||||
Finally, install the "elftosb" binary. The "install" target is missing, so just
|
||||
copy the binary by hand:
|
||||
|
||||
$ sudo cp bld/linux/elftosb /usr/local/bin/
|
||||
|
||||
Make sure the "elftosb" binary can be found in your $PATH, in this case this
|
||||
means "/usr/local/bin/" has to be in your $PATH.
|
||||
|
||||
2) Compiling U-Boot for M28
|
||||
---------------------------
|
||||
|
||||
Compiling the U-Boot for M28 is straightforward and done as compiling U-Boot
|
||||
for any other ARM device. For cross-compiler setup, please refer to ELDK5.0
|
||||
documentation. First, clean up the source code:
|
||||
|
||||
$ make mrproper
|
||||
|
||||
Next, configure U-Boot for M28EVK:
|
||||
|
||||
$ make m28evk_config
|
||||
|
||||
Lastly, compile U-Boot and prepare a "BootStream". The "BootStream" is a special
|
||||
type of file, which the i.MX28 CPU can boot. This is handled by the following
|
||||
command:
|
||||
|
||||
$ make u-boot.sb
|
||||
|
||||
HINT: To speed-up the build process, you can add -j<N>, where N is number of
|
||||
compiler instances that'll run in parallel.
|
||||
|
||||
The code produces "u-boot.sb" file. This file needs to be augmented with a
|
||||
proper header to allow successful boot from SD or NAND. Adding the header is
|
||||
discussed in the following chapters.
|
||||
|
||||
3) Installation of U-Boot for M28EVK to SD card
|
||||
-----------------------------------------------
|
||||
|
||||
To boot an M28 from SD, set the boot mode DIP switches according to i.MX28
|
||||
manual chapter 12.2.1 (Table 12-2), PORT=SSP0, SD/MMC master on SSP0, 3.3V.
|
||||
|
||||
An SD card the i.MX28 CPU can use to boot U-Boot must contain a DOS partition
|
||||
table, which in turn carries a partition of special type and which contains a
|
||||
special header. The rest of partitions in the DOS partition table can be used
|
||||
by the user.
|
||||
|
||||
To prepare such partition, use your favourite partitioning tool. The partition
|
||||
must have the following parameters:
|
||||
|
||||
* Start sector .......... sector 2048
|
||||
* Partition size ........ at least 1024 kb
|
||||
* Partition type ........ 0x53 (sometimes "OnTrack DM6 Aux3")
|
||||
|
||||
For example in Linux fdisk, the sequence for a clear card follows. Be sure to
|
||||
run fdisk with the option "-u=sectors" to set units to sectors:
|
||||
|
||||
* o ..................... create a clear partition table
|
||||
* n ..................... create new partition
|
||||
* p ............. primary partition
|
||||
* 1 ............. first partition
|
||||
* 2048 .......... first sector is 2048
|
||||
* +1M ........... make the partition 1Mb big
|
||||
* t 1 ................... change first partition ID
|
||||
* 53 ............ change the ID to 0x53 (OnTrack DM6 Aux3)
|
||||
* <create other partitions>
|
||||
* w ..................... write partition table to disk
|
||||
|
||||
The partition layout is ready, next the special partition must be filled with
|
||||
proper contents. The contents is generated by running the following command (see
|
||||
chapter 2)):
|
||||
|
||||
$ ./tools/mxsboot sd u-boot.sb u-boot.sd
|
||||
|
||||
The resulting file, "u-boot.sd", shall then be written to the partition. In this
|
||||
case, we assume the first partition of the SD card is /dev/mmcblk0p1:
|
||||
|
||||
$ dd if=u-boot.sd of=/dev/mmcblk0p1
|
||||
|
||||
Last step is to insert the card into M28EVK and boot.
|
||||
|
||||
NOTE: If the user needs to adjust the start sector, the "mxsboot" tool contains
|
||||
a "-p" switch for that purpose. The "-p" switch takes the sector number as
|
||||
an argument.
|
||||
|
||||
4) Installation of U-Boot for M28 to NAND flash
|
||||
-----------------------------------------------
|
||||
|
||||
To boot an M28 from NAND, set the boot mode DIP switches according to i.MX28
|
||||
manual chapter 12.2.1 (Table 12-2), PORT=GPMI, NAND 1.8 V.
|
||||
|
||||
There are two possibilities when preparing an image writable to NAND flash.
|
||||
|
||||
I) The NAND wasn't written at all yet or the BCB is broken
|
||||
----------------------------------------------------------
|
||||
In this case, both BCB (FCB and DBBT) and firmware needs to be
|
||||
written to NAND. To generate NAND image containing all these,
|
||||
there is a tool called "mxsboot" in the "tools/" directory. The tool
|
||||
is invoked on "u-boot.sb" file from chapter 2):
|
||||
|
||||
$ ./tools/mxsboot nand u-boot.sb u-boot.nand
|
||||
|
||||
NOTE: The above invokation works for NAND flash with geometry of
|
||||
2048b per page, 64b OOB data, 128kb erase size. If your chip
|
||||
has a different geometry, please use:
|
||||
|
||||
-w <size> change page size (default 2048 b)
|
||||
-o <size> change oob size (default 64 b)
|
||||
-e <size> change erase size (default 131072 b)
|
||||
|
||||
The geometry information can be obtained from running U-Boot
|
||||
on M28 by issuing the "nand info" command.
|
||||
|
||||
The resulting file, "u-boot.nand" can be written directly to NAND
|
||||
from the U-Boot prompt. To simplify the process, the U-Boot default
|
||||
environment contains script "update_nand_full" to update the system.
|
||||
|
||||
This script expects a working TFTP server containing the file
|
||||
"u-boot.nand" in it's root directory. This can be changed by
|
||||
adjusting the "update_nand_full_filename" varible.
|
||||
|
||||
To update the system, run the following in U-Boot prompt:
|
||||
|
||||
=> run update_nand_full
|
||||
|
||||
In case you would only need to update the bootloader in future,
|
||||
see II) below.
|
||||
|
||||
II) The NAND was already written with a good BCB
|
||||
------------------------------------------------
|
||||
This part applies after the part I) above was done at least once.
|
||||
|
||||
If part I) above was done correctly already, there is no need to
|
||||
write the FCB and DBBT parts of NAND again. It's possible to upgrade
|
||||
only the bootloader image.
|
||||
|
||||
To simplify the process of firmware update, the U-Boot default
|
||||
environment contains script "update_nand_firmware" to update only
|
||||
the firmware, without rewriting FCB and DBBT.
|
||||
|
||||
This script expects a working TFTP server containing the file
|
||||
"u-boot.sb" in it's root directory. This can be changed by
|
||||
adjusting the "update_nand_firmware_filename" varible.
|
||||
|
||||
To update the system, run the following in U-Boot prompt:
|
||||
|
||||
=> run update_nand_firmware
|
||||
|
||||
III) Special settings for the update scripts
|
||||
--------------------------------------------
|
||||
There is a slight possibility of the user wanting to adjust the
|
||||
STRIDE and COUNT options of the NAND boot. For description of these,
|
||||
see i.MX28 manual section 12.12.1.2 and 12.12.1.3.
|
||||
|
||||
The update scripts take this possibility into account. In case the
|
||||
user changes STRIDE by blowing fuses, the user also has to change
|
||||
"update_nand_stride" variable. In case the user changes COUNT by
|
||||
blowing fuses, the user also has to change "update_nand_count"
|
||||
variable for the update scripts to work correctly.
|
||||
|
||||
In case the user needs to boot a firmware image bigger than 1Mb, the
|
||||
user has to adjust the "update_nand_firmware_maxsz" variable for the
|
||||
update scripts to work properly.
|
||||
Follow the instructions from doc/README.mx28_common to generate a bootable SD
|
||||
card or to boot from NAND flash.
|
||||
|
||||
226
doc/README.mx28_common
Normal file
226
doc/README.mx28_common
Normal file
@@ -0,0 +1,226 @@
|
||||
Booting U-boot on a MX28 processor
|
||||
==================================
|
||||
|
||||
This document describes the MX28 U-Boot port. This document mostly
|
||||
covers topics related to making the module/board bootable.
|
||||
|
||||
Terminology
|
||||
-----------
|
||||
|
||||
The dollar symbol ($) introduces a snipped of shell code. This shall be typed
|
||||
into the unix command prompt in U-Boot source code root directory.
|
||||
|
||||
The (=>) introduces a snipped of code that should by typed into U-Boot command
|
||||
prompt
|
||||
|
||||
Contents
|
||||
--------
|
||||
|
||||
1) Prerequisites
|
||||
2) Compiling U-Boot for a MX28 based board
|
||||
3) Installation of U-Boot for a MX28 based board to SD card
|
||||
|
||||
1) Prerequisites
|
||||
----------------
|
||||
|
||||
To make a MX28 based board bootable, some tools are necessary. The first one
|
||||
is the "elftosb" tool distributed by Freescale Semiconductor. The other one
|
||||
is the "mxsboot" tool found in U-Boot source tree.
|
||||
|
||||
Firstly, obtain the elftosb archive from the following location:
|
||||
|
||||
http://foss.doredevelopment.dk/mirrors/imx/elftosb-10.12.01.tar.gz
|
||||
|
||||
We use a $VER variable here to denote the current version. At the time of
|
||||
writing of this document, that is "10.12.01". To obtain the file from command
|
||||
line, use:
|
||||
|
||||
$ VER="10.12.01"
|
||||
$ wget http://foss.doredevelopment.dk/mirrors/imx/elftosb-${VER}.tar.gz
|
||||
|
||||
Extract the file:
|
||||
|
||||
$ tar xzf elftosb-${VER}.tar.gz
|
||||
|
||||
Compile the file. We need to manually tell the linker to use also libm:
|
||||
|
||||
$ cd elftosb-${VER}/
|
||||
$ make LIBS="-lstdc++ -lm" elftosb
|
||||
|
||||
Optionally, remove debugging symbols from elftosb:
|
||||
|
||||
$ strip bld/linux/elftosb
|
||||
|
||||
Finally, install the "elftosb" binary. The "install" target is missing, so just
|
||||
copy the binary by hand:
|
||||
|
||||
$ sudo cp bld/linux/elftosb /usr/local/bin/
|
||||
|
||||
Make sure the "elftosb" binary can be found in your $PATH, in this case this
|
||||
means "/usr/local/bin/" has to be in your $PATH.
|
||||
|
||||
2) Compiling U-Boot for a MX28 based board
|
||||
-------------------------------------------
|
||||
|
||||
Compiling the U-Boot for a MX28 board is straightforward and done as compiling U-Boot
|
||||
for any other ARM device. For cross-compiler setup, please refer to ELDK5.0
|
||||
documentation. First, clean up the source code:
|
||||
|
||||
$ make mrproper
|
||||
|
||||
Next, configure U-Boot for a MX28 based board
|
||||
|
||||
$ make <mx28_based_board_name>_config
|
||||
|
||||
Examples:
|
||||
|
||||
1. For building U-boot for Denx M28EVK board:
|
||||
|
||||
$ make m28evk_config
|
||||
|
||||
2. For building U-boot for Freescale MX28EVK board:
|
||||
|
||||
$ make mx28evk_config
|
||||
|
||||
Lastly, compile U-Boot and prepare a "BootStream". The "BootStream" is a special
|
||||
type of file, which the i.MX28 CPU can boot. This is handled by the following
|
||||
command:
|
||||
|
||||
$ make u-boot.sb
|
||||
|
||||
HINT: To speed-up the build process, you can add -j<N>, where N is number of
|
||||
compiler instances that'll run in parallel.
|
||||
|
||||
The code produces "u-boot.sb" file. This file needs to be augmented with a
|
||||
proper header to allow successful boot from SD or NAND. Adding the header is
|
||||
discussed in the following chapters.
|
||||
|
||||
3) Installation of U-Boot for a MX28 based board to SD card
|
||||
-----------------------------------------------------------
|
||||
|
||||
To boot a MX28 based board from SD, set the boot mode DIP switches according
|
||||
to i.MX28 manual chapter 12.2.1 (Table 12-2), PORT=SSP0, SD/MMC master on
|
||||
SSP0, 3.3V.
|
||||
|
||||
|
||||
An SD card the i.MX28 CPU can use to boot U-Boot must contain a DOS partition
|
||||
table, which in turn carries a partition of special type and which contains a
|
||||
special header. The rest of partitions in the DOS partition table can be used
|
||||
by the user.
|
||||
|
||||
To prepare such partition, use your favourite partitioning tool. The partition
|
||||
must have the following parameters:
|
||||
|
||||
* Start sector .......... sector 2048
|
||||
* Partition size ........ at least 1024 kb
|
||||
* Partition type ........ 0x53 (sometimes "OnTrack DM6 Aux3")
|
||||
|
||||
For example in Linux fdisk, the sequence for a clear card follows. Be sure to
|
||||
run fdisk with the option "-u=sectors" to set units to sectors:
|
||||
|
||||
* o ..................... create a clear partition table
|
||||
* n ..................... create new partition
|
||||
* p ............. primary partition
|
||||
* 1 ............. first partition
|
||||
* 2048 .......... first sector is 2048
|
||||
* +1M ........... make the partition 1Mb big
|
||||
* t 1 ................... change first partition ID
|
||||
* 53 ............ change the ID to 0x53 (OnTrack DM6 Aux3)
|
||||
* <create other partitions>
|
||||
* w ..................... write partition table to disk
|
||||
|
||||
The partition layout is ready, next the special partition must be filled with
|
||||
proper contents. The contents is generated by running the following command
|
||||
(see chapter 2)):
|
||||
|
||||
$ ./tools/mxsboot sd u-boot.sb u-boot.sd
|
||||
|
||||
The resulting file, "u-boot.sd", shall then be written to the partition. In this
|
||||
case, we assume the first partition of the SD card is /dev/mmcblk0p1:
|
||||
|
||||
$ dd if=u-boot.sd of=/dev/mmcblk0p1
|
||||
|
||||
Last step is to insert the card into MX28 based board and boot.
|
||||
|
||||
NOTE: If the user needs to adjust the start sector, the "mxsboot" tool contains
|
||||
a "-p" switch for that purpose. The "-p" switch takes the sector number as
|
||||
an argument.
|
||||
|
||||
4) Installation of U-Boot for NAND flash
|
||||
-----------------------------------------------
|
||||
|
||||
To boot a MX28 based board from NAND, set the boot mode DIP switches according to i.MX28
|
||||
manual chapter 12.2.1 (Table 12-2), PORT=GPMI, NAND 1.8 V.
|
||||
|
||||
There are two possibilities when preparing an image writable to NAND flash.
|
||||
|
||||
I) The NAND wasn't written at all yet or the BCB is broken
|
||||
----------------------------------------------------------
|
||||
In this case, both BCB (FCB and DBBT) and firmware needs to be
|
||||
written to NAND. To generate NAND image containing all these,
|
||||
there is a tool called "mxsboot" in the "tools/" directory. The tool
|
||||
is invoked on "u-boot.sb" file from chapter 2):
|
||||
|
||||
$ ./tools/mxsboot nand u-boot.sb u-boot.nand
|
||||
|
||||
NOTE: The above invokation works for NAND flash with geometry of
|
||||
2048b per page, 64b OOB data, 128kb erase size. If your chip
|
||||
has a different geometry, please use:
|
||||
|
||||
-w <size> change page size (default 2048 b)
|
||||
-o <size> change oob size (default 64 b)
|
||||
-e <size> change erase size (default 131072 b)
|
||||
|
||||
The geometry information can be obtained from running U-Boot
|
||||
on the MX28 board by issuing the "nand info" command.
|
||||
|
||||
The resulting file, "u-boot.nand" can be written directly to NAND
|
||||
from the U-Boot prompt. To simplify the process, the U-Boot default
|
||||
environment contains script "update_nand_full" to update the system.
|
||||
|
||||
This script expects a working TFTP server containing the file
|
||||
"u-boot.nand" in it's root directory. This can be changed by
|
||||
adjusting the "update_nand_full_filename" varible.
|
||||
|
||||
To update the system, run the following in U-Boot prompt:
|
||||
|
||||
=> run update_nand_full
|
||||
|
||||
In case you would only need to update the bootloader in future,
|
||||
see II) below.
|
||||
|
||||
II) The NAND was already written with a good BCB
|
||||
------------------------------------------------
|
||||
This part applies after the part I) above was done at least once.
|
||||
|
||||
If part I) above was done correctly already, there is no need to
|
||||
write the FCB and DBBT parts of NAND again. It's possible to upgrade
|
||||
only the bootloader image.
|
||||
|
||||
To simplify the process of firmware update, the U-Boot default
|
||||
environment contains script "update_nand_firmware" to update only
|
||||
the firmware, without rewriting FCB and DBBT.
|
||||
|
||||
This script expects a working TFTP server containing the file
|
||||
"u-boot.sb" in it's root directory. This can be changed by
|
||||
adjusting the "update_nand_firmware_filename" varible.
|
||||
|
||||
To update the system, run the following in U-Boot prompt:
|
||||
|
||||
=> run update_nand_firmware
|
||||
|
||||
III) Special settings for the update scripts
|
||||
--------------------------------------------
|
||||
There is a slight possibility of the user wanting to adjust the
|
||||
STRIDE and COUNT options of the NAND boot. For description of these,
|
||||
see i.MX28 manual section 12.12.1.2 and 12.12.1.3.
|
||||
|
||||
The update scripts take this possibility into account. In case the
|
||||
user changes STRIDE by blowing fuses, the user also has to change
|
||||
"update_nand_stride" variable. In case the user changes COUNT by
|
||||
blowing fuses, the user also has to change "update_nand_count"
|
||||
variable for the update scripts to work correctly.
|
||||
|
||||
In case the user needs to boot a firmware image bigger than 1Mb, the
|
||||
user has to adjust the "update_nand_firmware_maxsz" variable for the
|
||||
update scripts to work properly.
|
||||
29
doc/README.mx28evk
Normal file
29
doc/README.mx28evk
Normal file
@@ -0,0 +1,29 @@
|
||||
FREESCALE MX28EVK
|
||||
==================
|
||||
|
||||
Supported hardware: only MX28EVK rev D is supported in U-boot.
|
||||
|
||||
Files of the MX28EVK port
|
||||
--------------------------
|
||||
|
||||
arch/arm/cpu/arm926ejs/mx28/ - The CPU support code for the Freescale i.MX28
|
||||
arch/arm/include/asm/arch-mx28/ - Header files for the Freescale i.MX28
|
||||
board/freescale/mx28evk/ - MX28EVK board specific files
|
||||
include/configs/mx28evk.h - MX28EVK configuration file
|
||||
|
||||
Jumper configuration
|
||||
---------------------
|
||||
|
||||
To boot MX28EVK from an SD card, set the boot mode DIP switches as:
|
||||
|
||||
* Boot Mode Select: 1 0 0 1 (Boot from SD card Slot 0 - U42)
|
||||
* JTAG PSWITCH RESET: To the left (reset enabled)
|
||||
* Battery Source: Down
|
||||
* Wall 5V: Up
|
||||
* VDD 5V: To the left (off)
|
||||
* Hold Button: Down (off)
|
||||
|
||||
Follow the instructions from doc/README.mx28_common to generate a bootable SD
|
||||
card.
|
||||
|
||||
Insert the SD card in slot 0, power up the board and U-boot will boot.
|
||||
@@ -31,7 +31,8 @@ Note: Replace sXx with the device representing the SD card in your system.
|
||||
Note: This writes SD card loader at address 0
|
||||
|
||||
2. Put this SD card into the slot for the large SD card (SD3 on the bottom of
|
||||
the board)
|
||||
the board). Make sure SW1 switch is at position "00", so that it can boot
|
||||
from the fuses.
|
||||
|
||||
3. Power-up the SabreLite, press 'space' to enter command mode in the U-Boot
|
||||
(the default one the board is shipped with, starting from the SPI NOR) and
|
||||
|
||||
@@ -23,7 +23,7 @@ of each choice are listed below.
|
||||
|
||||
Choice #1 does not enable CONFIG_PCI, and assumes that the PCI slot
|
||||
will be left empty (M66EN high), and so the board will operate with
|
||||
a base clock of 66MHz. Note that you need both PCI enabled in u-boot
|
||||
a base clock of 66MHz. Note that you need both PCI enabled in u-boot
|
||||
and linux in order to have functional PCI under linux.
|
||||
|
||||
The second enables PCI support and builds for a 33MHz clock rate. Note
|
||||
@@ -37,29 +37,29 @@ card. [The above discussion assumes that the SW2[1-4] has not been changed
|
||||
to reflect a different CCB:SYSCLK ratio]
|
||||
|
||||
The third option builds PCI support in, and leaves the clocking at the
|
||||
default 66MHz. Options four and five are just repeats of option two
|
||||
default 66MHz. Options four and five are just repeats of option two
|
||||
and three, but with PCI-e support enabled as well.
|
||||
|
||||
PCI output listing with an intel e1000 PCI-x and a Syskonnect SK-9Exx
|
||||
is shown below for sbc8548_PCI_66_PCIE_config. (Note that PCI-e with
|
||||
is shown below for sbc8548_PCI_66_PCIE_config. (Note that PCI-e with
|
||||
a 33MHz PCI configuration is currently untested.)
|
||||
|
||||
=> pci 0
|
||||
Scanning PCI devices on bus 0
|
||||
BusDevFun VendorId DeviceId Device Class Sub-Class
|
||||
BusDevFun VendorId DeviceId Device Class Sub-Class
|
||||
_____________________________________________________________
|
||||
00.00.00 0x1057 0x0012 Processor 0x20
|
||||
00.01.00 0x8086 0x1026 Network controller 0x00
|
||||
00.00.00 0x1057 0x0012 Processor 0x20
|
||||
00.01.00 0x8086 0x1026 Network controller 0x00
|
||||
=> pci 1
|
||||
Scanning PCI devices on bus 1
|
||||
BusDevFun VendorId DeviceId Device Class Sub-Class
|
||||
BusDevFun VendorId DeviceId Device Class Sub-Class
|
||||
_____________________________________________________________
|
||||
01.00.00 0x1957 0x0012 Processor 0x20
|
||||
01.00.00 0x1957 0x0012 Processor 0x20
|
||||
=> pci 2
|
||||
Scanning PCI devices on bus 2
|
||||
BusDevFun VendorId DeviceId Device Class Sub-Class
|
||||
BusDevFun VendorId DeviceId Device Class Sub-Class
|
||||
_____________________________________________________________
|
||||
02.00.00 0x1148 0x9e00 Network controller 0x00
|
||||
02.00.00 0x1148 0x9e00 Network controller 0x00
|
||||
=>
|
||||
|
||||
Memory Size and using SPD:
|
||||
@@ -80,10 +80,10 @@ You can also visually inspect the board to see if this hardware
|
||||
fix has been applied:
|
||||
|
||||
1) Remove R314 (RES-R0174-033, 1K, 0603). R314 is located on
|
||||
the back of the PCB behind the DDR SDRAM SODIMM connector.
|
||||
the back of the PCB behind the DDR SDRAM SODIMM connector.
|
||||
2) Solder RES-R0174-033 (1K, 0603) resistor from R314 pin 2 pad
|
||||
to R313 pin 2. Pin 2 for each resistor is the end of the
|
||||
resistor closest to the CPU.
|
||||
to R313 pin 2. Pin 2 for each resistor is the end of the
|
||||
resistor closest to the CPU.
|
||||
|
||||
Boards without the mod will have R314 and R313 in parallel, like "||".
|
||||
After the mod, they will be touching and form an "L" shape.
|
||||
@@ -155,7 +155,7 @@ Hardware Reference:
|
||||
===================
|
||||
|
||||
The following contains some summary information on hardware settings
|
||||
that are relevant to u-boot, based on the board manual. For the
|
||||
that are relevant to u-boot, based on the board manual. For the
|
||||
most up to date and complete details of the board, please request the
|
||||
reference manual ERG-00327-001.pdf from www.windriver.com
|
||||
|
||||
|
||||
@@ -4,10 +4,10 @@ Added in U-Boot:
|
||||
|
||||
Required properties:
|
||||
- clocks : Two clocks must be given, each as a phandle to the Tegra's
|
||||
CAR node and the clock number as a parameter:
|
||||
CAR node and the clock number as a parameter:
|
||||
- the I2C clock to use for the peripheral
|
||||
- the pll_p_out3 clock, which can be used for fast operation. This
|
||||
does not change and is the same for all I2C nodes.
|
||||
does not change and is the same for all I2C nodes.
|
||||
|
||||
Example:
|
||||
(TODO: merge with existing example):
|
||||
|
||||
@@ -18,6 +18,7 @@ alias gruss Graeme Russ <graeme.russ@gmail.com>
|
||||
alias hs Heiko Schocher <hs@denx.de>
|
||||
alias iwamatsu Nobuhiro Iwamatsu <iwamatsu@nigauri.org>
|
||||
alias jasonjin Jason Jin <jason.jin@freescale.com>
|
||||
alias jhersh Joe Hershberger <joe.hershberger@gmail.com>
|
||||
alias kimphill Kim Phillips <kim.phillips@freescale.com>
|
||||
alias macpaul Macpaul Lin <macpaul@andestech.com>
|
||||
alias marex Marek Vasut <marek.vasut@gmail.com>
|
||||
@@ -97,6 +98,6 @@ alias fdt uboot, Jerry Van Baren <vanbaren@cideas.com>
|
||||
alias i2c uboot, hs
|
||||
alias mmc uboot, afleming
|
||||
alias nand uboot, scottwood
|
||||
alias net uboot, wd
|
||||
alias net uboot, jhersh
|
||||
alias usb uboot, marex
|
||||
alias video uboot, ag
|
||||
|
||||
@@ -316,7 +316,7 @@ static int mxs_dma_request(int channel)
|
||||
* The channel will NOT be released if it's marked "busy" (see
|
||||
* mxs_dma_enable()).
|
||||
*/
|
||||
static int mxs_dma_release(int channel)
|
||||
int mxs_dma_release(int channel)
|
||||
{
|
||||
struct mxs_dma_chan *pchan;
|
||||
int ret;
|
||||
@@ -552,12 +552,10 @@ int mxs_dma_go(int chan)
|
||||
/*
|
||||
* Initialize the DMA hardware
|
||||
*/
|
||||
int mxs_dma_init(void)
|
||||
void mxs_dma_init(void)
|
||||
{
|
||||
struct mx28_apbh_regs *apbh_regs =
|
||||
(struct mx28_apbh_regs *)MXS_APBH_BASE;
|
||||
struct mxs_dma_chan *pchan;
|
||||
int ret, channel;
|
||||
|
||||
mx28_reset_block(&apbh_regs->hw_apbh_ctrl0_reg);
|
||||
|
||||
@@ -576,28 +574,26 @@ int mxs_dma_init(void)
|
||||
writel(APBH_CTRL0_APB_BURST_EN,
|
||||
&apbh_regs->hw_apbh_ctrl0_clr);
|
||||
#endif
|
||||
}
|
||||
|
||||
for (channel = 0; channel < MXS_MAX_DMA_CHANNELS; channel++) {
|
||||
pchan = mxs_dma_channels + channel;
|
||||
pchan->flags = MXS_DMA_FLAGS_VALID;
|
||||
int mxs_dma_init_channel(int channel)
|
||||
{
|
||||
struct mxs_dma_chan *pchan;
|
||||
int ret;
|
||||
|
||||
ret = mxs_dma_request(channel);
|
||||
pchan = mxs_dma_channels + channel;
|
||||
pchan->flags = MXS_DMA_FLAGS_VALID;
|
||||
|
||||
if (ret) {
|
||||
printf("MXS DMA: Can't acquire DMA channel %i\n",
|
||||
channel);
|
||||
ret = mxs_dma_request(channel);
|
||||
|
||||
goto err;
|
||||
}
|
||||
|
||||
mxs_dma_reset(channel);
|
||||
mxs_dma_ack_irq(channel);
|
||||
if (ret) {
|
||||
printf("MXS DMA: Can't acquire DMA channel %i\n",
|
||||
channel);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
mxs_dma_reset(channel);
|
||||
mxs_dma_ack_irq(channel);
|
||||
|
||||
err:
|
||||
while (--channel >= 0)
|
||||
mxs_dma_release(channel);
|
||||
return ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -34,6 +34,7 @@ enum mxc_gpio_direction {
|
||||
MXC_GPIO_DIRECTION_OUT,
|
||||
};
|
||||
|
||||
#define GPIO_TO_PORT(n) (n / 32)
|
||||
|
||||
/* GPIO port description */
|
||||
static unsigned long gpio_ports[] = {
|
||||
@@ -53,7 +54,7 @@ static unsigned long gpio_ports[] = {
|
||||
static int mxc_gpio_direction(unsigned int gpio,
|
||||
enum mxc_gpio_direction direction)
|
||||
{
|
||||
unsigned int port = gpio >> 5;
|
||||
unsigned int port = GPIO_TO_PORT(gpio);
|
||||
struct gpio_regs *regs;
|
||||
u32 l;
|
||||
|
||||
@@ -80,7 +81,7 @@ static int mxc_gpio_direction(unsigned int gpio,
|
||||
|
||||
int gpio_set_value(unsigned gpio, int value)
|
||||
{
|
||||
unsigned int port = gpio >> 5;
|
||||
unsigned int port = GPIO_TO_PORT(gpio);
|
||||
struct gpio_regs *regs;
|
||||
u32 l;
|
||||
|
||||
@@ -103,7 +104,7 @@ int gpio_set_value(unsigned gpio, int value)
|
||||
|
||||
int gpio_get_value(unsigned gpio)
|
||||
{
|
||||
unsigned int port = gpio >> 5;
|
||||
unsigned int port = GPIO_TO_PORT(gpio);
|
||||
struct gpio_regs *regs;
|
||||
u32 val;
|
||||
|
||||
@@ -121,7 +122,7 @@ int gpio_get_value(unsigned gpio)
|
||||
|
||||
int gpio_request(unsigned gpio, const char *label)
|
||||
{
|
||||
unsigned int port = gpio >> 5;
|
||||
unsigned int port = GPIO_TO_PORT(gpio);
|
||||
if (port >= ARRAY_SIZE(gpio_ports))
|
||||
return -1;
|
||||
return 0;
|
||||
@@ -144,6 +145,5 @@ int gpio_direction_output(unsigned gpio, int value)
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
gpio_set_value(gpio, value);
|
||||
return 0;
|
||||
return gpio_set_value(gpio, value);
|
||||
}
|
||||
|
||||
@@ -179,7 +179,7 @@ int mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data)
|
||||
for (i = 0; i < 4; i++) {
|
||||
int j;
|
||||
printf("\t\t\t\t\t%03d - ", i*4);
|
||||
ptr = &cmd->response[i];
|
||||
ptr = (u8 *)&cmd->response[i];
|
||||
ptr += 3;
|
||||
for (j = 0; j < 4; j++)
|
||||
printf("%02X ", *ptr--);
|
||||
|
||||
@@ -43,6 +43,13 @@
|
||||
#include <asm/arch/sys_proto.h>
|
||||
#include <asm/arch/dma.h>
|
||||
|
||||
/*
|
||||
* CONFIG_MXS_MMC_DMA: This feature is highly experimental and has no
|
||||
* performance benefit unless you operate the platform with
|
||||
* data cache enabled. This is disabled by default, enable
|
||||
* only if you know what you're doing.
|
||||
*/
|
||||
|
||||
struct mxsmmc_priv {
|
||||
int id;
|
||||
struct mx28_ssp_regs *regs;
|
||||
@@ -66,8 +73,13 @@ mxsmmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data)
|
||||
struct mx28_ssp_regs *ssp_regs = priv->regs;
|
||||
uint32_t reg;
|
||||
int timeout;
|
||||
uint32_t data_count, cache_data_count;
|
||||
uint32_t data_count;
|
||||
uint32_t ctrl0;
|
||||
#ifndef CONFIG_MXS_MMC_DMA
|
||||
uint32_t *data_ptr;
|
||||
#else
|
||||
uint32_t cache_data_count;
|
||||
#endif
|
||||
|
||||
debug("MMC%d: CMD%d\n", mmc->block_dev.dev, cmd->cmdidx);
|
||||
|
||||
@@ -185,7 +197,9 @@ mxsmmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data)
|
||||
return 0;
|
||||
|
||||
data_count = data->blocksize * data->blocks;
|
||||
timeout = MXSMMC_MAX_TIMEOUT;
|
||||
|
||||
#ifdef CONFIG_MXS_MMC_DMA
|
||||
if (data_count % ARCH_DMA_MINALIGN)
|
||||
cache_data_count = roundup(data_count, ARCH_DMA_MINALIGN);
|
||||
else
|
||||
@@ -218,6 +232,38 @@ mxsmmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data)
|
||||
invalidate_dcache_range((uint32_t)priv->desc->cmd.address,
|
||||
(uint32_t)(priv->desc->cmd.address + cache_data_count));
|
||||
}
|
||||
#else
|
||||
if (data->flags & MMC_DATA_READ) {
|
||||
data_ptr = (uint32_t *)data->dest;
|
||||
while (data_count && --timeout) {
|
||||
reg = readl(&ssp_regs->hw_ssp_status);
|
||||
if (!(reg & SSP_STATUS_FIFO_EMPTY)) {
|
||||
*data_ptr++ = readl(&ssp_regs->hw_ssp_data);
|
||||
data_count -= 4;
|
||||
timeout = MXSMMC_MAX_TIMEOUT;
|
||||
} else
|
||||
udelay(1000);
|
||||
}
|
||||
} else {
|
||||
data_ptr = (uint32_t *)data->src;
|
||||
timeout *= 100;
|
||||
while (data_count && --timeout) {
|
||||
reg = readl(&ssp_regs->hw_ssp_status);
|
||||
if (!(reg & SSP_STATUS_FIFO_FULL)) {
|
||||
writel(*data_ptr++, &ssp_regs->hw_ssp_data);
|
||||
data_count -= 4;
|
||||
timeout = MXSMMC_MAX_TIMEOUT;
|
||||
} else
|
||||
udelay(1000);
|
||||
}
|
||||
}
|
||||
|
||||
if (!timeout) {
|
||||
printf("MMC%d: Data timeout with command %d (status 0x%08x)!\n",
|
||||
mmc->block_dev.dev, cmd->cmdidx, reg);
|
||||
return COMM_ERR;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Check data errors */
|
||||
reg = readl(&ssp_regs->hw_ssp_status);
|
||||
@@ -292,6 +338,7 @@ int mxsmmc_initialize(bd_t *bis, int id, int (*wp)(int))
|
||||
(struct mx28_clkctrl_regs *)MXS_CLKCTRL_BASE;
|
||||
struct mmc *mmc = NULL;
|
||||
struct mxsmmc_priv *priv = NULL;
|
||||
int ret;
|
||||
|
||||
mmc = malloc(sizeof(struct mmc));
|
||||
if (!mmc)
|
||||
@@ -310,6 +357,10 @@ int mxsmmc_initialize(bd_t *bis, int id, int (*wp)(int))
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
ret = mxs_dma_init_channel(id);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
priv->mmc_is_wp = wp;
|
||||
priv->id = id;
|
||||
switch (id) {
|
||||
|
||||
@@ -1058,7 +1058,7 @@ int mxs_nand_init(struct mxs_nand_info *info)
|
||||
{
|
||||
struct mx28_gpmi_regs *gpmi_regs =
|
||||
(struct mx28_gpmi_regs *)MXS_GPMI_BASE;
|
||||
int i = 0;
|
||||
int i = 0, j;
|
||||
|
||||
info->desc = malloc(sizeof(struct mxs_dma_desc *) *
|
||||
MXS_NAND_DMA_DESCRIPTOR_COUNT);
|
||||
@@ -1073,7 +1073,11 @@ int mxs_nand_init(struct mxs_nand_info *info)
|
||||
}
|
||||
|
||||
/* Init the DMA controller. */
|
||||
mxs_dma_init();
|
||||
for (j = MXS_DMA_CHANNEL_AHB_APBH_GPMI0;
|
||||
j <= MXS_DMA_CHANNEL_AHB_APBH_GPMI7; j++) {
|
||||
if (mxs_dma_init_channel(j))
|
||||
goto err3;
|
||||
}
|
||||
|
||||
/* Reset the GPMI block. */
|
||||
mx28_reset_block(&gpmi_regs->hw_gpmi_ctrl0_reg);
|
||||
@@ -1089,6 +1093,9 @@ int mxs_nand_init(struct mxs_nand_info *info)
|
||||
|
||||
return 0;
|
||||
|
||||
err3:
|
||||
for (--j; j >= 0; j--)
|
||||
mxs_dma_release(j);
|
||||
err2:
|
||||
free(info->desc);
|
||||
err1:
|
||||
|
||||
@@ -367,7 +367,7 @@ static int onenand_command(struct mtd_info *mtd, int cmd, loff_t addr,
|
||||
this->write_word(value,
|
||||
this->base + ONENAND_REG_START_ADDRESS2);
|
||||
|
||||
if (ONENAND_IS_MLC(this))
|
||||
if (ONENAND_IS_4KB_PAGE(this))
|
||||
ONENAND_SET_BUFFERRAM0(this);
|
||||
else
|
||||
/* Switch to the next data buffer */
|
||||
@@ -395,7 +395,7 @@ static int onenand_command(struct mtd_info *mtd, int cmd, loff_t addr,
|
||||
case FLEXONENAND_CMD_RECOVER_LSB:
|
||||
case ONENAND_CMD_READ:
|
||||
case ONENAND_CMD_READOOB:
|
||||
if (ONENAND_IS_MLC(this))
|
||||
if (ONENAND_IS_4KB_PAGE(this))
|
||||
dataram = ONENAND_SET_BUFFERRAM0(this);
|
||||
else
|
||||
dataram = ONENAND_SET_NEXT_BUFFERRAM(this);
|
||||
@@ -893,7 +893,7 @@ static int onenand_read_ops_nolock(struct mtd_info *mtd, loff_t from,
|
||||
while (!ret) {
|
||||
/* If there is more to load then start next load */
|
||||
from += thislen;
|
||||
if (!ONENAND_IS_MLC(this) && read + thislen < len) {
|
||||
if (!ONENAND_IS_4KB_PAGE(this) && read + thislen < len) {
|
||||
this->main_buf = buf + thislen;
|
||||
this->command(mtd, ONENAND_CMD_READ, from, writesize);
|
||||
/*
|
||||
@@ -927,7 +927,7 @@ static int onenand_read_ops_nolock(struct mtd_info *mtd, loff_t from,
|
||||
oobcolumn = 0;
|
||||
}
|
||||
|
||||
if (ONENAND_IS_MLC(this) && (read + thislen < len)) {
|
||||
if (ONENAND_IS_4KB_PAGE(this) && (read + thislen < len)) {
|
||||
this->command(mtd, ONENAND_CMD_READ, from, writesize);
|
||||
ret = this->wait(mtd, FL_READING);
|
||||
if (unlikely(ret))
|
||||
@@ -944,13 +944,13 @@ static int onenand_read_ops_nolock(struct mtd_info *mtd, loff_t from,
|
||||
/* Set up for next read from bufferRAM */
|
||||
if (unlikely(boundary))
|
||||
this->write_word(ONENAND_DDP_CHIP1, this->base + ONENAND_REG_START_ADDRESS2);
|
||||
if (!ONENAND_IS_MLC(this))
|
||||
if (!ONENAND_IS_4KB_PAGE(this))
|
||||
ONENAND_SET_NEXT_BUFFERRAM(this);
|
||||
buf += thislen;
|
||||
thislen = min_t(int, writesize, len - read);
|
||||
column = 0;
|
||||
|
||||
if (!ONENAND_IS_MLC(this)) {
|
||||
if (!ONENAND_IS_4KB_PAGE(this)) {
|
||||
/* Now wait for load */
|
||||
ret = this->wait(mtd, FL_READING);
|
||||
onenand_update_bufferram(mtd, from, !ret);
|
||||
@@ -1024,7 +1024,8 @@ static int onenand_read_oob_nolock(struct mtd_info *mtd, loff_t from,
|
||||
|
||||
stats = mtd->ecc_stats;
|
||||
|
||||
readcmd = ONENAND_IS_MLC(this) ? ONENAND_CMD_READ : ONENAND_CMD_READOOB;
|
||||
readcmd = ONENAND_IS_4KB_PAGE(this) ?
|
||||
ONENAND_CMD_READ : ONENAND_CMD_READOOB;
|
||||
|
||||
while (read < len) {
|
||||
thislen = oobsize - column;
|
||||
@@ -1202,7 +1203,8 @@ int onenand_bbt_read_oob(struct mtd_info *mtd, loff_t from,
|
||||
|
||||
MTDDEBUG(MTD_DEBUG_LEVEL3, "onenand_bbt_read_oob: from = 0x%08x, len = %zi\n", (unsigned int) from, len);
|
||||
|
||||
readcmd = ONENAND_IS_MLC(this) ? ONENAND_CMD_READ : ONENAND_CMD_READOOB;
|
||||
readcmd = ONENAND_IS_4KB_PAGE(this) ?
|
||||
ONENAND_CMD_READ : ONENAND_CMD_READOOB;
|
||||
|
||||
/* Initialize return value */
|
||||
ops->oobretlen = 0;
|
||||
@@ -1271,7 +1273,8 @@ static int onenand_verify_oob(struct mtd_info *mtd, const u_char *buf, loff_t to
|
||||
u_char *oob_buf = this->oob_buf;
|
||||
int status, i, readcmd;
|
||||
|
||||
readcmd = ONENAND_IS_MLC(this) ? ONENAND_CMD_READ : ONENAND_CMD_READOOB;
|
||||
readcmd = ONENAND_IS_4KB_PAGE(this) ?
|
||||
ONENAND_CMD_READ : ONENAND_CMD_READOOB;
|
||||
|
||||
this->command(mtd, readcmd, to, mtd->oobsize);
|
||||
onenand_update_bufferram(mtd, to, 0);
|
||||
@@ -1560,7 +1563,8 @@ static int onenand_write_oob_nolock(struct mtd_info *mtd, loff_t to,
|
||||
|
||||
oobbuf = this->oob_buf;
|
||||
|
||||
oobcmd = ONENAND_IS_MLC(this) ? ONENAND_CMD_PROG : ONENAND_CMD_PROGOOB;
|
||||
oobcmd = ONENAND_IS_4KB_PAGE(this) ?
|
||||
ONENAND_CMD_PROG : ONENAND_CMD_PROGOOB;
|
||||
|
||||
/* Loop until all data write */
|
||||
while (written < len) {
|
||||
@@ -1577,7 +1581,7 @@ static int onenand_write_oob_nolock(struct mtd_info *mtd, loff_t to,
|
||||
memcpy(oobbuf + column, buf, thislen);
|
||||
this->write_bufferram(mtd, 0, ONENAND_SPARERAM, oobbuf, 0, mtd->oobsize);
|
||||
|
||||
if (ONENAND_IS_MLC(this)) {
|
||||
if (ONENAND_IS_4KB_PAGE(this)) {
|
||||
/* Set main area of DataRAM to 0xff*/
|
||||
memset(this->page_buf, 0xff, mtd->writesize);
|
||||
this->write_bufferram(mtd, 0, ONENAND_DATARAM,
|
||||
@@ -2140,7 +2144,10 @@ static void onenand_check_features(struct mtd_info *mtd)
|
||||
/* Lock scheme */
|
||||
switch (density) {
|
||||
case ONENAND_DEVICE_DENSITY_4Gb:
|
||||
this->options |= ONENAND_HAS_2PLANE;
|
||||
if (ONENAND_IS_DDP(this))
|
||||
this->options |= ONENAND_HAS_2PLANE;
|
||||
else
|
||||
this->options |= ONENAND_HAS_4KB_PAGE;
|
||||
|
||||
case ONENAND_DEVICE_DENSITY_2Gb:
|
||||
/* 2Gb DDP don't have 2 plane */
|
||||
@@ -2162,6 +2169,9 @@ static void onenand_check_features(struct mtd_info *mtd)
|
||||
}
|
||||
|
||||
if (ONENAND_IS_MLC(this))
|
||||
this->options |= ONENAND_HAS_4KB_PAGE;
|
||||
|
||||
if (ONENAND_IS_4KB_PAGE(this))
|
||||
this->options &= ~ONENAND_HAS_2PLANE;
|
||||
|
||||
if (FLEXONENAND(this)) {
|
||||
@@ -2175,6 +2185,9 @@ static void onenand_check_features(struct mtd_info *mtd)
|
||||
printk(KERN_DEBUG "Chip support all block unlock\n");
|
||||
if (this->options & ONENAND_HAS_2PLANE)
|
||||
printk(KERN_DEBUG "Chip has 2 plane\n");
|
||||
if (this->options & ONENAND_HAS_4KB_PAGE)
|
||||
printk(KERN_DEBUG "Chip has 4KiB pagesize\n");
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2501,23 +2514,24 @@ out:
|
||||
}
|
||||
|
||||
/**
|
||||
* onenand_probe - [OneNAND Interface] Probe the OneNAND device
|
||||
* onenand_chip_probe - [OneNAND Interface] Probe the OneNAND chip
|
||||
* @param mtd MTD device structure
|
||||
*
|
||||
* OneNAND detection method:
|
||||
* Compare the the values from command with ones from register
|
||||
*/
|
||||
static int onenand_probe(struct mtd_info *mtd)
|
||||
static int onenand_chip_probe(struct mtd_info *mtd)
|
||||
{
|
||||
struct onenand_chip *this = mtd->priv;
|
||||
int bram_maf_id, bram_dev_id, maf_id, dev_id, ver_id;
|
||||
int density;
|
||||
int bram_maf_id, bram_dev_id, maf_id, dev_id;
|
||||
int syscfg;
|
||||
|
||||
/* Save system configuration 1 */
|
||||
syscfg = this->read_word(this->base + ONENAND_REG_SYS_CFG1);
|
||||
|
||||
/* Clear Sync. Burst Read mode to read BootRAM */
|
||||
this->write_word((syscfg & ~ONENAND_SYS_CFG1_SYNC_READ), this->base + ONENAND_REG_SYS_CFG1);
|
||||
this->write_word((syscfg & ~ONENAND_SYS_CFG1_SYNC_READ),
|
||||
this->base + ONENAND_REG_SYS_CFG1);
|
||||
|
||||
/* Send the command for reading device ID from BootRAM */
|
||||
this->write_word(ONENAND_CMD_READID, this->base + ONENAND_BOOTRAM);
|
||||
@@ -2542,18 +2556,45 @@ static int onenand_probe(struct mtd_info *mtd)
|
||||
/* Read manufacturer and device IDs from Register */
|
||||
maf_id = this->read_word(this->base + ONENAND_REG_MANUFACTURER_ID);
|
||||
dev_id = this->read_word(this->base + ONENAND_REG_DEVICE_ID);
|
||||
ver_id = this->read_word(this->base + ONENAND_REG_VERSION_ID);
|
||||
this->technology = this->read_word(this->base + ONENAND_REG_TECHNOLOGY);
|
||||
|
||||
/* Check OneNAND device */
|
||||
if (maf_id != bram_maf_id || dev_id != bram_dev_id)
|
||||
return -ENXIO;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* onenand_probe - [OneNAND Interface] Probe the OneNAND device
|
||||
* @param mtd MTD device structure
|
||||
*
|
||||
* OneNAND detection method:
|
||||
* Compare the the values from command with ones from register
|
||||
*/
|
||||
int onenand_probe(struct mtd_info *mtd)
|
||||
{
|
||||
struct onenand_chip *this = mtd->priv;
|
||||
int dev_id, ver_id;
|
||||
int density;
|
||||
int ret;
|
||||
|
||||
ret = this->chip_probe(mtd);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* Read device IDs from Register */
|
||||
dev_id = this->read_word(this->base + ONENAND_REG_DEVICE_ID);
|
||||
ver_id = this->read_word(this->base + ONENAND_REG_VERSION_ID);
|
||||
this->technology = this->read_word(this->base + ONENAND_REG_TECHNOLOGY);
|
||||
|
||||
/* Flash device information */
|
||||
mtd->name = onenand_print_device_info(dev_id, ver_id);
|
||||
this->device_id = dev_id;
|
||||
this->version_id = ver_id;
|
||||
|
||||
/* Check OneNAND features */
|
||||
onenand_check_features(mtd);
|
||||
|
||||
density = onenand_get_density(dev_id);
|
||||
if (FLEXONENAND(this)) {
|
||||
this->dies = ONENAND_IS_DDP(this) ? 2 : 1;
|
||||
@@ -2576,7 +2617,7 @@ static int onenand_probe(struct mtd_info *mtd)
|
||||
mtd->writesize =
|
||||
this->read_word(this->base + ONENAND_REG_DATA_BUFFER_SIZE);
|
||||
/* We use the full BufferRAM */
|
||||
if (ONENAND_IS_MLC(this))
|
||||
if (ONENAND_IS_4KB_PAGE(this))
|
||||
mtd->writesize <<= 1;
|
||||
|
||||
mtd->oobsize = mtd->writesize >> 5;
|
||||
@@ -2607,9 +2648,6 @@ static int onenand_probe(struct mtd_info *mtd)
|
||||
else
|
||||
mtd->size = this->chipsize;
|
||||
|
||||
/* Check OneNAND features */
|
||||
onenand_check_features(mtd);
|
||||
|
||||
mtd->flags = MTD_CAP_NANDFLASH;
|
||||
mtd->erase = onenand_erase;
|
||||
mtd->read = onenand_read;
|
||||
@@ -2655,6 +2693,9 @@ int onenand_scan(struct mtd_info *mtd, int maxchips)
|
||||
if (!this->write_bufferram)
|
||||
this->write_bufferram = onenand_write_bufferram;
|
||||
|
||||
if (!this->chip_probe)
|
||||
this->chip_probe = onenand_chip_probe;
|
||||
|
||||
if (!this->block_markbad)
|
||||
this->block_markbad = onenand_default_block_markbad;
|
||||
if (!this->scan_bbt)
|
||||
|
||||
@@ -589,6 +589,16 @@ static void s3c_set_width_regs(struct onenand_chip *this)
|
||||
}
|
||||
#endif
|
||||
|
||||
int s5pc110_chip_probe(struct mtd_info *mtd)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int s5pc210_chip_probe(struct mtd_info *mtd)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void s3c_onenand_init(struct mtd_info *mtd)
|
||||
{
|
||||
struct onenand_chip *this = mtd->priv;
|
||||
|
||||
@@ -322,24 +322,19 @@ static int smi_write(unsigned int *src_addr, unsigned int *dst_addr,
|
||||
unsigned int length, ulong bank_addr)
|
||||
{
|
||||
int banknum;
|
||||
unsigned int WM;
|
||||
|
||||
switch (bank_addr) {
|
||||
case SMIBANK0_BASE:
|
||||
banknum = BANK0;
|
||||
WM = WM0;
|
||||
break;
|
||||
case SMIBANK1_BASE:
|
||||
banknum = BANK1;
|
||||
WM = WM1;
|
||||
break;
|
||||
case SMIBANK2_BASE:
|
||||
banknum = BANK2;
|
||||
WM = WM2;
|
||||
break;
|
||||
case SMIBANK3_BASE:
|
||||
banknum = BANK3;
|
||||
WM = WM3;
|
||||
break;
|
||||
default:
|
||||
return -1;
|
||||
|
||||
@@ -77,6 +77,8 @@ COBJS-$(CONFIG_ULI526X) += uli526x.o
|
||||
COBJS-$(CONFIG_VSC7385_ENET) += vsc7385.o
|
||||
COBJS-$(CONFIG_XILINX_AXIEMAC) += xilinx_axi_emac.o
|
||||
COBJS-$(CONFIG_XILINX_EMACLITE) += xilinx_emaclite.o
|
||||
COBJS-$(CONFIG_XILINX_LL_TEMAC) += xilinx_ll_temac.o xilinx_ll_temac_mdio.o \
|
||||
xilinx_ll_temac_fifo.o xilinx_ll_temac_sdma.o
|
||||
|
||||
COBJS := $(sort $(COBJS-y))
|
||||
SRCS := $(COBJS:.o=.c)
|
||||
|
||||
@@ -32,6 +32,8 @@
|
||||
#include <asm/io.h>
|
||||
#include "designware.h"
|
||||
|
||||
static int configure_phy(struct eth_device *dev);
|
||||
|
||||
static void tx_descs_init(struct eth_device *dev)
|
||||
{
|
||||
struct dw_eth_dev *priv = dev->priv;
|
||||
@@ -106,16 +108,20 @@ static int mac_reset(struct eth_device *dev)
|
||||
struct eth_mac_regs *mac_p = priv->mac_regs_p;
|
||||
struct eth_dma_regs *dma_p = priv->dma_regs_p;
|
||||
|
||||
ulong start;
|
||||
int timeout = CONFIG_MACRESET_TIMEOUT;
|
||||
|
||||
writel(DMAMAC_SRST, &dma_p->busmode);
|
||||
writel(MII_PORTSELECT, &mac_p->conf);
|
||||
|
||||
do {
|
||||
start = get_timer(0);
|
||||
while (get_timer(start) < timeout) {
|
||||
if (!(readl(&dma_p->busmode) & DMAMAC_SRST))
|
||||
return 0;
|
||||
udelay(1000);
|
||||
} while (timeout--);
|
||||
|
||||
/* Try again after 10usec */
|
||||
udelay(10);
|
||||
};
|
||||
|
||||
return -1;
|
||||
}
|
||||
@@ -144,10 +150,16 @@ static int dw_eth_init(struct eth_device *dev, bd_t *bis)
|
||||
struct eth_dma_regs *dma_p = priv->dma_regs_p;
|
||||
u32 conf;
|
||||
|
||||
if (priv->phy_configured != 1)
|
||||
configure_phy(dev);
|
||||
|
||||
/* Reset ethernet hardware */
|
||||
if (mac_reset(dev) < 0)
|
||||
return -1;
|
||||
|
||||
/* Resore the HW MAC address as it has been lost during MAC reset */
|
||||
dw_write_hwaddr(dev);
|
||||
|
||||
writel(FIXEDBURST | PRIORXTX_41 | BURST_16,
|
||||
&dma_p->busmode);
|
||||
|
||||
@@ -172,8 +184,7 @@ static int dw_eth_init(struct eth_device *dev, bd_t *bis)
|
||||
writel(readl(&dma_p->opmode) | RXSTART, &dma_p->opmode);
|
||||
writel(readl(&dma_p->opmode) | TXSTART, &dma_p->opmode);
|
||||
|
||||
writel(readl(&mac_p->conf) | RXENABLE, &mac_p->conf);
|
||||
writel(readl(&mac_p->conf) | TXENABLE, &mac_p->conf);
|
||||
writel(readl(&mac_p->conf) | RXENABLE | TXENABLE, &mac_p->conf);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -266,6 +277,7 @@ static int eth_mdio_read(struct eth_device *dev, u8 addr, u8 reg, u16 *val)
|
||||
{
|
||||
struct dw_eth_dev *priv = dev->priv;
|
||||
struct eth_mac_regs *mac_p = priv->mac_regs_p;
|
||||
ulong start;
|
||||
u32 miiaddr;
|
||||
int timeout = CONFIG_MDIO_TIMEOUT;
|
||||
|
||||
@@ -274,13 +286,16 @@ static int eth_mdio_read(struct eth_device *dev, u8 addr, u8 reg, u16 *val)
|
||||
|
||||
writel(miiaddr | MII_CLKRANGE_150_250M | MII_BUSY, &mac_p->miiaddr);
|
||||
|
||||
do {
|
||||
start = get_timer(0);
|
||||
while (get_timer(start) < timeout) {
|
||||
if (!(readl(&mac_p->miiaddr) & MII_BUSY)) {
|
||||
*val = readl(&mac_p->miidata);
|
||||
return 0;
|
||||
}
|
||||
udelay(1000);
|
||||
} while (timeout--);
|
||||
|
||||
/* Try again after 10usec */
|
||||
udelay(10);
|
||||
};
|
||||
|
||||
return -1;
|
||||
}
|
||||
@@ -289,6 +304,7 @@ static int eth_mdio_write(struct eth_device *dev, u8 addr, u8 reg, u16 val)
|
||||
{
|
||||
struct dw_eth_dev *priv = dev->priv;
|
||||
struct eth_mac_regs *mac_p = priv->mac_regs_p;
|
||||
ulong start;
|
||||
u32 miiaddr;
|
||||
int ret = -1, timeout = CONFIG_MDIO_TIMEOUT;
|
||||
u16 value;
|
||||
@@ -299,11 +315,16 @@ static int eth_mdio_write(struct eth_device *dev, u8 addr, u8 reg, u16 val)
|
||||
|
||||
writel(miiaddr | MII_CLKRANGE_150_250M | MII_BUSY, &mac_p->miiaddr);
|
||||
|
||||
do {
|
||||
if (!(readl(&mac_p->miiaddr) & MII_BUSY))
|
||||
start = get_timer(0);
|
||||
while (get_timer(start) < timeout) {
|
||||
if (!(readl(&mac_p->miiaddr) & MII_BUSY)) {
|
||||
ret = 0;
|
||||
udelay(1000);
|
||||
} while (timeout--);
|
||||
break;
|
||||
}
|
||||
|
||||
/* Try again after 10usec */
|
||||
udelay(10);
|
||||
};
|
||||
|
||||
/* Needed as a fix for ST-Phy */
|
||||
eth_mdio_read(dev, addr, reg, &value);
|
||||
@@ -344,18 +365,23 @@ static int dw_reset_phy(struct eth_device *dev)
|
||||
{
|
||||
struct dw_eth_dev *priv = dev->priv;
|
||||
u16 ctrl;
|
||||
ulong start;
|
||||
int timeout = CONFIG_PHYRESET_TIMEOUT;
|
||||
u32 phy_addr = priv->address;
|
||||
|
||||
eth_mdio_write(dev, phy_addr, MII_BMCR, BMCR_RESET);
|
||||
do {
|
||||
|
||||
start = get_timer(0);
|
||||
while (get_timer(start) < timeout) {
|
||||
eth_mdio_read(dev, phy_addr, MII_BMCR, &ctrl);
|
||||
if (!(ctrl & BMCR_RESET))
|
||||
break;
|
||||
udelay(1000);
|
||||
} while (timeout--);
|
||||
|
||||
if (timeout < 0)
|
||||
/* Try again after 10usec */
|
||||
udelay(10);
|
||||
};
|
||||
|
||||
if (get_timer(start) >= CONFIG_PHYRESET_TIMEOUT)
|
||||
return -1;
|
||||
|
||||
#ifdef CONFIG_PHY_RESET_DELAY
|
||||
@@ -372,6 +398,7 @@ static int configure_phy(struct eth_device *dev)
|
||||
#if defined(CONFIG_DW_AUTONEG)
|
||||
u16 bmsr;
|
||||
u32 timeout;
|
||||
ulong start;
|
||||
u16 anlpar, btsr;
|
||||
#else
|
||||
u16 ctrl;
|
||||
@@ -379,7 +406,7 @@ static int configure_phy(struct eth_device *dev)
|
||||
|
||||
#if defined(CONFIG_DW_SEARCH_PHY)
|
||||
phy_addr = find_phy(dev);
|
||||
if (phy_addr > 0)
|
||||
if (phy_addr >= 0)
|
||||
priv->address = phy_addr;
|
||||
else
|
||||
return -1;
|
||||
@@ -390,8 +417,10 @@ static int configure_phy(struct eth_device *dev)
|
||||
return -1;
|
||||
|
||||
#if defined(CONFIG_DW_AUTONEG)
|
||||
bmcr = BMCR_ANENABLE | BMCR_ANRESTART | BMCR_SPEED100 | \
|
||||
BMCR_FULLDPLX | BMCR_SPEED1000;
|
||||
/* Set Auto-Neg Advertisement capabilities to 10/100 half/full */
|
||||
eth_mdio_write(dev, phy_addr, MII_ADVERTISE, 0x1E1);
|
||||
|
||||
bmcr = BMCR_ANENABLE | BMCR_ANRESTART;
|
||||
#else
|
||||
bmcr = BMCR_SPEED100 | BMCR_FULLDPLX;
|
||||
|
||||
@@ -408,33 +437,56 @@ static int configure_phy(struct eth_device *dev)
|
||||
/* Read the phy status register and populate priv structure */
|
||||
#if defined(CONFIG_DW_AUTONEG)
|
||||
timeout = CONFIG_AUTONEG_TIMEOUT;
|
||||
do {
|
||||
start = get_timer(0);
|
||||
|
||||
while (get_timer(start) < timeout) {
|
||||
eth_mdio_read(dev, phy_addr, MII_BMSR, &bmsr);
|
||||
if (bmsr & BMSR_ANEGCOMPLETE)
|
||||
break;
|
||||
udelay(1000);
|
||||
} while (timeout--);
|
||||
|
||||
/* Try again after 10usec */
|
||||
udelay(10);
|
||||
};
|
||||
|
||||
eth_mdio_read(dev, phy_addr, MII_LPA, &anlpar);
|
||||
eth_mdio_read(dev, phy_addr, MII_STAT1000, &btsr);
|
||||
|
||||
if (btsr & (PHY_1000BTSR_1000FD | PHY_1000BTSR_1000HD)) {
|
||||
priv->speed = SPEED_1000M;
|
||||
if (btsr & PHY_1000BTSR_1000FD)
|
||||
if (bmsr & BMSR_ANEGCOMPLETE) {
|
||||
if (btsr & PHY_1000BTSR_1000FD) {
|
||||
priv->speed = SPEED_1000M;
|
||||
bmcr |= BMCR_SPEED1000;
|
||||
priv->duplex = FULL_DUPLEX;
|
||||
else
|
||||
bmcr |= BMCR_FULLDPLX;
|
||||
} else if (btsr & PHY_1000BTSR_1000HD) {
|
||||
priv->speed = SPEED_1000M;
|
||||
bmcr |= BMCR_SPEED1000;
|
||||
priv->duplex = HALF_DUPLEX;
|
||||
} else {
|
||||
if (anlpar & LPA_100)
|
||||
bmcr &= ~BMCR_FULLDPLX;
|
||||
} else if (anlpar & LPA_100FULL) {
|
||||
priv->speed = SPEED_100M;
|
||||
else
|
||||
priv->speed = SPEED_10M;
|
||||
|
||||
if (anlpar & (LPA_10FULL | LPA_100FULL))
|
||||
bmcr |= BMCR_SPEED100;
|
||||
priv->duplex = FULL_DUPLEX;
|
||||
else
|
||||
bmcr |= BMCR_FULLDPLX;
|
||||
} else if (anlpar & LPA_100HALF) {
|
||||
priv->speed = SPEED_100M;
|
||||
bmcr |= BMCR_SPEED100;
|
||||
priv->duplex = HALF_DUPLEX;
|
||||
}
|
||||
bmcr &= ~BMCR_FULLDPLX;
|
||||
} else if (anlpar & LPA_10FULL) {
|
||||
priv->speed = SPEED_10M;
|
||||
bmcr &= ~BMCR_SPEED100;
|
||||
priv->duplex = FULL_DUPLEX;
|
||||
bmcr |= BMCR_FULLDPLX;
|
||||
} else {
|
||||
priv->speed = SPEED_10M;
|
||||
bmcr &= ~BMCR_SPEED100;
|
||||
priv->duplex = HALF_DUPLEX;
|
||||
bmcr &= ~BMCR_FULLDPLX;
|
||||
}
|
||||
if (eth_mdio_write(dev, phy_addr, MII_BMCR, bmcr) < 0)
|
||||
return -1;
|
||||
} else
|
||||
return -1;
|
||||
#else
|
||||
if (eth_mdio_read(dev, phy_addr, MII_BMCR, &ctrl) < 0)
|
||||
return -1;
|
||||
@@ -451,6 +503,8 @@ static int configure_phy(struct eth_device *dev)
|
||||
else
|
||||
priv->speed = SPEED_10M;
|
||||
#endif
|
||||
priv->phy_configured = 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -511,14 +565,12 @@ int designware_initialize(u32 id, ulong base_addr, u32 phy_addr)
|
||||
priv->dma_regs_p = (struct eth_dma_regs *)(base_addr +
|
||||
DW_DMA_BASE_OFFSET);
|
||||
priv->address = phy_addr;
|
||||
priv->phy_configured = 0;
|
||||
|
||||
if (mac_reset(dev) < 0)
|
||||
return -1;
|
||||
|
||||
if (configure_phy(dev) < 0) {
|
||||
printf("Phy could not be configured\n");
|
||||
return -1;
|
||||
}
|
||||
configure_phy(dev);
|
||||
|
||||
dev->init = dw_eth_init;
|
||||
dev->send = dw_eth_send;
|
||||
|
||||
@@ -121,7 +121,7 @@ struct eth_dma_regs {
|
||||
#define RXSTART (1 << 1)
|
||||
|
||||
/* Descriptior related definitions */
|
||||
#define MAC_MAX_FRAME_SZ (2048)
|
||||
#define MAC_MAX_FRAME_SZ (1600)
|
||||
|
||||
struct dmamacdescr {
|
||||
u32 txrx_status;
|
||||
@@ -238,6 +238,7 @@ struct dw_eth_dev {
|
||||
u32 duplex;
|
||||
u32 tx_currdescnum;
|
||||
u32 rx_currdescnum;
|
||||
u32 phy_configured;
|
||||
u32 padding;
|
||||
|
||||
struct dmamacdescr tx_mac_descrtable[CONFIG_TX_DESCR_NUM];
|
||||
|
||||
@@ -52,6 +52,7 @@ DECLARE_GLOBAL_DATA_PTR;
|
||||
#define MV_PHY_ADR_REQUEST 0xee
|
||||
#define MVGBE_SMI_REG (((struct mvgbe_registers *)MVGBE0_BASE)->smi)
|
||||
|
||||
#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII)
|
||||
/*
|
||||
* smi_reg_read - miiphy_read callback function.
|
||||
*
|
||||
@@ -181,6 +182,7 @@ static int smi_reg_write(const char *devname, u8 phy_adr, u8 reg_ofs, u16 data)
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Stop and checks all queues */
|
||||
static void stop_queue(u32 * qreg)
|
||||
|
||||
399
drivers/net/xilinx_ll_temac.c
Normal file
399
drivers/net/xilinx_ll_temac.c
Normal file
@@ -0,0 +1,399 @@
|
||||
/*
|
||||
* Xilinx xps_ll_temac ethernet driver for u-boot
|
||||
*
|
||||
* supports SDMA or FIFO access and MDIO bus communication
|
||||
*
|
||||
* Copyright (C) 2011 - 2012 Stephan Linz <linz@li-pro.net>
|
||||
* Copyright (C) 2008 - 2011 Michal Simek <monstr@monstr.eu>
|
||||
* Copyright (C) 2008 - 2011 PetaLogix
|
||||
*
|
||||
* Based on Yoshio Kashiwagi kashiwagi@co-nss.co.jp driver
|
||||
* Copyright (C) 2008 Nissin Systems Co.,Ltd.
|
||||
* March 2008 created
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* [0]: http://www.xilinx.com/support/documentation
|
||||
*
|
||||
* [S]: [0]/ip_documentation/xps_ll_temac.pdf
|
||||
* [A]: [0]/application_notes/xapp1041.pdf
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include <common.h>
|
||||
#include <net.h>
|
||||
#include <netdev.h>
|
||||
#include <malloc.h>
|
||||
#include <asm/io.h>
|
||||
#include <miiphy.h>
|
||||
|
||||
#include "xilinx_ll_temac.h"
|
||||
#include "xilinx_ll_temac_fifo.h"
|
||||
#include "xilinx_ll_temac_sdma.h"
|
||||
#include "xilinx_ll_temac_mdio.h"
|
||||
|
||||
#if !defined(CONFIG_MII)
|
||||
# error "LL_TEMAC requires MII -- missing CONFIG_MII"
|
||||
#endif
|
||||
|
||||
#if !defined(CONFIG_PHYLIB)
|
||||
# error "LL_TEMAC requires PHYLIB -- missing CONFIG_PHYLIB"
|
||||
#endif
|
||||
|
||||
struct ll_temac_info {
|
||||
int flags;
|
||||
unsigned long base_addr;
|
||||
unsigned long ctrl_addr;
|
||||
char *devname;
|
||||
unsigned int phyaddr;
|
||||
char *mdio_busname;
|
||||
};
|
||||
|
||||
/* Ethernet interface ready status */
|
||||
int ll_temac_check_status(struct temac_reg *regs, u32 mask)
|
||||
{
|
||||
unsigned timeout = 50; /* 1usec * 50 = 50usec */
|
||||
|
||||
/*
|
||||
* Quote from LL TEMAC documentation: The bits in the RDY
|
||||
* register are asserted when there is no access in progress.
|
||||
* When an access is in progress, a bit corresponding to the
|
||||
* type of access is automatically de-asserted. The bit is
|
||||
* automatically re-asserted when the access is complete.
|
||||
*/
|
||||
while (timeout && (!(in_be32(®s->rdy) & mask))) {
|
||||
timeout--;
|
||||
udelay(1);
|
||||
}
|
||||
|
||||
if (!timeout) {
|
||||
printf("%s: Timeout on 0x%08x @%p\n", __func__,
|
||||
mask, ®s->rdy);
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Indirect write to ll_temac.
|
||||
*
|
||||
* http://www.xilinx.com/support/documentation/ip_documentation/xps_ll_temac.pdf
|
||||
* page 23, second paragraph, The use of CTL0 register or CTL1 register
|
||||
*/
|
||||
int ll_temac_indirect_set(struct temac_reg *regs, u16 regn, u32 reg_data)
|
||||
{
|
||||
out_be32(®s->lsw, (reg_data & MLSW_MASK));
|
||||
out_be32(®s->ctl, CTL_WEN | (regn & CTL_ADDR_MASK));
|
||||
|
||||
if (ll_temac_check_status(regs, RSE_CFG_WR))
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Indirect read from ll_temac.
|
||||
*
|
||||
* http://www.xilinx.com/support/documentation/ip_documentation/xps_ll_temac.pdf
|
||||
* page 23, second paragraph, The use of CTL0 register or CTL1 register
|
||||
*/
|
||||
int ll_temac_indirect_get(struct temac_reg *regs, u16 regn, u32* reg_data)
|
||||
{
|
||||
out_be32(®s->ctl, (regn & CTL_ADDR_MASK));
|
||||
|
||||
if (ll_temac_check_status(regs, RSE_CFG_RR))
|
||||
return 0;
|
||||
|
||||
*reg_data = in_be32(®s->lsw) & MLSW_MASK;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* setting sub-controller and ll_temac to proper setting */
|
||||
static int ll_temac_setup_ctrl(struct eth_device *dev)
|
||||
{
|
||||
struct ll_temac *ll_temac = dev->priv;
|
||||
struct temac_reg *regs = (struct temac_reg *)dev->iobase;
|
||||
|
||||
if (ll_temac->ctrlreset && ll_temac->ctrlreset(dev))
|
||||
return 0;
|
||||
|
||||
if (ll_temac->ctrlinit && ll_temac->ctrlinit(dev))
|
||||
return 0;
|
||||
|
||||
/* Promiscuous mode disable */
|
||||
if (!ll_temac_indirect_set(regs, TEMAC_AFM, 0))
|
||||
return 0;
|
||||
|
||||
/* Enable Receiver - RX bit */
|
||||
if (!ll_temac_indirect_set(regs, TEMAC_RCW1, RCW1_RX))
|
||||
return 0;
|
||||
|
||||
/* Enable Transmitter - TX bit */
|
||||
if (!ll_temac_indirect_set(regs, TEMAC_TC, TC_TX))
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Configure ll_temac based on negotiated speed and duplex
|
||||
* reported by PHY handling code
|
||||
*/
|
||||
static int ll_temac_adjust_link(struct eth_device *dev)
|
||||
{
|
||||
unsigned int speed, emmc_reg;
|
||||
struct temac_reg *regs = (struct temac_reg *)dev->iobase;
|
||||
struct ll_temac *ll_temac = dev->priv;
|
||||
struct phy_device *phydev = ll_temac->phydev;
|
||||
|
||||
if (!phydev->link) {
|
||||
printf("%s: No link.\n", phydev->dev->name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
switch (phydev->speed) {
|
||||
case 1000:
|
||||
speed = EMMC_LSPD_1000;
|
||||
break;
|
||||
case 100:
|
||||
speed = EMMC_LSPD_100;
|
||||
break;
|
||||
case 10:
|
||||
speed = EMMC_LSPD_10;
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!ll_temac_indirect_get(regs, TEMAC_EMMC, &emmc_reg))
|
||||
return 0;
|
||||
|
||||
emmc_reg &= ~EMMC_LSPD_MASK;
|
||||
emmc_reg |= speed;
|
||||
|
||||
if (!ll_temac_indirect_set(regs, TEMAC_EMMC, emmc_reg))
|
||||
return 0;
|
||||
|
||||
printf("%s: PHY is %s with %dbase%s, %s%s\n",
|
||||
dev->name, phydev->drv->name,
|
||||
phydev->speed, (phydev->port == PORT_TP) ? "T" : "X",
|
||||
(phydev->duplex) ? "FDX" : "HDX",
|
||||
(phydev->port == PORT_OTHER) ? ", unkown mode" : "");
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* setup mac addr */
|
||||
static int ll_temac_setup_mac_addr(struct eth_device *dev)
|
||||
{
|
||||
struct temac_reg *regs = (struct temac_reg *)dev->iobase;
|
||||
u32 val;
|
||||
|
||||
/* set up unicast MAC address filter */
|
||||
val = ((dev->enetaddr[3] << 24) | (dev->enetaddr[2] << 16) |
|
||||
(dev->enetaddr[1] << 8) | (dev->enetaddr[0]));
|
||||
val &= UAW0_UADDR_MASK;
|
||||
|
||||
if (!ll_temac_indirect_set(regs, TEMAC_UAW0, val))
|
||||
return 1;
|
||||
|
||||
val = ((dev->enetaddr[5] << 8) | dev->enetaddr[4]);
|
||||
val &= UAW1_UADDR_MASK;
|
||||
|
||||
if (!ll_temac_indirect_set(regs, TEMAC_UAW1, val))
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* halt device */
|
||||
static void ll_temac_halt(struct eth_device *dev)
|
||||
{
|
||||
struct ll_temac *ll_temac = dev->priv;
|
||||
struct temac_reg *regs = (struct temac_reg *)dev->iobase;
|
||||
|
||||
/* Disable Receiver */
|
||||
ll_temac_indirect_set(regs, TEMAC_RCW0, 0);
|
||||
|
||||
/* Disable Transmitter */
|
||||
ll_temac_indirect_set(regs, TEMAC_TC, 0);
|
||||
|
||||
if (ll_temac->ctrlhalt)
|
||||
ll_temac->ctrlhalt(dev);
|
||||
|
||||
/* Shut down the PHY, as needed */
|
||||
phy_shutdown(ll_temac->phydev);
|
||||
}
|
||||
|
||||
static int ll_temac_init(struct eth_device *dev, bd_t *bis)
|
||||
{
|
||||
struct ll_temac *ll_temac = dev->priv;
|
||||
|
||||
printf("%s: Xilinx XPS LocalLink Tri-Mode Ether MAC #%d at 0x%08X.\n",
|
||||
dev->name, dev->index, dev->iobase);
|
||||
|
||||
if (!ll_temac_setup_ctrl(dev))
|
||||
return -1;
|
||||
|
||||
/* Start up the PHY */
|
||||
phy_startup(ll_temac->phydev);
|
||||
|
||||
if (!ll_temac_adjust_link(dev)) {
|
||||
ll_temac_halt(dev);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* If there's no link, fail */
|
||||
return ll_temac->phydev->link ? 0 : -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Discover which PHY is attached to the device, and configure it
|
||||
* properly. If the PHY is not recognized, then return 0
|
||||
* (failure). Otherwise, return 1
|
||||
*/
|
||||
static int ll_temac_phy_init(struct eth_device *dev)
|
||||
{
|
||||
struct ll_temac *ll_temac = dev->priv;
|
||||
struct phy_device *phydev;
|
||||
unsigned int supported = PHY_GBIT_FEATURES;
|
||||
|
||||
/* interface - look at driver/net/tsec.c */
|
||||
phydev = phy_connect(ll_temac->bus, ll_temac->phyaddr,
|
||||
dev, PHY_INTERFACE_MODE_NONE);
|
||||
|
||||
phydev->supported &= supported;
|
||||
phydev->advertising = phydev->supported;
|
||||
|
||||
ll_temac->phydev = phydev;
|
||||
|
||||
phy_config(phydev);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize a single ll_temac devices
|
||||
*
|
||||
* Returns the result of ll_temac phy interface that were initialized
|
||||
*/
|
||||
int xilinx_ll_temac_initialize(bd_t *bis, struct ll_temac_info *devinf)
|
||||
{
|
||||
struct eth_device *dev;
|
||||
struct ll_temac *ll_temac;
|
||||
|
||||
dev = calloc(1, sizeof(*dev));
|
||||
if (dev == NULL)
|
||||
return 0;
|
||||
|
||||
ll_temac = calloc(1, sizeof(struct ll_temac));
|
||||
if (ll_temac == NULL) {
|
||||
free(dev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* use given name or generate its own unique name */
|
||||
if (devinf->devname) {
|
||||
strncpy(dev->name, devinf->devname, sizeof(dev->name));
|
||||
} else {
|
||||
snprintf(dev->name, sizeof(dev->name), "lltemac.%lx", devinf->base_addr);
|
||||
devinf->devname = dev->name;
|
||||
}
|
||||
|
||||
dev->iobase = devinf->base_addr;
|
||||
|
||||
dev->priv = ll_temac;
|
||||
dev->init = ll_temac_init;
|
||||
dev->halt = ll_temac_halt;
|
||||
dev->write_hwaddr = ll_temac_setup_mac_addr;
|
||||
|
||||
ll_temac->ctrladdr = devinf->ctrl_addr;
|
||||
if (devinf->flags & XILINX_LL_TEMAC_M_SDMA_PLB) {
|
||||
#if defined(CONFIG_XILINX_440) || defined(CONFIG_XILINX_405)
|
||||
if (devinf->flags & XILINX_LL_TEMAC_M_SDMA_DCR) {
|
||||
ll_temac_collect_xldcr_sdma_reg_addr(dev);
|
||||
ll_temac->in32 = ll_temac_xldcr_in32;
|
||||
ll_temac->out32 = ll_temac_xldcr_out32;
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
ll_temac_collect_xlplb_sdma_reg_addr(dev);
|
||||
ll_temac->in32 = ll_temac_xlplb_in32;
|
||||
ll_temac->out32 = ll_temac_xlplb_out32;
|
||||
}
|
||||
ll_temac->ctrlinit = ll_temac_init_sdma;
|
||||
ll_temac->ctrlhalt = ll_temac_halt_sdma;
|
||||
ll_temac->ctrlreset = ll_temac_reset_sdma;
|
||||
dev->recv = ll_temac_recv_sdma;
|
||||
dev->send = ll_temac_send_sdma;
|
||||
} else {
|
||||
ll_temac->in32 = NULL;
|
||||
ll_temac->out32 = NULL;
|
||||
ll_temac->ctrlinit = NULL;
|
||||
ll_temac->ctrlhalt = NULL;
|
||||
ll_temac->ctrlreset = ll_temac_reset_fifo;
|
||||
dev->recv = ll_temac_recv_fifo;
|
||||
dev->send = ll_temac_send_fifo;
|
||||
}
|
||||
|
||||
/* Link to specified MDIO bus */
|
||||
strncpy(ll_temac->mdio_busname, devinf->mdio_busname, MDIO_NAME_LEN);
|
||||
ll_temac->bus = miiphy_get_dev_by_name(ll_temac->mdio_busname);
|
||||
|
||||
/* Looking for a valid PHY address if it is not yet set */
|
||||
if (devinf->phyaddr == -1)
|
||||
ll_temac->phyaddr = ll_temac_phy_addr(ll_temac->bus);
|
||||
else
|
||||
ll_temac->phyaddr = devinf->phyaddr;
|
||||
|
||||
eth_register(dev);
|
||||
|
||||
/* Try to initialize PHY here, and return */
|
||||
return ll_temac_phy_init(dev);
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize a single ll_temac device with its mdio bus behind ll_temac
|
||||
*
|
||||
* Returns 1 if the ll_temac device and the mdio bus were initialized
|
||||
* otherwise returns 0
|
||||
*/
|
||||
int xilinx_ll_temac_eth_init(bd_t *bis, unsigned long base_addr, int flags,
|
||||
unsigned long ctrl_addr)
|
||||
{
|
||||
struct ll_temac_info devinf;
|
||||
struct ll_temac_mdio_info mdioinf;
|
||||
int ret;
|
||||
|
||||
/* prepare the internal driver informations */
|
||||
devinf.flags = flags;
|
||||
devinf.base_addr = base_addr;
|
||||
devinf.ctrl_addr = ctrl_addr;
|
||||
devinf.devname = NULL;
|
||||
devinf.phyaddr = -1;
|
||||
|
||||
mdioinf.name = devinf.mdio_busname = NULL;
|
||||
mdioinf.regs = (struct temac_reg *)devinf.base_addr;
|
||||
|
||||
ret = xilinx_ll_temac_mdio_initialize(bis, &mdioinf);
|
||||
if (ret >= 0) {
|
||||
|
||||
/*
|
||||
* If there was no MDIO bus name then take over the
|
||||
* new automaticaly generated by the MDIO init code.
|
||||
*/
|
||||
if (mdioinf.name != devinf.mdio_busname)
|
||||
devinf.mdio_busname = mdioinf.name;
|
||||
|
||||
ret = xilinx_ll_temac_initialize(bis, &devinf);
|
||||
if (ret > 0)
|
||||
return 1;
|
||||
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
310
drivers/net/xilinx_ll_temac.h
Normal file
310
drivers/net/xilinx_ll_temac.h
Normal file
@@ -0,0 +1,310 @@
|
||||
/*
|
||||
* Xilinx xps_ll_temac ethernet driver for u-boot
|
||||
*
|
||||
* LL_TEMAC interface
|
||||
*
|
||||
* Copyright (C) 2011 - 2012 Stephan Linz <linz@li-pro.net>
|
||||
* Copyright (C) 2008 - 2011 Michal Simek <monstr@monstr.eu>
|
||||
* Copyright (C) 2008 - 2011 PetaLogix
|
||||
*
|
||||
* Based on Yoshio Kashiwagi kashiwagi@co-nss.co.jp driver
|
||||
* Copyright (C) 2008 Nissin Systems Co.,Ltd.
|
||||
* March 2008 created
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* [0]: http://www.xilinx.com/support/documentation
|
||||
*
|
||||
* [S]: [0]/ip_documentation/xps_ll_temac.pdf
|
||||
* [A]: [0]/application_notes/xapp1041.pdf
|
||||
*/
|
||||
#ifndef _XILINX_LL_TEMAC_
|
||||
#define _XILINX_LL_TEMAC_
|
||||
|
||||
#include <config.h>
|
||||
#include <net.h>
|
||||
#include <phy.h>
|
||||
#include <miiphy.h>
|
||||
|
||||
#include <asm/types.h>
|
||||
#include <asm/byteorder.h>
|
||||
|
||||
#include "xilinx_ll_temac_sdma.h"
|
||||
|
||||
#if !defined(__BIG_ENDIAN)
|
||||
# error LL_TEMAC requires big endianess
|
||||
#endif
|
||||
|
||||
/*
|
||||
* TEMAC Memory and Register Definition
|
||||
*
|
||||
* [1]: [0]/ip_documentation/xps_ll_temac.pdf
|
||||
* page 19, Memory and Register Descriptions
|
||||
*/
|
||||
struct temac_reg {
|
||||
/* direct soft registers (low part) */
|
||||
u32 raf; /* Reset and Address Filter */
|
||||
u32 tpf; /* Transmit Pause Frame */
|
||||
u32 ifgp; /* Transmit Inter Frame Gap Adjustment */
|
||||
u32 is; /* Interrupt Status */
|
||||
u32 ip; /* Interrupt Pending */
|
||||
u32 ie; /* Interrupt Enable */
|
||||
u32 ttag; /* Transmit VLAN Tag */
|
||||
u32 rtag; /* Receive VLAN Tag */
|
||||
/* hard TEMAC registers */
|
||||
u32 msw; /* Most Significant Word Data */
|
||||
u32 lsw; /* Least Significant Word Data */
|
||||
u32 ctl; /* Control */
|
||||
u32 rdy; /* Ready Status */
|
||||
/* direct soft registers (high part) */
|
||||
u32 uawl; /* Unicast Address Word Lower */
|
||||
u32 uawu; /* Unicast Address Word Upper */
|
||||
u32 tpid0; /* VLAN TPID Word 0 */
|
||||
u32 tpid1; /* VLAN TPID Word 1 */
|
||||
};
|
||||
|
||||
/* Reset and Address Filter Registers (raf), [1] p25 */
|
||||
#define RAF_SR (1 << 13)
|
||||
#define RAF_EMFE (1 << 12)
|
||||
#define RAF_NFE (1 << 11)
|
||||
#define RAF_RVSTM_POS 9
|
||||
#define RAF_RVSTM_MASK (3 << RAF_RVSTM_POS)
|
||||
#define RAF_TVSTM_POS 7
|
||||
#define RAF_TVSTM_MASK (3 << RAF_TVSTM_POS)
|
||||
#define RAF_RVTM_POS 5
|
||||
#define RAF_RVTM_MASK (3 << RAF_RVTM_POS)
|
||||
#define RAF_TVTM_POS 3
|
||||
#define RAF_TVTM_MASK (3 << RAF_TVTM_POS)
|
||||
#define RAF_BCREJ (1 << 2)
|
||||
#define RAF_MCREJ (1 << 1)
|
||||
#define RAF_HTRST (1 << 0)
|
||||
|
||||
/* Transmit Pause Frame Registers (tpf), [1] p28 */
|
||||
#define TPF_TPFV_POS 0
|
||||
#define TPF_TPFV_MASK (0xFFFF << TPF_TPFV_POS)
|
||||
|
||||
/* Transmit Inter Frame Gap Adjustment Registers (ifgp), [1] p28 */
|
||||
#define IFGP_POS 0
|
||||
#define IFGP_MASK (0xFF << IFGP_POS)
|
||||
|
||||
/* Interrupt Status, Pending, Enable Registers (is, ip, ie), [1] p29-33 */
|
||||
#define ISPE_MR (1 << 7)
|
||||
#define ISPE_RDL (1 << 6)
|
||||
#define ISPE_TC (1 << 5)
|
||||
#define ISPE_RFO (1 << 4)
|
||||
#define ISPE_RR (1 << 3)
|
||||
#define ISPE_RC (1 << 2)
|
||||
#define ISPE_AN (1 << 1)
|
||||
#define ISPE_HAC (1 << 0)
|
||||
|
||||
/* Transmit, Receive VLAN Tag Registers (ttag, rtag), [1] p34-35 */
|
||||
#define TRTAG_TPID_POS 16
|
||||
#define TRTAG_TPID_MASK (0xFFFF << TRTAG_TPID_POS)
|
||||
#define TRTAG_PRIO_POS 13
|
||||
#define TRTAG_PRIO_MASK (7 << TRTAG_PRIO_POS)
|
||||
#define TRTAG_CFI (1 << 12)
|
||||
#define TRTAG_VID_POS 0
|
||||
#define TRTAG_VID_MASK (0xFFF << TRTAG_VID_POS)
|
||||
|
||||
/* Most, Least Significant Word Data Register (msw, lsw), [1] p46 */
|
||||
#define MLSW_POS 0
|
||||
#define MLSW_MASK (~0UL << MLSW_POS)
|
||||
|
||||
/* LSW Data Register for PHY addresses (lsw), [1] p66 */
|
||||
#define LSW_REGAD_POS 0
|
||||
#define LSW_REGAD_MASK (0x1F << LSW_REGAD_POS)
|
||||
#define LSW_PHYAD_POS 5
|
||||
#define LSW_PHYAD_MASK (0x1F << LSW_PHYAD_POS)
|
||||
|
||||
/* LSW Data Register for PHY data (lsw), [1] p66 */
|
||||
#define LSW_REGDAT_POS 0
|
||||
#define LSW_REGDAT_MASK (0xFFFF << LSW_REGDAT_POS)
|
||||
|
||||
/* Control Register (ctl), [1] p47 */
|
||||
#define CTL_WEN (1 << 15)
|
||||
#define CTL_ADDR_POS 0
|
||||
#define CTL_ADDR_MASK (0x3FF << CTL_ADDR_POS)
|
||||
|
||||
/* Ready Status Register Ethernet (rdy), [1] p48 */
|
||||
#define RSE_HACS_RDY (1 << 14)
|
||||
#define RSE_CFG_WR (1 << 6)
|
||||
#define RSE_CFG_RR (1 << 5)
|
||||
#define RSE_AF_WR (1 << 4)
|
||||
#define RSE_AF_RR (1 << 3)
|
||||
#define RSE_MIIM_WR (1 << 2)
|
||||
#define RSE_MIIM_RR (1 << 1)
|
||||
#define RSE_FABR_RR (1 << 0)
|
||||
|
||||
/* Unicast Address Word Lower, Upper Registers (uawl, uawu), [1] p35-36 */
|
||||
#define UAWL_UADDR_POS 0
|
||||
#define UAWL_UADDR_MASK (~0UL << UAWL_UADDR_POS)
|
||||
#define UAWU_UADDR_POS 0
|
||||
#define UAWU_UADDR_MASK (0xFFFF << UAWU_UADDR_POS)
|
||||
|
||||
/* VLAN TPID Word 0, 1 Registers (tpid0, tpid1), [1] p37 */
|
||||
#define TPID0_V0_POS 0
|
||||
#define TPID0_V0_MASK (0xFFFF << TPID0_V0_POS)
|
||||
#define TPID0_V1_POS 16
|
||||
#define TPID0_V1_MASK (0xFFFF << TPID0_V1_POS)
|
||||
#define TPID1_V2_POS 0
|
||||
#define TPID1_V2_MASK (0xFFFF << TPID1_V2_POS)
|
||||
#define TPID1_V3_POS 16
|
||||
#define TPID1_V3_MASK (0xFFFF << TPID1_V3_POS)
|
||||
|
||||
/*
|
||||
* TEMAC Indirectly Addressable Register Index Enumeration
|
||||
*
|
||||
* [0]: http://www.xilinx.com/support/documentation
|
||||
*
|
||||
* [1]: [0]/ip_documentation/xps_ll_temac.pdf
|
||||
* page 23, PLB Indirectly Addressable TEMAC Registers
|
||||
*/
|
||||
enum temac_ctrl {
|
||||
TEMAC_RCW0 = 0x200,
|
||||
TEMAC_RCW1 = 0x240,
|
||||
TEMAC_TC = 0x280,
|
||||
TEMAC_FCC = 0x2C0,
|
||||
TEMAC_EMMC = 0x300,
|
||||
TEMAC_PHYC = 0x320,
|
||||
TEMAC_MC = 0x340,
|
||||
TEMAC_UAW0 = 0x380,
|
||||
TEMAC_UAW1 = 0x384,
|
||||
TEMAC_MAW0 = 0x388,
|
||||
TEMAC_MAW1 = 0x38C,
|
||||
TEMAC_AFM = 0x390,
|
||||
TEMAC_TIS = 0x3A0,
|
||||
TEMAC_TIE = 0x3A4,
|
||||
TEMAC_MIIMWD = 0x3B0,
|
||||
TEMAC_MIIMAI = 0x3B4
|
||||
};
|
||||
|
||||
/* Receive Configuration Word 0, 1 Registers (RCW0, RCW1), [1] p50-51 */
|
||||
#define RCW0_PADDR_POS 0
|
||||
#define RCW0_PADDR_MASK (~0UL << RCW_PADDR_POS)
|
||||
#define RCW1_RST (1 << 31)
|
||||
#define RCW1_JUM (1 << 30)
|
||||
#define RCW1_FCS (1 << 29)
|
||||
#define RCW1_RX (1 << 28)
|
||||
#define RCW1_VLAN (1 << 27)
|
||||
#define RCW1_HD (1 << 26)
|
||||
#define RCW1_LT_DIS (1 << 25)
|
||||
#define RCW1_PADDR_POS 0
|
||||
#define RCW1_PADDR_MASK (0xFFFF << RCW_PADDR_POS)
|
||||
|
||||
/* Transmit Configuration Registers (TC), [1] p52 */
|
||||
#define TC_RST (1 << 31)
|
||||
#define TC_JUM (1 << 30)
|
||||
#define TC_FCS (1 << 29)
|
||||
#define TC_TX (1 << 28)
|
||||
#define TC_VLAN (1 << 27)
|
||||
#define TC_HD (1 << 26)
|
||||
#define TC_IFG (1 << 25)
|
||||
|
||||
/* Flow Control Configuration Registers (FCC), [1] p54 */
|
||||
#define FCC_FCTX (1 << 30)
|
||||
#define FCC_FCRX (1 << 29)
|
||||
|
||||
/* Ethernet MAC Mode Configuration Registers (EMMC), [1] p54 */
|
||||
#define EMMC_LSPD_POS 30
|
||||
#define EMMC_LSPD_MASK (3 << EMMC_LSPD_POS)
|
||||
#define EMMC_LSPD_1000 (2 << EMMC_LSPD_POS)
|
||||
#define EMMC_LSPD_100 (1 << EMMC_LSPD_POS)
|
||||
#define EMMC_LSPD_10 0
|
||||
#define EMMC_RGMII (1 << 29)
|
||||
#define EMMC_SGMII (1 << 28)
|
||||
#define EMMC_GPCS (1 << 27)
|
||||
#define EMMC_HOST (1 << 26)
|
||||
#define EMMC_TX16 (1 << 25)
|
||||
#define EMMC_RX16 (1 << 24)
|
||||
|
||||
/* RGMII/SGMII Configuration Registers (PHYC), [1] p56 */
|
||||
#define PHYC_SLSPD_POS 30
|
||||
#define PHYC_SLSPD_MASK (3 << EMMC_SLSPD_POS)
|
||||
#define PHYC_SLSPD_1000 (2 << EMMC_SLSPD_POS)
|
||||
#define PHYC_SLSPD_100 (1 << EMMC_SLSPD_POS)
|
||||
#define PHYC_SLSPD_10 0
|
||||
#define PHYC_RLSPD_POS 2
|
||||
#define PHYC_RLSPD_MASK (3 << EMMC_RLSPD_POS)
|
||||
#define PHYC_RLSPD_1000 (2 << EMMC_RLSPD_POS)
|
||||
#define PHYC_RLSPD_100 (1 << EMMC_RLSPD_POS)
|
||||
#define PHYC_RLSPD_10 0
|
||||
#define PHYC_RGMII_HD (1 << 1)
|
||||
#define PHYC_RGMII_LINK (1 << 0)
|
||||
|
||||
/* Management Configuration Registers (MC), [1] p57 */
|
||||
#define MC_MDIOEN (1 << 6)
|
||||
#define MC_CLKDIV_POS 0
|
||||
#define MC_CLKDIV_MASK (0x3F << MC_CLKDIV_POS)
|
||||
|
||||
/*
|
||||
* fHOSTCLK fMDC = fHOSTCLK
|
||||
* fMDC = ------------------- ---------> MC_CLKDIV = -------- - 1
|
||||
* (1 + MC_CLKDIV) * 2 2.5 MHz 5MHz
|
||||
*/
|
||||
#define MC_CLKDIV(f, m) ((f / (2 * m)) - 1)
|
||||
#define MC_CLKDIV_25(f) MC_CLKDIV(f, 2500000)
|
||||
#define MC_CLKDIV_20(f) MC_CLKDIV(f, 2000000)
|
||||
#define MC_CLKDIV_15(f) MC_CLKDIV(f, 1500000)
|
||||
#define MC_CLKDIV_10(f) MC_CLKDIV(f, 1000000)
|
||||
|
||||
/* Unicast Address Word 0, 1 Registers (UAW0, UAW1), [1] p58-59 */
|
||||
#define UAW0_UADDR_POS 0
|
||||
#define UAW0_UADDR_MASK (~0UL << UAW0_UADDR_POS)
|
||||
#define UAW1_UADDR_POS 0
|
||||
#define UAW1_UADDR_MASK (0xFFFF << UAW1_UADDR_POS)
|
||||
|
||||
/* Multicast Address Word 0, 1 Registers (MAW0, MAW1), [1] p60 */
|
||||
#define MAW0_MADDR_POS 0
|
||||
#define MAW0_MADDR_MASK (~0UL << MAW0_MADDR_POS)
|
||||
#define MAW1_RNW (1 << 23)
|
||||
#define MAW1_MAIDX_POS 16
|
||||
#define MAW1_MAIDX_MASK (3 << MAW1_MAIDX_POS)
|
||||
#define MAW1_MADDR_POS 0
|
||||
#define MAW1_MADDR_MASK (0xFFFF << MAW1_MADDR_POS)
|
||||
|
||||
/* Address Filter Mode Registers (AFM), [1] p63 */
|
||||
#define AFM_PM (1 << 31)
|
||||
|
||||
/* Interrupt Status, Enable Registers (TIS, TIE), [1] p63-65 */
|
||||
#define TISE_CFG_W (1 << 6)
|
||||
#define TISE_CFG_R (1 << 5)
|
||||
#define TISE_AF_W (1 << 4)
|
||||
#define TISE_AF_R (1 << 3)
|
||||
#define TISE_MIIM_W (1 << 2)
|
||||
#define TISE_MIIM_R (1 << 1)
|
||||
#define TISE_FABR_R (1 << 0)
|
||||
|
||||
/* MII Management Write Data Registers (MIIMWD), [1] p66 */
|
||||
#define MIIMWD_DATA_POS 0
|
||||
#define MIIMWD_DATA_MASK (0xFFFF << MIIMWD_DATA_POS)
|
||||
|
||||
/* Ethernet interface ready status */
|
||||
int ll_temac_check_status(struct temac_reg *regs, u32 mask);
|
||||
|
||||
/* Indirect write to ll_temac. */
|
||||
int ll_temac_indirect_set(struct temac_reg *regs, u16 regn, u32 reg_data);
|
||||
|
||||
/* Indirect read from ll_temac. */
|
||||
int ll_temac_indirect_get(struct temac_reg *regs, u16 regn, u32* reg_data);
|
||||
|
||||
struct ll_temac {
|
||||
phys_addr_t ctrladdr;
|
||||
phys_addr_t sdma_reg_addr[SDMA_CTRL_REGNUMS];
|
||||
|
||||
unsigned (*in32)(phys_addr_t);
|
||||
void (*out32)(phys_addr_t, unsigned);
|
||||
|
||||
int (*ctrlinit) (struct eth_device *);
|
||||
int (*ctrlhalt) (struct eth_device *);
|
||||
int (*ctrlreset) (struct eth_device *);
|
||||
|
||||
int phyaddr;
|
||||
struct phy_device *phydev;
|
||||
struct mii_dev *bus;
|
||||
char mdio_busname[MDIO_NAME_LEN];
|
||||
};
|
||||
|
||||
#endif /* _XILINX_LL_TEMAC_ */
|
||||
143
drivers/net/xilinx_ll_temac_fifo.c
Normal file
143
drivers/net/xilinx_ll_temac_fifo.c
Normal file
@@ -0,0 +1,143 @@
|
||||
/*
|
||||
* Xilinx xps_ll_temac ethernet driver for u-boot
|
||||
*
|
||||
* FIFO sub-controller
|
||||
*
|
||||
* Copyright (C) 2011 - 2012 Stephan Linz <linz@li-pro.net>
|
||||
* Copyright (C) 2008 - 2011 Michal Simek <monstr@monstr.eu>
|
||||
* Copyright (C) 2008 - 2011 PetaLogix
|
||||
*
|
||||
* Based on Yoshio Kashiwagi kashiwagi@co-nss.co.jp driver
|
||||
* Copyright (C) 2008 Nissin Systems Co.,Ltd.
|
||||
* March 2008 created
|
||||
*
|
||||
* CREDITS: tsec driver
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* [0]: http://www.xilinx.com/support/documentation
|
||||
*
|
||||
* [F]: [0]/ip_documentation/xps_ll_fifo.pdf
|
||||
* [S]: [0]/ip_documentation/xps_ll_temac.pdf
|
||||
* [A]: [0]/application_notes/xapp1041.pdf
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include <common.h>
|
||||
#include <net.h>
|
||||
|
||||
#include <asm/types.h>
|
||||
#include <asm/io.h>
|
||||
|
||||
#include "xilinx_ll_temac.h"
|
||||
#include "xilinx_ll_temac_fifo.h"
|
||||
|
||||
int ll_temac_reset_fifo(struct eth_device *dev)
|
||||
{
|
||||
struct ll_temac *ll_temac = dev->priv;
|
||||
struct fifo_ctrl *fifo_ctrl = (void *)ll_temac->ctrladdr;
|
||||
|
||||
out_be32(&fifo_ctrl->tdfr, LL_FIFO_TDFR_KEY);
|
||||
out_be32(&fifo_ctrl->rdfr, LL_FIFO_RDFR_KEY);
|
||||
out_be32(&fifo_ctrl->isr, ~0UL);
|
||||
out_be32(&fifo_ctrl->ier, 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ll_temac_recv_fifo(struct eth_device *dev)
|
||||
{
|
||||
int i, length = 0;
|
||||
u32 *buf = (u32 *)NetRxPackets[0];
|
||||
struct ll_temac *ll_temac = dev->priv;
|
||||
struct fifo_ctrl *fifo_ctrl = (void *)ll_temac->ctrladdr;
|
||||
|
||||
if (in_be32(&fifo_ctrl->isr) & LL_FIFO_ISR_RC) {
|
||||
|
||||
/* reset isr */
|
||||
out_be32(&fifo_ctrl->isr, ~0UL);
|
||||
|
||||
/*
|
||||
* MAYBE here:
|
||||
* while (fifo_ctrl->isr);
|
||||
*/
|
||||
|
||||
/*
|
||||
* The length is written (into RLR) by the XPS LL FIFO
|
||||
* when the packet is received across the RX LocalLink
|
||||
* interface and the receive data FIFO had enough
|
||||
* locations that all of the packet data has been saved.
|
||||
* The RLR should only be read when a receive packet is
|
||||
* available for processing (the receive occupancy is
|
||||
* not zero). Once the RLR is read, the receive packet
|
||||
* data should be read from the receive data FIFO before
|
||||
* the RLR is read again.
|
||||
*
|
||||
* [F] page 17, Receive Length Register (RLR)
|
||||
*/
|
||||
if (in_be32(&fifo_ctrl->rdfo) & LL_FIFO_RDFO_MASK) {
|
||||
length = in_be32(&fifo_ctrl->rlf) & LL_FIFO_RLF_MASK;
|
||||
} else {
|
||||
printf("%s: Got error, no receive occupancy\n",
|
||||
__func__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (length > PKTSIZE_ALIGN) {
|
||||
printf("%s: Got error, receive package too big (%i)\n",
|
||||
__func__, length);
|
||||
ll_temac_reset_fifo(dev);
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (i = 0; i < length; i += 4)
|
||||
*buf++ = in_be32(&fifo_ctrl->rdfd);
|
||||
|
||||
NetReceive(NetRxPackets[0], length);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ll_temac_send_fifo(struct eth_device *dev, volatile void *packet,
|
||||
int length)
|
||||
{
|
||||
int i;
|
||||
u32 *buf = (u32 *)packet;
|
||||
struct ll_temac *ll_temac = dev->priv;
|
||||
struct fifo_ctrl *fifo_ctrl = (void *)ll_temac->ctrladdr;
|
||||
|
||||
if (length < LL_FIFO_TLF_MIN) {
|
||||
printf("%s: Got error, transmit package too small (%i)\n",
|
||||
__func__, length);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (length > LL_FIFO_TLF_MAX) {
|
||||
printf("%s: Got error, transmit package too big (%i)\n",
|
||||
__func__, length);
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (i = 0; i < length; i += 4)
|
||||
out_be32(&fifo_ctrl->tdfd, *buf++);
|
||||
|
||||
/*
|
||||
* Once the packet length is written to the TLR it is
|
||||
* automatically moved to the transmit data FIFO with
|
||||
* the packet data freeing up the TLR for another value.
|
||||
* The packet length must be written to the TLR after
|
||||
* the packet data is written to the transmit data FIFO.
|
||||
* It is not valid to write data for multiple packets
|
||||
* to the transmit data FIFO before writing the packet
|
||||
* length values.
|
||||
*
|
||||
* [F] page 17, Transmit Length Register (TLR)
|
||||
*/
|
||||
out_be32(&fifo_ctrl->tlf, length);
|
||||
|
||||
return 0;
|
||||
}
|
||||
122
drivers/net/xilinx_ll_temac_fifo.h
Normal file
122
drivers/net/xilinx_ll_temac_fifo.h
Normal file
@@ -0,0 +1,122 @@
|
||||
/*
|
||||
* Xilinx xps_ll_temac ethernet driver for u-boot
|
||||
*
|
||||
* FIFO sub-controller interface
|
||||
*
|
||||
* Copyright (C) 2011 - 2012 Stephan Linz <linz@li-pro.net>
|
||||
* Copyright (C) 2008 - 2011 Michal Simek <monstr@monstr.eu>
|
||||
* Copyright (C) 2008 - 2011 PetaLogix
|
||||
*
|
||||
* Based on Yoshio Kashiwagi kashiwagi@co-nss.co.jp driver
|
||||
* Copyright (C) 2008 Nissin Systems Co.,Ltd.
|
||||
* March 2008 created
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* [0]: http://www.xilinx.com/support/documentation
|
||||
*
|
||||
* [S]: [0]/ip_documentation/xps_ll_temac.pdf
|
||||
* [A]: [0]/application_notes/xapp1041.pdf
|
||||
*/
|
||||
#ifndef _XILINX_LL_TEMAC_FIFO_
|
||||
#define _XILINX_LL_TEMAC_FIFO_
|
||||
|
||||
#include <net.h>
|
||||
|
||||
#include <asm/types.h>
|
||||
#include <asm/byteorder.h>
|
||||
|
||||
#if !defined(__BIG_ENDIAN)
|
||||
# error LL_TEMAC requires big endianess
|
||||
#endif
|
||||
|
||||
/*
|
||||
* FIFO Register Definition
|
||||
*
|
||||
* Used for memory mapped access from and to (Rd/Td) the LocalLink (LL)
|
||||
* Tri-Mode Ether MAC (TEMAC) via the 2 kb full duplex FIFO Controller,
|
||||
* one for each.
|
||||
*
|
||||
* [1]: [0]/ip_documentation/xps_ll_fifo.pdf
|
||||
* page 10, Registers Definition
|
||||
*/
|
||||
struct fifo_ctrl {
|
||||
u32 isr; /* Interrupt Status Register (RW) */
|
||||
u32 ier; /* Interrupt Enable Register (RW) */
|
||||
u32 tdfr; /* Transmit Data FIFO Reset (WO) */
|
||||
u32 tdfv; /* Transmit Data FIFO Vacancy (RO) */
|
||||
u32 tdfd; /* Transmit Data FIFO 32bit wide Data write port (WO) */
|
||||
u32 tlf; /* Transmit Length FIFO (WO) */
|
||||
u32 rdfr; /* Receive Data FIFO Reset (WO) */
|
||||
u32 rdfo; /* Receive Data FIFO Occupancy (RO) */
|
||||
u32 rdfd; /* Receive Data FIFO 32bit wide Data read port (RO) */
|
||||
u32 rlf; /* Receive Length FIFO (RO) */
|
||||
u32 llr; /* LocalLink Reset (WO) */
|
||||
};
|
||||
|
||||
/* Interrupt Status Register (ISR), [1] p11 */
|
||||
#define LL_FIFO_ISR_RPURE (1 << 31) /* Receive Packet Underrun Read Err */
|
||||
#define LL_FIFO_ISR_RPORE (1 << 30) /* Receive Packet Overrun Read Err */
|
||||
#define LL_FIFO_ISR_RPUE (1 << 29) /* Receive Packet Underrun Error */
|
||||
#define LL_FIFO_ISR_TPOE (1 << 28) /* Transmit Packet Overrun Error */
|
||||
#define LL_FIFO_ISR_TC (1 << 27) /* Transmit Complete */
|
||||
#define LL_FIFO_ISR_RC (1 << 26) /* Receive Complete */
|
||||
#define LL_FIFO_ISR_TSE (1 << 25) /* Transmit Size Error */
|
||||
#define LL_FIFO_ISR_TRC (1 << 24) /* Transmit Reset Complete */
|
||||
#define LL_FIFO_ISR_RRC (1 << 23) /* Receive Reset Complete */
|
||||
|
||||
/* Interrupt Enable Register (IER), [1] p12/p13 */
|
||||
#define LL_FIFO_IER_RPURE (1 << 31) /* Receive Packet Underrun Read Err */
|
||||
#define LL_FIFO_IER_RPORE (1 << 30) /* Receive Packet Overrun Read Err */
|
||||
#define LL_FIFO_IER_RPUE (1 << 29) /* Receive Packet Underrun Error */
|
||||
#define LL_FIFO_IER_TPOE (1 << 28) /* Transmit Packet Overrun Error */
|
||||
#define LL_FIFO_IER_TC (1 << 27) /* Transmit Complete */
|
||||
#define LL_FIFO_IER_RC (1 << 26) /* Receive Complete */
|
||||
#define LL_FIFO_IER_TSE (1 << 25) /* Transmit Size Error */
|
||||
#define LL_FIFO_IER_TRC (1 << 24) /* Transmit Reset Complete */
|
||||
#define LL_FIFO_IER_RRC (1 << 23) /* Receive Reset Complete */
|
||||
|
||||
/* Transmit Data FIFO Reset (TDFR), [1] p13/p14 */
|
||||
#define LL_FIFO_TDFR_KEY 0x000000A5UL
|
||||
|
||||
/* Transmit Data FIFO Vacancy (TDFV), [1] p14 */
|
||||
#define LL_FIFO_TDFV_POS 0
|
||||
#define LL_FIFO_TDFV_MASK (0x000001FFUL << LL_FIFO_TDFV_POS)
|
||||
|
||||
/* Transmit Length FIFO (TLF), [1] p16/p17 */
|
||||
#define LL_FIFO_TLF_POS 0
|
||||
#define LL_FIFO_TLF_MASK (0x000007FFUL << LL_FIFO_TLF_POS)
|
||||
#define LL_FIFO_TLF_MIN ((4 * sizeof(u32)) & LL_FIFO_TLF_MASK)
|
||||
#define LL_FIFO_TLF_MAX ((510 * sizeof(u32)) & LL_FIFO_TLF_MASK)
|
||||
|
||||
/* Receive Data FIFO Reset (RDFR), [1] p15 */
|
||||
#define LL_FIFO_RDFR_KEY 0x000000A5UL
|
||||
|
||||
/* Receive Data FIFO Occupancy (RDFO), [1] p16 */
|
||||
#define LL_FIFO_RDFO_POS 0
|
||||
#define LL_FIFO_RDFO_MASK (0x000001FFUL << LL_FIFO_RDFO_POS)
|
||||
|
||||
/* Receive Length FIFO (RLF), [1] p17/p18 */
|
||||
#define LL_FIFO_RLF_POS 0
|
||||
#define LL_FIFO_RLF_MASK (0x000007FFUL << LL_FIFO_RLF_POS)
|
||||
#define LL_FIFO_RLF_MIN ((4 * sizeof(uint32)) & LL_FIFO_RLF_MASK)
|
||||
#define LL_FIFO_RLF_MAX ((510 * sizeof(uint32)) & LL_FIFO_RLF_MASK)
|
||||
|
||||
/* LocalLink Reset (LLR), [1] p18 */
|
||||
#define LL_FIFO_LLR_KEY 0x000000A5UL
|
||||
|
||||
|
||||
/* reset FIFO and IRQ, disable interrupts */
|
||||
int ll_temac_reset_fifo(struct eth_device *dev);
|
||||
|
||||
/* receive buffered data from FIFO (polling ISR) */
|
||||
int ll_temac_recv_fifo(struct eth_device *dev);
|
||||
|
||||
/* send buffered data to FIFO */
|
||||
int ll_temac_send_fifo(struct eth_device *dev, volatile void *packet,
|
||||
int length);
|
||||
|
||||
#endif /* _XILINX_LL_TEMAC_FIFO_ */
|
||||
180
drivers/net/xilinx_ll_temac_mdio.c
Normal file
180
drivers/net/xilinx_ll_temac_mdio.c
Normal file
@@ -0,0 +1,180 @@
|
||||
/*
|
||||
* Xilinx xps_ll_temac ethernet driver for u-boot
|
||||
*
|
||||
* MDIO bus access
|
||||
*
|
||||
* Copyright (C) 2011 - 2012 Stephan Linz <linz@li-pro.net>
|
||||
* Copyright (C) 2008 - 2011 Michal Simek <monstr@monstr.eu>
|
||||
* Copyright (C) 2008 - 2011 PetaLogix
|
||||
*
|
||||
* Based on Yoshio Kashiwagi kashiwagi@co-nss.co.jp driver
|
||||
* Copyright (C) 2008 Nissin Systems Co.,Ltd.
|
||||
* March 2008 created
|
||||
*
|
||||
* CREDITS: tsec driver
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* [0]: http://www.xilinx.com/support/documentation
|
||||
*
|
||||
* [S]: [0]/ip_documentation/xps_ll_temac.pdf
|
||||
* [A]: [0]/application_notes/xapp1041.pdf
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include <common.h>
|
||||
#include <miiphy.h>
|
||||
#include <phy.h>
|
||||
#include <malloc.h>
|
||||
#include <asm/io.h>
|
||||
|
||||
#include "xilinx_ll_temac.h"
|
||||
#include "xilinx_ll_temac_mdio.h"
|
||||
|
||||
#if !defined(CONFIG_MII)
|
||||
# error "LL_TEMAC requires MII -- missing CONFIG_MII"
|
||||
#endif
|
||||
|
||||
#if !defined(CONFIG_PHYLIB)
|
||||
# error "LL_TEMAC requires PHYLIB -- missing CONFIG_PHYLIB"
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Prior to PHY access, the MDIO clock must be setup. This driver will set a
|
||||
* safe default that should work with PLB bus speeds of up to 150 MHz and keep
|
||||
* the MDIO clock below 2.5 MHz. If the user wishes faster access to the PHY
|
||||
* then the clock divisor can be set to a different value by setting the
|
||||
* correct bus speed value with CONFIG_XILINX_LL_TEMAC_CLK.
|
||||
*/
|
||||
#if !defined(CONFIG_XILINX_LL_TEMAC_CLK)
|
||||
#define MDIO_CLOCK_DIV MC_CLKDIV_10(150000000)
|
||||
#else
|
||||
#define MDIO_CLOCK_DIV MC_CLKDIV_25(CONFIG_XILINX_LL_TEMAC_CLK)
|
||||
#endif
|
||||
|
||||
static int ll_temac_mdio_setup(struct mii_dev *bus)
|
||||
{
|
||||
struct temac_reg *regs = (struct temac_reg *)bus->priv;
|
||||
|
||||
/* setup MDIO clock */
|
||||
ll_temac_indirect_set(regs, TEMAC_MC,
|
||||
MC_MDIOEN | (MDIO_CLOCK_DIV & MC_CLKDIV_MASK));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Indirect MII PHY read via ll_temac.
|
||||
*
|
||||
* http://www.xilinx.com/support/documentation/ip_documentation/xps_ll_temac.pdf
|
||||
* page 67, Using the MII Management to Access PHY Registers
|
||||
*/
|
||||
int ll_temac_local_mdio_read(struct temac_reg *regs, int addr, int devad,
|
||||
int regnum)
|
||||
{
|
||||
out_be32(®s->lsw,
|
||||
((addr << LSW_PHYAD_POS) & LSW_PHYAD_MASK) |
|
||||
(regnum & LSW_REGAD_MASK));
|
||||
out_be32(®s->ctl, TEMAC_MIIMAI);
|
||||
|
||||
ll_temac_check_status(regs, RSE_MIIM_RR);
|
||||
|
||||
return in_be32(®s->lsw) & LSW_REGDAT_MASK;
|
||||
}
|
||||
|
||||
/*
|
||||
* Indirect MII PHY write via ll_temac.
|
||||
*
|
||||
* http://www.xilinx.com/support/documentation/ip_documentation/xps_ll_temac.pdf
|
||||
* page 67, Using the MII Management to Access PHY Registers
|
||||
*/
|
||||
void ll_temac_local_mdio_write(struct temac_reg *regs, int addr, int devad,
|
||||
int regnum, u16 value)
|
||||
{
|
||||
out_be32(®s->lsw, (value & LSW_REGDAT_MASK));
|
||||
out_be32(®s->ctl, CTL_WEN | TEMAC_MIIMWD);
|
||||
|
||||
out_be32(®s->lsw,
|
||||
((addr << LSW_PHYAD_POS) & LSW_PHYAD_MASK) |
|
||||
(regnum & LSW_REGAD_MASK));
|
||||
out_be32(®s->ctl, CTL_WEN | TEMAC_MIIMAI);
|
||||
|
||||
ll_temac_check_status(regs, RSE_MIIM_WR);
|
||||
}
|
||||
|
||||
int ll_temac_phy_read(struct mii_dev *bus, int addr, int devad, int regnum)
|
||||
{
|
||||
struct temac_reg *regs = (struct temac_reg *)bus->priv;
|
||||
|
||||
return ll_temac_local_mdio_read(regs, addr, devad, regnum);
|
||||
}
|
||||
|
||||
int ll_temac_phy_write(struct mii_dev *bus, int addr, int devad, int regnum,
|
||||
u16 value)
|
||||
{
|
||||
struct temac_reg *regs = (struct temac_reg *)bus->priv;
|
||||
|
||||
ll_temac_local_mdio_write(regs, addr, devad, regnum, value);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Use MII register 1 (MII status register) to detect PHY
|
||||
*
|
||||
* A Mask used to verify certain PHY features (register content)
|
||||
* in the PHY detection register:
|
||||
* Auto-negotiation support, 10Mbps half/full duplex support
|
||||
*/
|
||||
#define PHY_DETECT_REG MII_BMSR
|
||||
#define PHY_DETECT_MASK (BMSR_10FULL | BMSR_10HALF | BMSR_ANEGCAPABLE)
|
||||
|
||||
/* Looking for a valid PHY address */
|
||||
int ll_temac_phy_addr(struct mii_dev *bus)
|
||||
{
|
||||
struct temac_reg *regs = (struct temac_reg *)bus->priv;
|
||||
unsigned short val;
|
||||
unsigned int phy;
|
||||
|
||||
for (phy = PHY_MAX_ADDR; phy >= 0; phy--) {
|
||||
val = ll_temac_local_mdio_read(regs, phy, 0, PHY_DETECT_REG);
|
||||
if ((val != 0xFFFF) &&
|
||||
((val & PHY_DETECT_MASK) == PHY_DETECT_MASK)) {
|
||||
/* Found a valid PHY address */
|
||||
return phy;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
int xilinx_ll_temac_mdio_initialize(bd_t *bis, struct ll_temac_mdio_info *info)
|
||||
{
|
||||
struct mii_dev *bus = mdio_alloc();
|
||||
|
||||
if (!bus) {
|
||||
printf("Failed to allocate LL_TEMAC MDIO bus: %s\n",
|
||||
info->name);
|
||||
return -1;
|
||||
}
|
||||
|
||||
bus->read = ll_temac_phy_read;
|
||||
bus->write = ll_temac_phy_write;
|
||||
bus->reset = NULL;
|
||||
|
||||
/* use given name or generate its own unique name */
|
||||
if (info->name) {
|
||||
strncpy(bus->name, info->name, MDIO_NAME_LEN);
|
||||
} else {
|
||||
snprintf(bus->name, MDIO_NAME_LEN, "lltemii.%p", info->regs);
|
||||
info->name = bus->name;
|
||||
}
|
||||
|
||||
bus->priv = info->regs;
|
||||
|
||||
ll_temac_mdio_setup(bus);
|
||||
return mdio_register(bus);
|
||||
}
|
||||
53
drivers/net/xilinx_ll_temac_mdio.h
Normal file
53
drivers/net/xilinx_ll_temac_mdio.h
Normal file
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
* Xilinx xps_ll_temac ethernet driver for u-boot
|
||||
*
|
||||
* MDIO bus access interface
|
||||
*
|
||||
* Copyright (C) 2011 - 2012 Stephan Linz <linz@li-pro.net>
|
||||
* Copyright (C) 2008 - 2011 Michal Simek <monstr@monstr.eu>
|
||||
* Copyright (C) 2008 - 2011 PetaLogix
|
||||
*
|
||||
* Based on Yoshio Kashiwagi kashiwagi@co-nss.co.jp driver
|
||||
* Copyright (C) 2008 Nissin Systems Co.,Ltd.
|
||||
* March 2008 created
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* [0]: http://www.xilinx.com/support/documentation
|
||||
*
|
||||
* [S]: [0]/ip_documentation/xps_ll_temac.pdf
|
||||
* [A]: [0]/application_notes/xapp1041.pdf
|
||||
*/
|
||||
#ifndef _XILINX_LL_TEMAC_MDIO_
|
||||
#define _XILINX_LL_TEMAC_MDIO_
|
||||
|
||||
#include <net.h>
|
||||
#include <miiphy.h>
|
||||
|
||||
#include <asm/types.h>
|
||||
#include <asm/byteorder.h>
|
||||
|
||||
#include "xilinx_ll_temac.h"
|
||||
|
||||
int ll_temac_local_mdio_read(struct temac_reg *regs, int addr, int devad,
|
||||
int regnum);
|
||||
void ll_temac_local_mdio_write(struct temac_reg *regs, int addr, int devad,
|
||||
int regnum, u16 value);
|
||||
|
||||
int ll_temac_phy_read(struct mii_dev *bus, int addr, int devad, int regnum);
|
||||
int ll_temac_phy_write(struct mii_dev *bus, int addr, int devad, int regnum,
|
||||
u16 value);
|
||||
|
||||
int ll_temac_phy_addr(struct mii_dev *bus);
|
||||
|
||||
struct ll_temac_mdio_info {
|
||||
struct temac_reg *regs;
|
||||
char *name;
|
||||
};
|
||||
|
||||
int xilinx_ll_temac_mdio_initialize(bd_t *bis, struct ll_temac_mdio_info *info);
|
||||
|
||||
#endif /* _XILINX_LL_TEMAC_MDIO_ */
|
||||
370
drivers/net/xilinx_ll_temac_sdma.c
Normal file
370
drivers/net/xilinx_ll_temac_sdma.c
Normal file
@@ -0,0 +1,370 @@
|
||||
/*
|
||||
* Xilinx xps_ll_temac ethernet driver for u-boot
|
||||
*
|
||||
* SDMA sub-controller
|
||||
*
|
||||
* Copyright (C) 2011 - 2012 Stephan Linz <linz@li-pro.net>
|
||||
* Copyright (C) 2008 - 2011 Michal Simek <monstr@monstr.eu>
|
||||
* Copyright (C) 2008 - 2011 PetaLogix
|
||||
*
|
||||
* Based on Yoshio Kashiwagi kashiwagi@co-nss.co.jp driver
|
||||
* Copyright (C) 2008 Nissin Systems Co.,Ltd.
|
||||
* March 2008 created
|
||||
*
|
||||
* CREDITS: tsec driver
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* [0]: http://www.xilinx.com/support/documentation
|
||||
*
|
||||
* [M]: [0]/ip_documentation/mpmc.pdf
|
||||
* [S]: [0]/ip_documentation/xps_ll_temac.pdf
|
||||
* [A]: [0]/application_notes/xapp1041.pdf
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include <common.h>
|
||||
#include <net.h>
|
||||
|
||||
#include <asm/types.h>
|
||||
#include <asm/io.h>
|
||||
|
||||
#include "xilinx_ll_temac.h"
|
||||
#include "xilinx_ll_temac_sdma.h"
|
||||
|
||||
#define TX_BUF_CNT 2
|
||||
|
||||
static unsigned int rx_idx; /* index of the current RX buffer */
|
||||
static unsigned int tx_idx; /* index of the current TX buffer */
|
||||
|
||||
struct rtx_cdmac_bd {
|
||||
struct cdmac_bd rx[PKTBUFSRX];
|
||||
struct cdmac_bd tx[TX_BUF_CNT];
|
||||
};
|
||||
|
||||
/*
|
||||
* DMA Buffer Descriptor alignment
|
||||
*
|
||||
* If the address contained in the Next Descriptor Pointer register is not
|
||||
* 8-word aligned or reaches beyond the range of available memory, the SDMA
|
||||
* halts processing and sets the CDMAC_BD_STCTRL_ERROR bit in the respective
|
||||
* status register (tx_chnl_sts or rx_chnl_sts).
|
||||
*
|
||||
* [1]: [0]/ip_documentation/mpmc.pdf
|
||||
* page 161, Next Descriptor Pointer
|
||||
*/
|
||||
static struct rtx_cdmac_bd cdmac_bd __aligned(32);
|
||||
|
||||
#if defined(CONFIG_XILINX_440) || defined(CONFIG_XILINX_405)
|
||||
|
||||
/*
|
||||
* Indirect DCR access operations mi{ft}dcr_xilinx() espacialy
|
||||
* for Xilinx PowerPC implementations on FPGA.
|
||||
*
|
||||
* FIXME: This part should go up to arch/powerpc -- but where?
|
||||
*/
|
||||
#include <asm/processor.h>
|
||||
#define XILINX_INDIRECT_DCR_ADDRESS_REG 0
|
||||
#define XILINX_INDIRECT_DCR_ACCESS_REG 1
|
||||
inline unsigned mifdcr_xilinx(const unsigned dcrn)
|
||||
{
|
||||
mtdcr(XILINX_INDIRECT_DCR_ADDRESS_REG, dcrn);
|
||||
return mfdcr(XILINX_INDIRECT_DCR_ACCESS_REG);
|
||||
}
|
||||
inline void mitdcr_xilinx(const unsigned dcrn, int val)
|
||||
{
|
||||
mtdcr(XILINX_INDIRECT_DCR_ADDRESS_REG, dcrn);
|
||||
mtdcr(XILINX_INDIRECT_DCR_ACCESS_REG, val);
|
||||
}
|
||||
|
||||
/* Xilinx Device Control Register (DCR) in/out accessors */
|
||||
inline unsigned ll_temac_xldcr_in32(phys_addr_t addr)
|
||||
{
|
||||
return mifdcr_xilinx((const unsigned)addr);
|
||||
}
|
||||
inline void ll_temac_xldcr_out32(phys_addr_t addr, unsigned value)
|
||||
{
|
||||
mitdcr_xilinx((const unsigned)addr, value);
|
||||
}
|
||||
|
||||
void ll_temac_collect_xldcr_sdma_reg_addr(struct eth_device *dev)
|
||||
{
|
||||
struct ll_temac *ll_temac = dev->priv;
|
||||
phys_addr_t dmac_ctrl = ll_temac->ctrladdr;
|
||||
phys_addr_t *ra = ll_temac->sdma_reg_addr;
|
||||
|
||||
ra[TX_NXTDESC_PTR] = dmac_ctrl + TX_NXTDESC_PTR;
|
||||
ra[TX_CURBUF_ADDR] = dmac_ctrl + TX_CURBUF_ADDR;
|
||||
ra[TX_CURBUF_LENGTH] = dmac_ctrl + TX_CURBUF_LENGTH;
|
||||
ra[TX_CURDESC_PTR] = dmac_ctrl + TX_CURDESC_PTR;
|
||||
ra[TX_TAILDESC_PTR] = dmac_ctrl + TX_TAILDESC_PTR;
|
||||
ra[TX_CHNL_CTRL] = dmac_ctrl + TX_CHNL_CTRL;
|
||||
ra[TX_IRQ_REG] = dmac_ctrl + TX_IRQ_REG;
|
||||
ra[TX_CHNL_STS] = dmac_ctrl + TX_CHNL_STS;
|
||||
ra[RX_NXTDESC_PTR] = dmac_ctrl + RX_NXTDESC_PTR;
|
||||
ra[RX_CURBUF_ADDR] = dmac_ctrl + RX_CURBUF_ADDR;
|
||||
ra[RX_CURBUF_LENGTH] = dmac_ctrl + RX_CURBUF_LENGTH;
|
||||
ra[RX_CURDESC_PTR] = dmac_ctrl + RX_CURDESC_PTR;
|
||||
ra[RX_TAILDESC_PTR] = dmac_ctrl + RX_TAILDESC_PTR;
|
||||
ra[RX_CHNL_CTRL] = dmac_ctrl + RX_CHNL_CTRL;
|
||||
ra[RX_IRQ_REG] = dmac_ctrl + RX_IRQ_REG;
|
||||
ra[RX_CHNL_STS] = dmac_ctrl + RX_CHNL_STS;
|
||||
ra[DMA_CONTROL_REG] = dmac_ctrl + DMA_CONTROL_REG;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_XILINX_440 || ONFIG_XILINX_405 */
|
||||
|
||||
/* Xilinx Processor Local Bus (PLB) in/out accessors */
|
||||
inline unsigned ll_temac_xlplb_in32(phys_addr_t addr)
|
||||
{
|
||||
return in_be32((void *)addr);
|
||||
}
|
||||
inline void ll_temac_xlplb_out32(phys_addr_t addr, unsigned value)
|
||||
{
|
||||
out_be32((void *)addr, value);
|
||||
}
|
||||
|
||||
/* collect all register addresses for Xilinx PLB in/out accessors */
|
||||
void ll_temac_collect_xlplb_sdma_reg_addr(struct eth_device *dev)
|
||||
{
|
||||
struct ll_temac *ll_temac = dev->priv;
|
||||
struct sdma_ctrl *sdma_ctrl = (void *)ll_temac->ctrladdr;
|
||||
phys_addr_t *ra = ll_temac->sdma_reg_addr;
|
||||
|
||||
ra[TX_NXTDESC_PTR] = (phys_addr_t)&sdma_ctrl->tx_nxtdesc_ptr;
|
||||
ra[TX_CURBUF_ADDR] = (phys_addr_t)&sdma_ctrl->tx_curbuf_addr;
|
||||
ra[TX_CURBUF_LENGTH] = (phys_addr_t)&sdma_ctrl->tx_curbuf_length;
|
||||
ra[TX_CURDESC_PTR] = (phys_addr_t)&sdma_ctrl->tx_curdesc_ptr;
|
||||
ra[TX_TAILDESC_PTR] = (phys_addr_t)&sdma_ctrl->tx_taildesc_ptr;
|
||||
ra[TX_CHNL_CTRL] = (phys_addr_t)&sdma_ctrl->tx_chnl_ctrl;
|
||||
ra[TX_IRQ_REG] = (phys_addr_t)&sdma_ctrl->tx_irq_reg;
|
||||
ra[TX_CHNL_STS] = (phys_addr_t)&sdma_ctrl->tx_chnl_sts;
|
||||
ra[RX_NXTDESC_PTR] = (phys_addr_t)&sdma_ctrl->rx_nxtdesc_ptr;
|
||||
ra[RX_CURBUF_ADDR] = (phys_addr_t)&sdma_ctrl->rx_curbuf_addr;
|
||||
ra[RX_CURBUF_LENGTH] = (phys_addr_t)&sdma_ctrl->rx_curbuf_length;
|
||||
ra[RX_CURDESC_PTR] = (phys_addr_t)&sdma_ctrl->rx_curdesc_ptr;
|
||||
ra[RX_TAILDESC_PTR] = (phys_addr_t)&sdma_ctrl->rx_taildesc_ptr;
|
||||
ra[RX_CHNL_CTRL] = (phys_addr_t)&sdma_ctrl->rx_chnl_ctrl;
|
||||
ra[RX_IRQ_REG] = (phys_addr_t)&sdma_ctrl->rx_irq_reg;
|
||||
ra[RX_CHNL_STS] = (phys_addr_t)&sdma_ctrl->rx_chnl_sts;
|
||||
ra[DMA_CONTROL_REG] = (phys_addr_t)&sdma_ctrl->dma_control_reg;
|
||||
}
|
||||
|
||||
/* Check for TX and RX channel errors. */
|
||||
static inline int ll_temac_sdma_error(struct eth_device *dev)
|
||||
{
|
||||
int err;
|
||||
struct ll_temac *ll_temac = dev->priv;
|
||||
phys_addr_t *ra = ll_temac->sdma_reg_addr;
|
||||
|
||||
err = ll_temac->in32(ra[TX_CHNL_STS]) & CHNL_STS_ERROR;
|
||||
err |= ll_temac->in32(ra[RX_CHNL_STS]) & CHNL_STS_ERROR;
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
int ll_temac_init_sdma(struct eth_device *dev)
|
||||
{
|
||||
struct ll_temac *ll_temac = dev->priv;
|
||||
struct cdmac_bd *rx_dp;
|
||||
struct cdmac_bd *tx_dp;
|
||||
phys_addr_t *ra = ll_temac->sdma_reg_addr;
|
||||
int i;
|
||||
|
||||
printf("%s: SDMA: %d Rx buffers, %d Tx buffers\n",
|
||||
dev->name, PKTBUFSRX, TX_BUF_CNT);
|
||||
|
||||
/* Initialize the Rx Buffer descriptors */
|
||||
for (i = 0; i < PKTBUFSRX; i++) {
|
||||
rx_dp = &cdmac_bd.rx[i];
|
||||
memset(rx_dp, 0, sizeof(*rx_dp));
|
||||
rx_dp->next_p = rx_dp;
|
||||
rx_dp->buf_len = PKTSIZE_ALIGN;
|
||||
rx_dp->phys_buf_p = (u8 *)NetRxPackets[i];
|
||||
flush_cache((u32)rx_dp->phys_buf_p, PKTSIZE_ALIGN);
|
||||
}
|
||||
flush_cache((u32)cdmac_bd.rx, sizeof(cdmac_bd.rx));
|
||||
|
||||
/* Initialize the TX Buffer Descriptors */
|
||||
for (i = 0; i < TX_BUF_CNT; i++) {
|
||||
tx_dp = &cdmac_bd.tx[i];
|
||||
memset(tx_dp, 0, sizeof(*tx_dp));
|
||||
tx_dp->next_p = tx_dp;
|
||||
}
|
||||
flush_cache((u32)cdmac_bd.tx, sizeof(cdmac_bd.tx));
|
||||
|
||||
/* Reset index counter to the Rx and Tx Buffer descriptors */
|
||||
rx_idx = tx_idx = 0;
|
||||
|
||||
/* initial Rx DMA start by writing to respective TAILDESC_PTR */
|
||||
ll_temac->out32(ra[RX_CURDESC_PTR], (int)&cdmac_bd.rx[rx_idx]);
|
||||
ll_temac->out32(ra[RX_TAILDESC_PTR], (int)&cdmac_bd.rx[rx_idx]);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ll_temac_halt_sdma(struct eth_device *dev)
|
||||
{
|
||||
unsigned timeout = 50; /* 1usec * 50 = 50usec */
|
||||
struct ll_temac *ll_temac = dev->priv;
|
||||
phys_addr_t *ra = ll_temac->sdma_reg_addr;
|
||||
|
||||
/*
|
||||
* Soft reset the DMA
|
||||
*
|
||||
* Quote from MPMC documentation: Writing a 1 to this field
|
||||
* forces the DMA engine to shutdown and reset itself. After
|
||||
* setting this bit, software must poll it until the bit is
|
||||
* cleared by the DMA. This indicates that the reset process
|
||||
* is done and the pipeline has been flushed.
|
||||
*/
|
||||
ll_temac->out32(ra[DMA_CONTROL_REG], DMA_CONTROL_RESET);
|
||||
while (timeout && (ll_temac->in32(ra[DMA_CONTROL_REG])
|
||||
& DMA_CONTROL_RESET)) {
|
||||
timeout--;
|
||||
udelay(1);
|
||||
}
|
||||
|
||||
if (!timeout) {
|
||||
printf("%s: Timeout\n", __func__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ll_temac_reset_sdma(struct eth_device *dev)
|
||||
{
|
||||
u32 r;
|
||||
struct ll_temac *ll_temac = dev->priv;
|
||||
phys_addr_t *ra = ll_temac->sdma_reg_addr;
|
||||
|
||||
/* Soft reset the DMA. */
|
||||
if (ll_temac_halt_sdma(dev))
|
||||
return -1;
|
||||
|
||||
/* Now clear the interrupts. */
|
||||
r = ll_temac->in32(ra[TX_CHNL_CTRL]);
|
||||
r &= ~CHNL_CTRL_IRQ_MASK;
|
||||
ll_temac->out32(ra[TX_CHNL_CTRL], r);
|
||||
|
||||
r = ll_temac->in32(ra[RX_CHNL_CTRL]);
|
||||
r &= ~CHNL_CTRL_IRQ_MASK;
|
||||
ll_temac->out32(ra[RX_CHNL_CTRL], r);
|
||||
|
||||
/* Now ACK pending IRQs. */
|
||||
ll_temac->out32(ra[TX_IRQ_REG], IRQ_REG_IRQ_MASK);
|
||||
ll_temac->out32(ra[RX_IRQ_REG], IRQ_REG_IRQ_MASK);
|
||||
|
||||
/* Set tail-ptr mode, disable errors for both channels. */
|
||||
ll_temac->out32(ra[DMA_CONTROL_REG],
|
||||
/* Enable use of tail pointer register */
|
||||
DMA_CONTROL_TPE |
|
||||
/* Disable error when 2 or 4 bit coalesce cnt overfl */
|
||||
DMA_CONTROL_RXOCEID |
|
||||
/* Disable error when 2 or 4 bit coalesce cnt overfl */
|
||||
DMA_CONTROL_TXOCEID);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ll_temac_recv_sdma(struct eth_device *dev)
|
||||
{
|
||||
int length, pb_idx;
|
||||
struct cdmac_bd *rx_dp = &cdmac_bd.rx[rx_idx];
|
||||
struct ll_temac *ll_temac = dev->priv;
|
||||
phys_addr_t *ra = ll_temac->sdma_reg_addr;
|
||||
|
||||
if (ll_temac_sdma_error(dev)) {
|
||||
|
||||
if (ll_temac_reset_sdma(dev))
|
||||
return -1;
|
||||
|
||||
ll_temac_init_sdma(dev);
|
||||
}
|
||||
|
||||
flush_cache((u32)rx_dp, sizeof(*rx_dp));
|
||||
|
||||
if (!(rx_dp->sca.stctrl & CDMAC_BD_STCTRL_COMPLETED))
|
||||
return 0;
|
||||
|
||||
if (rx_dp->sca.stctrl & (CDMAC_BD_STCTRL_SOP | CDMAC_BD_STCTRL_EOP)) {
|
||||
pb_idx = rx_idx;
|
||||
length = rx_dp->sca.app[4] & CDMAC_BD_APP4_RXBYTECNT_MASK;
|
||||
} else {
|
||||
pb_idx = -1;
|
||||
length = 0;
|
||||
printf("%s: Got part of package, unsupported (%x)\n",
|
||||
__func__, rx_dp->sca.stctrl);
|
||||
}
|
||||
|
||||
/* flip the buffer */
|
||||
flush_cache((u32)rx_dp->phys_buf_p, length);
|
||||
|
||||
/* reset the current descriptor */
|
||||
rx_dp->sca.stctrl = 0;
|
||||
rx_dp->sca.app[4] = 0;
|
||||
flush_cache((u32)rx_dp, sizeof(*rx_dp));
|
||||
|
||||
/* Find next empty buffer descriptor, preparation for next iteration */
|
||||
rx_idx = (rx_idx + 1) % PKTBUFSRX;
|
||||
rx_dp = &cdmac_bd.rx[rx_idx];
|
||||
flush_cache((u32)rx_dp, sizeof(*rx_dp));
|
||||
|
||||
/* DMA start by writing to respective TAILDESC_PTR */
|
||||
ll_temac->out32(ra[RX_CURDESC_PTR], (int)&cdmac_bd.rx[rx_idx]);
|
||||
ll_temac->out32(ra[RX_TAILDESC_PTR], (int)&cdmac_bd.rx[rx_idx]);
|
||||
|
||||
if (length > 0 && pb_idx != -1)
|
||||
NetReceive(NetRxPackets[pb_idx], length);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ll_temac_send_sdma(struct eth_device *dev, volatile void *packet,
|
||||
int length)
|
||||
{
|
||||
unsigned timeout = 50; /* 1usec * 50 = 50usec */
|
||||
struct cdmac_bd *tx_dp = &cdmac_bd.tx[tx_idx];
|
||||
struct ll_temac *ll_temac = dev->priv;
|
||||
phys_addr_t *ra = ll_temac->sdma_reg_addr;
|
||||
|
||||
if (ll_temac_sdma_error(dev)) {
|
||||
|
||||
if (ll_temac_reset_sdma(dev))
|
||||
return -1;
|
||||
|
||||
ll_temac_init_sdma(dev);
|
||||
}
|
||||
|
||||
tx_dp->phys_buf_p = (u8 *)packet;
|
||||
tx_dp->buf_len = length;
|
||||
tx_dp->sca.stctrl = CDMAC_BD_STCTRL_SOP | CDMAC_BD_STCTRL_EOP |
|
||||
CDMAC_BD_STCTRL_STOP_ON_END;
|
||||
|
||||
flush_cache((u32)packet, length);
|
||||
flush_cache((u32)tx_dp, sizeof(*tx_dp));
|
||||
|
||||
/* DMA start by writing to respective TAILDESC_PTR */
|
||||
ll_temac->out32(ra[TX_CURDESC_PTR], (int)tx_dp);
|
||||
ll_temac->out32(ra[TX_TAILDESC_PTR], (int)tx_dp);
|
||||
|
||||
/* Find next empty buffer descriptor, preparation for next iteration */
|
||||
tx_idx = (tx_idx + 1) % TX_BUF_CNT;
|
||||
tx_dp = &cdmac_bd.tx[tx_idx];
|
||||
|
||||
do {
|
||||
flush_cache((u32)tx_dp, sizeof(*tx_dp));
|
||||
udelay(1);
|
||||
} while (timeout-- && !(tx_dp->sca.stctrl & CDMAC_BD_STCTRL_COMPLETED));
|
||||
|
||||
if (!timeout) {
|
||||
printf("%s: Timeout\n", __func__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
281
drivers/net/xilinx_ll_temac_sdma.h
Normal file
281
drivers/net/xilinx_ll_temac_sdma.h
Normal file
@@ -0,0 +1,281 @@
|
||||
/*
|
||||
* Xilinx xps_ll_temac ethernet driver for u-boot
|
||||
*
|
||||
* SDMA sub-controller interface
|
||||
*
|
||||
* Copyright (C) 2011 - 2012 Stephan Linz <linz@li-pro.net>
|
||||
* Copyright (C) 2008 - 2011 Michal Simek <monstr@monstr.eu>
|
||||
* Copyright (C) 2008 - 2011 PetaLogix
|
||||
*
|
||||
* Based on Yoshio Kashiwagi kashiwagi@co-nss.co.jp driver
|
||||
* Copyright (C) 2008 Nissin Systems Co.,Ltd.
|
||||
* March 2008 created
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* [0]: http://www.xilinx.com/support/documentation
|
||||
*
|
||||
* [S]: [0]/ip_documentation/xps_ll_temac.pdf
|
||||
* [A]: [0]/application_notes/xapp1041.pdf
|
||||
*/
|
||||
#ifndef _XILINX_LL_TEMAC_SDMA_
|
||||
#define _XILINX_LL_TEMAC_SDMA_
|
||||
|
||||
#include <net.h>
|
||||
|
||||
#include <asm/types.h>
|
||||
#include <asm/byteorder.h>
|
||||
|
||||
#include <linux/compiler.h>
|
||||
|
||||
#if !defined(__BIG_ENDIAN)
|
||||
# error LL_TEMAC requires big endianess
|
||||
#endif
|
||||
|
||||
/*
|
||||
* DMA Buffer Descriptor for CDMAC
|
||||
*
|
||||
* Used for data connection from and to (Rx/Tx) the LocalLink (LL) TEMAC via
|
||||
* the Communications Direct Memory Access Controller (CDMAC) -- one for each.
|
||||
*
|
||||
* overview:
|
||||
* ftp://ftp.xilinx.com/pub/documentation/misc/mpmc_getting_started.pdf
|
||||
*
|
||||
* [1]: [0]/ip_documentation/mpmc.pdf
|
||||
* page 140, DMA Operation Descriptors
|
||||
*
|
||||
* [2]: [0]/user_guides/ug200.pdf
|
||||
* page 229, DMA Controller -- Descriptor Format
|
||||
*
|
||||
* [3]: [0]/ip_documentation/xps_ll_temac.pdf
|
||||
* page 72, Transmit LocalLink Frame Format
|
||||
* page 73, Receive LocalLink Frame Format
|
||||
*/
|
||||
struct cdmac_bd {
|
||||
struct cdmac_bd *next_p; /* Next Descriptor Pointer */
|
||||
u8 *phys_buf_p; /* Buffer Address */
|
||||
u32 buf_len; /* Buffer Length */
|
||||
union {
|
||||
u8 stctrl; /* Status/Control the DMA transfer */
|
||||
u32 app[5]; /* application specific data */
|
||||
} __packed __aligned(1) sca;
|
||||
};
|
||||
|
||||
/* CDMAC Descriptor Status and Control (stctrl), [1] p140, [2] p230 */
|
||||
#define CDMAC_BD_STCTRL_ERROR (1 << 7)
|
||||
#define CDMAC_BD_STCTRL_IRQ_ON_END (1 << 6)
|
||||
#define CDMAC_BD_STCTRL_STOP_ON_END (1 << 5)
|
||||
#define CDMAC_BD_STCTRL_COMPLETED (1 << 4)
|
||||
#define CDMAC_BD_STCTRL_SOP (1 << 3)
|
||||
#define CDMAC_BD_STCTRL_EOP (1 << 2)
|
||||
#define CDMAC_BD_STCTRL_DMACHBUSY (1 << 1)
|
||||
|
||||
/* CDMAC Descriptor APP0: Transmit LocalLink Footer Word 3, [3] p72 */
|
||||
#define CDMAC_BD_APP0_TXCSCNTRL (1 << 0)
|
||||
|
||||
/* CDMAC Descriptor APP1: Transmit LocalLink Footer Word 4, [3] p73 */
|
||||
#define CDMAC_BD_APP1_TXCSBEGIN_POS 16
|
||||
#define CDMAC_BD_APP1_TXCSBEGIN_MASK (0xFFFF << CDMAC_BD_APP1_TXCSBEGIN_POS)
|
||||
#define CDMAC_BD_APP1_TXCSINSERT_POS 0
|
||||
#define CDMAC_BD_APP1_TXCSINSERT_MASK (0xFFFF << CDMAC_BD_APP1_TXCSINSERT_POS)
|
||||
|
||||
/* CDMAC Descriptor APP2: Transmit LocalLink Footer Word 5, [3] p73 */
|
||||
#define CDMAC_BD_APP2_TXCSINIT_POS 0
|
||||
#define CDMAC_BD_APP2_TXCSINIT_MASK (0xFFFF << CDMAC_BD_APP2_TXCSINIT_POS)
|
||||
|
||||
/* CDMAC Descriptor APP0: Receive LocalLink Footer Word 3, [3] p73 */
|
||||
#define CDMAC_BD_APP0_MADDRU_POS 0
|
||||
#define CDMAC_BD_APP0_MADDRU_MASK (0xFFFF << CDMAC_BD_APP0_MADDRU_POS)
|
||||
|
||||
/* CDMAC Descriptor APP1: Receive LocalLink Footer Word 4, [3] p74 */
|
||||
#define CDMAC_BD_APP1_MADDRL_POS 0
|
||||
#define CDMAC_BD_APP1_MADDRL_MASK (~0UL << CDMAC_BD_APP1_MADDRL_POS)
|
||||
|
||||
/* CDMAC Descriptor APP2: Receive LocalLink Footer Word 5, [3] p74 */
|
||||
#define CDMAC_BD_APP2_BCAST_FRAME (1 << 2)
|
||||
#define CDMAC_BD_APP2_IPC_MCAST_FRAME (1 << 1)
|
||||
#define CDMAC_BD_APP2_MAC_MCAST_FRAME (1 << 0)
|
||||
|
||||
/* CDMAC Descriptor APP3: Receive LocalLink Footer Word 6, [3] p74 */
|
||||
#define CDMAC_BD_APP3_TLTPID_POS 16
|
||||
#define CDMAC_BD_APP3_TLTPID_MASK (0xFFFF << CDMAC_BD_APP3_TLTPID_POS)
|
||||
#define CDMAC_BD_APP3_RXCSRAW_POS 0
|
||||
#define CDMAC_BD_APP3_RXCSRAW_MASK (0xFFFF << CDMAC_BD_APP3_RXCSRAW_POS)
|
||||
|
||||
/* CDMAC Descriptor APP4: Receive LocalLink Footer Word 7, [3] p74 */
|
||||
#define CDMAC_BD_APP4_VLANTAG_POS 16
|
||||
#define CDMAC_BD_APP4_VLANTAG_MASK (0xFFFF << CDMAC_BD_APP4_VLANTAG_POS)
|
||||
#define CDMAC_BD_APP4_RXBYTECNT_POS 0
|
||||
#define CDMAC_BD_APP4_RXBYTECNT_MASK (0x3FFF << CDMAC_BD_APP4_RXBYTECNT_POS)
|
||||
|
||||
/*
|
||||
* SDMA Register Definition
|
||||
*
|
||||
* [0]: http://www.xilinx.com/support/documentation
|
||||
*
|
||||
* [1]: [0]/ip_documentation/mpmc.pdf
|
||||
* page 54, SDMA Register Summary
|
||||
* page 160, SDMA Registers
|
||||
*
|
||||
* [2]: [0]/user_guides/ug200.pdf
|
||||
* page 244, DMA Controller -- Programming Interface and Registers
|
||||
*/
|
||||
#define SDMA_CTRL_REGTYPE u32
|
||||
#define SDMA_CTRL_REGSIZE sizeof(SDMA_CTRL_REGTYPE)
|
||||
struct sdma_ctrl {
|
||||
/* Transmit Registers */
|
||||
SDMA_CTRL_REGTYPE tx_nxtdesc_ptr; /* TX Next Description Pointer */
|
||||
SDMA_CTRL_REGTYPE tx_curbuf_addr; /* TX Current Buffer Address */
|
||||
SDMA_CTRL_REGTYPE tx_curbuf_length; /* TX Current Buffer Length */
|
||||
SDMA_CTRL_REGTYPE tx_curdesc_ptr; /* TX Current Descriptor Pointer */
|
||||
SDMA_CTRL_REGTYPE tx_taildesc_ptr; /* TX Tail Descriptor Pointer */
|
||||
SDMA_CTRL_REGTYPE tx_chnl_ctrl; /* TX Channel Control */
|
||||
SDMA_CTRL_REGTYPE tx_irq_reg; /* TX Interrupt Register */
|
||||
SDMA_CTRL_REGTYPE tx_chnl_sts; /* TX Status Register */
|
||||
/* Receive Registers */
|
||||
SDMA_CTRL_REGTYPE rx_nxtdesc_ptr; /* RX Next Descriptor Pointer */
|
||||
SDMA_CTRL_REGTYPE rx_curbuf_addr; /* RX Current Buffer Address */
|
||||
SDMA_CTRL_REGTYPE rx_curbuf_length; /* RX Current Buffer Length */
|
||||
SDMA_CTRL_REGTYPE rx_curdesc_ptr; /* RX Current Descriptor Pointer */
|
||||
SDMA_CTRL_REGTYPE rx_taildesc_ptr; /* RX Tail Descriptor Pointer */
|
||||
SDMA_CTRL_REGTYPE rx_chnl_ctrl; /* RX Channel Control */
|
||||
SDMA_CTRL_REGTYPE rx_irq_reg; /* RX Interrupt Register */
|
||||
SDMA_CTRL_REGTYPE rx_chnl_sts; /* RX Status Register */
|
||||
/* Control Registers */
|
||||
SDMA_CTRL_REGTYPE dma_control_reg; /* DMA Control Register */
|
||||
};
|
||||
|
||||
#define SDMA_CTRL_REGNUMS sizeof(struct sdma_ctrl)/SDMA_CTRL_REGSIZE
|
||||
|
||||
/*
|
||||
* DMAC Register Index Enumeration
|
||||
*
|
||||
* [2]: http://www.xilinx.com/support/documentation/user_guides/ug200.pdf
|
||||
* page 244, DMA Controller -- Programming Interface and Registers
|
||||
*/
|
||||
enum dmac_ctrl {
|
||||
/* Transmit Registers */
|
||||
TX_NXTDESC_PTR = 0, /* TX Next Description Pointer */
|
||||
TX_CURBUF_ADDR, /* TX Current Buffer Address */
|
||||
TX_CURBUF_LENGTH, /* TX Current Buffer Length */
|
||||
TX_CURDESC_PTR, /* TX Current Descriptor Pointer */
|
||||
TX_TAILDESC_PTR, /* TX Tail Descriptor Pointer */
|
||||
TX_CHNL_CTRL, /* TX Channel Control */
|
||||
TX_IRQ_REG, /* TX Interrupt Register */
|
||||
TX_CHNL_STS, /* TX Status Register */
|
||||
/* Receive Registers */
|
||||
RX_NXTDESC_PTR, /* RX Next Descriptor Pointer */
|
||||
RX_CURBUF_ADDR, /* RX Current Buffer Address */
|
||||
RX_CURBUF_LENGTH, /* RX Current Buffer Length */
|
||||
RX_CURDESC_PTR, /* RX Current Descriptor Pointer */
|
||||
RX_TAILDESC_PTR, /* RX Tail Descriptor Pointer */
|
||||
RX_CHNL_CTRL, /* RX Channel Control */
|
||||
RX_IRQ_REG, /* RX Interrupt Register */
|
||||
RX_CHNL_STS, /* RX Status Register */
|
||||
/* Control Registers */
|
||||
DMA_CONTROL_REG /* DMA Control Register */
|
||||
};
|
||||
|
||||
/* Rx/Tx Channel Control Register (*_chnl_ctrl), [1] p163, [2] p246/p252 */
|
||||
#define CHNL_CTRL_ITO_POS 24
|
||||
#define CHNL_CTRL_ITO_MASK (0xFF << CHNL_CTRL_ITO_POS)
|
||||
#define CHNL_CTRL_IC_POS 16
|
||||
#define CHNL_CTRL_IC_MASK (0xFF << CHNL_CTRL_IC_POS)
|
||||
#define CHNL_CTRL_MSBADDR_POS 12
|
||||
#define CHNL_CTRL_MSBADDR_MASK (0xF << CHNL_CTRL_MSBADDR_POS)
|
||||
#define CHNL_CTRL_AME (1 << 11)
|
||||
#define CHNL_CTRL_OBWC (1 << 10)
|
||||
#define CHNL_CTRL_IOE (1 << 9)
|
||||
#define CHNL_CTRL_LIC (1 << 8)
|
||||
#define CHNL_CTRL_IE (1 << 7)
|
||||
#define CHNL_CTRL_IEE (1 << 2)
|
||||
#define CHNL_CTRL_IDE (1 << 1)
|
||||
#define CHNL_CTRL_ICE (1 << 0)
|
||||
|
||||
/* All interrupt enable bits */
|
||||
#define CHNL_CTRL_IRQ_MASK (CHNL_CTRL_IE | \
|
||||
CHNL_CTRL_IEE | \
|
||||
CHNL_CTRL_IDE | \
|
||||
CHNL_CTRL_ICE)
|
||||
|
||||
/* Rx/Tx Interrupt Status Register (*_irq_reg), [1] p164, [2] p247/p253 */
|
||||
#define IRQ_REG_DTV_POS 24
|
||||
#define IRQ_REG_DTV_MASK (0xFF << IRQ_REG_DTV_POS)
|
||||
#define IRQ_REG_CCV_POS 16
|
||||
#define IRQ_REG_CCV_MASK (0xFF << IRQ_REG_CCV_POS)
|
||||
#define IRQ_REG_WRCQ_EMPTY (1 << 14)
|
||||
#define IRQ_REG_CIC_POS 10
|
||||
#define IRQ_REG_CIC_MASK (0xF << IRQ_REG_CIC_POS)
|
||||
#define IRQ_REG_DIC_POS 8
|
||||
#define IRQ_REG_DIC_MASK (3 << 8)
|
||||
#define IRQ_REG_PLB_RD_NMI (1 << 4)
|
||||
#define IRQ_REG_PLB_WR_NMI (1 << 3)
|
||||
#define IRQ_REG_EI (1 << 2)
|
||||
#define IRQ_REG_DI (1 << 1)
|
||||
#define IRQ_REG_CI (1 << 0)
|
||||
|
||||
/* All interrupt bits */
|
||||
#define IRQ_REG_IRQ_MASK (IRQ_REG_PLB_RD_NMI | \
|
||||
IRQ_REG_PLB_WR_NMI | \
|
||||
IRQ_REG_EI | IRQ_REG_DI | IRQ_REG_CI)
|
||||
|
||||
/* Rx/Tx Channel Status Register (*_chnl_sts), [1] p165, [2] p249/p255 */
|
||||
#define CHNL_STS_ERROR_TAIL (1 << 21)
|
||||
#define CHNL_STS_ERROR_CMP (1 << 20)
|
||||
#define CHNL_STS_ERROR_ADDR (1 << 19)
|
||||
#define CHNL_STS_ERROR_NXTP (1 << 18)
|
||||
#define CHNL_STS_ERROR_CURP (1 << 17)
|
||||
#define CHNL_STS_ERROR_BSYWR (1 << 16)
|
||||
#define CHNL_STS_ERROR (1 << 7)
|
||||
#define CHNL_STS_IOE (1 << 6)
|
||||
#define CHNL_STS_SOE (1 << 5)
|
||||
#define CHNL_STS_CMPLT (1 << 4)
|
||||
#define CHNL_STS_SOP (1 << 3)
|
||||
#define CHNL_STS_EOP (1 << 2)
|
||||
#define CHNL_STS_EBUSY (1 << 1)
|
||||
|
||||
/* DMA Control Register (dma_control_reg), [1] p166, [2] p256 */
|
||||
#define DMA_CONTROL_PLBED (1 << 5)
|
||||
#define DMA_CONTROL_RXOCEID (1 << 4)
|
||||
#define DMA_CONTROL_TXOCEID (1 << 3)
|
||||
#define DMA_CONTROL_TPE (1 << 2)
|
||||
#define DMA_CONTROL_RESET (1 << 0)
|
||||
|
||||
#if defined(CONFIG_XILINX_440) || defined(CONFIG_XILINX_405)
|
||||
|
||||
/* Xilinx Device Control Register (DCR) in/out accessors */
|
||||
unsigned ll_temac_xldcr_in32(phys_addr_t addr);
|
||||
void ll_temac_xldcr_out32(phys_addr_t addr, unsigned value);
|
||||
|
||||
/* collect all register addresses for Xilinx DCR in/out accessors */
|
||||
void ll_temac_collect_xldcr_sdma_reg_addr(struct eth_device *dev);
|
||||
|
||||
#endif /* CONFIG_XILINX_440 || CONFIG_XILINX_405 */
|
||||
|
||||
/* Xilinx Processor Local Bus (PLB) in/out accessors */
|
||||
unsigned ll_temac_xlplb_in32(phys_addr_t base);
|
||||
void ll_temac_xlplb_out32(phys_addr_t base, unsigned value);
|
||||
|
||||
/* collect all register addresses for Xilinx PLB in/out accessors */
|
||||
void ll_temac_collect_xlplb_sdma_reg_addr(struct eth_device *dev);
|
||||
|
||||
/* initialize both Rx/Tx buffer descriptors */
|
||||
int ll_temac_init_sdma(struct eth_device *dev);
|
||||
|
||||
/* halt both Rx/Tx transfers */
|
||||
int ll_temac_halt_sdma(struct eth_device *dev);
|
||||
|
||||
/* reset SDMA and IRQ, disable interrupts and errors */
|
||||
int ll_temac_reset_sdma(struct eth_device *dev);
|
||||
|
||||
/* receive buffered data from SDMA (polling ISR) */
|
||||
int ll_temac_recv_sdma(struct eth_device *dev);
|
||||
|
||||
/* send buffered data to SDMA */
|
||||
int ll_temac_send_sdma(struct eth_device *dev, volatile void *packet,
|
||||
int length);
|
||||
|
||||
#endif /* _XILINX_LL_TEMAC_SDMA_ */
|
||||
@@ -912,4 +912,3 @@ submit_int_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
|
||||
dev, pipe, buffer, length, interval);
|
||||
return ehci_submit_async(dev, pipe, buffer, length, NULL);
|
||||
}
|
||||
|
||||
|
||||
@@ -200,12 +200,12 @@ int omap_ehci_hcd_init(struct omap_usbhs_board_data *usbhs_pdata)
|
||||
if (is_ehci_phy_mode(usbhs_pdata->port_mode[1]))
|
||||
clrbits_le32(®, OMAP_UHH_HOSTCONFIG_ULPI_P2_BYPASS);
|
||||
else
|
||||
setbits_le32(®, OMAP_UHH_HOSTCONFIG_ULPI_P1_BYPASS);
|
||||
setbits_le32(®, OMAP_UHH_HOSTCONFIG_ULPI_P2_BYPASS);
|
||||
|
||||
if (is_ehci_phy_mode(usbhs_pdata->port_mode[2]))
|
||||
clrbits_le32(®, OMAP_UHH_HOSTCONFIG_ULPI_P3_BYPASS);
|
||||
else
|
||||
setbits_le32(®, OMAP_UHH_HOSTCONFIG_ULPI_P1_BYPASS);
|
||||
setbits_le32(®, OMAP_UHH_HOSTCONFIG_ULPI_P3_BYPASS);
|
||||
} else if (rev == OMAP_USBHS_REV2) {
|
||||
clrsetbits_le32(®, (OMAP_P1_MODE_CLEAR | OMAP_P2_MODE_CLEAR),
|
||||
OMAP4_UHH_HOSTCONFIG_APP_START_CLK);
|
||||
|
||||
12
dts/Makefile
12
dts/Makefile
@@ -36,7 +36,7 @@ $(error Your architecture does not have device tree support enabled. \
|
||||
Please define CONFIG_ARCH_DEVICE_TREE))
|
||||
|
||||
# We preprocess the device tree file provide a useful define
|
||||
DTS_CPPFLAGS := -DARCH_CPU_DTS=\"../arch/$(ARCH)/dts/$(CONFIG_ARCH_DEVICE_TREE).dtsi\"
|
||||
DTS_CPPFLAGS := -DARCH_CPU_DTS=\"$(SRCTREE)/arch/$(ARCH)/dts/$(CONFIG_ARCH_DEVICE_TREE).dtsi\"
|
||||
|
||||
all: $(obj).depend $(LIB)
|
||||
|
||||
@@ -46,9 +46,13 @@ all: $(obj).depend $(LIB)
|
||||
DT_BIN := $(obj)dt.dtb
|
||||
|
||||
$(DT_BIN): $(TOPDIR)/board/$(VENDOR)/dts/$(DEVICE_TREE).dts
|
||||
cat $< | $(CPP) -P $(DTS_CPPFLAGS) - >$@.tmp
|
||||
$(DTC) -R 4 -p 0x1000 -O dtb -o ${DT_BIN} $@.tmp
|
||||
rm $@.tmp
|
||||
rc=$$( \
|
||||
cat $< | $(CPP) -P $(DTS_CPPFLAGS) - | \
|
||||
{ { $(DTC) -R 4 -p 0x1000 -O dtb -o ${DT_BIN} - 2>&1 ; \
|
||||
echo $$? >&3 ; } | \
|
||||
grep -v '^DTC: dts->dtb on file' ; \
|
||||
} 3>&1 ) ; \
|
||||
exit $$rc
|
||||
|
||||
process_lds = \
|
||||
$(1) | sed -r -n 's/^OUTPUT_$(2)[ ("]*([^")]*).*/\1/p'
|
||||
|
||||
@@ -203,6 +203,13 @@ enum bootstage_id {
|
||||
BOOTSTAGE_ID_ALLOC,
|
||||
};
|
||||
|
||||
/*
|
||||
* Return the time since boot in microseconds, This is needed for bootstage
|
||||
* and should be defined in CPU- or board-specific code. If undefined then
|
||||
* millisecond resolution will be used (the standard get_timer()).
|
||||
*/
|
||||
ulong timer_get_boot_us(void);
|
||||
|
||||
/*
|
||||
* Board code can implement show_boot_progress() if needed.
|
||||
*
|
||||
|
||||
@@ -206,13 +206,6 @@ typedef void (interrupt_handler_t)(void *);
|
||||
|
||||
#endif /* CONFIG_SERIAL_MULTI */
|
||||
|
||||
/*
|
||||
* Return the time since boot in microseconds, This is needed for bootstage
|
||||
* and should be defined in CPU- or board-specific code. If undefined then
|
||||
* millisecond resolution will be used (the standard get_timer()).
|
||||
*/
|
||||
ulong timer_get_boot_us(void);
|
||||
|
||||
/*
|
||||
* General Purpose Utilities
|
||||
*/
|
||||
|
||||
@@ -90,7 +90,8 @@
|
||||
|
||||
|
||||
#define CONFIG_BOOTDELAY 5
|
||||
#define CONFIG_HUSH_PARSER
|
||||
#define CONFIG_SYS_HUSH_PARSER
|
||||
#define CONFIG_SYS_PROMPT_HUSH_PS2 "> "
|
||||
#define CONFIG_SYS_PROMPT "\nEV123 U-Boot> "
|
||||
#define CONFIG_SYS_LONGHELP 1
|
||||
|
||||
|
||||
@@ -139,6 +139,8 @@
|
||||
#define CONFIG_CMD_PING
|
||||
#define CONFIG_I2C_CMD_NO_FLAT
|
||||
#define CONFIG_I2C_CMD_TREE
|
||||
#define CONFIG_CMD_USB
|
||||
#define CONFIG_CMD_FAT
|
||||
|
||||
#define CONFIG_SYS_LONGHELP
|
||||
|
||||
@@ -169,6 +171,18 @@
|
||||
/*
|
||||
* Hardware drivers
|
||||
*/
|
||||
#define CONFIG_USB_ATMEL
|
||||
#define CONFIG_USB_OHCI_NEW
|
||||
#define CONFIG_AT91C_PQFP_UHPBUG
|
||||
#define CONFIG_USB_STORAGE
|
||||
#define CONFIG_DOS_PARTITION
|
||||
#define CONFIG_ISO_PARTITION
|
||||
#define CONFIG_EFI_PARTITION
|
||||
|
||||
#define CONFIG_SYS_USB_OHCI_MAX_ROOT_PORTS 1
|
||||
#define CONFIG_SYS_USB_OHCI_CPU_INIT
|
||||
#define CONFIG_SYS_USB_OHCI_REGS_BASE 0x00300000
|
||||
#define CONFIG_SYS_USB_OHCI_SLOT_NAME "at91rm9200"
|
||||
|
||||
/*
|
||||
* UART/CONSOLE
|
||||
|
||||
@@ -43,7 +43,7 @@
|
||||
#define CONFIG_SH4 1
|
||||
#define CONFIG_SH4A 1
|
||||
#define CONFIG_CPU_SH7724 1
|
||||
#define BOARD_LATE_INIT 1
|
||||
#define CONFIG_BOARD_LATE_INIT 1
|
||||
#define CONFIG_ECOVEC 1
|
||||
|
||||
#define CONFIG_ECOVEC_ROMIMAGE_ADDR 0xA0040000
|
||||
|
||||
@@ -34,6 +34,7 @@
|
||||
#define CONFIG_MX35_HCLK_FREQ 24000000
|
||||
|
||||
#define CONFIG_SYS_DCACHE_OFF
|
||||
#define CONFIG_SYS_CACHELINE_SIZE 32
|
||||
|
||||
#define CONFIG_DISPLAY_CPUINFO
|
||||
|
||||
@@ -98,6 +99,7 @@
|
||||
#define CONFIG_BOOTP_DNS
|
||||
|
||||
#define CONFIG_CMD_NAND
|
||||
#define CONFIG_CMD_CACHE
|
||||
|
||||
#define CONFIG_CMD_I2C
|
||||
#define CONFIG_CMD_SPI
|
||||
|
||||
@@ -62,6 +62,7 @@
|
||||
#define CONFIG_SPL_NAND_SUPPORT
|
||||
#define CONFIG_SPL_NAND_SIMPLE
|
||||
#define CONFIG_SPL_NAND_LOAD
|
||||
#define CONFIG_SPL_LIBGENERIC_SUPPORT /* for udelay and __div64_32 for NAND */
|
||||
#define CONFIG_SPL_SERIAL_SUPPORT
|
||||
#define CONFIG_SPL_LDSCRIPT "board/$(BOARDDIR)/u-boot-spl-hawk.lds"
|
||||
#define CONFIG_SPL_TEXT_BASE 0xc1080000
|
||||
|
||||
@@ -93,7 +93,7 @@
|
||||
#define CONFIG_SYS_SDRAM_BASE PHYS_SDRAM_1
|
||||
/* Point initial SP in SRAM so SPL can use it too. */
|
||||
|
||||
#define CONFIG_SYS_INIT_RAM_ADDR 0x00002000
|
||||
#define CONFIG_SYS_INIT_RAM_ADDR 0x00000000
|
||||
#define CONFIG_SYS_INIT_RAM_SIZE (128 * 1024)
|
||||
|
||||
#define CONFIG_SYS_INIT_SP_OFFSET \
|
||||
@@ -145,13 +145,17 @@
|
||||
#define CONFIG_MXS_MMC
|
||||
#endif
|
||||
|
||||
/*
|
||||
* APBH DMA
|
||||
*/
|
||||
#define CONFIG_APBH_DMA
|
||||
|
||||
/*
|
||||
* NAND
|
||||
*/
|
||||
#define CONFIG_ENV_SIZE (16 * 1024)
|
||||
#ifdef CONFIG_CMD_NAND
|
||||
#define CONFIG_NAND_MXS
|
||||
#define CONFIG_APBH_DMA
|
||||
#define CONFIG_SYS_MAX_NAND_DEVICE 1
|
||||
#define CONFIG_SYS_NAND_BASE 0x60000000
|
||||
#define CONFIG_SYS_NAND_5_ADDR_CYCLE
|
||||
|
||||
@@ -65,11 +65,12 @@
|
||||
|
||||
/* ethernet */
|
||||
#undef CONFIG_SYS_ENET
|
||||
#ifdef XILINX_EMACLITE_BASEADDR
|
||||
# define CONFIG_XILINX_EMACLITE 1
|
||||
#if defined(XILINX_EMACLITE_BASEADDR)
|
||||
# define CONFIG_XILINX_EMACLITE 1
|
||||
# define CONFIG_SYS_ENET
|
||||
#elif XILINX_LLTEMAC_BASEADDR
|
||||
# define CONFIG_XILINX_LL_TEMAC 1
|
||||
#endif
|
||||
#if defined(XILINX_LLTEMAC_BASEADDR)
|
||||
# define CONFIG_XILINX_LL_TEMAC 1
|
||||
# define CONFIG_SYS_ENET
|
||||
#endif
|
||||
#if defined(XILINX_AXIEMAC_BASEADDR)
|
||||
@@ -339,7 +340,7 @@
|
||||
#define CONFIG_FIT 1
|
||||
#define CONFIG_OF_LIBFDT 1
|
||||
|
||||
#if defined(CONFIG_XILINX_AXIEMAC)
|
||||
#if defined(CONFIG_XILINX_LL_TEMAC) || defined(CONFIG_XILINX_AXIEMAC)
|
||||
# define CONFIG_MII 1
|
||||
# define CONFIG_CMD_MII 1
|
||||
# define CONFIG_PHY_GIGE 1
|
||||
|
||||
@@ -81,7 +81,7 @@
|
||||
#define CONFIG_SYS_SDRAM_BASE PHYS_SDRAM_1
|
||||
/* Point initial SP in SRAM so SPL can use it too. */
|
||||
|
||||
#define CONFIG_SYS_INIT_RAM_ADDR 0x00002000
|
||||
#define CONFIG_SYS_INIT_RAM_ADDR 0x00000000
|
||||
#define CONFIG_SYS_INIT_RAM_SIZE (128 * 1024)
|
||||
|
||||
#define CONFIG_SYS_INIT_SP_OFFSET \
|
||||
|
||||
@@ -34,10 +34,10 @@
|
||||
#define CONFIG_MX35_HCLK_FREQ 24000000
|
||||
|
||||
#define CONFIG_DISPLAY_CPUINFO
|
||||
#define CONFIG_DISPLAY_BOARDINFO
|
||||
|
||||
/* Set TEXT at the beginning of the NOR flash */
|
||||
#define CONFIG_SYS_TEXT_BASE 0xA0000000
|
||||
#define CONFIG_SYS_CACHELINE_SIZE 32
|
||||
|
||||
#define CONFIG_SYS_64BIT_VSPRINTF
|
||||
|
||||
@@ -106,6 +106,7 @@
|
||||
#define CONFIG_BOOTP_DNS
|
||||
|
||||
#define CONFIG_CMD_NAND
|
||||
#define CONFIG_CMD_CACHE
|
||||
|
||||
#define CONFIG_CMD_I2C
|
||||
#define CONFIG_CMD_SPI
|
||||
|
||||
@@ -169,4 +169,6 @@
|
||||
|
||||
#define CONFIG_OF_LIBFDT
|
||||
|
||||
#define CONFIG_SYS_DCACHE_OFF
|
||||
|
||||
#endif /* __CONFIG_H */
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
*
|
||||
* 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
|
||||
* 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
|
||||
@@ -23,8 +23,8 @@
|
||||
#define __CONFIG_H
|
||||
|
||||
#define CONFIG_MX6Q
|
||||
#define CONFIG_SYS_MX6_HCLK 24000000
|
||||
#define CONFIG_SYS_MX6_CLK32 32768
|
||||
#define CONFIG_SYS_MX6_HCLK 24000000
|
||||
#define CONFIG_SYS_MX6_CLK32 32768
|
||||
#define CONFIG_DISPLAY_CPUINFO
|
||||
#define CONFIG_DISPLAY_BOARDINFO
|
||||
|
||||
@@ -38,14 +38,14 @@
|
||||
#define CONFIG_REVISION_TAG
|
||||
|
||||
/* Size of malloc() pool */
|
||||
#define CONFIG_SYS_MALLOC_LEN (CONFIG_ENV_SIZE + 2 * 1024 * 1024)
|
||||
#define CONFIG_SYS_MALLOC_LEN (CONFIG_ENV_SIZE + 2 * 1024 * 1024)
|
||||
|
||||
#define CONFIG_ARCH_CPU_INIT
|
||||
#define CONFIG_BOARD_EARLY_INIT_F
|
||||
#define CONFIG_MXC_GPIO
|
||||
|
||||
#define CONFIG_MXC_UART
|
||||
#define CONFIG_MXC_UART_BASE UART2_BASE
|
||||
#define CONFIG_MXC_UART_BASE UART2_BASE
|
||||
|
||||
#define CONFIG_CMD_SF
|
||||
#ifdef CONFIG_CMD_SF
|
||||
@@ -75,10 +75,10 @@
|
||||
#define CONFIG_CMD_DHCP
|
||||
#define CONFIG_CMD_MII
|
||||
#define CONFIG_CMD_NET
|
||||
#define CONFIG_FEC_MXC
|
||||
#define CONFIG_MII
|
||||
#define CONFIG_FEC_MXC
|
||||
#define CONFIG_MII
|
||||
#define IMX_FEC_BASE ENET_BASE_ADDR
|
||||
#define CONFIG_FEC_XCV_TYPE RGMII
|
||||
#define CONFIG_FEC_XCV_TYPE RGMII
|
||||
#define CONFIG_ETHPRIME "FEC"
|
||||
#define CONFIG_FEC_MXC_PHYADDR 6
|
||||
#define CONFIG_PHYLIB
|
||||
@@ -99,8 +99,8 @@
|
||||
|
||||
/* allow to overwrite serial and ethaddr */
|
||||
#define CONFIG_ENV_OVERWRITE
|
||||
#define CONFIG_CONS_INDEX 1
|
||||
#define CONFIG_BAUDRATE 115200
|
||||
#define CONFIG_CONS_INDEX 1
|
||||
#define CONFIG_BAUDRATE 115200
|
||||
#define CONFIG_SYS_BAUDRATE_TABLE {9600, 19200, 38400, 57600, 115200}
|
||||
|
||||
/* Command definition */
|
||||
@@ -108,48 +108,48 @@
|
||||
|
||||
#undef CONFIG_CMD_IMLS
|
||||
|
||||
#define CONFIG_BOOTDELAY 3
|
||||
#define CONFIG_BOOTDELAY 3
|
||||
|
||||
#define CONFIG_LOADADDR 0x10800000
|
||||
#define CONFIG_SYS_TEXT_BASE 0x17800000
|
||||
#define CONFIG_LOADADDR 0x10800000
|
||||
#define CONFIG_SYS_TEXT_BASE 0x17800000
|
||||
|
||||
#define CONFIG_EXTRA_ENV_SETTINGS \
|
||||
"script=boot.scr\0" \
|
||||
"uimage=uImage\0" \
|
||||
"console=ttymxc3\0" \
|
||||
"console=ttymxc1\0" \
|
||||
"fdt_high=0xffffffff\0" \
|
||||
"initrd_high=0xffffffff\0" \
|
||||
"mmcdev=0\0" \
|
||||
"mmcpart=2\0" \
|
||||
"mmcroot=/dev/mmcblk0p3 rootwait rw\0" \
|
||||
"mmcargs=setenv bootargs console=${console},${baudrate} " \
|
||||
"root=${mmcroot}\0" \
|
||||
"root=${mmcroot}\0" \
|
||||
"loadbootscript=" \
|
||||
"fatload mmc ${mmcdev}:${mmcpart} ${loadaddr} ${script};\0" \
|
||||
"fatload mmc ${mmcdev}:${mmcpart} ${loadaddr} ${script};\0" \
|
||||
"bootscript=echo Running bootscript from mmc ...; " \
|
||||
"source\0" \
|
||||
"source\0" \
|
||||
"loaduimage=fatload mmc ${mmcdev}:${mmcpart} ${loadaddr} ${uimage}\0" \
|
||||
"mmcboot=echo Booting from mmc ...; " \
|
||||
"run mmcargs; " \
|
||||
"bootm\0" \
|
||||
"run mmcargs; " \
|
||||
"bootm\0" \
|
||||
"netargs=setenv bootargs console=${console},${baudrate} " \
|
||||
"root=/dev/nfs " \
|
||||
"ip=dhcp nfsroot=${serverip}:${nfsroot},v3,tcp\0" \
|
||||
"root=/dev/nfs " \
|
||||
"ip=dhcp nfsroot=${serverip}:${nfsroot},v3,tcp\0" \
|
||||
"netboot=echo Booting from net ...; " \
|
||||
"run netargs; " \
|
||||
"dhcp ${uimage}; bootm\0" \
|
||||
"run netargs; " \
|
||||
"dhcp ${uimage}; bootm\0" \
|
||||
|
||||
#define CONFIG_BOOTCOMMAND \
|
||||
"mmc dev ${mmcdev};" \
|
||||
"if mmc rescan ${mmcdev}; then " \
|
||||
"if run loadbootscript; then " \
|
||||
"run bootscript; " \
|
||||
"else " \
|
||||
"if run loaduimage; then " \
|
||||
"run mmcboot; " \
|
||||
"else run netboot; " \
|
||||
"fi; " \
|
||||
"fi; " \
|
||||
"if run loadbootscript; then " \
|
||||
"run bootscript; " \
|
||||
"else " \
|
||||
"if run loaduimage; then " \
|
||||
"run mmcboot; " \
|
||||
"else run netboot; " \
|
||||
"fi; " \
|
||||
"fi; " \
|
||||
"else run netboot; fi"
|
||||
|
||||
#define CONFIG_ARP_TIMEOUT 200UL
|
||||
@@ -158,30 +158,30 @@
|
||||
#define CONFIG_SYS_LONGHELP
|
||||
#define CONFIG_SYS_HUSH_PARSER
|
||||
#define CONFIG_SYS_PROMPT_HUSH_PS2 "> "
|
||||
#define CONFIG_SYS_PROMPT "MX6QSABRELITE U-Boot > "
|
||||
#define CONFIG_SYS_PROMPT "MX6QSABRELITE U-Boot > "
|
||||
#define CONFIG_AUTO_COMPLETE
|
||||
#define CONFIG_SYS_CBSIZE 256
|
||||
#define CONFIG_SYS_CBSIZE 256
|
||||
|
||||
/* Print Buffer Size */
|
||||
#define CONFIG_SYS_PBSIZE (CONFIG_SYS_CBSIZE + sizeof(CONFIG_SYS_PROMPT) + 16)
|
||||
#define CONFIG_SYS_MAXARGS 16
|
||||
#define CONFIG_SYS_MAXARGS 16
|
||||
#define CONFIG_SYS_BARGSIZE CONFIG_SYS_CBSIZE
|
||||
|
||||
#define CONFIG_SYS_MEMTEST_START 0x10000000
|
||||
#define CONFIG_SYS_MEMTEST_END 0x10010000
|
||||
#define CONFIG_SYS_MEMTEST_END 0x10010000
|
||||
|
||||
#define CONFIG_SYS_LOAD_ADDR CONFIG_LOADADDR
|
||||
#define CONFIG_SYS_HZ 1000
|
||||
#define CONFIG_SYS_LOAD_ADDR CONFIG_LOADADDR
|
||||
#define CONFIG_SYS_HZ 1000
|
||||
|
||||
#define CONFIG_CMDLINE_EDITING
|
||||
#define CONFIG_STACKSIZE (128 * 1024)
|
||||
#define CONFIG_STACKSIZE (128 * 1024)
|
||||
|
||||
/* Physical Memory Map */
|
||||
#define CONFIG_NR_DRAM_BANKS 1
|
||||
#define PHYS_SDRAM MMDC0_ARB_BASE_ADDR
|
||||
#define PHYS_SDRAM_SIZE (1u * 1024 * 1024 * 1024)
|
||||
#define CONFIG_NR_DRAM_BANKS 1
|
||||
#define PHYS_SDRAM MMDC0_ARB_BASE_ADDR
|
||||
#define PHYS_SDRAM_SIZE (1u * 1024 * 1024 * 1024)
|
||||
|
||||
#define CONFIG_SYS_SDRAM_BASE PHYS_SDRAM
|
||||
#define CONFIG_SYS_SDRAM_BASE PHYS_SDRAM
|
||||
#define CONFIG_SYS_INIT_RAM_ADDR IRAM_BASE_ADDR
|
||||
#define CONFIG_SYS_INIT_RAM_SIZE IRAM_SIZE
|
||||
|
||||
@@ -212,4 +212,10 @@
|
||||
|
||||
#define CONFIG_OF_LIBFDT
|
||||
|
||||
#endif /* __CONFIG_H */
|
||||
#define CONFIG_SYS_DCACHE_OFF
|
||||
|
||||
#ifndef CONFIG_SYS_DCACHE_OFF
|
||||
#define CONFIG_CMD_CACHE
|
||||
#endif
|
||||
|
||||
#endif /* __CONFIG_H */
|
||||
|
||||
@@ -131,7 +131,8 @@
|
||||
#define CONFIG_SYS_MALLOC_BASE (CONFIG_SYS_MONITOR_BASE - \
|
||||
CONFIG_SYS_MALLOC_LEN)
|
||||
#define CONFIG_SYS_GBL_DATA_OFFSET (CONFIG_SYS_MALLOC_BASE - \
|
||||
GENERATED_GBL_DATA_SIZE)
|
||||
GENERATED_GBL_DATA_SIZE - \
|
||||
GENERATED_BD_INFO_SIZE)
|
||||
#define CONFIG_SYS_INIT_SP CONFIG_SYS_GBL_DATA_OFFSET
|
||||
|
||||
/*
|
||||
|
||||
@@ -167,6 +167,7 @@
|
||||
#define CONFIG_CMD_PING
|
||||
#define CONFIG_CMD_DHCP
|
||||
#define CONFIG_CMD_SETEXPR /* Evaluate expressions */
|
||||
#define CONFIG_CMD_GPIO /* Enable gpio command */
|
||||
|
||||
#undef CONFIG_CMD_FLASH /* flinfo, erase, protect */
|
||||
#undef CONFIG_CMD_FPGA /* FPGA configuration Support */
|
||||
@@ -280,10 +281,16 @@
|
||||
"ramboot=echo Booting from ramdisk ...; " \
|
||||
"run ramargs; " \
|
||||
"bootm ${loadaddr}\0" \
|
||||
|
||||
"userbutton=if gpio input 173; then run userbutton_xm; " \
|
||||
"else run userbutton_nonxm; fi;\0" \
|
||||
"userbutton_xm=gpio input 4;\0" \
|
||||
"userbutton_nonxm=gpio input 7;\0"
|
||||
/* "run userbutton" will return 1 (false) if is pressed and 0 (false) if not */
|
||||
#define CONFIG_BOOTCOMMAND \
|
||||
"if mmc rescan ${mmcdev}; then " \
|
||||
"if userbutton; then " \
|
||||
"if run userbutton; then " \
|
||||
"setenv bootenv uEnv.txt;" \
|
||||
"else " \
|
||||
"setenv bootenv user.txt;" \
|
||||
"fi;" \
|
||||
"echo SD/MMC found on device ${mmcdev};" \
|
||||
|
||||
@@ -46,6 +46,8 @@
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define CONFIG_SYS_LITTLE_ENDIAN
|
||||
|
||||
#define CONFIG_ETHADDR DE:AD:BE:EF:01:01 /* Ethernet address */
|
||||
|
||||
#define CONFIG_BOOTDELAY 2 /* autoboot after 2 seconds */
|
||||
|
||||
@@ -233,6 +233,7 @@
|
||||
#define CONFIG_SYS_MONITOR_LEN (256 << 10) /* Reserve 2 sectors */
|
||||
|
||||
#define CONFIG_USE_ONENAND_BOARD_INIT
|
||||
#define CONFIG_SAMSUNG_ONENAND
|
||||
#define CONFIG_SYS_ONENAND_BASE 0x0C000000
|
||||
|
||||
#define CONFIG_ENV_IS_IN_MMC 1
|
||||
|
||||
@@ -71,7 +71,7 @@
|
||||
/* Size of malloc() pool */
|
||||
#define CONFIG_ENV_SIZE (128 << 10) /* 128 KiB */
|
||||
/* Sector */
|
||||
#define CONFIG_SYS_MALLOC_LEN (CONFIG_ENV_SIZE + (512 << 10))
|
||||
#define CONFIG_SYS_MALLOC_LEN (1024*1024)
|
||||
|
||||
/* Hardware drivers */
|
||||
|
||||
@@ -139,7 +139,9 @@
|
||||
#define CONFIG_CMD_MTDPARTS /* Enable MTD parts commands */
|
||||
#define CONFIG_CMD_NAND /* NAND support */
|
||||
#define CONFIG_CMD_NAND_LOCK_UNLOCK /* nand (un)lock commands */
|
||||
#define CONFIG_CMD_UBI /* UBIFS commands */
|
||||
#define CONFIG_CMD_UBI /* UBI commands */
|
||||
#define CONFIG_CMD_UBIFS /* UBIFS commands */
|
||||
#define CONFIG_LZO /* LZO is needed for UBIFS */
|
||||
|
||||
#undef CONFIG_CMD_NET
|
||||
#undef CONFIG_CMD_NFS
|
||||
@@ -180,7 +182,8 @@
|
||||
"setenv bootargs ${bootargs} " \
|
||||
"omapfb.mode=lcd:${lcdmode} " \
|
||||
"omapdss.def_disp=${defaultdisplay} " \
|
||||
"root=ubi0:rootfs " \
|
||||
"root=ubi0:root " \
|
||||
"ubi.mtd=4 " \
|
||||
"rootfstype=ubifs " \
|
||||
"${kernelopts}\0" \
|
||||
"loadbootscript=fatload mmc ${mmcdev} ${loadaddr} boot.scr\0" \
|
||||
@@ -191,9 +194,13 @@
|
||||
"mmcboot=echo Booting from mmc ...; " \
|
||||
"run mmcargs; " \
|
||||
"bootm ${loadaddr}\0" \
|
||||
"loaduimage_ubi=mtd default; " \
|
||||
"ubi part fs; " \
|
||||
"ubifsmount root; " \
|
||||
"ubifsload ${loadaddr} /boot/uImage\0" \
|
||||
"nandboot=echo Booting from nand ...; " \
|
||||
"run nandargs; " \
|
||||
"nand read ${loadaddr} 280000 400000; " \
|
||||
"run loaduimage_ubi; " \
|
||||
"bootm ${loadaddr}\0" \
|
||||
"autoboot=if mmc rescan ${mmcdev}; then " \
|
||||
"if run loadbootscript; then " \
|
||||
|
||||
@@ -101,6 +101,7 @@ struct onenand_chip {
|
||||
size_t count);
|
||||
unsigned short (*read_word) (void __iomem *addr);
|
||||
void (*write_word) (unsigned short value, void __iomem *addr);
|
||||
int (*chip_probe)(struct mtd_info *mtd);
|
||||
void (*mmcontrol) (struct mtd_info *mtd, int sync_read);
|
||||
int (*block_markbad)(struct mtd_info *mtd, loff_t ofs);
|
||||
int (*scan_bbt)(struct mtd_info *mtd);
|
||||
@@ -139,6 +140,9 @@ struct onenand_chip {
|
||||
#define ONENAND_IS_DDP(this) \
|
||||
(this->device_id & ONENAND_DEVICE_IS_DDP)
|
||||
|
||||
#define ONENAND_IS_4KB_PAGE(this) \
|
||||
(this->options & ONENAND_HAS_4KB_PAGE)
|
||||
|
||||
#define ONENAND_IS_2PLANE(this) (0)
|
||||
|
||||
/*
|
||||
@@ -147,6 +151,7 @@ struct onenand_chip {
|
||||
#define ONENAND_HAS_CONT_LOCK (0x0001)
|
||||
#define ONENAND_HAS_UNLOCK_ALL (0x0002)
|
||||
#define ONENAND_HAS_2PLANE (0x0004)
|
||||
#define ONENAND_HAS_4KB_PAGE (0x0008)
|
||||
#define ONENAND_RUNTIME_BADBLOCK_CHECK (0x0200)
|
||||
#define ONENAND_PAGEBUF_ALLOC (0x1000)
|
||||
#define ONENAND_OOBBUF_ALLOC (0x2000)
|
||||
|
||||
@@ -127,5 +127,7 @@ struct samsung_onenand {
|
||||
|
||||
/* common initialize function */
|
||||
extern void s3c_onenand_init(struct mtd_info *);
|
||||
extern int s5pc110_chip_probe(struct mtd_info *);
|
||||
extern int s5pc210_chip_probe(struct mtd_info *);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -102,6 +102,18 @@ int xilinx_axiemac_initialize(bd_t *bis, unsigned long base_addr,
|
||||
unsigned long dma_addr);
|
||||
int xilinx_emaclite_initialize(bd_t *bis, unsigned long base_addr,
|
||||
int txpp, int rxpp);
|
||||
int xilinx_ll_temac_eth_init(bd_t *bis, unsigned long base_addr, int flags,
|
||||
unsigned long ctrl_addr);
|
||||
|
||||
/*
|
||||
* As long as the Xilinx xps_ll_temac ethernet driver has not its own interface
|
||||
* exported by a public hader file, we need a global definition at this point.
|
||||
*/
|
||||
#if defined(CONFIG_XILINX_LL_TEMAC)
|
||||
#define XILINX_LL_TEMAC_M_FIFO 0 /* use FIFO Ctrl */
|
||||
#define XILINX_LL_TEMAC_M_SDMA_PLB (1 << 0)/* use SDMA Ctrl via PLB */
|
||||
#define XILINX_LL_TEMAC_M_SDMA_DCR (1 << 1)/* use SDMA Ctrl via DCR */
|
||||
#endif
|
||||
|
||||
/* Boards with PCI network controllers can call this from their board_eth_init()
|
||||
* function to initialize whatever's on board.
|
||||
|
||||
17
lib/time.c
17
lib/time.c
@@ -47,20 +47,3 @@ void mdelay(unsigned long msec)
|
||||
while (msec--)
|
||||
udelay(1000);
|
||||
}
|
||||
|
||||
ulong __timer_get_boot_us(void)
|
||||
{
|
||||
static ulong base_time;
|
||||
|
||||
/*
|
||||
* We can't implement this properly. Return 0 on the first call and
|
||||
* larger values after that.
|
||||
*/
|
||||
if (base_time)
|
||||
return get_timer(base_time) * 1000;
|
||||
base_time = get_timer(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
ulong timer_get_boot_us(void)
|
||||
__attribute__((weak, alias("__timer_get_boot_us")));
|
||||
|
||||
@@ -172,8 +172,7 @@ int eth_write_hwaddr(struct eth_device *dev, const char *base_name,
|
||||
unsigned char env_enetaddr[6];
|
||||
int ret = 0;
|
||||
|
||||
if (!eth_getenv_enetaddr_by_index(base_name, eth_number, env_enetaddr))
|
||||
return -1;
|
||||
eth_getenv_enetaddr_by_index(base_name, eth_number, env_enetaddr);
|
||||
|
||||
if (memcmp(env_enetaddr, "\0\0\0\0\0\0", 6)) {
|
||||
if (memcmp(dev->enetaddr, "\0\0\0\0\0\0", 6) &&
|
||||
|
||||
@@ -213,7 +213,7 @@ int main(int argc, char **argv)
|
||||
filebuf = mmap(NULL, sizeof(*envptr) * filesize, PROT_READ,
|
||||
MAP_PRIVATE, txt_fd, 0);
|
||||
if (filebuf == MAP_FAILED) {
|
||||
fprintf(stderr, "mmap (%ld bytes) failed: %s\n",
|
||||
fprintf(stderr, "mmap (%zu bytes) failed: %s\n",
|
||||
sizeof(*envptr) * filesize,
|
||||
strerror(errno));
|
||||
fprintf(stderr, "Falling back to read()\n");
|
||||
@@ -221,7 +221,7 @@ int main(int argc, char **argv)
|
||||
filebuf = malloc(sizeof(*envptr) * filesize);
|
||||
ret = read(txt_fd, filebuf, sizeof(*envptr) * filesize);
|
||||
if (ret != sizeof(*envptr) * filesize) {
|
||||
fprintf(stderr, "Can't read the whole input file (%ld bytes): %s\n",
|
||||
fprintf(stderr, "Can't read the whole input file (%zu bytes): %s\n",
|
||||
sizeof(*envptr) * filesize,
|
||||
strerror(errno));
|
||||
|
||||
|
||||
1
tools/patman/.gitignore
vendored
Normal file
1
tools/patman/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
*.pyc
|
||||
408
tools/patman/README
Normal file
408
tools/patman/README
Normal file
@@ -0,0 +1,408 @@
|
||||
# Copyright (c) 2011 The Chromium OS Authors.
|
||||
#
|
||||
# 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
|
||||
#
|
||||
|
||||
What is this?
|
||||
=============
|
||||
|
||||
This tool is a Python script which:
|
||||
- Creates patch directly from your branch
|
||||
- Cleans them up by removing unwanted tags
|
||||
- Inserts a cover letter with change lists
|
||||
- Runs the patches through checkpatch.pl and its own checks
|
||||
- Optionally emails them out to selected people
|
||||
|
||||
It is intended to automate patch creation and make it a less
|
||||
error-prone process. It is useful for U-Boot and Linux work so far,
|
||||
since it uses the checkpatch.pl script.
|
||||
|
||||
It is configured almost entirely by tags it finds in your commits.
|
||||
This means that you can work on a number of different branches at
|
||||
once, and keep the settings with each branch rather than having to
|
||||
git format-patch, git send-email, etc. with the correct parameters
|
||||
each time. So for example if you put:
|
||||
|
||||
Series-to: fred.blogs@napier.co.nz
|
||||
|
||||
in one of your commits, the series will be sent there.
|
||||
|
||||
|
||||
How to use this tool
|
||||
====================
|
||||
|
||||
This tool requires a certain way of working:
|
||||
|
||||
- Maintain a number of branches, one for each patch series you are
|
||||
working on
|
||||
- Add tags into the commits within each branch to indicate where the
|
||||
series should be sent, cover letter, version, etc. Most of these are
|
||||
normally in the top commit so it is easy to change them with 'git
|
||||
commit --amend'
|
||||
- Each branch tracks the upstream branch, so that this script can
|
||||
automatically determine the number of commits in it (optional)
|
||||
- Check out a branch, and run this script to create and send out your
|
||||
patches. Weeks later, change the patches and repeat, knowing that you
|
||||
will get a consistent result each time.
|
||||
|
||||
|
||||
How to configure it
|
||||
===================
|
||||
|
||||
For most cases patman will locate and use the file 'doc/git-mailrc' in
|
||||
your U-Boot directory. This contains most of the aliases you will need.
|
||||
|
||||
To add your own, create a file ~/.config/patman directory like this:
|
||||
|
||||
>>>>
|
||||
# patman alias file
|
||||
|
||||
[alias]
|
||||
me: Simon Glass <sjg@chromium.org>
|
||||
|
||||
u-boot: U-Boot Mailing List <u-boot@lists.denx.de>
|
||||
wolfgang: Wolfgang Denk <wd@denx.de>
|
||||
others: Mike Frysinger <vapier@gentoo.org>, Fred Bloggs <f.bloggs@napier.net>
|
||||
|
||||
<<<<
|
||||
|
||||
Aliases are recursive.
|
||||
|
||||
The checkpatch.pl in the U-Boot tools/ subdirectory will be located and
|
||||
used. Failing that you can put it into your path or ~/bin/checkpatch.pl
|
||||
|
||||
|
||||
How to run it
|
||||
=============
|
||||
|
||||
First do a dry run:
|
||||
|
||||
$ ./tools/scripts/patman/patman -n
|
||||
|
||||
If it can't detect the upstream branch, try telling it how many patches
|
||||
there are in your series:
|
||||
|
||||
$ ./tools/scripts/patman/patman -n -c5
|
||||
|
||||
This will create patch files in your current directory and tell you who
|
||||
it is thinking of sending them to. Take a look at the patch files.
|
||||
|
||||
$ ./tools/scripts/patman/patman -n -c5 -s1
|
||||
|
||||
Similar to the above, but skip the first commit and take the next 5. This
|
||||
is useful if your top commit is for setting up testing.
|
||||
|
||||
|
||||
How to add tags
|
||||
===============
|
||||
|
||||
To make this script useful you must add tags like the following into any
|
||||
commit. Most can only appear once in the whole series.
|
||||
|
||||
Series-to: email / alias
|
||||
Email address / alias to send patch series to (you can add this
|
||||
multiple times)
|
||||
|
||||
Series-cc: email / alias, ...
|
||||
Email address / alias to Cc patch series to (you can add this
|
||||
multiple times)
|
||||
|
||||
Series-version: n
|
||||
Sets the version number of this patch series
|
||||
|
||||
Series-prefix: prefix
|
||||
Sets the subject prefix. Normally empty but it can be RFC for
|
||||
RFC patches, or RESEND if you are being ignored.
|
||||
|
||||
Cover-letter:
|
||||
This is the patch set title
|
||||
blah blah
|
||||
more blah blah
|
||||
END
|
||||
Sets the cover letter contents for the series. The first line
|
||||
will become the subject of the cover letter
|
||||
|
||||
Series-notes:
|
||||
blah blah
|
||||
blah blah
|
||||
more blah blah
|
||||
END
|
||||
Sets some notes for the patch series, which you don't want in
|
||||
the commit messages, but do want to send, The notes are joined
|
||||
together and put after the cover letter. Can appear multiple
|
||||
times.
|
||||
|
||||
Signed-off-by: Their Name <email>
|
||||
A sign-off is added automatically to your patches (this is
|
||||
probably a bug). If you put this tag in your patches, it will
|
||||
override the default signoff that patman automatically adds.
|
||||
|
||||
Tested-by: Their Name <email>
|
||||
Acked-by: Their Name <email>
|
||||
These indicate that someone has acked or tested your patch.
|
||||
When you get this reply on the mailing list, you can add this
|
||||
tag to the relevant commit and the script will include it when
|
||||
you send out the next version. If 'Tested-by:' is set to
|
||||
yourself, it will be removed. No one will believe you.
|
||||
|
||||
Series-changes: n
|
||||
- Guinea pig moved into its cage
|
||||
- Other changes ending with a blank line
|
||||
<blank line>
|
||||
This can appear in any commit. It lists the changes for a
|
||||
particular version n of that commit. The change list is
|
||||
created based on this information. Each commit gets its own
|
||||
change list and also the whole thing is repeated in the cover
|
||||
letter (where duplicate change lines are merged).
|
||||
|
||||
By adding your change lists into your commits it is easier to
|
||||
keep track of what happened. When you amend a commit, remember
|
||||
to update the log there and then, knowing that the script will
|
||||
do the rest.
|
||||
|
||||
Cc: Their Name <email>
|
||||
This copies a single patch to another email address.
|
||||
|
||||
Various other tags are silently removed, like these Chrome OS and
|
||||
Gerrit tags:
|
||||
|
||||
BUG=...
|
||||
TEST=...
|
||||
Change-Id:
|
||||
Review URL:
|
||||
Reviewed-on:
|
||||
Reviewed-by:
|
||||
|
||||
|
||||
Exercise for the reader: Try adding some tags to one of your current
|
||||
patch series and see how the patches turn out.
|
||||
|
||||
|
||||
Where Patches Are Sent
|
||||
======================
|
||||
|
||||
Once the patches are created, patman sends them using gti send-email. The
|
||||
whole series is sent to the recipients in Series-to: and Series-cc.
|
||||
You can Cc individual patches to other people with the Cc: tag. Tags in the
|
||||
subject are also picked up to Cc patches. For example, a commit like this:
|
||||
|
||||
>>>>
|
||||
commit 10212537b85ff9b6e09c82045127522c0f0db981
|
||||
Author: Mike Frysinger <vapier@gentoo.org>
|
||||
Date: Mon Nov 7 23:18:44 2011 -0500
|
||||
|
||||
x86: arm: add a git mailrc file for maintainers
|
||||
|
||||
This should make sending out e-mails to the right people easier.
|
||||
|
||||
Cc: sandbox, mikef, ag
|
||||
Cc: afleming
|
||||
<<<<
|
||||
|
||||
will create a patch which is copied to x86, arm, sandbox, mikef, ag and
|
||||
afleming.
|
||||
|
||||
|
||||
Example Work Flow
|
||||
=================
|
||||
|
||||
The basic workflow is to create your commits, add some tags to the top
|
||||
commit, and type 'patman' to check and send them.
|
||||
|
||||
Here is an example workflow for a series of 4 patches. Let's say you have
|
||||
these rather contrived patches in the following order in branch us-cmd in
|
||||
your tree where 'us' means your upstreaming activity (newest to oldest as
|
||||
output by git log --oneline):
|
||||
|
||||
7c7909c wip
|
||||
89234f5 Don't include standard parser if hush is used
|
||||
8d640a7 mmc: sparc: Stop using builtin_run_command()
|
||||
0c859a9 Rename run_command2() to run_command()
|
||||
a74443f sandbox: Rename run_command() to builtin_run_command()
|
||||
|
||||
The first patch is some test things that enable your code to be compiled,
|
||||
but that you don't want to submit because there is an existing patch for it
|
||||
on the list. So you can tell patman to create and check some patches
|
||||
(skipping the first patch) with:
|
||||
|
||||
patman -s1 -n
|
||||
|
||||
If you want to do all of them including the work-in-progress one, then
|
||||
(if you are tracking an upstream branch):
|
||||
|
||||
patman -n
|
||||
|
||||
Let's say that patman reports an error in the second patch. Then:
|
||||
|
||||
git rebase -i HEAD~6
|
||||
<change 'pick' to 'edit' in 89234f5>
|
||||
<use editor to make code changes>
|
||||
git add -u
|
||||
git rebase --continue
|
||||
|
||||
Now you have an updated patch series. To check it:
|
||||
|
||||
patman -s1 -n
|
||||
|
||||
Let's say it is now clean and you want to send it. Now you need to set up
|
||||
the destination. So amend the top commit with:
|
||||
|
||||
git commit --amend
|
||||
|
||||
Use your editor to add some tags, so that the whole commit message is:
|
||||
|
||||
The current run_command() is really only one of the options, with
|
||||
hush providing the other. It really shouldn't be called directly
|
||||
in case the hush parser is bring used, so rename this function to
|
||||
better explain its purpose.
|
||||
|
||||
Series-to: u-boot
|
||||
Series-cc: bfin, marex
|
||||
Series-prefix: RFC
|
||||
Cover-letter:
|
||||
Unified command execution in one place
|
||||
|
||||
At present two parsers have similar code to execute commands. Also
|
||||
cmd_usage() is called all over the place. This series adds a single
|
||||
function which processes commands called cmd_process().
|
||||
END
|
||||
|
||||
Change-Id: Ica71a14c1f0ecb5650f771a32fecb8d2eb9d8a17
|
||||
|
||||
|
||||
You want this to be an RFC and Cc the whole series to the bfin alias and
|
||||
to Marek. Two of the patches have tags (those are the bits at the front of
|
||||
the subject that say mmc: sparc: and sandbox:), so 8d640a7 will be Cc'd to
|
||||
mmc and sparc, and the last one to sandbox.
|
||||
|
||||
Now to send the patches, take off the -n flag:
|
||||
|
||||
patman -s1
|
||||
|
||||
The patches will be created, shown in your editor, and then sent along with
|
||||
the cover letter. Note that patman's tags are automatically removed so that
|
||||
people on the list don't see your secret info.
|
||||
|
||||
Of course patches often attract comments and you need to make some updates.
|
||||
Let's say one person sent comments and you get an Acked-by: on one patch.
|
||||
Also, the patch on the list that you were waiting for has been merged,
|
||||
so you can drop your wip commit. So you resync with upstream:
|
||||
|
||||
git fetch origin (or whatever upstream is called)
|
||||
git rebase origin/master
|
||||
|
||||
and use git rebase -i to edit the commits, dropping the wip one. You add
|
||||
the ack tag to one commit:
|
||||
|
||||
Acked-by: Heiko Schocher <hs@denx.de>
|
||||
|
||||
update the Series-cc: in the top commit:
|
||||
|
||||
Series-cc: bfin, marex, Heiko Schocher <hs@denx.de>
|
||||
|
||||
and remove the Series-prefix: tag since it it isn't an RFC any more. The
|
||||
series is now version two, so the series info in the top commit looks like
|
||||
this:
|
||||
|
||||
Series-to: u-boot
|
||||
Series-cc: bfin, marex, Heiko Schocher <hs@denx.de>
|
||||
Series-version: 2
|
||||
Cover-letter:
|
||||
...
|
||||
|
||||
Finally, you need to add a change log to the two commits you changed. You
|
||||
add change logs to each individual commit where the changes happened, like
|
||||
this:
|
||||
|
||||
Series-changes: 2
|
||||
- Updated the command decoder to reduce code size
|
||||
- Wound the torque propounder up a little more
|
||||
|
||||
(note the blank line at the end of the list)
|
||||
|
||||
When you run patman it will collect all the change logs from the different
|
||||
commits and combine them into the cover letter, if you have one. So finally
|
||||
you have a new series of commits:
|
||||
|
||||
faeb973 Don't include standard parser if hush is used
|
||||
1b2f2fe mmc: sparc: Stop using builtin_run_command()
|
||||
cfbe330 Rename run_command2() to run_command()
|
||||
0682677 sandbox: Rename run_command() to builtin_run_command()
|
||||
|
||||
so to send them:
|
||||
|
||||
patman
|
||||
|
||||
and it will create and send the version 2 series.
|
||||
|
||||
General points:
|
||||
|
||||
1. When you change back to the us-cmd branch days or weeks later all your
|
||||
information is still there, safely stored in the commits. You don't need
|
||||
to remember what version you are up to, who you sent the last lot of patches
|
||||
to, or anything about the change logs.
|
||||
|
||||
2. If you put tags in the subject, patman will Cc the maintainers
|
||||
automatically in many cases.
|
||||
|
||||
3. If you want to keep the commits from each series you sent so that you can
|
||||
compare change and see what you did, you can either create a new branch for
|
||||
each version, or just tag the branch before you start changing it:
|
||||
|
||||
git tag sent/us-cmd-rfc
|
||||
...later...
|
||||
git tag sent/us-cmd-v2
|
||||
|
||||
4. If you want to modify the patches a little before sending, you can do
|
||||
this in your editor, but be careful!
|
||||
|
||||
5. If you want to run git send-email yourself, use the -n flag which will
|
||||
print out the command line patman would have used.
|
||||
|
||||
6. It is a good idea to add the change log info as you change the commit,
|
||||
not later when you can't remember which patch you changed. You can always
|
||||
go back and change or remove logs from commits.
|
||||
|
||||
|
||||
Other thoughts
|
||||
==============
|
||||
|
||||
This script has been split into sensible files but still needs work.
|
||||
Most of these are indicated by a TODO in the code.
|
||||
|
||||
It would be nice if this could handle the In-reply-to side of things.
|
||||
|
||||
The tests are incomplete, as is customary. Use the -t flag to run them,
|
||||
and make sure you are in the tools/scripts/patman directory first:
|
||||
|
||||
$ cd /path/to/u-boot
|
||||
$ cd tools/scripts/patman
|
||||
$ patman -t
|
||||
|
||||
Error handling doesn't always produce friendly error messages - e.g.
|
||||
putting an incorrect tag in a commit may provide a confusing message.
|
||||
|
||||
There might be a few other features not mentioned in this README. They
|
||||
might be bugs. In particular, tags are case sensitive which is probably
|
||||
a bad thing.
|
||||
|
||||
|
||||
Simon Glass <sjg@chromium.org>
|
||||
v1, v2, 19-Oct-11
|
||||
revised v3 24-Nov-11
|
||||
161
tools/patman/checkpatch.py
Normal file
161
tools/patman/checkpatch.py
Normal file
@@ -0,0 +1,161 @@
|
||||
# Copyright (c) 2011 The Chromium OS Authors.
|
||||
#
|
||||
# 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
|
||||
#
|
||||
|
||||
import command
|
||||
import gitutil
|
||||
import os
|
||||
import re
|
||||
import terminal
|
||||
|
||||
def FindCheckPatch():
|
||||
try_list = [
|
||||
os.getcwd(),
|
||||
os.path.join(os.getcwd(), '..', '..'),
|
||||
os.path.join(gitutil.GetTopLevel(), 'tools'),
|
||||
'%s/bin' % os.getenv('HOME'),
|
||||
]
|
||||
# Look in current dir
|
||||
for path in try_list:
|
||||
fname = os.path.join(path, 'checkpatch.pl')
|
||||
if os.path.isfile(fname):
|
||||
return fname
|
||||
|
||||
# Look upwwards for a Chrome OS tree
|
||||
while not os.path.ismount(path):
|
||||
fname = os.path.join(path, 'src', 'third_party', 'kernel', 'files',
|
||||
'scripts', 'checkpatch.pl')
|
||||
if os.path.isfile(fname):
|
||||
return fname
|
||||
path = os.path.dirname(path)
|
||||
print 'Could not find checkpatch.pl'
|
||||
return None
|
||||
|
||||
def CheckPatch(fname, verbose=False):
|
||||
"""Run checkpatch.pl on a file.
|
||||
|
||||
Returns:
|
||||
4-tuple containing:
|
||||
result: False=failure, True=ok
|
||||
problems: List of problems, each a dict:
|
||||
'type'; error or warning
|
||||
'msg': text message
|
||||
'file' : filename
|
||||
'line': line number
|
||||
lines: Number of lines
|
||||
"""
|
||||
result = False
|
||||
error_count, warning_count, lines = 0, 0, 0
|
||||
problems = []
|
||||
chk = FindCheckPatch()
|
||||
if not chk:
|
||||
raise OSError, ('Cannot find checkpatch.pl - please put it in your ' +
|
||||
'~/bin directory')
|
||||
item = {}
|
||||
stdout = command.Output(chk, '--no-tree', fname)
|
||||
#pipe = subprocess.Popen(cmd, stdout=subprocess.PIPE)
|
||||
#stdout, stderr = pipe.communicate()
|
||||
|
||||
# total: 0 errors, 0 warnings, 159 lines checked
|
||||
re_stats = re.compile('total: (\\d+) errors, (\d+) warnings, (\d+)')
|
||||
re_ok = re.compile('.*has no obvious style problems')
|
||||
re_bad = re.compile('.*has style problems, please review')
|
||||
re_error = re.compile('ERROR: (.*)')
|
||||
re_warning = re.compile('WARNING: (.*)')
|
||||
re_file = re.compile('#\d+: FILE: ([^:]*):(\d+):')
|
||||
|
||||
for line in stdout.splitlines():
|
||||
if verbose:
|
||||
print line
|
||||
|
||||
# A blank line indicates the end of a message
|
||||
if not line and item:
|
||||
problems.append(item)
|
||||
item = {}
|
||||
match = re_stats.match(line)
|
||||
if match:
|
||||
error_count = int(match.group(1))
|
||||
warning_count = int(match.group(2))
|
||||
lines = int(match.group(3))
|
||||
elif re_ok.match(line):
|
||||
result = True
|
||||
elif re_bad.match(line):
|
||||
result = False
|
||||
match = re_error.match(line)
|
||||
if match:
|
||||
item['msg'] = match.group(1)
|
||||
item['type'] = 'error'
|
||||
match = re_warning.match(line)
|
||||
if match:
|
||||
item['msg'] = match.group(1)
|
||||
item['type'] = 'warning'
|
||||
match = re_file.match(line)
|
||||
if match:
|
||||
item['file'] = match.group(1)
|
||||
item['line'] = int(match.group(2))
|
||||
|
||||
return result, problems, error_count, warning_count, lines, stdout
|
||||
|
||||
def GetWarningMsg(col, msg_type, fname, line, msg):
|
||||
'''Create a message for a given file/line
|
||||
|
||||
Args:
|
||||
msg_type: Message type ('error' or 'warning')
|
||||
fname: Filename which reports the problem
|
||||
line: Line number where it was noticed
|
||||
msg: Message to report
|
||||
'''
|
||||
if msg_type == 'warning':
|
||||
msg_type = col.Color(col.YELLOW, msg_type)
|
||||
elif msg_type == 'error':
|
||||
msg_type = col.Color(col.RED, msg_type)
|
||||
return '%s: %s,%d: %s' % (msg_type, fname, line, msg)
|
||||
|
||||
def CheckPatches(verbose, args):
|
||||
'''Run the checkpatch.pl script on each patch'''
|
||||
error_count = 0
|
||||
warning_count = 0
|
||||
col = terminal.Color()
|
||||
|
||||
for fname in args:
|
||||
ok, problems, errors, warnings, lines, stdout = CheckPatch(fname,
|
||||
verbose)
|
||||
if not ok:
|
||||
error_count += errors
|
||||
warning_count += warnings
|
||||
print '%d errors, %d warnings for %s:' % (errors,
|
||||
warnings, fname)
|
||||
if len(problems) != error_count + warning_count:
|
||||
print "Internal error: some problems lost"
|
||||
for item in problems:
|
||||
print GetWarningMsg(col, item['type'], item['file'],
|
||||
item['line'], item['msg'])
|
||||
#print stdout
|
||||
if error_count != 0 or warning_count != 0:
|
||||
str = 'checkpatch.pl found %d error(s), %d warning(s)' % (
|
||||
error_count, warning_count)
|
||||
color = col.GREEN
|
||||
if warning_count:
|
||||
color = col.YELLOW
|
||||
if error_count:
|
||||
color = col.RED
|
||||
print col.Color(color, str)
|
||||
return False
|
||||
return True
|
||||
72
tools/patman/command.py
Normal file
72
tools/patman/command.py
Normal file
@@ -0,0 +1,72 @@
|
||||
# Copyright (c) 2011 The Chromium OS Authors.
|
||||
#
|
||||
# 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
|
||||
#
|
||||
|
||||
import os
|
||||
import subprocess
|
||||
|
||||
"""Shell command ease-ups for Python."""
|
||||
|
||||
def RunPipe(pipeline, infile=None, outfile=None,
|
||||
capture=False, oneline=False, hide_stderr=False):
|
||||
"""
|
||||
Perform a command pipeline, with optional input/output filenames.
|
||||
|
||||
hide_stderr Don't allow output of stderr (default False)
|
||||
"""
|
||||
last_pipe = None
|
||||
while pipeline:
|
||||
cmd = pipeline.pop(0)
|
||||
kwargs = {}
|
||||
if last_pipe is not None:
|
||||
kwargs['stdin'] = last_pipe.stdout
|
||||
elif infile:
|
||||
kwargs['stdin'] = open(infile, 'rb')
|
||||
if pipeline or capture:
|
||||
kwargs['stdout'] = subprocess.PIPE
|
||||
elif outfile:
|
||||
kwargs['stdout'] = open(outfile, 'wb')
|
||||
if hide_stderr:
|
||||
kwargs['stderr'] = open('/dev/null', 'wb')
|
||||
|
||||
last_pipe = subprocess.Popen(cmd, **kwargs)
|
||||
|
||||
if capture:
|
||||
ret = last_pipe.communicate()[0]
|
||||
if not ret:
|
||||
return None
|
||||
elif oneline:
|
||||
return ret.rstrip('\r\n')
|
||||
else:
|
||||
return ret
|
||||
else:
|
||||
return os.waitpid(last_pipe.pid, 0)[1] == 0
|
||||
|
||||
def Output(*cmd):
|
||||
return RunPipe([cmd], capture=True)
|
||||
|
||||
def OutputOneLine(*cmd):
|
||||
return RunPipe([cmd], capture=True, oneline=True)
|
||||
|
||||
def Run(*cmd, **kwargs):
|
||||
return RunPipe([cmd], **kwargs)
|
||||
|
||||
def RunList(cmd):
|
||||
return RunPipe([cmd], capture=True)
|
||||
87
tools/patman/commit.py
Normal file
87
tools/patman/commit.py
Normal file
@@ -0,0 +1,87 @@
|
||||
# Copyright (c) 2011 The Chromium OS Authors.
|
||||
#
|
||||
# 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
|
||||
#
|
||||
|
||||
import re
|
||||
|
||||
# Separates a tag: at the beginning of the subject from the rest of it
|
||||
re_subject_tag = re.compile('([^:]*):\s*(.*)')
|
||||
|
||||
class Commit:
|
||||
"""Holds information about a single commit/patch in the series.
|
||||
|
||||
Args:
|
||||
hash: Commit hash (as a string)
|
||||
|
||||
Variables:
|
||||
hash: Commit hash
|
||||
subject: Subject line
|
||||
tags: List of maintainer tag strings
|
||||
changes: Dict containing a list of changes (single line strings).
|
||||
The dict is indexed by change version (an integer)
|
||||
cc_list: List of people to aliases/emails to cc on this commit
|
||||
"""
|
||||
def __init__(self, hash):
|
||||
self.hash = hash
|
||||
self.subject = None
|
||||
self.tags = []
|
||||
self.changes = {}
|
||||
self.cc_list = []
|
||||
|
||||
def AddChange(self, version, info):
|
||||
"""Add a new change line to the change list for a version.
|
||||
|
||||
Args:
|
||||
version: Patch set version (integer: 1, 2, 3)
|
||||
info: Description of change in this version
|
||||
"""
|
||||
if not self.changes.get(version):
|
||||
self.changes[version] = []
|
||||
self.changes[version].append(info)
|
||||
|
||||
def CheckTags(self):
|
||||
"""Create a list of subject tags in the commit
|
||||
|
||||
Subject tags look like this:
|
||||
|
||||
propounder: Change the widget to propound correctly
|
||||
|
||||
Multiple tags are supported. The list is updated in self.tag
|
||||
|
||||
Returns:
|
||||
None if ok, else the name of a tag with no email alias
|
||||
"""
|
||||
str = self.subject
|
||||
m = True
|
||||
while m:
|
||||
m = re_subject_tag.match(str)
|
||||
if m:
|
||||
tag = m.group(1)
|
||||
self.tags.append(tag)
|
||||
str = m.group(2)
|
||||
return None
|
||||
|
||||
def AddCc(self, cc_list):
|
||||
"""Add a list of people to Cc when we send this patch.
|
||||
|
||||
Args:
|
||||
cc_list: List of aliases or email addresses
|
||||
"""
|
||||
self.cc_list += cc_list
|
||||
372
tools/patman/gitutil.py
Normal file
372
tools/patman/gitutil.py
Normal file
@@ -0,0 +1,372 @@
|
||||
# Copyright (c) 2011 The Chromium OS Authors.
|
||||
#
|
||||
# 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
|
||||
#
|
||||
|
||||
import command
|
||||
import re
|
||||
import os
|
||||
import series
|
||||
import settings
|
||||
import subprocess
|
||||
import sys
|
||||
import terminal
|
||||
|
||||
|
||||
def CountCommitsToBranch():
|
||||
"""Returns number of commits between HEAD and the tracking branch.
|
||||
|
||||
This looks back to the tracking branch and works out the number of commits
|
||||
since then.
|
||||
|
||||
Return:
|
||||
Number of patches that exist on top of the branch
|
||||
"""
|
||||
pipe = [['git', 'log', '--oneline', '@{upstream}..'],
|
||||
['wc', '-l']]
|
||||
stdout = command.RunPipe(pipe, capture=True, oneline=True)
|
||||
patch_count = int(stdout)
|
||||
return patch_count
|
||||
|
||||
def CreatePatches(start, count, series):
|
||||
"""Create a series of patches from the top of the current branch.
|
||||
|
||||
The patch files are written to the current directory using
|
||||
git format-patch.
|
||||
|
||||
Args:
|
||||
start: Commit to start from: 0=HEAD, 1=next one, etc.
|
||||
count: number of commits to include
|
||||
Return:
|
||||
Filename of cover letter
|
||||
List of filenames of patch files
|
||||
"""
|
||||
if series.get('version'):
|
||||
version = '%s ' % series['version']
|
||||
cmd = ['git', 'format-patch', '-M', '--signoff']
|
||||
if series.get('cover'):
|
||||
cmd.append('--cover-letter')
|
||||
prefix = series.GetPatchPrefix()
|
||||
if prefix:
|
||||
cmd += ['--subject-prefix=%s' % prefix]
|
||||
cmd += ['HEAD~%d..HEAD~%d' % (start + count, start)]
|
||||
|
||||
stdout = command.RunList(cmd)
|
||||
files = stdout.splitlines()
|
||||
|
||||
# We have an extra file if there is a cover letter
|
||||
if series.get('cover'):
|
||||
return files[0], files[1:]
|
||||
else:
|
||||
return None, files
|
||||
|
||||
def ApplyPatch(verbose, fname):
|
||||
"""Apply a patch with git am to test it
|
||||
|
||||
TODO: Convert these to use command, with stderr option
|
||||
|
||||
Args:
|
||||
fname: filename of patch file to apply
|
||||
"""
|
||||
cmd = ['git', 'am', fname]
|
||||
pipe = subprocess.Popen(cmd, stdout=subprocess.PIPE,
|
||||
stderr=subprocess.PIPE)
|
||||
stdout, stderr = pipe.communicate()
|
||||
re_error = re.compile('^error: patch failed: (.+):(\d+)')
|
||||
for line in stderr.splitlines():
|
||||
if verbose:
|
||||
print line
|
||||
match = re_error.match(line)
|
||||
if match:
|
||||
print GetWarningMsg('warning', match.group(1), int(match.group(2)),
|
||||
'Patch failed')
|
||||
return pipe.returncode == 0, stdout
|
||||
|
||||
def ApplyPatches(verbose, args, start_point):
|
||||
"""Apply the patches with git am to make sure all is well
|
||||
|
||||
Args:
|
||||
verbose: Print out 'git am' output verbatim
|
||||
args: List of patch files to apply
|
||||
start_point: Number of commits back from HEAD to start applying.
|
||||
Normally this is len(args), but it can be larger if a start
|
||||
offset was given.
|
||||
"""
|
||||
error_count = 0
|
||||
col = terminal.Color()
|
||||
|
||||
# Figure out our current position
|
||||
cmd = ['git', 'name-rev', 'HEAD', '--name-only']
|
||||
pipe = subprocess.Popen(cmd, stdout=subprocess.PIPE)
|
||||
stdout, stderr = pipe.communicate()
|
||||
if pipe.returncode:
|
||||
str = 'Could not find current commit name'
|
||||
print col.Color(col.RED, str)
|
||||
print stdout
|
||||
return False
|
||||
old_head = stdout.splitlines()[0]
|
||||
|
||||
# Checkout the required start point
|
||||
cmd = ['git', 'checkout', 'HEAD~%d' % start_point]
|
||||
pipe = subprocess.Popen(cmd, stdout=subprocess.PIPE,
|
||||
stderr=subprocess.PIPE)
|
||||
stdout, stderr = pipe.communicate()
|
||||
if pipe.returncode:
|
||||
str = 'Could not move to commit before patch series'
|
||||
print col.Color(col.RED, str)
|
||||
print stdout, stderr
|
||||
return False
|
||||
|
||||
# Apply all the patches
|
||||
for fname in args:
|
||||
ok, stdout = ApplyPatch(verbose, fname)
|
||||
if not ok:
|
||||
print col.Color(col.RED, 'git am returned errors for %s: will '
|
||||
'skip this patch' % fname)
|
||||
if verbose:
|
||||
print stdout
|
||||
error_count += 1
|
||||
cmd = ['git', 'am', '--skip']
|
||||
pipe = subprocess.Popen(cmd, stdout=subprocess.PIPE)
|
||||
stdout, stderr = pipe.communicate()
|
||||
if pipe.returncode != 0:
|
||||
print col.Color(col.RED, 'Unable to skip patch! Aborting...')
|
||||
print stdout
|
||||
break
|
||||
|
||||
# Return to our previous position
|
||||
cmd = ['git', 'checkout', old_head]
|
||||
pipe = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||
stdout, stderr = pipe.communicate()
|
||||
if pipe.returncode:
|
||||
print col.Color(col.RED, 'Could not move back to head commit')
|
||||
print stdout, stderr
|
||||
return error_count == 0
|
||||
|
||||
def BuildEmailList(in_list, tag=None, alias=None):
|
||||
"""Build a list of email addresses based on an input list.
|
||||
|
||||
Takes a list of email addresses and aliases, and turns this into a list
|
||||
of only email address, by resolving any aliases that are present.
|
||||
|
||||
If the tag is given, then each email address is prepended with this
|
||||
tag and a space. If the tag starts with a minus sign (indicating a
|
||||
command line parameter) then the email address is quoted.
|
||||
|
||||
Args:
|
||||
in_list: List of aliases/email addresses
|
||||
tag: Text to put before each address
|
||||
|
||||
Returns:
|
||||
List of email addresses
|
||||
|
||||
>>> alias = {}
|
||||
>>> alias['fred'] = ['f.bloggs@napier.co.nz']
|
||||
>>> alias['john'] = ['j.bloggs@napier.co.nz']
|
||||
>>> alias['mary'] = ['Mary Poppins <m.poppins@cloud.net>']
|
||||
>>> alias['boys'] = ['fred', ' john']
|
||||
>>> alias['all'] = ['fred ', 'john', ' mary ']
|
||||
>>> BuildEmailList(['john', 'mary'], None, alias)
|
||||
['j.bloggs@napier.co.nz', 'Mary Poppins <m.poppins@cloud.net>']
|
||||
>>> BuildEmailList(['john', 'mary'], '--to', alias)
|
||||
['--to "j.bloggs@napier.co.nz"', \
|
||||
'--to "Mary Poppins <m.poppins@cloud.net>"']
|
||||
>>> BuildEmailList(['john', 'mary'], 'Cc', alias)
|
||||
['Cc j.bloggs@napier.co.nz', 'Cc Mary Poppins <m.poppins@cloud.net>']
|
||||
"""
|
||||
quote = '"' if tag and tag[0] == '-' else ''
|
||||
raw = []
|
||||
for item in in_list:
|
||||
raw += LookupEmail(item, alias)
|
||||
result = []
|
||||
for item in raw:
|
||||
if not item in result:
|
||||
result.append(item)
|
||||
if tag:
|
||||
return ['%s %s%s%s' % (tag, quote, email, quote) for email in result]
|
||||
return result
|
||||
|
||||
def EmailPatches(series, cover_fname, args, dry_run, cc_fname,
|
||||
self_only=False, alias=None):
|
||||
"""Email a patch series.
|
||||
|
||||
Args:
|
||||
series: Series object containing destination info
|
||||
cover_fname: filename of cover letter
|
||||
args: list of filenames of patch files
|
||||
dry_run: Just return the command that would be run
|
||||
cc_fname: Filename of Cc file for per-commit Cc
|
||||
self_only: True to just email to yourself as a test
|
||||
|
||||
Returns:
|
||||
Git command that was/would be run
|
||||
|
||||
>>> alias = {}
|
||||
>>> alias['fred'] = ['f.bloggs@napier.co.nz']
|
||||
>>> alias['john'] = ['j.bloggs@napier.co.nz']
|
||||
>>> alias['mary'] = ['m.poppins@cloud.net']
|
||||
>>> alias['boys'] = ['fred', ' john']
|
||||
>>> alias['all'] = ['fred ', 'john', ' mary ']
|
||||
>>> alias[os.getenv('USER')] = ['this-is-me@me.com']
|
||||
>>> series = series.Series()
|
||||
>>> series.to = ['fred']
|
||||
>>> series.cc = ['mary']
|
||||
>>> EmailPatches(series, 'cover', ['p1', 'p2'], True, 'cc-fname', False, \
|
||||
alias)
|
||||
'git send-email --annotate --to "f.bloggs@napier.co.nz" --cc \
|
||||
"m.poppins@cloud.net" --cc-cmd "./patman --cc-cmd cc-fname" cover p1 p2'
|
||||
>>> EmailPatches(series, None, ['p1'], True, 'cc-fname', False, alias)
|
||||
'git send-email --annotate --to "f.bloggs@napier.co.nz" --cc \
|
||||
"m.poppins@cloud.net" --cc-cmd "./patman --cc-cmd cc-fname" p1'
|
||||
>>> series.cc = ['all']
|
||||
>>> EmailPatches(series, 'cover', ['p1', 'p2'], True, 'cc-fname', True, \
|
||||
alias)
|
||||
'git send-email --annotate --to "this-is-me@me.com" --cc-cmd "./patman \
|
||||
--cc-cmd cc-fname" cover p1 p2'
|
||||
>>> EmailPatches(series, 'cover', ['p1', 'p2'], True, 'cc-fname', False, \
|
||||
alias)
|
||||
'git send-email --annotate --to "f.bloggs@napier.co.nz" --cc \
|
||||
"f.bloggs@napier.co.nz" --cc "j.bloggs@napier.co.nz" --cc \
|
||||
"m.poppins@cloud.net" --cc-cmd "./patman --cc-cmd cc-fname" cover p1 p2'
|
||||
"""
|
||||
to = BuildEmailList(series.get('to'), '--to', alias)
|
||||
if not to:
|
||||
print ("No recipient, please add something like this to a commit\n"
|
||||
"Series-to: Fred Bloggs <f.blogs@napier.co.nz>")
|
||||
return
|
||||
cc = BuildEmailList(series.get('cc'), '--cc', alias)
|
||||
if self_only:
|
||||
to = BuildEmailList([os.getenv('USER')], '--to', alias)
|
||||
cc = []
|
||||
cmd = ['git', 'send-email', '--annotate']
|
||||
cmd += to
|
||||
cmd += cc
|
||||
cmd += ['--cc-cmd', '"%s --cc-cmd %s"' % (sys.argv[0], cc_fname)]
|
||||
if cover_fname:
|
||||
cmd.append(cover_fname)
|
||||
cmd += args
|
||||
str = ' '.join(cmd)
|
||||
if not dry_run:
|
||||
os.system(str)
|
||||
return str
|
||||
|
||||
|
||||
def LookupEmail(lookup_name, alias=None, level=0):
|
||||
"""If an email address is an alias, look it up and return the full name
|
||||
|
||||
TODO: Why not just use git's own alias feature?
|
||||
|
||||
Args:
|
||||
lookup_name: Alias or email address to look up
|
||||
|
||||
Returns:
|
||||
tuple:
|
||||
list containing a list of email addresses
|
||||
|
||||
Raises:
|
||||
OSError if a recursive alias reference was found
|
||||
ValueError if an alias was not found
|
||||
|
||||
>>> alias = {}
|
||||
>>> alias['fred'] = ['f.bloggs@napier.co.nz']
|
||||
>>> alias['john'] = ['j.bloggs@napier.co.nz']
|
||||
>>> alias['mary'] = ['m.poppins@cloud.net']
|
||||
>>> alias['boys'] = ['fred', ' john', 'f.bloggs@napier.co.nz']
|
||||
>>> alias['all'] = ['fred ', 'john', ' mary ']
|
||||
>>> alias['loop'] = ['other', 'john', ' mary ']
|
||||
>>> alias['other'] = ['loop', 'john', ' mary ']
|
||||
>>> LookupEmail('mary', alias)
|
||||
['m.poppins@cloud.net']
|
||||
>>> LookupEmail('arthur.wellesley@howe.ro.uk', alias)
|
||||
['arthur.wellesley@howe.ro.uk']
|
||||
>>> LookupEmail('boys', alias)
|
||||
['f.bloggs@napier.co.nz', 'j.bloggs@napier.co.nz']
|
||||
>>> LookupEmail('all', alias)
|
||||
['f.bloggs@napier.co.nz', 'j.bloggs@napier.co.nz', 'm.poppins@cloud.net']
|
||||
>>> LookupEmail('odd', alias)
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
ValueError: Alias 'odd' not found
|
||||
>>> LookupEmail('loop', alias)
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
OSError: Recursive email alias at 'other'
|
||||
"""
|
||||
if not alias:
|
||||
alias = settings.alias
|
||||
lookup_name = lookup_name.strip()
|
||||
if '@' in lookup_name: # Perhaps a real email address
|
||||
return [lookup_name]
|
||||
|
||||
lookup_name = lookup_name.lower()
|
||||
|
||||
if level > 10:
|
||||
raise OSError, "Recursive email alias at '%s'" % lookup_name
|
||||
|
||||
out_list = []
|
||||
if lookup_name:
|
||||
if not lookup_name in alias:
|
||||
raise ValueError, "Alias '%s' not found" % lookup_name
|
||||
for item in alias[lookup_name]:
|
||||
todo = LookupEmail(item, alias, level + 1)
|
||||
for new_item in todo:
|
||||
if not new_item in out_list:
|
||||
out_list.append(new_item)
|
||||
|
||||
#print "No match for alias '%s'" % lookup_name
|
||||
return out_list
|
||||
|
||||
def GetTopLevel():
|
||||
"""Return name of top-level directory for this git repo.
|
||||
|
||||
Returns:
|
||||
Full path to git top-level directory
|
||||
|
||||
This test makes sure that we are running tests in the right subdir
|
||||
|
||||
>>> os.path.realpath(os.getcwd()) == \
|
||||
os.path.join(GetTopLevel(), 'tools', 'scripts', 'patman')
|
||||
True
|
||||
"""
|
||||
return command.OutputOneLine('git', 'rev-parse', '--show-toplevel')
|
||||
|
||||
def GetAliasFile():
|
||||
"""Gets the name of the git alias file.
|
||||
|
||||
Returns:
|
||||
Filename of git alias file, or None if none
|
||||
"""
|
||||
fname = command.OutputOneLine('git', 'config', 'sendemail.aliasesfile')
|
||||
if fname:
|
||||
fname = os.path.join(GetTopLevel(), fname.strip())
|
||||
return fname
|
||||
|
||||
def Setup():
|
||||
"""Set up git utils, by reading the alias files."""
|
||||
settings.Setup('')
|
||||
|
||||
# Check for a git alias file also
|
||||
alias_fname = GetAliasFile()
|
||||
if alias_fname:
|
||||
settings.ReadGitAliases(alias_fname)
|
||||
|
||||
if __name__ == "__main__":
|
||||
import doctest
|
||||
|
||||
doctest.testmod()
|
||||
444
tools/patman/patchstream.py
Normal file
444
tools/patman/patchstream.py
Normal file
@@ -0,0 +1,444 @@
|
||||
# Copyright (c) 2011 The Chromium OS Authors.
|
||||
#
|
||||
# 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
|
||||
#
|
||||
|
||||
import os
|
||||
import re
|
||||
import shutil
|
||||
import tempfile
|
||||
|
||||
import command
|
||||
import commit
|
||||
import gitutil
|
||||
from series import Series
|
||||
|
||||
# Tags that we detect and remove
|
||||
re_remove = re.compile('^BUG=|^TEST=|^Change-Id:|^Review URL:'
|
||||
'|Reviewed-on:|Reviewed-by:')
|
||||
|
||||
# Lines which are allowed after a TEST= line
|
||||
re_allowed_after_test = re.compile('^Signed-off-by:')
|
||||
|
||||
# The start of the cover letter
|
||||
re_cover = re.compile('^Cover-letter:')
|
||||
|
||||
# Patch series tag
|
||||
re_series = re.compile('^Series-(\w*): *(.*)')
|
||||
|
||||
# Commit tags that we want to collect and keep
|
||||
re_tag = re.compile('^(Tested-by|Acked-by|Signed-off-by|Cc): (.*)')
|
||||
|
||||
# The start of a new commit in the git log
|
||||
re_commit = re.compile('^commit (.*)')
|
||||
|
||||
# We detect these since checkpatch doesn't always do it
|
||||
re_space_before_tab = re.compile('^[+].* \t')
|
||||
|
||||
# States we can be in - can we use range() and still have comments?
|
||||
STATE_MSG_HEADER = 0 # Still in the message header
|
||||
STATE_PATCH_SUBJECT = 1 # In patch subject (first line of log for a commit)
|
||||
STATE_PATCH_HEADER = 2 # In patch header (after the subject)
|
||||
STATE_DIFFS = 3 # In the diff part (past --- line)
|
||||
|
||||
class PatchStream:
|
||||
"""Class for detecting/injecting tags in a patch or series of patches
|
||||
|
||||
We support processing the output of 'git log' to read out the tags we
|
||||
are interested in. We can also process a patch file in order to remove
|
||||
unwanted tags or inject additional ones. These correspond to the two
|
||||
phases of processing.
|
||||
"""
|
||||
def __init__(self, series, name=None, is_log=False):
|
||||
self.skip_blank = False # True to skip a single blank line
|
||||
self.found_test = False # Found a TEST= line
|
||||
self.lines_after_test = 0 # MNumber of lines found after TEST=
|
||||
self.warn = [] # List of warnings we have collected
|
||||
self.linenum = 1 # Output line number we are up to
|
||||
self.in_section = None # Name of start...END section we are in
|
||||
self.notes = [] # Series notes
|
||||
self.section = [] # The current section...END section
|
||||
self.series = series # Info about the patch series
|
||||
self.is_log = is_log # True if indent like git log
|
||||
self.in_change = 0 # Non-zero if we are in a change list
|
||||
self.blank_count = 0 # Number of blank lines stored up
|
||||
self.state = STATE_MSG_HEADER # What state are we in?
|
||||
self.tags = [] # Tags collected, like Tested-by...
|
||||
self.signoff = [] # Contents of signoff line
|
||||
self.commit = None # Current commit
|
||||
|
||||
def AddToSeries(self, line, name, value):
|
||||
"""Add a new Series-xxx tag.
|
||||
|
||||
When a Series-xxx tag is detected, we come here to record it, if we
|
||||
are scanning a 'git log'.
|
||||
|
||||
Args:
|
||||
line: Source line containing tag (useful for debug/error messages)
|
||||
name: Tag name (part after 'Series-')
|
||||
value: Tag value (part after 'Series-xxx: ')
|
||||
"""
|
||||
if name == 'notes':
|
||||
self.in_section = name
|
||||
self.skip_blank = False
|
||||
if self.is_log:
|
||||
self.series.AddTag(self.commit, line, name, value)
|
||||
|
||||
def CloseCommit(self):
|
||||
"""Save the current commit into our commit list, and reset our state"""
|
||||
if self.commit and self.is_log:
|
||||
self.series.AddCommit(self.commit)
|
||||
self.commit = None
|
||||
|
||||
def FormatTags(self, tags):
|
||||
out_list = []
|
||||
for tag in sorted(tags):
|
||||
if tag.startswith('Cc:'):
|
||||
tag_list = tag[4:].split(',')
|
||||
out_list += gitutil.BuildEmailList(tag_list, 'Cc:')
|
||||
else:
|
||||
out_list.append(tag)
|
||||
return out_list
|
||||
|
||||
def ProcessLine(self, line):
|
||||
"""Process a single line of a patch file or commit log
|
||||
|
||||
This process a line and returns a list of lines to output. The list
|
||||
may be empty or may contain multiple output lines.
|
||||
|
||||
This is where all the complicated logic is located. The class's
|
||||
state is used to move between different states and detect things
|
||||
properly.
|
||||
|
||||
We can be in one of two modes:
|
||||
self.is_log == True: This is 'git log' mode, where most output is
|
||||
indented by 4 characters and we are scanning for tags
|
||||
|
||||
self.is_log == False: This is 'patch' mode, where we already have
|
||||
all the tags, and are processing patches to remove junk we
|
||||
don't want, and add things we think are required.
|
||||
|
||||
Args:
|
||||
line: text line to process
|
||||
|
||||
Returns:
|
||||
list of output lines, or [] if nothing should be output
|
||||
"""
|
||||
# Initially we have no output. Prepare the input line string
|
||||
out = []
|
||||
line = line.rstrip('\n')
|
||||
if self.is_log:
|
||||
if line[:4] == ' ':
|
||||
line = line[4:]
|
||||
|
||||
# Handle state transition and skipping blank lines
|
||||
series_match = re_series.match(line)
|
||||
commit_match = re_commit.match(line) if self.is_log else None
|
||||
tag_match = None
|
||||
if self.state == STATE_PATCH_HEADER:
|
||||
tag_match = re_tag.match(line)
|
||||
is_blank = not line.strip()
|
||||
if is_blank:
|
||||
if (self.state == STATE_MSG_HEADER
|
||||
or self.state == STATE_PATCH_SUBJECT):
|
||||
self.state += 1
|
||||
|
||||
# We don't have a subject in the text stream of patch files
|
||||
# It has its own line with a Subject: tag
|
||||
if not self.is_log and self.state == STATE_PATCH_SUBJECT:
|
||||
self.state += 1
|
||||
elif commit_match:
|
||||
self.state = STATE_MSG_HEADER
|
||||
|
||||
# If we are in a section, keep collecting lines until we see END
|
||||
if self.in_section:
|
||||
if line == 'END':
|
||||
if self.in_section == 'cover':
|
||||
self.series.cover = self.section
|
||||
elif self.in_section == 'notes':
|
||||
if self.is_log:
|
||||
self.series.notes += self.section
|
||||
else:
|
||||
self.warn.append("Unknown section '%s'" % self.in_section)
|
||||
self.in_section = None
|
||||
self.skip_blank = True
|
||||
self.section = []
|
||||
else:
|
||||
self.section.append(line)
|
||||
|
||||
# Detect the commit subject
|
||||
elif not is_blank and self.state == STATE_PATCH_SUBJECT:
|
||||
self.commit.subject = line
|
||||
|
||||
# Detect the tags we want to remove, and skip blank lines
|
||||
elif re_remove.match(line):
|
||||
self.skip_blank = True
|
||||
|
||||
# TEST= should be the last thing in the commit, so remove
|
||||
# everything after it
|
||||
if line.startswith('TEST='):
|
||||
self.found_test = True
|
||||
elif self.skip_blank and is_blank:
|
||||
self.skip_blank = False
|
||||
|
||||
# Detect the start of a cover letter section
|
||||
elif re_cover.match(line):
|
||||
self.in_section = 'cover'
|
||||
self.skip_blank = False
|
||||
|
||||
# If we are in a change list, key collected lines until a blank one
|
||||
elif self.in_change:
|
||||
if is_blank:
|
||||
# Blank line ends this change list
|
||||
self.in_change = 0
|
||||
else:
|
||||
self.series.AddChange(self.in_change, self.commit, line)
|
||||
self.skip_blank = False
|
||||
|
||||
# Detect Series-xxx tags
|
||||
elif series_match:
|
||||
name = series_match.group(1)
|
||||
value = series_match.group(2)
|
||||
if name == 'changes':
|
||||
# value is the version number: e.g. 1, or 2
|
||||
try:
|
||||
value = int(value)
|
||||
except ValueError as str:
|
||||
raise ValueError("%s: Cannot decode version info '%s'" %
|
||||
(self.commit.hash, line))
|
||||
self.in_change = int(value)
|
||||
else:
|
||||
self.AddToSeries(line, name, value)
|
||||
self.skip_blank = True
|
||||
|
||||
# Detect the start of a new commit
|
||||
elif commit_match:
|
||||
self.CloseCommit()
|
||||
self.commit = commit.Commit(commit_match.group(1)[:7])
|
||||
|
||||
# Detect tags in the commit message
|
||||
elif tag_match:
|
||||
# Onlly allow a single signoff tag
|
||||
if tag_match.group(1) == 'Signed-off-by':
|
||||
if self.signoff:
|
||||
self.warn.append('Patch has more than one Signed-off-by '
|
||||
'tag')
|
||||
self.signoff += [line]
|
||||
|
||||
# Remove Tested-by self, since few will take much notice
|
||||
elif (tag_match.group(1) == 'Tested-by' and
|
||||
tag_match.group(2).find(os.getenv('USER') + '@') != -1):
|
||||
self.warn.append("Ignoring %s" % line)
|
||||
elif tag_match.group(1) == 'Cc':
|
||||
self.commit.AddCc(tag_match.group(2).split(','))
|
||||
else:
|
||||
self.tags.append(line);
|
||||
|
||||
# Well that means this is an ordinary line
|
||||
else:
|
||||
pos = 1
|
||||
# Look for ugly ASCII characters
|
||||
for ch in line:
|
||||
# TODO: Would be nicer to report source filename and line
|
||||
if ord(ch) > 0x80:
|
||||
self.warn.append("Line %d/%d ('%s') has funny ascii char" %
|
||||
(self.linenum, pos, line))
|
||||
pos += 1
|
||||
|
||||
# Look for space before tab
|
||||
m = re_space_before_tab.match(line)
|
||||
if m:
|
||||
self.warn.append('Line %d/%d has space before tab' %
|
||||
(self.linenum, m.start()))
|
||||
|
||||
# OK, we have a valid non-blank line
|
||||
out = [line]
|
||||
self.linenum += 1
|
||||
self.skip_blank = False
|
||||
if self.state == STATE_DIFFS:
|
||||
pass
|
||||
|
||||
# If this is the start of the diffs section, emit our tags and
|
||||
# change log
|
||||
elif line == '---':
|
||||
self.state = STATE_DIFFS
|
||||
|
||||
# Output the tags (signeoff first), then change list
|
||||
out = []
|
||||
if self.signoff:
|
||||
out += self.signoff
|
||||
log = self.series.MakeChangeLog(self.commit)
|
||||
out += self.FormatTags(self.tags)
|
||||
out += [line] + log
|
||||
elif self.found_test:
|
||||
if not re_allowed_after_test.match(line):
|
||||
self.lines_after_test += 1
|
||||
|
||||
return out
|
||||
|
||||
def Finalize(self):
|
||||
"""Close out processing of this patch stream"""
|
||||
self.CloseCommit()
|
||||
if self.lines_after_test:
|
||||
self.warn.append('Found %d lines after TEST=' %
|
||||
self.lines_after_test)
|
||||
|
||||
def ProcessStream(self, infd, outfd):
|
||||
"""Copy a stream from infd to outfd, filtering out unwanting things.
|
||||
|
||||
This is used to process patch files one at a time.
|
||||
|
||||
Args:
|
||||
infd: Input stream file object
|
||||
outfd: Output stream file object
|
||||
"""
|
||||
# Extract the filename from each diff, for nice warnings
|
||||
fname = None
|
||||
last_fname = None
|
||||
re_fname = re.compile('diff --git a/(.*) b/.*')
|
||||
while True:
|
||||
line = infd.readline()
|
||||
if not line:
|
||||
break
|
||||
out = self.ProcessLine(line)
|
||||
|
||||
# Try to detect blank lines at EOF
|
||||
for line in out:
|
||||
match = re_fname.match(line)
|
||||
if match:
|
||||
last_fname = fname
|
||||
fname = match.group(1)
|
||||
if line == '+':
|
||||
self.blank_count += 1
|
||||
else:
|
||||
if self.blank_count and (line == '-- ' or match):
|
||||
self.warn.append("Found possible blank line(s) at "
|
||||
"end of file '%s'" % last_fname)
|
||||
outfd.write('+\n' * self.blank_count)
|
||||
outfd.write(line + '\n')
|
||||
self.blank_count = 0
|
||||
self.Finalize()
|
||||
|
||||
|
||||
def GetMetaData(start, count):
|
||||
"""Reads out patch series metadata from the commits
|
||||
|
||||
This does a 'git log' on the relevant commits and pulls out the tags we
|
||||
are interested in.
|
||||
|
||||
Args:
|
||||
start: Commit to start from: 0=HEAD, 1=next one, etc.
|
||||
count: Number of commits to list
|
||||
"""
|
||||
pipe = [['git', 'log', '--reverse', 'HEAD~%d' % start, '-n%d' % count]]
|
||||
stdout = command.RunPipe(pipe, capture=True)
|
||||
series = Series()
|
||||
ps = PatchStream(series, is_log=True)
|
||||
for line in stdout.splitlines():
|
||||
ps.ProcessLine(line)
|
||||
ps.Finalize()
|
||||
return series
|
||||
|
||||
def FixPatch(backup_dir, fname, series, commit):
|
||||
"""Fix up a patch file, by adding/removing as required.
|
||||
|
||||
We remove our tags from the patch file, insert changes lists, etc.
|
||||
The patch file is processed in place, and overwritten.
|
||||
|
||||
A backup file is put into backup_dir (if not None).
|
||||
|
||||
Args:
|
||||
fname: Filename to patch file to process
|
||||
series: Series information about this patch set
|
||||
commit: Commit object for this patch file
|
||||
Return:
|
||||
A list of errors, or [] if all ok.
|
||||
"""
|
||||
handle, tmpname = tempfile.mkstemp()
|
||||
outfd = os.fdopen(handle, 'w')
|
||||
infd = open(fname, 'r')
|
||||
ps = PatchStream(series)
|
||||
ps.commit = commit
|
||||
ps.ProcessStream(infd, outfd)
|
||||
infd.close()
|
||||
outfd.close()
|
||||
|
||||
# Create a backup file if required
|
||||
if backup_dir:
|
||||
shutil.copy(fname, os.path.join(backup_dir, os.path.basename(fname)))
|
||||
shutil.move(tmpname, fname)
|
||||
return ps.warn
|
||||
|
||||
def FixPatches(series, fnames):
|
||||
"""Fix up a list of patches identified by filenames
|
||||
|
||||
The patch files are processed in place, and overwritten.
|
||||
|
||||
Args:
|
||||
series: The series object
|
||||
fnames: List of patch files to process
|
||||
"""
|
||||
# Current workflow creates patches, so we shouldn't need a backup
|
||||
backup_dir = None #tempfile.mkdtemp('clean-patch')
|
||||
count = 0
|
||||
for fname in fnames:
|
||||
commit = series.commits[count]
|
||||
commit.patch = fname
|
||||
result = FixPatch(backup_dir, fname, series, commit)
|
||||
if result:
|
||||
print '%d warnings for %s:' % (len(result), fname)
|
||||
for warn in result:
|
||||
print '\t', warn
|
||||
print
|
||||
count += 1
|
||||
print 'Cleaned %d patches' % count
|
||||
return series
|
||||
|
||||
def InsertCoverLetter(fname, series, count):
|
||||
"""Inserts a cover letter with the required info into patch 0
|
||||
|
||||
Args:
|
||||
fname: Input / output filename of the cover letter file
|
||||
series: Series object
|
||||
count: Number of patches in the series
|
||||
"""
|
||||
fd = open(fname, 'r')
|
||||
lines = fd.readlines()
|
||||
fd.close()
|
||||
|
||||
fd = open(fname, 'w')
|
||||
text = series.cover
|
||||
prefix = series.GetPatchPrefix()
|
||||
for line in lines:
|
||||
if line.startswith('Subject:'):
|
||||
# TODO: if more than 10 patches this should save 00/xx, not 0/xx
|
||||
line = 'Subject: [%s 0/%d] %s\n' % (prefix, count, text[0])
|
||||
|
||||
# Insert our cover letter
|
||||
elif line.startswith('*** BLURB HERE ***'):
|
||||
# First the blurb test
|
||||
line = '\n'.join(text[1:]) + '\n'
|
||||
if series.get('notes'):
|
||||
line += '\n'.join(series.notes) + '\n'
|
||||
|
||||
# Now the change list
|
||||
out = series.MakeChangeLog(None)
|
||||
line += '\n' + '\n'.join(out)
|
||||
fd.write(line)
|
||||
fd.close()
|
||||
1
tools/patman/patman
Symbolic link
1
tools/patman/patman
Symbolic link
@@ -0,0 +1 @@
|
||||
patman.py
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user