Re: [U-Boot] [PATCH 01/10] lcd, amba: remove this frame buffer driver since it is not used
Hello. Since CONFIG_VIDEO_AMBA is not set by any board, it does not seem to be used, so remove it since there is no way to (compile) test it. I used the driver on the nhk8815. But actually it looks like the later patch in this set, that my commit message references, was not merged. I remember I used it in 32-bit mode and had to hack some things to make it work, inluding a fater memcopy as scrolling was very slow. I don't think I can resurrect my nhk8815 device any soon, and it looks like nobody else is using this logic cell, so I'm fine removing the driver. Acked-by: Alessandro Rubini rub...@unipv.it /alessandro ___ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot
Re: [U-Boot] http client?
Hm... but 20 minutes versus 30 seconds cannot be explained by TFTP versus HTTP alone. There must be other effects impacting your network traffic. Did you run any deeper analysis? I'm sure it depends on network delays. TCP has the sliding window mechanism, so several packets can be in flight before you get a single ack. TFTP requires one ack for each data packet, doesn't it? If you have high delays, TCP is usually a win, even with relatively low bandwidth. Otherwise, we need a an UDP protocol that doesn't require individual ack. /alessandro ___ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot
[U-Boot] [RFC] arm/board.c: avoid ifdef using weak default functions
From: Alessandro Rubini rub...@gnudd.com While it's a matter of personal taste, I prefer to avoid ifdef when possible. For example, I don't like to add BOARD_LATE_INIT in the config file just to have my board_late_init() function called. This patch (not meant to be applied mainstram, jsut for discussion) tries to simplify and make more readable the code in lib_arm/board.c. If this is considered useful it can be done more seriously to all platforms, and allow over time to remove defines in the class of BOARD_LATE_INIT. A serious reordering will definitely need more time, and this is just a quick hack to show the idea; some things are suboptimal like the arm_pci_init() thing which has to remain an ifdef and should be fixed in a different way (I think all init function should return int and print their own messages, to simplify this factoring out, but again it's a matter of personal taste). About the use of weak, I first converted .a to .o, but then found it works nonetheless, and led functions are already weak ones in this file. Is the idea worth pursuing? Or does it conflich with other work in progress? --- lib_arm/board.c | 62 ++ 1 files changed, 30 insertions(+), 32 deletions(-) diff --git a/lib_arm/board.c b/lib_arm/board.c index a44d308..50fe74b 100644 --- a/lib_arm/board.c +++ b/lib_arm/board.c @@ -61,10 +61,26 @@ DECLARE_GLOBAL_DATA_PTR; ulong monitor_flash_len; -#ifdef CONFIG_HAS_DATAFLASH -extern int AT91F_DataflashInit(void); -extern void dataflash_print_info(void); -#endif +/* Some functions may be there or not. Use a weak placeholder to avoid ifdef */ +int __normal_nop(void) { return 0; } +void __void_nop(void) {} + +/* parts of init_sequence that may not be present */ +int arch_cpu_init(void) __attribute__((weak, alias(__normal_nop))); +int interrupt_init(void) __attribute__((weak, alias(__normal_nop))); +int print_cpuinfo(void) __attribute__((weak, alias(__normal_nop))); +int checkboard(void) __attribute__((weak, alias(__normal_nop))); + +/* other functions that appear later and depend on config items */ +int AT91F_DataflashInit(void) __attribute__((weak, alias(__normal_nop))); +void dataflash_print_info(void) __attribute__((weak, alias(__void_nop))); +void serial_initialize(void) __attribute__((weak, alias(__void_nop))); +void onenand_init(void) __attribute__((weak, alias(__void_nop))); +int drv_vfd_init(void) __attribute__((weak, alias(__normal_nop))); +void api_init(void) __attribute__((weak, alias(__void_nop))); +int arch_misc_init(void) __attribute__((weak, alias(__normal_nop))); +int misc_init_r(void) __attribute__((weak, alias(__normal_nop))); +int board_late_init(void) __attribute__((weak, alias(__normal_nop))); #ifndef CONFIG_IDENT_STRING #define CONFIG_IDENT_STRING @@ -227,6 +243,11 @@ static int init_func_i2c (void) puts (ready\n); return (0); } +#else +static int init_func_i2c (void) +{ + return 0; +} #endif #if defined(CONFIG_CMD_PCI) || defined (CONFIG_PCI) @@ -236,6 +257,11 @@ static int arm_pci_init(void) pci_init(); return 0; } +#else +static int arm_pci_init(void) +{ + return 0; +} #endif /* CONFIG_CMD_PCI || CONFIG_PCI */ /* @@ -266,32 +292,20 @@ typedef int (init_fnc_t) (void); int print_cpuinfo (void); init_fnc_t *init_sequence[] = { -#if defined(CONFIG_ARCH_CPU_INIT) arch_cpu_init, /* basic arch cpu dependent setup */ -#endif board_init, /* basic board dependent setup */ -#if defined(CONFIG_USE_IRQ) interrupt_init, /* set up exceptions */ -#endif timer_init, /* initialize timer */ env_init, /* initialize environment */ init_baudrate, /* initialze baudrate settings */ serial_init,/* serial communications setup */ console_init_f, /* stage 1 init of console */ display_banner, /* say that we are here */ -#if defined(CONFIG_DISPLAY_CPUINFO) print_cpuinfo, /* display cpu info (and speed) */ -#endif -#if defined(CONFIG_DISPLAY_BOARDINFO) checkboard, /* display board info */ -#endif -#if defined(CONFIG_HARD_I2C) || defined(CONFIG_SOFT_I2C) init_func_i2c, -#endif dram_init, /* configure available RAM banks */ -#if defined(CONFIG_CMD_PCI) || defined (CONFIG_PCI) arm_pci_init, -#endif display_dram_config, NULL, }; @@ -365,26 +379,18 @@ void start_armboot (void) nand_init();/* go init the NAND */ #endif -#if defined(CONFIG_CMD_ONENAND) onenand_init(); -#endif -#ifdef CONFIG_HAS_DATAFLASH AT91F_DataflashInit(); dataflash_print_info(); -#endif /* initialize environment */ env_relocate (); -#ifdef CONFIG_VFD /* must do this after the framebuffer is allocated */ drv_vfd_init(); -#endif /* CONFIG_VFD */ -#ifdef
Re: [U-Boot] http client?
When I looked at the RFC data it appears that the overhead of IP fragmentation and reassembly (which does add overhead as the number of gateways increases) may be worth the time... Just tried it: U-Boot doesn't support reassembly, it seems. net.c confirms it: /* Can't deal with fragments */ if (ip-ip_off htons(IP_OFFS | IP_FLAGS_MFRAG)) { return; } I don't think it's worth adding. /alessandro ___ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot
[U-Boot] [PATCH/RFC] net: defragment IP packets
This patch add a quick and dirty defrag step in IP reception. This allows to increase the TFTP block size and get more performance in slow links (but at that point it should be made configurable). The overhead is negligible, verified with an ARM9 CPU and 10MB data file, changing the server MTU from 1500 to 800 and then 550. However, on a LAN connection, I didn't see advantes with using a 4k block size with default MTU. Signed-off-by: Alessandro Rubini rub...@gnudd.com --- This patch is over mainline, without the (much appreciated) cleanup patch that reached the list these days. net/net.c | 46 ++ 1 files changed, 42 insertions(+), 4 deletions(-) diff --git a/net/net.c b/net/net.c index 641c37c..5034a2e 100644 --- a/net/net.c +++ b/net/net.c @@ -1117,6 +1117,46 @@ static void CDPStart(void) } #endif +/* This only reassembles fragments that come in proper order */ +static inline IP_t *NetDefragment(IP_t *ip, int *lenp) +{ + static uchar pkt_buff[16384]; /*temporary arbitrary limit */ + static int next_fragment; + static ushort pkt_id; + + #define IPSZ 20 + uchar *pkt = (uchar *)ip; + ushort ip_off; + int offset, len = *lenp -2; + + ip_off = ntohs(ip-ip_off); + if (!(ip_off (IP_OFFS | IP_FLAGS_MFRAG))) + return ip; + + offset = (ip_off IP_OFFS) * 8; + if (!offset) { /* new packet begins, discard any we might have */ + pkt_id = ip-ip_id; + memcpy(pkt_buff, ip, len); + next_fragment = len; + return NULL; + } + + /* further fragment: discard IP header */ + offset += IPSZ; len -= IPSZ; pkt += IPSZ; + + if (ip-ip_id != pkt_id || offset != next_fragment) + return NULL; /* out of order */ + + /* further fragment: skip ip header (we miss offset_of...) */ + memcpy(pkt_buff + next_fragment, pkt, len); + next_fragment += len; + + if (ip_off IP_FLAGS_MFRAG) + return NULL; /* more expected */ + + *lenp = next_fragment; + return (IP_t *)pkt_buff; +} void NetReceive(volatile uchar * inpkt, int len) @@ -1360,6 +1400,8 @@ NetReceive(volatile uchar * inpkt, int len) break; case PROT_IP: + if (!(ip = NetDefragment(ip, len))) + return; #ifdef ET_DEBUG puts (Got IP\n); #endif @@ -1378,10 +1420,6 @@ NetReceive(volatile uchar * inpkt, int len) if ((ip-ip_hl_v 0xf0) != 0x40) { return; } - /* Can't deal with fragments */ - if (ip-ip_off htons(IP_OFFS | IP_FLAGS_MFRAG)) { - return; - } /* can't deal with headers 20 bytes */ if ((ip-ip_hl_v 0x0f) 0x05) { return; -- 1.6.0.2 ___ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot
Re: [U-Boot] http client?
Me: Just tried it: U-Boot doesn't support reassembly, it seems. Robin Getz: I don't think anyone said it did. I'm sorry, I misread that in your message. Me: I don't think it's worth adding. Robin: This is based on ... ? laziness, mainly. And personal preference over simpler code where possible. But you are right, no real reason. So I've done it trivially (see patch posted today). On my LAN it doesn't make any noticeable difference: only I have more lost packets if I increase the block size too much, so it gets worse. I would like to know if it helps Jeffery Palmer. BTW: you (Jeffery) told you tried a blocksize of 16k, but how could it work if u-boot refuses fragments? Did you add defragmenting to the code first? /alessandro ___ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot
[U-Boot] [PATCH v2 1/2] arm nomadik: add gpio support
From: Alessandro Rubini rub...@unipv.it Signed-off-by: Alessandro Rubini rub...@unipv.it Acked-by: Andrea Gallo andrea.ga...@stericsson.com --- cpu/arm926ejs/nomadik/Makefile |2 +- cpu/arm926ejs/nomadik/gpio.c| 99 +++ include/asm-arm/arch-nomadik/gpio.h | 42 +++ 3 files changed, 142 insertions(+), 1 deletions(-) create mode 100644 cpu/arm926ejs/nomadik/gpio.c create mode 100644 include/asm-arm/arch-nomadik/gpio.h diff --git a/cpu/arm926ejs/nomadik/Makefile b/cpu/arm926ejs/nomadik/Makefile index e3bd2ee..0fc9f2a 100644 --- a/cpu/arm926ejs/nomadik/Makefile +++ b/cpu/arm926ejs/nomadik/Makefile @@ -25,7 +25,7 @@ include $(TOPDIR)/config.mk LIB= $(obj)lib$(SOC).a -COBJS = timer.o +COBJS = timer.o gpio.o SOBJS = reset.o SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) diff --git a/cpu/arm926ejs/nomadik/gpio.c b/cpu/arm926ejs/nomadik/gpio.c new file mode 100644 index 000..62a375b --- /dev/null +++ b/cpu/arm926ejs/nomadik/gpio.c @@ -0,0 +1,99 @@ +/* + * (C) Copyright 2009 Alessandro Rubini + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include common.h +#include asm/io.h +#include asm/arch/gpio.h + +static unsigned long gpio_base[4] = { + NOMADIK_GPIO0_BASE, + NOMADIK_GPIO1_BASE, + NOMADIK_GPIO2_BASE, + NOMADIK_GPIO3_BASE +}; + +enum gpio_registers { + GPIO_DAT = 0x00, /* data register */ + GPIO_DATS = 0x04, /* data set */ + GPIO_DATC = 0x08, /* data clear */ + GPIO_PDIS = 0x0c, /* pull disable */ + GPIO_DIR = 0x10, /* direction */ + GPIO_DIRS = 0x14, /* direction set */ + GPIO_DIRC = 0x18, /* direction clear */ + GPIO_AFSLA =0x20, /* alternate function select A */ + GPIO_AFSLB =0x24, /* alternate function select B */ +}; + +static inline unsigned long gpio_to_base(int gpio) +{ + return gpio_base[gpio / 32]; +} + +static inline u32 gpio_to_bit(int gpio) +{ + return 1 (gpio 0x1f); +} + +void nmk_gpio_af(int gpio, int alternate_function) +{ + unsigned long base = gpio_to_base(gpio); + u32 bit = gpio_to_bit(gpio); + u32 afunc, bfunc; + + /* alternate function is 0..3, with one bit per register */ + afunc = readl(base + GPIO_AFSLA) ~bit; + bfunc = readl(base + GPIO_AFSLB) ~bit; + if (alternate_function 1) afunc |= bit; + if (alternate_function 2) bfunc |= bit; + writel(afunc, base + GPIO_AFSLA); + writel(bfunc, base + GPIO_AFSLB); +} + +void nmk_gpio_dir(int gpio, int dir) +{ + unsigned long base = gpio_to_base(gpio); + u32 bit = gpio_to_bit(gpio); + + if (dir) + writel(bit, base + GPIO_DIRS); + else + writel(bit, base + GPIO_DIRC); +} + +void nmk_gpio_set(int gpio, int val) +{ + unsigned long base = gpio_to_base(gpio); + u32 bit = gpio_to_bit(gpio); + + if (val) + writel(bit, base + GPIO_DATS); + else + writel(bit, base + GPIO_DATC); +} + +int nmk_gpio_get(int gpio) +{ + unsigned long base = gpio_to_base(gpio); + u32 bit = gpio_to_bit(gpio); + + return readl(base + GPIO_DAT) bit; +} diff --git a/include/asm-arm/arch-nomadik/gpio.h b/include/asm-arm/arch-nomadik/gpio.h new file mode 100644 index 000..1d3c9ce --- /dev/null +++ b/include/asm-arm/arch-nomadik/gpio.h @@ -0,0 +1,42 @@ +/* + * (C) Copyright 2009 Alessandro Rubini + * + * 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
[U-Boot] [PATCH v2 2/2] arm nomadik: add i2c
From: Alessandro Rubini rub...@unipv.it Signed-off-by: Alessandro Rubini rub...@unipv.it Acked-by: Andrea Gallo andrea.ga...@stericsson.com --- board/st/nhk8815/nhk8815.c | 16 ++-- include/configs/nhk8815.h | 18 +- 2 files changed, 31 insertions(+), 3 deletions(-) diff --git a/board/st/nhk8815/nhk8815.c b/board/st/nhk8815/nhk8815.c index 085a5e0..1fa506a 100644 --- a/board/st/nhk8815/nhk8815.c +++ b/board/st/nhk8815/nhk8815.c @@ -27,6 +27,7 @@ #include common.h #include asm/io.h +#include asm/arch/gpio.h DECLARE_GLOBAL_DATA_PTR; @@ -61,9 +62,20 @@ int board_init(void) return 0; } -int misc_init_r(void) +int board_late_init(void) { - setenv(verify, n); + /* Set the two I2C gpio lines to be gpio high */ + nmk_gpio_set(__SCL, 1); nmk_gpio_set(__SDA, 1); + nmk_gpio_dir(__SCL, 1); nmk_gpio_dir(__SDA, 1); + nmk_gpio_af(__SCL, GPIO_GPIO); nmk_gpio_af(__SDA, GPIO_GPIO); + + /* Reset the I2C port expander, on GPIO77 */ + nmk_gpio_af(77, GPIO_GPIO); + nmk_gpio_dir(77, 1); + nmk_gpio_set(77, 0); + udelay(10); + nmk_gpio_set(77, 1); + return 0; } diff --git a/include/configs/nhk8815.h b/include/configs/nhk8815.h index 3e2e09f..8a83d92 100644 --- a/include/configs/nhk8815.h +++ b/include/configs/nhk8815.h @@ -93,7 +93,7 @@ #define CONFIG_SYS_GBL_DATA_SIZE 128 /* for initial data */ #define CONFIG_SYS_64BIT_VSPRINTF /* mtd desires this */ -#define CONFIG_MISC_INIT_R /* call misc_init_r during start up */ +#define BOARD_LATE_INIT/* call board_late_init during start up */ /* timing informazion */ #define CONFIG_SYS_HZ 1000 /* Mandatory... */ @@ -110,6 +110,22 @@ #define CONFIG_PL01x_PORTS { (void *)CFG_SERIAL0, (void *)CFG_SERIAL1 } #define CONFIG_PL011_CLOCK 4800 +/* i2c, for the port extenders (uses gpio.c in board directory) */ +#ifndef __ASSEMBLY__ +#include asm/arch/gpio.h +#define CONFIG_CMD_I2C +#define CONFIG_SOFT_I2C +#define CONFIG_SYS_I2C_SPEED 40 +#define __SDA 63 +#define __SCL 62 +#define I2C_SDA(x) nmk_gpio_set(__SDA, x) +#define I2C_SCL(x) nmk_gpio_set(__SCL, x) +#define I2C_READ (nmk_gpio_get(__SDA)!=0) +#define I2C_ACTIVE nmk_gpio_dir(__SDA, 1) +#define I2C_TRISTATE nmk_gpio_dir(__SDA, 0) +#define I2C_DELAY (udelay(2)) +#endif /* __ASSEMBLY__ */ + /* Ethernet */ #define PCI_MEMORY_VADDR 0xe800 #define PCI_IO_VADDR 0xee00 -- 1.6.0.2 ___ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot
Re: [U-Boot] [PATCH/RFC] net: defragment IP packets
http://www.faqs.org/rfcs/rfc815.html Yeah, I had seen this - but didn't want to duplicate something that Alessandro might already working on... Alessandro - were you going to add out of order packets? If the code has chances to go mainline, I'll be happy to complete this task. So unless I get a nak earlier, I'm going to find a time slot in the next few days (with your fixes, I suppose, or should they remain separate patches?) To make your host send out of order/delayed packets, which should be more real world/long haul try something like: # modprobe sch_netem (if it's not compiled into your kernel) # tc qdisc change dev eth0 root netem reorder 50% delay 10ms Thanks a lot, I was missing that. /alessandro ___ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot
Re: [U-Boot] [PATCH/RFC] net: defragment IP packets
Thanks for your comments. Should have a CONFIG_ something - to make this conditional. This has been asked by Ben too. Will do, although I'm not very happy about all those conditionals for every few lines of code. Some of your remarks are just symptoms of this being a quick hack, like the memcpy not checked, the missed getenv and so on. and I was doing md5 or sha1 on things to make sure that things came over properly... Yes, me too. Besides booting the stuff I got. /alessandro ___ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot
Re: [U-Boot] [PATCH v3] zlib: updated to v.1.2.3
Please, is there somebody that can test this patch on a differen arch than PPC? Arm: success. tornado% git log --pretty=oneline | head -1 b201171f2b4d509f3ad510b214bee70ff902e3d6 zlib: updated to v.1.2.3 U-Boot 2009.06-00494-gb201171 (Jul 27 2009 - 17:05:15) [...] ## Booting kernel from Legacy Image at 01308000 ... Image Name: Linux-2.6.31-rc3 Image Type: ARM Linux Kernel Image (gzip compressed) Data Size:1706717 Bytes = 1.6 MB Load Address: 8000 Entry Point: 8000 Uncompressing Kernel Image ... OK /alessandro ___ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot
[U-Boot] [PATCH] zlib: allow 0 as destination pointer
The entry point of an image can be 0 (like on PowerPC), so allow next_out to be NULL in inflate() Signed-off-by: Alessandro Rubini rub...@unipv.it --- Stefan Roese: I'll try to uncompress to something != 0 tomorrow on PPC. You are right. I naively thought my arm has RAM at 0 like PPC, but entry point of image is not really 0. lib_generic/zlib.c |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/lib_generic/zlib.c b/lib_generic/zlib.c index f415f6b..49fb145 100644 --- a/lib_generic/zlib.c +++ b/lib_generic/zlib.c @@ -1365,7 +1365,7 @@ int flush; static const unsigned short order[19] = /* permutation of code lengths */ {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; -if (strm == Z_NULL || strm-state == Z_NULL || strm-next_out == Z_NULL || +if (strm == Z_NULL || strm-state == Z_NULL || (strm-next_in == Z_NULL strm-avail_in != 0)) return Z_STREAM_ERROR; -- 1.5.6.5 ___ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot
Re: [U-Boot] [PATCH] zlib: allow 0 as destination pointer
Hi rhabarber1848, please could you test latest two zlib patches I have sent few minutes ago? Unfortunately you add outcb() only in inflatestart and inflateend. IT should also go in the main loop. Being an out-callback with arguments, it should be called during copy to output, with proper arguments (and in that form it would be a fix to the official zlib). I tried this one, which is a quick hack (no arguments passed, so not suitable for upstream zlib in any case). Moreover, one of those two should be sufficient, but I don't know which one exactly. I'm lazy so I won't trace program flow in detail. I think rhabarber should test with this addition too and select which one is the good one. (formatted for git-am for quick testing, even thought he talk is irrelevant as a commit message). ps: please note that your addition of outcb() has white-space inconsistency with zlib.c (which is not u-boot style while those lines are). /alessandro --- lib_generic/zlib.c |6 ++ 1 files changed, 6 insertions(+), 0 deletions(-) diff --git a/lib_generic/zlib.c b/lib_generic/zlib.c index 6a78dc9..66b18eb 100644 --- a/lib_generic/zlib.c +++ b/lib_generic/zlib.c @@ -1129,6 +1129,10 @@ unsigned out; state = (struct inflate_state FAR *)strm-state; +/* call watchdog_reset if needed (addition for U-Boot) */ +if (strm-outcb != Z_NULL) +(*strm-outcb)(Z_NULL, 0); + /* if it hasn't been done already, allocate space for the window */ if (state-window == Z_NULL) { state-window = (unsigned char FAR *) @@ -1741,6 +1745,8 @@ int flush; Tracev((stderr, inflate: codes ok\n)); state-mode = LEN; case LEN: +if (strm-outcb != Z_NULL) /* for watchdog (U-Boot) */ +(*strm-outcb)(Z_NULL, 0); if (have = 6 left = 258) { RESTORE(); inflate_fast(strm, out); -- 1.6.0.2 ___ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot
[U-Boot] [PATCH 0/3] Defragment IP packets
This patch-set implements the defragment code. PAtch 3 is just for me, to enable it. It may also be a good thing to have, so people can look for actual users and find one. If needed, I'll add another patch for documentation. I've done as RFC815 says although an unlikely insane fragment is not handled (see code and patch comment). Robin's suggestions have been include by two: - ports are not checked (tftp code doesn't check either), only ID - the ckeck is done in an inline function, not in the main function: I agree call/ret is worse than if, but there is no call here. (I split the function in two to make it clear, but it's most likely not even needed). Ben asked: 1. Configurable block size (via a well-named CONFIG). Choose a good default value. Done. The default is as before, as our polling ether may discard pacjets if the burst is too fast. Mine receives only 4-5 fragments, so 8192 is not viable for me (4k works quite good). I suspect some may just cache 1 packet, so even two fragments won't work for them, thus the unchanged default. 2. Handle out-of-order fragments, and some test results showing that it works. This the end of a transfer with 4096 block size: frag 1480 - 1480 frag 0 - 1480 frag 2960 - 1148 done, len 4108 frag 2960 - 1148 frag 0 - 1480 frag 1480 - 1480 done, len 4108 frag 1480 - 1480 frag 0 - 1480 frag 2960 - 1148 done, len 4108 frag 0 - 1480 frag 1480 - 664 done, len 2144 The image, written over zeroed memory, crc'd and booted correctly. Then I removed the prints. 3. Make the feature configurable CONFIG_IP_DEFRAG 4. Test with a TFTP server that doesn't have blksize feature enabled Done. Actually, my code is not called in this case. /alessandro Alessandro Rubini (3): net: defragment IP packets tftp: get the tftp block size from config file and from the environment arm nomadik: select defrag and 4k tftp block size include/configs/nhk8815.h |3 + net/net.c | 172 +++-- net/tftp.c| 13 +++- 3 files changed, 181 insertions(+), 7 deletions(-) ___ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot
[U-Boot] [PATCH 1/3] net: defragment IP packets
The defragmenting code is enabled by CONFIG_IP_DEFRAG. The code is useful for TFTP transfers, so the static reassembly buffer is sized based on CONFIG_TFTP_MAXBLOCK (default is 16kB). The packet buffer is used as an array of hole structures, acting as a double-linked list. Each new fragment can split a hole in two, reduce a hole or fill a hole. No support is there for a fragment overlapping two diffrent holes (i.e., thre new fragment is across an already-received fragment). The code includes a number of suggestions by Robin Getz. Signed-off-by: Alessandro Rubini rub...@gnudd.com --- net/net.c | 172 +++-- 1 files changed, 167 insertions(+), 5 deletions(-) diff --git a/net/net.c b/net/net.c index 641c37c..be382dd 100644 --- a/net/net.c +++ b/net/net.c @@ -1117,6 +1117,164 @@ static void CDPStart(void) } #endif +#ifdef CONFIG_IP_DEFRAG +/* + * This function collects fragments in a single packet, according + * to the algorithm in RFC815. It returns NULL or the pointer to + * a complete packet, in static storage + */ +#ifndef CONFIG_TFTP_MAXBLOCK +#define CONFIG_TFTP_MAXBLOCK 16384 +#endif +#define IP_PAYLOAD (CONFIG_TFTP_MAXBLOCK + 4) +#define IP_PKTSIZE (IP_PAYLOAD + IP_HDR_SIZE_NO_UDP) + +/* + * this is the packet being assembled, either data or frag control. + * Fragments go by 8 bytes, so this union must be 8 bytes long + */ +struct hole { + /* first_byte is address of this structure */ + u16 last_byte; /* last byte in this hole + 1 (begin of next hole) */ + u16 next_hole; /* index of next (in 8-b blocks), 0 == none */ + u16 prev_hole; /* index of prev, 0 == none */ + u16 unused; +}; + +static IP_t *__NetDefragment(IP_t *ip, int *lenp) +{ + static uchar pkt_buff[IP_PKTSIZE] __attribute__((aligned(PKTALIGN))); + static u16 first_hole, total_len; + struct hole *payload, *thisfrag, *h, *newh; + IP_t *localip = (IP_t *)pkt_buff; + uchar *indata = (uchar *)ip; + int offset8, start, len, done = 0; + u16 ip_off = ntohs(ip-ip_off); + + /* payload starts after IP header, this fragment is in there */ + payload = (struct hole *)(pkt_buff + IP_HDR_SIZE_NO_UDP); + offset8 = (ip_off IP_OFFS); + thisfrag = payload + offset8; + start = offset8 * 8; + len = ntohs(ip-ip_len) - IP_HDR_SIZE_NO_UDP; + + if (start + len IP_PAYLOAD) /* fragment extends too far */ + return NULL; + + if (!total_len || localip-ip_id != ip-ip_id) { + /* new (or different) packet, reset structs */ + total_len = 0x; + payload[0].last_byte = ~0; + payload[0].next_hole = 0; + payload[0].prev_hole = 0; + first_hole = 0; + /* any IP header will work, copy the first we received */ + memcpy(localip, ip, IP_HDR_SIZE_NO_UDP); + } + + /* +* What follows is the reassembly algorithm. We use the payload +* array as a linked list of hole descriptors, as each hole starts +* at a multiple of 8 bytes. However, last byte can be whatever value, +* so it is represented as byte count, not as 8-byte blocks. +*/ + + h = payload + first_hole; + while (h-last_byte start) { + if (!h-next_hole) { + /* no hole that far away */ + return NULL; + } + h = payload + h-next_hole; + } + + if (offset8 + (len / 8) = h - payload) { + /* no overlap with holes (dup fragment?) */ + return NULL; + } + + if (!(ip_off IP_FLAGS_MFRAG)) { + /* no more fragmentss: truncate this (last) hole */ + total_len = start + len; + h-last_byte = start + len; + } + + /* +* There is some overlap: fix the hole list. This code doesn't +* deal with a fragment that overlaps with two different holes +* (thus being a superset of a previously-received fragment). +*/ + + if ( (h = thisfrag) (h-last_byte = start + len) ) { + /* complete overlap with hole: remove hole */ + if (!h-prev_hole !h-next_hole) { + /* last remaining hole */ + done = 1; + } else if (!h-prev_hole) { + /* first hole */ + first_hole = h-next_hole; + payload[h-next_hole].prev_hole = 0; + } else if (!h-next_hole) { + /* last hole */ + payload[h-prev_hole].next_hole = 0; + } else { + /* in the middle of the list */ + payload[h-next_hole].prev_hole = h-prev_hole; + payload[h-prev_hole].next_hole = h-next_hole; + } + + } else if (h
[U-Boot] [PATCH 2/3] tftp: get the tftp block size from config file and from the environment
Raising the block size is useful if CONFIG_IP_DEFRAG is used. Howerver, the last fragments in a burst may overflow the receiving ethernet, so the default is left at 1468, with thre new CONFIG_TFTP_BLOCKSIZE for config files. Further, tftpblocksize can be set in the environment. Signed-off-by: Alessandro Rubini rub...@gnudd.com --- net/tftp.c | 13 +++-- 1 files changed, 11 insertions(+), 2 deletions(-) diff --git a/net/tftp.c b/net/tftp.c index b0f1cca..b315d5a 100644 --- a/net/tftp.c +++ b/net/tftp.c @@ -86,8 +86,14 @@ extern flash_info_t flash_info[]; /* 512 is poor choice for ethernet, MTU is typically 1500. * Minus eth.hdrs thats 1468. Can get 2x better throughput with * almost-MTU block sizes. At least try... fall back to 512 if need be. + * (but those using CONFIG_IP_DEFRAG may want to set a larger block in cfg file) */ +#ifdef CONFIG_TFTP_BLOCKSIZE +#define TFTP_MTU_BLOCKSIZE CONFIG_TFTP_BLKSIZE +#else #define TFTP_MTU_BLOCKSIZE 1468 +#endif + static unsigned short TftpBlkSize=TFTP_BLOCK_SIZE; static unsigned short TftpBlkSizeOption=TFTP_MTU_BLOCKSIZE; @@ -475,9 +481,12 @@ TftpTimeout (void) void TftpStart (void) { -#ifdef CONFIG_TFTP_PORT char *ep; /* Environment pointer */ -#endif + + /* Allow the user to choose tftpblocksize */ + if ((ep = getenv(tftpblocksize)) != NULL) + TftpBlkSizeOption = simple_strtol(ep, NULL, 10); + debug(tftp block size is %i\n, TftpBlkSizeOption); TftpServerIP = NetServerIP; if (BootFile[0] == '\0') { -- 1.6.0.2 ___ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot
[U-Boot] [PATCH 3/3] arm nomadik: select defrag and 4k tftp block size
Signed-off-by: Alessandro Rubini rub...@gnudd.com --- include/configs/nhk8815.h |3 +++ 1 files changed, 3 insertions(+), 0 deletions(-) diff --git a/include/configs/nhk8815.h b/include/configs/nhk8815.h index bfa91a2..fd6d7d1 100644 --- a/include/configs/nhk8815.h +++ b/include/configs/nhk8815.h @@ -147,6 +147,9 @@ #define CONFIG_SMC_USE_32_BIT #define CONFIG_BOOTFILEuImage +#define CONFIG_IP_DEFRAG +#define CONFIG_TFTP_BLOCKSIZE 4096 /* for faster download */ + /* Storage information: onenand and nand */ #define CONFIG_CMD_ONENAND #define CONFIG_MTD_ONENAND_VERIFY_WRITE -- 1.6.0.2 ___ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot
[U-Boot] [PATCH 2/3 V2] tftp: get tftpblocksize from cfg file and env
Raising the block size is useful if CONFIG_IP_DEFRAG is used. Howerver, the last fragments in a burst may overflow the receiving ethernet, so the default is left at 1468, with thre new CONFIG_TFTP_BLOCKSIZE for config files. Further, tftpblocksize can be set in the environment. Signed-off-by: Alessandro Rubini rub...@gnudd.com --- V2: fixed a damned typo in CONFIG_ names Also, I shortened the first line. Sorry for this bad V1. net/tftp.c | 13 +++-- 1 files changed, 11 insertions(+), 2 deletions(-) diff --git a/net/tftp.c b/net/tftp.c index b0f1cca..34b79c4 100644 --- a/net/tftp.c +++ b/net/tftp.c @@ -86,8 +86,14 @@ extern flash_info_t flash_info[]; /* 512 is poor choice for ethernet, MTU is typically 1500. * Minus eth.hdrs thats 1468. Can get 2x better throughput with * almost-MTU block sizes. At least try... fall back to 512 if need be. + * (but those using CONFIG_IP_DEFRAG may want to set a larger block in cfg file) */ +#ifdef CONFIG_TFTP_BLOCKSIZE +#define TFTP_MTU_BLOCKSIZE CONFIG_TFTP_BLOCKSIZE +#else #define TFTP_MTU_BLOCKSIZE 1468 +#endif + static unsigned short TftpBlkSize=TFTP_BLOCK_SIZE; static unsigned short TftpBlkSizeOption=TFTP_MTU_BLOCKSIZE; @@ -475,9 +481,12 @@ TftpTimeout (void) void TftpStart (void) { -#ifdef CONFIG_TFTP_PORT char *ep; /* Environment pointer */ -#endif + + /* Allow the user to choose tftpblocksize */ + if ((ep = getenv(tftpblocksize)) != NULL) + TftpBlkSizeOption = simple_strtol(ep, NULL, 10); + debug(tftp block size is %i\n, TftpBlkSizeOption); TftpServerIP = NetServerIP; if (BootFile[0] == '\0') { -- 1.6.0.2 ___ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot
Re: [U-Boot] [PATCH 1/3] net: defragment IP packets
Thanks for your comments. +#ifndef CONFIG_TFTP_MAXBLOCK +#define CONFIG_TFTP_MAXBLOCK 16384 It is more than tftp - nfs could also use the same. Yes, I know. But most users are tftp ones. And if you want an even number (like 16k) as a tftp packet you need to add the headers and the sequence count. And I prefer to have the useful number in the config. So I used TFTP in the name in order for NFS users to know they must make some calculation. How about CONFIG_NET_MAXDEFRAG instead? We could have MAXPAYLOAD if we count in NFS overhead as well (I don't know how much it is, currently. Hope you see my point. +static IP_t *__NetDefragment(IP_t *ip, int *lenp) +{ I don't understand the purpose of the lenp. The calling function doesn't use the len var, except for ICMP_ECHO_REQUEST, which are not allowed to be fragmented. I eliminated it - and suffered no side effects. Well, since the caller has this len variable, I didn't want to leave it corrupted. But if it's actually unused after this point, we can well discard it. +if (!total_len || localip-ip_id != ip-ip_id) { +/* new (or different) packet, reset structs */ +total_len = 0x; +payload[0].last_byte = ~0; +payload[0].next_hole = 0; +payload[0].prev_hole = 0; +first_hole = 0; +/* any IP header will work, copy the first we received */ +memcpy(localip, ip, IP_HDR_SIZE_NO_UDP); +} I'm not sure the reset if we loose a packet, or get a bad one - start over is a great idea. Well, either we keep more than one in-reassembly packet (and storage begins to be a problem here) or not. I prefer not. For some reason - why I'm ping flooding when tftping a large file (with large tftp block size) - things hang. If I set the block size to under the MTU - it works fine. Do you get the same? Didn't try, and I can't do that today. I suspect either your ping is over-mtu, so each new fragment triggers the above code, or simply your ether+uboot can't keep up with the data rate. As eaplained in the cover letter cover.1248943812.git.rub...@unipv.it some fragments can be lost in high traffic, as polling mode doesn't allow to enqueue packets. So I think you just loose some fragments, as target CPU time is eaten by the ping packets, and you don't get the complete reassembled packet any more. I'm pretty sure it's like this. On the other hand, I found a minor issue in this situation: - start a tftp transfer - ctrl-C it - start another Server retransmissions for the first transfer go into the defrag engine e that reset-defrag-data code is triggered, so a packet may be lost, and I get a sporadic T in the receiving u-boot. I think it's not a real problem, though --- or, now that I rethink about it, it can be the same issue as above: my ether can't enqueue 8k of stuff so a fragment is lost in that case. +#else /* !CONFIG_IP_DEFRAG */ + +static inline IP_t *NetDefragment(IP_t *ip, int *lenp) +{ +return ip; +} +#endif This needs to have the same logic (ip_off (IP_OFFS | IP_FLAGS_MFRAG)) as the above function. See comment below. Yes, correct. Thanks. /alessandro ___ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot
Re: [U-Boot] [PATCH 1/3] net: defragment IP packets
or simply your ether+uboot can't keep up with the data rate. That doesn't explain, why does it work, when there is no fragmentation??? Well, with no fragmentation there is less traffic. Each tftp packet is one patch, instead of a burst of packets (intermixed with pings). Is the target replying to all pings? Or is it loosing some? If it looses say 30%, I expect one fragment in 3 to be lost as well. If your big-tftp is 4 fragments, 20% passes it loss is equally spread ((2/3)^4), but I fear much less as the burst saturates the incoming queue. I'm pretty sure it's like this. I'm not convinced yet - but need to do some further poking on a different network... Thanks for these tests, mine is just guessing. What is missing in the reassembly code (that is described in RFC815) is the timer. (quote from the RFC): -- The final part of the algorithm is some sort of timer based mechanism which decrements the time to live field of each partially reassembled datagram, so that incomplete datagrams which have outlived their usefulness can be detected and deleted. -- But I reassemble one packet only, so I don't need to timeout partly-filled packets to recover memory. A soon as I have a fragment for a new packet, the old packet is discarded (while unfragmented stuff flies intermixed). /alessandro ___ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot
Re: [U-Boot] [PATCH 1/3] net: defragment IP packets
Is the target replying to all pings? Yes. And I can see the same in wireshark. Ah. I see. Strange... What is missing in the reassembly code (that is described in RFC815) is the timer. (quote from the RFC): -- The final part of the algorithm is some sort of timer based mechanism which decrements the time to live field of each partially reassembled datagram, so that incomplete datagrams which have outlived their usefulness can be detected and deleted. -- But I reassemble one packet only, so I don't need to timeout partly-filled packets to recover memory. But it is for the state that you described - the user cntr-C a current transfer, and the reassembly algorithm doesn't know to throw away a partially accepted packet, when things are cancelled... No, it's not like that. The old instance of the TFTP server resends the last packet of the aborted xfer, while the new server sends the new packet. Both packets are new, they just come as intermixed fragments. And none survives as there is only one reassembly buffer. Or something like that, but both are fresh fragmented packets, no timeout would solve this sporadic problem. It seems to me that if we want a secure defagment system (one that can be use to net-boot production systems in hostile networks), it's going to be too complex. It could work well, however, as a faster tool for the interactive developer. /alessandro ___ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot
Re: [U-Boot] [PATCH 1/3] net: defragment IP packets
What I'm talking about is: - start a tftp file transfer. - CNTR-C it, causing a partial reassembly to done. - start a new transfer. Yes, exactly the case I observed. But you are not guaranteed a partial reassembly happens, as you should be ctrl-c-ing at the exact right time. All I did was add this to the start of NetLoop() to ensure that things are OK. #ifdef CONFIG_IP_DEFRAG memset(pkt_buff, 0, IP_HDR_SIZE_NO_UDP); #endif And the behaviour changed? It's strange, as the new fragments will most likely (but 1/64k) have a different ID. The old instance of the TFTP server resends the last packet of the aborted xfer, It sounded strange to me as well, but with atftpd it is what happens. Earlier I had plain-old tftpd, which didn't even support blksize option. Here it is, from PC to PC: 17:28:49.166859 IP morgana.45177 rudo.32854: UDP, length 516 17:28:49.167030 IP rudo.32854 morgana.45177: UDP, length 4 17:28:49.167338 IP morgana.45177 rudo.32854: UDP, length 516 17:28:54.173411 IP morgana.45177 rudo.32854: UDP, length 516 17:28:59.178620 IP morgana.45177 rudo.32854: UDP, length 516 17:29:04.183788 IP morgana.45177 rudo.32854: UDP, length 516 17:29:09.188972 IP morgana.45177 rudo.32854: UDP, length 516 17:29:14.194160 IP morgana.45177 rudo.32854: UDP, length 516 atftpd repeats after 5, 10, 15, 20, 25 seconds, and nothing more. I installed the hpa version just for trying (but I'm getting back to atftpd, as i don't like the grub-like restriction only absolute pathnames). It behaves similarly: 17:40:42.404539 IP morgana.54278 rudo.32854: UDP, length 516 17:40:42.404717 IP rudo.32854 morgana.54278: UDP, length 4 17:40:42.404972 IP morgana.54278 rudo.32854: UDP, length 516 17:40:43.407340 IP morgana.54278 rudo.32854: UDP, length 516 17:40:45.409766 IP morgana.54278 rudo.32854: UDP, length 516 17:40:49.414101 IP morgana.54278 rudo.32854: UDP, length 516 17:40:57.422814 IP morgana.54278 rudo.32854: UDP, length 516 17:41:13.439200 IP morgana.54278 rudo.32854: UDP, length 516 Here it's 1, 3, 7, 16, 31 seconds. As a minimal test - since we are only talking about tftp and nfs (so far) - if we did not attempt to assemble packets which are not coming from the serverip, that might be an OK thing to do... if (NetReadIP(ip-ip_src) != NetServerIP) Yes, I agree. All I'm asking for is something robust... :) Great, thanks /alessandro ___ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot
Re: [U-Boot] [U-BOOT] error: end address not on sector boundary when I use saveenv cmd
When I set all the environment variable and try to save on flash , I am getting Error: end address not on sector boundary. Check the settings in your config file. The environment must live in an integer number of sectors, and sector size depends on the flash chip (usually 64k or 128k). But still my kernel boots with the env setting I made, saveenv failed, but in-memory env has been modified. but on restart these enviroment settings are lost. That's because saveenv failed, next time you read environment from flash (or, most likely, compile defaults). hope this helps /alessandro ___ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot
Re: [U-Boot] [U-BOOT] error: end address not on sector boundary when I use saveenv cmd
I already looked at my config file, but couldn't root cause the problem Here are some of the definitions from my configs, incase anything wrong CONFIG_SYS_FLASH_BASE 0x1000 CONFIG_ENV_ADDR0x1004 Ok. But you'd better copy whole lines from config file instead of choosing words from them. Sometimes the error is in the details. SECTOR_SIZE SZ_256K // 256KB sector size (the comment is redundant here) so the environment is in the second sector (it starts at the beginning of a sector). You problem is with the end, so CFG_ENV_SIZE must be wrong in your config. It should be 256k as well. /alessandro ___ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot
Re: [U-Boot] PATCH mtd CFI flash: timeout calculation underflow if imprecise 1kHz timer: fix
With old configuration it could happen tout=0 if CONFIG_SYS_HZ1000 solved using an unsigned long long I had the same problem with an ancient version of a vendor-ported u-boot. There my CFG_HZ was 100, so the timeout was 0. I used this, which avoids the preprocessor conditional. Since the HZ value is a compile-time constant, the compiler chooses the if or else branch and doesn't spit a run-time conditional.2 if (CFG_HZ 10) tout *= CFG_HZ/1000; /* for a big HZ, avoid overflow */ else tout = tout * CFG_HZ / 1000 + 1; /alessandro ___ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot
Re: [U-Boot] PATCH mtd CFI flash: timeout calculation underflow if imprecise 1kHz timer: fix
+tout = tout * CONFIG_SYS_HZ / 1000 + 1; 2) There should be a Signed-off-by: from Alessandro, too. Signed-off-by: Alessandro Rubini rub...@gnudd.com 5) Omit the +1. It seems bogus to me. Since the timeout is an error condition, It's better to have it longer than shorter. Since integer division truncates towards 0, I'd better give my hardware more time before signalling an error (an unlikely situation), rather than timing out on an operation that would complete in the expected time. This happens with low HZ values, which I know are discouraged nowadays. Not a big issue, anyway, I'm fine either way. /alessandro ___ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot
Re: [U-Boot] U-boot make config errors
u-boot]$ make mx31_config Configuring for mx31 board... rm: cannot remove `asm': Is a directory Asm should be a symlink. It seems you checked in your own versioning system the directory pointed by the link and not the link itself. Most likely your versioning system doesn't handle symlinks. You should learn git instead of replicating the repository: it takes some time, but it's well spent. /alessandro ___ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot
Re: [U-Boot] Kirkwood gpio (was: timeout calculation underflow if imprecise 1kHz timer: fix)
I'd prefer tout = DIV_ROUND_UP(tout*CONFIG_SYS_HZ, 1000); Ok for me. BTW: Looking for DIV_ROUND_UP, I found that it's defined in ./include/asm/arch-kirkwood/gpio.h as well. I was checking whether it can be removed, but it looks like nobody is using the driver. tornado$ grep -r CONFIG_KIRKWOOD_GPIO . ./drivers/gpio/Makefile:COBJS-$(CONFIG_KIRKWOOD_GPIO) += kw_gpio.o The header and C file were added on Jun 29th, but there's not user yet. It has been tested by Heiko on the Suen3, but it's not mainline. And even that patch doesn't define CONFIG_KIRKWOOD_GPIO . /alessandro ___ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot
[U-Boot] Subject: [PATCH] kirkwood/gpio.h: remove duplicate definition
Signed-off-by: Alessandro Rubini rub...@gnudd.com --- To test the define is not really needed, I applied the suen3 patch and added CONFIG_KIRKWOOD_GPIO to the config file. Now back to defrag stuff. include/asm-arm/arch-kirkwood/gpio.h |2 -- 1 files changed, 0 insertions(+), 2 deletions(-) diff --git a/include/asm-arm/arch-kirkwood/gpio.h b/include/asm-arm/arch-kirkwood/gpio.h index a79102b..b5bacde 100644 --- a/include/asm-arm/arch-kirkwood/gpio.h +++ b/include/asm-arm/arch-kirkwood/gpio.h @@ -17,8 +17,6 @@ #ifndef __KIRKWOOD_GPIO_H #define __KIRKWOOD_GPIO_H -/* got from kernel include/linux/kernel.h */ -#define DIV_ROUND_UP(n,d) (((n) + (d) - 1) / (d)) /* got from kernel include/linux/bitops.h */ #define BITS_PER_BYTE 8 #define BITS_TO_LONGS(nr) DIV_ROUND_UP(nr, BITS_PER_BYTE * sizeof(long)) -- 1.6.0.2 ___ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot
[U-Boot] [PATCH 0/4] Network defrag
I finally fixed the defrag code, testing with NFS as well. Didn't take performance figures, tough, for lack of time. I wanted to do config + environment for the NFS case, like tftp, but didnt' do the second step out of laziness (also, the source file has long lines while I have 80 columns). For the record, I added the check on ip_src and ip_dst, but everything stopped working. So I reverted that instead of entering a long debugging session. The CONFIG_NET_MAXDEFRAG argument is the actual payload, so I add NFS overhead to that figure, which is expected to a beautiful 4096 or 8192. I feel this is better than other options, as the person writing the config is not expected to know how much protocol overhead is there. Alessandro Rubini (4): net: defragment IP packets tftp: get the tftp block size from config file and from the environment nfs: accept CONFIG_NFS_READ_SIZE from config file arm nomadik: activate defrag choose 4k transfer block size include/configs/nhk8815.h |4 + net/net.c | 188 +++- net/nfs.h | 10 ++- net/tftp.c| 13 +++- 4 files changed, 206 insertions(+), 9 deletions(-) ___ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot
[U-Boot] [PATCH 1/4] net: defragment IP packets
The defragmenting code is enabled by CONFIG_IP_DEFRAG; the code is useful for TFTP and NFS transfers. The user can specify the maximum defragmented payload as CONFIG_NET_MAXDEFRAG (default 16k). Since NFS has a bigger per-packet overhead than TFTP, the static reassembly buffer can hold CONFIG_NET_MAXDEFRAG + the NFS overhead. The packet buffer is used as an array of hole structures, acting as a double-linked list. Each new fragment can split a hole in two, reduce a hole or fill a hole. No support is there for a fragment overlapping two diffrent holes (i.e., thre new fragment is across an already-received fragment). Signed-off-by: Alessandro Rubini rub...@gnudd.com --- net/net.c | 188 +++-- 1 files changed, 183 insertions(+), 5 deletions(-) diff --git a/net/net.c b/net/net.c index 641c37c..986d614 100644 --- a/net/net.c +++ b/net/net.c @@ -1117,6 +1117,176 @@ static void CDPStart(void) } #endif +#ifdef CONFIG_IP_DEFRAG +/* + * This function collects fragments in a single packet, according + * to the algorithm in RFC815. It returns NULL or the pointer to + * a complete packet, in static storage + */ +#ifndef CONFIG_NET_MAXDEFRAG +#define CONFIG_NET_MAXDEFRAG 16384 +#endif +/* + * MAXDEFRAG, above, is chosen in the config file and is real data + * so we need to add the NFS overhead, which is more than TFTP. + * To use sizeof in the internal unnamed structures, we need a real + * instance (can't do sizeof(struct rpc_t.u.reply)), unfortunately). + * The compiler doesn't complain nor allocates the actual structure + */ +static struct rpc_t rpc_specimen; +#define IP_PKTSIZE (CONFIG_NET_MAXDEFRAG + sizeof(rpc_specimen.u.reply)) + +#define IP_MAXUDP (IP_PKTSIZE - IP_HDR_SIZE_NO_UDP) + +/* + * this is the packet being assembled, either data or frag control. + * Fragments go by 8 bytes, so this union must be 8 bytes long + */ +struct hole { + /* first_byte is address of this structure */ + u16 last_byte; /* last byte in this hole + 1 (begin of next hole) */ + u16 next_hole; /* index of next (in 8-b blocks), 0 == none */ + u16 prev_hole; /* index of prev, 0 == none */ + u16 unused; +}; + +static IP_t *__NetDefragment(IP_t *ip, int *lenp) +{ + static uchar pkt_buff[IP_PKTSIZE] __attribute__((aligned(PKTALIGN))); + static u16 first_hole, total_len; + struct hole *payload, *thisfrag, *h, *newh; + IP_t *localip = (IP_t *)pkt_buff; + uchar *indata = (uchar *)ip; + int offset8, start, len, done = 0; + u16 ip_off = ntohs(ip-ip_off); + + /* payload starts after IP header, this fragment is in there */ + payload = (struct hole *)(pkt_buff + IP_HDR_SIZE_NO_UDP); + offset8 = (ip_off IP_OFFS); + thisfrag = payload + offset8; + start = offset8 * 8; + len = ntohs(ip-ip_len) - IP_HDR_SIZE_NO_UDP; + + if (start + len IP_MAXUDP) /* fragment extends too far */ + return NULL; + + if (!total_len || localip-ip_id != ip-ip_id) { + /* new (or different) packet, reset structs */ + total_len = 0x; + payload[0].last_byte = ~0; + payload[0].next_hole = 0; + payload[0].prev_hole = 0; + first_hole = 0; + /* any IP header will work, copy the first we received */ + memcpy(localip, ip, IP_HDR_SIZE_NO_UDP); + } + + /* +* What follows is the reassembly algorithm. We use the payload +* array as a linked list of hole descriptors, as each hole starts +* at a multiple of 8 bytes. However, last byte can be whatever value, +* so it is represented as byte count, not as 8-byte blocks. +*/ + + h = payload + first_hole; + while (h-last_byte start) { + if (!h-next_hole) { + /* no hole that far away */ + return NULL; + } + h = payload + h-next_hole; + } + + if (offset8 + (len / 8) = h - payload) { + /* no overlap with holes (dup fragment?) */ + return NULL; + } + + if (!(ip_off IP_FLAGS_MFRAG)) { + /* no more fragmentss: truncate this (last) hole */ + total_len = start + len; + h-last_byte = start + len; + } + + /* +* There is some overlap: fix the hole list. This code doesn't +* deal with a fragment that overlaps with two different holes +* (thus being a superset of a previously-received fragment). +*/ + + if ( (h = thisfrag) (h-last_byte = start + len) ) { + /* complete overlap with hole: remove hole */ + if (!h-prev_hole !h-next_hole) { + /* last remaining hole */ + done = 1; + } else if (!h-prev_hole) { + /* first hole
[U-Boot] [PATCH 2/4] tftp: get the tftp block size from config file and from the environment
Increasing the block size is useful if CONFIG_IP_DEFRAG is used. Howerver, the last fragments in a burst may overflow the receiving ethernet, so the default is left at 1468, with thre new CONFIG_TFTP_BLOCKSIZE for config files. Further, tftpblocksize can be set in the environment. Signed-off-by: Alessandro Rubini rub...@gnudd.com --- net/tftp.c | 13 +++-- 1 files changed, 11 insertions(+), 2 deletions(-) diff --git a/net/tftp.c b/net/tftp.c index b0f1cca..34b79c4 100644 --- a/net/tftp.c +++ b/net/tftp.c @@ -86,8 +86,14 @@ extern flash_info_t flash_info[]; /* 512 is poor choice for ethernet, MTU is typically 1500. * Minus eth.hdrs thats 1468. Can get 2x better throughput with * almost-MTU block sizes. At least try... fall back to 512 if need be. + * (but those using CONFIG_IP_DEFRAG may want to set a larger block in cfg file) */ +#ifdef CONFIG_TFTP_BLOCKSIZE +#define TFTP_MTU_BLOCKSIZE CONFIG_TFTP_BLOCKSIZE +#else #define TFTP_MTU_BLOCKSIZE 1468 +#endif + static unsigned short TftpBlkSize=TFTP_BLOCK_SIZE; static unsigned short TftpBlkSizeOption=TFTP_MTU_BLOCKSIZE; @@ -475,9 +481,12 @@ TftpTimeout (void) void TftpStart (void) { -#ifdef CONFIG_TFTP_PORT char *ep; /* Environment pointer */ -#endif + + /* Allow the user to choose tftpblocksize */ + if ((ep = getenv(tftpblocksize)) != NULL) + TftpBlkSizeOption = simple_strtol(ep, NULL, 10); + debug(tftp block size is %i\n, TftpBlkSizeOption); TftpServerIP = NetServerIP; if (BootFile[0] == '\0') { -- 1.6.0.2 ___ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot
[U-Boot] [PATCH 3/4] nfs: accept CONFIG_NFS_READ_SIZE from config file
To take advantage of defragmented packets, the config file can define CONFIG_NFS_READ_SIZE to override the 1kB default. No support is there for an environment variable by now. Signed-off-by: Alessandro Rubini rub...@gnudd.com --- net/nfs.h | 10 -- 1 files changed, 8 insertions(+), 2 deletions(-) diff --git a/net/nfs.h b/net/nfs.h index 712afa0..de8a0c6 100644 --- a/net/nfs.h +++ b/net/nfs.h @@ -38,8 +38,14 @@ /* Block size used for NFS read accesses. A RPC reply packet (including all * headers) must fit within a single Ethernet frame to avoid fragmentation. - * Chosen to be a power of two, as most NFS servers are optimized for this. */ -#define NFS_READ_SIZE 1024 + * However, if CONFIG_IP_DEFRAG is set, the config file may want to use a + * bigger value. In any case, most NFS servers are optimized for a power of 2. + */ +#ifdef CONFIG_NFS_READ_SIZE +#define NFS_READ_SIZE CONFIG_NFS_READ_SIZE +#else +#define NFS_READ_SIZE 1024 /* biggest power of two that fits Ether frame */ +#endif #define NFS_MAXLINKDEPTH 16 -- 1.6.0.2 ___ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot
[U-Boot] [PATCH 4/4] arm nomadik: activate defrag choose 4k transfer block size
This chooses 4kB data size for both TFTP and NFS, as an example about how to use support for IP fragments. Signed-off-by: Alessandro Rubini rub...@gnudd.com --- include/configs/nhk8815.h |4 1 files changed, 4 insertions(+), 0 deletions(-) diff --git a/include/configs/nhk8815.h b/include/configs/nhk8815.h index 67b72dc..4c3c4f8 100644 --- a/include/configs/nhk8815.h +++ b/include/configs/nhk8815.h @@ -147,6 +147,10 @@ #define CONFIG_SMC_USE_32_BIT #define CONFIG_BOOTFILEuImage +#define CONFIG_IP_DEFRAG /* Allows faster download, TFTP and NFS */ +#define CONFIG_TFTP_BLOCKSIZE 4096 +#define CONFIG_NFS_READ_SIZE 4096 + /* Storage information: onenand and nand */ #define CONFIG_CMD_ONENAND #define CONFIG_MTD_ONENAND_VERIFY_WRITE -- 1.6.0.2 ___ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot
Re: [U-Boot] [RFC PATCH v2] ARM: Avoid compiler optimization for usages of readb, writeb and friends.
Dirk Behme: Just for the record: The trick is to ensure that the __arch_putx() containing the volatile is not the last statement in the GCC statement-expression. So, using something like #define writeb(v,c) ({ __iowmb(); __arch_putb(v,c); v;}) (note the additional 'v;') should result in correct code, too. Yes, that's good. Also 0 may work, and may be more readable, (or not, according to who reads it). The patches sent by Wolfgang and Alexander using #define writeb(v,c) do { __iowmb(); __arch_putb(v,c); } while (0) do the same with a slightly different syntax, so these patches are fine, too. It's not just different syntax, it's different semantics. The ({...}) trick turns statements into expressions, while the do {...} while(0) does not. I'd better not forbid statements like while (reg = readb(addr), reg != VALUE) { } or if (readb(addr) == VALUE) { ... } or swtich (readb(addr)) { ... } While I agree they may in general not be clean, I can forsee meaningful uses. Moreover, I'd better allow expression-looking macros to really behave like expressions -- otherwise error messages are quite hard to understand for the unaquainted. IMHO, the only reason to use do {} while(0) over statemente expressions is being portable but in u-boot we are gcc-specific anyways. /alessandro ___ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot
[U-Boot] [PATCH] arm nomadik: rename board and cleanup config
From: Alessandro Rubini rub...@unipv.it This patch cleans up some glitches in the initial submission: - nobody calls it nmdk8815: the board is nhk8815, so rename - nand and onenand can coexist, so fix config file accordingly - configure the chip select for OneNand, so it works properly - removed a pair of unused defines and reordered the jffs defs - add some comments and an explanation of the two configs Signed-off-by: Alessandro Rubini rub...@unipv.it Acked-by: Andrea Gallo andrea.ga...@stericsson.com --- If needed I can split this, but I think it's trivial enough. Over this I'll send a few additions in the next days. Makefile | 10 ++-- board/st/{nmdk8815 = nhk8815}/Makefile|2 +- board/st/{nmdk8815 = nhk8815}/config.mk |0 .../st/{nmdk8815/nmdk8815.c = nhk8815/nhk8815.c} |4 ++ board/st/{nmdk8815 = nhk8815}/platform.S |0 cpu/arm926ejs/nomadik/reset.S | 12 + doc/{README.nmdk8815 = README.nhk8815}|9 +++ include/configs/{nmdk8815.h = nhk8815.h} | 57 8 files changed, 55 insertions(+), 39 deletions(-) rename board/st/{nmdk8815 = nhk8815}/Makefile (98%) rename board/st/{nmdk8815 = nhk8815}/config.mk (100%) rename board/st/{nmdk8815/nmdk8815.c = nhk8815/nhk8815.c} (91%) rename board/st/{nmdk8815 = nhk8815}/platform.S (100%) rename doc/{README.nmdk8815 = README.nhk8815} (75%) rename include/configs/{nmdk8815.h = nhk8815.h} (77%) diff --git a/Makefile b/Makefile index acec1a0..14ba063 100644 --- a/Makefile +++ b/Makefile @@ -2841,17 +2841,17 @@ mx1fs2_config : unconfig netstar_config:unconfig @$(MKCONFIG) $(@:_config=) arm arm925t netstar -nmdk8815_config \ -nmdk8815_onenand_config: unconfig +nhk8815_config \ +nhk8815_onenand_config:unconfig @mkdir -p $(obj)include @ $(obj)include/config.h @if [ $(findstring _onenand, $@) ] ; then \ echo #define CONFIG_BOOT_ONENAND $(obj)include/config.h; \ - $(XECHO) ... configured for OneNand Flash; \ + $(XECHO) ... configured to boot from OneNand Flash; \ else \ - $(XECHO) ... configured for Nand Flash; \ + $(XECHO) ... configured to boot from Nand Flash; \ fi - @$(MKCONFIG) -a nmdk8815 arm arm926ejs nmdk8815 st nomadik + @$(MKCONFIG) -a nhk8815 arm arm926ejs nhk8815 st nomadik omap1510inn_config : unconfig @$(MKCONFIG) $(@:_config=) arm arm925t omap1510inn diff --git a/board/st/nmdk8815/Makefile b/board/st/nhk8815/Makefile similarity index 98% rename from board/st/nmdk8815/Makefile rename to board/st/nhk8815/Makefile index be9a424..b37fe53 100644 --- a/board/st/nmdk8815/Makefile +++ b/board/st/nhk8815/Makefile @@ -29,7 +29,7 @@ include $(TOPDIR)/config.mk LIB= $(obj)lib$(BOARD).a -COBJS := nmdk8815.o +COBJS := nhk8815.o SOBJS := platform.o SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) diff --git a/board/st/nmdk8815/config.mk b/board/st/nhk8815/config.mk similarity index 100% rename from board/st/nmdk8815/config.mk rename to board/st/nhk8815/config.mk diff --git a/board/st/nmdk8815/nmdk8815.c b/board/st/nhk8815/nhk8815.c similarity index 91% rename from board/st/nmdk8815/nmdk8815.c rename to board/st/nhk8815/nhk8815.c index edf4626..085a5e0 100644 --- a/board/st/nmdk8815/nmdk8815.c +++ b/board/st/nhk8815/nhk8815.c @@ -53,6 +53,10 @@ int board_init(void) writel(0x305b, REG_FSMC_BCR1); writel(0x00033f33, REG_FSMC_BTR1); + /* Set up SMCS0 for OneNand: sram-like once again */ + writel(0x30db, NOMADIK_FSMC_BASE + 0x00); /* FSMC_BCR0 */ + writel(0x02100551, NOMADIK_FSMC_BASE + 0x04); /* FSMC_BTR0 */ + icache_enable(); return 0; } diff --git a/board/st/nmdk8815/platform.S b/board/st/nhk8815/platform.S similarity index 100% rename from board/st/nmdk8815/platform.S rename to board/st/nhk8815/platform.S diff --git a/cpu/arm926ejs/nomadik/reset.S b/cpu/arm926ejs/nomadik/reset.S index 948996b..694c32b 100644 --- a/cpu/arm926ejs/nomadik/reset.S +++ b/cpu/arm926ejs/nomadik/reset.S @@ -6,20 +6,10 @@ .align 5 .globl reset_cpu reset_cpu: -#if defined CONFIG_NOMADIK_8815 - ldr r0, =NOMADIK_SRC_BASE + ldr r0, =NOMADIK_SRC_BASE /* System and Reset Controller */ ldr r1, =0x1 str r1, [r0, #0x18] -#else - ldr r1, rstctl1 /* get clkm1 reset ctl */ - mov r3, #0x0 - strhr3, [r1]/* clear it */ - mov r3, #0x8 - strhr3, [r1]/* force dsp+arm reset */ -#endif _loop_forever: b _loop_forever -rstctl1: - .word 0xfffece10 diff --git a/doc/README.nmdk8815 b/doc/README.nhk8815 similarity index 75% rename from doc/README.nmdk8815 rename to doc/README.nhk8815 index 453cfae..940f24d 100644 --- a/doc/README.nmdk8815
[U-Boot] [PATCH 0/4 v2] Clean up the Nomadik board and add OneNand
This patch-set cleans up some glitches in my first submission. I posted it as a single patch and a separate timer patch. The first one is split as JC asked, and the timer patch is there as well since it is conceptually in the same set, although I had no comments on the timer part yet. JC: I didn't split clean and onenand, since the change in partitioning information in the config file is part of introducing onenand. A split would have introduced a never-tested artificial middle version. Alessandro Rubini (4): arm nomadik: rename board to nhk8815 arm nomadik: cleanup reset arm nomadik: allow Nand and OneNand to coexists arm nomadik: use 1000 as HZ value and rewrite timer code Makefile | 10 +- board/st/{nmdk8815 = nhk8815}/Makefile|2 +- board/st/{nmdk8815 = nhk8815}/config.mk |0 .../st/{nmdk8815/nmdk8815.c = nhk8815/nhk8815.c} |4 + board/st/{nmdk8815 = nhk8815}/platform.S |0 cpu/arm926ejs/nomadik/reset.S | 13 +-- cpu/arm926ejs/nomadik/timer.c | 190 ++-- doc/{README.nmdk8815 = README.nhk8815}| 10 + include/configs/{nmdk8815.h = nhk8815.h} | 59 --- 9 files changed, 109 insertions(+), 179 deletions(-) rename board/st/{nmdk8815 = nhk8815}/Makefile (98%) rename board/st/{nmdk8815 = nhk8815}/config.mk (100%) rename board/st/{nmdk8815/nmdk8815.c = nhk8815/nhk8815.c} (91%) rename board/st/{nmdk8815 = nhk8815}/platform.S (100%) rename doc/{README.nmdk8815 = README.nhk8815} (75%) rename include/configs/{nmdk8815.h = nhk8815.h} (76%) ___ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot
[U-Boot] [PATCH 1/4 v2] arm nomadik: rename board to nhk8815
From: Alessandro Rubini rub...@unipv.it This is an error in my side in the initial submission: nobody calls it nmdk8815, it's nomadik hardware kit, nhk8815, instead. Signed-off-by: Alessandro Rubini rub...@unipv.it Acked-by: Andrea Gallo andrea.ga...@stericsson.com --- Makefile |6 +++--- board/st/{nmdk8815 = nhk8815}/Makefile|2 +- board/st/{nmdk8815 = nhk8815}/config.mk |0 .../st/{nmdk8815/nmdk8815.c = nhk8815/nhk8815.c} |0 board/st/{nmdk8815 = nhk8815}/platform.S |0 doc/{README.nmdk8815 = README.nhk8815}|0 include/configs/{nmdk8815.h = nhk8815.h} |3 ++- 7 files changed, 6 insertions(+), 5 deletions(-) rename board/st/{nmdk8815 = nhk8815}/Makefile (98%) rename board/st/{nmdk8815 = nhk8815}/config.mk (100%) rename board/st/{nmdk8815/nmdk8815.c = nhk8815/nhk8815.c} (100%) rename board/st/{nmdk8815 = nhk8815}/platform.S (100%) rename doc/{README.nmdk8815 = README.nhk8815} (100%) rename include/configs/{nmdk8815.h = nhk8815.h} (97%) diff --git a/Makefile b/Makefile index bcc81c9..37e50f0 100644 --- a/Makefile +++ b/Makefile @@ -2839,8 +2839,8 @@ mx1fs2_config : unconfig netstar_config:unconfig @$(MKCONFIG) $(@:_config=) arm arm925t netstar -nmdk8815_config \ -nmdk8815_onenand_config: unconfig +nhk8815_config \ +nhk8815_onenand_config:unconfig @mkdir -p $(obj)include @ $(obj)include/config.h @if [ $(findstring _onenand, $@) ] ; then \ @@ -2849,7 +2849,7 @@ nmdk8815_onenand_config: unconfig else \ $(XECHO) ... configured for Nand Flash; \ fi - @$(MKCONFIG) -a nmdk8815 arm arm926ejs nmdk8815 st nomadik + @$(MKCONFIG) -a nhk8815 arm arm926ejs nhk8815 st nomadik omap1510inn_config : unconfig @$(MKCONFIG) $(@:_config=) arm arm925t omap1510inn diff --git a/board/st/nmdk8815/Makefile b/board/st/nhk8815/Makefile similarity index 98% rename from board/st/nmdk8815/Makefile rename to board/st/nhk8815/Makefile index be9a424..b37fe53 100644 --- a/board/st/nmdk8815/Makefile +++ b/board/st/nhk8815/Makefile @@ -29,7 +29,7 @@ include $(TOPDIR)/config.mk LIB= $(obj)lib$(BOARD).a -COBJS := nmdk8815.o +COBJS := nhk8815.o SOBJS := platform.o SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) diff --git a/board/st/nmdk8815/config.mk b/board/st/nhk8815/config.mk similarity index 100% rename from board/st/nmdk8815/config.mk rename to board/st/nhk8815/config.mk diff --git a/board/st/nmdk8815/nmdk8815.c b/board/st/nhk8815/nhk8815.c similarity index 100% rename from board/st/nmdk8815/nmdk8815.c rename to board/st/nhk8815/nhk8815.c diff --git a/board/st/nmdk8815/platform.S b/board/st/nhk8815/platform.S similarity index 100% rename from board/st/nmdk8815/platform.S rename to board/st/nhk8815/platform.S diff --git a/doc/README.nmdk8815 b/doc/README.nhk8815 similarity index 100% rename from doc/README.nmdk8815 rename to doc/README.nhk8815 diff --git a/include/configs/nmdk8815.h b/include/configs/nhk8815.h similarity index 97% rename from include/configs/nmdk8815.h rename to include/configs/nhk8815.h index 6d7b94f..df9d523 100644 --- a/include/configs/nmdk8815.h +++ b/include/configs/nhk8815.h @@ -1,7 +1,8 @@ /* * (C) Copyright 2005 * STMicroelectronics. - * Configuration settings for the STn8815 nomadik board. + * Configuration settings for the Nomadik Hardware Kit NHK-8815, + * the evaluation board for the Nomadik 8815 System on Chip. * * See file CREDITS for list of people who contributed to this * project. -- 1.6.0.2 ___ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot
[U-Boot] [PATCH 2/4 v2] arm nomadik: cleanup reset
From: Alessandro Rubini rub...@unipv.it There is only one public release of the Nomadik chip, so the ifdef in reset code as well as a define in the config file are not needed Signed-off-by: Alessandro Rubini rub...@unipv.it Acked-by: Andrea Gallo andrea.ga...@stericsson.com --- cpu/arm926ejs/nomadik/reset.S | 13 + include/configs/nhk8815.h |5 ++--- 2 files changed, 3 insertions(+), 15 deletions(-) diff --git a/cpu/arm926ejs/nomadik/reset.S b/cpu/arm926ejs/nomadik/reset.S index 948996b..ec95472 100644 --- a/cpu/arm926ejs/nomadik/reset.S +++ b/cpu/arm926ejs/nomadik/reset.S @@ -6,20 +6,9 @@ .align 5 .globl reset_cpu reset_cpu: -#if defined CONFIG_NOMADIK_8815 - ldr r0, =NOMADIK_SRC_BASE + ldr r0, =NOMADIK_SRC_BASE /* System and Reset Controller */ ldr r1, =0x1 str r1, [r0, #0x18] -#else - ldr r1, rstctl1 /* get clkm1 reset ctl */ - mov r3, #0x0 - strhr3, [r1]/* clear it */ - mov r3, #0x8 - strhr3, [r1]/* force dsp+arm reset */ -#endif _loop_forever: b _loop_forever - -rstctl1: - .word 0xfffece10 diff --git a/include/configs/nhk8815.h b/include/configs/nhk8815.h index df9d523..321adfa 100644 --- a/include/configs/nhk8815.h +++ b/include/configs/nhk8815.h @@ -30,9 +30,8 @@ #define CONFIG_ARM926EJS #define CONFIG_NOMADIK -#define CONFIG_NOMADIK_8815 -#define CONFIG_NOMADIK_NDK15 -#define CONFIG_NOMADIK_NHK15 +#define CONFIG_NOMADIK_8815/* cpu variant */ +#define CONFIG_NOMADIK_NHK8815 /* board variant */ #define CONFIG_SKIP_LOWLEVEL_INIT /* we have already been loaded to RAM */ -- 1.6.0.2 ___ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot
[U-Boot] [PATCH 3/4 v2] arm nomadik: allow Nand and OneNand to coexists
From: Alessandro Rubini rub...@unipv.it The evaluation kit has both Nand and OneNand, both drivers are there and the two configurations only select a different default for the jffs partition. This adds the OneNand driver and cleans up storage. Signed-off-by: Alessandro Rubini rub...@unipv.it Acked-by: Andrea Gallo andrea.ga...@stericsson.com --- Makefile |4 +- board/st/nhk8815/nhk8815.c |4 +++ doc/README.nhk8815 | 10 + include/configs/nhk8815.h | 49 +++ 4 files changed, 47 insertions(+), 20 deletions(-) diff --git a/Makefile b/Makefile index 37e50f0..d2454c8 100644 --- a/Makefile +++ b/Makefile @@ -2845,9 +2845,9 @@ nhk8815_onenand_config: unconfig @ $(obj)include/config.h @if [ $(findstring _onenand, $@) ] ; then \ echo #define CONFIG_BOOT_ONENAND $(obj)include/config.h; \ - $(XECHO) ... configured for OneNand Flash; \ + $(XECHO) ... configured to boot from OneNand Flash; \ else \ - $(XECHO) ... configured for Nand Flash; \ + $(XECHO) ... configured to boot from Nand Flash; \ fi @$(MKCONFIG) -a nhk8815 arm arm926ejs nhk8815 st nomadik diff --git a/board/st/nhk8815/nhk8815.c b/board/st/nhk8815/nhk8815.c index edf4626..085a5e0 100644 --- a/board/st/nhk8815/nhk8815.c +++ b/board/st/nhk8815/nhk8815.c @@ -53,6 +53,10 @@ int board_init(void) writel(0x305b, REG_FSMC_BCR1); writel(0x00033f33, REG_FSMC_BTR1); + /* Set up SMCS0 for OneNand: sram-like once again */ + writel(0x30db, NOMADIK_FSMC_BASE + 0x00); /* FSMC_BCR0 */ + writel(0x02100551, NOMADIK_FSMC_BASE + 0x04); /* FSMC_BTR0 */ + icache_enable(); return 0; } diff --git a/doc/README.nhk8815 b/doc/README.nhk8815 index 453cfae..9008e39 100644 --- a/doc/README.nhk8815 +++ b/doc/README.nhk8815 @@ -15,6 +15,16 @@ SDRAM configuration, PLL setup and initial loading from NAND is implemented in the X-Loader, so U-Boot is already running in SDRAM when control is handed over to it. +The Makefile offers two different configurations to be used if you +boot from Nand or OneNand. + +make nhk8815_config +make nhk8815_onenand_config + +Both support OneNand and Nand. Since U-Boot, running in RAM, can't know +where it was loaded from, the configurations differ in where the filesystem +is looked for by default. + On www.st.com/nomadik and on www.stnwireless.com there are documents, summary data and white papers on Nomadik. The full datasheet for diff --git a/include/configs/nhk8815.h b/include/configs/nhk8815.h index 321adfa..bf1a915 100644 --- a/include/configs/nhk8815.h +++ b/include/configs/nhk8815.h @@ -55,6 +55,7 @@ #define CONFIG_SYS_HUSH_PARSER #define CONFIG_SYS_PROMPT Nomadik #define CONFIG_SYS_PROMPT_HUSH_PS2 +#define CONFIG_CMDLINE_EDITING #define CONFIG_SYS_CBSIZE 256 /* Console I/O Buffer Size */ #define CONFIG_SYS_PBSIZE (CONFIG_SYS_CBSIZE \ + sizeof(CONFIG_SYS_PROMPT) + 16) @@ -90,6 +91,7 @@ #define CONFIG_SYS_MEMTEST_END 0x0FFF #define CONFIG_SYS_MALLOC_LEN (CONFIG_ENV_SIZE + 256 * 1024) #define CONFIG_SYS_GBL_DATA_SIZE 128 /* for initial data */ +#define CONFIG_SYS_64BIT_VSPRINTF /* mtd desires this */ #define CONFIG_MISC_INIT_R /* call misc_init_r during start up */ @@ -120,43 +122,54 @@ #define CONFIG_SMC_USE_32_BIT #define CONFIG_BOOTFILEuImage -/* flash memory and filesystem information */ -#define CONFIG_DOS_PARTITION +/* Storage information: onenand and nand */ +#define CONFIG_CMD_ONENAND #define CONFIG_MTD_ONENAND_VERIFY_WRITE #define CONFIG_SYS_ONENAND_BASE0x3000 + +#define CONFIG_CMD_NAND #define CONFIG_SYS_MAX_NAND_DEVICE 1 #define CONFIG_SYS_NAND_BASE 0x4000 /* SMPS0n */ +/* + * Filesystem information + * + * Since U-Boot has been loaded to RAM by vendor code, we could use + * either or both OneNand and Nand. However, we need to know where the + * filesystem lives. Comments below report vendor-selected partitions + */ #ifdef CONFIG_BOOT_ONENAND - -# define CONFIG_CMD_ONENAND /* Temporary: nand and onenand can't coexist */ /* PartitionSizeStart * XloaderTOC + X-Loader256KB 0x * Memory init function 256KB 0x0004 -* U-Boot 2MB 0x0008 +* U-Boot + env 2MB 0x0008 * Sysimage (kernel + ramdisk) 4MB 0x0028 * JFFS2 Root filesystem22MB0x0068 * JFFS2 User Data 227.5MB 0x01C8 */ -# define CONFIG_JFFS2_PART_SIZE 0x40 -# define CONFIG_JFFS2_PART_OFFSET0x28 - +# define CONFIG_JFFS2_DEVonenand0 +# define
[U-Boot] [PATCH 4/4 v2] arm nomadik: use 1000 as HZ value and rewrite timer code
From: Alessandro Rubini rub...@unipv.it This sets CONFIG_SYS_HZ to 1000 as required, and completely rewrites timer code, which is now both correct and much smaller. Unused functions like udelay_masked() have been removed as no driver uses them, even the ones that are not currently active for this board. Signed-off-by: Alessandro Rubini rub...@unipv.it Acked-by: Andrea Gallo andrea.ga...@stericsson.com --- cpu/arm926ejs/nomadik/timer.c | 190 +++- include/configs/nhk8815.h |2 +- 2 files changed, 53 insertions(+), 139 deletions(-) diff --git a/cpu/arm926ejs/nomadik/timer.c b/cpu/arm926ejs/nomadik/timer.c index 2870d24..3618c4a 100644 --- a/cpu/arm926ejs/nomadik/timer.c +++ b/cpu/arm926ejs/nomadik/timer.c @@ -1,20 +1,5 @@ /* - * (C) Copyright 2003 - * Texas Instruments www.ti.com - * - * (C) Copyright 2002 - * Sysgo Real-Time Solutions, GmbH www.elinos.com - * Marius Groeger mgroe...@sysgo.de - * - * (C) Copyright 2002 - * Sysgo Real-Time Solutions, GmbH www.elinos.com - * Alex Zuepke a...@sysgo.de - * - * (C) Copyright 2002-2004 - * Gary Jennejohn, DENX Software Engineering, ga...@denx.de - * - * (C) Copyright 2004 - * Philippe Robin, ARM Ltd. philippe.ro...@arm.com + * (C) Copyright 2009 Alessandro Rubini * * See file CREDITS for list of people who contributed to this * project. @@ -38,145 +23,74 @@ #include common.h #include asm/io.h -#define TIMER_LOAD_VAL 0x +/* + * Registers in the MTU block -- same as mach/mtu.h in linux +*/ + +#define MTU_IMSC 0x00/* Interrupt mask set/clear */ +#define MTU_RIS0x04/* Raw interrupt status */ +#define MTU_MIS0x08/* Masked interrupt status */ +#define MTU_ICR0x0C/* Interrupt clear register */ + +/* per-timer registers take 0..3 as argument */ +#define MTU_LR(x) (0x10 + 0x10 * (x) + 0x00) /* Load value */ +#define MTU_VAL(x) (0x10 + 0x10 * (x) + 0x04) /* Current value */ +#define MTU_CR(x) (0x10 + 0x10 * (x) + 0x08) /* Control reg */ +#define MTU_BGLR(x)(0x10 + 0x10 * (x) + 0x0c) /* At next overflow */ + +/* bits for the control register */ +#define MTU_CRn_ENA0x80 +#define MTU_CRn_PERIODIC 0x40/* if 0 = free-running */ +#define MTU_CRn_PRESCALE_MASK 0x0c +#define MTU_CRn_PRESCALE_1 0x00 +#define MTU_CRn_PRESCALE_160x04 +#define MTU_CRn_PRESCALE_256 0x08 +#define MTU_CRn_32BITS 0x02 +#define MTU_CRn_ONESHOT0x01/* if 0 = wraps reloading from BGLR*/ -/* macro to read the 32 bit timer */ -#define READ_TIMER readl(CONFIG_SYS_TIMERBASE + 20) -static ulong timestamp; -static ulong lastdec; +/* + * The timer is a decrementer, we'll left it free running at 2.4MHz. + * We have 2.4 ticks per microsecond and an overflow in almost 30min + */ +#define TIMER_CLOCK(24*100*1000) +#define COUNT_TO_USEC(x) ((x)*5/12) /* overflows at 6min */ +#define USEC_TO_COUNT(x) ((x)*12/5) /* overflows at 6min */ +#define TICKS_PER_HZ (TIMER_CLOCK/CONFIG_SYS_HZ) +#define TICKS_TO_HZ(x) ((x)/TICKS_PER_HZ) + +/* macro to read the 32 bit timer: since it decrements, we invert read value */ +#define READ_TIMER() (~readl(CONFIG_SYS_TIMERBASE + MTU_VAL(0))) -/* nothing really to do with interrupts, just starts up a counter. */ +/* Configure a free-running, auto-wrap counter with no prescaler */ int timer_init(void) { - /* Load timer with initial value */ - writel(TIMER_LOAD_VAL, CONFIG_SYS_TIMERBASE + 16); - - /* -* Set timer to be enabled, free-running, no interrupts, 256 divider, -* 32-bit, wrap-mode -*/ - writel(0x8a, CONFIG_SYS_TIMERBASE + 24); - - /* init the timestamp and lastdec value */ - reset_timer_masked(); - + writel(MTU_CRn_ENA | MTU_CRn_PRESCALE_1 | MTU_CRn_32BITS, + CONFIG_SYS_TIMERBASE + MTU_CR(0)); + reset_timer(); return 0; } -/* - * timer without interrupts - */ +/* Restart counting from 0 */ void reset_timer(void) { - reset_timer_masked(); + writel(0, CONFIG_SYS_TIMERBASE + MTU_LR(0)); /* Immediate effect */ } +/* Return how many HZ passed since base */ ulong get_timer(ulong base) { - return get_timer_masked() - base; -} - -void set_timer(ulong t) -{ - timestamp = t; + ulong res = TICKS_TO_HZ(READ_TIMER()) - base; + return res; } -/* delay x useconds AND perserve advance timstamp value */ +/* Delay x useconds */ void udelay(unsigned long usec) { - ulong tmo, tmp; - - if (usec = 1000) { - /* if big number, spread normalization to seconds */ - tmo = usec / 1000; /* start to normalize */ - tmo *= CONFIG_SYS_HZ; /* find number of ticks */ - tmo /= 1000;/* finish normalize. */ - } else { - /* small number, don't kill it prior to HZ
[U-Boot] [PATCH v3] arm nomadik: use 1000 as HZ value and rewrite timer code
From: Alessandro Rubini rub...@unipv.it This sets CONFIG_SYS_HZ to 1000 as required, and completely rewrites timer code, which is now both correct and much smaller. Unused functions like udelay_masked() have been removed as no driver uses them, even the ones that are not currently active for this board. mtu.h is copied literally from the kernel sources. Signed-off-by: Alessandro Rubini rub...@unipv.it Acked-by: Andrea Gallo andrea.ga...@stericsson.com --- I've used mtu.h from kernel sources and done the other changes as requested (the extra variable just to return it was a mishap from an earlier printf I needed to find a misconfig). for the record what is its precision now? it counts at 2.4MHz, so the 1000HZ tick has no approximation and udelay is correct with sub-microsecond error. I'll use in soft_i2c, needed to turn on the LCD light. cpu/arm926ejs/nomadik/mtu.h | 45 +++ cpu/arm926ejs/nomadik/timer.c | 166 +++-- include/configs/nhk8815.h |2 +- 3 files changed, 73 insertions(+), 140 deletions(-) create mode 100644 cpu/arm926ejs/nomadik/mtu.h diff --git a/cpu/arm926ejs/nomadik/mtu.h b/cpu/arm926ejs/nomadik/mtu.h new file mode 100644 index 000..21b4a7a --- /dev/null +++ b/cpu/arm926ejs/nomadik/mtu.h @@ -0,0 +1,45 @@ + +#ifndef __ASM_ARCH_MTU_H +#define __ASM_ARCH_MTU_H + +/* + * The MTU device hosts four different counters, with 4 set of + * registers. These are register names. + */ + +#define MTU_IMSC 0x00/* Interrupt mask set/clear */ +#define MTU_RIS0x04/* Raw interrupt status */ +#define MTU_MIS0x08/* Masked interrupt status */ +#define MTU_ICR0x0C/* Interrupt clear register */ + +/* per-timer registers take 0..3 as argument */ +#define MTU_LR(x) (0x10 + 0x10 * (x) + 0x00) /* Load value */ +#define MTU_VAL(x) (0x10 + 0x10 * (x) + 0x04) /* Current value */ +#define MTU_CR(x) (0x10 + 0x10 * (x) + 0x08) /* Control reg */ +#define MTU_BGLR(x)(0x10 + 0x10 * (x) + 0x0c) /* At next overflow */ + +/* bits for the control register */ +#define MTU_CRn_ENA0x80 +#define MTU_CRn_PERIODIC 0x40/* if 0 = free-running */ +#define MTU_CRn_PRESCALE_MASK 0x0c +#define MTU_CRn_PRESCALE_1 0x00 +#define MTU_CRn_PRESCALE_160x04 +#define MTU_CRn_PRESCALE_256 0x08 +#define MTU_CRn_32BITS 0x02 +#define MTU_CRn_ONESHOT0x01/* if 0 = wraps reloading from BGLR*/ + +/* Other registers are usual amba/primecell registers, currently not used */ +#define MTU_ITCR 0xff0 +#define MTU_ITOP 0xff4 + +#define MTU_PERIPH_ID0 0xfe0 +#define MTU_PERIPH_ID1 0xfe4 +#define MTU_PERIPH_ID2 0xfe8 +#define MTU_PERIPH_ID3 0xfeC + +#define MTU_PCELL0 0xff0 +#define MTU_PCELL1 0xff4 +#define MTU_PCELL2 0xff8 +#define MTU_PCELL3 0xffC + +#endif /* __ASM_ARCH_MTU_H */ diff --git a/cpu/arm926ejs/nomadik/timer.c b/cpu/arm926ejs/nomadik/timer.c index 2870d24..d0946ec 100644 --- a/cpu/arm926ejs/nomadik/timer.c +++ b/cpu/arm926ejs/nomadik/timer.c @@ -1,20 +1,5 @@ /* - * (C) Copyright 2003 - * Texas Instruments www.ti.com - * - * (C) Copyright 2002 - * Sysgo Real-Time Solutions, GmbH www.elinos.com - * Marius Groeger mgroe...@sysgo.de - * - * (C) Copyright 2002 - * Sysgo Real-Time Solutions, GmbH www.elinos.com - * Alex Zuepke a...@sysgo.de - * - * (C) Copyright 2002-2004 - * Gary Jennejohn, DENX Software Engineering, ga...@denx.de - * - * (C) Copyright 2004 - * Philippe Robin, ARM Ltd. philippe.ro...@arm.com + * (C) Copyright 2009 Alessandro Rubini * * See file CREDITS for list of people who contributed to this * project. @@ -37,146 +22,49 @@ #include common.h #include asm/io.h +#include mtu.h -#define TIMER_LOAD_VAL 0x - -/* macro to read the 32 bit timer */ -#define READ_TIMER readl(CONFIG_SYS_TIMERBASE + 20) +/* + * The timer is a decrementer, we'll left it free running at 2.4MHz. + * We have 2.4 ticks per microsecond and an overflow in almost 30min + */ +#define TIMER_CLOCK(24 * 100 * 1000) +#define COUNT_TO_USEC(x) ((x) * 5 / 12) /* overflows at 6min */ +#define USEC_TO_COUNT(x) ((x) * 12 / 5) /* overflows at 6min */ +#define TICKS_PER_HZ (TIMER_CLOCK / CONFIG_SYS_HZ) +#define TICKS_TO_HZ(x) ((x) / TICKS_PER_HZ) -static ulong timestamp; -static ulong lastdec; +/* macro to read the 32 bit timer: since it decrements, we invert read value */ +#define READ_TIMER() (~readl(CONFIG_SYS_TIMERBASE + MTU_VAL(0))) -/* nothing really to do with interrupts, just starts up a counter. */ +/* Configure a free-running, auto-wrap counter with no prescaler */ int timer_init(void) { - /* Load timer with initial value */ - writel(TIMER_LOAD_VAL, CONFIG_SYS_TIMERBASE + 16); - - /* -* Set timer to be enabled, free-running, no interrupts, 256 divider, -* 32-bit, wrap-mode
Re: [U-Boot] [help] u-boot mailing list seems to block my git send-email
[sorry for my previous post, I messed the headers] Both mails are not appeared in the mailing list, but Stefan received (1) and I received (1) and (2). Actually, the mailing list is configured to not send a copy to you if you are in the Cc: list. I changed it for myself, but I fear this is the new mailman (insane) default, as I have the same problem in other lists. /alessandro ___ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot
Re: [U-Boot] [PATCH 1/1] Add support for Eukrea CPU9260 SBC
I've tried something very close to what is done in tqm8xx but I don't manage to get something reliable : either it hangs or I get data abort. After checking the datasheet, I don't understand how we can change the geometry of this SDRAM controler while running from SDRAM No, you can't. That part must be done while you run from flash. Actually, this is done in cpu/arm926ejs/at91/lowlevel_init.S, in the table SMRDATA1. So, with the current code base, you can't autodetect ram size on the atmel 926x. I have the same problem, as I have boards that ship as either 64M or 128M. I'd configure for 128M and look for aliases, reconfiguring for 64M if needed. This can be done in lowlevel_init.S or by setting up a temporary C environment with sp in static RAM and doing it in C. In both cases, this doesn't fit the current code base and some refactoring would be needed to go mainline. /alessandro ___ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot
Re: [U-Boot] [PATCH] Refresh LZMA-lib to 4.65
watchdog.diff reset watchdog timer to avoid reboot during decompression on slow machines. Actually, you don't need all these ifdef, that clutter the code. watchdog.h already include this: /* * No hardware or software watchdog. */ #if defined(__ASSEMBLY__) #define WATCHDOG_RESET /*XXX DO_NOT_DEL_THIS_COMMENT*/ #else #define WATCHDOG_RESET() {} #endif /* __ASSEMBLY__ */ So please don't ifdef around WATCHDOG_RESET /alessandro ___ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot
[U-Boot] [PATCH] cmd_i2c: bugfix: add missing brace
From: Alessandro Rubini rubini-l...@gnudd.com The sub-command parser missed a brace, so return 0; is always taken and no error message is diplayed if you say i2c scan instead of i2c probe, for example. Proper brace is added. Also, a misleading and unneeded else is removed. Signed-off-by: Alessandro Rubini rub...@gnudd.com.it --- common/cmd_i2c.c |6 +++--- 1 files changed, 3 insertions(+), 3 deletions(-) diff --git a/common/cmd_i2c.c b/common/cmd_i2c.c index ae26845..8f0fc9e 100644 --- a/common/cmd_i2c.c +++ b/common/cmd_i2c.c @@ -1282,17 +1282,17 @@ int do_i2c(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) return do_i2c_crc(cmdtp, flag, argc, argv); if (!strncmp(argv[0], pr, 2)) return do_i2c_probe(cmdtp, flag, argc, argv); - if (!strncmp(argv[0], re, 2)) + if (!strncmp(argv[0], re, 2)) { i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE); return 0; + } if (!strncmp(argv[0], lo, 2)) return do_i2c_loop(cmdtp, flag, argc, argv); #if defined(CONFIG_CMD_SDRAM) if (!strncmp(argv[0], sd, 2)) return do_sdram(cmdtp, flag, argc, argv); #endif - else - cmd_usage(cmdtp); + cmd_usage(cmdtp); return 0; } -- 1.6.0.2 ___ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot
Re: [U-Boot] [PATCH 1/1] Add support for Eukrea CPU9260 SBC
So, with the current code base, you can't autodetect ram size on the atmel 926x. Argh. So this should be fixed. Yes. Other architectures (like PPC) do all this in C. This should be possible on ARM, too. Everything is possible. I fear it's not trivial to make a generic ARM implementation, since each platform has its own way to bring up stuff. Who is going to attack this - you, Alessandro? I'm going to do it for 9263 next week, for a project I'm following. Then I'll be glad to study the general situation and see if I can suggest anything useful. /alessandro ___ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot
[U-Boot] [PATCH 0/2] arm nomadik: gpio and i2c
This adds gpio and i2c support for the Nomadik evaluation kit. They are needed to turn on the LCD backlight in order to later add LCD support. I have one doubt and some questions on gpio: To use soft_i2c I need to define some macros in the config file. Instead of writing hard numbers there I called the gpio functions, but the config file is inluded from asm sources as well. I don't think my approach is beautiful at all (both #ifndef __ASSEMBLY__ and #include ../board/), but I didn't find a better solution. I would like to add a gpio command, and I've found no generic gpio stuff. Only one board (cm-bf527) has a gpio commands, but quite a few have similar commands to set leds or other bits. Is time ripe for a generic gpio driver with board-specific limits and operations? Would that be interesting for u-boot-next? Should I process with a board-specific gpio command by now? /alessandro Alessandro Rubini (2): arm nomadik: add gpio support arm nomadik: add i2c board/st/nhk8815/Makefile |2 +- board/st/nhk8815/gpio.c| 99 board/st/nhk8815/gpio.h| 42 ++ board/st/nhk8815/nhk8815.c | 16 ++- include/configs/nhk8815.h | 18 - 5 files changed, 173 insertions(+), 4 deletions(-) create mode 100644 board/st/nhk8815/gpio.c create mode 100644 board/st/nhk8815/gpio.h ___ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot
[U-Boot] [PATCH 1/2] arm nomadik: add gpio support
From: Alessandro Rubini rub...@unipv.it Signed-off-by: Alessandro Rubini rub...@unipv.it Acked-by: Andrea Gallo andrea.ga...@stericsson.com --- board/st/nhk8815/Makefile |2 +- board/st/nhk8815/gpio.c | 99 + board/st/nhk8815/gpio.h | 42 +++ 3 files changed, 142 insertions(+), 1 deletions(-) create mode 100644 board/st/nhk8815/gpio.c create mode 100644 board/st/nhk8815/gpio.h diff --git a/board/st/nhk8815/Makefile b/board/st/nhk8815/Makefile index b37fe53..80a1ab6 100644 --- a/board/st/nhk8815/Makefile +++ b/board/st/nhk8815/Makefile @@ -29,7 +29,7 @@ include $(TOPDIR)/config.mk LIB= $(obj)lib$(BOARD).a -COBJS := nhk8815.o +COBJS := nhk8815.o gpio.o SOBJS := platform.o SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) diff --git a/board/st/nhk8815/gpio.c b/board/st/nhk8815/gpio.c new file mode 100644 index 000..e0857b6 --- /dev/null +++ b/board/st/nhk8815/gpio.c @@ -0,0 +1,99 @@ +/* + * (C) Copyright 2009 Alessandro Rubini + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include common.h +#include asm/io.h +#include gpio.h + +static unsigned long gpio_base[4] = { + NOMADIK_GPIO0_BASE, + NOMADIK_GPIO1_BASE, + NOMADIK_GPIO2_BASE, + NOMADIK_GPIO3_BASE +}; + +enum gpio_registers { + GPIO_DAT = 0x00, /* data register */ + GPIO_DATS = 0x04, /* data set */ + GPIO_DATC = 0x08, /* data clear */ + GPIO_PDIS = 0x0c, /* pull disable */ + GPIO_DIR = 0x10, /* direction */ + GPIO_DIRS = 0x14, /* direction set */ + GPIO_DIRC = 0x18, /* direction clear */ + GPIO_AFSLA =0x20, /* alternate function select A */ + GPIO_AFSLB =0x24, /* alternate function select B */ +}; + +static inline unsigned long gpio_to_base(int gpio) +{ + return gpio_base[gpio / 32]; +} + +static inline u32 gpio_to_bit(int gpio) +{ + return 1 (gpio 0x1f); +} + +void nmk_gpio_af(int gpio, int alternate_function) +{ + unsigned long base = gpio_to_base(gpio); + u32 bit = gpio_to_bit(gpio); + u32 afunc, bfunc; + + /* alternate function is 0..3, with one bit per register */ + afunc = readl(base + GPIO_AFSLA) ~bit; + bfunc = readl(base + GPIO_AFSLB) ~bit; + if (alternate_function 1) afunc |= bit; + if (alternate_function 2) bfunc |= bit; + writel(afunc, base + GPIO_AFSLA); + writel(bfunc, base + GPIO_AFSLB); +} + +void nmk_gpio_dir(int gpio, int dir) +{ + unsigned long base = gpio_to_base(gpio); + u32 bit = gpio_to_bit(gpio); + + if (dir) + writel(bit, base + GPIO_DIRS); + else + writel(bit, base + GPIO_DIRC); +} + +void nmk_gpio_set(int gpio, int val) +{ + unsigned long base = gpio_to_base(gpio); + u32 bit = gpio_to_bit(gpio); + + if (val) + writel(bit, base + GPIO_DATS); + else + writel(bit, base + GPIO_DATC); +} + +int nmk_gpio_get(int gpio) +{ + unsigned long base = gpio_to_base(gpio); + u32 bit = gpio_to_bit(gpio); + + return readl(base + GPIO_DAT) bit; +} diff --git a/board/st/nhk8815/gpio.h b/board/st/nhk8815/gpio.h new file mode 100644 index 000..1d3c9ce --- /dev/null +++ b/board/st/nhk8815/gpio.h @@ -0,0 +1,42 @@ +/* + * (C) Copyright 2009 Alessandro Rubini + * + * 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
[U-Boot] [PATCH 2/2] arm nomadik: add i2c
From: Alessandro Rubini rub...@unipv.it Signed-off-by: Alessandro Rubini rub...@unipv.it Acked-by: Andrea Gallo andrea.ga...@stericsson.com --- board/st/nhk8815/nhk8815.c | 16 ++-- include/configs/nhk8815.h | 18 +- 2 files changed, 31 insertions(+), 3 deletions(-) diff --git a/board/st/nhk8815/nhk8815.c b/board/st/nhk8815/nhk8815.c index 085a5e0..2215ef9 100644 --- a/board/st/nhk8815/nhk8815.c +++ b/board/st/nhk8815/nhk8815.c @@ -27,6 +27,7 @@ #include common.h #include asm/io.h +#include gpio.h DECLARE_GLOBAL_DATA_PTR; @@ -61,9 +62,20 @@ int board_init(void) return 0; } -int misc_init_r(void) +int board_late_init(void) { - setenv(verify, n); + /* Set the two I2C gpio lines to be gpio high */ + nmk_gpio_set(__SCL, 1); nmk_gpio_set(__SDA, 1); + nmk_gpio_dir(__SCL, 1); nmk_gpio_dir(__SDA, 1); + nmk_gpio_af(__SCL, GPIO_GPIO); nmk_gpio_af(__SDA, GPIO_GPIO); + + /* Reset the I2C port expander, on GPIO77 */ + nmk_gpio_af(77, GPIO_GPIO); + nmk_gpio_dir(77, 1); + nmk_gpio_set(77, 0); + udelay(10); + nmk_gpio_set(77, 1); + return 0; } diff --git a/include/configs/nhk8815.h b/include/configs/nhk8815.h index 3e2e09f..165d465 100644 --- a/include/configs/nhk8815.h +++ b/include/configs/nhk8815.h @@ -93,7 +93,7 @@ #define CONFIG_SYS_GBL_DATA_SIZE 128 /* for initial data */ #define CONFIG_SYS_64BIT_VSPRINTF /* mtd desires this */ -#define CONFIG_MISC_INIT_R /* call misc_init_r during start up */ +#define BOARD_LATE_INIT/* call board_late_init during start up */ /* timing informazion */ #define CONFIG_SYS_HZ 1000 /* Mandatory... */ @@ -110,6 +110,22 @@ #define CONFIG_PL01x_PORTS { (void *)CFG_SERIAL0, (void *)CFG_SERIAL1 } #define CONFIG_PL011_CLOCK 4800 +/* i2c, for the port extenders (uses gpio.c in board directory) */ +#ifndef __ASSEMBLY__ +#include ../board/st/nhk8815/gpio.h +#define CONFIG_CMD_I2C +#define CONFIG_SOFT_I2C +#define CONFIG_SYS_I2C_SPEED 40 +#define __SDA 63 +#define __SCL 62 +#define I2C_SDA(x) nmk_gpio_set(__SDA, x) +#define I2C_SCL(x) nmk_gpio_set(__SCL, x) +#define I2C_READ (nmk_gpio_get(__SDA)!=0) +#define I2C_ACTIVE nmk_gpio_dir(__SDA, 1) +#define I2C_TRISTATE nmk_gpio_dir(__SDA, 0) +#define I2C_DELAY (udelay(2)) +#endif /* __ASSEMBLY__ */ + /* Ethernet */ #define PCI_MEMORY_VADDR 0xe800 #define PCI_IO_VADDR 0xee00 -- 1.6.0.2 ___ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot
[U-Boot] [PATCH] env_onenand: fix compiler warning for error message
From: Alessandro Rubini rub...@gnudd.com Since env_addr is a loff_t (long long), %08lx is not a good format; this uses %08llx (not %016llx), to get 8 or more hex digits. I tnknk padding to 8 digits makes things more readable for small numbers, and the unlikely values over 4GB are reported correctly anyways. Signed-off-by: Alessandro Rubini rub...@gnudd.com --- I found this during ./MAKEALL arm, and it affects my nhk8815 as well. The warning was already reported today by Dirk Behme, thus this is reply to his message. common/env_onenand.c |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/common/env_onenand.c b/common/env_onenand.c index 476fdbc..0b03537 100644 --- a/common/env_onenand.c +++ b/common/env_onenand.c @@ -101,7 +101,7 @@ int saveenv(void) instr.addr = env_addr; instr.mtd = mtd; if (mtd-erase(mtd, instr)) { - printf(OneNAND: erase failed at 0x%08lx\n, env_addr); + printf(OneNAND: erase failed at 0x%08llx\n, (u64)env_addr); return 1; } -- 1.6.0.2 ___ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot
[U-Boot] [PATCH] video: move extern declarations from C to headers
From: Alessandro Rubini rub...@gnudd.com This moves some extern declaration from lcd.c to lcd.h, removing unneeded ifdef around a pair of them. Additionally, since gunzip_bmp() was declared static in cmd_bmp.c but extern in lcd.c, I removed the static. The extra #include lcd.h in cmd_bmp.c is added to ensure the header is consistent with the source. This has been compile-tested on both ARM (at91 boards) and PowerPC (HH405_config, TQM823L_LCD_config, mcc200_config), to test all use combinations. Signed-off-by: Alessandro Rubini rub...@gnudd.it --- common/cmd_bmp.c |5 +++-- common/lcd.c | 16 include/lcd.h| 12 3 files changed, 15 insertions(+), 18 deletions(-) diff --git a/common/cmd_bmp.c b/common/cmd_bmp.c index fc8462e..faa10a4 100644 --- a/common/cmd_bmp.c +++ b/common/cmd_bmp.c @@ -26,6 +26,7 @@ */ #include common.h +#include lcd.h #include bmp_layout.h #include command.h #include asm/byteorder.h @@ -46,7 +47,7 @@ int gunzip(void *, int, unsigned char *, unsigned long *); * didn't contain a valid BMP signature. */ #ifdef CONFIG_VIDEO_BMP_GZIP -static bmp_image_t *gunzip_bmp(unsigned long addr, unsigned long *lenp) +bmp_image_t *gunzip_bmp(unsigned long addr, unsigned long *lenp) { void *dst; unsigned long len; @@ -85,7 +86,7 @@ static bmp_image_t *gunzip_bmp(unsigned long addr, unsigned long *lenp) return bmp; } #else -static bmp_image_t *gunzip_bmp(unsigned long addr, unsigned long *lenp) +bmp_image_t *gunzip_bmp(unsigned long addr, unsigned long *lenp) { return NULL; } diff --git a/common/lcd.c b/common/lcd.c index c87de0b..dc8fea6 100644 --- a/common/lcd.c +++ b/common/lcd.c @@ -79,25 +79,13 @@ static inline void lcd_putc_xy (ushort x, ushort y, uchar c); static int lcd_init (void *lcdbase); static int lcd_clear (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]); -extern void lcd_ctrl_init (void *lcdbase); -extern void lcd_enable (void); static void *lcd_logo (void); - -#if (LCD_BPP == LCD_COLOR8) || (LCD_BPP == LCD_COLOR16) -extern void lcd_setcolreg (ushort regno, - ushort red, ushort green, ushort blue); -#endif -#if LCD_BPP == LCD_MONOCHROME -extern void lcd_initcolregs (void); -#endif - static int lcd_getbgcolor (void); static void lcd_setfgcolor (int color); static void lcd_setbgcolor (int color); char lcd_is_enabled = 0; -extern vidinfo_t panel_info; #ifdef NOT_USED_SO_FAR static void lcd_getcolreg (ushort regno, @@ -815,10 +803,6 @@ int lcd_display_bitmap(ulong bmp_image, int x, int y) } #endif -#ifdef CONFIG_VIDEO_BMP_GZIP -extern bmp_image_t *gunzip_bmp(unsigned long addr, unsigned long *lenp); -#endif - static void *lcd_logo (void) { #ifdef CONFIG_SPLASH_SCREEN diff --git a/include/lcd.h b/include/lcd.h index f054cac..2de36ab 100644 --- a/include/lcd.h +++ b/include/lcd.h @@ -43,6 +43,18 @@ extern void *lcd_console_address;/* Start of console buffer */ extern short console_col; extern short console_row; +extern struct vidinfo panel_info; + +extern void lcd_ctrl_init (void *lcdbase); +extern void lcd_enable (void); + +/* setcolreg used in 8bpp/16bpp; initcolregs used in monochrome */ +extern void lcd_setcolreg (ushort regno, + ushort red, ushort green, ushort blue); +extern void lcd_initcolregs (void); + +/* gunzip_bmp used if CONFIG_VIDEO_BMP_GZIP */ +extern struct bmp_image *gunzip_bmp(unsigned long addr, unsigned long *lenp); #if defined CONFIG_MPC823 /* -- 1.6.0.2 ___ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot
[U-Boot] [PATCH] cmd_flash.c: fix compile error for boards with DataFlash
From: Alessandro Rubini rub...@gnudd.com The local variables addr_first and addr_last are used if HAS_DATAFLASH even if SYS_NO_FLASH (meaning no NOR flash). This adds the definitions withing the brace where the names are used, to avoid cluttering the initial ifdef. Signed-off-by: Alessandro Rubini rub...@gnudd.com --- 5 boards were not compiling with ./MAKEALL arm, now they all work. Actually, even at91sam9263ek_nandflash_config was in error, but it's not one of the MAKEALL targets. Should MAKEALL test all possible configs or not? common/cmd_flash.c |2 ++ 1 files changed, 2 insertions(+), 0 deletions(-) diff --git a/common/cmd_flash.c b/common/cmd_flash.c index bc651fa..4f12bbc 100644 --- a/common/cmd_flash.c +++ b/common/cmd_flash.c @@ -496,6 +496,8 @@ int do_protect (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) #ifdef CONFIG_HAS_DATAFLASH if ((strcmp(argv[2], all) != 0) (strcmp(argv[2], bank) != 0)) { + ulong addr_first, addr_last; + addr_first = simple_strtoul(argv[2], NULL, 16); addr_last = simple_strtoul(argv[3], NULL, 16); -- 1.6.0.2 ___ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot
Re: [U-Boot] [RFC]Â CONFIG naming convetion
I would think should be CONFIG_DRIVERS_PATA_BFIN I dosagree, the DRIVERS part is just added line noise. It's a name space - making sure it is differentiated from an option. Yeah, and we end up with variable names that cannot be used any more because they exceed the maximum line length. What about DRV or even D if you insist? CONFIG_D_I2C_SOFT ? I personally find the config files pretty unreadable. Options that enable a driver should be different from those that select a behaviour, in my opinion. While people responsible for their board know all the stuff they wrote, but when someone undergoes a more general code change several or all config files must be checked. A driver namespace would help, in my opionion. /alessandro ___ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot
Re: [U-Boot] [PATCH 0/2] arm nomadik: gpio and i2c
Agreed. So we need an gpio_core.c / .h which defines the following functions (just a proposal): Yes. typedef struct gpio_adapter { int (*init_pin)(int pin); int (*set)(int pin, value); int (*get)(int pin); int (*dir)(int pin, int direction); int (*level)(int pin, int level); } I don't understand the init_pin function, nor what level is. Actually, even dir can be dropped: a get configures as input, a set configures as output, the extra instruction is very little overhead. But an alternate function configuration is definitely needed: everybody has alternate functions associated to the pins. Just say 0 is gpio and 1...n is SoC-specific. So, are you going to write it? Or should someone else do that? thanks /alessandro ___ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot
Re: [U-Boot] [PATCH 0/2] arm nomadik: gpio and i2c
what with deinit_pin(pin, function)? That would be in shape with init_pin()? No, it's not clear what it is. I'd rename init to setup, adding an AF argument. So I can setup it as AF2, or as GPIO-OUT, or whatever. (There, we could also unset the marker, that this pin is no longer used for gpio ...) No, I wouldn't like the marker. It's a boot loader, it shouldn't overdo sanity checks. Most of the times it runs the same bootcmd over and over. In the rare but important case it's a debugging tool, it shouldn't force policy, in my opinion (I already have problems with the kernel gpiolib, that doesn't let me fix mishaps at will). Also, a board can have more then one gpio adapter, how we address such a case? As Wolfgang suggested, we don't. If atmel calls it PORTC-12 I have no problem calling it gpio-76 by concatentating the ports as 0..31, 32..64, ... It's still better to have a gpio command than doing mw addr val over and over. In my old-fashioned way, it should be as simple as possible, but no simpler. /alessandro ___ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot
Re: [U-Boot] U-Boot environment update in linux embedded ARM architecture
0x2 *U-Boot (2009.06)* 0x6 *U-Boot Env.* So two blocks. for u-boot, which is bigger than one block. the u-boot environment part of the u-boot code is overwritten with the environment parameters. This happens only when our NAND flash has bad blocks in the u-boot zone. (Block 1 and 2), In this case u-boot is stored in two blocks, but skipping the bad block. Your env area will contain the trailing part of u-boot binary. I'm sure your consultant already told you. /Questo messaggio ed i suoi allegati viene spedito solo alle persone indicate come destinatarie. Esso contiene informazioni confidenziali Please avoid this meaningless stuff when posting to public lists (even in private mail it sounds insulting, but that's just personal taste). /alessandro ___ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot
[U-Boot] [PATCH] lcd.h: define extern vidinfo_t for all cases
From: Alessandro Rubini rub...@gnudd.com include/lcd.h has different vidinfo for different platforms, and several extern declaration, but one for the default case was missing. This makes them a single extern declaration for everyone. Signed-off-by: Alessandro Rubini rub...@gnudd.com --- include/lcd.h |8 ++-- 1 files changed, 2 insertions(+), 6 deletions(-) diff --git a/include/lcd.h b/include/lcd.h index f054cac..8048419 100644 --- a/include/lcd.h +++ b/include/lcd.h @@ -75,8 +75,6 @@ typedef struct vidinfo { u_char vl_wbf; /* Wait between frames */ } vidinfo_t; -extern vidinfo_t panel_info; - #elif defined CONFIG_PXA250 /* * PXA LCD DMA descriptor @@ -146,8 +144,6 @@ typedef struct vidinfo { struct pxafb_info pxa; } vidinfo_t; -extern vidinfo_t panel_info; - #elif defined(CONFIG_ATMEL_LCD) typedef struct vidinfo { @@ -173,8 +169,6 @@ typedef struct vidinfo { u_long mmio; /* Memory mapped registers */ } vidinfo_t; -extern vidinfo_t panel_info; - #else typedef struct vidinfo { @@ -190,6 +184,8 @@ typedef struct vidinfo { #endif /* CONFIG_MPC823, CONFIG_PXA250 or CONFIG_MCC200 or CONFIG_ATMEL_LCD */ +extern vidinfo_t panel_info; + /* Video functions */ #if defined(CONFIG_RBC823) -- 1.6.0.2 ___ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot
[U-Boot] [PATCH] Nomadik: fix reset_timer()
From: Alessandro Rubini rub...@unipv.it The timer decrements and READ_TIMER() negates the value read. Writing 0 in reset_timer() is this wrong, as a readback before 400us will read back 0 and will report 1780 seconds, so nand operations did timeout. This patch writes ~0 in reset_timer to prevent this. Signed-off-by: Alessandro Rubini rub...@unipv.it Acked-by: Andrea Gallo andrea.ga...@stericsson.com Cc: Jean-Christophe PLAGNIOL-VILLARD plagn...@jcrosoft.com --- cpu/arm926ejs/nomadik/timer.c |4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diff --git a/cpu/arm926ejs/nomadik/timer.c b/cpu/arm926ejs/nomadik/timer.c index 16067c9..2115b71 100644 --- a/cpu/arm926ejs/nomadik/timer.c +++ b/cpu/arm926ejs/nomadik/timer.c @@ -46,10 +46,10 @@ int timer_init(void) return 0; } -/* Restart counting from 0 */ +/* Restart counting from ~0 (can't be 0, since READ_TIMER negates) */ void reset_timer(void) { - writel(0, CONFIG_SYS_TIMERBASE + MTU_LR(0)); /* Immediate effect */ + writel(~0, CONFIG_SYS_TIMERBASE + MTU_LR(0)); /* Immediate effect */ } /* Return how many HZ passed since base */ -- 1.5.6.5 ___ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot
[U-Boot] [PATCH 0/3] make memcpy and memset 32-bit copies
I've added 32-bit lcd to the Nomadik (not submitted yet), and I found the scroll to be very slow, as the screen is big. Instead of activating the if 0 stanza for 32-bit scroll in lcd.c, I'd better have a faster memcpy/memset globally. So this patch set adds 32-bit memcpy and memset and removes the #if 0 part in the scroll function. For me it's 4 times faster (help from 14s to 3.5s). I agree I should use 8-bits in u-boot, but the speedup of 32bit memcpy/memset is there regardless, as most users are 32-bit aligned anyways. Alessandro Rubini (3): memcpy: use 32-bit copies if possible memset: use 32-bit copies if possible lcd: remove '#if 0' 32-bit scroll, now memcpy does it common/lcd.c | 21 - lib_generic/string.c | 27 +-- 2 files changed, 25 insertions(+), 23 deletions(-) ___ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot
[U-Boot] [PATCH 1/3] memcpy: use 32-bit copies if possible
From: Alessandro Rubini rub...@unipv.it Signed-off-by: Alessandro Rubini rub...@unipv.it Acked-by: Andrea Gallo andrea.ga...@stericsson.com --- lib_generic/string.c | 11 ++- 1 files changed, 10 insertions(+), 1 deletions(-) diff --git a/lib_generic/string.c b/lib_generic/string.c index 181eda6..fdccab6 100644 --- a/lib_generic/string.c +++ b/lib_generic/string.c @@ -449,7 +449,16 @@ char * bcopy(const char * src, char * dest, int count) void * memcpy(void * dest,const void *src,size_t count) { char *tmp = (char *) dest, *s = (char *) src; + u32 *d32 = (u32 *)dest, *s32 = (u32 *) src; + /* if both are aligned, use 32-bit copy */ + if ( (((int)dest 3) | ((int)src 3) | (count 3)) == 0 ) { + count /= 4; + while (count--) + *d32++ = *s32++; + return dest; + } + /* else, use 1-byte copy */ while (count--) *tmp++ = *s++; -- 1.5.6.5 ___ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot
[U-Boot] [PATCH 3/3] lcd: remove '#if 0' 32-bit scroll, now memcpy does it
From: Alessandro Rubini rub...@unipv.it Signed-off-by: Alessandro Rubini rub...@unipv.it Acked-by: Andrea Gallo andrea.ga...@stericsson.com --- common/lcd.c | 21 - 1 files changed, 0 insertions(+), 21 deletions(-) diff --git a/common/lcd.c b/common/lcd.c index dc8fea6..4e31618 100644 --- a/common/lcd.c +++ b/common/lcd.c @@ -99,32 +99,11 @@ static int lcd_getfgcolor (void); static void console_scrollup (void) { -#if 1 /* Copy up rows ignoring the first one */ memcpy (CONSOLE_ROW_FIRST, CONSOLE_ROW_SECOND, CONSOLE_SCROLL_SIZE); /* Clear the last one */ memset (CONSOLE_ROW_LAST, COLOR_MASK(lcd_color_bg), CONSOLE_ROW_SIZE); -#else - /* -* Poor attempt to optimize speed by moving longs. -* But the code is ugly, and not a bit faster :-( -*/ - ulong *t = (ulong *)CONSOLE_ROW_FIRST; - ulong *s = (ulong *)CONSOLE_ROW_SECOND; - ulongl = CONSOLE_SCROLL_SIZE / sizeof(ulong); - uchar c = lcd_color_bg 0xFF; - ulong val= (c24) | (c16) | (c8) | c; - - while (l--) - *t++ = *s++; - - t = (ulong *)CONSOLE_ROW_LAST; - l = CONSOLE_ROW_SIZE / sizeof(ulong); - - while (l-- 0) - *t++ = val; -#endif } /*--*/ -- 1.5.6.5 ___ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot
[U-Boot] [PATCH 2/3] memset: use 32-bit copies if possible
From: Alessandro Rubini rub...@unipv.it Signed-off-by: Alessandro Rubini rub...@unipv.it Acked-by: Andrea Gallo andrea.ga...@stericsson.com --- lib_generic/string.c | 16 +++- 1 files changed, 15 insertions(+), 1 deletions(-) diff --git a/lib_generic/string.c b/lib_generic/string.c index fdccab6..68e0255 100644 --- a/lib_generic/string.c +++ b/lib_generic/string.c @@ -404,7 +404,21 @@ char *strswab(const char *s) void * memset(void * s,int c,size_t count) { char *xs = (char *) s; + u32 *s32 = (u32 *) s; + int c32 = 0; /* most common case */ + /* do it 32 bits at a time if possible */ + if ( ((count 3) | ((int)s 3)) == 0) { + count /= 4; + if (c) { /* not 0: build 32-bit value */ + c32 = c | (c8); + c32 |= c32 16; + } + while (count--) + *s32++ = c32; + return s; + } + /* else, fill 8 bits at a time */ while (count--) *xs++ = c; -- 1.5.6.5 ___ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot
Re: [U-Boot] [PATCH 1/3] memcpy: use 32-bit copies if possible
while 64bit isnt in today, might as well avoid unclean code from the start when possible. in other words, used unsigned int rather than u32 and cast to unsigned long rather than int. You are right. Will do. +count /= 4; count = 2 ? although gcc probably optimizes this properly. gcc-4.0 for arm already turns it into a shift. I'll use sizeof(unsigned long) in version 2. Thanks /alessandro ___ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot
Re: [U-Boot] [PATCH 1/3] memcpy: use 32-bit copies if possible
I was making my v2, and I found a problem wrt: while 64bit isnt in today, might as well avoid unclean code from the start when possible. in other words, used unsigned int rather than u32 and cast to unsigned long rather than int. Since int is 32 also on 64bit systems, I used unsigned long. For memcpy all is well, for memset I have this problem: void * memset(void * s,int c,size_t count) { char *xs = (char *) s; unsigned long *sl = (unsigned long *) s; unsigned long cl; /* do it one word at a time (32 bits or 64 bits) if possible */ if ( ((count | (int)s) (sizeof(long) - 1)) == 0) { count /= sizeof(long); cl = (c 0xff) | ((c 0xff) 8); cl |= cl 16; if (sizeof(long) 4) cl |= cl 32; while (count--) *sl++ = cl; return s; } /* else, fill 8 bits at a time */ while (count--) *xs++ = c; return s; } string.c:416: warning: left shift count = width of type (obviously there is no such shift in the generated code, since the condition is false at compile time). I think I'll stick to u32 for memset, unless I get better suggestions. /alessandro ___ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot
[U-Boot] [PATCH V2 0/3] make memcpy and memset faster
I've added 32-bit lcd to the Nomadik (not submitted yet), and I found the scroll to be very slow, as the screen is big. Instead of activating the if 0 stanza for 32-bit scroll in lcd.c, I'd better have a faster memcpy/memset globally. So this patch set adds ulong-wide memcpy and memset, then removes the #if 0 part in the scroll function. For me scrolling is 4 times faster on a 32 bit system. V2: I incorporated most of the comments, but I didn't change the for loops to help the compiler optimizing it, since nowadays gcc is already doing the loops his own way irrespective of what i write. Similarly, I'm not interested in 4 bytes at a time, then 1 at a time as it's quite a corner case. If such optimizations are really useful, then we'd better have hand-crafted assembly for each arch, possibly lifted from glibc. Alessandro Rubini (3): memcpy: copy one word at a time if possible memset: fill one word at a time if possible lcd: remove '#if 0' 32-bit scroll, now memcpy does it common/lcd.c | 21 - lib_generic/string.c | 34 +- 2 files changed, 29 insertions(+), 26 deletions(-) ___ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot
[U-Boot] [PATCH V2 1/3] memcpy: copy one word at a time if possible
From: Alessandro Rubini rub...@unipv.it Signed-off-by: Alessandro Rubini rub...@unipv.it Acked-by: Andrea Gallo andrea.ga...@stericsson.com --- lib_generic/string.c | 17 + 1 files changed, 13 insertions(+), 4 deletions(-) diff --git a/lib_generic/string.c b/lib_generic/string.c index 181eda6..9911941 100644 --- a/lib_generic/string.c +++ b/lib_generic/string.c @@ -446,12 +446,21 @@ char * bcopy(const char * src, char * dest, int count) * You should not use this function to access IO space, use memcpy_toio() * or memcpy_fromio() instead. */ -void * memcpy(void * dest,const void *src,size_t count) +void * memcpy(void *dest, const void *src, size_t count) { - char *tmp = (char *) dest, *s = (char *) src; + char *d8 = (char *)dest, *s8 = (char *)src; + unsigned long *dl = (unsigned long *)dest, *sl = (unsigned long *)src; + /* if all data is aligned (common case), copy a word at a time */ + if ( (((int)dest | (int)src | count) (sizeof(long) - 1)) == 0) { + count /= sizeof(unsigned long); + while (count--) + *dl++ = *sl++; + return dest; + } + /* else, use 1-byte copy */ while (count--) - *tmp++ = *s++; + *d8++ = *s8++; return dest; } -- 1.6.0.2 ___ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot
[U-Boot] [PATCH V2 2/3] memset: fill one word at a time if possible
From: Alessandro Rubini rub...@unipv.it Signed-off-by: Alessandro Rubini rub...@unipv.it Acked-by: Andrea Gallo andrea.ga...@stericsson.com --- lib_generic/string.c | 17 - 1 files changed, 16 insertions(+), 1 deletions(-) diff --git a/lib_generic/string.c b/lib_generic/string.c index 9911941..5f7aff9 100644 --- a/lib_generic/string.c +++ b/lib_generic/string.c @@ -404,7 +404,22 @@ char *strswab(const char *s) void * memset(void * s,int c,size_t count) { char *xs = (char *) s; - + unsigned long *sl = (unsigned long *) s; + unsigned long cl = 0; + int i; + + /* do it one word at a time (32 bits or 64 bits) if possible */ + if ( ((count | (int)s) (sizeof(long) - 1)) == 0) { + count /= sizeof(long); + for (i=0; isizeof(long); ++i) { + cl = 8; + cl |= c 0xff; + } + while (count--) + *sl++ = cl; + return s; + } + /* else, fill 8 bits at a time */ while (count--) *xs++ = c; -- 1.6.0.2 ___ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot
[U-Boot] [PATCH V2 3/3] lcd: remove '#if 0' 32-bit scroll, now memcpy does it
From: Alessandro Rubini rub...@unipv.it Signed-off-by: Alessandro Rubini rub...@unipv.it Acked-by: Andrea Gallo andrea.ga...@stericsson.com --- common/lcd.c | 21 - 1 files changed, 0 insertions(+), 21 deletions(-) diff --git a/common/lcd.c b/common/lcd.c index dc8fea6..4e31618 100644 --- a/common/lcd.c +++ b/common/lcd.c @@ -99,32 +99,11 @@ static int lcd_getfgcolor (void); static void console_scrollup (void) { -#if 1 /* Copy up rows ignoring the first one */ memcpy (CONSOLE_ROW_FIRST, CONSOLE_ROW_SECOND, CONSOLE_SCROLL_SIZE); /* Clear the last one */ memset (CONSOLE_ROW_LAST, COLOR_MASK(lcd_color_bg), CONSOLE_ROW_SIZE); -#else - /* -* Poor attempt to optimize speed by moving longs. -* But the code is ugly, and not a bit faster :-( -*/ - ulong *t = (ulong *)CONSOLE_ROW_FIRST; - ulong *s = (ulong *)CONSOLE_ROW_SECOND; - ulongl = CONSOLE_SCROLL_SIZE / sizeof(ulong); - uchar c = lcd_color_bg 0xFF; - ulong val= (c24) | (c16) | (c8) | c; - - while (l--) - *t++ = *s++; - - t = (ulong *)CONSOLE_ROW_LAST; - l = CONSOLE_ROW_SIZE / sizeof(ulong); - - while (l-- 0) - *t++ = val; -#endif } /*--*/ -- 1.6.0.2 ___ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot
[U-Boot] [PATCH] setenv: do console redirection even if previously unset
From: Alessandro Rubini rub...@unipv.it If stdout is not previously set, doing setenv stdout lcd had no effect, since console redirection only worked if the environment variable was already set; the second time you run setenv it worked. Most default environments lack stdin/out/err definitions, so I'm sure I'm not alone with this problem. This patch simply moves a block of code out of a conditional, to do the same work even if the variable was previously unset. Signed-off-by: Alessandro Rubini rub...@unipv.it Acked-by: Andrea Gallo andrea.ga...@stericsson.com --- common/cmd_nvedit.c | 62 +- 1 files changed, 31 insertions(+), 31 deletions(-) diff --git a/common/cmd_nvedit.c b/common/cmd_nvedit.c index 2186205..9f8d531 100644 --- a/common/cmd_nvedit.c +++ b/common/cmd_nvedit.c @@ -202,6 +202,37 @@ int _do_setenv (int flag, int argc, char *argv[]) break; } + /* Check for console redirection */ + if (strcmp(name,stdin) == 0) { + console = stdin; + } else if (strcmp(name,stdout) == 0) { + console = stdout; + } else if (strcmp(name,stderr) == 0) { + console = stderr; + } + + if (console != -1) { + if (argc 3) { /* Cannot delete it! */ + printf(Can't delete \%s\\n, name); + return 1; + } + +#ifdef CONFIG_CONSOLE_MUX + i = iomux_doenv(console, argv[2]); + if (i) + return i; +#else + /* Try assigning specified device */ + if (console_assign (console, argv[2]) 0) + return 1; + +#ifdef CONFIG_SERIAL_MULTI + if (serial_assign (argv[2]) 0) + return 1; +#endif +#endif /* CONFIG_CONSOLE_MUX */ + } + /* * Delete any existing definition */ @@ -229,37 +260,6 @@ int _do_setenv (int flag, int argc, char *argv[]) } #endif - /* Check for console redirection */ - if (strcmp(name,stdin) == 0) { - console = stdin; - } else if (strcmp(name,stdout) == 0) { - console = stdout; - } else if (strcmp(name,stderr) == 0) { - console = stderr; - } - - if (console != -1) { - if (argc 3) { /* Cannot delete it! */ - printf(Can't delete \%s\\n, name); - return 1; - } - -#ifdef CONFIG_CONSOLE_MUX - i = iomux_doenv(console, argv[2]); - if (i) - return i; -#else - /* Try assigning specified device */ - if (console_assign (console, argv[2]) 0) - return 1; - -#ifdef CONFIG_SERIAL_MULTI - if (serial_assign (argv[2]) 0) - return 1; -#endif -#endif /* CONFIG_CONSOLE_MUX */ - } - /* * Switch to new baudrate if new baudrate is supported */ -- 1.6.0.2 ___ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot
Re: [U-Boot] [PATCH V2 1/3] memcpy: copy one word at a time if possible
No interest in the suggestion to not require count to be an exact multiple of 4/8? Actually, I wrote about that in my patch 0/3. I don't think it would be that hard to update the logic accordingly and this would let your code be utilized much more often, especially if/when we run on a 64-bit machine. That's true, but I think the most important case is lcd scrolling, where it's usually a big power of two -- that's where we had the #ifdef, so the problem was known, I suppose. Currently, I don't even know if this is going to be picked up, so I don't want to go too far -- and in that case I would like to measure things and be able to test for stupid bugs, so it takes time. Scrolling the video is an easy test for memcpy. If there's interest, there's memmov to fix; it's used pretty often and it's the same idea as memcpy (well, scrolling should use memmove, in theory). /alessandro ___ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot
Re: [U-Boot] [PATCH V2 1/3] memcpy: copy one word at a time if possible
That's true, but I think the most important case is lcd scrolling, where it's usually a big power of two -- that's where we had the #ifdef, so the problem was known, I suppose. I think the most important case for *you* is lcd scrolling, but for 99% of everyone else, it isn't at all:) Well, its a big memcpy, and it has direct effect on the user. Every other copy is smaller, or has no interactive value. memcpy() and memset() are used 100 times more often in non-lcd related code and most boards don't even have LCDs. That's true. But it's only a boot loader (I just looked at what Nicolas Pitre did in the kernel for ARM strcpy and, well). So I made some measures (it's one of Pike's rules of programming: * Rule 2. Measure. Don't tune for speed until you've measured, and even then don't unless one part of the code overwhelms the rest. ) I booted in u-boot, typed setenv stdout serial then boot, which goes over the ethernet. Stopped the system after u-boot gave over control to the kernel. Result: 10412 memcopies so divided (number, length): 3941 4 1583 6 772 20 1 46 1 47 3 60 1024 64 1 815 1 888 770 1148 1543 1480 1 2283 1 3836 770 4096 So I dare say non-power-of-4 is a minority anyways: 1587 calls, 12689 bytes. i.e. 15.2% of the calls and 0.2% of the data. Data collected in memory with patch below, used with following line: od -An -t d4 logfile | awk '{print $4}' | sort -n | uniq -c diff --git a/include/configs/nhk8815.h b/include/configs/nhk8815.h index edd698e..a390f28 100644 --- a/include/configs/nhk8815.h +++ b/include/configs/nhk8815.h @@ -28,6 +28,8 @@ #include nomadik.h +#define CONFIG_MCLOGSIZE (16*1024) + #define CONFIG_ARM926EJS #define CONFIG_NOMADIK #define CONFIG_NOMADIK_8815/* cpu variant */ diff --git a/lib_generic/string.c b/lib_generic/string.c index 5f7aff9..5afa11e 100644 --- a/lib_generic/string.c +++ b/lib_generic/string.c @@ -19,6 +19,7 @@ #include linux/string.h #include linux/ctype.h #include malloc.h +#include common.h #if 0 /* not used - was: #ifndef __HAVE_ARCH_STRNICMP */ @@ -461,11 +462,29 @@ char * bcopy(const char * src, char * dest, int count) * You should not use this function to access IO space, use memcpy_toio() * or memcpy_fromio() instead. */ + +#ifndef CONFIG_MCLOGSIZE /* if you want to log the memcpy calls, define it */ +#define CONFIG_MCLOGSIZE 0 +#endif +struct mclog {int idx; void *dst; const void *src; int cnt;}; +static struct mclog mclog[CONFIG_MCLOGSIZE]; + void * memcpy(void *dest, const void *src, size_t count) { char *d8 = (char *)dest, *s8 = (char *)src; unsigned long *dl = (unsigned long *)dest, *sl = (unsigned long *)src; + if (CONFIG_MCLOGSIZE) { + static int idx; + struct mclog *p = mclog + (idx % (CONFIG_MCLOGSIZE ?: 1)); + if (!idx) printf(memcpy log at %p, size 0x%x\n, +mclog, sizeof(mclog)); + p-idx = idx++; + p-dst = dest; + p-src = src; + p-cnt = count; + } + /* if all data is aligned (common case), copy a word at a time */ if ( (((int)dest | (int)src | count) (sizeof(long) - 1)) == 0) { count /= sizeof(unsigned long); ___ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot
Re: [U-Boot] [PATCH V2 1/3] memcpy: copy one word at a time if possible
The statistics are going to be very different for different scenarios. Yes, I know. For example, network operations seem to be the majority of your large memcpys, this isn't the case for everyone. True. I noticed it after sending -- although I expected it. In any case, my only suggestion would be that if we're improving memcpy()/memset(), do the extra 10% of effort required to make them a little better. That 10% of effort will improve 15.2% of all memcpy() calls for the foreseeable future:) It mainly depends on Wolfgang but, hey, it's not 10% of effort. I promise I won't comment on future patches:) No problem at all. And I apologize if my tone looked rude, it wasn't meant to. Thank you for your comments. /alessandro, who didn't notice ppc has an asm implementation of its own ___ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot
[U-Boot] [PATCH V3 1/3] lib_generic memcpy: copy one word at a time if possible
From: Alessandro Rubini rub...@unipv.it If source and destination are aligned, this copies ulong values until possible, trailing part is copied by byte. Thanks for the details to Wolfgang Denk, Mike Frysinger, Peter Tyser, Chris Moore. Signed-off-by: Alessandro Rubini rub...@unipv.it Acked-by: Andrea Gallo andrea.ga...@stericsson.com --- lib_generic/string.c | 19 +++ 1 files changed, 15 insertions(+), 4 deletions(-) diff --git a/lib_generic/string.c b/lib_generic/string.c index 181eda6..9bee79b 100644 --- a/lib_generic/string.c +++ b/lib_generic/string.c @@ -446,12 +446,23 @@ char * bcopy(const char * src, char * dest, int count) * You should not use this function to access IO space, use memcpy_toio() * or memcpy_fromio() instead. */ -void * memcpy(void * dest,const void *src,size_t count) +void * memcpy(void *dest, const void *src, size_t count) { - char *tmp = (char *) dest, *s = (char *) src; - + unsigned long *dl = (unsigned long *)dest, *sl = (unsigned long *)src; + char *d8, *s8; + + /* while all data is aligned (common case), copy a word at a time */ + if ( (((ulong)dest | (ulong)src | count) (sizeof(*dl) - 1)) == 0) { + while (count = sizeof(*dl)) { + *dl++ = *sl++; + count -= sizeof(*dl); + } + } + /* copy the reset one byte at a time */ + d8 = (char *)dl; + s8 = (char *)sl; while (count--) - *tmp++ = *s++; + *d8++ = *s8++; return dest; } -- 1.5.6.5 ___ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot
[U-Boot] [PATCH V3 2/3] lib_generic memset: fill one word at a time if possible
From: Alessandro Rubini rub...@unipv.it If the destination is aligned, fill ulong values until possible. Then fill remaining part by bytes. Signed-off-by: Alessandro Rubini rub...@unipv.it Acked-by: Andrea Gallo andrea.ga...@stericsson.com --- lib_generic/string.c | 22 +++--- 1 files changed, 19 insertions(+), 3 deletions(-) diff --git a/lib_generic/string.c b/lib_generic/string.c index 9bee79b..1575c63 100644 --- a/lib_generic/string.c +++ b/lib_generic/string.c @@ -403,10 +403,26 @@ char *strswab(const char *s) */ void * memset(void * s,int c,size_t count) { - char *xs = (char *) s; - + unsigned long *sl = (unsigned long *) s; + unsigned long cl = 0; + char *s8; + int i; + + /* do it one word at a time (32 bits or 64 bits) while possible */ + if ( ((count | (ulong)s) (sizeof(*sl) - 1)) == 0) { + for (i=0; isizeof(*sl); ++i) { + cl = 8; + cl |= c 0xff; + } + while (count = sizeof(*sl)) { + *sl++ = cl; + count -= sizeof(*sl); + } + } + /* fill 8 bits at a time */ + s8 = (char *)sl; while (count--) - *xs++ = c; + *s8++ = c; return s; } -- 1.5.6.5 ___ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot
[U-Boot] [PATCH V3 3/3] lcd: remove '#if 0' 32-bit scroll, now memcpy does it
Actually, we should use memmove here, as areas overlap, but memmove is not yet optimized. From: Alessandro Rubini rub...@unipv.it Signed-off-by: Alessandro Rubini rub...@unipv.it Acked-by: Andrea Gallo andrea.ga...@stericsson.com --- common/lcd.c | 21 - 1 files changed, 0 insertions(+), 21 deletions(-) diff --git a/common/lcd.c b/common/lcd.c index dc8fea6..4e31618 100644 --- a/common/lcd.c +++ b/common/lcd.c @@ -99,32 +99,11 @@ static int lcd_getfgcolor (void); static void console_scrollup (void) { -#if 1 /* Copy up rows ignoring the first one */ memcpy (CONSOLE_ROW_FIRST, CONSOLE_ROW_SECOND, CONSOLE_SCROLL_SIZE); /* Clear the last one */ memset (CONSOLE_ROW_LAST, COLOR_MASK(lcd_color_bg), CONSOLE_ROW_SIZE); -#else - /* -* Poor attempt to optimize speed by moving longs. -* But the code is ugly, and not a bit faster :-( -*/ - ulong *t = (ulong *)CONSOLE_ROW_FIRST; - ulong *s = (ulong *)CONSOLE_ROW_SECOND; - ulongl = CONSOLE_SCROLL_SIZE / sizeof(ulong); - uchar c = lcd_color_bg 0xFF; - ulong val= (c24) | (c16) | (c8) | c; - - while (l--) - *t++ = *s++; - - t = (ulong *)CONSOLE_ROW_LAST; - l = CONSOLE_ROW_SIZE / sizeof(ulong); - - while (l-- 0) - *t++ = val; -#endif } /*--*/ -- 1.5.6.5 ___ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot
Re: [U-Boot] [PATCH V3 1/3] lib_generic memcpy: copy one word at a time if possible
i think you want to drop the count from the list, otherwise we dont consume the leading groups of 4 bytes if count isnt a multiple of 4. Yes, same for memset. See Wolfgang it was not 10% more? These micro optimizations are hairy, as you need to measure them to make sure they work. Ok, V4 tomorrow. /alessandro ___ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot
[U-Boot] [PATCH 2/8] include/nomadik.h: add physical address for cldc
From: Alessandro Rubini rub...@unipv.it Signed-off-by: Alessandro Rubini rub...@unipv.it Acked-by: Andrea Gallo andrea.ga...@stericsson.com --- include/nomadik.h |1 + 1 files changed, 1 insertions(+), 0 deletions(-) diff --git a/include/nomadik.h b/include/nomadik.h index d9405fd..ea65b2d 100644 --- a/include/nomadik.h +++ b/include/nomadik.h @@ -4,6 +4,7 @@ #define __NOMADIK_H__ /* Base addresses of our peripherals */ +#define NOMADIK_CLCDC_BASE 0x1012 /* CLCD Controller */ #define NOMADIK_SRC_BASE 0x101E /* System and Reset Cnt */ #define NOMADIK_PMU_BASE 0x101E9000 /* Power Management Unit */ #define NOMADIK_MPMC_BASE 0x1011 /* SDRAM Controller */ -- 1.6.0.2 ___ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot
[U-Boot] [PATCH 3/8] drivers/misc: add stmpe2401 port extender and keypad controller
From: Alessandro Rubini rub...@unipv.it Signed-off-by: Alessandro Rubini rub...@unipv.it Acked-by: Andrea Gallo andrea.ga...@stericsson.com --- drivers/misc/Makefile|1 + drivers/misc/stmpe2401.c | 176 ++ include/stmpe2401.h | 66 + 3 files changed, 243 insertions(+), 0 deletions(-) create mode 100644 drivers/misc/stmpe2401.c create mode 100644 include/stmpe2401.h diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile index f6df60f..76c009a 100644 --- a/drivers/misc/Makefile +++ b/drivers/misc/Makefile @@ -30,6 +30,7 @@ COBJS-$(CONFIG_DS4510) += ds4510.o COBJS-$(CONFIG_FSL_LAW) += fsl_law.o COBJS-$(CONFIG_NS87308) += ns87308.o COBJS-$(CONFIG_STATUS_LED) += status_led.o +COBJS-$(CONFIG_STMPE2401) += stmpe2401.o COBJS-$(CONFIG_TWL4030_LED) += twl4030_led.o COBJS := $(COBJS-y) diff --git a/drivers/misc/stmpe2401.c b/drivers/misc/stmpe2401.c new file mode 100644 index 000..9bab1b4 --- /dev/null +++ b/drivers/misc/stmpe2401.c @@ -0,0 +1,176 @@ +/* + * board/st/nhk8815/egpio.c: extended gpio as found on nhk8815 board + * + * Copyright 2009 Alessandro Rubini rub...@unipv.it + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ +#include common.h +#include i2c.h +#include stmpe2401.h + +/* + * First, an interface to set and read registers, used in this file as well + */ +int pe_getreg(int addr, int reg) +{ + unsigned char val8 = reg; + int ret; + + ret = i2c_read(addr, reg, 1 /* len */, val8, 1); + if (ret 0) return ret; + return val8; +} + +int pe_setreg(int addr, int reg, int val) +{ + unsigned char val8 = val; + + return i2c_write(addr, reg, 1, val8, 1); +} + +/* + * Generic higher-level GPIO interface + */ +int pe_gpio_af(int addr, int pin, int af) +{ + int regval; + + regval = pe_getreg(addr, PE_GPIO_AFR(pin)); + if (regval 0) return regval; + regval = ~PE_GPIO_AF_MASK(pin); + regval |= af PE_GPIO_AF_SHIFT(pin); + return pe_setreg(addr, PE_GPIO_AFR(pin), regval); +} + +int pe_gpio_dir(int addr, int pin, int dir) +{ + int regval; + + /* 0 == input, 1 == output */ + regval = pe_getreg(addr, PE_GPIO_GPDR(pin)); + if (regval 0) return regval; + regval = ~PE_GPIO_MASK(pin); + if (dir) regval |= PE_GPIO_MASK(pin); + return pe_setreg(addr, PE_GPIO_GPDR(pin), regval); +} + +int pe_gpio_pud(int addr, int pin, int pu, int pd) +{ + int regval, mask = PE_GPIO_MASK(pin); + + /* change pullup */ + regval = pe_getreg(addr, PE_GPIO_GPPUR(pin)); + if (regval 0) return regval; + if (pu) regval |= mask; + else regval = ~mask; + regval = pe_setreg(addr, PE_GPIO_GPPUR(pin), regval); + if (regval 0) return regval; + + /* change pulldown */ + regval = pe_getreg(addr, PE_GPIO_GPPDR(pin)); + if (regval 0) return regval; + if (pu) regval |= mask; + else regval = ~mask; + regval = pe_setreg(addr, PE_GPIO_GPPDR(pin), regval); + if (regval 0) return regval; + + return 0; +} + +int pe_gpio_set(int addr, int pin, int val) +{ + int reg; + + if (val) reg = PE_GPIO_GPSR(pin); + else reg = PE_GPIO_GPCR(pin); + + return pe_setreg(addr, reg, PE_GPIO_MASK(pin)); +} + +int pe_gpio_get(int addr, int pin) +{ + int regval; + + regval = pe_getreg(addr, PE_GPIO_GPMR(pin)); + if (regval 0) return regval; + return (regval PE_GPIO_MASK(pin)) ? 1 : 0; +} + +/* + * Generic higher-level keypad interface: we have 12 rows out, 8 columns in + */ +int pe_kpc_init(int addr, int rowmask, int colmask, int debounce_ms) +{ + int i; + /* note that gpio15 is missing in the rows, so use tables */ + static unsigned char row_to_gpio[12] = { + 8, 9, 10, 11, 12, 13, 14, 16, 17, 18, 19, 20}; + static unsigned char col_to_gpio[8] = { + 0, 1, 2, 3, 4, 5, 6, 7}; + + /* First, configure pins for alternate functions (and pullup) */ + for (i = 0; i ARRAY_SIZE(row_to_gpio); i++) { + if (rowmask (1 i)) { + pe_gpio_dir(addr, row_to_gpio[i], 1 /* out
[U-Boot] [PATCH 4/8] nhk8815.h: define we need stmpe
From: Alessandro Rubini rub...@unipv.it Signed-off-by: Alessandro Rubini rub...@unipv.it Acked-by: Andrea Gallo andrea.ga...@stericsson.com --- include/configs/nhk8815.h |7 ++- 1 files changed, 6 insertions(+), 1 deletions(-) diff --git a/include/configs/nhk8815.h b/include/configs/nhk8815.h index a00c2fb..e1be45b 100644 --- a/include/configs/nhk8815.h +++ b/include/configs/nhk8815.h @@ -110,7 +110,7 @@ #define CONFIG_PL01x_PORTS { (void *)CFG_SERIAL0, (void *)CFG_SERIAL1 } #define CONFIG_PL011_CLOCK 4800 -/* i2c, for the port extenders (uses gpio.c in board directory) */ +/* i2c, for the stmpe2401 port extenders (uses gpio.c in board directory) */ #ifndef __ASSEMBLY__ #include asm/arch/gpio.h #define CONFIG_CMD_I2C @@ -126,6 +126,11 @@ #define I2C_DELAY (udelay(2)) #endif /* __ASSEMBLY__ */ +/* Activate port extenders and define their i2c address */ +#define CONFIG_STMPE2401 +#define STMPE0 0x43 +#define STMPE1 0x44 + /* Ethernet */ #define PCI_MEMORY_VADDR 0xe800 #define PCI_IO_VADDR 0xee00 -- 1.6.0.2 ___ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot
[U-Boot] [PATCH 5/8] lcd: make 16bpp work
From: Alessandro Rubini rub...@unipv.it Signed-off-by: Alessandro Rubini rub...@unipv.it Acked-by: Andrea Gallo andrea.ga...@stericsson.com --- common/lcd.c | 26 -- 1 files changed, 20 insertions(+), 6 deletions(-) diff --git a/common/lcd.c b/common/lcd.c index 4e31618..d05c025 100644 --- a/common/lcd.c +++ b/common/lcd.c @@ -63,7 +63,7 @@ // #ifdef CONFIG_LCD_LOGO # include bmp_logo.h /* Get logo data, width and height */ -# if (CONSOLE_COLOR_WHITE = BMP_LOGO_OFFSET) +# if (CONSOLE_COLOR_WHITE = BMP_LOGO_OFFSET) (LCD_BPP != LCD_COLOR16) # error Default Color Map overlaps with Logo Color Map # endif #endif @@ -244,10 +244,12 @@ static void lcd_drawchars (ushort x, ushort y, uchar *str, int count) bits = 1; } #elif LCD_BPP == LCD_COLOR16 - for (c=0; c16; ++c) { - *d++ = (bits 0x80) ? - lcd_color_fg : lcd_color_bg; - bits = 1; + { + u16 *d = (u16 *)dest; + for (c=0; c8; ++c) { + *d++ = (bits 0x80) ? 0x : 0; + bits = 1; + } } #endif } @@ -529,6 +531,13 @@ void bitmap_plot (int x, int y) cmap = (ushort *)(cp-lcd_cmap[BMP_LOGO_OFFSET*sizeof(ushort)]); #elif defined(CONFIG_ATMEL_LCD) cmap = (uint *) (panel_info.mmio + ATMEL_LCDC_LUT(0)); +#else + /* +* default case: generic system with no cmap (most likely 16bpp) +* We set cmap to the source palette, so no change is done. +* This avoids even more ifdef in the next stanza +*/ + cmap = bmp_logo_palette; #endif WATCHDOG_RESET(); @@ -567,10 +576,15 @@ void bitmap_plot (int x, int y) } } else { /* true color mode */ + u16 col16; fb16 = (ushort *)(lcd_base + y * lcd_line_length + x); for (i=0; iBMP_LOGO_HEIGHT; ++i) { for (j=0; jBMP_LOGO_WIDTH; j++) { - fb16[j] = bmp_logo_palette[(bmap[j])]; + col16 = bmp_logo_palette[(bmap[j]-16)]; + fb16[j] = + ((col16 0x000F) 1) | + ((col16 0x00F0) 3) | + ((col16 0x0F00) 4); } bmap += BMP_LOGO_WIDTH; fb16 += panel_info.vl_col; -- 1.6.0.2 ___ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot
[U-Boot] [PATCH 0/8] ARM Nomadik: video and keypad for nhk8815 (and RFC inside)
This adds support for display and keypad on the Nomadik evaluation kit. I tried to split the changes as best as I can. First the amba-lcd is added as a generic driver, although it receives pre-computed register values, as it misses the code to assemble register bits from higher-level parameters. I think it acceptable for a boot loader, although it could be better. Then, I add the STMicro Port Extender 2401 as a separete driver. It's an i2c-driven port extender found on the evaluation kit; I coded it in order for other boards to use the code if needed. common/lcd.c is a ifdef hell, and I had a hard time adding 32bpp support. Howerver, it was not something I could submit, because it was even worse with ifdef than now, so I turned to 16bpp. 16bpp wasn't working either, so I tried to fix it. This is definitely suboptimal, and I need help in making it right. Fortunately only the mimc200 uses 16bpp so any issues should be easy to fix. The mimc200 uses CONFIG_ATMEL_LCD, actually, so it falls on different ifdefs than me. May I tell that I'd better remove ATMEL_LCD from common/lcd.c and push specifics in a separate file? Is that task worth endorsing? I think once atmel is out of the way, the other specific clases (pxa and little ore) should be easy, so lcd.c can finally be made more maintainable. Will we do that? BTW: I know the name make 16bpp work is not suitable for upstream, but since I expect at least a V2 series to be needed, I'd better avoid renaming it at this point. Similarly, there are no comments within each patch, I'll split this explanation in proper places for V2. Alessandro Rubini (8): video: add amba-clcd prime-cell include/nomadik.h: add physical address for cldc drivers/misc: add stmpe2401 port extender and keypad controller nhk8815.h: define we need stmpe lcd: make 16bpp work nhk8815: added keypad nhk8815: start lower in RAM, so the 800x480 frame buffer fits nhk8815: added lcd support board/st/nhk8815/Makefile |6 +- board/st/nhk8815/config.mk |7 +- board/st/nhk8815/keypad.c | 100 + board/st/nhk8815/lcd.c | 89 ++ board/st/nhk8815/nhk8815.c |9 ++ common/lcd.c | 26 +-- drivers/misc/Makefile |1 + drivers/misc/stmpe2401.c | 176 drivers/video/Makefile |1 + drivers/video/amba.c | 86 + include/amba_clcd.h| 85 + include/configs/nhk8815.h | 20 +- include/nomadik.h |1 + include/stmpe2401.h| 66 14 files changed, 660 insertions(+), 13 deletions(-) create mode 100644 board/st/nhk8815/keypad.c create mode 100644 board/st/nhk8815/lcd.c create mode 100644 drivers/misc/stmpe2401.c create mode 100644 drivers/video/amba.c create mode 100644 include/amba_clcd.h create mode 100644 include/stmpe2401.h ___ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot
[U-Boot] [PATCH 6/8] nhk8815: added keypad
From: Alessandro Rubini rub...@unipv.it Signed-off-by: Alessandro Rubini rub...@unipv.it Acked-by: Andrea Gallo andrea.ga...@stericsson.com --- board/st/nhk8815/Makefile |5 ++- board/st/nhk8815/keypad.c | 100 board/st/nhk8815/nhk8815.c |5 ++ include/configs/nhk8815.h |3 + 4 files changed, 112 insertions(+), 1 deletions(-) create mode 100644 board/st/nhk8815/keypad.c diff --git a/board/st/nhk8815/Makefile b/board/st/nhk8815/Makefile index b37fe53..1bb1d2c 100644 --- a/board/st/nhk8815/Makefile +++ b/board/st/nhk8815/Makefile @@ -29,7 +29,10 @@ include $(TOPDIR)/config.mk LIB= $(obj)lib$(BOARD).a -COBJS := nhk8815.o +COBJS-y:= nhk8815.o +COBJS-$(CONFIG_NHK8815_KEYPAD) += keypad.o + +COBJS := $(COBJS-y) SOBJS := platform.o SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) diff --git a/board/st/nhk8815/keypad.c b/board/st/nhk8815/keypad.c new file mode 100644 index 000..1753cd1 --- /dev/null +++ b/board/st/nhk8815/keypad.c @@ -0,0 +1,100 @@ +/* + * board/st/nhk8815/keypad.c: keypad on nhk8815 board, based on STMPE2401 + * + * Copyright 2009 Alessandro Rubini rub...@unipv.it + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ +#include common.h +#include stdio_dev.h +#include i2c.h +#include stmpe2401.h + +/* + * Keymap for our 4x4 matrix: since we have just + * a few keys, use a string for each of the keys. + */ +static char *keymap[4][4] = { + {, back, ffw, left}, + {, tvout, playpause, right}, + {vol-, lock, rew, up}, + {vol+, start, ok, down} +}; + +/* this keeps track of the string being returned */ +static char *nextchar = ; + +/* This getc can return failure, not permitted in the caller */ +static int __nhk8815_getc(void) +{ +int row, col, res; + +res = pe_kpc_getkey(STMPE0, row, col); +if (res 0) return res; /* invalid */ +nextchar = keymap[row][col]; +return 0; +} + +/* This is low level: may not report a valid key (a release, for example) */ +static int __nhk8815_tstc(void) +{ + /* the interrupt is active low */ + int gpio = nmk_gpio_get(76); + return !gpio; +} + +/* This is the one that is being called, it reads the pending string */ +static int nhk8815_tstc(void) +{ + if (*nextchar) /* there's already data */ + return 1; + if (!__nhk8815_tstc()) /* no new data? */ + return 0; + __nhk8815_getc(); /* get (or not) new data */ + return (nextchar[0] != '\0'); +} + +/* So this is only called when there is data in the currenct string */ +static int nhk8815_getc(void) +{ + return *(nextchar++); +} + +/* called from late init */ +int nhk8815_keypad_init(void) +{ +struct stdio_dev dev; + + printf(%s:%s\n, __FILE__, __func__); + + /* The keypad is on EXP0, columns 0..3, rows 0..3 */ + pe_kpc_init(STMPE0, 0x0f, 0x0f, 30 /* ms */); + + /* Keypad interrupt: GPIO76 */ + nmk_gpio_af(76, GPIO_GPIO); + nmk_gpio_dir(76, 0); + +memset (dev, 0, sizeof (dev)); + dev.flags = DEV_FLAGS_INPUT; +dev.getc = nhk8815_getc; +dev.tstc = nhk8815_tstc; + strcpy(dev.name, keypad); + stdio_register(dev); + return 0; +} diff --git a/board/st/nhk8815/nhk8815.c b/board/st/nhk8815/nhk8815.c index eadce40..efeb0d2 100644 --- a/board/st/nhk8815/nhk8815.c +++ b/board/st/nhk8815/nhk8815.c @@ -106,9 +106,14 @@ int board_eth_init(bd_t *bis) } #endif +extern int nhk8815_keypad_init(void); /* ./keypad.c */ + /* Initialization callback, from lib_arm/board.c */ int board_late_init(void) { +#ifdef CONFIG_NHK8815_KEYPAD + nhk8815_keypad_init(); +#endif return 0; } diff --git a/include/configs/nhk8815.h b/include/configs/nhk8815.h index e1be45b..f9dbd7a 100644 --- a/include/configs/nhk8815.h +++ b/include/configs/nhk8815.h @@ -131,6 +131,9 @@ #define STMPE0 0x43 #define STMPE1 0x44 +/* Keypad using stmpe2401 */ +#define CONFIG_NHK8815_KEYPAD + /* Ethernet */ #define PCI_MEMORY_VADDR 0xe800 #define PCI_IO_VADDR 0xee00 -- 1.6.0.2 ___ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de
[U-Boot] [PATCH 7/8] nhk8815: start lower in RAM, so the 800x480 frame buffer fits
From: Alessandro Rubini rub...@unipv.it Signed-off-by: Alessandro Rubini rub...@unipv.it Acked-by: Andrea Gallo andrea.ga...@stericsson.com --- board/st/nhk8815/config.mk |7 ++- 1 files changed, 2 insertions(+), 5 deletions(-) diff --git a/board/st/nhk8815/config.mk b/board/st/nhk8815/config.mk index 590393b..faf1d53 100644 --- a/board/st/nhk8815/config.mk +++ b/board/st/nhk8815/config.mk @@ -18,9 +18,6 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, # MA 02111-1307 USA -# -# -# image should be loaded at 0x0100 -# -TEXT_BASE = 0x03F8 +# A display of 800x480x4 takes almost 2MB, so we must be lower than that. +TEXT_BASE = 0x03c0 -- 1.6.0.2 ___ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot
[U-Boot] [PATCH 8/8] nhk8815: added lcd support
From: Alessandro Rubini rub...@unipv.it Signed-off-by: Alessandro Rubini rub...@unipv.it Acked-by: Andrea Gallo andrea.ga...@stericsson.com --- board/st/nhk8815/Makefile |1 + board/st/nhk8815/lcd.c | 89 board/st/nhk8815/nhk8815.c |4 ++ include/configs/nhk8815.h | 10 + 4 files changed, 104 insertions(+), 0 deletions(-) create mode 100644 board/st/nhk8815/lcd.c diff --git a/board/st/nhk8815/Makefile b/board/st/nhk8815/Makefile index 1bb1d2c..7155f12 100644 --- a/board/st/nhk8815/Makefile +++ b/board/st/nhk8815/Makefile @@ -31,6 +31,7 @@ LIB = $(obj)lib$(BOARD).a COBJS-y:= nhk8815.o COBJS-$(CONFIG_NHK8815_KEYPAD) += keypad.o +COBJS-$(CONFIG_LCD) += lcd.o COBJS := $(COBJS-y) SOBJS := platform.o diff --git a/board/st/nhk8815/lcd.c b/board/st/nhk8815/lcd.c new file mode 100644 index 000..0f59b2b --- /dev/null +++ b/board/st/nhk8815/lcd.c @@ -0,0 +1,89 @@ +/* + * board/st/nhk8815/lcd.c: use amba clcd and STMPE2401 for backlight/reset + * + * Copyright 2009 Alessandro Rubini rub...@unipv.it + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ +#include common.h +#include lcd.h +#include amba_clcd.h +#include stmpe2401.h + +/* Two configurations are supported: 32bpp and 16bpp */ +#if LCD_BPP == LCD_COLOR32 +# define CLCD_CNTL_VAL 0x0019182b +# define CLCD_BPIX_VAL 5 /* 15 = 32 */ +#elif LCD_BPP == LCD_COLOR16 +# define CLCD_CNTL_VAL 0x001d1829 +# define CLCD_BPIX_VAL 4 /* 14 = 16 */ +#else +# error Invalid LCD_BPP in config file +#endif + +/* Horribly, these are precomputed registers */ +struct clcd_regs nhk8815_clcd_regs = { + .tim0 = 0xd52600c4, /* horizontal timings */ + .tim1 = 0x220a01df, /* vertical timings */ + .tim2 = 0x031f1821, /* clock and signal polarity */ + .tim3 = 0, /* not used */ + .cntl = CLCD_CNTL_VAL, /* control, pixel size etc */ + .pixclock = 18*1000*1000, /* 18 MHz */ +}; + +/* This is the panel_info for generic boards. Too little info, actually */ +vidinfo_t panel_info = { + .vl_col = 800, + .vl_row = 480, + .vl_bpix = CLCD_BPIX_VAL, + .priv = nhk8815_clcd_regs, +}; + +/* Don't turn on (too early), but configure data lines and remove reset */ +void lcd_enable(void) +{ + printf(%s:%s\n, __FILE__, __func__); + int i; + + /* Turn the alternate functions as needed */ + for (i = 32; i = 39; i++) + nmk_gpio_af(i, GPIO_ALT_B); + + /* EXP1_GPIO_5 = output high -- remove reset from display */ + pe_gpio_af(STMPE1, 5, PE_GPIO_AF_GPIO); + pe_gpio_dir(STMPE1, 5, 1); + pe_gpio_set(STMPE1, 5, 1); +} + +/* Called from late_init: we turn on the backlight through port expander */ +int nhk8815_backlight_on(void) +{ + printf(%s:%s\n, __FILE__, __func__); + int i; + + /* Turn the alternate functions as needed */ + for (i = 32; i = 39; i++) + nmk_gpio_af(i, GPIO_ALT_B); + + /* EXP0_GPIO_21 = output high -- backlight */ + pe_gpio_af(STMPE0, 21, PE_GPIO_AF_GPIO); + pe_gpio_dir(STMPE0, 21, 1); + pe_gpio_set(STMPE0, 21, 1); + return 0; +} diff --git a/board/st/nhk8815/nhk8815.c b/board/st/nhk8815/nhk8815.c index efeb0d2..ded7681 100644 --- a/board/st/nhk8815/nhk8815.c +++ b/board/st/nhk8815/nhk8815.c @@ -107,6 +107,7 @@ int board_eth_init(bd_t *bis) #endif extern int nhk8815_keypad_init(void); /* ./keypad.c */ +extern int nhk8815_backlight_on(void); /* in ./lcd.c */ /* Initialization callback, from lib_arm/board.c */ int board_late_init(void) @@ -114,6 +115,9 @@ int board_late_init(void) #ifdef CONFIG_NHK8815_KEYPAD nhk8815_keypad_init(); #endif +#ifdef CONFIG_LCD + nhk8815_backlight_on(); +#endif return 0; } diff --git a/include/configs/nhk8815.h b/include/configs/nhk8815.h index f9dbd7a..ad098d9 100644 --- a/include/configs/nhk8815.h +++ b/include/configs/nhk8815.h @@ -134,6 +134,16 @@ /* Keypad using stmpe2401 */ #define CONFIG_NHK8815_KEYPAD +/* Display
Re: [U-Boot] [PATCH V3 1/3] lib_generic memcpy: copy one word at a time if possible
Hello Chris +unsigned long *dl = (unsigned long *)dest, *sl = (unsigned long *)src; Nitpick: Are you sure the casts are necessary here ? Without the one on src it complains because of const. So I write both for symetry. + if ( (((ulong)dest | (ulong)src) (sizeof(*dl) - 1)) == 0) { The or should not include count: the remaining count % sizeof(unsigned long) bytes are copied below. Yes, that's why I'm sending V4 today. Actually, I booted V3 but didn't measure it, so this bug went unnoticed. But I won't measure it today, either... Ok for spaces around operators (even if the whole of string.c is strangely spaced, but that's historical). thanks /alessandro ___ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot
[U-Boot] [PATCH V4 1/3] lib_generic memcpy: copy one word at a time if possible
From: Alessandro Rubini rub...@unipv.it If source and destination are aligned, this copies ulong values until possible, trailing part is copied by byte. Thanks for the details to Wolfgang Denk, Mike Frysinger, Peter Tyser, Chris Moore. Signed-off-by: Alessandro Rubini rub...@unipv.it Acked-by: Andrea Gallo andrea.ga...@stericsson.com Acked-by: Mike Frysinger vap...@gentoo.org --- lib_generic/string.c | 19 +++ 1 files changed, 15 insertions(+), 4 deletions(-) diff --git a/lib_generic/string.c b/lib_generic/string.c index 181eda6..61a45dc 100644 --- a/lib_generic/string.c +++ b/lib_generic/string.c @@ -446,12 +446,23 @@ char * bcopy(const char * src, char * dest, int count) * You should not use this function to access IO space, use memcpy_toio() * or memcpy_fromio() instead. */ -void * memcpy(void * dest,const void *src,size_t count) +void * memcpy(void *dest, const void *src, size_t count) { - char *tmp = (char *) dest, *s = (char *) src; - + unsigned long *dl = (unsigned long *)dest, *sl = (unsigned long *)src; + char *d8, *s8; + + /* while all data is aligned (common case), copy a word at a time */ + if ( (((ulong)dest | (ulong)src) (sizeof(*dl) - 1)) == 0) { + while (count = sizeof(*dl)) { + *dl++ = *sl++; + count -= sizeof(*dl); + } + } + /* copy the reset one byte at a time */ + d8 = (char *)dl; + s8 = (char *)sl; while (count--) - *tmp++ = *s++; + *d8++ = *s8++; return dest; } -- 1.6.0.2 ___ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot
[U-Boot] [PATCH V4 2/3] lib_generic memset: fill one word at a time if possible
From: Alessandro Rubini rub...@unipv.it If the destination is aligned, fill ulong values until possible. Then fill remaining part by byte. Signed-off-by: Alessandro Rubini rub...@unipv.it Acked-by: Andrea Gallo andrea.ga...@stericsson.com Acked-by: Mike Frysinger vap...@gentoo.org --- lib_generic/string.c | 22 +++--- 1 files changed, 19 insertions(+), 3 deletions(-) diff --git a/lib_generic/string.c b/lib_generic/string.c index 61a45dc..b375b81 100644 --- a/lib_generic/string.c +++ b/lib_generic/string.c @@ -403,10 +403,26 @@ char *strswab(const char *s) */ void * memset(void * s,int c,size_t count) { - char *xs = (char *) s; - + unsigned long *sl = (unsigned long *) s; + unsigned long cl = 0; + char *s8; + int i; + + /* do it one word at a time (32 bits or 64 bits) while possible */ + if ( ((ulong)s (sizeof(*sl) - 1)) == 0) { + for (i = 0; i sizeof(*sl); i++) { + cl = 8; + cl |= c 0xff; + } + while (count = sizeof(*sl)) { + *sl++ = cl; + count -= sizeof(*sl); + } + } + /* fill 8 bits at a time */ + s8 = (char *)sl; while (count--) - *xs++ = c; + *s8++ = c; return s; } -- 1.6.0.2 ___ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot
[U-Boot] [PATCH V4 3/3] lcd: remove '#if 0' 32-bit scroll, now memcpy does it
From: Alessandro Rubini rub...@unipv.it Signed-off-by: Alessandro Rubini rub...@unipv.it Acked-by: Andrea Gallo andrea.ga...@stericsson.com --- common/lcd.c | 21 - 1 files changed, 0 insertions(+), 21 deletions(-) diff --git a/common/lcd.c b/common/lcd.c index dc8fea6..4e31618 100644 --- a/common/lcd.c +++ b/common/lcd.c @@ -99,32 +99,11 @@ static int lcd_getfgcolor (void); static void console_scrollup (void) { -#if 1 /* Copy up rows ignoring the first one */ memcpy (CONSOLE_ROW_FIRST, CONSOLE_ROW_SECOND, CONSOLE_SCROLL_SIZE); /* Clear the last one */ memset (CONSOLE_ROW_LAST, COLOR_MASK(lcd_color_bg), CONSOLE_ROW_SIZE); -#else - /* -* Poor attempt to optimize speed by moving longs. -* But the code is ugly, and not a bit faster :-( -*/ - ulong *t = (ulong *)CONSOLE_ROW_FIRST; - ulong *s = (ulong *)CONSOLE_ROW_SECOND; - ulongl = CONSOLE_SCROLL_SIZE / sizeof(ulong); - uchar c = lcd_color_bg 0xFF; - ulong val= (c24) | (c16) | (c8) | c; - - while (l--) - *t++ = *s++; - - t = (ulong *)CONSOLE_ROW_LAST; - l = CONSOLE_ROW_SIZE / sizeof(ulong); - - while (l-- 0) - *t++ = val; -#endif } /*--*/ -- 1.6.0.2 ___ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot
Re: [U-Boot] [PATCH V4 2/3] lib_generic memset: fill one word at a time if possible
The above while can be slow if not the complier manages to turn into: But the compiler is able, and Wolfgang already told that in another thread. Yes, I checked my assembly. No, not all platforms and all versions. like Wolfgang. I think you may have a point, but unless you have a measured misworking case to show, we'd better stop here. /alessandro, who'll lift linux/arch/arm/lib/memcpy.S next time ___ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot
[U-Boot] [PATCH (repost)] Nomadik: fix reset_timer()
From: Alessandro Rubini rub...@unipv.it The timer decrements and READ_TIMER() negates the value read. Writing 0 in reset_timer() is this wrong, as a readback before 400us will read back 0 and will report 1780 seconds, so nand operations did timeout. This patch writes ~0 in reset_timer to prevent this. Signed-off-by: Alessandro Rubini rub...@unipv.it Acked-by: Andrea Gallo andrea.ga...@stericsson.com --- This must be applied for nand to work. It's a simple bugfix so I think it got simply forgotten. BTW: I got no feedback for the lcd/keypad stuff, neither positive nor negative. Shall I repost my current status in that regard? thanks /alessandro cpu/arm926ejs/nomadik/timer.c |4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diff --git a/cpu/arm926ejs/nomadik/timer.c b/cpu/arm926ejs/nomadik/timer.c index 16067c9..2115b71 100644 --- a/cpu/arm926ejs/nomadik/timer.c +++ b/cpu/arm926ejs/nomadik/timer.c @@ -46,10 +46,10 @@ int timer_init(void) return 0; } -/* Restart counting from 0 */ +/* Restart counting from ~0 (can't be 0, since READ_TIMER negates) */ void reset_timer(void) { - writel(0, CONFIG_SYS_TIMERBASE + MTU_LR(0)); /* Immediate effect */ + writel(~0, CONFIG_SYS_TIMERBASE + MTU_LR(0)); /* Immediate effect */ } /* Return how many HZ passed since base */ -- 1.5.6.5 ___ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot
Re: [U-Boot] [PATCH (repost)] Nomadik: fix reset_timer()
Um... why is READ_TIMER doing such a stupid thing as negating values? Because the counter counts down. I could have returns 0 - value or ~value. Since I chose the latter initially, this fix keeps the same approach. I can't return the value I read, since it goes backwards. /alessandro ___ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot
Re: [U-Boot] [PATCH (repost)] Nomadik: fix reset_timer()
Well, to me READ_TIMER() sounds like a function/macro to read some value from some timer; if that timer counts doen, then successive calls to that macro/function would return decreasing values. Counting up or down is a property of the specific timer and should be handled elsewhere; such policy does IMHO not belong into some accessor function. Well, I thought this was an easy fix. Unfortunately, I can't test any new code for a few days, so a patch that changes this, while trivial, may be bugged. Unless I get an ack from you, I'll send a timer which negates elsewhere in a day or so. /alessandro ___ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot
[U-Boot] [PATCH V3] Nomadik: fix reset_timer()
From: Alessandro Rubini rub...@unipv.it Previous code was failing when reading back the timer less than 400us after resetting it. This lead nand operations to incorrectly timeout any now and then. This changes READ_TIMER from negation to subtraction, so after writing 0 to reset it, an immediate read is correctly reported as 0 elapsed ticks. Signed-off-by: Alessandro Rubini rub...@unipv.it Acked-by: Andrea Gallo andrea.ga...@stericsson.com --- This is an alternative to V2, which is being posted at the same time. I prefer this approach to that one, as it fixes the problem without switching subsequent code to negative logic. cpu/arm926ejs/nomadik/timer.c |4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diff --git a/cpu/arm926ejs/nomadik/timer.c b/cpu/arm926ejs/nomadik/timer.c index 16067c9..991752d 100644 --- a/cpu/arm926ejs/nomadik/timer.c +++ b/cpu/arm926ejs/nomadik/timer.c @@ -34,8 +34,8 @@ #define TICKS_PER_HZ (TIMER_CLOCK / CONFIG_SYS_HZ) #define TICKS_TO_HZ(x) ((x) / TICKS_PER_HZ) -/* macro to read the 32 bit timer: since it decrements, we invert read value */ -#define READ_TIMER() (~readl(CONFIG_SYS_TIMERBASE + MTU_VAL(0))) +/* macro to read the decrementing 32 bit timer as an increasing count */ +#define READ_TIMER() (0 - readl(CONFIG_SYS_TIMERBASE + MTU_VAL(0))) /* Configure a free-running, auto-wrap counter with no prescaler */ int timer_init(void) -- 1.6.0.2 ___ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot
[U-Boot] [PATCH V2] Nomadik: fix reset_timer()
From: Alessandro Rubini rub...@unipv.it Previously the code wrote 0 to reset the counter and used negation to read an increasing value from the register. However, a readback before 400us still returned 0, which was reported as 1780 seconds, thus nand failed to work any now and then. As suggested by Wolfgang Denk, this changes READ_TIMER to just return the hardware counter (a declerasing one) and changes code using the value. Compile-tested only, at this point. Signed-off-by: Alessandro Rubini rub...@unipv.it Acked-by: Andrea Gallo andrea.ga...@stericsson.com --- Please note that V3 is being posted at the same time. I prefer V3 to this V2, but V2 is how I've been asked to do things. cpu/arm926ejs/nomadik/timer.c | 14 +++--- 1 files changed, 7 insertions(+), 7 deletions(-) diff --git a/cpu/arm926ejs/nomadik/timer.c b/cpu/arm926ejs/nomadik/timer.c index 16067c9..c7dd65d 100644 --- a/cpu/arm926ejs/nomadik/timer.c +++ b/cpu/arm926ejs/nomadik/timer.c @@ -34,8 +34,8 @@ #define TICKS_PER_HZ (TIMER_CLOCK / CONFIG_SYS_HZ) #define TICKS_TO_HZ(x) ((x) / TICKS_PER_HZ) -/* macro to read the 32 bit timer: since it decrements, we invert read value */ -#define READ_TIMER() (~readl(CONFIG_SYS_TIMERBASE + MTU_VAL(0))) +/* macro to read the 32 bit timer: note however that the count decreases */ +#define READ_TIMER() readl(CONFIG_SYS_TIMERBASE + MTU_VAL(0)) /* Configure a free-running, auto-wrap counter with no prescaler */ int timer_init(void) @@ -46,7 +46,7 @@ int timer_init(void) return 0; } -/* Restart counting from 0 */ +/* Restart counting from 0 (still, it is a decrementing counter) */ void reset_timer(void) { writel(0, CONFIG_SYS_TIMERBASE + MTU_LR(0)); /* Immediate effect */ @@ -55,7 +55,7 @@ void reset_timer(void) /* Return how many HZ passed since base */ ulong get_timer(ulong base) { - return TICKS_TO_HZ(READ_TIMER()) - base; + return TICKS_TO_HZ(-READ_TIMER()) - base; } /* Delay x useconds */ @@ -63,8 +63,8 @@ void udelay(unsigned long usec) { ulong ini, end; - ini = READ_TIMER(); - end = ini + USEC_TO_COUNT(usec); - while ((signed)(end - READ_TIMER()) 0) + ini = READ_TIMER(); /* decrementing value */ + end = ini - USEC_TO_COUNT(usec); + while ((signed)(READ_TIMER() - end) 0) ; } -- 1.6.0.2 ___ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot
Re: [U-Boot] [PATCH 1/2] ARM Conditionally compile board LED functions
I withdraw this patch. I will rethink this and come up with something better. I agree weak is better than ifdef. But the led situation on ARM isn't really pleasant when you look in lib_arm/board.c . When I proposed a simplification of board.c back on Jul 22 ([RFC] arm/board.c: avoid ifdef using weak default functions, I noticed the led approach and thought it would need cleanup (for example, by moving out of board.c to led.c or something). However, the patch was rejected by JC as he has initcalls as work in progress. Since we still missing the initcalls (as missing JC), could that patch be reconsidered? I can rebase if there's any interest. /alessandro ___ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot
Re: [U-Boot] [PATCH 6/8] nhk8815: added keypad
Hello Wolfgang. Thanks for looking at my patch-set. +printf(%s:%s\n, __FILE__, __func__); Guess this should be debug() instead? Actually, this was meant to be removed in final code. As explained in the 0/8 message, this patch set was mainly and RFC, as some of the stuff looked questionable to me. So I chose to post my current status to get some comments on the approach, not on the details which I know were just work in progress, though working on real hardware. So, unless there are serious issues, I'll clean up my current tree, add comments to each patch and repost as V2. thanks /alessandro ___ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot
Re: [U-Boot] [PATCH 8/8] nhk8815: added lcd support
I'm almost done with the requested changes on this patch set, will post V2 this evening after re-running ./makeall as needed. I've a question, though: +extern int nhk8815_backlight_on(void); /* in ./lcd.c */ Please move prototype decl;arations to some header file. Unfortunately, there is no suitable file. It's just that I split code related to different drivers in different files, for better housekeeping. These two are called nhk8815-something as they are board-specific anyways. Should I create a local header file in this same board directory, with just the two prototypes? Or ifndef __ASSEMBLY__ in the board config file is better? I'd better ask first to avoid a V3 just for this detail. Thanks /alessandro ___ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot
[U-Boot] [PATCH V2 0/9] display and keypad support for nhk8815
This patch set implements display and keypad support. To turn the display on I need the STMPE2401 port expander, set up as a separate driver in this patch set. It's the same set I sent for RFC on Oct 9 2009, with the requested fixes. I also added commit messages to each of them, and an initial nhk-specific patch that was not submitted for RFC. Detailed list of changes from V1 (as well as fixed message-id): 1/9 (nhk8815: fix i2c and other gpios at board_init time, not later): new patch, needed to apply the other ones. Please note that there is a block with local variables; I know it is generally not advisable but they are really of strictly local use, I think they deserve their limited scope. 2/9 (video: add amba-clcd prime-cell): include/amba_clcd.h: fixed white space (spaces before tab) better comments on the data structures 3/9 (include/nomadik.h: add physical address for cldc): unchanged 4/9 (drivers/misc: add stmpe2401 port extender and keypad controller): drivers/misc/stmpe2401.c: newlined all statements of if/else include/stmpe2401.h: white space fixes Note: I did not turn it into a C structure, as those registers are I2C registers, so they are plain numbers, not offsets in an I/O memory region where I use readl/writel 5/9 (nhk8815.h: define we need stmpe): unchanged 6/9 (lcd: make 16bpp work): declared the new d pointer in new ifdef block. I dislike it, but my previous approach to avoid the ifdef was nacked. common/lcd.c is a mess, unfortunately. I made ./MAKEALL arm and ./MAKEALL ppc with no adverse effects. 7/9 (nhk8815: added keypad): layout (space, if blocks) removed extra __LINE__ temporary printouts added an header for local prototypes 8/9 (nhk8815: start lower in RAM, so the 800x480 frame buffer fits): changed the comment in config.mk. 9/9 (nhk8815: added lcd support): white space changes (tabified the structures) removed the __LINE__ temporary printouts used the header introduced in 7/9 for local prototypes Alessandro Rubini (9): nhk8815: change the order of initialization video: add amba-clcd prime-cell include/nomadik.h: add physical address for cldc drivers/misc: add stmpe2401 port extender and keypad controller nhk8815.h: define we need stmpe lcd: make 16bpp work nhk8815: added keypad nhk8815: start lower in RAM, so the 800x480 frame buffer fits nhk8815: added lcd support board/st/nhk8815/Makefile |6 +- board/st/nhk8815/config.mk |8 +- board/st/nhk8815/keypad.c | 99 +++ board/st/nhk8815/lcd.c | 87 board/st/nhk8815/nhk8815-devices.h |8 ++ board/st/nhk8815/nhk8815.c | 38 +-- common/lcd.c | 27 - drivers/misc/Makefile |1 + drivers/misc/stmpe2401.c | 191 drivers/video/Makefile |1 + drivers/video/amba.c | 86 include/amba_clcd.h| 85 include/configs/nhk8815.h | 20 - include/nomadik.h |1 + include/stmpe2401.h| 66 15 files changed, 701 insertions(+), 23 deletions(-) create mode 100644 board/st/nhk8815/keypad.c create mode 100644 board/st/nhk8815/lcd.c create mode 100644 board/st/nhk8815/nhk8815-devices.h create mode 100644 drivers/misc/stmpe2401.c create mode 100644 drivers/video/amba.c create mode 100644 include/amba_clcd.h create mode 100644 include/stmpe2401.h ___ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot
[U-Boot] [PATCH V2 1/9] nhk8815: change the order of initialization
From: Alessandro Rubini rub...@unipv.it Some inizialization was in board_late_init(), but to satisfy drivers added in the next patches must be performed in normal board_init. This patch leaves board_late_init() empty, but later patches fill it. Signed-off-by: Alessandro Rubini rub...@unipv.it Acked-by: Andrea Gallo andrea.ga...@stericsson.com --- board/st/nhk8815/nhk8815.c | 31 +-- 1 files changed, 21 insertions(+), 10 deletions(-) diff --git a/board/st/nhk8815/nhk8815.c b/board/st/nhk8815/nhk8815.c index faef810..eadce40 100644 --- a/board/st/nhk8815/nhk8815.c +++ b/board/st/nhk8815/nhk8815.c @@ -60,22 +60,26 @@ int board_init(void) writel(0x02100551, NOMADIK_FSMC_BASE + 0x04); /* FSMC_BTR0 */ icache_enable(); - return 0; -} -int board_late_init(void) -{ + /* +* Configure I2C pins, as we will use I2C in a later commit +*/ + /* Set the two I2C gpio lines to be gpio high */ nmk_gpio_set(__SCL, 1); nmk_gpio_set(__SDA, 1); nmk_gpio_dir(__SCL, 1); nmk_gpio_dir(__SDA, 1); nmk_gpio_af(__SCL, GPIO_GPIO); nmk_gpio_af(__SDA, GPIO_GPIO); - /* Reset the I2C port expander, on GPIO77 */ - nmk_gpio_af(77, GPIO_GPIO); - nmk_gpio_dir(77, 1); - nmk_gpio_set(77, 0); - udelay(10); - nmk_gpio_set(77, 1); + /* Put the two I2C port expanders out of reset, on GPIO77 and 79 */ + { + int n[2]={77, 79}; + int i; + for (i = 0; i ARRAY_SIZE(n); i++) { + nmk_gpio_af(n[i], GPIO_GPIO); + nmk_gpio_dir(n[i], 1); + nmk_gpio_set(n[i], 1); + } + } return 0; } @@ -101,3 +105,10 @@ int board_eth_init(bd_t *bis) return rc; } #endif + +/* Initialization callback, from lib_arm/board.c */ +int board_late_init(void) +{ + return 0; +} + -- 1.6.0.2 ___ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot