summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJustin Waters <justin.waters@timesys.com>2013-04-24 17:38:39 -0400
committerJustin Waters <justin.waters@timesys.com>2013-04-24 17:38:39 -0400
commit75c641ece39c136001340df61f0ad57028ce4ffc (patch)
treee5f2c5f5764770a34d0e39b5eace575fd4751527
parent1341f103ac87882633b019a5a137056818234248 (diff)
LogicPD Support for OMAP3/DM3/AM3 boards 2.1 Update
-rw-r--r--Makefile6
-rw-r--r--arch/arm/cpu/armv7/omap3/sys_info.c6
-rw-r--r--arch/arm/include/asm/arch-omap3/dma.h183
-rw-r--r--arch/arm/include/asm/arch-omap3/omap3.h3
-rw-r--r--arch/arm/lib/board.c5
-rw-r--r--arch/arm/lib/cache.c62
-rw-r--r--board/ti/logic/Makefile6
-rw-r--r--board/ti/logic/logic-display.c33
-rw-r--r--board/ti/logic/logic-product-id.c74
-rw-r--r--board/ti/logic/logic.c116
-rw-r--r--board/ti/logic/prod-id/Makefile50
-rw-r--r--board/ti/logic/prod-id/interface.h15
-rw-r--r--board/ti/logic/prod-id/startup.c124
-rw-r--r--common/cmd_mtdparts.c19
-rw-r--r--common/cmd_nvedit.c5
-rw-r--r--common/console.c49
-rw-r--r--common/env_common.c10
-rw-r--r--drivers/dma/Makefile2
-rw-r--r--drivers/dma/omap3_dma.c242
-rw-r--r--drivers/i2c/omap24xx_i2c.c7
-rw-r--r--drivers/mmc/omap3_mmc.c16
-rw-r--r--drivers/mtd/nand/nand.c11
-rw-r--r--drivers/mtd/nand/nand_util.c3
-rw-r--r--drivers/mtd/nand/omap_gpmc.c54
-rw-r--r--drivers/power/twl4030.c42
-rw-r--r--drivers/serial/ns16550.c19
-rw-r--r--drivers/serial/serial.c12
-rw-r--r--drivers/video/omap3_dss.c12
-rw-r--r--include/common.h23
-rw-r--r--include/configs/omap3logic.h429
-rw-r--r--include/i2c.h1
-rw-r--r--include/nand.h1
-rw-r--r--include/ns16550.h8
-rw-r--r--include/twl4030.h1
-rw-r--r--lib/vsprintf.c172
-rwxr-xr-xmkconfig3
36 files changed, 1529 insertions, 295 deletions
diff --git a/Makefile b/Makefile
index 1440c06ba0..1a5353e16c 100644
--- a/Makefile
+++ b/Makefile
@@ -292,10 +292,14 @@ ifeq ($(SOC),s5pc2xx)
LIBS += $(CPUDIR)/s5p-common/libs5p-common.o
endif
+LIBBOARD = board/$(BOARDDIR)/lib$(BOARD).o
+ifeq ($(CONFIG_NAME),omap3logic)
+LIBS += board/$(BOARDDIR)/prod-id/libprod-id.o
+endif
+
LIBS := $(addprefix $(obj),$(sort $(LIBS)))
.PHONY : $(LIBS) $(TIMESTAMP_FILE)
-LIBBOARD = board/$(BOARDDIR)/lib$(BOARD).o
LIBBOARD := $(addprefix $(obj),$(LIBBOARD))
# Add GCC lib
diff --git a/arch/arm/cpu/armv7/omap3/sys_info.c b/arch/arm/cpu/armv7/omap3/sys_info.c
index 549ac19189..598457610f 100644
--- a/arch/arm/cpu/armv7/omap3/sys_info.c
+++ b/arch/arm/cpu/armv7/omap3/sys_info.c
@@ -74,7 +74,11 @@ void dieid_num_r(void)
******************************************/
u32 get_cpu_type(void)
{
- return readl(&ctrl_base->ctrl_omap_stat);
+ u32 cpu_type;
+ cpu_type = readl(&ctrl_base->ctrl_omap_stat);
+ if (cpu_type == OMAP3730_WRONG_EFUSE)
+ cpu_type = OMAP3730;
+ return cpu_type;
}
/******************************************
diff --git a/arch/arm/include/asm/arch-omap3/dma.h b/arch/arm/include/asm/arch-omap3/dma.h
new file mode 100644
index 0000000000..edc2cbf98e
--- /dev/null
+++ b/arch/arm/include/asm/arch-omap3/dma.h
@@ -0,0 +1,183 @@
+#ifndef __SDMA_H
+#define __SDMA_H
+
+/* Copyright (C) 2011
+ * Corscience GmbH & Co. KG - Simon Schwarz <schwarz <at> corscience.de>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+// #ifndef __KERNEL_STRICT_NAMES
+// #ifndef __ASSEMBLY__
+struct dma4_chan {
+ u32 ccr;
+ u32 clnk_ctrl;
+ u32 cicr;
+ u32 csr;
+ u32 csdp;
+ u32 cen;
+ u32 cfn;
+ u32 cssa;
+ u32 cdsa;
+ u32 csel;
+ u32 csfl;
+ u32 cdel;
+ u32 cdfl;
+ u32 csac;
+ u32 cdac;
+ u32 ccen;
+ u32 ccfn;
+ u32 color;
+};
+
+struct dma4_chan_padded {
+ u32 ccr;
+ u32 clnk_ctrl;
+ u32 cicr;
+ u32 csr;
+ u32 csdp;
+ u32 cen;
+ u32 cfn;
+ u32 cssa;
+ u32 cdsa;
+ u32 csel;
+ u32 csfl;
+ u32 cdel;
+ u32 cdfl;
+ u32 csac;
+ u32 cdac;
+ u32 ccen;
+ u32 ccfn;
+ u32 color;
+ u8 res1[0x60 - sizeof(struct dma4_chan)];
+};
+
+struct dma4 {
+ u32 revision;
+ u8 res1[0x4];
+ u32 irqstatus_l[0x4];
+ u32 irqenable_l[0x4];
+ u32 sysstatus;
+ u32 ocp_sysconfig;
+ u8 res2[0x34];
+ u32 caps_0;
+ u8 res3[0x4];
+ u32 caps_2;
+ u32 caps_3;
+ u32 caps_4;
+ u32 gcr;
+ u8 res4[0x4];
+ /* Dinon - Use dma4_chan_padded instead of dma4_chan for
+ * channel 1 ~ 31 to work */
+ struct dma4_chan_padded chan[32];
+};
+// #endif /*__ASSEMBLY__ */
+// #endif /* __KERNEL_STRICT_NAMES */
+
+/* Functions */
+void omap3_dma_init(void);
+int omap3_dma_conf_transfer(uint32_t chan, uint32_t *src, uint32_t *dst,
+ uint32_t sze);
+int omap3_dma_start_transfer(uint32_t chan);
+int omap3_dma_wait_for_transfer(uint32_t chan, int chained);
+int omap3_dma_conf_chan(uint32_t chan, struct dma4_chan *config);
+int omap3_dma_set_conf_chan(uint32_t chan, struct dma4_chan *config);
+int omap3_dma_get_conf_chan(uint32_t chan, struct dma4_chan *config);
+int omap3_dma_transfer(int channel, void *src, void *dst, int size, int flags);
+void omap3_dma_channel_init(int channel, int next_channel, int csdp_size,
+ int ccr_src_amode, int ccr_dst_amode);
+
+#define DMA_CHANNEL_NAND 0
+#define DMA_CHANNEL_MMC 1
+
+/* Register settings */
+#define CSDP_DATA_TYPE_8BIT 0x0
+#define CSDP_DATA_TYPE_16BIT 0x1
+#define CSDP_DATA_TYPE_32BIT 0x2
+#define CSDP_SRC_BURST_SINGLE (0x0 << 7)
+#define CSDP_SRC_BURST_EN_16BYTES (0x1 << 7)
+#define CSDP_SRC_BURST_EN_32BYTES (0x2 << 7)
+#define CSDP_SRC_BURST_EN_64BYTES (0x3 << 7)
+#define CSDP_DST_BURST_SINGLE (0x0 << 14)
+#define CSDP_DST_BURST_EN_16BYTES (0x1 << 14)
+#define CSDP_DST_BURST_EN_32BYTES (0x2 << 14)
+#define CSDP_DST_BURST_EN_64BYTES (0x3 << 14)
+#define CSDP_DST_ENDIAN_LOCK_ADAPT (0x0 << 18)
+#define CSDP_DST_ENDIAN_LOCK_LOCK (0x1 << 18)
+#define CSDP_DST_ENDIAN_LITTLE (0x0 << 19)
+#define CSDP_DST_ENDIAN_BIG (0x1 << 19)
+#define CSDP_SRC_ENDIAN_LOCK_ADAPT (0x0 << 20)
+#define CSDP_SRC_ENDIAN_LOCK_LOCK (0x1 << 20)
+#define CSDP_SRC_ENDIAN_LITTLE (0x0 << 21)
+#define CSDP_SRC_ENDIAN_BIG (0x1 << 21)
+
+#define CICR_MISALIGNED_ERR_IE (0x1 << 11)
+#define CICR_SUPERVISOR_ERR_IE (0x1 << 10)
+#define CICR_TRANS_ERR_IE (0x1 << 8)
+#define CICR_BLOCK_IE (0x1 << 5)
+
+#define CCR_READ_PRIORITY_LOW (0x0 << 6)
+#define CCR_READ_PRIORITY_HIGH (0x1 << 6)
+#define CCR_ENABLE_DISABLED (0x0 << 7)
+#define CCR_ENABLE_ENABLE (0x1 << 7)
+#define CCR_SRC_AMODE_CONSTANT (0x0 << 12)
+#define CCR_SRC_AMODE_POST_INC (0x1 << 12)
+#define CCR_SRC_AMODE_SINGLE_IDX (0x2 << 12)
+#define CCR_SRC_AMODE_DOUBLE_IDX (0x3 << 12)
+#define CCR_DST_AMODE_CONSTANT (0x0 << 14)
+#define CCR_DST_AMODE_POST_INC (0x1 << 14)
+#define CCR_DST_AMODE_SINGLE_IDX (0x2 << 14)
+#define CCR_DST_AMODE_SOUBLE_IDX (0x3 << 14)
+
+#define CCR_RD_ACTIVE_MASK (1 << 9)
+#define CCR_WR_ACTIVE_MASK (1 << 10)
+
+#define CSR_SUPER_BLOCK (0x1 << 14)
+#define CSR_DRAIN_END (0x1 << 12)
+#define CSR_MISALIGNED_ADRS_ERR (0x1 << 11)
+#define CSR_SUPERVISOR_ERR (0x1 << 10)
+#define CSR_TRANS_ERR (0x1 << 8)
+#define CSR_PKT (0x1 << 7)
+#define CSR_SYNC (0x1 << 6)
+#define CSR_BLOCK (0x1 << 5)
+#define CSR_LAST (0x1 << 4)
+#define CSR_FRAME (0x1 << 3)
+#define CSR_HALF (0x1 << 2)
+#define CSR_DROP (0x1 << 1)
+
+#if 1
+#define CSR_ALL_MASK \
+ (CSR_MISALIGNED_ADRS_ERR \
+ | CSR_SUPERVISOR_ERR | CSR_TRANS_ERR | CSR_PKT | CSR_SYNC \
+ | CSR_BLOCK | CSR_LAST | CSR_FRAME | CSR_HALF | CSR_DROP)
+#else
+#define CSR_ALL_MASK \
+ (CSR_SUPER_BLOCK | CSR_DRAIN_END | CSR_MISALIGNED_ADRS_ERR \
+ | CSR_SUPERVISOR_ERR | CSR_TRANS_ERR | CSR_PKT | CSR_SYNC \
+ | CSR_BLOCK | CSR_LAST | CSR_FRAME | CSR_HALF | CSR_DROP)
+#endif
+
+#define CLNK_CTRL_ENABLE_LNK (1 << 15)
+
+/* others */
+#define CHAN_NR_MIN 0
+#define CHAN_NR_MAX 31
+
+
+#define FB_DMA_START (1 << 0)
+#define FB_DMA_WAIT (1 << 1)
+
+#endif /* __SDMA_H */
diff --git a/arch/arm/include/asm/arch-omap3/omap3.h b/arch/arm/include/asm/arch-omap3/omap3.h
index 8c91b9aac9..117ad1ee61 100644
--- a/arch/arm/include/asm/arch-omap3/omap3.h
+++ b/arch/arm/include/asm/arch-omap3/omap3.h
@@ -47,6 +47,8 @@
#define OMAP34XX_L4_PER 0x49000000
#define OMAP34XX_L4_IO_BASE OMAP34XX_CORE_L4_IO_BASE
+#define OMAP34XX_DMA4_BASE 0x48056000
+
/* CONTROL */
#define OMAP34XX_CTRL_BASE (OMAP34XX_L4_IO_BASE + 0x2000)
@@ -248,5 +250,6 @@ struct gpio {
#define AM3517 0x1c00
#define OMAP3730 0x0c00
+#define OMAP3730_WRONG_EFUSE 0x0e00
#endif
diff --git a/arch/arm/lib/board.c b/arch/arm/lib/board.c
index 2e22319947..21e6feb182 100644
--- a/arch/arm/lib/board.c
+++ b/arch/arm/lib/board.c
@@ -50,6 +50,7 @@
#include <asm/arch/sys_proto.h>
#include <onenand_uboot.h>
#include <mmc.h>
+#include <asm/arch/dma.h>
#ifdef CONFIG_BITBANGMII
#include <miiphy.h>
@@ -465,6 +466,10 @@ void board_init_r (gd_t *id, ulong dest_addr)
debug ("Now running in RAM - U-Boot at: %08lx\n", dest_addr);
+#if defined(CONFIG_OMAP_DMA)
+ omap3_dma_init();
+#endif
+
#ifdef CONFIG_LOGBUFFER
logbuff_init_ptrs ();
#endif
diff --git a/arch/arm/lib/cache.c b/arch/arm/lib/cache.c
index 30686fe69b..80a8205a2c 100644
--- a/arch/arm/lib/cache.c
+++ b/arch/arm/lib/cache.c
@@ -25,6 +25,68 @@
#include <common.h>
+#ifdef CONFIG_OMAP34XX
+/* Cache routine for OMAP34XX (Cortex-A8) */
+void invalidate_dcache_range(unsigned long start, unsigned long stop)
+{
+ unsigned int cache_level_id; /* cache level ID register */
+ unsigned int cache_size_id; /* cache size ID register */
+ unsigned long addr, end_addr;
+ unsigned int level;
+ unsigned int line_size;
+ unsigned int assoc, num_sets;
+
+ /* First get the cache ID register */
+ asm("mrc p15, 1, %0, c0, c0, 1 @ get cache level ID" : "=r" (cache_level_id) : : "cc");
+ /* Strip off LoU/LoC */
+ cache_level_id &= ~0xFF000000;
+
+ /* Loop over the levels until there's no higher order cache */
+ for (level = 0; cache_level_id; level+=2) {
+ /* Select the level */
+ asm volatile("mcr p15, 2, %0, c0, c0, 0 @ Select cache level"
+ : : "r" (level) : "cc");
+
+ asm("mrc p15, 1, %0, c0, c0, 0 @ get cache size ID" : "=r" (cache_size_id) : : "cc");
+
+ /* Number of bytes in line */
+ line_size = (1 << ((cache_size_id & 0x3) + 2)) * 4;
+
+ /* Calculate number of sets * associativity to
+ * figure if its easier to use MVA vs set/way */
+ assoc = ((cache_size_id >> 2) + 1) & 0x3ff;
+ num_sets = ((cache_size_id >> 13) + 1) & 0x7fff;
+
+ if (0 && (assoc * num_sets * line_size) > (stop - start)) {
+ /* Cheaper to flush/invalidate using set/way */
+ ;
+ } else {
+ /* Cheaper to flush/invalidate using MVA */
+ addr = start & ~line_size;
+ end_addr = (stop + line_size - 1) & ~line_size;
+
+ /* Clean and invalidate each line */
+ for (; addr < end_addr; addr += line_size) {
+ asm volatile("mcr p15, 0, %0, c7, c14, 1 @ clean/invalidate Dcache" : : "r" (addr) : "cc");
+ }
+ }
+
+ /* Peel off this cache layer and continue until no more */
+ cache_level_id >>= 3;
+ }
+
+ /* Switch back to level 0 */
+ asm volatile("mcr p15, 2, %0, c0, c0, 0 @ Cache Size SelectID"
+ : : "r" (0) : "cc");
+
+ asm volatile("mcr p15, 0, %0, c7, c5, 4 @ flush prefetch buffer" : : "r" (0) : "cc");
+#if 0
+ /* invalidate the I-cache */
+ asm volatile("mcr p15 0, %0, c7, c5, 0 @ I+BTB cache invalidate", : : "r" (0) : "cc");
+#endif
+}
+#endif
+
void flush_cache (unsigned long dummy1, unsigned long dummy2)
{
#if defined(CONFIG_OMAP2420) || defined(CONFIG_ARM1136)
diff --git a/board/ti/logic/Makefile b/board/ti/logic/Makefile
index 67c7fd3f92..ad1cc270bf 100644
--- a/board/ti/logic/Makefile
+++ b/board/ti/logic/Makefile
@@ -25,10 +25,10 @@ include $(TOPDIR)/config.mk
LIB = $(obj)lib$(BOARD).o
-PROD_ID_OBJS := prod-id/query.o prod-id/startup.o prod-id/crc-15.o \
- prod-id/extract.o prod-id/type.o prod-id/size.o
+#PROD_ID_OBJS := prod-id/query.o prod-id/startup.o prod-id/crc-15.o \
+# prod-id/extract.o prod-id/type.o prod-id/size.o
-COBJS := logic.o logic-data.o logic-at88.o logic-at24.o logic-i2c.o logic-gpio.o logic-display.o logic-product-id.o $(PROD_ID_OBJS)
+COBJS := logic.o logic-data.o logic-at88.o logic-at24.o logic-i2c.o logic-gpio.o logic-display.o logic-product-id.o # $(PROD_ID_OBJS)
SRCS := $(COBJS:.o=.c)
OBJS := $(addprefix $(obj),$(COBJS))
diff --git a/board/ti/logic/logic-display.c b/board/ti/logic/logic-display.c
index 3c0d17c188..d0efb36e26 100644
--- a/board/ti/logic/logic-display.c
+++ b/board/ti/logic/logic-display.c
@@ -354,14 +354,14 @@ struct logic_panel *logic_find_panel(void)
strncpy(panel_name, panel, sizeof(panel_name));
panel_name[sizeof(panel_name)-1] = '\0';
- /* Search for trailing "-dvi" or "-hdmi", if found
+ /* Search for trailing "-dvi"/"-24" or "-hdmi"/"-24", if found
* set data_lines and strip off trailing specifier */
data_lines = 16;
if ((p = strrchr(panel_name, '-')) != NULL) {
- if (!strcmp(p+1, "dvi")) {
+ if (!strcmp(p+1, "dvi") || !strcmp(p+1, "16")) {
data_lines = 16;
*p='\0';
- } else if (!strcmp(p+1, "hdmi")) {
+ } else if (!strcmp(p+1, "hdmi") || !strcmp(p+1, "24")) {
data_lines = 24;
*p='\0';
}
@@ -887,3 +887,30 @@ U_BOOT_CMD(draw_test, 1, 1, do_draw_test,
" - Draw ramps/stipples/boarders on LCD",
""
);
+
+int do_info_video(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
+{
+ struct omap_video_timings *timing;
+ printf("Current display parameters:\n");
+ printf("name: %s\n", default_panel.name);
+ printf("config: %#x\n", default_panel.config);
+ printf("acb: %#x\n", default_panel.acb);
+ printf("data_lines: %d\n", default_panel.data_lines);
+ timing = &default_panel.timing;
+ printf("x_res: %d\n", timing->x_res);
+ printf("y_res: %d\n", timing->y_res);
+ printf("pixel_clock: %d\n", timing->pixel_clock);
+ printf("hsw: %d\n", timing->hsw);
+ printf("hfp: %d\n", timing->hfp);
+ printf("hbp: %d\n", timing->hbp);
+ printf("vsw: %d\n", timing->vsw);
+ printf("vfp: %d\n", timing->vfp);
+ printf("vbp: %d\n", timing->vbp);
+
+ return 0;
+}
+
+U_BOOT_CMD(dump_video, 1, 1, do_info_video,
+ " - Displays information on video parameters",
+ ""
+);
diff --git a/board/ti/logic/logic-product-id.c b/board/ti/logic/logic-product-id.c
index 4f427f94b6..3142511d97 100644
--- a/board/ti/logic/logic-product-id.c
+++ b/board/ti/logic/logic-product-id.c
@@ -40,6 +40,20 @@
struct id_data id_data;
+void id_fetch_bytes(unsigned char *mem_ptr, int offset, int size, int *oor)
+{
+ id_printf("%s mem_ptr %p offset %d size %d\n", __FUNCTION__, mem_ptr, offset, size);
+ if (id_data.root_size && ((offset + size) >= (id_data.root_offset + id_data.root_size))) {
+ id_error("Attempt to read past end of buffer (offset %u >= (%u + %u))", offset, id_data.root_offset, id_data.root_size);
+ *oor = -ID_ERANGE;
+ return;
+ }
+ if (at24_read(offset, mem_ptr, size) != 0) {
+ *oor = -ID_ENODEV;
+ }
+ return;
+}
+
/* Fetch a byte of data from the ID data on the i2c bus */
unsigned char id_fetch_byte(unsigned char *mem_ptr, int offset, int *oor)
{
@@ -47,7 +61,7 @@ unsigned char id_fetch_byte(unsigned char *mem_ptr, int offset, int *oor)
/* If data is off end of known size then complain */
if (id_data.root_size && (offset >= (id_data.root_offset + id_data.root_size))) {
- id_printf("Attempt to read past end of buffer (offset %u >= size %u)\n", offset, sizeof(id_data_buf));
+ id_error("Attempt to read past end of buffer (offset %u >= (%u + %u))", offset, id_data.root_offset, id_data.root_size);
*oor = -ID_ERANGE;
return 0; /* Force upper layer to recover */
}
@@ -84,6 +98,25 @@ int id_printf(const char *fmt, ...)
return 0;
}
+#ifdef DEBUG_NEW_ID_CODE
+int id_dbg_printf(const char *fmt, ...)
+{
+ va_list args;
+ char printbuffer[256];
+
+ va_start (args, fmt);
+ /* For this to work, printbuffer must be larger than
+ * anything we ever want to print.
+ */
+ vsprintf (printbuffer, fmt, args);
+ va_end (args);
+ /* Print the string */
+ serial_puts (printbuffer);
+
+ return 0;
+}
+#endif
+
void id_error(const char *fmt, ...)
{
va_list args;
@@ -100,6 +133,22 @@ void id_error(const char *fmt, ...)
}
+static int _at24_setup(void)
+{
+ int ret;
+
+ ret=at24_wakeup();
+ if(ret)
+ printf("wakeup_err=%d\n", ret);
+ return ret;
+}
+
+static int _at24_shutdown(void)
+{
+ at24_shutdown();
+ return 0;
+}
+
static int found_id_data;
/* Initialize the product ID data and return 0 if found */
static int product_id_init(void)
@@ -114,15 +163,8 @@ static int product_id_init(void)
* going back to the AT24 to read the data. */
id_data.mem_ptr = (void *)SRAM_BASE;
- ret=at24_wakeup();
- if(ret) {
- printf("wakeup_err=%d\n", ret);
- }
-
- ret = id_startup(&id_data);
-
- at24_shutdown();
+ ret = id_startup(&id_data, _at24_setup, _at24_shutdown);
if (ret != ID_EOK) {
return -1;
@@ -273,13 +315,25 @@ int logic_extract_gpmc_timing(int cs, int *config_regs)
int do_dump_id_data(cmd_tbl_t * cmdtp, int flag, int argc, char *const argv[])
{
+ int i;
printf("id_data: mem_ptr %p root_offset %u root_size %u\n",
id_data.mem_ptr, id_data.root_offset, id_data.root_size);
+
+ for (i=0; i<(id_data.root_offset + id_data.root_size); ++i) {
+ if (!(i & 0xf)) {
+ if (i)
+ printf("\n");
+ printf("%04x:", i);
+ }
+ printf(" %02x", id_data.mem_ptr[i]);
+ }
+ printf("\n");
+
return 1;
}
U_BOOT_CMD(
dump_id_data, 1, 1, do_dump_id_data,
"dump_id_data - dump product ID data",
- "dump product ID data in human-readable form"
+ "dump raw new product ID data as hex"
);
diff --git a/board/ti/logic/logic.c b/board/ti/logic/logic.c
index 94562bdd40..b6c16b1d40 100644
--- a/board/ti/logic/logic.c
+++ b/board/ti/logic/logic.c
@@ -31,6 +31,7 @@
#include <netdev.h>
#include <flash.h>
#include <nand.h>
+#include <malloc.h>
#include <i2c.h>
#include <twl4030.h>
#include <asm/io.h>
@@ -147,10 +148,59 @@ void nand_switch_ecc_method(int method)
omap_nand_switch_ecc(new_mode);
}
+/* Non-zero if NOR flash exists on SOM */
+int omap3logic_nor_exists;
+
+/* Dynamic MTD id/parts default value functions */
+static char *omap3logic_mtdparts_default;
+static char *omap3logic_mtdids_default;
+
+char *get_mtdparts_default(void)
+{
+ char str[strlen(MTDPARTS_NAND_DEFAULT) + strlen(MTDPARTS_NOR_DEFAULT) + 10];
+
+ if (!omap3logic_mtdparts_default) {
+ str[0] = '\0';
+ if (nand_size())
+ strcpy(str, MTDPARTS_NAND_DEFAULT);
+ if (omap3logic_nor_exists) {
+ if (strlen(str))
+ strcat(str, ";");
+
+ strcat(str, MTDPARTS_NOR_DEFAULT);
+ }
+ omap3logic_mtdparts_default = malloc(strlen(str) + 1);
+ if (omap3logic_mtdparts_default)
+ strcpy(omap3logic_mtdparts_default, str);
+ }
+ return omap3logic_mtdparts_default;
+}
+
+char *get_mtdids_default(void)
+{
+ char str[strlen(MTDIDS_NAND_DEFAULT) + strlen(MTDIDS_NOR_DEFAULT) + 10];
+
+ if (!omap3logic_mtdids_default) {
+ str[0] = '\0';
+ if (nand_size())
+ strcpy(str, MTDIDS_NAND_DEFAULT);
+ if (omap3logic_nor_exists) {
+ if (strlen(str))
+ strcat(str, ",");
+ strcat(str, MTDIDS_NOR_DEFAULT);
+ }
+ omap3logic_mtdids_default = malloc(strlen(str) + 1);
+ if (omap3logic_mtdids_default)
+ strcpy(omap3logic_mtdids_default, str);
+ }
+ return omap3logic_mtdids_default;
+}
+
/*
- * Touchup the environment, specificaly to setenv "defaultecc"
+ * Touchup the environment, specificaly "defaultecc", the display,
+ * and mtdids/mtdparts on default environment
*/
-void touchup_env(void)
+void touchup_env(int initial_env)
{
/* Set the defaultecc environment variable to the "natural"
* ECC method supported by the NAND chip */
@@ -163,6 +213,12 @@ void touchup_env(void)
/* touchup the display environment variable(s) */
touchup_display_env();
+
+ if (initial_env) {
+ /* Need to set mdtids/mtdparts to computed defaults */
+ setenv("mtdparts", get_mtdparts_default());
+ setenv("mtdids", get_mtdids_default());
+ }
}
/*
@@ -226,6 +282,14 @@ int board_init(void)
/* Probe for NOR and if found put into sync mode */
fix_flash_sync();
+ /* Initialize twl4030 voltages */
+ twl4030_power_init();
+
+ /* If we're a Torpedo, enable BBCHEN charge the backup battery */
+ if (gd->bd->bi_arch_number == MACH_TYPE_DM3730_TORPEDO
+ || gd->bd->bi_arch_number == MACH_TYPE_OMAP3_TORPEDO) {
+ twl4030_enable_bb_charging(3200, 25); /* 3.2V @ 25uA */
+ }
return 0;
}
@@ -243,7 +307,8 @@ int board_late_init(void)
#endif
#ifdef CONFIG_CMD_NAND_LOCK_UNLOCK
- nand_unlock(&nand_info[0], 0x0, nand_info[0].size);
+ if (nand_size())
+ nand_unlock(&nand_info[0], 0x0, nand_info[0].size);
#endif
#ifdef CONFIG_ENABLE_TWL4030_CHARGING
@@ -276,8 +341,6 @@ void init_vaux1_voltage(void)
unsigned char data;
unsigned short msg;
- i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
-
/* Select the output voltage */
data = 0x04;
i2c_write(I2C_TRITON2, 0x72, 1, &data, 1);
@@ -297,6 +360,27 @@ void init_vaux1_voltage(void)
#endif
}
+/* Mux I2C bus pins appropriately for this board */
+int i2c_mux_bux_pins(int bus)
+{
+ switch(bus) {
+ case 0:
+ /* I2C1_SCA/I2C1_SDL are *always* mixed for I2C */
+ break;
+ case 1:
+ MUX_VAL(CP(I2C2_SCL), (IEN | PTU | EN | M0));
+ MUX_VAL(CP(I2C2_SDA), (IEN | PTU | EN | M0));
+ break;
+ case 2:
+ MUX_VAL(CP(I2C3_SCL), (IEN | PTU | EN | M0));
+ MUX_VAL(CP(I2C3_SDA), (IEN | PTU | EN | M0));
+ break;
+ default:
+ return -1;
+ }
+ return 0;
+}
+
/*
* Check _SYSCONFIG registers and fixup bootrom code leaving them in
* non forced-idle/smart-stdby mode
@@ -326,11 +410,6 @@ static void check_sysconfig_regs(void)
*/
int misc_init_r(void)
{
-
-#ifdef CONFIG_DRIVER_OMAP34XX_I2C
- i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
-#endif
-
/* Turn on vaux1 to make sure voltage is to the product ID chip.
* Extract production data from ID chip, used to selectively
* initialize portions of the system */
@@ -387,6 +466,9 @@ static void setup_net_chip(void)
}
/* GPMC CS0 settings for Logic SOM LV/Torpedo NAND settings */
+#if 0
+/* Following are from current DVT (2012-03-13), but don't work on T+W;
+ * nand-small-stress-test2.sh shows differences between copied files */
#define LOGIC_NAND_GPMC_CONFIG1 0x00001800
#define LOGIC_NAND_GPMC_CONFIG2 0x00090900
#define LOGIC_NAND_GPMC_CONFIG3 0x00090900
@@ -394,6 +476,17 @@ static void setup_net_chip(void)
#define LOGIC_NAND_GPMC_CONFIG5 0x0007080A
#define LOGIC_NAND_GPMC_CONFIG6 0x000002CF
#define LOGIC_NAND_GPMC_CONFIG7 0x00000C70
+#else
+/* Timings that look to work on SOM LV/Torpedo after NAND testing;
+ * not sure if optimal */
+#define LOGIC_NAND_GPMC_CONFIG1 0x00001800
+#define LOGIC_NAND_GPMC_CONFIG2 0x00090900
+#define LOGIC_NAND_GPMC_CONFIG3 0x00090902
+#define LOGIC_NAND_GPMC_CONFIG4 0x07020702
+#define LOGIC_NAND_GPMC_CONFIG5 0x0008080A
+#define LOGIC_NAND_GPMC_CONFIG6 0x000002CF
+#define LOGIC_NAND_GPMC_CONFIG7 0x00000C70
+#endif
static void setup_nand_settings(void)
{
@@ -509,7 +602,6 @@ static void setup_isp176x_settings(void)
* Description: Setting up the configuration GPMC registers specific to the
* NOR flash (and place in sync mode if not done).
*/
-int omap3logic_flash_exists;
static void fix_flash_sync(void)
{
int arch_number;
@@ -591,7 +683,7 @@ static void fix_flash_sync(void)
} else
puts ("NOR: Already initialized in sync mode\n");
- omap3logic_flash_exists = 1;
+ omap3logic_nor_exists = 1;
}
int board_eth_init(bd_t *bis)
diff --git a/board/ti/logic/prod-id/Makefile b/board/ti/logic/prod-id/Makefile
new file mode 100644
index 0000000000..f6dea58eba
--- /dev/null
+++ b/board/ti/logic/prod-id/Makefile
@@ -0,0 +1,50 @@
+#
+# (C) Copyright 2000, 2001, 2002
+# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+#
+# See file CREDITS for list of people who contributed to this
+# project.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of
+# the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+
+include $(TOPDIR)/config.mk
+
+LIB = $(obj)libprod-id.o
+
+PROD_ID_OBJS := query.o startup.o crc-15.o \
+ extract.o type.o size.o
+
+COBJS := $(PROD_ID_OBJS)
+
+SRCS := $(COBJS:.o=.c)
+OBJS := $(addprefix $(obj),$(COBJS))
+
+$(LIB): $(obj).depend $(OBJS)
+ $(call cmd_link_o_target, $(OBJS))
+
+clean:
+ rm -f $(OBJS)
+
+distclean: clean
+ rm -f $(LIB) core *.bak $(obj).depend
+
+#########################################################################
+
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
+
+sinclude $(obj).depend
diff --git a/board/ti/logic/prod-id/interface.h b/board/ti/logic/prod-id/interface.h
index 2646df24ed..8333146a88 100644
--- a/board/ti/logic/prod-id/interface.h
+++ b/board/ti/logic/prod-id/interface.h
@@ -47,6 +47,7 @@ struct id_key {
* set *oor to non-zero. If mem_ptr is non-NULL use it as a pointer to
* a cached copy of the ID data */
extern unsigned char id_fetch_byte(unsigned char *mem_ptr, int offset, int *oor);
+extern void id_fetch_bytes(unsigned char *mem_ptr, int offset, int size, int *oor);
struct id_data {
/* mem_ptr is a pointer to read the initial ID data into, then if not
@@ -58,7 +59,10 @@ struct id_data {
/* Function to do the intial startup (i.e. figure out how much data, offset of
* key table, etc */
-extern int id_startup(struct id_data *data);
+extern int id_startup(struct id_data *data,
+ int (*setup_id_chip)(void),
+ int (*shutdown_id_chip)(void));
+
/*
* Functions provided back to callers for use in accessing data
*/
@@ -82,6 +86,8 @@ extern int id_whatis(struct id_cookie *cookie, idenum_t *type);
/* Given a string, return the key code (or -1 if not found) */
extern int id_data_get_key(char *key_name);
+/* Define to get id_dbg_printf() output... */
+#undef DEBUG_NEW_ID_CODE
/* ID error routine to handle malformed data */
extern void id_error(const char *fmt, ...);
@@ -89,6 +95,13 @@ extern void id_error(const char *fmt, ...);
/* Ouptut routine */
extern int id_printf(const char *format, ...);
+/* Ouptut debug routine; define DEBUG_NEW_ID_CODE to enable it */
+#ifdef DEBUG_NEW_ID_CODE
+extern int id_dbg_printf(const char *format, ...);
+#else
+#define id_dbg_printf(fmt, ...)
+#endif
+
/* User interface functions */
extern int id_dict_size(struct id_data *data, struct id_cookie *cookie);
diff --git a/board/ti/logic/prod-id/startup.c b/board/ti/logic/prod-id/startup.c
index 73dd74069d..d87836ccd1 100644
--- a/board/ti/logic/prod-id/startup.c
+++ b/board/ti/logic/prod-id/startup.c
@@ -19,7 +19,7 @@ struct __attribute__ ((packed)) id_checksums {
unsigned short data;
} ;
-int id_startup(struct id_data *data)
+static int _id_startup(struct id_data *data, int first_run)
{
int i, err;
struct id_cookie cookie;
@@ -28,68 +28,74 @@ int id_startup(struct id_data *data)
unsigned short xsum;
struct id_header hdr;
struct id_checksums xsums;
- unsigned char *mem_ptr = data->mem_ptr;
-
- /* Clear out data->mem_ptr since we want all the fetches to come
- * from the AT24 chip. Once we've validated the CRCs, restore
- * data->mem_ptr to allow id_fetch_byte to read from data->mem_ptr
- * instead of the AT24 chip. Should speed up accesses dramatically */
- data->mem_ptr = NULL;
+ unsigned char *mem_ptr;
+ unsigned char *cache_ptr;
+
+ if (first_run) {
+ cache_ptr = data->mem_ptr;
+ data->mem_ptr = NULL;
+ mem_ptr = NULL;
+ } else {
+ cache_ptr = NULL;
+ mem_ptr = data->mem_ptr;
+ }
+
+ id_dbg_printf("%s: first_run %d cach_ptr %p mem_ptr %p\n", __FUNCTION__, first_run, cache_ptr, mem_ptr);
memset(&cookie, 0, sizeof(cookie));
/* Data starts with the header, should be 'LpId' */
for (i=0; i<4; ++i) {
- byte = id_fetch_byte(NULL, cookie.offset, &err);
+ byte = id_fetch_byte(cache_ptr, cookie.offset, &err);
if (mem_ptr)
mem_ptr[cookie.offset] = byte;
hdr.signature[i] = byte;
cookie.offset++;
if (err != ID_EOK) {
- id_printf("%s[%u]\n", __FILE__, __LINE__);
+ id_dbg_printf("%s[%u]\n", __FILE__, __LINE__);
goto err_ret;
}
if (hdr.signature[i] != header_tag[i]) {
- id_printf("%s[%u]\n", __FILE__, __LINE__);
+ id_dbg_printf("%s[%u]\n", __FILE__, __LINE__);
err = ID_ENODEV;
goto err_ret;
}
}
/* First LE 8-bit value is ID format version */
- byte = id_fetch_byte(NULL, cookie.offset, &err);
+ byte = id_fetch_byte(cache_ptr, cookie.offset, &err);
if (mem_ptr)
mem_ptr[cookie.offset] = byte;
hdr.id_fmt_ver = byte;
cookie.offset++;
/* Second LE 8-bit value is currently not used */
- byte = id_fetch_byte(NULL, cookie.offset, &err);
+ byte = id_fetch_byte(cache_ptr, cookie.offset, &err);
if (mem_ptr)
mem_ptr[cookie.offset] = byte;
hdr.unused0 = byte;
cookie.offset++;
/* Next LE 16-bit value is length of data */
- byte = id_fetch_byte(NULL, cookie.offset, &err);
+ byte = id_fetch_byte(cache_ptr, cookie.offset, &err);
if (mem_ptr)
mem_ptr[cookie.offset] = byte;
hdr.data_length = byte;
cookie.offset++;
- byte = id_fetch_byte(NULL, cookie.offset, &err);
+ byte = id_fetch_byte(cache_ptr, cookie.offset, &err);
if (mem_ptr)
mem_ptr[cookie.offset] = byte;
hdr.data_length |= byte << 8;
cookie.offset++;
/* Next LE 16-bit value is xsum of header */
- byte = id_fetch_byte(NULL, cookie.offset, &err);
+ byte = id_fetch_byte(cache_ptr, cookie.offset, &err);
if (mem_ptr)
mem_ptr[cookie.offset] = byte;
xsums.header = byte;
cookie.offset++;
- byte = id_fetch_byte(NULL, cookie.offset, &err);
+ byte = id_fetch_byte(cache_ptr, cookie.offset, &err);
if (mem_ptr)
mem_ptr[cookie.offset] = byte;
xsums.header |= byte << 8;
@@ -102,20 +108,20 @@ int id_startup(struct id_data *data)
crc_15_step(&xsum, p[i]);
if (xsum != xsums.header) {
- id_printf("%s[%u] xsum: 0x%04x, xsums.header: 0x%04x\n",
+ id_dbg_printf("%s[%u] xsum: 0x%04x, xsums.header: 0x%04x\n",
__FILE__, __LINE__, xsum, xsums.header);
err = -ID_EL2NSYNC;
goto err_ret;
}
/* Next LE 16-bit value is xsum of data */
- byte = id_fetch_byte(NULL, cookie.offset, &err);
+ byte = id_fetch_byte(cache_ptr, cookie.offset, &err);
if (mem_ptr)
mem_ptr[cookie.offset] = byte;
xsums.data = byte;
cookie.offset++;
- byte = id_fetch_byte(NULL, cookie.offset, &err);
+ byte = id_fetch_byte(cache_ptr, cookie.offset, &err);
if (mem_ptr)
mem_ptr[cookie.offset] = byte;
xsums.data |= byte << 8;
@@ -123,42 +129,57 @@ int id_startup(struct id_data *data)
/* Checksum the data (next id_len bytes), must match xsums.data */
xsum = 0;
- for (i = 0; i < hdr.data_length; ++i) {
- byte = id_fetch_byte(NULL, cookie.offset + i, &err);
- if (mem_ptr)
- mem_ptr[cookie.offset + i] = byte;
+ id_dbg_printf("%s: mem_ptr %p\n", __FUNCTION__, mem_ptr);
+ if (mem_ptr) {
+ id_fetch_bytes(mem_ptr+cookie.offset, cookie.offset, hdr.data_length, &err);
if (err != ID_EOK) {
- id_printf("%s[%u]\n", __FILE__, __LINE__);
- goto err_ret;
+ id_error("%s:%d err %d", __FUNCTION__, __LINE__, err);
+ goto hard_way;
+ }
+ for (i = 0; i < hdr.data_length; ++i) {
+ crc_15_step(&xsum, mem_ptr[cookie.offset + i]);
+ }
+ } else {
+ hard_way:
+ for (i = 0; i < hdr.data_length; ++i) {
+ byte = id_fetch_byte(cache_ptr, cookie.offset + i, &err);
+ if (mem_ptr)
+ mem_ptr[cookie.offset + i] = byte;
+ if (err != ID_EOK) {
+ id_dbg_printf("%s[%u]\n", __FILE__, __LINE__);
+ goto err_ret;
+ }
+ crc_15_step(&xsum, byte);
}
- crc_15_step(&xsum, byte);
}
if (xsum != xsums.data) {
- id_printf("%s[%u] xsum: 0x%04x, xsums.data: 0x%04x\n",
+ id_dbg_printf("%s[%u] xsum: 0x%04x, xsums.data: 0x%04x\n",
__FILE__, __LINE__, xsum, xsums.data);
err = -ID_EL2NSYNC;
goto err_ret;
}
+
/* offset is now at the first byte of the root dictionary which
contains its span */
data->root_offset = cookie.offset;
+ cookie.mem_ptr = cache_ptr;
data->root_size = extract_unsigned_pnum(&cookie, 5, &err);
if (err != ID_EOK) {
- id_printf("%s[%u]\n", __FILE__, __LINE__);
+ id_dbg_printf("%s[%u]\n", __FILE__, __LINE__);
goto err_ret;
}
- data->root_size += cookie.offset - data->root_offset;
-
-#if 0
- id_printf("Data format version: %u\n", hdr.id_fmt_ver);
-#endif
-
/* Restore data->mem_ptr to allow id_fetch_byte to read
* from the cached data instead of the AT24 chip */
data->mem_ptr = mem_ptr;
+ id_dbg_printf("%s:%d root_size (old %u) now %u + %u\n", __FUNCTION__, __LINE__,
+ data->root_size, cookie.offset, data->root_offset);
+ data->root_size += cookie.offset - data->root_offset;
+
+ id_dbg_printf("Data format version: %u\n", hdr.id_fmt_ver);
+
return ID_EOK;
err_ret:
@@ -170,6 +191,39 @@ err_ret:
return err;
}
+int id_startup(struct id_data *data, int (*setup_id_chip)(void), int (*shutdown_id_chip)(void))
+{
+ int ret, ret2;
+ void *mem_ptr = data->mem_ptr;
+
+ /* See if product ID already exists in SRAM (i.e. from x-loader) */
+ if (data->mem_ptr) {
+ ret = _id_startup(data, 1);
+ data->mem_ptr = mem_ptr;
+ if (!ret) {
+ id_printf("Found new Product ID data at %p\n", mem_ptr);
+ return ret;
+ }
+ }
+
+ /* No ID data in SRAM, setup the ID chip and read for real */
+ ret = (*setup_id_chip)();
+ if (ret) {
+ id_error("%s: setup_id_chip failed!", __FUNCTION__);
+ return ret;
+ }
+ ret = _id_startup(data, 0);
+ if (!ret)
+ id_printf("Cache new Product ID data from AT24 to %p\n", mem_ptr);
+ ret2 = (*shutdown_id_chip)();
+ if (ret2)
+ id_error("%s: shutdown_id_chip failed!", __FUNCTION__);
+
+ if (!ret && ret2)
+ ret = ret2;
+
+ return ret;
+}
/*
* Reset the cookie to cover the whole root dictionary
*/
diff --git a/common/cmd_mtdparts.c b/common/cmd_mtdparts.c
index d0639f6cd2..32d6c899d1 100644
--- a/common/cmd_mtdparts.c
+++ b/common/cmd_mtdparts.c
@@ -124,6 +124,7 @@
* field for read-only partitions */
#define MTD_WRITEABLE_CMD 1
+#ifndef CONFIG_MTDPARTS_DYNAMIC_DEFAULT
/* default values for mtdids and mtdparts variables */
#if defined(MTDIDS_DEFAULT)
static const char *const mtdids_default = MTDIDS_DEFAULT;
@@ -136,6 +137,15 @@ static const char *const mtdparts_default = MTDPARTS_DEFAULT;
#else
static const char *const mtdparts_default = NULL;
#endif
+char *get_mtdparts_default(void)
+{
+ return (char *)mtdparts_default;
+}
+char *get_mtdids_default(void)
+{
+ return (char *)mtdids_default;
+}
+#endif
/* copies of last seen 'mtdids', 'mtdparts' and 'partition' env variables */
#define MTDIDS_MAXLEN 128
@@ -1307,6 +1317,7 @@ static void print_partition_table(void)
static void list_partitions(void)
{
struct part_info *part;
+ char *mtdids_default, *mtdparts_default;
debug("\n---list_partitions---\n");
print_partition_table();
@@ -1324,6 +1335,7 @@ static void list_partitions(void)
}
}
+ mtdids_default = get_mtdids_default();
printf("\ndefaults:\n");
printf("mtdids : %s\n",
mtdids_default ? mtdids_default : "none");
@@ -1332,6 +1344,7 @@ static void list_partitions(void)
* if default mtdparts string is greater than console
* printbuffer. Use puts() to prevent system crashes.
*/
+ mtdparts_default = get_mtdparts_default();
puts("mtdparts: ");
puts(mtdparts_default ? mtdparts_default : "none");
puts("\n");
@@ -1715,6 +1728,7 @@ int mtdparts_init(void)
const char *current_partition;
int ids_changed;
char tmp_ep[PARTITION_MAXLEN];
+ char *mtdids_default, *mtdparts_default;
debug("\n---mtdparts_init---\n");
if (!initialized) {
@@ -1747,6 +1761,7 @@ int mtdparts_init(void)
/* if mtdids varible is empty try to use defaults */
if (!ids) {
+ mtdids_default = get_mtdids_default();
if (mtdids_default) {
debug("mtdids variable not defined, using default\n");
ids = mtdids_default;
@@ -1933,8 +1948,12 @@ int do_chpart(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
*/
int do_mtdparts(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
+ char *mtdids_default, *mtdparts_default;
+
if (argc == 2) {
if (strcmp(argv[1], "default") == 0) {
+ mtdids_default = get_mtdids_default();
+ mtdparts_default = get_mtdparts_default();
setenv("mtdids", (char *)mtdids_default);
setenv("mtdparts", (char *)mtdparts_default);
setenv("partition", NULL);
diff --git a/common/cmd_nvedit.c b/common/cmd_nvedit.c
index 91728f7109..bbebdd2f37 100644
--- a/common/cmd_nvedit.c
+++ b/common/cmd_nvedit.c
@@ -591,11 +591,6 @@ static int do_env_default(cmd_tbl_t *cmdtp, int flag, int argc, char * const arg
return cmd_usage(cmdtp);
set_default_env("## Resetting to default environment\n");
-#if defined(CONFIG_TOUCHUP_ENV)
- /* On a restored environment, need to initialise board
- * specific variables */
- touchup_env();
-#endif
return 0;
}
diff --git a/common/console.c b/common/console.c
index 8c650e05e1..340eee878f 100644
--- a/common/console.c
+++ b/common/console.c
@@ -270,22 +270,29 @@ void fputs(int file, const char *s)
console_puts(file, s);
}
+void fprintf_out(struct vsprintf_out *p, char ch)
+{
+ fputc(p->dat.file, ch);
+}
+
int fprintf(int file, const char *fmt, ...)
{
va_list args;
uint i;
- char printbuffer[CONFIG_SYS_PBSIZE];
+ struct vsprintf_out r;
+
+ memset(&r, 0, sizeof(r));
+ r.out = fprintf_out;
+ r.dat.file = file;
va_start(args, fmt);
/* For this to work, printbuffer must be larger than
* anything we ever want to print.
*/
- i = vsprintf(printbuffer, fmt, args);
+ i = vsfprintf(&r, fmt, args);
va_end(args);
- /* Send to desired file */
- fputs(file, printbuffer);
return i;
}
@@ -365,37 +372,39 @@ void puts(const char *s)
}
}
+static void vprintf_out(struct vsprintf_out *p, char ch)
+{
+ p->dat.len++;
+ putc(ch);
+}
+
+
int printf(const char *fmt, ...)
{
va_list args;
uint i;
- char printbuffer[CONFIG_SYS_PBSIZE];
+ struct vsprintf_out r;
- va_start(args, fmt);
+ memset(&r, 0, sizeof(r));
+ r.out = vprintf_out;
- /* For this to work, printbuffer must be larger than
- * anything we ever want to print.
- */
- i = vsprintf(printbuffer, fmt, args);
+ va_start(args, fmt);
+ i = vsfprintf(&r, fmt, args);
va_end(args);
- /* Print the string */
- puts(printbuffer);
return i;
}
int vprintf(const char *fmt, va_list args)
{
uint i;
- char printbuffer[CONFIG_SYS_PBSIZE];
+ struct vsprintf_out r;
- /* For this to work, printbuffer must be larger than
- * anything we ever want to print.
- */
- i = vsprintf(printbuffer, fmt, args);
+ memset(&r, 0, sizeof(r));
+ r.out = vprintf_out;
+
+ i = vsfprintf(&r, fmt, args);
- /* Print the string */
- puts(printbuffer);
return i;
}
@@ -459,7 +468,7 @@ inline void dbg(const char *fmt, ...)
/* For this to work, printbuffer must be larger than
* anything we ever want to print.
*/
- i = vsprintf(printbuffer, fmt, args);
+ i = vsnprintf(printbuffer, sizeof(printbuffer), fmt, args);
va_end(args);
if ((screen + sizeof(screen) - 1 - cursor)
diff --git a/common/env_common.c b/common/env_common.c
index 04a947e92b..af7a9cb57c 100644
--- a/common/env_common.c
+++ b/common/env_common.c
@@ -194,6 +194,9 @@ void set_default_env(const char *s)
error("Environment import failed: errno = %d\n", errno);
}
gd->flags |= GD_FLG_ENV_READY;
+#ifdef CONFIG_TOUCHUP_ENV
+ touchup_env(1);
+#endif
}
int env_check_valid(const char *buf)
@@ -221,6 +224,9 @@ int env_import(const char *buf, int check)
if (himport_r(&env_htab, (char *)ep->data, ENV_SIZE, '\0', 0)) {
gd->flags |= GD_FLG_ENV_READY;
+#ifdef CONFIG_TOUCHUP_ENV
+ touchup_env(0);
+#endif
return 1;
}
@@ -247,10 +253,10 @@ void env_relocate (void)
#endif
} else {
env_relocate_spec ();
- }
#ifdef CONFIG_TOUCHUP_ENV
- touchup_env();
+ touchup_env(0);
#endif
+ }
}
#ifdef CONFIG_AUTO_COMPLETE
diff --git a/drivers/dma/Makefile b/drivers/dma/Makefile
index 9d945a042a..c585f332a7 100644
--- a/drivers/dma/Makefile
+++ b/drivers/dma/Makefile
@@ -25,6 +25,8 @@ include $(TOPDIR)/config.mk
LIB := $(obj)libdma.o
+COBJS-$(CONFIG_OMAP_DMA) += omap3_dma.o
+
COBJS-$(CONFIG_FSLDMAFEC) += MCD_tasksInit.o MCD_dmaApi.o MCD_tasks.o
COBJS-$(CONFIG_FSL_DMA) += fsl_dma.o
diff --git a/drivers/dma/omap3_dma.c b/drivers/dma/omap3_dma.c
new file mode 100644
index 0000000000..869e686d99
--- /dev/null
+++ b/drivers/dma/omap3_dma.c
@@ -0,0 +1,242 @@
+/* Copyright (C) 2011
+ * Corscience GmbH & Co. KG - Simon Schwarz <schwarz <at> corscience.de>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+/* This is a basic implementation of the SDMA/DMA4 controller of OMAP3
+ * Tested on Silicon Revision major:0x4 minor:0x0
+ */
+
+#include <common.h>
+#include <asm/arch/cpu.h>
+#include <asm/arch/dma.h>
+#include <asm/io.h>
+#include <asm/errno.h>
+
+static struct dma4 *dma4_cfg = (struct dma4 *)OMAP34XX_DMA4_BASE;
+uint32_t dma_active; /* if a transfer is started the respective
+ bit is set for the logical channel */
+
+/* Initial config of omap dma */
+void omap3_dma_init(void)
+{
+ dma_active = 0;
+ writel(~0, &dma4_cfg->irqenable_l[0]);
+}
+
+/* Check if we have the given channel
+ * PARAMETERS:
+ * chan: Channel number
+ *
+ * RETURN of non-zero means error */
+static inline int check_channel(uint32_t chan)
+{
+ if (chan < CHAN_NR_MIN || chan > CHAN_NR_MAX)
+ return -EINVAL;
+ return 0;
+}
+
+static inline void reset_irq(uint32_t chan)
+{
+ /* reset IRQ reason */
+#if 1
+ writel(CSR_ALL_MASK, &dma4_cfg->chan[chan].csr);
+#else
+ writel(0x1DFE, &dma4_cfg->chan[chan].csr);
+#endif
+ /* reset IRQ */
+ writel((1 << chan), &dma4_cfg->irqstatus_l[0]);
+ dma_active &= ~(1 << chan);
+}
+
+/* Set Source, Destination and Size of DMA transfer for the
+ * specified channel.
+ * PARAMETERS:
+ * chan: channel to use
+ * src: source of the transfer
+ * dst: destination of the transfer
+ * sze: Size of the transfer
+ *
+ * RETURN of non-zero means error */
+int omap3_dma_conf_transfer(uint32_t chan, uint32_t *src, uint32_t *dst,
+ uint32_t sze)
+{
+ if (check_channel(chan))
+ return -EINVAL;
+ /* CDSA0 */
+ writel((uint32_t)src, &dma4_cfg->chan[chan].cssa);
+ writel((uint32_t)dst, &dma4_cfg->chan[chan].cdsa);
+ writel(sze, &dma4_cfg->chan[chan].cen);
+ return 0;
+}
+
+/* Start the DMA transfer */
+int omap3_dma_start_transfer(uint32_t chan)
+{
+ uint32_t val;
+
+ if (check_channel(chan))
+ return -EINVAL;
+
+ val = readl(&dma4_cfg->chan[chan].ccr);
+ /* Test for channel already in use */
+ if (val & CCR_ENABLE_ENABLE) {
+ printf("%s: ccr %x, returning -EBUSY\n", __FUNCTION__, val);
+ return -EBUSY;
+ }
+
+ writel((val | CCR_ENABLE_ENABLE), &dma4_cfg->chan[chan].ccr);
+ dma_active |= (1 << chan);
+ debug("started transfer...\n");
+ return 0;
+}
+
+void omap3_dma_channel_init(int channel, int next_channel, int csdp_size,
+ int ccr_src_amode, int ccr_dst_amode)
+{
+ struct dma4_chan cfg;
+
+ /* config the channel */
+ omap3_dma_get_conf_chan(channel, &cfg);
+#if 1
+ cfg.csdp = CSDP_SRC_BURST_EN_64BYTES |
+ CSDP_DST_BURST_EN_64BYTES | CSDP_DST_ENDIAN_LOCK_ADAPT |
+ CSDP_DST_ENDIAN_LITTLE | CSDP_SRC_ENDIAN_LOCK_ADAPT |
+ CSDP_SRC_ENDIAN_LITTLE;
+ cfg.cfn = 1;
+ cfg.ccr = CCR_READ_PRIORITY_HIGH;
+ cfg.csdp |= csdp_size;
+ cfg.ccr |= ccr_src_amode;
+ cfg.ccr |= ccr_dst_amode;
+#else
+ cfg.cdsp |= CSDP_DATA_TYPE_32BIT;
+ cfg.csdp = CSDP_DATA_TYPE_32BIT | CSDP_SRC_BURST_EN_64BYTES |
+ CSDP_DST_BURST_EN_64BYTES | CSDP_DST_ENDIAN_LOCK_ADAPT |
+ CSDP_DST_ENDIAN_LITTLE | CSDP_SRC_ENDIAN_LOCK_ADAPT |
+ CSDP_SRC_ENDIAN_LITTLE;
+ cfg.ccr = CCR_READ_PRIORITY_HIGH | CCR_DST_AMODE_POST_INC;
+ if (src_post_incr)
+ {
+ cfg.ccr |= CCR_SRC_AMODE_CONSTANT;
+ }
+ else
+ {
+ cfg.ccr |= CCR_SRC_AMODE_POST_INC;
+ }
+#endif
+ cfg.cicr = CICR_BLOCK_IE | CICR_MISALIGNED_ERR_IE
+ | CICR_SUPERVISOR_ERR_IE | CICR_TRANS_ERR_IE;
+
+ if (next_channel >= 0)
+ {
+ cfg.clnk_ctrl = CLNK_CTRL_ENABLE_LNK | next_channel;
+ }
+ else
+ {
+ cfg.clnk_ctrl = 0;
+ }
+ omap3_dma_set_conf_chan(channel, &cfg);
+}
+
+/* Busy-waiting for a DMA transfer
+ * This has to be called before another transfer is started
+ * PARAMETER
+ * chan: Channel to wait for
+ *
+ * RETURN of non-zero means error*/
+int omap3_dma_wait_for_transfer(uint32_t chan, int chained)
+{
+ uint32_t val;
+
+ if (!chained)
+ {
+ if (!(dma_active & (1 << chan))) {
+ val = readl(&dma4_cfg->irqstatus_l[0]);
+ if (!(val & chan)) {
+ debug("dma: The channel you are trying to wait for "
+ "was never activated - ERROR\n");
+ return -1; /* channel was never active */
+ }
+ }
+ }
+
+ /* all irqs on line 0 */
+ while (!(readl(&dma4_cfg->irqstatus_l[0]) & (1 << chan)))
+ asm("nop");
+
+ val = readl(&dma4_cfg->chan[chan].csr);
+ if ((val & CSR_TRANS_ERR) | (val & CSR_SUPERVISOR_ERR) |
+ (val & CSR_MISALIGNED_ADRS_ERR)) {
+ debug("err code: %X\n", val);
+ debug("dma: transfer error detected\n");
+ reset_irq(chan);
+ return -1;
+ }
+ reset_irq(chan);
+ return 0;
+}
+
+int omap3_dma_transfer(int channel, void *src, void *dst, int size, int flags)
+{
+ int res;
+ res = omap3_dma_conf_transfer(channel, src, dst, (size + 3) / 4);
+ if (res < 0)
+ {
+ printf("omap3_dma_conf_transfer = %d\n", res);
+ return res;
+ }
+ if (flags & FB_DMA_START)
+ {
+ res = omap3_dma_start_transfer(channel);
+ if (res < 0)
+ {
+ printf("omap3_dma_start_transfer = %d\n", res);
+ return res;
+ }
+ }
+ if (flags & FB_DMA_WAIT)
+ {
+ res = omap3_dma_wait_for_transfer(channel, 0);
+ }
+ return res;
+}
+
+/* set channel config to config
+ *
+ * RETURN of non-zero means error */
+int omap3_dma_set_conf_chan(uint32_t chan, struct dma4_chan *config)
+{
+ if (check_channel(chan))
+ return -EINVAL;
+ /* Dinon - Use dma4_chan_padded instead of dma4_chan for
+ * channel 1 ~ 31 to work */
+ *((struct dma4_chan *)&dma4_cfg->chan[chan]) = *config;
+ return 0;
+}
+
+/* get channel config to config
+ *
+ * RETURN of non-zero means error */
+int omap3_dma_get_conf_chan(uint32_t chan, struct dma4_chan *config)
+{
+ if (check_channel(chan))
+ return -EINVAL;
+ /* Dinon - Use dma4_chan_padded instead of dma4_chan for
+ * channel 1 ~ 31 to work */
+ *config = *((struct dma4_chan *)&dma4_cfg->chan[chan]);
+ return 0;
+}
diff --git a/drivers/i2c/omap24xx_i2c.c b/drivers/i2c/omap24xx_i2c.c
index ec02a5d33e..ca64e37ce6 100644
--- a/drivers/i2c/omap24xx_i2c.c
+++ b/drivers/i2c/omap24xx_i2c.c
@@ -40,6 +40,12 @@ static struct i2c *i2c_base = (struct i2c *)I2C_DEFAULT_BASE;
static unsigned int bus_initialized[I2C_BUS_MAX];
static unsigned int current_bus;
+int __i2c_mux_bus_pins(int bus)
+{
+ return 0;
+}
+void i2c_mux_bus_pins(int bus) __attribute__ ((weak, alias ("__i2c_mux_bus_pins")));
+
void i2c_init (int speed, int slaveadd)
{
int psc, fsscll, fssclh;
@@ -143,6 +149,7 @@ void i2c_init (int speed, int slaveadd)
if (gd->flags & GD_FLG_RELOC)
bus_initialized[current_bus] = 1;
+ i2c_mux_bus_pins(current_bus);
}
static int i2c_read_byte (u8 devaddr, u8 regoffset, u8 * value)
diff --git a/drivers/mmc/omap3_mmc.c b/drivers/mmc/omap3_mmc.c
index 83d2791887..3f1252dddb 100644
--- a/drivers/mmc/omap3_mmc.c
+++ b/drivers/mmc/omap3_mmc.c
@@ -30,6 +30,9 @@
#include <i2c.h>
#include <twl4030.h>
#include <asm/io.h>
+#include <asm/arch/dma.h>
+
+#undef CONFIG_OMAP_DMA /* DMA for MMC doesn't work yet */
#include "omap3_mmc.h"
@@ -280,11 +283,19 @@ static unsigned char mmc_read_data(unsigned int *output_buf)
writel(readl(&mmc_base->stat) | BRR_MASK,
&mmc_base->stat);
+#ifdef CONFIG_OMAP_DMA
+ /* Invalidate the datacache for the buffer,
+ * setup the DMA and wait for it to finish */
+ invalidate_dcache_range((unsigned long)output_buf, MMCSD_SECTOR_SIZE);
+
+ omap3_dma_transfer(DMA_CHANNEL_MMC, &mmc_base->data, output_buf, MMCSD_SECTOR_SIZE, FB_DMA_START | FB_DMA_WAIT);
+#else
for (k = 0; k < MMCSD_SECTOR_SIZE / 4; k++) {
*output_buf = readl(&mmc_base->data);
output_buf++;
read_count += 4;
}
+#endif
}
if (mmc_stat & BWR_MASK)
@@ -641,6 +652,11 @@ int mmc_legacy_init(int dev)
mmc_blk_dev.removable = 0;
mmc_blk_dev.block_read = mmc_bread;
+#ifdef CONFIG_OMAP_DMA
+ omap3_dma_channel_init(DMA_CHANNEL_MMC, -1, CSDP_DATA_TYPE_32BIT, CCR_SRC_AMODE_CONSTANT, CCR_DST_AMODE_POST_INC);
+#endif
+
fat_register_device(&mmc_blk_dev, 1);
+
return 0;
}
diff --git a/drivers/mtd/nand/nand.c b/drivers/mtd/nand/nand.c
index d987f4c85c..8a623e8480 100644
--- a/drivers/mtd/nand/nand.c
+++ b/drivers/mtd/nand/nand.c
@@ -77,17 +77,22 @@ static void nand_init_chip(struct mtd_info *mtd, struct nand_chip *nand,
}
+unsigned int mtd_nand_size;
+unsigned int nand_size(void)
+{
+ return mtd_nand_size;
+}
+
void nand_init(void)
{
int i;
- unsigned int size = 0;
for (i = 0; i < CONFIG_SYS_MAX_NAND_DEVICE; i++) {
nand_init_chip(&nand_info[i], &nand_chip[i], base_address[i]);
- size += nand_info[i].size / 1024;
+ mtd_nand_size += nand_info[i].size / 1024;
if (nand_curr_device == -1)
nand_curr_device = i;
}
- printf("%u MiB\n", size / 1024);
+ printf("%u MiB\n", mtd_nand_size / 1024);
#ifdef CONFIG_SYS_NAND_SELECT_DEVICE
/*
diff --git a/drivers/mtd/nand/nand_util.c b/drivers/mtd/nand/nand_util.c
index 82e661d39c..c9f1283fa0 100644
--- a/drivers/mtd/nand/nand_util.c
+++ b/drivers/mtd/nand/nand_util.c
@@ -510,7 +510,8 @@ int nand_write_skip_bad(nand_info_t *nand, loff_t offset, size_t *length,
return -EINVAL;
}
- if (!need_skip && !withoob) {
+ /* Write one page at a time since need to update percentage */
+ if (0 && !need_skip && !withoob) {
rval = nand_write (nand, offset, length, buffer);
if (rval == 0)
return 0;
diff --git a/drivers/mtd/nand/omap_gpmc.c b/drivers/mtd/nand/omap_gpmc.c
index d5ee9bc583..1a636cad23 100644
--- a/drivers/mtd/nand/omap_gpmc.c
+++ b/drivers/mtd/nand/omap_gpmc.c
@@ -31,8 +31,49 @@
#include <linux/mtd/nand_ecc.h>
#include <linux/mtd/nand_bch.h>
#include <nand.h>
+#include <asm/arch/dma.h>
+
static uint8_t cs;
+
+#ifdef CONFIG_OMAP_DMA
+void omap_dma_read_buf16(struct mtd_info *mtd, uint8_t *buf, int len)
+{
+ int i;
+ struct nand_chip *chip = mtd->priv;
+ u16 *p = (u16 *) buf;
+
+// printf("%s: len %u\n", __FUNCTION__, len);
+
+
+ /* If request is too small, read it by hand */
+ if (len <= 32) {
+ len >>= 1;
+ for (i = 0; i < len; i+=8) {
+ *p++ = readw(chip->IO_ADDR_R);
+ *p++ = readw(chip->IO_ADDR_R);
+ *p++ = readw(chip->IO_ADDR_R);
+ *p++ = readw(chip->IO_ADDR_R);
+ *p++ = readw(chip->IO_ADDR_R);
+ *p++ = readw(chip->IO_ADDR_R);
+ *p++ = readw(chip->IO_ADDR_R);
+ *p++ = readw(chip->IO_ADDR_R);
+ }
+ for (; i < len; ++i)
+ *p++ = readw(chip->IO_ADDR_R);
+ return;
+ }
+
+ /* Invalidate the datacache for the buffer, program the DMA and wait
+ * for it to finish */
+ invalidate_dcache_range((unsigned long)p, (unsigned long)(p + len));
+
+
+ /* Transfer the data(and wait to complete) */
+ omap3_dma_transfer(DMA_CHANNEL_NAND, chip->IO_ADDR_R, buf, len, FB_DMA_START | FB_DMA_WAIT);
+}
+#endif
+
static struct nand_ecclayout hw_nand_oob = GPMC_NAND_HW_ECC_LAYOUT;
static struct nand_ecclayout chip_nand_oob = GPMC_NAND_CHIP_ECC_LAYOUT;
@@ -282,7 +323,7 @@ int omap_nand_chip_has_ecc(void)
if (nand_curr_device < 0 ||
nand_curr_device >= CONFIG_SYS_MAX_NAND_DEVICE ||
!nand_info[nand_curr_device].name) {
- printf("Error: Can't switch ecc, no devices available\n");
+ /* If no device, no in-chip ECC! */
return 0;
}
@@ -572,10 +613,8 @@ void omap_nand_switch_ecc(enum omap_nand_ecc_mode mode)
if (nand_curr_device < 0 ||
nand_curr_device >= CONFIG_SYS_MAX_NAND_DEVICE ||
- !nand_info[nand_curr_device].name) {
- printf("Error: Can't switch ecc, no devices available\n");
+ !nand_info[nand_curr_device].name)
return;
- }
mtd = &nand_info[nand_curr_device];
nand = mtd->priv;
@@ -664,6 +703,13 @@ void omap_nand_switch_ecc(enum omap_nand_ecc_mode mode)
nand->ecc.hwctl = omap_enable_chip_hwecc;
nand->ecc.correct = omap_correct_chip_hwecc;
nand->ecc.read_oob = omap_read_oob_chipecc;
+#ifdef CONFIG_OMAP_DMA
+ omap3_dma_channel_init(DMA_CHANNEL_NAND, -1, CSDP_DATA_TYPE_32BIT, CCR_SRC_AMODE_CONSTANT, CCR_DST_AMODE_POST_INC);
+ if (nand->options & NAND_BUSWIDTH_16)
+ nand->read_buf = omap_dma_read_buf16;
+ else
+ printf("%s: Huh? not 16-bit for DMA\n", __FUNCTION__);
+#endif
nand->ecc.mode = NAND_ECC_CHIP; /* internal to chip */
nand->ecc.layout = &chip_nand_oob;
if (nand->options & NAND_BUSWIDTH_16)
diff --git a/drivers/power/twl4030.c b/drivers/power/twl4030.c
index cf79161aaf..b62ed176d2 100644
--- a/drivers/power/twl4030.c
+++ b/drivers/power/twl4030.c
@@ -86,7 +86,7 @@ void twl4030_power_init(void)
twl4030_pmrecv_vsel_cfg(TWL4030_PM_RECEIVER_VPLL2_DEDICATED,
TWL4030_PM_RECEIVER_VPLL2_VSEL_18,
TWL4030_PM_RECEIVER_VPLL2_DEV_GRP,
- TWL4030_PM_RECEIVER_DEV_GRP_ALL);
+ TWL4030_PM_RECEIVER_DEV_GRP_P1);
/* set VDAC to 1.8V */
twl4030_pmrecv_vsel_cfg(TWL4030_PM_RECEIVER_VDAC_DEDICATED,
@@ -133,6 +133,46 @@ U_BOOT_CMD(poweroff, 1, 1, do_poweroff,
);
#ifdef CONFIG_TWL4030_CHARGING
+/* Enable the battery backup charger */
+int twl4030_enable_bb_charging(unsigned int millivolts, unsigned int microamps)
+{
+ u8 val;
+
+ if (millivolts >= 3200)
+ val = 0x0c;
+ else if (millivolts >= 3100)
+ val = 0x08;
+ else if (millivolts >= 3000)
+ val = 0x04;
+ else if (millivolts < 2500) {
+ val = 0;
+ goto write_it;
+ }
+ if (microamps >= 1000)
+ val |= 0x03;
+ else if (microamps >= 500)
+ val |= 0x02;
+ else if (microamps >= 150)
+ val |= 0x01;
+ else if (microamps < 25) {
+ val = 0;
+ goto write_it;
+ }
+
+ val |= 0x10; /* set BBCHEN */
+
+ printf("Enable battery backup charger (BB_CFG = 0x%02x)\n", val);
+write_it:
+ if (twl4030_i2c_write_u8(TWL4030_CHIP_PM_RECEIVER, val,
+ TWL4030_PM_RECEIVER_BB_CFG)) {
+ printf("Error:TWL4030: failed to write BB_CFG\n");
+ return 1;
+ }
+ return 0;
+}
+
+
+/* Enable AC charging */
int twl4030_enable_charging(void)
{
u8 val = 0;
diff --git a/drivers/serial/ns16550.c b/drivers/serial/ns16550.c
index 8eeb48fb2a..a44bd97ecb 100644
--- a/drivers/serial/ns16550.c
+++ b/drivers/serial/ns16550.c
@@ -53,9 +53,22 @@ void NS16550_init (NS16550_t com_port, int baud_divisor)
#endif /* CONFIG_OMAP */
}
+#ifdef CONFIG_SERIAL_OUTPUT_FIFO
+/* Flush transmit fifo and holding register */
+void NS16550_flush_tx_fifo(NS16550_t com_port)
+{
+ while ((serial_in(&com_port->lsr) & UART_LSR_TEMT) == 0)
+ ;
+}
+#endif
+
#ifndef CONFIG_NS16550_MIN_FUNCTIONS
void NS16550_reinit (NS16550_t com_port, int baud_divisor)
{
+#ifdef CONFIG_SERIAL_OUTPUT_FIFO
+ /* flush output fifo before changing baudrate */
+ NS16550_flush_tx_fifo(com_port);
+#endif
serial_out(CONFIG_SYS_NS16550_IER, &com_port->ier);
serial_out(UART_LCR_BKSE | UART_LCRVAL, &com_port->lcr);
serial_out(0, &com_port->dll);
@@ -72,7 +85,13 @@ void NS16550_reinit (NS16550_t com_port, int baud_divisor)
void NS16550_putc (NS16550_t com_port, char c)
{
+#ifdef CONFIG_SERIAL_OUTPUT_FIFO
+ /* Wait for some room in the fifo */
+ while ((serial_in(&com_port->ssr) & UART_SSR_TX_FIFO_FULL));
+#else
+ /* Wait for Xmit holding register to be empty */
while ((serial_in(&com_port->lsr) & UART_LSR_THRE) == 0);
+#endif
serial_out(c, &com_port->thr);
/*
diff --git a/drivers/serial/serial.c b/drivers/serial/serial.c
index 4032dfde74..913432c27e 100644
--- a/drivers/serial/serial.c
+++ b/drivers/serial/serial.c
@@ -215,6 +215,18 @@ _serial_puts (const char *s,const int port)
}
}
+#ifdef CONFIG_SERIAL_OUTPUT_FIFO
+void
+_serial_flush_output(const int port)
+{
+ NS16550_flush_tx_fifo(PORT);
+}
+#else
+void
+_serial_flush_output(void)
+{
+}
+#endif
int
_serial_getc(const int port)
diff --git a/drivers/video/omap3_dss.c b/drivers/video/omap3_dss.c
index 6b33250d3a..8d629d3a04 100644
--- a/drivers/video/omap3_dss.c
+++ b/drivers/video/omap3_dss.c
@@ -30,6 +30,7 @@
#include <asm/arch/dss.h>
#include <asm/arch/sys_proto.h>
+#undef DEBUG
#ifdef DEBUG
#define DSS_DBG_CLK(fmt, ...) printf(fmt, ##__VA_ARGS__)
#else
@@ -217,11 +218,12 @@ void dispc_find_clk_divs(int is_tft, unsigned long req_pck, unsigned long fck,
}
found:
+
cinfo->lck_div = best_ld;
cinfo->pck_div = best_pd;
cinfo->lck = fck / cinfo->lck_div;
cinfo->pck = cinfo->lck / cinfo->pck_div;
- DSS_DBG_CLK("%s: %d best_ld %u best_pd %u pck %lu\n", __FUNCTION__, __LINE__, best_ld, best_pd, cinfo->pck);
+ DSS_DBG_CLK("%s:%d fck %lu best_ld %u best_pd %u pck %lu\n", __FUNCTION__, __LINE__, fck, best_ld, best_pd, cinfo->pck);
}
int omap3_dss_calc_divisor(int is_tft, unsigned int req_pck,
@@ -269,9 +271,11 @@ int omap3_dss_calc_divisor(int is_tft, unsigned int req_pck,
dispc_find_clk_divs(is_tft, req_pck, fck, &cur_dispc);
- DSS_DBG_CLK("%s:%d cur.pck %u < best_pck %u?\n", __FUNCTION__, __LINE__,
- abs(cur_dispc.pck - req_pck),
- abs(best_dispc.pck - req_pck));
+ DSS_DBG_CLK("%s:%d cur.pck(%d-%d) %u < best_pck(%d-%d) %u?\n", __FUNCTION__, __LINE__,
+ cur_dispc.pck, req_pck,
+ abs(cur_dispc.pck - req_pck),
+ best_dispc.pck, req_pck,
+ abs(best_dispc.pck - req_pck));
if (abs(cur_dispc.pck - req_pck) <
abs(best_dispc.pck - req_pck)) {
diff --git a/include/common.h b/include/common.h
index 8b32431b56..9ba1e93711 100644
--- a/include/common.h
+++ b/include/common.h
@@ -312,7 +312,7 @@ extern void nand_setup_default_ecc_method(void);
extern void nand_switch_ecc_default(int *ecc_method);
extern void nand_switch_ecc_method(int ecc_method);
extern int setenv_reserved_name(const char *name);
-extern void touchup_env(void);
+extern void touchup_env(int is_initial_env);
/* common/exports.c */
void jumptable_init(void);
@@ -494,6 +494,7 @@ void _serial_setbrg (const int);
void _serial_putc (const char, const int);
void _serial_putc_raw(const char, const int);
void _serial_puts (const char *, const int);
+void _serial_flush_output(const int);
int _serial_getc (const int);
int _serial_tstc (const int);
@@ -662,6 +663,21 @@ void panic(const char *fmt, ...)
int sprintf(char * buf, const char *fmt, ...)
__attribute__ ((format (__printf__, 2, 3)));
int vsprintf(char *buf, const char *fmt, va_list args);
+int vsnprintf(char *buf, size_t size, const char *fmt, va_list args);
+
+struct vsprintf_out {
+ /* Function to call to output char to string/function */
+ void (*out)(struct vsprintf_out *p, char ch);
+ struct {
+ char *buf;
+ int len; /* Length of characters output */
+ int limit; /* limit of string to output characters in */
+ int file; /* file number for output (in fprintf) */
+ void (*outchar) (char ch); /* Function to putc() */
+ } dat;
+};
+
+int vsfprintf(struct vsprintf_out *p, const char *fmt, va_list args);
/* lib/strmhz.c */
char * strmhz(char *buf, unsigned long hz);
@@ -748,6 +764,11 @@ int cpu_disable(int nr);
int cpu_release(int nr, int argc, char * const argv[]);
#endif
+/* Dynmaic mtdpart/id defaults */
+#ifdef CONFIG_MTDPARTS_DYNAMIC_DEFAULT
+extern char *get_mtdids_default(void);
+extern char *get_mtdparts_default(void);
+#endif /* CONFIG_MTDPARTS_DYNAMIC_DEFAULT */
#endif /* __ASSEMBLY__ */
/* Put only stuff here that the assembler can digest */
diff --git a/include/configs/omap3logic.h b/include/configs/omap3logic.h
index f797cbcce7..5dfeb9bb72 100644
--- a/include/configs/omap3logic.h
+++ b/include/configs/omap3logic.h
@@ -41,6 +41,10 @@
#define CONFIG_OMAP34XX 1 /* which is a 34XX */
#define CONFIG_OMAP3430 1 /* which is in a 3430 */
#define CONFIG_OMAP3_LOGIC 1 /* working with Logic OMAP boards */
+#define CONFIG_OMAP_DMA 1
+
+#define CONFIG_USE_ARCH_MEMSET 1
+#define CONFIG_USE_ARCH_MEMCPY 1
/* Define following to enable new product ID code. */
#define CONFIG_OMAP3_LOGIC_USE_NEW_PRODUCT_ID 1
@@ -97,6 +101,7 @@
#define CONFIG_SYS_NS16550_SERIAL
#define CONFIG_SYS_NS16550_REG_SIZE (-4)
#define CONFIG_SYS_NS16550_CLK V_NS16550_CLK
+#define CONFIG_SERIAL_OUTPUT_FIFO /* Use full serial tx fifo */
/*
* select serial console configuration
@@ -120,12 +125,14 @@
/* DDR - I use Micron DDR */
#define CONFIG_OMAP3_MICRON_DDR 1
+#if 0
/* USB
* Enable CONFIG_MUSB_HCD for Host functionalities MSC, keyboard
* Enable CONFIG_MUSB_UDD for Device functionalities.
*/
#define CONFIG_USB_OMAP3 1
#define CONFIG_MUSB_HCD 1
+#endif
/* #define CONFIG_MUSB_UDC 1 */
#ifdef CONFIG_USB_OMAP3
@@ -173,10 +180,18 @@
#define CONFIG_CMD_NAND /* NAND support */
#define CONFIG_MTD_DEVICE /* needed for MTD mtdparts support */
#define CONFIG_CMD_MTDPARTS /* MTD partition support */
-#define MTDIDS_DEFAULT "nand0=omap2-nand.0"
-#define MTDPARTS_DEFAULT "mtdparts=omap2-nand.0:512k(x-loader),"\
+#define MTDIDS_NAND_DEFAULT "nand0=omap2-nand.0"
+#define MTDIDS_NOR_DEFAULT "nor0=physmap-flash.0"
+#define MTDPARTS_NAND_DEFAULT "mtdparts=omap2-nand.0:512k(x-loader),"\
"1664k(u-boot),384k(u-boot-env),"\
"5m(kernel),20m(ramdisk),-(fs)"
+
+#define MTDPARTS_NOR_DEFAULT "physmap-flash.0:-(nor)"
+
+/* mtdparts/id default values are dynamic since some modules may
+ * not have NOR flash */
+#define CONFIG_MTDPARTS_DYNAMIC_DEFAULT
+
#define CONFIG_NAND_SET_DEFAULT /* Set default NAND access method */
#define CONFIG_NAND_MULTIPLE_ECC /* NAND has multiple ECC methods */
#define CONFIG_TOUCHUP_ENV /* Set board-specific environment vars */
@@ -186,7 +201,11 @@
#define CONFIG_CMD_CACHE /* Cache control */
#define CONFIG_CMD_TIME /* time command */
+#if 0
+/* L2 was disabled since observed that large displays (720p) weren't working
+ * Verify can boot kernel using either XGA or 720p HDMI displays settings */
#define CONFIG_L2_OFF 1 /* Keep L2 Cache Disabled */
+#endif
#define BOARD_LATE_INIT
@@ -198,9 +217,10 @@
#define CONFIG_CMD_GPMC_CONFIG /* gpmc_config */
#define CONFIG_CMD_MUX_CONFIG /* mux_config */
#define CONFIG_CMD_SDRC_CONFIG /* sdrc_config */
+#define CONFIG_CMD_SETEXPR /* setexpr command */
#define CONFIG_HARD_I2C 1
-#define CONFIG_SYS_I2C_SPEED 100000
+#define CONFIG_SYS_I2C_SPEED 400000
#define CONFIG_SYS_I2C_SLAVE 1
#define CONFIG_SYS_I2C_BUS 0
#define CONFIG_SYS_I2C_BUS_SELECT 1
@@ -294,10 +314,11 @@
/* variables as indicated below for a successful boot. */
/* */
/* - $kernel_location */
-/* Must always be set. Values can be ram, nand, mmc, or tftp. */
+/* Must always be set. Values can be ram, nand, nand-part, mmc, or tftp. */
/* */
/* - $rootfs_location */
-/* Must always be set. Values can be ram, tftp, /dev, nfs, mmc, or nand. */
+/* Must always be set. Values can be: */
+/* ram, tftp, /dev, nfs, mmc, nand, nand-part. */
/* */
/* - $rootfs_type */
/* Must always be set. Values can be ramdisk, jffs, yaffs, ext3, or nfs. */
@@ -307,25 +328,54 @@
/* */
/* - If booting from /dev based file system, then $rootfs_device must be */
/* set. */
+/* - If booting kernel from nand-part location, $kernel_partition */
+/* must be set. */
+/* - If rootfs is coming from nand-part (i.e. ramdisk in NAND), then */
+/* $ramdisk_partition must be set. */
+/* must be set. */
/* - If booting from a ramdisk image, then $ramdisksize, and $ramdiskaddr */
/* must be set. */
/* - If booting from an nfs location, then $serverip, $nfsrootpath, and */
/* $nfsoptions must be set. */
-/* - If booting from nand, $ramdisk_nand_offset, $ramdisk_nand_size, */
-/* $kernel_nand_offset, and $kernel_nand_size must be set. */
+/* - If booting from nand, $ramdisk_partition, */
+/* $kernel_partition must be set. */
/* - If booting from a file system, $ramdiskimage, and $kernelimage must be */
/* set. */
/* - Optionally, a boot script named "boot.scr" can be placed in SD to */
/* override any other boot scripts. */
/*****************************************************************************/
+
+/*****************************************************************************/
+/* When using the makenandboot script, be sure to set: */
+/* */
+/* - xloadimage File name of x-loader on the SD card */
+/* - ubootimage File name of u-boot on the SD card */
+/* - kernelimage File name of the kernel image on the SD card */
+/* - ramdiskimage File name of the ramdisk image on the SD card */
+/* - xloader_partition Name of the x-loader partition in mtdparts */
+/* - uboot_partition Name of the u-boot partition in mtdparts */
+/* - kernel_partition Name of the kernel partition in mtdparts */
+/* - ramdisk_partition Name of the ramdisk partition in mtdparts */
+/* */
+/* When using makeyaffsboot script, be sure to set: */
+/* */
+/* - xloadimage File name of x-loader on the SD card */
+/* - ubootimage File name of u-boot on the SD card */
+/* - kernelimage File name of the kernel image on the SD card */
+/* - yaffsimage File name of the YAFFS root FS on the SD card */
+/* - xloader_partition Name of the x-loader partition in mtdparts */
+/* - uboot_partition Name of the u-boot partition in mtdparts */
+/* - kernel_partition Name of the kernel partition in mtdparts */
+/* - yaffs_partition Name of the YAFFS root FS in mtdparts */
+/*****************************************************************************/
+
#define CONFIG_EXTRA_ENV_SETTINGS \
OMAP3LOGIC_USBTTY \
"bootargs=\0" \
"otherbootargs=ignore_loglevel early_printk no_console_suspend \0" \
"consoledevice=ttyO0\0" \
+ "autoload=no\0" \
"setconsole=setenv console ${consoledevice},${baudrate}n8\0" \
- "mtdids=" MTDIDS_DEFAULT "\0" \
- "mtdparts=" MTDPARTS_DEFAULT "\0" \
"disablecharging=no\0" \
"mmc_bootscript_addr=0x80FF0000\0" \
"disablecharging no\0" \
@@ -334,132 +384,163 @@
"kernel_location=mmc \0" \
"rootfs_location=mmc \0" \
"rootfs_type=ramdisk \0" \
- "rootfs_device=/dev/mtdblock4 \0" \
+ "rootfs_device=/dev/mtdblock5 \0" \
+ "xloadimage=mlo\0" \
+ "ubootimage=u-boot.bin.ift\0" \
+ "kernelimage=uImage\0" \
+ "ramdiskimage=rootfs.ext2.gz.uboot\0" \
+ "yaffsimage=rootfs.yaffs2\0" \
+ "xloader_partition=x-loader\0" \
+ "uboot_partition=u-boot\0" \
+ "kernel_partition=kernel\0" \
+ "ramdisk_partition=ramdisk\0" \
+ "yaffs_partition=fs\0" \
+ "arg_loadcmd=fatload mmc 1\0" \
"ramdisksize=64000\0" \
"ramdiskaddr=0x82000000\0" \
- "ramdiskimage=rootfs.ext2.gz.uboot\0" \
- "ramdisk_nand_offset=0x00680000\0" \
- "ramdisk_nand_size=0x00d40000\0" \
- "kernel_nand_offset=0x00280000 \0" \
- "kernel_nand_size=0x00400000 \0" \
- "kernelimage=uImage \0" \
- "serverip=192.168.3.5\0" \
+ "tftpdir=\0" \
+ "serverip=192.168.3.10\0" \
"nfsrootpath=/opt/nfs-exports/ltib-omap\0" \
"nfsoptions=,wsize=1500,rsize=1500\0" \
"rotation=0\0" \
- "autoboot=echo \"\n== Checking mmc1 for alternate boot script " CONFIG_MMC_BOOTSCRIPT_NAME " ==\"; " \
- "if mmc init; then " \
- "if run loadbootscript; then " \
- "echo \"\"; " \
- "echo \"== Found script on mmc 1, starting ==\"; " \
- "run bootscript; " \
- "else " \
- "echo \"\"; " \
- "echo \"== Script not found on mmc 1, proceeding with defaultboot ==\"; " \
- "run defaultboot;" \
- "fi; " \
- "else run defaultboot; fi\0" \
+ "autoboot=echo \"\n== Checking mmc1 for alternate boot script " CONFIG_MMC_BOOTSCRIPT_NAME " ==\";" \
+ " if mmc init; then \n" \
+ " if run loadbootscript; then \n" \
+ " echo \"\"; \n" \
+ " echo \"== Found script on mmc 1, starting ==\"; \n" \
+ " run bootscript; \n" \
+ " else \n" \
+ " echo \"\"; \n" \
+ " echo \"== Script not found on mmc 1, proceeding with defaultboot ==\"; \n" \
+ " run defaultboot;\n" \
+ " fi; \n" \
+ " else run defaultboot; fi\0" \
"loadbootscript=fatload mmc 1 $mmc_bootscript_addr " CONFIG_MMC_BOOTSCRIPT_NAME "\0" \
"bootscript=source ${mmc_bootscript_addr}\0" \
- "vrfb_arg=if itest ${rotation} -ne 0; then " \
- "setenv bootargs ${bootargs} omapfb.vrfb=y omapfb.rotate=${rotation}; " \
+ "vrfb_arg=if itest ${rotation} -ne 0; then \n" \
+ "setenv bootargs ${bootargs} omapfb.vrfb=y omapfb.rotate=${rotation}; \n" \
"fi\0" \
"dump_bootargs=echo \"\"; echo \"== Kernel bootargs ==\"; echo $bootargs; echo \"\"; \0" \
"dump_boot_sources=echo \"kernel_location: $kernel_location, " \
"rootfs_location: $rootfs_location, " \
- "rootfs_type: $rootfs_type\"; " \
+ "rootfs_type: $rootfs_type\"; " \
"echo \"\"; " \
- "\0" \
- "load_kernel=if test $kernel_location = 'ram'; then " \
- "echo \"== kernel located at $loadaddr ==\"; " \
- "echo \"\"; " \
- "setenv bootm_arg1 ${loadaddr};" \
- "else if test $kernel_location = 'nand'; then " \
- "echo \"== Loading kernel from nand to $loadaddr ==\"; " \
- "nand read.i $loadaddr $kernel_nand_offset $kernel_nand_size; " \
- "echo \"\"; " \
- "setenv bootm_arg1 ${loadaddr};" \
- "else if test $kernel_location = 'mmc'; then " \
- "echo \"== Loading kernel file $kernelimage to $loadaddr ==\"; " \
- "mmc init; " \
- "fatload mmc 1 $loadaddr $kernelimage; " \
- "echo \"\"; " \
- "setenv bootm_arg1 ${loadaddr};" \
- "else if test $kernel_location = 'tftp'; then " \
- "echo \"== Loading kernel file $tftpdir$kernelimage to $loadaddr ==\"; " \
- "tftpboot $loadaddr $tftpdir$kernelimage; " \
- "echo \"\"; " \
- "setenv bootm_arg1 ${loadaddr};" \
- "else "\
- "echo \"== kernel_location must be set to ram, nand, mmc, or tftp!! ==\"; " \
- "echo \"\"; " \
- "fi; " \
- "fi; " \
- "fi; " \
- "fi " \
- "\0" \
- "load_rootfs=if test $rootfs_location = 'ram'; then " \
- "echo \"== rootfs located at $ramdiskaddr ==\"; " \
- "echo \"\"; " \
- "setenv bootm_arg2 ${ramdiskaddr}; " \
- "else if test $rootfs_location = 'tftp'; then " \
- "echo \"== Loading rootfs file $tftpdir$ramdiskimage to $ramdiskaddr ==\"; " \
- "tftpboot $ramdiskaddr $tftpdir$ramdiskimage;" \
- "echo \"\"; " \
- "setenv bootm_arg2 ${ramdiskaddr}; " \
- "else if test $rootfs_location = '/dev'; then " \
- "echo \"== rootfs located in $rootfs_device ==\"; " \
- "echo \"\"; " \
- "setenv bootargs ${bootargs} root=${rootfs_device}; " \
- "setenv bootm_arg2; " \
- "else if test $rootfs_location = 'nfs'; then " \
- "echo \"== rootfs located at $nfs_root_path on server $serverip ==\"; " \
- "echo \"\"; " \
- "setenv bootargs ${bootargs} root=/dev/nfs; " \
- "setenv bootm_arg2; " \
- "else if test $rootfs_location = 'mmc'; then " \
- "echo \"== Loading rootfs file $ramdiskimage to $ramdiskaddr ==\"; " \
- "fatload mmc 1 ${ramdiskaddr} ${ramdiskimage}; "\
- "setenv bootm_arg2 ${ramdiskaddr}; " \
- "else if test $rootfs_location = 'nand'; then " \
- "echo \"== Loading rootfs from nand to $ramdiskaddr ==\"; " \
- "nand read.i $ramdiskaddr $ramdisk_nand_offset $ramdisk_nand_size; " \
- "setenv bootm_arg2 ${ramdiskaddr}; " \
- "else "\
- "echo \"== rootfs_location must be set to ram, tftp, /dev, nfs, mmc, or nand!! == \"; " \
- "echo \"\"; " \
- "fi; " \
- "fi; " \
- "fi; " \
- "fi; " \
- "fi; " \
- "fi " \
- "\0" \
- "set_rootfs_type=if test $rootfs_type = 'ramdisk'; then " \
- "setenv bootargs ${bootargs} root=/dev/ram rw ramdisk_size=${ramdisksize}; " \
- "else if test $rootfs_type = 'jffs'; then " \
- "setenv bootargs ${bootargs} rw rootfstype=jffs2;" \
- "else if test $rootfs_type = 'yaffs'; then " \
- "setenv bootargs ${bootargs} rw rootfstype=yaffs2;" \
- "else if test $rootfs_type = 'ext3'; then " \
- "setenv bootargs ${bootargs} rw rootfstype=ext3 rootwait; " \
- "else if test $rootfs_type = 'nfs'; then " \
- "setenv bootargs ${bootargs} rw nfsroot=${serverip}:${nfsrootpath}${nfsoptions} ip=dhcp; " \
- "else "\
- "echo \"$rootfs_type must be set to ramdisk, jffs, yaffs, ext3, or nfs\"; " \
- "echo \"\"; " \
- "fi; " \
- "fi; " \
- "fi; " \
- "fi; " \
- "fi " \
- "\0" \
+ "\0" \
+ "load_kernel=if test $kernel_location = 'ram'; then \n" \
+ " echo \"== kernel located at $loadaddr ==\"; \n" \
+ " echo \"\"; \n" \
+ " setenv bootm_arg1 ${loadaddr};\n" \
+ " else \n" \
+ " if test $kernel_location = 'nand'; then \n" \
+ " echo \"== Loading kernel from nand to $loadaddr ==\"; \n" \
+ " nand read.i $loadaddr $kernel_partition; \n" \
+ " echo \"\"; \n" \
+ " setenv bootm_arg1 ${loadaddr};\n" \
+ " else \n" \
+ " if test $kernel_location = 'nand-part'; then \n" \
+ " echo \"== Loading kernel from nand partition $kernel_partition to $loadaddr ==\"; \n" \
+ " nboot $loadaddr $kernel_partition; \n" \
+ " echo \"\"; \n" \
+ " setenv bootm_arg1 ${loadaddr};\n" \
+ " else \n" \
+ " if test $kernel_location = 'mmc'; then \n" \
+ " echo \"== Loading kernel file $kernelimage to $loadaddr ==\"; \n" \
+ " mmc init; \n" \
+ " fatload mmc 1 $loadaddr $kernelimage; \n" \
+ " echo \"\"; \n" \
+ " setenv bootm_arg1 ${loadaddr};\n" \
+ " else \n" \
+ " if test $kernel_location = 'tftp'; then \n" \
+ " echo \"== Loading kernel file $tftpdir$kernelimage to $loadaddr ==\"; \n" \
+ " tftpboot $loadaddr $tftpdir$kernelimage; \n" \
+ " echo \"\"; \n" \
+ " setenv bootm_arg1 ${loadaddr};\n" \
+ " else \n" \
+ " echo \"== kernel_location must be set to ram, nand, mmc, or tftp!! ==\"; \n" \
+ " echo \"\"; \n" \
+ " fi; \n" \
+ " fi; \n" \
+ " fi; \n" \
+ " fi; \n" \
+ " fi\n " \
+ "\0" \
+ "load_rootfs=if test $rootfs_location = 'ram'; then \n" \
+ " echo \"== rootfs located at $ramdiskaddr ==\"; \n" \
+ " echo \"\"; \n" \
+ " setenv bootm_arg2 ${ramdiskaddr}; \n" \
+ " else \n" \
+ " if test $rootfs_location = 'tftp'; then \n" \
+ " echo \"== Loading rootfs file $tftpdir$ramdiskimage to $ramdiskaddr ==\"; \n" \
+ " tftpboot $ramdiskaddr $tftpdir$ramdiskimage;\n" \
+ " echo \"\"; \n" \
+ " setenv bootm_arg2 ${ramdiskaddr}; \n" \
+ " else \n" \
+ " if test $rootfs_location = '/dev'; then \n" \
+ " echo \"== rootfs located in $rootfs_device ==\"; \n" \
+ " echo \"\"; \n" \
+ " setenv bootargs ${bootargs} root=${rootfs_device}; \n" \
+ " setenv bootm_arg2; \n" \
+ " else \n" \
+ " if test $rootfs_location = 'nfs'; then \n" \
+ " echo \"== rootfs located at $nfsrootpath on server $serverip ==\"; \n" \
+ " echo \"\"; \n" \
+ " setenv bootargs ${bootargs} root=/dev/nfs; \n" \
+ " setenv bootm_arg2; \n" \
+ " else \n" \
+ " if test $rootfs_location = 'mmc'; then\n " \
+ " echo \"== Loading rootfs file $ramdiskimage to $ramdiskaddr ==\"; \n" \
+ " fatload mmc 1 ${ramdiskaddr} ${ramdiskimage}; \n"\
+ " setenv bootm_arg2 ${ramdiskaddr}; \n" \
+ " else \n" \
+ " if test $rootfs_location = 'nand'; then \n" \
+ " echo \"== Loading rootfs from nand to $ramdiskaddr ==\"; \n" \
+ " nand read.i $ramdiskaddr $ramdisk_partition; \n" \
+ " setenv bootm_arg2 ${ramdiskaddr}; \n" \
+ " else \n"\
+ " if test $rootfs_location = 'nand-part'; then \n" \
+ " echo \"== Loading rootfs from nand partition $ramdisk_partition to $ramdiskaddr ==\"; \n" \
+ " nand read.i $ramdiskaddr $ramdisk_partition; \n" \
+ " setenv bootm_arg2 ${ramdiskaddr}; \n" \
+ " else \n"\
+ " echo \"== rootfs_location must be set to ram, tftp, /dev, nfs, mmc, nand-part or nand!! == \"; \n" \
+ " echo \"\"; \n" \
+ " fi; \n" \
+ " fi; \n" \
+ " fi; \n" \
+ " fi; \n" \
+ " fi; \n" \
+ " fi; \n" \
+ " fi" \
+ "\0" \
+ "set_rootfs_type=if test $rootfs_type = 'ramdisk'; then \n" \
+ " setenv bootargs ${bootargs} root=/dev/ram rw ramdisk_size=${ramdisksize}; \n" \
+ " else \n" \
+ " if test $rootfs_type = 'jffs'; then \n" \
+ " setenv bootargs ${bootargs} rw rootfstype=jffs2;\n" \
+ " else \n" \
+ " if test $rootfs_type = 'yaffs'; then \n" \
+ " setenv bootargs ${bootargs} rw rootfstype=yaffs2;\n" \
+ " else \n" \
+ " if test $rootfs_type = 'ext3'; then \n" \
+ " setenv bootargs ${bootargs} rw rootfstype=ext3 rootwait; \n" \
+ " else \n" \
+ " if test $rootfs_type = 'nfs'; then \n" \
+ " setenv bootargs ${bootargs} rw nfsroot=${serverip}:${nfsrootpath}${nfsoptions} ip=dhcp; \n" \
+ " else \n"\
+ " echo \"$rootfs_type must be set to ramdisk, jffs, yaffs, ext3, or nfs\"; \n" \
+ " echo \"\"; \n" \
+ " fi; \n" \
+ " fi; \n" \
+ " fi; \n" \
+ " fi; \n" \
+ " fi" \
+ "\0" \
"addmtdparts=setenv bootargs ${bootargs} ${mtdparts} \0" \
"common_bootargs=" \
" setenv bootargs ${bootargs} display=${display} ${otherbootargs}; " \
" run addmtdparts; " \
" run vrfb_arg; " \
- " \0" \
+ "\0" \
"dump_run_bootm=" \
" echo \"bootm $bootm_arg1 $bootm_arg2\"; " \
" echo \"\"; " \
@@ -470,30 +551,118 @@
" run common_bootargs; " \
" run load_kernel; " \
" run load_rootfs; " \
- " run set_rootfs_type; " \
+ " run set_rootfs_type; " \
" run dump_bootargs; " \
" run dump_run_bootm; " \
+ "\0" \
"nfsboot=" \
" setenv kernel_location tftp; " \
" setenv rootfs_location nfs; " \
" setenv rootfs_type nfs; " \
" run defaultboot; " \
"\0" \
- "mtdboot=" \
- " setenv kernel_location mmc; " \
- " setenv rootfs_location mmc; " \
- " setenv rootfs_type ramdisk; " \
- " run defaultboot; " \
- "\0" \
"ramboot=" \
" setenv kernel_location tftp; " \
" setenv rootfs_location tftp; " \
" setenv rootfs_type ramdisk; " \
" run defaultboot; " \
+ "\0" \
+ "checkerror=if test $error = '';\n" \
+ " then\n" \
+ " echo \033[31m${error}\033[0m\n" \
+ " echo_lcd /pAA/k${error}\n" \
+ " else\n" \
+ " echo \033[1mDone!\033[m\n" \
+ " echo_lcd /pAA/kCompleted burning sucessfully./n\n" \
+ " echo_lcd /kIt is safe to remove the SD card/n\n" \
+ " echo_lcd /kand restart the devkit./n\n" \
+ " fi" \
+ "\0" \
+ "initmmc=if test $error = '';then;else\n" \
+ " if mmc init;then;else;\n" \
+ " setenv error \"Failed to initialize MMC\"\n" \
+ " fi\n" \
+ " fi" \
+ "\0" \
+ "checkmmcfile=if test $error = '';then;else\n" \
+ " if fatload mmc 1 ${loadaddr} ${arg_filename} 1;then;else;\n" \
+ " setenv error \"Unable to load ${arg_filename}\";\n" \
+ " fi\n" \
+ " fi" \
+ "\0" \
+ "burnfile=if test $error = '';then;else\n" \
+ " echo \"\033[1m== Loading ${arg_filename} ==\033[0m\"\n" \
+ " echo_lcd /pAA/kPartition ${arg_partition}:\n" \
+ " echo_lcd /pBA/kLoading ${arg_filename}/aC;lcd_percent \"/gC/k /P%...\"\n" \
+ " if ${arg_loadcmd} ${loadaddr} ${arg_filename};then;\n" \
+ " echo \"\033[1m== Burning ${arg_partition} ==\033[0m\"\n" \
+ " lcd_percent \"/pBA/kErasing Partition /P%...\"\n" \
+ " nand erase.part ${arg_partition}\n" \
+ " echo_lcd /pBA/kWriting ${arg_filename} to Partition/aC;lcd_percent \"/gC/k /P%...\"\n" \
+ " nand ${arg_writecmd} ${loadaddr} ${arg_partition} ${filesize}\n" \
+ " lcd_percent \"\"\n" \
+ " echo_lcd /pAA/k/pAB/k\n" \
+ " else\n" \
+ " setenv error \"Unable to load ${arg_filename}\"\n" \
+ " fi\n" \
+ " fi" \
+ "\0" \
+ "burnmmcxloader=if test $error = '';then;else\n" \
+ " nandecc hw;\n" \
+ " arg_filename=${xloadimage};arg_partition=${xloader_partition};arg_writecmd=write.i;\n" \
+ " run burnfile\n" \
+ " if test $error = '';then;else\n" \
+ " nand write.i ${loadaddr} 0x00020000 ${filesize}\n" \
+ " nand write.i ${loadaddr} 0x00040000 ${filesize}\n" \
+ " nand write.i ${loadaddr} 0x00060000 ${filesize}\n" \
+ " fi\n" \
+ " fi" \
+ "\0" \
+ "burncommon=if test $error = '';then;else\n" \
+ " arg_filename=${xloadimage};run checkmmcfile;\n" \
+ " arg_filename=${ubootimage};run checkmmcfile;\n" \
+ " arg_filename=${kernelimage};run checkmmcfile;\n" \
+ " run burnmmcxloader;\n" \
+ " nandecc ${defaultecc};\n" \
+ " arg_writecmd=write.i;\n" \
+ " arg_filename=${ubootimage};arg_partition=${uboot_partition};run burnfile;\n" \
+ " arg_filename=${kernelimage};arg_partition=${kernel_partition};run burnfile;\n" \
+ " fi" \
+ "\0" \
+ "makenandboot=if true;then;\n" \
+ " setenv error;\n" \
+ " run initmmc;\n" \
+ " arg_filename=${ramdiskimage};run checkmmcfile;\n" \
+ " run burncommon;\n" \
+ " arg_filename=${ramdiskimage};arg_partition=${ramdisk_partition};arg_writecmd=write.i;\n" \
+ " run burnfile;\n" \
+ " if test $error = '';then;else\n" \
+ " setenv kernel_location nand-part\n" \
+ " setenv rootfs_location nand-part\n" \
+ " setenv rootfs_type ramdisk\n" \
+ " saveenv\n" \
+ " fi\n" \
+ " run checkerror;\n" \
+ " fi" \
+ "\0" \
+ "makeyaffsboot=if true;then;\n" \
+ " setenv error;\n" \
+ " run initmmc;\n" \
+ " arg_filename=${yaffsimage};run checkmmcfile;\n" \
+ " run burncommon;\n" \
+ " arg_filename=${yaffsimage};arg_partition=${yaffs_partition};arg_writecmd=write.yaffs;\n" \
+ " run burnfile;\n" \
+ " if test $error = '';then;else\n" \
+ " setenv kernel_location nand-part\n" \
+ " setenv rootfs_location /dev\n" \
+ " setenv rootfs_type yaffs\n" \
+ " setenv rootfs_device /dev/mtdblock5\n" \
+ " saveenv\n" \
+ " fi\n" \
+ " run checkerror;\n" \
+ " fi" \
"\0"
-
-
#define CONFIG_AUTO_COMPLETE 1
/*
* Miscellaneous configurable options
@@ -554,9 +723,9 @@
*/
/* variable that's non-zero if flash exists */
-#define CONFIG_SYS_FLASH_PRESENCE omap3logic_flash_exists
+#define CONFIG_SYS_FLASH_PRESENCE omap3logic_nor_exists
#ifndef __ASSEMBLY__
-extern int omap3logic_flash_exists;
+extern int omap3logic_nor_exists;
#endif
#define CONFIG_SYS_FLASH_BASE 0x10000000 /* FLASH base address */
#define CONFIG_SYS_FLASH_SIZE 8 /* 8MB */
@@ -566,6 +735,7 @@ extern int omap3logic_flash_exists;
#undef CONFIG_SYS_FLASH_CHECKSUM
#define CONFIG_SYS_FLASH_CFI /* use the Common Flash Interface */
#define CONFIG_FLASH_CFI_DRIVER /* use the CFI driver */
+#define CONFIG_FLASH_CFI_MTD /* use the CFI MTD interface */
/* **** PISMO SUPPORT *** */
@@ -581,6 +751,7 @@ extern int omap3logic_flash_exists;
#define SMNAND_ENV_OFFSET 0x220000 /* environment starts here */
#if defined(CONFIG_CMD_NAND)
+#define CONFIG_SYS_NAND_QUIET_TEST 1
#define CONFIG_NAND_OMAP_GPMC
#define CONFIG_MTD_NAND_BCH
#define CONFIG_MTD_NAND_ECC_BCH
diff --git a/include/i2c.h b/include/i2c.h
index 8ceb4c8521..c6aee208c3 100644
--- a/include/i2c.h
+++ b/include/i2c.h
@@ -107,6 +107,7 @@
* Initialization, must be called once on start up, may be called
* repeatedly to change the speed and slave addresses.
*/
+int i2c_mux_bus_pins(int bus);
void i2c_init(int speed, int slaveaddr);
void i2c_init_board(void);
#ifdef CONFIG_SYS_I2C_BOARD_LATE_INIT
diff --git a/include/nand.h b/include/nand.h
index f7b0a60b8a..d135927a29 100644
--- a/include/nand.h
+++ b/include/nand.h
@@ -25,6 +25,7 @@
#define _NAND_H_
extern void nand_init(void);
+extern unsigned int nand_size(void); /* Size of NAND */
extern int nand_set_dev(int idx);
#include <linux/mtd/compat.h>
diff --git a/include/ns16550.h b/include/ns16550.h
index 9ea81e9463..9c417b2736 100644
--- a/include/ns16550.h
+++ b/include/ns16550.h
@@ -111,6 +111,11 @@ typedef volatile struct NS16550 *NS16550_t;
#define UART_LCR_DLAB 0x80 /* Divisor latch access bit */
/*
+ * These are the definitions for the Supplementary Status Register
+ */
+#define UART_SSR_TX_FIFO_FULL 0x01 /* TX FiFo full */
+
+/*
* These are the definitions for the Line Status Register
*/
#define UART_LSR_DR 0x01 /* Data ready */
@@ -163,3 +168,6 @@ void NS16550_putc (NS16550_t com_port, char c);
char NS16550_getc (NS16550_t com_port);
int NS16550_tstc (NS16550_t com_port);
void NS16550_reinit (NS16550_t com_port, int baud_divisor);
+#ifdef CONFIG_SERIAL_OUTPUT_FIFO
+void NS16550_flush_tx_fifo(NS16550_t com_port);
+#endif
diff --git a/include/twl4030.h b/include/twl4030.h
index 6d5bb1553a..ec6bc82774 100644
--- a/include/twl4030.h
+++ b/include/twl4030.h
@@ -590,6 +590,7 @@ void twl4030_power_init(void);
void twl4030_power_mmc_init(void);
/* For charging */
int twl4030_enable_charging(void);
+int twl4030_enable_bb_charging(unsigned int millivolts, unsigned int microamps);
/*
* LED
diff --git a/lib/vsprintf.c b/lib/vsprintf.c
index 3b924ec5e0..7f02181691 100644
--- a/lib/vsprintf.c
+++ b/lib/vsprintf.c
@@ -281,6 +281,7 @@ static noinline char* put_dec(char *buf, unsigned NUM_TYPE num)
}
}
+
#define ZEROPAD 1 /* pad with zero */
#define SIGN 2 /* unsigned/signed long */
#define PLUS 4 /* show plus */
@@ -289,7 +290,7 @@ static noinline char* put_dec(char *buf, unsigned NUM_TYPE num)
#define SMALL 32 /* Must be 32 == 0x20 */
#define SPECIAL 64 /* 0x */
-static char *number(char *buf, unsigned NUM_TYPE num, int base, int size, int precision, int type)
+static void number(struct vsprintf_out *p, unsigned NUM_TYPE num, int base, int size, int precision, int type)
{
/* we are called with base 8, 10 or 16, only, thus don't need "G..." */
static const char digits[16] = "0123456789ABCDEF"; /* "GHIJKLMNOPQRSTUVWXYZ"; */
@@ -352,36 +353,44 @@ static char *number(char *buf, unsigned NUM_TYPE num, int base, int size, int pr
/* leading space padding */
size -= precision;
if (!(type & (ZEROPAD+LEFT)))
- while(--size >= 0)
- *buf++ = ' ';
+ while(--size >= 0) {
+ p->out(p, ' ');
+ }
/* sign */
- if (sign)
- *buf++ = sign;
+ if (sign) {
+ p->out(p, sign);
+ }
/* "0x" / "0" prefix */
if (need_pfx) {
- *buf++ = '0';
- if (base == 16)
- *buf++ = ('X' | locase);
+ p->out(p, '0');
+ if (base == 16) {
+ p->out(p, 'X' | locase);
+ }
}
/* zero or space padding */
if (!(type & LEFT)) {
char c = (type & ZEROPAD) ? '0' : ' ';
- while (--size >= 0)
- *buf++ = c;
+ while (--size >= 0) {
+ p->out(p, c);
+ }
}
/* hmm even more zero padding? */
- while (i <= --precision)
- *buf++ = '0';
+ while (i <= --precision) {
+ p->out(p, '0');
+ }
/* actual digits of result */
- while (--i >= 0)
- *buf++ = tmp[i];
+ while (--i >= 0) {
+ p->out(p, tmp[i]);
+ }
/* trailing space padding */
- while (--size >= 0)
- *buf++ = ' ';
- return buf;
+ while (--size >= 0) {
+ p->out(p, ' ');
+ }
}
-static char *string(char *buf, char *s, int field_width, int precision, int flags)
+static void string(
+ struct vsprintf_out *p,
+ char *s, int field_width, int precision, int flags)
{
int len, i;
@@ -391,17 +400,19 @@ static char *string(char *buf, char *s, int field_width, int precision, int flag
len = strnlen(s, precision);
if (!(flags & LEFT))
- while (len < field_width--)
- *buf++ = ' ';
- for (i = 0; i < len; ++i)
- *buf++ = *s++;
- while (len < field_width--)
- *buf++ = ' ';
- return buf;
+ while (len < field_width--) {
+ p->out(p, ' ');
+ }
+ for (i = 0; i < len; ++i) {
+ p->out(p, *s++);
+ }
+ while (len < field_width--) {
+ p->out(p, ' ');
+ }
}
#ifdef CONFIG_CMD_NET
-static char *mac_address_string(char *buf, u8 *addr, int field_width,
+static void mac_address_string(struct vsprintf_out *outp, u8 *addr, int field_width,
int precision, int flags)
{
char mac_addr[6 * 3]; /* (6 * 2 hex digits), 5 colons and trailing zero */
@@ -415,10 +426,10 @@ static char *mac_address_string(char *buf, u8 *addr, int field_width,
}
*p = '\0';
- return string(buf, mac_addr, field_width, precision, flags & ~SPECIAL);
+ string(outp, mac_addr, field_width, precision, flags & ~SPECIAL);
}
-static char *ip6_addr_string(char *buf, u8 *addr, int field_width,
+static void ip6_addr_string(struct vsprintf_out *outp, u8 *addr, int field_width,
int precision, int flags)
{
char ip6_addr[8 * 5]; /* (8 * 4 hex digits), 7 colons and trailing zero */
@@ -433,10 +444,10 @@ static char *ip6_addr_string(char *buf, u8 *addr, int field_width,
}
*p = '\0';
- return string(buf, ip6_addr, field_width, precision, flags & ~SPECIAL);
+ string(outp, ip6_addr, field_width, precision, flags & ~SPECIAL);
}
-static char *ip4_addr_string(char *buf, u8 *addr, int field_width,
+static void ip4_addr_string(struct vsprintf_out *outp, u8 *addr, int field_width,
int precision, int flags)
{
char ip4_addr[4 * 4]; /* (4 * 3 decimal digits), 3 dots and trailing zero */
@@ -454,7 +465,7 @@ static char *ip4_addr_string(char *buf, u8 *addr, int field_width,
}
*p = '\0';
- return string(buf, ip4_addr, field_width, precision, flags & ~SPECIAL);
+ string(outp, ip4_addr, field_width, precision, flags & ~SPECIAL);
}
#endif
@@ -476,10 +487,10 @@ static char *ip4_addr_string(char *buf, u8 *addr, int field_width,
* function pointers are really function descriptors, which contain a
* pointer to the real address.
*/
-static char *pointer(const char *fmt, char *buf, void *ptr, int field_width, int precision, int flags)
+static void pointer(struct vsprintf_out *p, const char *fmt, void *ptr, int field_width, int precision, int flags)
{
if (!ptr)
- return string(buf, "(null)", field_width, precision, flags);
+ return string(p, "(null)", field_width, precision, flags);
#ifdef CONFIG_CMD_NET
switch (*fmt) {
@@ -487,15 +498,15 @@ static char *pointer(const char *fmt, char *buf, void *ptr, int field_width, int
flags |= SPECIAL;
/* Fallthrough */
case 'M':
- return mac_address_string(buf, ptr, field_width, precision, flags);
+ return mac_address_string(p, ptr, field_width, precision, flags);
case 'i':
flags |= SPECIAL;
/* Fallthrough */
case 'I':
if (fmt[1] == '6')
- return ip6_addr_string(buf, ptr, field_width, precision, flags);
+ return ip6_addr_string(p, ptr, field_width, precision, flags);
if (fmt[1] == '4')
- return ip4_addr_string(buf, ptr, field_width, precision, flags);
+ return ip4_addr_string(p, ptr, field_width, precision, flags);
flags &= ~SPECIAL;
break;
}
@@ -505,7 +516,7 @@ static char *pointer(const char *fmt, char *buf, void *ptr, int field_width, int
field_width = 2*sizeof(void *);
flags |= ZEROPAD;
}
- return number(buf, (unsigned long) ptr, 16, field_width, precision, flags);
+ number(p, (unsigned long) ptr, 16, field_width, precision, flags);
}
/**
@@ -525,11 +536,12 @@ static char *pointer(const char *fmt, char *buf, void *ptr, int field_width, int
* Call this function if you are already dealing with a va_list.
* You probably want sprintf() instead.
*/
-int vsprintf(char *buf, const char *fmt, va_list args)
+int vsfprintf(
+ struct vsprintf_out *p,
+ const char *fmt, va_list args)
{
unsigned NUM_TYPE num;
int base;
- char *str;
int flags; /* flags to number() */
@@ -541,11 +553,10 @@ int vsprintf(char *buf, const char *fmt, va_list args)
/* 'z' changed to 'Z' --davidm 1/25/99 */
/* 't' added for ptrdiff_t */
- str = buf;
for (; *fmt ; ++fmt) {
if (*fmt != '%') {
- *str++ = *fmt;
+ p->out(p, *fmt);
continue;
}
@@ -608,19 +619,20 @@ int vsprintf(char *buf, const char *fmt, va_list args)
switch (*fmt) {
case 'c':
if (!(flags & LEFT))
- while (--field_width > 0)
- *str++ = ' ';
- *str++ = (unsigned char) va_arg(args, int);
+ while (--field_width > 0) {
+ p->out(p, ' ');
+ }
+ p->out(p, (unsigned char) va_arg(args, int));
while (--field_width > 0)
- *str++ = ' ';
+ p->out(p, ' ');
continue;
case 's':
- str = string(str, va_arg(args, char *), field_width, precision, flags);
+ string(p, va_arg(args, char *), field_width, precision, flags);
continue;
case 'p':
- str = pointer(fmt+1, str,
+ pointer(p, fmt+1,
va_arg(args, void *),
field_width, precision, flags);
/* Skip all alphanumeric pointer suffixes */
@@ -631,15 +643,15 @@ int vsprintf(char *buf, const char *fmt, va_list args)
case 'n':
if (qualifier == 'l') {
long * ip = va_arg(args, long *);
- *ip = (str - buf);
+ *ip = p->dat.len;
} else {
int * ip = va_arg(args, int *);
- *ip = (str - buf);
+ *ip = p->dat.len;
}
continue;
case '%':
- *str++ = '%';
+ p->out(p, '%');
continue;
/* integer number formats - set up the flags and "break" */
@@ -660,11 +672,12 @@ int vsprintf(char *buf, const char *fmt, va_list args)
break;
default:
- *str++ = '%';
- if (*fmt)
- *str++ = *fmt;
- else
+ p->out(p, '%');
+ if (*fmt) {
+ p->out(p, *fmt);
+ } else {
--fmt;
+ }
continue;
}
if (qualifier == 'L') /* "quad" for 64 bit variables */
@@ -686,10 +699,48 @@ int vsprintf(char *buf, const char *fmt, va_list args)
if (flags & SIGN)
num = (signed int) num;
}
- str = number(str, num, base, field_width, precision, flags);
+ number(p, num, base, field_width, precision, flags);
}
- *str = '\0';
- return str-buf;
+ p->out(p, '\0');
+ return p->dat.len - 1;
+}
+
+
+/* vsprintf helper function to output characters into a string */
+static void vsprintf_buf(struct vsprintf_out *p, char ch)
+{
+ p->dat.buf[p->dat.len++] = ch;
+}
+
+int vsprintf(char *buf, const char *fmt, va_list args)
+{
+ struct vsprintf_out r;
+
+ memset(&r, 0, sizeof(r));
+ r.out = vsprintf_buf;
+ r.dat.buf = buf;
+
+ return vsfprintf(&r, fmt, args);
+}
+
+/* vsnprintf helper function to output characters into a string
+ * unless the character overflows the buffer */
+static void vsnprintf_buf(struct vsprintf_out *p, char ch)
+{
+ if (p->dat.len < p->dat.limit)
+ p->dat.buf[p->dat.len++] = ch;
+}
+
+int vsnprintf(char *buf, size_t size, const char *fmt, va_list args)
+{
+ struct vsprintf_out r;
+
+ memset(&r, 0, sizeof(r));
+ r.out = vsnprintf_buf;
+ r.dat.buf = buf;
+ r.dat.limit = size;
+
+ return vsfprintf(&r, fmt, args);
}
/**
@@ -707,9 +758,14 @@ int sprintf(char * buf, const char *fmt, ...)
{
va_list args;
int i;
+ struct vsprintf_out r;
+
+ memset(&r, 0, sizeof(r));
+ r.out = vsprintf_buf;
+ r.dat.buf = buf;
va_start(args, fmt);
- i=vsprintf(buf,fmt,args);
+ i=vsfprintf(&r, fmt,args);
va_end(args);
return i;
}
diff --git a/mkconfig b/mkconfig
index ad9945e802..04c2fe80d5 100755
--- a/mkconfig
+++ b/mkconfig
@@ -123,7 +123,8 @@ fi
#
# Create include file for Make
#
-echo "ARCH = ${arch}" > config.mk
+echo "CONFIG_NAME = $CONFIG_NAME" > config.mk
+echo "ARCH = ${arch}" >> config.mk
echo "CPU = ${cpu}" >> config.mk
echo "BOARD = ${board}" >> config.mk