[U-Boot] [PATCH 2/3] arm: mx31: use common timer functions
From: Andrew Ruder This patch moves mx31 to the common timer functions added in commit 8dfafdd - Introduce common timer functions The (removed) mx31 timer code (specifically __udelay()) could deadlock at the 32-bit boundary of get_ticks(). get_ticks() returned a 32-bit value cast up to a 64-bit value. If get_ticks() + tmo in __udelay() crossed the 32-bit boundary, the while condition became unconditionally true and locks the processor. Rather than patch the specific mx31 issues, simply move everything over to the common code. Signed-off-by: Andrew Ruder Cc: Marek Vasut Cc: Linus Walleij Cc: Wolfgang Denk Cc: Fabio Estevam Cc: Helmut Raiger --- This patch has been COMPILE tested only. The situation isn't quite as bad on mx31 as 32-bit rollover occurs in about a day and a half. Before patch: Configuring for qong board... 456 -rw-r--r-- 1 andy andy 463236 Aug 12 08:36 u-boot.bin After patch: Configuring for qong board... 456 -rw-r--r-- 1 andy andy 463248 Aug 12 08:38 u-boot.bin arch/arm/cpu/arm1136/mx31/timer.c | 104 +- arch/arm/include/asm/arch-mx31/imx-regs.h | 10 +++ 2 files changed, 12 insertions(+), 102 deletions(-) diff --git a/arch/arm/cpu/arm1136/mx31/timer.c b/arch/arm/cpu/arm1136/mx31/timer.c index f111242..3a81ce4 100644 --- a/arch/arm/cpu/arm1136/mx31/timer.c +++ b/arch/arm/cpu/arm1136/mx31/timer.c @@ -7,9 +7,6 @@ #include #include -#include -#include -#include #include #define TIMER_BASE 0x53f9 /* General purpose timer 1 */ @@ -28,57 +25,6 @@ DECLARE_GLOBAL_DATA_PTR; -/* - * "time" is measured in 1 / CONFIG_SYS_HZ seconds, - * "tick" is internal timer period - */ - -#ifdef CONFIG_MX31_TIMER_HIGH_PRECISION -/* ~0.4% error - measured with stop-watch on 100s boot-delay */ -static inline unsigned long long tick_to_time(unsigned long long tick) -{ - tick *= CONFIG_SYS_HZ; - do_div(tick, MXC_CLK32); - return tick; -} - -static inline unsigned long long time_to_tick(unsigned long long time) -{ - time *= MXC_CLK32; - do_div(time, CONFIG_SYS_HZ); - return time; -} - -static inline unsigned long long us_to_tick(unsigned long long us) -{ - us = us * MXC_CLK32 + 99; - do_div(us, 100); - return us; -} -#else -/* ~2% error */ -#define TICK_PER_TIME ((MXC_CLK32 + CONFIG_SYS_HZ / 2) / CONFIG_SYS_HZ) -#define US_PER_TICK(100 / MXC_CLK32) - -static inline unsigned long long tick_to_time(unsigned long long tick) -{ - do_div(tick, TICK_PER_TIME); - return tick; -} - -static inline unsigned long long time_to_tick(unsigned long long time) -{ - return time * TICK_PER_TIME; -} - -static inline unsigned long long us_to_tick(unsigned long long us) -{ - us += US_PER_TICK - 1; - do_div(us, US_PER_TICK); - return us; -} -#endif - /* The 32768Hz 32-bit timer overruns in 131072 seconds */ int timer_init(void) { @@ -95,53 +41,7 @@ int timer_init(void) return 0; } -unsigned long long get_ticks(void) -{ - ulong now = GPTCNT; /* current tick value */ - - if (now >= gd->arch.lastinc)/* normal mode (non roll) */ - /* move stamp forward with absolut diff ticks */ - gd->arch.tbl += (now - gd->arch.lastinc); - else/* we have rollover of incrementer */ - gd->arch.tbl += (0x - gd->arch.lastinc) + now; - gd->arch.lastinc = now; - return gd->arch.tbl; -} - -ulong get_timer_masked(void) -{ - /* -* get_ticks() returns a long long (64 bit), it wraps in -* 2^64 / MXC_CLK32 = 2^64 / 2^15 = 2^49 ~ 5 * 10^14 (s) ~ -* 5 * 10^9 days... and get_ticks() * CONFIG_SYS_HZ wraps in -* 5 * 10^6 days - long enough. -*/ - return tick_to_time(get_ticks()); -} - -ulong get_timer(ulong base) -{ - return get_timer_masked() - base; -} - -/* delay x useconds AND preserve advance timestamp value */ -void __udelay(unsigned long usec) -{ - unsigned long long tmp; - ulong tmo; - - tmo = us_to_tick(usec); - tmp = get_ticks() + tmo;/* get current timestamp */ - - while (get_ticks() < tmp) /* loop till event */ -/*NOP*/; -} - -/* - * This function is derived from PowerPC code (timebase clock frequency). - * On ARM it returns the number of timer ticks per second. - */ -ulong get_tbclk(void) +unsigned long timer_read_counter(void) { - return MXC_CLK32; + return GPTCNT; } diff --git a/arch/arm/include/asm/arch-mx31/imx-regs.h b/arch/arm/include/asm/arch-mx31/imx-regs.h index f23350e..71ebd24 100644 --- a/arch/arm/include/asm/arch-mx31/imx-regs.h +++ b/arch/arm/include/asm/arch-mx31/imx-regs.h @@ -909,9 +909,19 @@ struct esdc_regs { #define MXC_CSPIPERIOD_32KHZ (1 << 15) #define MAX_SPI_BYTES 4 + #define MXC_SPI_BASE_ADDRESSES \ 0x43fa4000, \ 0x50010
[U-Boot] [PATCH 1/3] arm: pxa: use common timer functions
From: Andrew Ruder This patch moves pxa to the common timer functions added in commit 8dfafdd - Introduce common timer functions The (removed) pxa timer code (specifically __udelay()) could deadlock at the 32-bit boundary of get_ticks(). get_ticks() returned a 32-bit value cast up to a 64-bit value. If get_ticks() + tmo in __udelay() crossed the 32-bit boundary, the while condition became unconditionally true and locked the processor. Rather than patch the specific pxa issues, simply move everything over to the common code. Signed-off-by: Andrew Ruder Cc: Marek Vasut --- 32-bit rollover occurs every 22 minutes so even a long y-modem transfer was enough to hit this issue fairly regularly. This has been tested. arch/arm/cpu/pxa/timer.c | 69 +--- include/configs/pxa-common.h | 13 + 2 files changed, 14 insertions(+), 68 deletions(-) diff --git a/arch/arm/cpu/pxa/timer.c b/arch/arm/cpu/pxa/timer.c index c4717de..11fefd5 100644 --- a/arch/arm/cpu/pxa/timer.c +++ b/arch/arm/cpu/pxa/timer.c @@ -6,80 +6,13 @@ * SPDX-License-Identifier:GPL-2.0+ */ -#include #include #include -#include DECLARE_GLOBAL_DATA_PTR; -#defineTIMER_LOAD_VAL 0x - -#definetimestamp (gd->arch.tbl) -#definelastinc (gd->arch.lastinc) - -#if defined(CONFIG_CPU_PXA27X) || defined(CONFIG_CPU_MONAHANS) -#defineTIMER_FREQ_HZ 325 -#elif defined(CONFIG_CPU_PXA25X) -#defineTIMER_FREQ_HZ 3686400 -#else -#error "Timer frequency unknown - please config PXA CPU type" -#endif - -static unsigned long long tick_to_time(unsigned long long tick) -{ - return lldiv(tick * CONFIG_SYS_HZ, TIMER_FREQ_HZ); -} - -static unsigned long long us_to_tick(unsigned long long us) -{ - return lldiv(us * TIMER_FREQ_HZ, 100); -} - int timer_init(void) { - writel(0, OSCR); + writel(0, CONFIG_SYS_TIMER_COUNTER); return 0; } - -unsigned long long get_ticks(void) -{ - /* Current tick value */ - uint32_t now = readl(OSCR); - - if (now >= lastinc) { - /* -* Normal mode (non roll) -* Move stamp forward with absolute diff ticks -*/ - timestamp += (now - lastinc); - } else { - /* We have rollover of incrementer */ - timestamp += (TIMER_LOAD_VAL - lastinc) + now; - } - - lastinc = now; - return timestamp; -} - -ulong get_timer(ulong base) -{ - return tick_to_time(get_ticks()) - base; -} - -void __udelay(unsigned long usec) -{ - unsigned long long tmp; - ulong tmo; - - tmo = us_to_tick(usec); - tmp = get_ticks() + tmo;/* get current timestamp */ - - while (get_ticks() < tmp) /* loop till event */ -/*NOP*/; -} - -ulong get_tbclk(void) -{ - return TIMER_FREQ_HZ; -} diff --git a/include/configs/pxa-common.h b/include/configs/pxa-common.h index f0ecc34..8da37a3 100644 --- a/include/configs/pxa-common.h +++ b/include/configs/pxa-common.h @@ -43,4 +43,17 @@ #defineCONFIG_USB_STORAGE #endif +/* + * Generic timer support + */ +#if defined(CONFIG_CPU_PXA27X) || defined(CONFIG_CPU_MONAHANS) +#defineCONFIG_SYS_TIMER_RATE 325 +#elif defined(CONFIG_CPU_PXA25X) +#defineCONFIG_SYS_TIMER_RATE 3686400 +#else +#error "Timer frequency unknown - please config PXA CPU type" +#endif + +#define CONFIG_SYS_TIMER_COUNTER 0x40A00010 /* OSCR */ + #endif /* __CONFIG_PXA_COMMON_H__ */ -- 2.0.1 ___ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot
[U-Boot] [PATCH 0/3] Initial cleanup of arm port timer subsystem
From: Andrew Ruder Hey all, Was tracking down an issue on a PXA270 based board where a long y-modem transfer would frequently deadlock the board in the middle of the transfer. Unfortunately I felt like I had opened pandora's box by looking around at other ports. Very few ports were 32-bit rollover safe! Most looked like they would just skip a __udelay on roll-over. These are fixes for the couple I noticed that would potentially deadlock if __udelay crossed the 32-bit boundary. And some are so complicated that I didn't waste time looking at them. get_ticks() which returns a unsigned long long had a variety of implementations. Some returned a number that wrapped at 32 bits which worked with some implementations of __udelay. Others returned a number that wraps at a fraction of 32-bits which would hit the roll-over issues at an unexpected place and fail even more often. There is a lot of opportunity here for tons of code removal by moving more ports to the common code. Here are some notes that I took while going through some that might save someone some time. This was a very cursory look so my apologies if I have missed something. ** u-boot/arch/arm/cpu/arm1136/mx31/timer.c:98:20:unsigned long long get_ticks(void) get_ticks() returns 32-bit number __udelay() depends on 64-bit value - HANGS ** u-boot/arch/arm/cpu/arm1136/mx35/timer.c:75:20:unsigned long long get_ticks(void) get_ticks() returns 32-bit number __udelay() depends on 64-bit value - HANGS ** u-boot/arch/arm/cpu/arm1176/bcm2835/timer.c:37:20:unsigned long long get_ticks(void) get_ticks() returns 32-bit number __udelay() is safe ** u-boot/arch/arm/cpu/arm1176/tnetv107x/timer.c:67:20:unsigned long long get_ticks(void) get_ticks() isn't even a 32-bit number __udelay() is safe ** u-boot/arch/arm/cpu/arm920t/a320/timer.c:74:20:unsigned long long get_ticks(void) get_ticks() returns 64-bit number __udelay() is safe ** u-boot/arch/arm/cpu/arm920t/at91/timer.c:115:20:unsigned long long get_ticks(void) get_ticks() isn't even a 32-bit number __udelay() is safe ** u-boot/arch/arm/cpu/arm920t/ep93xx/timer.c:58:20:unsigned long long get_ticks(void) get_ticks() returns 64-bit number __udelay() is safe until 64-bit rollover ** u-boot/arch/arm/cpu/arm920t/imx/timer.c:70:20:unsigned long long get_ticks(void) get_ticks() returns a 32-bit number __udelay is safe ** u-boot/arch/arm/cpu/arm920t/s3c24x0/timer.c:110:20:unsigned long long get_ticks(void) get_ticks() is complicated. tbu abused for something else __udelay might be safe? It handles 32-bit rollover correctly if get_ticks() is really a 32-bit number ** u-boot/arch/arm/cpu/arm926ejs/armada100/timer.c:182:20:unsigned long long get_ticks(void) get_ticks() isn't a 32-bit number __udelay completely doesn't handle roll-over ** u-boot/arch/arm/cpu/arm926ejs/at91/timer.c:75:20:unsigned long long get_ticks(void) get_ticks() returns 64-bit number __udelay handles roll-over looks perfect ** u-boot/arch/arm/cpu/arm926ejs/davinci/timer.c:56:20:unsigned long long get_ticks(void) get_ticks() returns 64-bit number chooses to ignore roll-over ** u-boot/arch/arm/cpu/arm926ejs/kirkwood/timer.c:145:20:unsigned long long get_ticks(void) get_ticks() returns 32-bit number no idea, too complicated ** u-boot/arch/arm/cpu/arm926ejs/mb86r0x/timer.c:65:20:unsigned long long get_ticks(void) get_ticks() returns 32-bit number __udelay doesn't handle roll-over ** u-boot/arch/arm/cpu/arm926ejs/lpc32xx/timer.c:74:20:unsigned long long get_ticks(void) get_ticks() returns 32-bit number __udelay is safe (doesn't handle roll-over - doesn't need to) ** u-boot/arch/arm/cpu/arm926ejs/mx27/timer.c:111:20:unsigned long long get_ticks(void) get_ticks() returns 32-bit number __udelay broken ** u-boot/arch/arm/cpu/arm926ejs/mxs/timer.c:81:20:unsigned long long get_ticks(void) get_ticks() returns 32-bit number __udelay complicated ** u-boot/arch/arm/cpu/arm926ejs/nomadik/timer.c:63:20:unsigned long long get_ticks(void) get_ticks() isn't a 32-bit number __udelay complicated ** u-boot/arch/arm/cpu/arm926ejs/omap/timer.c:140:20:unsigned long long get_ticks(void) get_ticks() isn't a 32-bit number __udelay looks good ** u-boot/arch/arm/cpu/arm926ejs/orion5x/timer.c:159:20:unsigned long long get_ticks(void) get_ticks() returns 32-bit number __udelay complicated ** u-boot/arch/arm/cpu/arm926ejs/pantheon/timer.c:189:20:unsigned long long get_ticks(void) get_ticks() doesn't return a 32-bit number __udelay doesn't handle roll-over ** u-boot/arch/arm/cpu/arm926ejs/spear/timer.c:111:20:unsigned long long get_ticks(void) get_ticks() doesn't return a 32-bit number __udelay looks good ** u-boot/arch/arm/cpu/armv7/arch_timer.c:24:20:unsigned long long get_ticks(void) get_ticks() returns 64-bit number __udelay doesn't handle 64-bit roll-over ** u-boot/arch/arm/cpu/armv7/at91/timer.c:78:20:unsigned long long get_ticks(void) get_ticks() returns 64-bit number
[U-Boot] [PATCH 3/3] arm: mx35: use common timer functions
From: Andrew Ruder This patch moves mx35 to the common timer functions added in commit 8dfafdd - Introduce common timer functions The (removed) mx35 timer code (specifically __udelay()) could deadlock at the 32-bit boundary of get_ticks(). get_ticks() returned a 32-bit value cast up to a 64-bit value. If get_ticks() + tmo in __udelay() crossed the 32-bit boundary, the while condition became unconditionally true and locks the processor. Rather than patch the specific mx35 issues, simply move everything over to the common code. Signed-off-by: Andrew Ruder Cc: Marek Vasut Cc: Stefano Babic --- This patch has been COMPILE tested only. The situation isn't quite as bad on mx35 as 32-bit rollover occurs in about a day and a half. Before patch: Configuring for woodburn board... 308 -rw-r--r-- 1 andy andy 314232 Aug 12 08:36 u-boot.bin After patch: Configuring for woodburn board... 308 -rw-r--r-- 1 andy andy 314208 Aug 12 08:37 u-boot.bin arch/arm/cpu/arm1136/mx35/timer.c | 83 --- arch/arm/include/asm/arch-mx35/imx-regs.h | 12 + 2 files changed, 12 insertions(+), 83 deletions(-) diff --git a/arch/arm/cpu/arm1136/mx35/timer.c b/arch/arm/cpu/arm1136/mx35/timer.c index cc6166f..4edf533 100644 --- a/arch/arm/cpu/arm1136/mx35/timer.c +++ b/arch/arm/cpu/arm1136/mx35/timer.c @@ -9,16 +9,11 @@ #include #include -#include #include #include -#include DECLARE_GLOBAL_DATA_PTR; -#define timestamp (gd->arch.tbl) -#define lastinc(gd->arch.lastinc) - /* General purpose timers bitfields */ #define GPTCR_SWR (1<<15)/* Software reset */ #define GPTCR_FRR (1<<9) /* Freerun / restart */ @@ -26,27 +21,6 @@ DECLARE_GLOBAL_DATA_PTR; #define GPTCR_TEN (1)/* Timer enable */ /* - * "time" is measured in 1 / CONFIG_SYS_HZ seconds, - * "tick" is internal timer period - */ -/* ~0.4% error - measured with stop-watch on 100s boot-delay */ -static inline unsigned long long tick_to_time(unsigned long long tick) -{ - tick *= CONFIG_SYS_HZ; - do_div(tick, MXC_CLK32); - - return tick; -} - -static inline unsigned long long us_to_tick(unsigned long long us) -{ - us = us * MXC_CLK32 + 99; - do_div(us, 100); - - return us; -} - -/* * nothing really to do with interrupts, just starts up a counter. * The 32KHz 32-bit timer overruns in 134217 seconds */ @@ -71,60 +45,3 @@ int timer_init(void) return 0; } - -unsigned long long get_ticks(void) -{ - struct gpt_regs *gpt = (struct gpt_regs *)GPT1_BASE_ADDR; - ulong now = readl(&gpt->counter); /* current tick value */ - - if (now >= lastinc) { - /* -* normal mode (non roll) -* move stamp forward with absolut diff ticks -*/ - timestamp += (now - lastinc); - } else { - /* we have rollover of incrementer */ - timestamp += (0x - lastinc) + now; - } - lastinc = now; - return timestamp; -} - -ulong get_timer_masked(void) -{ - /* -* get_ticks() returns a long long (64 bit), it wraps in -* 2^64 / MXC_CLK32 = 2^64 / 2^15 = 2^49 ~ 5 * 10^14 (s) ~ -* 5 * 10^9 days... and get_ticks() * CONFIG_SYS_HZ wraps in -* 5 * 10^6 days - long enough. -*/ - return tick_to_time(get_ticks()); -} - -ulong get_timer(ulong base) -{ - return get_timer_masked() - base; -} - -/* delay x useconds AND preserve advance timstamp value */ -void __udelay(unsigned long usec) -{ - unsigned long long tmp; - ulong tmo; - - tmo = us_to_tick(usec); - tmp = get_ticks() + tmo;/* get current timestamp */ - - while (get_ticks() < tmp) /* loop till event */ -/*NOP*/; -} - -/* - * This function is derived from PowerPC code (timebase clock frequency). - * On ARM it returns the number of timer ticks per second. - */ -ulong get_tbclk(void) -{ - return MXC_CLK32; -} diff --git a/arch/arm/include/asm/arch-mx35/imx-regs.h b/arch/arm/include/asm/arch-mx35/imx-regs.h index b530029..28a47ed 100644 --- a/arch/arm/include/asm/arch-mx35/imx-regs.h +++ b/arch/arm/include/asm/arch-mx35/imx-regs.h @@ -372,4 +372,16 @@ struct aips_regs { #define CCM_RCSR_NF_16BIT_SEL (1 << 14) #endif + +/* + * Generic timer support + */ +#ifdef CONFIG_MX35_CLK32 +#defineCONFIG_SYS_TIMER_RATE CONFIG_MX35_CLK32 +#else +#defineCONFIG_SYS_TIMER_RATE 32768 +#endif + +#define CONFIG_SYS_TIMER_COUNTER (GPT1_BASE_ADDR+36) + #endif /* __ASM_ARCH_MX35_H */ -- 2.0.1 ___ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot
[U-Boot] [PATCH] net: tftpsrv: Get correct client MAC address
NetServerEther was not being cleared in the tftp server code, so the destination MAC address would be whatever the last destination MAC address was. Scenario: U-Boot: dhcp tftpsrv Host: Send device WRQ Device: Responds with ACK to dhcp server mac address with host ip address By clearing NetServerEther, we force a lookup of the host MAC address to go with the associated host IP. Signed-off-by: Andrew Ruder --- net/tftp.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/net/tftp.c b/net/tftp.c index 6d333d5..002052a 100644 --- a/net/tftp.c +++ b/net/tftp.c @@ -849,6 +849,9 @@ TftpStartServer(void) TftpState = STATE_RECV_WRQ; net_set_udp_handler(TftpHandler); + + /* zero out server ether in case the server ip has changed */ + memset(NetServerEther, 0, 6); } #endif /* CONFIG_CMD_TFTPSRV */ -- 1.8.4.rc3 ___ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot
[U-Boot] [PATCH] cmd_nvedit.c: Add env exists command
env exists is a way to test (in hush) if an environment variable exists. A workaround existed using printenv but this new command doesn't require all the stdout/stderr redirection to prevent printing information to the screen. Example: $ set testexists 1 $ env exists testexists && echo "yes" yes $ env exists testexists || echo "no" $ set testexists $ env exists testexists && echo "yes" $ env exists testexists || echo "no" no $ Signed-off-by: Andrew Ruder --- README | 1 + common/cmd_nvedit.c | 23 +++ 2 files changed, 24 insertions(+) diff --git a/README b/README index 09662a4..0718459 100644 --- a/README +++ b/README @@ -843,6 +843,7 @@ The following options need to be configured: CONFIG_CMD_ELF * bootelf, bootvx CONFIG_CMD_ENV_CALLBACK * display details about env callbacks CONFIG_CMD_ENV_FLAGS* display details about env flags + CONFIG_CMD_ENV_EXISTS * check existence of env variable CONFIG_CMD_EXPORTENV* export the environment CONFIG_CMD_EXT2 * ext2 command support CONFIG_CMD_EXT4 * ext4 command support diff --git a/common/cmd_nvedit.c b/common/cmd_nvedit.c index ba9ba16..0d4d02c 100644 --- a/common/cmd_nvedit.c +++ b/common/cmd_nvedit.c @@ -1059,6 +1059,23 @@ sep_err: } #endif +#if defined(CONFIG_CMD_ENV_EXISTS) +static int do_env_exists(cmd_tbl_t *cmdtp, int flag, int argc, + char * const argv[]) +{ + ENTRY e, *ep; + + if (argc < 2) + return CMD_RET_USAGE; + + e.key = argv[1]; + e.data = NULL; + hsearch_r(e, FIND, &ep, &env_htab, 0); + + return (ep == NULL) ? 1 : 0; +} +#endif + /* * New command line interface: "env" command with subcommands */ @@ -1094,6 +,9 @@ static cmd_tbl_t cmd_env_sub[] = { U_BOOT_CMD_MKENT(save, 1, 0, do_env_save, "", ""), #endif U_BOOT_CMD_MKENT(set, CONFIG_SYS_MAXARGS, 0, do_env_set, "", ""), +#if defined(CONFIG_CMD_ENV_EXISTS) + U_BOOT_CMD_MKENT(exists, 2, 0, do_env_exists, "", ""), +#endif }; #if defined(CONFIG_NEEDS_MANUAL_RELOC) @@ -1136,6 +1156,9 @@ static char env_help_text[] = #if defined(CONFIG_CMD_EDITENV) "env edit name - edit environment variable\n" #endif +#if defined(CONFIG_CMD_ENV_EXISTS) + "env exists name - tests for existence of variable\n" +#endif #if defined(CONFIG_CMD_EXPORTENV) "env export [-t | -b | -c] [-s size] addr [var ...] - export environment\n" #endif -- 1.8.4.rc3 ___ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot
[U-Boot] [PATCH] spi: soft_spi: Support NULL din/dout buffers
This mirrors the conventions used in other SPI drivers (kirkwood, davinci, atmel, et al) where the din/dout buffer can be NULL when the received/transmitted data isn't important. This reduces the need for allocating additional buffers when write-only/read-only functionality is needed. In the din == NULL case, the received data is simply not stored. In the dout == NULL case, zeroes are transmitted. Signed-off-by: Andrew Ruder --- drivers/spi/soft_spi.c | 18 +- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/drivers/spi/soft_spi.c b/drivers/spi/soft_spi.c index 5d22351..5fdd091 100644 --- a/drivers/spi/soft_spi.c +++ b/drivers/spi/soft_spi.c @@ -137,9 +137,15 @@ int spi_xfer(struct spi_slave *slave, unsigned int bitlen, * Check if it is time to work on a new byte. */ if((j % 8) == 0) { - tmpdout = *txd++; + if (txd) { + tmpdout = *txd++; + } else { + tmpdout = 0; + } if(j != 0) { - *rxd++ = tmpdin; + if (rxd) { + *rxd++ = tmpdin; + } } tmpdin = 0; } @@ -164,9 +170,11 @@ int spi_xfer(struct spi_slave *slave, unsigned int bitlen, * bits over to left-justify them. Then store the last byte * read in. */ - if((bitlen % 8) != 0) - tmpdin <<= 8 - (bitlen % 8); - *rxd++ = tmpdin; + if (rxd) { + if((bitlen % 8) != 0) + tmpdin <<= 8 - (bitlen % 8); + *rxd++ = tmpdin; + } if (flags & SPI_XFER_END) spi_cs_deactivate(slave); -- 1.8.4.rc3 ___ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot
[U-Boot] [PATCH] net: dm9000: random mac address support
When an unprogrammed EEPROM is attached to a dm9000, the dm9000 will come up with a invalid MAC address of ff:ff:ff:ff:ff:ff. Add code that gets enabled if CONFIG_RANDOM_MACADDR is enabled that generates a random (and valid) locally administered MAC address that allows the system to network boot until a real MAC address can be configured. Signed-off-by: Andrew Ruder --- drivers/net/dm9000x.c | 9 + 1 file changed, 9 insertions(+) diff --git a/drivers/net/dm9000x.c b/drivers/net/dm9000x.c index f7170e0..b68d808 100644 --- a/drivers/net/dm9000x.c +++ b/drivers/net/dm9000x.c @@ -342,6 +342,15 @@ static int dm9000_init(struct eth_device *dev, bd_t *bd) DM9000_iow(DM9000_ISR, ISR_ROOS | ISR_ROS | ISR_PTS | ISR_PRS); printf("MAC: %pM\n", dev->enetaddr); + if (!is_valid_ether_addr(dev->enetaddr)) { +#ifdef CONFIG_RANDOM_MACADDR + printf("Bad MAC address (uninitialized EEPROM?), randomizing\n"); + eth_random_enetaddr(dev->enetaddr); + printf("MAC: %pM\n", dev->enetaddr); +#else + printf("WARNING: Bad MAC address (uninitialized EEPROM?)\n"); +#endif + } /* fill device MAC address registers */ for (i = 0, oft = DM9000_PAR; i < 6; i++, oft++) -- 1.8.4.rc3 ___ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot
Re: [U-Boot] [PATCH] cmd_nvedit.c: Add env exists command
On Wed, Oct 23, 2013 at 06:55:02AM -0700, James Chargin wrote: > I have, more recently, been using scripting of the form > > if test "X" != "X${var}"; then > echo defined > else > echo undefined > fi Thanks for the feedback. I was attempting to do something like that originally but was hitting problems related to the expansion which I'm still tracking down: WRONG: $ set var $ test "x${var}" = "x" && echo undefined undefined $ set var 1 $ test "x${var}" = "x" && echo undefined $ set var "1; 2; 3" $ test "x${var}" = "x" && echo undefined >> undefined It DOES seem to work a lot better with != as you mentioned above though... RIGHT: $ set var $ test "x${var}" != "x" && echo defined $ set var 1 $ test "x${var}" != "x" && echo defined defined $ set var "1; 2; 3" $ test "x${var}" != "x" && echo defined defined - Andy ___ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot
Re: [U-Boot] ARM: interrupt_init before relocation, write fails
On Wed, Oct 23, 2013 at 11:41:45AM -0600, Joe Kulikauskas wrote: > If I revert that patch, I don't see that problem. FWIW, I am working on a PXA270 target, and have had to revert this patch as well. I hadn't gotten around to tracking down where and why I was crashing though so hadn't emailed in a bug report yet. Now seeing as there's someone else now seeing it too I thought I would chime in with a "me too". Rob: CC'd you since you were the author and might have some insight. Full email in entirety below. - Andy On Wed, Oct 23, 2013 at 11:41:45AM -0600, Joe Kulikauskas wrote: > v2013.10-rc1 (and after) has a patch ( > http://lists.denx.de/pipermail/u-boot/2013-June/156298.html) which sets up > the abort stack before relocation. However, what I am seeing: > IRQ_STACK_START_IN > is in flash at that time, so this write fails. > > interrupt_init: > FF0A0FA8 e59f3010 LDR R3,ff0a0fc0 (ff0a0050=IRQ_STACK_START_IN) > > Before this patch, abort stack setup was done after relocation, so target > location is in RAM and writeable. > > interrupt_init: > 9FFB4020 e59f3010 LDR R3,9ffb4038 (9ffb3054=IRQ_STACK_START_IN) > > If I revert that patch, I don't see that problem. > > Joe Kulikauskas ___ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot
[U-Boot] [PATCH RESEND-WITH-JUSTIFICATION] spi: soft_spi: Support NULL din/dout buffers
This mirrors the conventions used in other SPI drivers (kirkwood, davinci, atmel, et al) where the din/dout buffer can be NULL when the received/transmitted data isn't important. This reduces the need for allocating additional buffers when write-only/read-only functionality is needed. In the din == NULL case, the received data is simply not stored. In the dout == NULL case, zeroes are transmitted. Signed-off-by: Andrew Ruder Cc: Jean-Christophe PLAGNIOL-VILLARD Cc: Jagan Teki --- So going through and cleaning up some of my trees and determining which patches have not been taken. A little more justification for this patch - I've gone through all of the current SPI implementations and have determined what (if any) support the driver has for half duplex operation by giving NULL for one of the two buffers (din/dout). This greatly reduces the need for temporary buffers for writing or reading large amounts of half-duplex data to devices over SPI. Here's the list: altera_spi.c - SUPPORTS NULL din or dout andes_spi.c - REQUIRES NULL din or dout armada100_spi.c - SUPPORTS NULL din or dout atmel_spi.c - SUPPORTS NULL din or dout bfin_spi6xx.c - SUPPORTS NULL din or dout bfin_spi.c- SUPPORTS NULL din or dout cf_qspi.c - SUPPORTS NULL din or dout cf_spi.c - SUPPORTS NULL din or dout davinci_spi.c - SUPPORTS NULL din or dout exynos_spi.c - SUPPORTS NULL din or dout fdt_spi.c-tegra20_sf - SUPPORTS NULL din or dout fdt_spi.c-tegra20_sl - SUPPORTS NULL din or dout fdt_spi.c-tegra114- SUPPORTS NULL din or dout fsl_espi.c- SUPPORTS NULL din (NOT dout) ftssp010_spi.c- SUPPORTS NULL din or dout ich.c - SUPPORTS NULL din or dout kirkwood_spi.c- SUPPORTS NULL din or dout mpc52xx_spi.c - NO SUPPORT mpc8xxx_spi.c - NO SUPPORT mxc_spi.c - NO SUPPORT mxs_spi.c - REQUIRES NULL din or dout oc_tiny_spi.c - SUPPORTS NULL din or dout omap3_spi.c - SUPPORTS NULL din or dout sandbox_spi.c - SUPPORTS NULL din or dout sh_qspi.c - SUPPORTS NULL din or dout sh_spi.c - SUPPORTS NULL din or dout soft_spi.c- NO SUPPORT ti_qspi.c - SUPPORTS NULL din or dout xilinx_spi.c - SUPPORTS NULL din or dout zynq_spi.c- SUPPORTS NULL din or dout Furthermore, this would not affect any board already using temporary buffers and it would continue to work as usual. The *only* obscure corner case that this will not work is if NULL (0x0) is a valid buffer address in your system and you are transferring SPI to/from it. This seems very unlikely and would probably break in other ways from library functions that check their arguments. drivers/spi/soft_spi.c | 18 +- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/drivers/spi/soft_spi.c b/drivers/spi/soft_spi.c index 5d22351..5fdd091 100644 --- a/drivers/spi/soft_spi.c +++ b/drivers/spi/soft_spi.c @@ -137,9 +137,15 @@ int spi_xfer(struct spi_slave *slave, unsigned int bitlen, * Check if it is time to work on a new byte. */ if((j % 8) == 0) { - tmpdout = *txd++; + if (txd) { + tmpdout = *txd++; + } else { + tmpdout = 0; + } if(j != 0) { - *rxd++ = tmpdin; + if (rxd) { + *rxd++ = tmpdin; + } } tmpdin = 0; } @@ -164,9 +170,11 @@ int spi_xfer(struct spi_slave *slave, unsigned int bitlen, * bits over to left-justify them. Then store the last byte * read in. */ - if((bitlen % 8) != 0) - tmpdin <<= 8 - (bitlen % 8); - *rxd++ = tmpdin; + if (rxd) { + if((bitlen % 8) != 0) + tmpdin <<= 8 - (bitlen % 8); + *rxd++ = tmpdin; + } if (flags & SPI_XFER_END) spi_cs_deactivate(slave); -- 1.9.0.rc3.12.gbc97e2d ___ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot
Re: [U-Boot] [PATCH RESEND-WITH-JUSTIFICATION] spi: soft_spi: Support NULL din/dout buffers
I further justify this with a list of drivers that depend on half-duplex SPI operation: drivers/mmc/mmc_spi.c: spi_xfer(spi, 2 * 8, tok, NULL, 0); drivers/mtd/spi/eeprom_m95xxx.c:if (spi_xfer(slave, 8, buf, NULL, SPI_XFER_BEGIN | SPI_XFER_END)) drivers/mtd/spi/sf_ops.c: ret = spi_xfer(spi, 8, NULL, &status, 0); drivers/net/e1000_spi.c:return e1000_spi_xfer(hw, 8*sizeof(op), op, NULL, intr); drivers/net/enc28j60.c: spi_xfer(enc->slave, 2 * 8, dout, NULL, drivers/rtc/m41t94.c: ret = spi_xfer(slave, 64, buf, NULL, SPI_XFER_BEGIN | SPI_XFER_END); And an old email first highlighting this issue in 2010 with the soft_spi driver: http://article.gmane.org/gmane.comp.boot-loaders.u-boot/75839/match=soft_spi ___ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot
Re: [U-Boot] [PATCH RESEND-WITH-JUSTIFICATION] spi: soft_spi: Support NULL din/dout buffers
On Fri, Apr 11, 2014 at 12:24:20AM +0530, Jagan Teki wrote: > At-least from zynq_spi.c case - I wouldn't find that obscure case as you > pointed > and even with dout NULL which is status poll from (sf_ops.c). zynq_spi is correct, soft_spi is not. zynq_spi.c: int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *dout, void *din, unsigned long flags) { const u8 *tx_buf = dout; u8 *rx_buf = din, buf; [...] if (tx_buf) buf = *tx_buf++; else buf = 0; [...] if (rx_buf) *rx_buf++ = buf; [...] > It would be great if you mentioned issue scenario for status poll case > drivers/mtd/spi/sf_ops.c: ret = spi_xfer(spi, 8, NULL, > &status, 0); That breaks on soft_spi, hence the patch. Cheers, Andy ___ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot
Re: [U-Boot] [PATCH RESEND-WITH-JUSTIFICATION] spi: soft_spi: Support NULL din/dout buffers
On Fri, Apr 11, 2014 at 12:33:45AM +0530, Jagan Teki wrote: > >> It would be great if you mentioned issue scenario for status poll case > >> drivers/mtd/spi/sf_ops.c: ret = spi_xfer(spi, 8, NULL, > >> &status, 0); > OK - means issue only with soft_spi.c is it? Yes, and a couple other drivers. > Can you share the issue log or typical use case scenario w.r.t soft_spi.c, > I need to understand how this got resolved with your change. Yes, you actually posted one such case that will not work "correctly" with soft_spi. In the line of code you posted above, soft_spi will actually perform a read from address 0x0. In most cases, the read side isn't a huge deal, but on the write side it can cause all kinds of surprises. > I understand you assigned '0' when dout is NULL and you took the buf > only when din is !NULL. Yes, just handling NULL case to be how most drivers are handling it and how apparently most users of the spi modules (like mtd/spi/sf_ops) are clearly expecting it to work. - Andy ___ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot
[U-Boot] [PATCH v2] spi: soft_spi: Support NULL din/dout buffers
This mirrors the conventions used in other SPI drivers (kirkwood, davinci, atmel, et al) where the din/dout buffer can be NULL when the received/transmitted data isn't important. This reduces the need for allocating additional buffers when write-only/read-only functionality is needed. In the din == NULL case, the received data is simply not stored. In the dout == NULL case, zeroes are transmitted. Signed-off-by: Andrew Ruder Cc: Jean-Christophe PLAGNIOL-VILLARD Cc: Jagan Teki --- Cleaned up errors/warnings from checkpatch.pl. I'm surprised they were flagged by the script since the actual ERRORs were all on lines I didn't change but were only included in the context. scripts/checkpatch.pl 0001-spi-soft_spi-Support-NULL-din-dout-buffers.patch total: 0 errors, 0 warnings, 0 checks, 31 lines checked drivers/spi/soft_spi.c | 18 -- 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/drivers/spi/soft_spi.c b/drivers/spi/soft_spi.c index 5d22351..c969be3 100644 --- a/drivers/spi/soft_spi.c +++ b/drivers/spi/soft_spi.c @@ -136,10 +136,14 @@ int spi_xfer(struct spi_slave *slave, unsigned int bitlen, /* * Check if it is time to work on a new byte. */ - if((j % 8) == 0) { - tmpdout = *txd++; + if ((j % 8) == 0) { + if (txd) + tmpdout = *txd++; + else + tmpdout = 0; if(j != 0) { - *rxd++ = tmpdin; + if (rxd) + *rxd++ = tmpdin; } tmpdin = 0; } @@ -164,9 +168,11 @@ int spi_xfer(struct spi_slave *slave, unsigned int bitlen, * bits over to left-justify them. Then store the last byte * read in. */ - if((bitlen % 8) != 0) - tmpdin <<= 8 - (bitlen % 8); - *rxd++ = tmpdin; + if (rxd) { + if ((bitlen % 8) != 0) + tmpdin <<= 8 - (bitlen % 8); + *rxd++ = tmpdin; + } if (flags & SPI_XFER_END) spi_cs_deactivate(slave); -- 1.9.0.rc3.12.gbc97e2d ___ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot
[U-Boot] [PATCH] ubi: reset relevant globals in ubi_exit()
Before calling ubi_init() the U-Boot wrapper calls ubi_mtd_param_parse() to have the UBI driver add it to its mtd_dev_param[] array and increment mtd_devs. The first time ubi_init() is called, mtd_devs would be 1. Before ubi_init() is called again (another partition is attached), ubi_mtd_param_parse() is called again, incrementing mtd_devs again (now 2). This results in ubi_init() now trying to attach the first partition and the second partition. Fix this by adding a section at the end of ubi_exit() where we reset any globals that would need to be reset (in this case, just mtd_devs). Test case: $ ubi part ; ubi part Before patch: $ ubi part data UBI: attaching mtd1 to ubi0 UBI: scanning is finished UBI: attached mtd1 (name "mtd=4", size 4 MiB) to ubi0 [...] UBI: available PEBs: 0, total reserved PEBs: 32, [...] $ ubi part data UBI: detaching mtd1 from ubi0 UBI: mtd1 is detached from ubi0 UBI: attaching mtd1 to ubi0 [...] UBI: available PEBs: 0, total reserved PEBs: 32, [...] ** Note that this is where it tries to attach mtd1 again, fails, and ** then detaches everything as it errors out of ubi_init() UBI: detaching mtd1 from ubi0 UBI: mtd1 is detached from ubi0 UBI init error 17 $ After patch: $ ubi part data UBI: attaching mtd1 to ubi0 UBI: scanning is finished UBI: attached mtd1 (name "mtd=4", size 4 MiB) to ubi0 [...] UBI: available PEBs: 0, total reserved PEBs: 32, [...] $ ubi part data UBI: detaching mtd1 from ubi0 UBI: mtd1 is detached from ubi0 UBI: attaching mtd1 to ubi0 UBI: scanning is finished UBI: attached mtd1 (name "mtd=4", size 4 MiB) to ubi0 [...] UBI: available PEBs: 0, total reserved PEBs: 32, [...] $ Signed-off-by: Andrew Ruder Cc: Heiko Schocher Cc: Kyungmin Park --- drivers/mtd/ubi/build.c | 4 1 file changed, 4 insertions(+) Not sure this is the best place to make the change, but it is one of the least obtrusive, IMO. Please Cc: me on any responses as it will go directly to my inbox! diff --git a/drivers/mtd/ubi/build.c b/drivers/mtd/ubi/build.c index 584cf5f..fc5cbce 100644 --- a/drivers/mtd/ubi/build.c +++ b/drivers/mtd/ubi/build.c @@ -1384,6 +1384,10 @@ void ubi_exit(void) misc_deregister(&ubi_ctrl_cdev); class_remove_file(ubi_class, &ubi_version); class_destroy(ubi_class); +#ifdef __UBOOT__ + /* Reset any globals that the driver depends on being zeroed */ + mtd_devs = 0; +#endif } module_exit(ubi_exit); -- 2.1.1 ___ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot
Re: [U-Boot] [PATCH] ubi: reset relevant globals in ubi_exit()
On 11/14/2014 12:20 AM, Heiko Schocher wrote: > Good catch, but wondering, why this not poped up in my tests, as I > did such a test ... Are you on 2014.10? I don't think this issue existed on the 2014.07-rc3 I was using earlier. - Andy ___ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot
Re: [U-Boot] [U-Boot,1/3] arm: pxa: use common timer functions
On 08/30/2014 10:13 AM, Tom Rini wrote: > As it stands today this breaks building a number of PXA boards so it > needs to be picked up and re-worked / build tested, thanks! I'm still planning on getting back to this and taking a look. At the time I was on a slightly older version of U-Boot (2014.07-rc3 I think) and hadn't yet figured out what was going on with all of the Kconfig changes so mostly just made sure it applied cleanly on HEAD. My apologies! - Andy ___ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot
[U-Boot] [PATCH v2] arm: pxa: use common timer functions
From: Andrew Ruder This patch moves pxa to the common timer functions added in commit 8dfafdd - Introduce common timer functions The (removed) pxa timer code (specifically __udelay()) could deadlock at the 32-bit boundary of get_ticks(). get_ticks() returned a 32-bit value cast up to a 64-bit value. If get_ticks() + tmo in __udelay() crossed the 32-bit boundary, the while condition became unconditionally true and locked the processor. Rather than patch the specific pxa issues, simply move everything over to the common code. Signed-off-by: Andrew Ruder Cc: Marek Vasut Cc: Tom Rini --- FIRST VERSION AVAILABLE AT: http://article.gmane.org/gmane.comp.boot-loaders.u-boot/192978 I missed some compile-testing last time and didn't notice that not every board includes configs/pxa-common.h. Rather than try to fix-up every board config (and possibly break out of tree ones, etc.), add a PXA-specific config.h. In any case, it must be something included via common.h as the generic time framework requires the CONFIG_SYS_TIMER_COUNTER definition. One potential gotcha here is that now pxa-regs gets included via common.h which adds lots of short register names to the global namespace. Compile-tested every PXA board from the generated boards.cfg and didn't see any issues. Board-tested the PXA270. checkpatch output: total: 0 errors, 0 warnings, 0 checks, 75 lines checked NOTE: Ignored message types: COMPLEX_MACRO CONSIDER_KSTRTO MINMAX MULTISTATEMENT_MACRO_USE_DO_WHILE NETWORKING_BLOCK_COMMENT_STYLE USLEEP_RANGE 0001-arm-pxa-use-common-timer-functions.patch has no obvious style problems and is ready for submission. arch/arm/cpu/pxa/timer.c | 69 +- arch/arm/include/asm/arch-pxa/config.h | 25 arch/arm/include/asm/config.h | 5 ++- 3 files changed, 30 insertions(+), 69 deletions(-) create mode 100644 arch/arm/include/asm/arch-pxa/config.h diff --git a/arch/arm/cpu/pxa/timer.c b/arch/arm/cpu/pxa/timer.c index c4717de..11fefd5 100644 --- a/arch/arm/cpu/pxa/timer.c +++ b/arch/arm/cpu/pxa/timer.c @@ -6,80 +6,13 @@ * SPDX-License-Identifier:GPL-2.0+ */ -#include #include #include -#include DECLARE_GLOBAL_DATA_PTR; -#defineTIMER_LOAD_VAL 0x - -#definetimestamp (gd->arch.tbl) -#definelastinc (gd->arch.lastinc) - -#if defined(CONFIG_CPU_PXA27X) || defined(CONFIG_CPU_MONAHANS) -#defineTIMER_FREQ_HZ 325 -#elif defined(CONFIG_CPU_PXA25X) -#defineTIMER_FREQ_HZ 3686400 -#else -#error "Timer frequency unknown - please config PXA CPU type" -#endif - -static unsigned long long tick_to_time(unsigned long long tick) -{ - return lldiv(tick * CONFIG_SYS_HZ, TIMER_FREQ_HZ); -} - -static unsigned long long us_to_tick(unsigned long long us) -{ - return lldiv(us * TIMER_FREQ_HZ, 100); -} - int timer_init(void) { - writel(0, OSCR); + writel(0, CONFIG_SYS_TIMER_COUNTER); return 0; } - -unsigned long long get_ticks(void) -{ - /* Current tick value */ - uint32_t now = readl(OSCR); - - if (now >= lastinc) { - /* -* Normal mode (non roll) -* Move stamp forward with absolute diff ticks -*/ - timestamp += (now - lastinc); - } else { - /* We have rollover of incrementer */ - timestamp += (TIMER_LOAD_VAL - lastinc) + now; - } - - lastinc = now; - return timestamp; -} - -ulong get_timer(ulong base) -{ - return tick_to_time(get_ticks()) - base; -} - -void __udelay(unsigned long usec) -{ - unsigned long long tmp; - ulong tmo; - - tmo = us_to_tick(usec); - tmp = get_ticks() + tmo;/* get current timestamp */ - - while (get_ticks() < tmp) /* loop till event */ -/*NOP*/; -} - -ulong get_tbclk(void) -{ - return TIMER_FREQ_HZ; -} diff --git a/arch/arm/include/asm/arch-pxa/config.h b/arch/arm/include/asm/arch-pxa/config.h new file mode 100644 index 000..5836945 --- /dev/null +++ b/arch/arm/include/asm/arch-pxa/config.h @@ -0,0 +1,25 @@ +/* + * Copyright (C) 2014 Andrew Ruder + * + * SPDX-License-Identifier:GPL-2.0+ + */ + +#ifndef _ASM_ARM_PXA_CONFIG_ +#define _ASM_ARM_PXA_CONFIG_ + +#include + +/* + * Generic timer support + */ +#if defined(CONFIG_CPU_PXA27X) || defined(CONFIG_CPU_MONAHANS) +#defineCONFIG_SYS_TIMER_RATE 325 +#elif defined(CONFIG_CPU_PXA25X) +#defineCONFIG_SYS_TIMER_RATE 3686400 +#else +#error "Timer frequency unknown - please config PXA CPU type" +#endif + +#define CONFIG_SYS_TIMER_COUNTER OSCR + +#endif /* _ASM_ARM_PXA_CONFIG_ */ diff --git a/arch/arm/include/asm/config.h b/arch/arm/include/asm/config.h index be80434..1cfc83b 100644 --- a/arch/arm/include/asm/config.h +++ b/arch/arm/include/asm/config.h @@ -23,7 +23,10 @@ #incl
[U-Boot] [PATCH v2] arm: pxa: use common timer functions
This patch moves pxa to the common timer functions added in commit 8dfafdd - Introduce common timer functions The (removed) pxa timer code (specifically __udelay()) could deadlock at the 32-bit boundary of get_ticks(). get_ticks() returned a 32-bit value cast up to a 64-bit value. If get_ticks() + tmo in __udelay() crossed the 32-bit boundary, the while condition became unconditionally true and locked the processor. Rather than patch the specific pxa issues, simply move everything over to the common code. Signed-off-by: Andrew Ruder Cc: Marek Vasut Cc: Tom Rini --- FIRST VERSION AVAILABLE AT: http://article.gmane.org/gmane.comp.boot-loaders.u-boot/192978 I missed some compile-testing last time and didn't notice that not every board includes configs/pxa-common.h. Rather than try to fix-up every board config (and possibly break out of tree ones, etc.), add a PXA-specific config.h. In any case, it must be something included via common.h as the generic time framework requires the CONFIG_SYS_TIMER_COUNTER definition. One potential gotcha here is that now pxa-regs gets included via common.h which adds lots of short register names to the global namespace. Compile-tested every PXA board from the generated boards.cfg and didn't see any issues. Board-tested the PXA270. checkpatch output: total: 0 errors, 0 warnings, 0 checks, 75 lines checked NOTE: Ignored message types: COMPLEX_MACRO CONSIDER_KSTRTO MINMAX MULTISTATEMENT_MACRO_USE_DO_WHILE NETWORKING_BLOCK_COMMENT_STYLE USLEEP_RANGE 0001-arm-pxa-use-common-timer-functions.patch has no obvious style problems and is ready for submission. arch/arm/cpu/pxa/timer.c | 69 +- arch/arm/include/asm/arch-pxa/config.h | 25 arch/arm/include/asm/config.h | 5 ++- 3 files changed, 30 insertions(+), 69 deletions(-) create mode 100644 arch/arm/include/asm/arch-pxa/config.h diff --git a/arch/arm/cpu/pxa/timer.c b/arch/arm/cpu/pxa/timer.c index c4717de..11fefd5 100644 --- a/arch/arm/cpu/pxa/timer.c +++ b/arch/arm/cpu/pxa/timer.c @@ -6,80 +6,13 @@ * SPDX-License-Identifier:GPL-2.0+ */ -#include #include #include -#include DECLARE_GLOBAL_DATA_PTR; -#defineTIMER_LOAD_VAL 0x - -#definetimestamp (gd->arch.tbl) -#definelastinc (gd->arch.lastinc) - -#if defined(CONFIG_CPU_PXA27X) || defined(CONFIG_CPU_MONAHANS) -#defineTIMER_FREQ_HZ 325 -#elif defined(CONFIG_CPU_PXA25X) -#defineTIMER_FREQ_HZ 3686400 -#else -#error "Timer frequency unknown - please config PXA CPU type" -#endif - -static unsigned long long tick_to_time(unsigned long long tick) -{ - return lldiv(tick * CONFIG_SYS_HZ, TIMER_FREQ_HZ); -} - -static unsigned long long us_to_tick(unsigned long long us) -{ - return lldiv(us * TIMER_FREQ_HZ, 100); -} - int timer_init(void) { - writel(0, OSCR); + writel(0, CONFIG_SYS_TIMER_COUNTER); return 0; } - -unsigned long long get_ticks(void) -{ - /* Current tick value */ - uint32_t now = readl(OSCR); - - if (now >= lastinc) { - /* -* Normal mode (non roll) -* Move stamp forward with absolute diff ticks -*/ - timestamp += (now - lastinc); - } else { - /* We have rollover of incrementer */ - timestamp += (TIMER_LOAD_VAL - lastinc) + now; - } - - lastinc = now; - return timestamp; -} - -ulong get_timer(ulong base) -{ - return tick_to_time(get_ticks()) - base; -} - -void __udelay(unsigned long usec) -{ - unsigned long long tmp; - ulong tmo; - - tmo = us_to_tick(usec); - tmp = get_ticks() + tmo;/* get current timestamp */ - - while (get_ticks() < tmp) /* loop till event */ -/*NOP*/; -} - -ulong get_tbclk(void) -{ - return TIMER_FREQ_HZ; -} diff --git a/arch/arm/include/asm/arch-pxa/config.h b/arch/arm/include/asm/arch-pxa/config.h new file mode 100644 index 000..5836945 --- /dev/null +++ b/arch/arm/include/asm/arch-pxa/config.h @@ -0,0 +1,25 @@ +/* + * Copyright (C) 2014 Andrew Ruder + * + * SPDX-License-Identifier:GPL-2.0+ + */ + +#ifndef _ASM_ARM_PXA_CONFIG_ +#define _ASM_ARM_PXA_CONFIG_ + +#include + +/* + * Generic timer support + */ +#if defined(CONFIG_CPU_PXA27X) || defined(CONFIG_CPU_MONAHANS) +#defineCONFIG_SYS_TIMER_RATE 325 +#elif defined(CONFIG_CPU_PXA25X) +#defineCONFIG_SYS_TIMER_RATE 3686400 +#else +#error "Timer frequency unknown - please config PXA CPU type" +#endif + +#define CONFIG_SYS_TIMER_COUNTER OSCR + +#endif /* _ASM_ARM_PXA_CONFIG_ */ diff --git a/arch/arm/include/asm/config.h b/arch/arm/include/asm/config.h index be80434..1cfc83b 100644 --- a/arch/arm/include/asm/config.h +++ b/arch/arm/include/asm/config.h @@ -23,7 +23,10 @@ #include #e
Re: [U-Boot] [PATCH v2] arm: pxa: use common timer functions
Please ignore this one as it has the messed up From: line without the author name. Sorry for the noise. - Andy ___ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot
[U-Boot] [PATCH 0/3] DM9000 support for multiple interfaces
This is a rework of the DM9000 driver to support registering interfaces dynamically (i.e. determine how many ethernet chips we have at boot and register 0, 1, 2, or more). It was tested on a yet-to-be-submitted board which is based on the PXA270 + 0, 1, or 2 DM9000 chips. To maintain backwards compatibility with older board files, we add a new initialize function taking the io address, data address, and availability of a SROM chip. The old initialize function is now a shim around this new initialize function but provides the parameters based on the old DM9000 preprocessor symbols. I have compile-tested this on all the arm-based boards. Cc: Joe Hershberger Andrew Ruder (3): dm9000: mark dump_regs() function as unused dm9000: Add struct eth_device * to SROM functions dm9000: rework dm9000 to support multiple devices board/trizepsiv/eeprom.c | 5 +- drivers/net/dm9000x.c| 382 +++ include/dm9000.h | 8 +- include/netdev.h | 1 + 4 files changed, 224 insertions(+), 172 deletions(-) -- 2.1.1 ___ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot
[U-Boot] [PATCH 2/3] dm9000: Add struct eth_device * to SROM functions
Currently this argument is not used. To eventually support multiple DM9000's these public-facing functions will need a new argument - the ethernet device. Fix-up the one board using this part of the DM9000 API. Compile-tested only. Signed-off-by: Andrew Ruder Cc: Joe Hershberger Cc: Stefano Babic --- board/trizepsiv/eeprom.c | 5 +++-- drivers/net/dm9000x.c| 10 +- include/dm9000.h | 8 3 files changed, 12 insertions(+), 11 deletions(-) diff --git a/board/trizepsiv/eeprom.c b/board/trizepsiv/eeprom.c index 1318edc..d9045dd 100644 --- a/board/trizepsiv/eeprom.c +++ b/board/trizepsiv/eeprom.c @@ -8,6 +8,7 @@ #include #include #include +#include static int do_read_dm9000_eeprom ( cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { unsigned int i; @@ -16,7 +17,7 @@ static int do_read_dm9000_eeprom ( cmd_tbl_t *cmdtp, int flag, int argc, char * for (i=0; i < 0x40; i++) { if (!(i % 0x10)) printf("\n%08x:", i); - dm9000_read_srom_word(i, data); + dm9000_read_srom_word(eth_get_dev_by_index(0), i, data); printf(" %02x%02x", data[1], data[0]); } printf ("\n"); @@ -35,7 +36,7 @@ static int do_write_dm9000_eeprom ( cmd_tbl_t *cmdtp, int flag, int argc, char * printf("Wrong offset : 0x%x\n",offset); return cmd_usage(cmdtp); } - dm9000_write_srom_word(offset, value); + dm9000_write_srom_word(eth_get_dev_by_index(0), offset, value); return (0); } diff --git a/drivers/net/dm9000x.c b/drivers/net/dm9000x.c index 50a36f3..230f368 100644 --- a/drivers/net/dm9000x.c +++ b/drivers/net/dm9000x.c @@ -534,9 +534,9 @@ static int dm9000_rx(struct eth_device *netdev) /* Read a word data from SROM */ -#if !defined(CONFIG_DM9000_NO_SROM) -void dm9000_read_srom_word(int offset, u8 *to) +void dm9000_read_srom_word(struct eth_device *dev, int offset, u8 *to) { + (void)dev; DM9000_iow(DM9000_EPAR, offset); DM9000_iow(DM9000_EPCR, 0x4); udelay(8000); @@ -545,8 +545,9 @@ void dm9000_read_srom_word(int offset, u8 *to) to[1] = DM9000_ior(DM9000_EPDRH); } -void dm9000_write_srom_word(int offset, u16 val) +void dm9000_write_srom_word(struct eth_device *dev, int offset, u16 val) { + (void)dev; DM9000_iow(DM9000_EPAR, offset); DM9000_iow(DM9000_EPDRH, ((val >> 8) & 0xff)); DM9000_iow(DM9000_EPDRL, (val & 0xff)); @@ -554,14 +555,13 @@ void dm9000_write_srom_word(int offset, u16 val) udelay(8000); DM9000_iow(DM9000_EPCR, 0); } -#endif static void dm9000_get_enetaddr(struct eth_device *dev) { #if !defined(CONFIG_DM9000_NO_SROM) int i; for (i = 0; i < 3; i++) - dm9000_read_srom_word(i, dev->enetaddr + (2 * i)); + dm9000_read_srom_word(dev, i, dev->enetaddr + (2 * i)); #endif } diff --git a/include/dm9000.h b/include/dm9000.h index 42b04fa..825c32a 100644 --- a/include/dm9000.h +++ b/include/dm9000.h @@ -8,10 +8,10 @@ #ifndef __DM9000_H__ #define __DM9000_H__ +struct eth_device; + /** function prototypes **/ -#if !defined(CONFIG_DM9000_NO_SROM) -void dm9000_write_srom_word(int offset, u16 val); -void dm9000_read_srom_word(int offset, u8 *to); -#endif +void dm9000_write_srom_word(struct eth_device *dev, int offset, u16 val); +void dm9000_read_srom_word(struct eth_device *dev, int offset, u8 *to); #endif /* __DM9000_H__ */ -- 2.1.1 ___ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot
[U-Boot] [PATCH 1/3] dm9000: mark dump_regs() function as unused
dump_regs() is a handy function to keep around for bringing up a new dm9000-based board, but defining CONFIG_DM9000_DEBUG only adds the function - nowhere currently uses it. Rather than remove a potentially useful function, let's just tell gcc to not emit a warning when it is unused. Signed-off-by: Andrew Ruder Cc: Joe Hershberger --- drivers/net/dm9000x.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/dm9000x.c b/drivers/net/dm9000x.c index 4de9d41..50a36f3 100644 --- a/drivers/net/dm9000x.c +++ b/drivers/net/dm9000x.c @@ -126,7 +126,7 @@ static void DM9000_iow(int reg, u8 value); #ifdef CONFIG_DM9000_DEBUG static void -dump_regs(void) +dump_regs(void) __attribute__ ((unused)) { DM9000_DBG("\n"); DM9000_DBG("NCR (0x00): %02x\n", DM9000_ior(0)); -- 2.1.1 ___ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot
[U-Boot] [PATCH 3/3] dm9000: rework dm9000 to support multiple devices
The DM9000 was hard-coded to only support one DM9000 device. This patch adds a new initialization function - dm9000_initialize_ex() - to support registering multiple (and possibly dynamic) numbers of dm9000 devices. This patch consists of: * Change the board_info struct to a private struct under eth_device. * Add io address/data address/srom availability information to this private struct. * Replace all uses of DM9000_IO/DM9000_DATA with new members, ensure that the eth_device struct propagates down to all helper functions. * Make dm9000_initialize() call dm9000_initialize_ex() with filled in information from the old preprocessor symbols (DM9000_IO, DM9000_DATA, etc.) Overall the following parameters have been moved over to being a per-chip setting: DM9000_IO, DM9000_DATA, CONFIG_DM9000_NO_SROM while the following is still a global setting affecting all chips: CONFIG_DM9000_BYTE_SWAPPED And the following has been removed entirely: CONFIG_DM9000_BASE (was only used in a single printf) Signed-off-by: Andrew Ruder Cc: Joe Hershberger --- drivers/net/dm9000x.c | 378 -- include/netdev.h | 1 + 2 files changed, 215 insertions(+), 164 deletions(-) diff --git a/drivers/net/dm9000x.c b/drivers/net/dm9000x.c index 230f368..2ed3121 100644 --- a/drivers/net/dm9000x.c +++ b/drivers/net/dm9000x.c @@ -55,6 +55,7 @@ TODO: external MII is not functional, only internal at the moment. #include #include #include +#include #include "dm9000x.h" @@ -80,7 +81,9 @@ TODO: external MII is not functional, only internal at the moment. #endif /* Structure/enum declaration --- */ -typedef struct board_info { +struct dm9000_priv { + ulong data_base; + ulong io_base; u32 runt_length_counter;/* counter: RX length < 64byte */ u32 long_length_counter;/* counter: RX length > 1514byte */ u32 reset_counter; /* counter: RESET */ @@ -89,23 +92,22 @@ typedef struct board_info { u16 tx_pkt_cnt; u16 queue_start_addr; u16 dbug_cnt; + u8 has_srom; u8 phy_addr; u8 device_wait_reset; /* device state */ unsigned char srom[128]; - void (*outblk)(volatile void *data_ptr, int count); - void (*inblk)(void *data_ptr, int count); - void (*rx_status)(u16 *RxStatus, u16 *RxLen); - struct eth_device netdev; -} board_info_t; -static board_info_t dm9000_info; + void (*outblk)(struct eth_device *dev, volatile void *data_ptr, int count); + void (*inblk)(struct eth_device *dev, void *data_ptr, int count); + void (*rx_status)(struct eth_device *dev, u16 *RxStatus, u16 *RxLen); +}; /* function declaration - */ -static int dm9000_probe(void); -static u16 dm9000_phy_read(int); -static void dm9000_phy_write(int, u16); -static u8 DM9000_ior(int); -static void DM9000_iow(int reg, u8 value); +static int dm9000_probe(struct eth_device *); +static u16 dm9000_phy_read(struct eth_device *, int); +static void dm9000_phy_write(struct eth_device *, int, u16); +static u8 DM9000_ior(struct eth_device *, int); +static void DM9000_iow(struct eth_device *, int reg, u8 value); /* DM9000 network board routine */ #ifndef CONFIG_DM9000_BYTE_SWAPPED @@ -126,125 +128,138 @@ static void DM9000_iow(int reg, u8 value); #ifdef CONFIG_DM9000_DEBUG static void -dump_regs(void) __attribute__ ((unused)) +dump_regs(struct eth_device *dev) __attribute__ ((unused)) { DM9000_DBG("\n"); - DM9000_DBG("NCR (0x00): %02x\n", DM9000_ior(0)); - DM9000_DBG("NSR (0x01): %02x\n", DM9000_ior(1)); - DM9000_DBG("TCR (0x02): %02x\n", DM9000_ior(2)); - DM9000_DBG("TSRI (0x03): %02x\n", DM9000_ior(3)); - DM9000_DBG("TSRII (0x04): %02x\n", DM9000_ior(4)); - DM9000_DBG("RCR (0x05): %02x\n", DM9000_ior(5)); - DM9000_DBG("RSR (0x06): %02x\n", DM9000_ior(6)); - DM9000_DBG("ISR (0xFE): %02x\n", DM9000_ior(DM9000_ISR)); + DM9000_DBG("NCR (0x00): %02x\n", DM9000_ior(dev, 0)); + DM9000_DBG("NSR (0x01): %02x\n", DM9000_ior(dev, 1)); + DM9000_DBG("TCR (0x02): %02x\n", DM9000_ior(dev, 2)); + DM9000_DBG("TSRI (0x03): %02x\n", DM9000_ior(dev, 3)); + DM9000_DBG("TSRII (0x04): %02x\n", DM9000_ior(dev, 4)); + DM9000_DBG("RCR (0x05): %02x\n", DM9000_ior(dev, 5)); + DM9000_DBG("RSR (0x06): %02x\n", DM9000_ior(dev, 6)); + DM9000_DBG("ISR (0xFE): %02x\n", DM9000_ior(dev, DM9000_ISR)); DM9000_DBG("\n"); } #endif -static void dm9000_outblk_8bit(volatile void *data_ptr, int count) +static void dm9000_outblk_8bit(struct eth_de
Re: [U-Boot] [PATCH 3/3] dm9000: rework dm9000 to support multiple devices
This one triggered a whole bunch of check-patch issues that I need to clean-up mostly due to dm9000x.c not originally meeting all of the coding conventions. I'll send a V2 of this momentarily. - Andy ___ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot
[U-Boot] [PATCH 3/3 V2] dm9000: rework dm9000 to support multiple devices
The DM9000 was hard-coded to only support one DM9000 device. This patch adds a new initialization function - dm9000_initialize_ex() - to support registering multiple (and possibly dynamic) numbers of dm9000 devices. This patch consists of: * Change the board_info struct to a private struct under eth_device. * Add io address/data address/srom availability information to this private struct. * Replace all uses of DM9000_IO/DM9000_DATA with new members, ensure that the eth_device struct propagates down to all helper functions. * Make dm9000_initialize() call dm9000_initialize_ex() with filled in information from the old preprocessor symbols (DM9000_IO, DM9000_DATA, etc.) Overall the following parameters have been moved over to being a per-chip setting: DM9000_IO, DM9000_DATA, CONFIG_DM9000_NO_SROM while the following is still a global setting affecting all chips: CONFIG_DM9000_BYTE_SWAPPED And the following has been removed entirely: CONFIG_DM9000_BASE (was only used in a single printf) Signed-off-by: Andrew Ruder Cc: Joe Hershberger --- Maybe a useful exercise anyway, this patch is significantly more messy with all the whitespace cleanups. See the v1 for the changes without the noise. :) drivers/net/dm9000x.c | 468 +- include/netdev.h | 1 + 2 files changed, 269 insertions(+), 200 deletions(-) diff --git a/drivers/net/dm9000x.c b/drivers/net/dm9000x.c index 230f368..89528a8 100644 --- a/drivers/net/dm9000x.c +++ b/drivers/net/dm9000x.c @@ -29,7 +29,7 @@ v1.2 03/18/2003 Weilun Huang : -- 12/15/2003 Initial port to u-boot by - Sascha Hauer + Sascha Hauer 06/03/2008 Remy Bohmer - Fixed the driver to work with DM9000A. @@ -55,6 +55,7 @@ TODO: external MII is not functional, only internal at the moment. #include #include #include +#include #include "dm9000x.h" @@ -63,24 +64,26 @@ TODO: external MII is not functional, only internal at the moment. /* #define CONFIG_DM9000_DEBUG */ #ifdef CONFIG_DM9000_DEBUG -#define DM9000_DBG(fmt,args...) printf(fmt, ##args) -#define DM9000_DMP_PACKET(func,packet,length) \ +#define DM9000_DBG(fmt, args...) printf(fmt, ##args) +#define DM9000_DMP_PACKET(func, packet, length) \ do { \ - int i; \ + int i; \ printf("%s: length: %d\n", func, length); \ for (i = 0; i < length; i++) { \ if (i % 8 == 0) \ printf("\n%s: %02x: ", func, i);\ - printf("%02x ", ((unsigned char *) packet)[i]); \ + printf("%02x ", ((unsigned char *)packet)[i]); \ } printf("\n"); \ - } while(0) + } while (0) #else -#define DM9000_DBG(fmt,args...) -#define DM9000_DMP_PACKET(func,packet,length) +#define DM9000_DBG(fmt, args...) do {} while (0) +#define DM9000_DMP_PACKET(func, packet, length) do {} while (0) #endif /* Structure/enum declaration --- */ -typedef struct board_info { +struct dm9000_priv { + ulong data_base; + ulong io_base; u32 runt_length_counter;/* counter: RX length < 64byte */ u32 long_length_counter;/* counter: RX length > 1514byte */ u32 reset_counter; /* counter: RESET */ @@ -89,32 +92,31 @@ typedef struct board_info { u16 tx_pkt_cnt; u16 queue_start_addr; u16 dbug_cnt; + u8 has_srom; u8 phy_addr; u8 device_wait_reset; /* device state */ unsigned char srom[128]; - void (*outblk)(volatile void *data_ptr, int count); - void (*inblk)(void *data_ptr, int count); - void (*rx_status)(u16 *RxStatus, u16 *RxLen); - struct eth_device netdev; -} board_info_t; -static board_info_t dm9000_info; + void (*outblk)(struct eth_device *dev, void *data_ptr, int count); + void (*inblk)(struct eth_device *dev, void *data_ptr, int count); + void (*rx_status)(struct eth_device *dev, u16 *rxstatus, u16 *rxlen); +}; /* function declaration - */ -static int dm9000_probe(void); -static u16 dm9000_phy_read(int); -static void dm9000_phy_write(int, u16); -static u8 DM9000_ior(int); -static void DM9000_iow(int reg, u8 value); +static int dm9000_probe(struct eth_device *); +static u16 dm9000_phy_read(struct eth_device *, int); +static void dm9000_phy_write(struct eth_device *, int, u16); +static u8 DM9000_ior(struct eth_device *,
Re: [U-Boot] [PATCH 2/3] dm9000: Add struct eth_device * to SROM functions
On Mon, Oct 20, 2014 at 03:17:13PM -0400, Tom Rini wrote: > You shouldn't have to add this to avoid a warning I think. And frankly, > if it does for some reason since 3/3 makes use of dev, I'm OK with a > bisect adding a trivial warning like this, rather than do compiler > games. Fair enough, the more I look at it, the more it looks like I probably missed a warning on this patch + CONFIG_DM9000_NO_SROM (defined but not used) so it is still pretty easy to trigger a warning on this patch. I'll just remove the indicated parts in v2 of the series and let the warnings get cleaned up in 3/3 as you have suggested. Will send a v2 of series in a bit after seeing if there is any feedback on the approaches used in 3/3. - Andy ___ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot
Re: [U-Boot] [PATCH 3/3 V2] dm9000: rework dm9000 to support multiple devices
On 10/20/2014 03:00 PM, Tom Rini wrote: > So, on new platforms we call dm9000_initialize with the right IO/DATA > locations for the given device, yes? I think I'd rather update everyone > else to call things the right and new way, rather than work-around > supporting both. The expectation is that new platforms would move over to dm9000_initialize_ex(), dm9000_initialize() just being a shim to use what used to be #define'd in the board config.h for backwards compatibility with older boards. There's really 3 options that I fought with: 1.) Change dm9000_initialize() to dm9000_initialize(x, y, z). PATCH #3 then also includes changes to all of the various boards. 2.) Add dm9000_initialize_ex(x, y, z), make dm9000_initialize() call dm9000_initiailize_ex(x, y, z). No boards need to change. This is what I chose. 3.) Hybrid approach, do #2, make another patch (#4) that moves everything over to dm9000_initialize_ex(x, y, z) while renaming it to dm9000_initialize(x, y, z). Seems more round-about than #1 with the same end-result, but sometimes I feel like it is a little easier to review the meat of this change (#3) without it also dealing with tons of board churn. Thoughts? - Andy ___ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot
[U-Boot] Regression with ubifs initialization
Hey all, It appears that 2014.10 has some issues with UBIFS initialization (details at bottom). git-bisect results in one of the following commits being broken. Surely it is the mtd one, but its parent commit (compat.h) does not compile. [ff94bc40af3] mtd, ubi, ubifs: resync with Linux-3.14 [0c06db59836] lib, linux: move linux specific defines to linux/compat.h A little background for the errors below. My MTD table: device nor0 <0.flash>, # parts = 5 #: namesizeoffset mask_flags 0: uboot 0x0008 0x 0 1: env 0x0002 0x0008 0 2: env_redund 0x0002 0x000a 0 3: env_factory 0x0002 0x000c 0 4: data0x0040 0x000e 0 = Older (2014.07) U-Boot, I can do something like this: $ erase nor0,4 Erase Flash Partition nor0,4, bank 0, 0x000e - 0x004d done Erased 32 sectors $ ubi part data UBI: attaching mtd1 to ubi0 UBI: physical eraseblock size: 131072 bytes (128 KiB) UBI: logical eraseblock size:130944 bytes UBI: smallest flash I/O unit:1 UBI: VID header offset: 64 (aligned 64) UBI: data offset:128 UBI: empty MTD device detected UBI: create volume table (copy #1) UBI: create volume table (copy #2) UBI: attached mtd1 to ubi0 UBI: MTD device name:"mtd=4" UBI: MTD device size:4 MiB UBI: number of good PEBs:32 UBI: number of bad PEBs: 0 UBI: max. allowed volumes: 128 UBI: wear-leveling threshold:4096 UBI: number of internal volumes: 1 UBI: number of user volumes: 0 UBI: available PEBs: 28 UBI: total number of reserved PEBs: 4 UBI: number of PEBs reserved for bad PEB handling: 0 UBI: max/mean erase counter: 1/0 $ = Newer (2014.10) U-Boot, I get the following $ erase nor0,4 Erase Flash Partition nor0,4, bank 0, 0x000e - 0x004d done Erased 32 sectors $ ubi part data UBI: attaching mtd1 to ubi0 $ ubi info UBI: MTD device name:"(a" UBI: MTD device size:18446742253448744536 MiB UBI: physical eraseblock size: -443412400 bytes (-433020 KiB) UBI: logical eraseblock size:-442945536 bytes UBI: number of good PEBs:-494718944 UBI: number of bad PEBs: -444399596 UBI: smallest flash I/O unit:-452780024 UBI: VID header offset: -444391424 (aligned -390234000) UBI: data offset:-443207680 UBI: max. allowed volumes: -509550577 UBI: wear-leveling threshold:4096 UBI: number of internal volumes: 1 UBI: number of user volumes: 479 UBI: available PEBs: -443686912 UBI: total number of reserved PEBs: -450899448 UBI: number of PEBs reserved for bad PEB handling: -514859008 UBI: max/mean erase counter: -450944464/-393084916 - Andy ___ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot
Re: [U-Boot] Regression with ubifs initialization
On Mon, Oct 27, 2014 at 03:33:00PM +0100, Wolfgang Denk wrote: > > It appears that 2014.10 has some issues with UBIFS initialization > > (details at bottom). git-bisect results in one of the following commits > > being broken. Surely it is the mtd one, but its parent commit > > (compat.h) does not compile. > > Which board are you talking about? I have a board with a PXA270 and NOR flash. I am happy to submit the patches which add the board support, but they aren't really ready and cleaned up for submission. > And which toolchain(s) are/have you been using to build U-Boot? A crosstools-ng compiled gcc 4.8.2. Would be interested to know if this is expected behavior: a.) erase flash partition b.) Call out erased partition as a ubi partition c.) ubi triggers a initialization. Because if so, that seems to no longer happen and it blindly attempts to use the erased flash as valid ubi data. - Andy ___ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot
Re: [U-Boot] Regression with ubifs initialization
On Mon, Oct 27, 2014 at 09:45:16AM -0500, Andrew Ruder wrote: > On Mon, Oct 27, 2014 at 03:33:00PM +0100, Wolfgang Denk wrote: > > > It appears that 2014.10 has some issues with UBIFS initialization > > > (details at bottom). git-bisect results in one of the following commits > > > being broken. Surely it is the mtd one, but its parent commit > > > (compat.h) does not compile. > > > > Which board are you talking about? > > I have a board with a PXA270 and NOR flash. I am happy to submit the > patches which add the board support, but they aren't really ready and > cleaned up for submission. > > > And which toolchain(s) are/have you been using to build U-Boot? > > A crosstools-ng compiled gcc 4.8.2. Wolfgang and I talked quite a bit on IRC and just catching up anyone else looking at this with a few additional details that came out of this. The problem appears to stem from 'ubi part data' completing with no errors while also not filling in any of the ubi_devices[] array. This in turn results in the global 'ubi' variable being NULL (on PXA270 this is u-boot in flash). At this point display_ubi_info() gets passed NULL and ends up printing compiler-dependent junk for all the values. That being said, I tried 4.9.1 and had the same issue (display_ubi_info() being passed NULL) with different symptoms (complete lock up because it ends up hitting data alignment issues when it starts treating opcodes as pointers). - Andy ___ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot
[U-Boot] [PATCH 2/2] mtd: nor: initialize writebufsize field
UBI drivers error out if writebufsize is not filled in correctly. Grab this information from the CFI flash_info struct. Signed-off-by: Andrew Ruder Cc: Wolfgang Denk Cc: Heiko Schocher Cc: Stefan Roese --- drivers/mtd/cfi_mtd.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/mtd/cfi_mtd.c b/drivers/mtd/cfi_mtd.c index ac805ff..d4c9609 100644 --- a/drivers/mtd/cfi_mtd.c +++ b/drivers/mtd/cfi_mtd.c @@ -226,6 +226,7 @@ int cfi_mtd_init(void) mtd->flags = MTD_CAP_NORFLASH; mtd->size = fi->size; mtd->writesize = 1; + mtd->writebufsize = fi->buffer_size; mtd->_erase = cfi_mtd_erase; mtd->_read = cfi_mtd_read; -- 2.1.1 ___ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot
[U-Boot] [PATCH 1/2] ubi: enable error reporting in initialization
The UBI layer will disable much of its error reporting when it is compiled into the linux kernel to avoid stopping boot. We want this error reporting in U-Boot since we don't initialize the UBI layer until it is used and want the error reporting. We force this by telling the UBI layer we are building as a module. Signed-off-by: Andrew Ruder Cc: Wolfgang Denk Cc: Heiko Schocher Cc: Kyungmin Park --- include/ubi_uboot.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/ubi_uboot.h b/include/ubi_uboot.h index 1fd15f4..6ff0e23 100644 --- a/include/ubi_uboot.h +++ b/include/ubi_uboot.h @@ -51,6 +51,8 @@ #undef CONFIG_MTD_UBI_BLOCK +#define CONFIG_MTD_UBI_MODULE + #if !defined(CONFIG_MTD_UBI_BEB_LIMIT) #define CONFIG_MTD_UBI_BEB_LIMIT 20 #endif -- 2.1.1 ___ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot
Re: [U-Boot] [PATCH 1/2] ubi: enable error reporting in initialization
On Wed, Nov 05, 2014 at 07:57:27AM +0100, Heiko Schocher wrote: > The problem is in generally enabling this feature in the size impact ... > This should be discussed if we want this for all boards ... This change actually only triggers a few changes that affect whether or not ubi_init() returns error codes or not. For the purpose of discussion, I've added the only places where the CONFIG_MTD_UBI_MODULE is checked (ubi_is_module()). drivers/mtd/ubi/build.c: 1: /* Attach MTD devices */ 2: for (i = 0; i < mtd_devs; i++) { 3: [...] 4: mtd = open_mtd_device(p->name); 5: if (IS_ERR(mtd)) { 6: err = PTR_ERR(mtd); 7: ubi_err("cannot open mtd %s, error %d", p->name, err); 8: /* See comment below re-ubi_is_module(). */ 9: if (ubi_is_module()) 10: goto out_detach; 11: continue; 12: } 13: 14: mutex_lock(&ubi_devices_mutex); 15: err = ubi_attach_mtd_dev(mtd, p->ubi_num, 16: p->vid_hdr_offs, p->max_beb_per1024); 17: mutex_unlock(&ubi_devices_mutex); 18: if (err < 0) { 19: ubi_err("cannot attach mtd%d", mtd->index); 20: put_mtd_device(mtd); 21: 22: /* 23: * Originally UBI stopped initializing on any error. 24: * However, later on it was found out that this 25: * behavior is not very good when UBI is compiled into 26: * the kernel and the MTD devices to attach are passed 27: * through the command line. Indeed, UBI failure 28: * stopped whole boot sequence. 29: * 30: * To fix this, we changed the behavior for the 31: * non-module case, but preserved the old behavior for 32: * the module case, just for compatibility. This is a 33: * little inconsistent, though. 34: */ 35: if (ubi_is_module()) 36: goto out_detach; 37: } 38: } 39: 40: err = ubiblock_init(); 41: if (err) { 42: ubi_err("block: cannot initialize, error %d", err); 43: 44: /* See comment above re-ubi_is_module(). */ 45: if (ubi_is_module()) 46: goto out_detach; 47: } 48: 49: return 0; 50: 51: out_detach: 52: [...] 53: return err; Note that errors at lines 5, 18, and 40 are ignored (and the function returns 0) when not building UBI as a module. This means that when an error occurs in this function, U-Boot believes it has succeeded which leads to the corruption and lock up issues. No new error messages are enabled via this change, simply making ubi_init return a proper return code. With and without this change (size check) on a ARM target: % make -j5 > /dev/null 2>&1 && wc -c u-boot.bin && git revert --no-edit ca28e16192 && make -j5 > /dev/null 2>&1 && wc -c u-boot.bin 383436 u-boot.bin [elecsys_falcon/next c9a88c1] Revert "ubi: enable error reporting in initialization" 1 file changed, 2 deletions(-) 383356 u-boot.bin % Note that it actually makes the size go down by 80 bytes on my target! > Ok, didn;t tried this with enabling "CONFIG_MTD_UBI_MODULE" ... > But the name CONFIG_MTD_UBI_MODULE is not perfect, if we want > just to enable error messages ... Agree, didn't know what the general feelings were towards making changes to the UBI layer specifically. It would be nice if the function was called ubi_allow_init_errors() instead of ubi_is_module() and checked for either __UBOOT__ or the CONFIG_MTD_UBI_MODULE being defined. Cheers, Andy ___ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot
Re: [U-Boot] [PATCH v2] mtd, cfi, ubi: add missing writebufsize initialization
On Fri, Oct 31, 2014 at 11:29:45AM +0100, Heiko Schocher wrote: > diff --git a/drivers/mtd/cfi_mtd.c b/drivers/mtd/cfi_mtd.c > index ac805ff..709a486 100644 > --- a/drivers/mtd/cfi_mtd.c > +++ b/drivers/mtd/cfi_mtd.c > @@ -226,6 +226,7 @@ int cfi_mtd_init(void) > mtd->flags = MTD_CAP_NORFLASH; > mtd->size = fi->size; > mtd->writesize = 1; > + mtd->writebufsize = mtd->writesize; Sorry I didn't see this patch up front! My only nit-pick is that this is effectively ignoring the write buffer present on many (most? all?) NOR flashes since this field is supposed to be the maximum write buffer size, not the minimum write buffer size (judging by its user ubifs and associated comments). As such, this really should be fi->buffer_size IMO, not mtd->writesize (i.e. 1). But, the only user of this field seems to be ubifs (not even ubi) for writes so I'm just not sure it really matters. Cheers, Andy ___ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot
Re: [U-Boot] [PATCH 2/2] mtd: nor: initialize writebufsize field
On Wed, Nov 05, 2014 at 08:00:21AM +0100, Heiko Schocher wrote: > >diff --git a/drivers/mtd/cfi_mtd.c b/drivers/mtd/cfi_mtd.c > >index ac805ff..d4c9609 100644 > >--- a/drivers/mtd/cfi_mtd.c > >+++ b/drivers/mtd/cfi_mtd.c > >@@ -226,6 +226,7 @@ int cfi_mtd_init(void) > > mtd->flags = MTD_CAP_NORFLASH; > > mtd->size = fi->size; > > mtd->writesize = 1; > >+mtd->writebufsize = fi->buffer_size; > ^ should be cfi > > This is a typo ... your patch would not compile ... please just > ack the patch [1], thanks! I responded on the other thread with your other patch. I apologize for not seeing it originally. This patch, imo, is correct though and definitely compiles - not a typo! - Andy ___ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot
[U-Boot] [PATCH v2] ubi: enable error reporting in initialization
The UBI layer will disable much of its error reporting when it is compiled into the linux kernel to avoid stopping boot. We want this error reporting in U-Boot since we don't initialize the UBI layer until it is used and want the error reporting. We force this by telling the UBI layer we are building as a module. Signed-off-by: Andrew Ruder Cc: Wolfgang Denk Cc: Heiko Schocher Cc: Kyungmin Park --- include/ubi_uboot.h | 8 1 file changed, 8 insertions(+) diff --git a/include/ubi_uboot.h b/include/ubi_uboot.h index 1fd15f4..324fe72 100644 --- a/include/ubi_uboot.h +++ b/include/ubi_uboot.h @@ -51,6 +51,14 @@ #undef CONFIG_MTD_UBI_BLOCK +/* ubi_init() disables returning error codes when built into the Linux + * kernel so that it doesn't hang the Linux kernel boot process. Since + * the U-Boot driver code depends on getting valid error codes from this + * function we just tell the UBI layer that we are building as a module + * (which only enables the additional error reporting). + */ +#define CONFIG_MTD_UBI_MODULE + #if !defined(CONFIG_MTD_UBI_BEB_LIMIT) #define CONFIG_MTD_UBI_BEB_LIMIT 20 #endif -- 2.1.1 ___ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot
Re: [U-Boot] [PATCH v2] mtd, cfi, ubi: add missing writebufsize initialization
On Wed, Nov 05, 2014 at 01:20:00PM -0600, Andrew Ruder wrote: > I'm just not sure it really matters. That being said: Acked-by: Andrew Ruder Cheers :), Andy ___ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot
Re: [U-Boot] [PATCH 3/3 V2] dm9000: rework dm9000 to support multiple devices
On 08/11/2015 12:58 PM, Joe Hershberger wrote: > What ever became of this series? I failed to ever email it in... I have a redone series, let me clean it up and give it a quick test and make sure it works on latest... Needed to rebase on about 10 months of upstream. ___ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot
[U-Boot] [PATCH V2 3/5] dm9000: Add struct eth_device * to SROM functions
Currently this argument is not used. To eventually support multiple DM9000's these public-facing functions will need a new argument - the ethernet device. Fix-up the one board using this part of the DM9000 API. Compile-tested only. Signed-off-by: Andrew Ruder Cc: Joe Hershberger --- board/trizepsiv/eeprom.c | 5 +++-- drivers/net/dm9000x.c| 6 +++--- include/dm9000.h | 6 -- 3 files changed, 10 insertions(+), 7 deletions(-) diff --git a/board/trizepsiv/eeprom.c b/board/trizepsiv/eeprom.c index 1318edc..d9045dd 100644 --- a/board/trizepsiv/eeprom.c +++ b/board/trizepsiv/eeprom.c @@ -8,6 +8,7 @@ #include #include #include +#include static int do_read_dm9000_eeprom ( cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { unsigned int i; @@ -16,7 +17,7 @@ static int do_read_dm9000_eeprom ( cmd_tbl_t *cmdtp, int flag, int argc, char * for (i=0; i < 0x40; i++) { if (!(i % 0x10)) printf("\n%08x:", i); - dm9000_read_srom_word(i, data); + dm9000_read_srom_word(eth_get_dev_by_index(0), i, data); printf(" %02x%02x", data[1], data[0]); } printf ("\n"); @@ -35,7 +36,7 @@ static int do_write_dm9000_eeprom ( cmd_tbl_t *cmdtp, int flag, int argc, char * printf("Wrong offset : 0x%x\n",offset); return cmd_usage(cmdtp); } - dm9000_write_srom_word(offset, value); + dm9000_write_srom_word(eth_get_dev_by_index(0), offset, value); return (0); } diff --git a/drivers/net/dm9000x.c b/drivers/net/dm9000x.c index 258c8a3..e1a10b5 100644 --- a/drivers/net/dm9000x.c +++ b/drivers/net/dm9000x.c @@ -528,7 +528,7 @@ static int dm9000_rx(struct eth_device *netdev) Read a word data from SROM */ #if !defined(CONFIG_DM9000_NO_SROM) -void dm9000_read_srom_word(int offset, u8 *to) +void dm9000_read_srom_word(struct eth_device *dev, int offset, u8 *to) { DM9000_iow(DM9000_EPAR, offset); DM9000_iow(DM9000_EPCR, 0x4); @@ -538,7 +538,7 @@ void dm9000_read_srom_word(int offset, u8 *to) to[1] = DM9000_ior(DM9000_EPDRH); } -void dm9000_write_srom_word(int offset, u16 val) +void dm9000_write_srom_word(struct eth_device *dev, int offset, u16 val) { DM9000_iow(DM9000_EPAR, offset); DM9000_iow(DM9000_EPDRH, ((val >> 8) & 0xff)); @@ -554,7 +554,7 @@ static void dm9000_get_enetaddr(struct eth_device *dev) #if !defined(CONFIG_DM9000_NO_SROM) int i; for (i = 0; i < 3; i++) - dm9000_read_srom_word(i, dev->enetaddr + (2 * i)); + dm9000_read_srom_word(dev, i, dev->enetaddr + (2 * i)); #endif } diff --git a/include/dm9000.h b/include/dm9000.h index 42b04fa..7a7e629 100644 --- a/include/dm9000.h +++ b/include/dm9000.h @@ -10,8 +10,10 @@ /** function prototypes **/ #if !defined(CONFIG_DM9000_NO_SROM) -void dm9000_write_srom_word(int offset, u16 val); -void dm9000_read_srom_word(int offset, u8 *to); +struct eth_device; + +void dm9000_write_srom_word(struct eth_device *dev, int offset, u16 val); +void dm9000_read_srom_word(struct eth_device *dev, int offset, u8 *to); #endif #endif /* __DM9000_H__ */ -- 2.1.4 ___ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot
[U-Boot] [PATCH V2 2/5] dm9000: mark dump_regs() function as unused
dump_regs() is a handy function to keep around for bringing up a new dm9000-based board, but defining CONFIG_DM9000_DEBUG only adds the function - nowhere currently uses it. Rather than remove a potentially useful function, let's just tell gcc to not emit a warning when it is unused. Signed-off-by: Andrew Ruder Cc: Joe Hershberger --- drivers/net/dm9000x.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/net/dm9000x.c b/drivers/net/dm9000x.c index 415c4b7..258c8a3 100644 --- a/drivers/net/dm9000x.c +++ b/drivers/net/dm9000x.c @@ -54,6 +54,7 @@ TODO: external MII is not functional, only internal at the moment. #include #include #include +#include #include "dm9000x.h" @@ -124,7 +125,7 @@ static void DM9000_iow(int reg, u8 value); #endif #ifdef CONFIG_DM9000_DEBUG -static void +static __maybe_unused void dump_regs(void) { DM9000_DBG("\n"); -- 2.1.4 ___ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot
[U-Boot] [PATCH V2 1/5] dm9000: whitespace cleanups
Signed-off-by: Andrew Ruder Cc: Joe Hershberger --- drivers/net/dm9000x.c | 108 -- 1 file changed, 52 insertions(+), 56 deletions(-) diff --git a/drivers/net/dm9000x.c b/drivers/net/dm9000x.c index 3c41cec..415c4b7 100644 --- a/drivers/net/dm9000x.c +++ b/drivers/net/dm9000x.c @@ -29,7 +29,7 @@ v1.2 03/18/2003 Weilun Huang : -- 12/15/2003 Initial port to u-boot by - Sascha Hauer + Sascha Hauer 06/03/2008 Remy Bohmer - Fixed the driver to work with DM9000A. @@ -46,7 +46,6 @@ v1.2 03/18/2003 Weilun Huang : - some minor code cleanups These changes are tested with DM9000{A,EP,E} together with a 200MHz Atmel AT91SAM9261 core - TODO: external MII is not functional, only internal at the moment. */ @@ -63,20 +62,20 @@ TODO: external MII is not functional, only internal at the moment. /* #define CONFIG_DM9000_DEBUG */ #ifdef CONFIG_DM9000_DEBUG -#define DM9000_DBG(fmt,args...) printf(fmt, ##args) -#define DM9000_DMP_PACKET(func,packet,length) \ +#define DM9000_DBG(fmt, args...) printf(fmt, ##args) +#define DM9000_DMP_PACKET(func, packet, length) \ do { \ - int i; \ + int i; \ printf("%s: length: %d\n", func, length); \ for (i = 0; i < length; i++) { \ if (i % 8 == 0) \ printf("\n%s: %02x: ", func, i);\ - printf("%02x ", ((unsigned char *) packet)[i]); \ + printf("%02x ", ((unsigned char *)packet)[i]); \ } printf("\n"); \ - } while(0) + } while (0) #else -#define DM9000_DBG(fmt,args...) -#define DM9000_DMP_PACKET(func,packet,length) +#define DM9000_DBG(fmt, args...) do {} while (0) +#define DM9000_DMP_PACKET(func, packet, length) do {} while (0) #endif /* Structure/enum declaration --- */ @@ -92,9 +91,9 @@ typedef struct board_info { u8 phy_addr; u8 device_wait_reset; /* device state */ unsigned char srom[128]; - void (*outblk)(volatile void *data_ptr, int count); + void (*outblk)(void *data_ptr, int count); void (*inblk)(void *data_ptr, int count); - void (*rx_status)(u16 *RxStatus, u16 *RxLen); + void (*rx_status)(u16 *rx_status, u16 *rx_len); struct eth_device netdev; } board_info_t; static board_info_t dm9000_info; @@ -109,12 +108,12 @@ static void DM9000_iow(int reg, u8 value); /* DM9000 network board routine */ #ifndef CONFIG_DM9000_BYTE_SWAPPED -#define DM9000_outb(d,r) writeb(d, (volatile u8 *)(r)) -#define DM9000_outw(d,r) writew(d, (volatile u16 *)(r)) -#define DM9000_outl(d,r) writel(d, (volatile u32 *)(r)) -#define DM9000_inb(r) readb((volatile u8 *)(r)) -#define DM9000_inw(r) readw((volatile u16 *)(r)) -#define DM9000_inl(r) readl((volatile u32 *)(r)) +#define DM9000_outb(d, r) writeb(d, (u8 *)(r)) +#define DM9000_outw(d, r) writew(d, (u16 *)(r)) +#define DM9000_outl(d, r) writel(d, (u32 *)(r)) +#define DM9000_inb(r) readb((u8 *)(r)) +#define DM9000_inw(r) readw((u16 *)(r)) +#define DM9000_inl(r) readl((u32 *)(r)) #else #define DM9000_outb(d, r) __raw_writeb(d, r) #define DM9000_outw(d, r) __raw_writew(d, r) @@ -141,35 +140,35 @@ dump_regs(void) } #endif -static void dm9000_outblk_8bit(volatile void *data_ptr, int count) +static void dm9000_outblk_8bit(void *data_ptr, int count) { int i; for (i = 0; i < count; i++) - DM9000_outbu8 *) data_ptr)[i] & 0xff), DM9000_DATA); + DM9000_outbu8 *)data_ptr)[i] & 0xff), DM9000_DATA); } -static void dm9000_outblk_16bit(volatile void *data_ptr, int count) +static void dm9000_outblk_16bit(void *data_ptr, int count) { int i; u32 tmplen = (count + 1) / 2; for (i = 0; i < tmplen; i++) - DM9000_outw(((u16 *) data_ptr)[i], DM9000_DATA); + DM9000_outw(((u16 *)data_ptr)[i], DM9000_DATA); } -static void dm9000_outblk_32bit(volatile void *data_ptr, int count) +static void dm9000_outblk_32bit(void *data_ptr, int count) { int i; u32 tmplen = (count + 3) / 4; for (i = 0; i < tmplen; i++) - DM9000_outl(((u32 *) data_ptr)[i], DM9000_DATA); + DM9000_outl(((u32 *)data_ptr)[i], DM9000_DATA); } static void dm9000_inblk_8bit(void *data_ptr, int count) { int i; for (i = 0; i <
[U-Boot] [PATCH V2 0/5] DM9000 support for multiple interfaces
This is a rework of the DM9000 driver to support registering interfaces dynamically (i.e. determine how many ethernet chips we have at boot and register 0, 1, 2, or more). It was tested on a yet-to-be-submitted board which is based on the PXA270 + 0, 1, or 2 DM9000 chips. To maintain backwards compatibility with older board files, we add a new initialize function taking the io address, data address, and availability of a SROM chip. The old initialize function is now a shim around this new initialize function but provides the parameters based on the old DM9000 preprocessor symbols. I have compile-tested this on the following: at91sam9261ek_dataflash_cs0_defconfig davinci_dm355evm_defconfig davinci_dm355leopard_defconfig lp8x4x_defconfig pm9261_defconfig scb9328_defconfig devkit8000_defconfig colibri_pxa270_defconfig trizepsiv_defconfig vpac270_nor_128_defconfig I have not compile-tested the following: M5253DEMO ip04 I have board tested this on a yet-to-be-upstreamed port of a pxa270 board that reads an i2c eeprom to determine which (and how many) ethernet chips are enabled. Cc: Joe Hershberger Andrew Ruder (5): dm9000: whitespace cleanups dm9000: mark dump_regs() function as unused dm9000: Add struct eth_device * to SROM functions dm9000: dm9000_initialize stub dm9000: rework dm9000 to support multiple devices board/altera/nios2-generic/nios2-generic.c| 3 +- board/atmel/at91sam9261ek/at91sam9261ek.c | 2 +- board/davinci/dm355evm/dm355evm.c | 2 +- board/davinci/dm355leopard/dm355leopard.c | 2 +- board/freescale/m5253demo/m5253demo.c | 2 +- board/icpdas/lp8x4x/lp8x4x.c | 2 +- board/ip04/ip04.c | 2 +- board/ronetix/pm9261/pm9261.c | 2 +- board/scb9328/scb9328.c | 2 +- board/timll/devkit8000/devkit8000.c | 2 +- board/toradex/colibri_pxa270/colibri_pxa270.c | 2 +- board/trizepsiv/conxs.c | 2 +- board/trizepsiv/eeprom.c | 5 +- board/vpac270/vpac270.c | 2 +- drivers/net/dm9000x.c | 457 +++--- include/configs/M5253DEMO.h | 1 + include/configs/at91sam9261ek.h | 3 +- include/configs/colibri_pxa270.h | 1 + include/configs/davinci_dm355evm.h| 1 + include/configs/davinci_dm355leopard.h| 1 + include/configs/devkit8000.h | 3 +- include/configs/ip04.h| 2 +- include/configs/lp8x4x.h | 2 + include/configs/pm9261.h | 2 +- include/configs/scb9328.h | 1 + include/configs/trizepsiv.h | 1 + include/configs/vpac270.h | 1 + include/dm9000.h | 8 +- include/netdev.h | 2 +- 29 files changed, 290 insertions(+), 228 deletions(-) -- 2.1.4 ___ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot
[U-Boot] [PATCH V2 4/5] dm9000: dm9000_initialize stub
Change the dm9000_initialize function to taking arguments for io address, data address, and availability of srom. Right now we aren't actually using any of this inside of drivers/net/dm9000x.c but we are making way for support for boards that have multiple (or discovered) numbers of dm9000 devices. Signed-off-by: Andrew Ruder Cc: Joe Hershberger --- board/altera/nios2-generic/nios2-generic.c| 3 +-- board/atmel/at91sam9261ek/at91sam9261ek.c | 2 +- board/davinci/dm355evm/dm355evm.c | 2 +- board/davinci/dm355leopard/dm355leopard.c | 2 +- board/freescale/m5253demo/m5253demo.c | 2 +- board/icpdas/lp8x4x/lp8x4x.c | 2 +- board/ip04/ip04.c | 2 +- board/ronetix/pm9261/pm9261.c | 2 +- board/scb9328/scb9328.c | 2 +- board/timll/devkit8000/devkit8000.c | 2 +- board/toradex/colibri_pxa270/colibri_pxa270.c | 2 +- board/trizepsiv/conxs.c | 2 +- board/vpac270/vpac270.c | 2 +- drivers/net/dm9000x.c | 2 +- include/configs/M5253DEMO.h | 1 + include/configs/at91sam9261ek.h | 3 +-- include/configs/colibri_pxa270.h | 1 + include/configs/davinci_dm355evm.h| 1 + include/configs/davinci_dm355leopard.h| 1 + include/configs/devkit8000.h | 3 +-- include/configs/ip04.h| 2 +- include/configs/lp8x4x.h | 2 ++ include/configs/pm9261.h | 2 +- include/configs/scb9328.h | 1 + include/configs/trizepsiv.h | 1 + include/configs/vpac270.h | 1 + include/netdev.h | 2 +- 27 files changed, 28 insertions(+), 22 deletions(-) diff --git a/board/altera/nios2-generic/nios2-generic.c b/board/altera/nios2-generic/nios2-generic.c index 834cbeb..d6ed636 100644 --- a/board/altera/nios2-generic/nios2-generic.c +++ b/board/altera/nios2-generic/nios2-generic.c @@ -61,8 +61,7 @@ int board_eth_init(bd_t *bis) rc += smc9_initialize(0, CONFIG_SMC9_BASE); #endif #ifdef CONFIG_DRIVER_DM9000 - rc += dm9000_initialize(bis); -#endif + rc += dm9000_initialize(0, DM9000_IO, DM9000_DATA, DM9000_HAS_SROM); #ifdef CONFIG_ALTERA_TSE rc += altera_tse_initialize(0, CONFIG_SYS_ALTERA_TSE_MAC_BASE, diff --git a/board/atmel/at91sam9261ek/at91sam9261ek.c b/board/atmel/at91sam9261ek/at91sam9261ek.c index 5250474..551f612 100644 --- a/board/atmel/at91sam9261ek/at91sam9261ek.c +++ b/board/atmel/at91sam9261ek/at91sam9261ek.c @@ -255,7 +255,7 @@ int board_init(void) #ifdef CONFIG_DRIVER_DM9000 int board_eth_init(bd_t *bis) { - return dm9000_initialize(bis); + return dm9000_initialize(0, DM9000_IO, DM9000_DATA, DM9000_HAS_SROM); } #endif diff --git a/board/davinci/dm355evm/dm355evm.c b/board/davinci/dm355evm/dm355evm.c index e5a958f..c37595d 100644 --- a/board/davinci/dm355evm/dm355evm.c +++ b/board/davinci/dm355evm/dm355evm.c @@ -74,7 +74,7 @@ int board_init(void) #ifdef CONFIG_DRIVER_DM9000 int board_eth_init(bd_t *bis) { - return dm9000_initialize(bis); + return dm9000_initialize(0, DM9000_IO, DM9000_DATA, DM9000_HAS_SROM); } #endif diff --git a/board/davinci/dm355leopard/dm355leopard.c b/board/davinci/dm355leopard/dm355leopard.c index 53902f9..e8c99f0 100644 --- a/board/davinci/dm355leopard/dm355leopard.c +++ b/board/davinci/dm355leopard/dm355leopard.c @@ -72,7 +72,7 @@ int board_init(void) #ifdef CONFIG_DRIVER_DM9000 int board_eth_init(bd_t *bis) { - return dm9000_initialize(bis); + return dm9000_initialize(0, DM9000_IO, DM9000_DATA, DM9000_HAS_SROM); } #endif diff --git a/board/freescale/m5253demo/m5253demo.c b/board/freescale/m5253demo/m5253demo.c index 7e516bf..dfe3c0c 100644 --- a/board/freescale/m5253demo/m5253demo.c +++ b/board/freescale/m5253demo/m5253demo.c @@ -135,6 +135,6 @@ void ide_set_reset(int idereset) #ifdef CONFIG_DRIVER_DM9000 int board_eth_init(bd_t *bis) { - return dm9000_initialize(bis); + return dm9000_initialize(0, DM9000_IO, DM9000_DATA, DM9000_HAS_SROM); } #endif diff --git a/board/icpdas/lp8x4x/lp8x4x.c b/board/icpdas/lp8x4x/lp8x4x.c index a136dc4..88099fe 100644 --- a/board/icpdas/lp8x4x/lp8x4x.c +++ b/board/icpdas/lp8x4x/lp8x4x.c @@ -123,6 +123,6 @@ int board_usb_cleanup(int index, enum usb_init_type init) #ifdef CONFIG_DRIVER_DM9000 int board_eth_init(bd_t *bis) { - return dm9000_initialize(bis); + return dm9000_initialize(0, DM9000_IO, DM9000_DATA, DM9000_HAS_SROM); } #endif diff --git a/board/ip04/ip04.c b/board/ip04/ip04.c index 70765bc..0de71aa 100644 --- a/board/ip04/ip04.c +++ b/board/ip04/ip04.c @@ -24,6 +24,6 @@ int checkboard(void) #ifdef CONFIG_DRIVER_DM9000 int board_eth_init(bd_t *bis) { - return dm9000_initi
[U-Boot] [PATCH V2 5/5] dm9000: rework dm9000 to support multiple devices
The DM9000 was hard-coded to only support one DM9000 device. This patch changes the initialization function - dm9000_initialize - to support registering multiple (and possibly dynamic) numbers of dm9000 devices. This patch consists of: * Change the board_info struct to a private struct under eth_device. * Add io address/data address/srom availability information to this private struct. * Replace all uses of DM9000_IO/DM9000_DATA with new members, ensure that the eth_device struct propagates down to all helper functions. * Call dm9000_initialize_ex() with filled in information from the old preprocessor symbols (DM9000_IO, DM9000_DATA, etc.) Overall the following parameters have been moved over to being a per-chip setting: DM9000_IO, DM9000_DATA, CONFIG_DM9000_NO_SROM while the following is still a global setting affecting all chips: CONFIG_DM9000_BYTE_SWAPPED And the following has been removed entirely: CONFIG_DM9000_BASE (was only used in a single printf) Signed-off-by: Andrew Ruder Cc: Joe Hershberger --- drivers/net/dm9000x.c | 382 +- include/dm9000.h | 2 - 2 files changed, 220 insertions(+), 164 deletions(-) diff --git a/drivers/net/dm9000x.c b/drivers/net/dm9000x.c index 9778ef9..d0ea5d7 100644 --- a/drivers/net/dm9000x.c +++ b/drivers/net/dm9000x.c @@ -55,6 +55,7 @@ TODO: external MII is not functional, only internal at the moment. #include #include #include +#include #include "dm9000x.h" @@ -80,7 +81,9 @@ TODO: external MII is not functional, only internal at the moment. #endif /* Structure/enum declaration --- */ -typedef struct board_info { +struct dm9000_priv { + ulong data_base; + ulong io_base; u32 runt_length_counter;/* counter: RX length < 64byte */ u32 long_length_counter;/* counter: RX length > 1514byte */ u32 reset_counter; /* counter: RESET */ @@ -89,23 +92,22 @@ typedef struct board_info { u16 tx_pkt_cnt; u16 queue_start_addr; u16 dbug_cnt; + u8 has_srom; u8 phy_addr; u8 device_wait_reset; /* device state */ unsigned char srom[128]; - void (*outblk)(void *data_ptr, int count); - void (*inblk)(void *data_ptr, int count); - void (*rx_status)(u16 *rx_status, u16 *rx_len); - struct eth_device netdev; -} board_info_t; -static board_info_t dm9000_info; + void (*outblk)(struct eth_device *dev, void *data_ptr, int count); + void (*inblk)(struct eth_device *dev, void *data_ptr, int count); + void (*rx_status)(struct eth_device *dev, u16 *rx_status, u16 *rx_len); +}; /* function declaration - */ -static int dm9000_probe(void); -static u16 dm9000_phy_read(int); -static void dm9000_phy_write(int, u16); -static u8 DM9000_ior(int); -static void DM9000_iow(int reg, u8 value); +static int dm9000_probe(struct eth_device *); +static u16 dm9000_phy_read(struct eth_device *, int); +static void dm9000_phy_write(struct eth_device *, int, u16); +static u8 DM9000_ior(struct eth_device *, int); +static void DM9000_iow(struct eth_device *, int reg, u8 value); /* DM9000 network board routine */ #ifndef CONFIG_DM9000_BYTE_SWAPPED @@ -126,125 +128,147 @@ static void DM9000_iow(int reg, u8 value); #ifdef CONFIG_DM9000_DEBUG static __maybe_unused void -dump_regs(void) +dump_regs(struct eth_device *dev) { DM9000_DBG("\n"); - DM9000_DBG("NCR (0x00): %02x\n", DM9000_ior(0)); - DM9000_DBG("NSR (0x01): %02x\n", DM9000_ior(1)); - DM9000_DBG("TCR (0x02): %02x\n", DM9000_ior(2)); - DM9000_DBG("TSRI (0x03): %02x\n", DM9000_ior(3)); - DM9000_DBG("TSRII (0x04): %02x\n", DM9000_ior(4)); - DM9000_DBG("RCR (0x05): %02x\n", DM9000_ior(5)); - DM9000_DBG("RSR (0x06): %02x\n", DM9000_ior(6)); - DM9000_DBG("ISR (0xFE): %02x\n", DM9000_ior(DM9000_ISR)); + DM9000_DBG("NCR (0x00): %02x\n", DM9000_ior(dev, 0)); + DM9000_DBG("NSR (0x01): %02x\n", DM9000_ior(dev, 1)); + DM9000_DBG("TCR (0x02): %02x\n", DM9000_ior(dev, 2)); + DM9000_DBG("TSRI (0x03): %02x\n", DM9000_ior(dev, 3)); + DM9000_DBG("TSRII (0x04): %02x\n", DM9000_ior(dev, 4)); + DM9000_DBG("RCR (0x05): %02x\n", DM9000_ior(dev, 5)); + DM9000_DBG("RSR (0x06): %02x\n", DM9000_ior(dev, 6)); + DM9000_DBG("ISR (0xFE): %02x\n", DM9000_ior(dev, DM9000_ISR)); DM9000_DBG("\n"); } #endif -static void dm9000_outblk_8bit(void *data_ptr, int count) +static void +dm9000_outblk_8bit(struct eth_device *dev, void *data_ptr, int count) { int i; + struct dm9000_priv *pri
Re: [U-Boot] [PATCH V2 0/5] DM9000 support for multiple interfaces
On 08/12/2015 12:24 PM, Andrew Ruder wrote: > To maintain backwards compatibility with older board files, we add a > new initialize function taking the io address, data address, and > availability of a SROM chip. The old initialize function is now a > shim around this new initialize function but provides the parameters > based on the old DM9000 preprocessor symbols. Uh, this is not true. Forgot to remove this paragraph from the cover letter. There is just a single dm9000_initialize() function that has been updated in every board file. ___ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot
[U-Boot] [PATCH] pxa: Fix boot hang by avoiding vector relocation
Since commit 3ff46cc42b9d73d0 ("arm: relocate the exception vectors") pxa does not boot anymore. Add a specific relocate_vectors macro that skips the vector relocation, as the pxa SoC does not provide RAM at the high vectors address (0x), and (0x) maps to ROM. This allows pxa to boot again. Cc: Marek Vasut Signed-off-by: Andrew Ruder --- arch/arm/cpu/pxa/Makefile | 1 + arch/arm/cpu/pxa/relocate.S | 23 +++ 2 files changed, 24 insertions(+) create mode 100644 arch/arm/cpu/pxa/relocate.S diff --git a/arch/arm/cpu/pxa/Makefile b/arch/arm/cpu/pxa/Makefile index 8cd475e..3ee08cd 100644 --- a/arch/arm/cpu/pxa/Makefile +++ b/arch/arm/cpu/pxa/Makefile @@ -13,3 +13,4 @@ obj-$(CONFIG_CPU_PXA27X) += pxa2xx.o obj-y += cpuinfo.o obj-y += timer.o obj-y += usb.o +obj-y += relocate.o diff --git a/arch/arm/cpu/pxa/relocate.S b/arch/arm/cpu/pxa/relocate.S new file mode 100644 index 000..fafd4da --- /dev/null +++ b/arch/arm/cpu/pxa/relocate.S @@ -0,0 +1,23 @@ +/* + * relocate - PXA270 vector relocation + * + * Copyright (c) 2013 Albert ARIBAUD + * + * SPDX-License-Identifier:GPL-2.0+ + */ + +#include + +/* + * The PXA SoC is very specific with respect to exceptions: it + * does not provide RAM at the high vectors address (0x), + * thus only the low address (0x) is useable; but that is + * in ROM, so let's avoid relocating the vectors. + */ + .section.text.relocate_vectors,"ax",%progbits + +ENTRY(relocate_vectors) + + bx lr + +ENDPROC(relocate_vectors) -- 2.1.4 ___ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot
[U-Boot] [PATCH] arm: pxa: use common timer functions
This patch moves pxa to the common timer functions added in commit 8dfafdd - Introduce common timer functions The (removed) pxa timer code (specifically __udelay()) could deadlock at the 32-bit boundary of get_ticks(). get_ticks() returned a 32-bit value cast up to a 64-bit value. If get_ticks() + tmo in __udelay() crossed the 32-bit boundary, the while condition became unconditionally true and locked the processor. Rather than patch the specific pxa issues, simply move everything over to the common code. Signed-off-by: Andrew Ruder Cc: Marek Vasut Cc: Tom Rini --- Tom, You had asked me to fix up this patch back on August 30, 2014. It broke compilation on some PXA ports. I have compile-tested on every PXA board in the tree, I believe. I have tested it on a yet-to-be-upstreamed board port based on the PXA270. arch/arm/cpu/pxa/timer.c | 69 +- arch/arm/include/asm/arch-pxa/config.h | 25 arch/arm/include/asm/config.h | 5 ++- 3 files changed, 30 insertions(+), 69 deletions(-) create mode 100644 arch/arm/include/asm/arch-pxa/config.h diff --git a/arch/arm/cpu/pxa/timer.c b/arch/arm/cpu/pxa/timer.c index c4717de..11fefd5 100644 --- a/arch/arm/cpu/pxa/timer.c +++ b/arch/arm/cpu/pxa/timer.c @@ -6,80 +6,13 @@ * SPDX-License-Identifier:GPL-2.0+ */ -#include #include #include -#include DECLARE_GLOBAL_DATA_PTR; -#defineTIMER_LOAD_VAL 0x - -#definetimestamp (gd->arch.tbl) -#definelastinc (gd->arch.lastinc) - -#if defined(CONFIG_CPU_PXA27X) || defined(CONFIG_CPU_MONAHANS) -#defineTIMER_FREQ_HZ 325 -#elif defined(CONFIG_CPU_PXA25X) -#defineTIMER_FREQ_HZ 3686400 -#else -#error "Timer frequency unknown - please config PXA CPU type" -#endif - -static unsigned long long tick_to_time(unsigned long long tick) -{ - return lldiv(tick * CONFIG_SYS_HZ, TIMER_FREQ_HZ); -} - -static unsigned long long us_to_tick(unsigned long long us) -{ - return lldiv(us * TIMER_FREQ_HZ, 100); -} - int timer_init(void) { - writel(0, OSCR); + writel(0, CONFIG_SYS_TIMER_COUNTER); return 0; } - -unsigned long long get_ticks(void) -{ - /* Current tick value */ - uint32_t now = readl(OSCR); - - if (now >= lastinc) { - /* -* Normal mode (non roll) -* Move stamp forward with absolute diff ticks -*/ - timestamp += (now - lastinc); - } else { - /* We have rollover of incrementer */ - timestamp += (TIMER_LOAD_VAL - lastinc) + now; - } - - lastinc = now; - return timestamp; -} - -ulong get_timer(ulong base) -{ - return tick_to_time(get_ticks()) - base; -} - -void __udelay(unsigned long usec) -{ - unsigned long long tmp; - ulong tmo; - - tmo = us_to_tick(usec); - tmp = get_ticks() + tmo;/* get current timestamp */ - - while (get_ticks() < tmp) /* loop till event */ -/*NOP*/; -} - -ulong get_tbclk(void) -{ - return TIMER_FREQ_HZ; -} diff --git a/arch/arm/include/asm/arch-pxa/config.h b/arch/arm/include/asm/arch-pxa/config.h new file mode 100644 index 000..5836945 --- /dev/null +++ b/arch/arm/include/asm/arch-pxa/config.h @@ -0,0 +1,25 @@ +/* + * Copyright (C) 2014 Andrew Ruder + * + * SPDX-License-Identifier:GPL-2.0+ + */ + +#ifndef _ASM_ARM_PXA_CONFIG_ +#define _ASM_ARM_PXA_CONFIG_ + +#include + +/* + * Generic timer support + */ +#if defined(CONFIG_CPU_PXA27X) || defined(CONFIG_CPU_MONAHANS) +#defineCONFIG_SYS_TIMER_RATE 325 +#elif defined(CONFIG_CPU_PXA25X) +#defineCONFIG_SYS_TIMER_RATE 3686400 +#else +#error "Timer frequency unknown - please config PXA CPU type" +#endif + +#define CONFIG_SYS_TIMER_COUNTER OSCR + +#endif /* _ASM_ARM_PXA_CONFIG_ */ diff --git a/arch/arm/include/asm/config.h b/arch/arm/include/asm/config.h index 7a34a01..22fff02 100644 --- a/arch/arm/include/asm/config.h +++ b/arch/arm/include/asm/config.h @@ -19,7 +19,10 @@ #include #endif -#ifdef CONFIG_LS102XA +#if defined(CONFIG_LS102XA) || \ + defined(CONFIG_CPU_PXA27X) || \ + defined(CONFIG_CPU_MONAHANS) || \ + defined(CONFIG_CPU_PXA25X) #include #endif -- 2.1.4 ___ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot
Re: [U-Boot] [PATCH] arm: pxa: use common timer functions
Tom, Just replying so you see this since apparently I should have used copy-paste on your e-mail address for the Cc: and not attempted to read after 45 cups of tea. - Andy ___ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot
[U-Boot] [PATCH] i2c: adding driver for pxa27x, pxa3xx, pxa25x
Cc: Marek Vasut Cc: Heiko Schocher Signed-off-by: Andrew Ruder --- This driver was written before the driver model stuff was really around (or at least based on a U-Boot version that only had very preliminary support) so there might be some older conventions in use here. I have tested on a PXA270 board running upstream master with this driver, however - so to some extent this all still works fine. Let me know if things need to change to be accepted, and I'll try to find some time to update! drivers/i2c/Makefile | 1 + drivers/i2c/pxa_i2c.c | 796 ++ 2 files changed, 797 insertions(+) create mode 100644 drivers/i2c/pxa_i2c.c diff --git a/drivers/i2c/Makefile b/drivers/i2c/Makefile index 9b45248..cf2c8a8 100644 --- a/drivers/i2c/Makefile +++ b/drivers/i2c/Makefile @@ -30,6 +30,7 @@ obj-$(CONFIG_SYS_I2C_MXS) += mxs_i2c.o obj-$(CONFIG_SYS_I2C_OMAP24XX) += omap24xx_i2c.o obj-$(CONFIG_SYS_I2C_OMAP34XX) += omap24xx_i2c.o obj-$(CONFIG_SYS_I2C_PPC4XX) += ppc4xx_i2c.o +obj-$(CONFIG_SYS_I2C_PXA) += pxa_i2c.o obj-$(CONFIG_SYS_I2C_RCAR) += rcar_i2c.o obj-$(CONFIG_SYS_I2C_S3C24X0) += s3c24x0_i2c.o obj-$(CONFIG_SYS_I2C_SANDBOX) += sandbox_i2c.o i2c-emul-uclass.o diff --git a/drivers/i2c/pxa_i2c.c b/drivers/i2c/pxa_i2c.c new file mode 100644 index 000..859d6cf --- /dev/null +++ b/drivers/i2c/pxa_i2c.c @@ -0,0 +1,796 @@ +/* + * pxa_i2c.c + * + * I2C adapter for the PXA I2C bus access. + * + * Copyright (C) 2002 Intrinsyc Software Inc. + * Copyright (C) 2004-2005 Deep Blue Solutions Ltd. + * Copyright (C) 2014 Andrew Ruder + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This is a heavily modified version of the PXA I2C driver from the Linux + * kernel 3.15.10. + */ + +#include +#include +#include +#include + +#include +#include + +#define MAX_TRANSFER_MS 5000 +#define WAIT_MASTER_MS 64 +#define ABORT_LENGTH_MS 50 + +/* Set up some defaults for various configurable pieces of this driver + * so that most of the time we don't need extra things defined + */ +#if !defined(CONFIG_SYS_PXA_STD_I2C_SPEED) +#define CONFIG_SYS_PXA_STD_I2C_SPEED 10 +#endif + +#if !defined(CONFIG_SYS_PXA_STD_I2C_SLAVE) +#define CONFIG_SYS_PXA_STD_I2C_SLAVE 1 +#endif + +#if !defined(CONFIG_SYS_PXA_PWR_I2C_SPEED) +#define CONFIG_SYS_PXA_PWR_I2C_SPEED 4 +#endif + +#if !defined(CONFIG_SYS_PXA_PWR_I2C_SLAVE) +#define CONFIG_SYS_PXA_PWR_I2C_SLAVE 1 +#endif + +#if defined(CONFIG_CPU_MONAHANS) && defined(CONFIG_PXA_PWR_I2C) +#warning Monahans + PWRI2C is unlikely to work without additional testing +#endif + +/* ICR initialize bit values +* +* 15. FM 0 (100 Khz operation) +* 14. UR 0 (No unit reset) +* 13. SADIE0 (Disables the unit from interrupting on slave addresses +* matching its slave address) +* 12. ALDIE0 (Disables the unit from interrupt when it loses arbitration +* in master mode) +* 11. SSDIE0 (Disables interrupts from a slave stop detected, in slave mode) +* 10. BEIE 1 (Enable interrupts from detected bus errors, no ACK sent) +* 9. IRFIE1 (Enable interrupts from full buffer received) +* 8. ITEIE1 (Enables the I2C unit to interrupt when transmit buffer empty) +* 7. GCD 1 (Disables i2c unit response to general call messages as a slave) +* 6. IUE 0 (Disable unit until we change settings) +* 5. SCLE 1 (Enables the i2c clock output for master mode (drives SCL) +* 4. MA 0 (Only send stop with the ICR stop bit) +* 3. TB 0 (We are not transmitting a byte initially) +* 2. ACKNAK 0 (Send an ACK after the unit receives a byte) +* 1. STOP 0 (Do not send a STOP) +* 0. START0 (Do not send a START) +* +*/ +#define I2C_ICR_INIT (ICR_BEIE | ICR_IRFIE | ICR_ITEIE | ICR_GCD | ICR_SCLE) + +/* I2C status register init values + * + * 10. BED 1 (Clear bus error detected) + * 9. SAD 1 (Clear slave address detected) + * 7. IRF 1 (Clear IDBR Receive Full) + * 6. ITE 1 (Clear IDBR Transmit Empty) + * 5. ALD 1 (Clear Arbitration Loss Detected) + * 4. SSD 1 (Clear Slave Stop Detected) + */ +#define I2C_ISR_INIT 0x7FF /* status register init */ + +#define dev_dbg(dev, fmt, args...) \ + debug("pxai2c%d: " fmt, (dev)->hwadapnr, ##args) +#define dev_err(dev, fmt, args...) \ + printf("pxai2c%d: " fmt, (dev)->hwadapnr, ##args) + +enum i2c_code { + I2C_SUCCESS = 0, + I2C_RETRY, + I2C_NAK, + I2C_BUS_ERROR, + I2C_TIMEOUT, + I2C_OTHER_ERROR, + I2C_ALL_RETRIES, + I2C_CONTINUE +}; + +/* + * I2C bit definitions + */ + +#define ICR_START (1 << 0) /* start bit */ +#define ICR_STOP (1 << 1)
Re: [U-Boot] [PATCH] i2c: adding driver for pxa27x, pxa3xx, pxa25x
> On Aug 12, 2015, at 2:34 PM, Marek Vasut wrote: > > On Wednesday, August 12, 2015 at 08:43:52 PM, Andrew Ruder wrote: > > Commit message is missing :'-( I actually was going with subject being sufficient on this one. I'll fill in some more info on this as far as origin and what it has been tested on and send in again. > >> Cc: Marek Vasut >> Cc: Heiko Schocher >> Signed-off-by: Andrew Ruder >> --- >> >> This driver was written before the driver model stuff was really around (or >> at least based on a U-Boot version that only had very preliminary support) >> so there might be some older conventions in use here. I have tested on a >> PXA270 board running upstream master with this driver, however - so to >> some extent this all still works fine. Let me know if things need to >> change to be accepted, and I'll try to find some time to update! >> >> drivers/i2c/Makefile | 1 + >> drivers/i2c/pxa_i2c.c | 796 >> ++ 2 files changed, 797 >> insertions(+) >> create mode 100644 drivers/i2c/pxa_i2c.c >> >> diff --git a/drivers/i2c/Makefile b/drivers/i2c/Makefile >> index 9b45248..cf2c8a8 100644 >> --- a/drivers/i2c/Makefile >> +++ b/drivers/i2c/Makefile >> @@ -30,6 +30,7 @@ obj-$(CONFIG_SYS_I2C_MXS) += mxs_i2c.o >> obj-$(CONFIG_SYS_I2C_OMAP24XX) += omap24xx_i2c.o >> obj-$(CONFIG_SYS_I2C_OMAP34XX) += omap24xx_i2c.o >> obj-$(CONFIG_SYS_I2C_PPC4XX) += ppc4xx_i2c.o >> +obj-$(CONFIG_SYS_I2C_PXA) += pxa_i2c.o >> obj-$(CONFIG_SYS_I2C_RCAR) += rcar_i2c.o >> obj-$(CONFIG_SYS_I2C_S3C24X0) += s3c24x0_i2c.o >> obj-$(CONFIG_SYS_I2C_SANDBOX) += sandbox_i2c.o i2c-emul-uclass.o >> diff --git a/drivers/i2c/pxa_i2c.c b/drivers/i2c/pxa_i2c.c >> new file mode 100644 >> index 000..859d6cf >> --- /dev/null >> +++ b/drivers/i2c/pxa_i2c.c >> @@ -0,0 +1,796 @@ >> +/* >> + * pxa_i2c.c >> + * >> + * I2C adapter for the PXA I2C bus access. >> + * >> + * Copyright (C) 2002 Intrinsyc Software Inc. >> + * Copyright (C) 2004-2005 Deep Blue Solutions Ltd. >> + * Copyright (C) 2014 Andrew Ruder >> + * >> + * This program is free software; you can redistribute it and/or modify >> + * it under the terms of the GNU General Public License version 2 as >> + * published by the Free Software Foundation. >> + * >> + * This is a heavily modified version of the PXA I2C driver from the >> Linux + * kernel 3.15.10. >> + */ >> + >> +#include >> +#include >> +#include >> +#include >> + >> +#include >> +#include >> + >> +#define MAX_TRANSFER_MS 5000 >> +#define WAIT_MASTER_MS 64 >> +#define ABORT_LENGTH_MS 50 >> + >> +/* Set up some defaults for various configurable pieces of this driver >> + * so that most of the time we don't need extra things defined > > Multiline comment should be of the form: > > /* > * foo > * bar > */ > >> + */ >> +#if !defined(CONFIG_SYS_PXA_STD_I2C_SPEED) >> +#define CONFIG_SYS_PXA_STD_I2C_SPEED 10 >> +#endif >> + >> +#if !defined(CONFIG_SYS_PXA_STD_I2C_SLAVE) >> +#define CONFIG_SYS_PXA_STD_I2C_SLAVE 1 >> +#endif >> + >> +#if !defined(CONFIG_SYS_PXA_PWR_I2C_SPEED) >> +#define CONFIG_SYS_PXA_PWR_I2C_SPEED 4 >> +#endif >> + >> +#if !defined(CONFIG_SYS_PXA_PWR_I2C_SLAVE) >> +#define CONFIG_SYS_PXA_PWR_I2C_SLAVE 1 >> +#endif > > Please remove all this stuff, it's only going to hide bugs. > >> +#if defined(CONFIG_CPU_MONAHANS) && defined(CONFIG_PXA_PWR_I2C) >> +#warning Monahans + PWRI2C is unlikely to work without additional testing >> +#endif >> + > > [...] > >> +#define ISR_ITE(1 << 6) /* tx buffer empty */ >> +#define ISR_IRF(1 << 7) /* rx buffer full */ >> +#define ISR_GCAD(1 << 8) /* general call address detected */ >> +#define ISR_SAD(1 << 9) /* slave address detected */ >> +#define ISR_BED(1 << 10) /* bus error no ACK/NAK */ >> + >> +struct pxa_i2c_msg { >> +u16 addr; >> +u16 flags; >> +#define I2C_M_TEN0x0010/* this is a ten bit chip address */ > > Be consistent about using 1 << n or 0x0n00 please. Just use the BIT(n) macro. > >> +#define I2C_M_RD0x0001/* read data, from slave to master */ >> +#define I2C_M_STOP0x8000/* if I2C_FUNC_PROTOCOL_MANGLING */ >> +#define I2C_M_NOSTART0x400
Re: [U-Boot] [PATCH V2 3/5] dm9000: Add struct eth_device * to SROM functions
On Wed, Aug 12, 2015 at 02:07:20PM -0500, Joe Hershberger wrote: > On Wed, Aug 12, 2015 at 12:24 PM, Andrew Ruder > wrote: > > /** function prototypes **/ > > #if !defined(CONFIG_DM9000_NO_SROM) > > -void dm9000_write_srom_word(int offset, u16 val); > > -void dm9000_read_srom_word(int offset, u8 *to); > > +struct eth_device; > > + > > +void dm9000_write_srom_word(struct eth_device *dev, int offset, u16 val); > > +void dm9000_read_srom_word(struct eth_device *dev, int offset, u8 *to); > > It will be better to pass the dm9000_priv* instead. See patch 5 for details. Even on the "public"-facing functions? Thanks, Andrew ___ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot
Re: [U-Boot] [PATCH] i2c: adding driver for pxa27x, pxa3xx, pxa25x
On Wed, Aug 12, 2015 at 09:34:14PM +0200, Marek Vasut wrote: > On Wednesday, August 12, 2015 at 08:43:52 PM, Andrew Ruder wrote: > > +#if !defined(CONFIG_SYS_PXA_STD_I2C_SPEED) > > +#define CONFIG_SYS_PXA_STD_I2C_SPEED 10 > > +#endif > > + > > +#if !defined(CONFIG_SYS_PXA_STD_I2C_SLAVE) > > +#define CONFIG_SYS_PXA_STD_I2C_SLAVE 1 > > +#endif > > + > > +#if !defined(CONFIG_SYS_PXA_PWR_I2C_SPEED) > > +#define CONFIG_SYS_PXA_PWR_I2C_SPEED 4 > > +#endif > > + > > +#if !defined(CONFIG_SYS_PXA_PWR_I2C_SLAVE) > > +#define CONFIG_SYS_PXA_PWR_I2C_SLAVE 1 > > +#endif > > Please remove all this stuff, it's only going to hide bugs. Hide in what way? Just require that ports define them when enabling the i2c driver? ... or don't make it externally configurable? Thanks, Andrew ___ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot