aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile2
-rw-r--r--blackfin_config.mk4
-rw-r--r--board/bf533-ezkit/Makefile8
-rw-r--r--board/bf533-ezkit/bf533-ezkit.c23
-rw-r--r--board/bf533-ezkit/flash-defines.h4
-rw-r--r--board/bf533-ezkit/flash.c10
-rw-r--r--board/bf533-stamp/Makefile12
-rw-r--r--board/bf533-stamp/bf533-stamp.c50
-rw-r--r--board/bf533-stamp/bf533-stamp.h3
-rw-r--r--board/bf533-stamp/video.c167
-rw-r--r--board/bf533-stamp/video.h25
-rw-r--r--board/bf537-stamp/Makefile10
-rw-r--r--board/bf537-stamp/bf537-stamp.c14
-rw-r--r--board/bf537-stamp/nand.c9
-rw-r--r--board/bf537-stamp/post-memory.c23
-rw-r--r--board/bf537-stamp/spi_flash.c8
-rw-r--r--board/bf561-ezkit/Makefile8
-rw-r--r--board/bf561-ezkit/bf561-ezkit.c14
-rw-r--r--common/cmd_bootldr.c135
-rw-r--r--common/cmd_cplbinfo.c4
-rw-r--r--common/cmd_otp.c163
-rw-r--r--common/devices.c3
-rw-r--r--cpu/blackfin/Makefile9
-rw-r--r--cpu/blackfin/cache.S4
-rw-r--r--cpu/blackfin/cpu.c6
-rw-r--r--cpu/blackfin/i2c.c428
-rw-r--r--cpu/blackfin/initcode.c2
-rw-r--r--cpu/blackfin/jtag-console.c125
-rw-r--r--cpu/blackfin/reset.c20
-rw-r--r--cpu/blackfin/serial.c4
-rw-r--r--cpu/blackfin/serial.h15
-rw-r--r--cpu/blackfin/start.S41
-rw-r--r--cpu/blackfin/traps.c52
-rw-r--r--drivers/i2c/Makefile1
-rw-r--r--drivers/i2c/bfin-twi_i2c.c285
-rw-r--r--drivers/net/bfin_mac.c47
-rw-r--r--include/asm-blackfin/blackfin-config-post.h84
-rw-r--r--include/asm-blackfin/blackfin_local.h2
-rw-r--r--include/asm-blackfin/mach-common/bits/bootrom.h72
-rw-r--r--include/asm-blackfin/mach-common/bits/ebiu.h21
-rw-r--r--include/asm-blackfin/mach-common/bits/otp.h21
-rw-r--r--include/configs/bf533-ezkit.h2
-rw-r--r--include/configs/bf533-stamp.h2
-rw-r--r--include/configs/bf537-stamp.h43
-rw-r--r--include/devices.h3
-rw-r--r--include/status_led.h3
-rw-r--r--lib_blackfin/Makefile2
-rw-r--r--lib_blackfin/board.c37
-rw-r--r--lib_blackfin/boot.c (renamed from lib_blackfin/bootm.c)19
-rw-r--r--lib_blackfin/string.c45
50 files changed, 1270 insertions, 824 deletions
diff --git a/Makefile b/Makefile
index d26a0044534..9647bd2f411 100644
--- a/Makefile
+++ b/Makefile
@@ -317,7 +317,7 @@ $(obj)u-boot.bin: $(obj)u-boot
$(OBJCOPY) ${OBJCFLAGS} -O binary $< $@
$(obj)u-boot.ldr: $(obj)u-boot
- $(LDR) -T $(CONFIG_BFIN_CPU) -f -c $@ $< $(LDR_FLAGS)
+ $(LDR) -T $(CONFIG_BFIN_CPU) -c $@ $< $(LDR_FLAGS)
$(obj)u-boot.ldr.hex: $(obj)u-boot.ldr
$(OBJCOPY) ${OBJCFLAGS} -O ihex $< $@ -I binary
diff --git a/blackfin_config.mk b/blackfin_config.mk
index c8be75e08ec..7bde4492634 100644
--- a/blackfin_config.mk
+++ b/blackfin_config.mk
@@ -33,7 +33,11 @@ endif
SYM_PREFIX = _
+LDR_FLAGS += --bmode $(subst BFIN_BOOT_,,$(CONFIG_BFIN_BOOT_MODE))
LDR_FLAGS += --use-vmas
+ifneq ($(CONFIG_BFIN_BOOT_MODE),BFIN_BOOT_BYPASS)
+LDR_FLAGS += --initcode $(obj)cpu/$(CPU)/initcode.o
+endif
ifneq (,$(findstring s,$(MAKEFLAGS)))
LDR_FLAGS += --quiet
endif
diff --git a/board/bf533-ezkit/Makefile b/board/bf533-ezkit/Makefile
index 6a45b7cb278..1260277a891 100644
--- a/board/bf533-ezkit/Makefile
+++ b/board/bf533-ezkit/Makefile
@@ -29,11 +29,11 @@ include $(TOPDIR)/config.mk
LIB = $(obj)lib$(BOARD).a
-COBJS := $(BOARD).o flash.o
+COBJS-y := $(BOARD).o flash.o
-SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c)
-OBJS := $(addprefix $(obj),$(COBJS))
-SOBJS := $(addprefix $(obj),$(SOBJS))
+SRCS := $(SOBJS-y:.o=.S) $(COBJS-y:.o=.c)
+OBJS := $(addprefix $(obj),$(COBJS-y))
+SOBJS := $(addprefix $(obj),$(SOBJS-y))
$(LIB): $(obj).depend $(OBJS) $(SOBJS) $(obj)u-boot.lds
$(AR) $(ARFLAGS) $@ $(OBJS) $(SOBJS)
diff --git a/board/bf533-ezkit/bf533-ezkit.c b/board/bf533-ezkit/bf533-ezkit.c
index 42c4b505551..d5f0b7c689e 100644
--- a/board/bf533-ezkit/bf533-ezkit.c
+++ b/board/bf533-ezkit/bf533-ezkit.c
@@ -1,7 +1,7 @@
/*
- * U-boot - ezkit533.c
+ * U-boot - main board file
*
- * Copyright (c) 2005-2007 Analog Devices Inc.
+ * Copyright (c) 2005-2008 Analog Devices Inc.
*
* (C) Copyright 2000-2004
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
@@ -26,9 +26,8 @@
*/
#include <common.h>
-#if defined(CONFIG_MISC_INIT_R)
#include "psd4256.h"
-#endif
+#include "flash-defines.h"
DECLARE_GLOBAL_DATA_PTR;
@@ -41,24 +40,11 @@ int checkboard(void)
phys_size_t initdram(int board_type)
{
-#ifdef DEBUG
- int brate;
- char *tmp = getenv("baudrate");
- brate = simple_strtoul(tmp, NULL, 16);
- printf("Serial Port initialized with Baud rate = %x\n", brate);
- printf("SDRAM attributes:\n");
- printf("tRCD %d SCLK Cycles,tRP %d SCLK Cycles,tRAS %d SCLK Cycles"
- "tWR %d SCLK Cycles,CAS Latency %d SCLK cycles \n",
- 3, 3, 6, 2, 3);
- printf("SDRAM Begin: 0x%x\n", CONFIG_SYS_SDRAM_BASE);
- printf("Bank size = %d MB\n", CONFIG_SYS_MAX_RAM_SIZE >> 20);
-#endif
gd->bd->bi_memstart = CONFIG_SYS_SDRAM_BASE;
gd->bd->bi_memsize = CONFIG_SYS_MAX_RAM_SIZE;
- return CONFIG_SYS_MAX_RAM_SIZE;
+ return gd->bd->bi_memsize;
}
-#if defined(CONFIG_MISC_INIT_R)
/* miscellaneous platform dependent initialisations */
int misc_init_r(void)
{
@@ -71,4 +57,3 @@ int misc_init_r(void)
return 0;
}
-#endif
diff --git a/board/bf533-ezkit/flash-defines.h b/board/bf533-ezkit/flash-defines.h
index 1a4aa5f2f70..eb0af947979 100644
--- a/board/bf533-ezkit/flash-defines.h
+++ b/board/bf533-ezkit/flash-defines.h
@@ -50,6 +50,7 @@
#define FLASH_SIZE 0x220000
#define FLASH_MAN_ST 2
#define CONFIG_SYS_FLASH0_BASE 0x20000000
+#define CONFIG_SYS_FLASH1_BASE 0x20200000
#define RESET_VAL 0xF0
flash_info_t flash_info[CONFIG_SYS_MAX_FLASH_BANKS];
@@ -68,9 +69,6 @@ int write_flash(long nOffset, int nValue);
void get_sector_number(long lOffset, int *pnSector);
int GetSectorProtectionStatus(flash_info_t * info, int nSector);
int GetOffset(int nBlock);
-int AFP_NumSectors = 40;
-long AFP_SectorSize1 = 0x10000;
-int AFP_SectorSize2 = 0x4000;
#define WRITESEQ1 0x0AAA
#define WRITESEQ2 0x0554
diff --git a/board/bf533-ezkit/flash.c b/board/bf533-ezkit/flash.c
index a861e16a3df..ab808d86b0c 100644
--- a/board/bf533-ezkit/flash.c
+++ b/board/bf533-ezkit/flash.c
@@ -29,6 +29,10 @@
#include <asm/io.h>
#include "flash-defines.h"
+int AFP_NumSectors = 40;
+long AFP_SectorSize1 = 0x10000;
+int AFP_SectorSize2 = 0x4000;
+
void flash_reset(void)
{
reset_flash();
@@ -123,7 +127,7 @@ void flash_print_info(flash_info_t * info)
printf("ST Microelectronics ");
break;
default:
- printf("Unknown Vendor: (0x%08X) ", info->flash_id);
+ printf("Unknown Vendor: (0x%08lX) ", info->flash_id);
break;
}
for (i = 0; i < info->sector_count; ++i) {
@@ -211,7 +215,7 @@ int write_data(long lStart, long lCount, uchar * pnData)
read_flash(ulOffset, &d);
if (d != 0xffff) {
printf
- ("Flash not erased at offset 0x%x Please erase to reprogram \n",
+ ("Flash not erased at offset 0x%lx Please erase to reprogram\n",
ulOffset);
return FLASH_FAIL;
}
@@ -230,7 +234,7 @@ int write_data(long lStart, long lCount, uchar * pnData)
read_flash(ulOffset, &d);
if (d != 0xffff) {
printf
- ("Flash not erased at offset 0x%x Please erase to reprogram \n",
+ ("Flash not erased at offset 0x%lx Please erase to reprogram\n",
ulOffset);
return FLASH_FAIL;
}
diff --git a/board/bf533-stamp/Makefile b/board/bf533-stamp/Makefile
index 5ae022885e4..a03fe89af13 100644
--- a/board/bf533-stamp/Makefile
+++ b/board/bf533-stamp/Makefile
@@ -1,7 +1,7 @@
#
# U-boot - Makefile
#
-# Copyright (c) 2005-2007 Analog Device Inc.
+# Copyright (c) 2005-2008 Analog Device Inc.
#
# (C) Copyright 2000-2006
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
@@ -29,11 +29,13 @@ include $(TOPDIR)/config.mk
LIB = $(obj)lib$(BOARD).a
-COBJS := $(BOARD).o spi_flash.o
+COBJS-y := $(BOARD).o
+COBJS-$(CONFIG_CMD_EEPROM) += spi_flash.o
+COBJS-$(CONFIG_VIDEO) += video.o
-SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c)
-OBJS := $(addprefix $(obj),$(COBJS))
-SOBJS := $(addprefix $(obj),$(SOBJS))
+SRCS := $(SOBJS-y:.o=.S) $(COBJS-y:.o=.c)
+OBJS := $(addprefix $(obj),$(COBJS-y))
+SOBJS := $(addprefix $(obj),$(SOBJS-y))
$(LIB): $(obj).depend $(OBJS) $(SOBJS) $(obj)u-boot.lds
$(AR) $(ARFLAGS) $@ $(OBJS) $(SOBJS)
diff --git a/board/bf533-stamp/bf533-stamp.c b/board/bf533-stamp/bf533-stamp.c
index 0c6324b4b67..44ebc931946 100644
--- a/board/bf533-stamp/bf533-stamp.c
+++ b/board/bf533-stamp/bf533-stamp.c
@@ -49,43 +49,28 @@ int checkboard(void)
phys_size_t initdram(int board_type)
{
-#ifdef DEBUG
- printf("SDRAM attributes:\n");
- printf
- (" tRCD:%d Cycles; tRP:%d Cycles; tRAS:%d Cycles; tWR:%d Cycles; "
- "CAS Latency:%d cycles\n", (SDRAM_tRCD >> 15), (SDRAM_tRP >> 11),
- (SDRAM_tRAS >> 6), (SDRAM_tWR >> 19), (SDRAM_CL >> 2));
- printf("SDRAM Begin: 0x%x\n", CONFIG_SYS_SDRAM_BASE);
- printf("Bank size = %d MB\n", 128);
-#endif
gd->bd->bi_memstart = CONFIG_SYS_SDRAM_BASE;
gd->bd->bi_memsize = CONFIG_SYS_MAX_RAM_SIZE;
- return (gd->bd->bi_memsize);
+ return gd->bd->bi_memsize;
}
+/* PF0 and PF1 are used to switch between the ethernet and flash:
+ * PF0 PF1
+ * flash: 0 0
+ * ether: 1 0
+ */
void swap_to(int device_id)
{
-
- if (device_id == ETHERNET) {
- *pFIO_DIR = PF0;
- SSYNC();
- *pFIO_FLAG_S = PF0;
- SSYNC();
- } else if (device_id == FLASH) {
- *pFIO_DIR = (PF4 | PF3 | PF2 | PF1 | PF0);
- *pFIO_FLAG_S = (PF4 | PF3 | PF2);
- *pFIO_MASKA_D = (PF8 | PF6 | PF5);
- *pFIO_MASKB_D = (PF7);
- *pFIO_POLAR = (PF8 | PF6 | PF5);
- *pFIO_EDGE = (PF8 | PF7 | PF6 | PF5);
- *pFIO_INEN = (PF8 | PF7 | PF6 | PF5);
- *pFIO_FLAG_D = (PF4 | PF3 | PF2);
- SSYNC();
- } else {
- printf("Unknown bank to switch\n");
- }
-
- return;
+ bfin_write_FIO_DIR(bfin_read_FIO_DIR() | PF1 | PF0);
+ SSYNC();
+ bfin_write_FIO_FLAG_C(PF1);
+ if (device_id == ETHERNET)
+ bfin_write_FIO_FLAG_S(PF0);
+ else if (device_id == FLASH)
+ bfin_write_FIO_FLAG_C(PF0);
+ else
+ printf("Unknown device to switch\n");
+ SSYNC();
}
#if defined(CONFIG_MISC_INIT_R)
@@ -113,9 +98,6 @@ int misc_init_r(void)
if (cf_stat) {
printf("Booting from COMPACT flash\n");
- /* Set cycle time for CF */
- *(volatile unsigned long *)ambctl1 = CF_AMBCTL1VAL;
-
for (i = 0; i < 0x1000; i++)
asm("nop;");
for (i = 0; i < 0x1000; i++)
diff --git a/board/bf533-stamp/bf533-stamp.h b/board/bf533-stamp/bf533-stamp.h
index 3b0d620b3c1..ebd39c77379 100644
--- a/board/bf533-stamp/bf533-stamp.h
+++ b/board/bf533-stamp/bf533-stamp.h
@@ -34,9 +34,6 @@ extern volatile unsigned long *ambctl0;
extern volatile unsigned long *ambctl1;
extern volatile unsigned long *amgctl;
-extern unsigned long pll_div_fact;
-extern void serial_setbrg(void);
-
/* Definitions used in Compact Flash Boot support */
#define FIO_EDGE_CF_BITS 0x0000
#define FIO_POLAR_CF_BITS 0x0000
diff --git a/board/bf533-stamp/video.c b/board/bf533-stamp/video.c
new file mode 100644
index 00000000000..3c15eaa7657
--- /dev/null
+++ b/board/bf533-stamp/video.c
@@ -0,0 +1,167 @@
+/*
+ * BF533-STAMP splash driver
+ *
+ * Copyright (c) 2006-2008 Analog Devices Inc.
+ * (C) Copyright 2000
+ * Paolo Scaffardi, AIRVENT SAM s.p.a - RIMINI(ITALY), arsenio@tin.it
+ * (C) Copyright 2002
+ * Wolfgang Denk, wd@denx.de
+ *
+ * Licensed under the GPL-2 or later.
+ */
+
+#include <stdarg.h>
+#include <common.h>
+#include <config.h>
+#include <malloc.h>
+#include <asm/blackfin.h>
+#include <asm/mach-common/bits/dma.h>
+#include <i2c.h>
+#include <linux/types.h>
+#include <devices.h>
+
+int gunzip(void *, int, unsigned char *, unsigned long *);
+
+#define DMA_SIZE16 2
+
+#include <asm/mach-common/bits/ppi.h>
+
+#define NTSC_FRAME_ADDR 0x06000000
+#include "video.h"
+
+/* NTSC OUTPUT SIZE 720 * 240 */
+#define VERTICAL 2
+#define HORIZONTAL 4
+
+int is_vblank_line(const int line)
+{
+ /*
+ * This array contains a single bit for each line in
+ * an NTSC frame.
+ */
+ if ((line <= 18) || (line >= 264 && line <= 281) || (line == 528))
+ return true;
+
+ return false;
+}
+
+int NTSC_framebuffer_init(char *base_address)
+{
+ const int NTSC_frames = 1;
+ const int NTSC_lines = 525;
+ char *dest = base_address;
+ int frame_num, line_num;
+
+ for (frame_num = 0; frame_num < NTSC_frames; ++frame_num) {
+ for (line_num = 1; line_num <= NTSC_lines; ++line_num) {
+ unsigned int code;
+ int offset = 0;
+ int i;
+
+ if (is_vblank_line(line_num))
+ offset++;
+
+ if (line_num > 266 || line_num < 3)
+ offset += 2;
+
+ /* Output EAV code */
+ code = system_code_map[offset].eav;
+ write_dest_byte((char)(code >> 24) & 0xff);
+ write_dest_byte((char)(code >> 16) & 0xff);
+ write_dest_byte((char)(code >> 8) & 0xff);
+ write_dest_byte((char)(code) & 0xff);
+
+ /* Output horizontal blanking */
+ for (i = 0; i < 67 * 2; ++i) {
+ write_dest_byte(0x80);
+ write_dest_byte(0x10);
+ }
+
+ /* Output SAV */
+ code = system_code_map[offset].sav;
+ write_dest_byte((char)(code >> 24) & 0xff);
+ write_dest_byte((char)(code >> 16) & 0xff);
+ write_dest_byte((char)(code >> 8) & 0xff);
+ write_dest_byte((char)(code) & 0xff);
+
+ /* Output empty horizontal data */
+ for (i = 0; i < 360 * 2; ++i) {
+ write_dest_byte(0x80);
+ write_dest_byte(0x10);
+ }
+ }
+ }
+
+ return dest - base_address;
+}
+
+void fill_frame(char *Frame, int Value)
+{
+ int *OddPtr32;
+ int OddLine;
+ int *EvenPtr32;
+ int EvenLine;
+ int i;
+ int *data;
+ int m, n;
+
+ /* fill odd and even frames */
+ for (OddLine = 22, EvenLine = 285; OddLine < 263; OddLine++, EvenLine++) {
+ OddPtr32 = (int *)((Frame + (OddLine * 1716)) + 276);
+ EvenPtr32 = (int *)((Frame + (EvenLine * 1716)) + 276);
+ for (i = 0; i < 360; i++, OddPtr32++, EvenPtr32++) {
+ *OddPtr32 = Value;
+ *EvenPtr32 = Value;
+ }
+ }
+
+ for (m = 0; m < VERTICAL; m++) {
+ data = (int *)u_boot_logo.data;
+ for (OddLine = (22 + m), EvenLine = (285 + m);
+ OddLine < (u_boot_logo.height * VERTICAL) + (22 + m);
+ OddLine += VERTICAL, EvenLine += VERTICAL) {
+ OddPtr32 = (int *)((Frame + ((OddLine) * 1716)) + 276);
+ EvenPtr32 =
+ (int *)((Frame + ((EvenLine) * 1716)) + 276);
+ for (i = 0; i < u_boot_logo.width / 2; i++) {
+ /* enlarge one pixel to m x n */
+ for (n = 0; n < HORIZONTAL; n++) {
+ *OddPtr32++ = *data;
+ *EvenPtr32++ = *data;
+ }
+ data++;
+ }
+ }
+ }
+}
+
+static void video_init(char *NTSCFrame)
+{
+ NTSC_framebuffer_init(NTSCFrame);
+ fill_frame(NTSCFrame, BLUE);
+
+ bfin_write_PPI_CONTROL(0x0082);
+ bfin_write_PPI_FRAME(0x020D);
+
+ bfin_write_DMA0_START_ADDR(NTSCFrame);
+ bfin_write_DMA0_X_COUNT(0x035A);
+ bfin_write_DMA0_X_MODIFY(0x0002);
+ bfin_write_DMA0_Y_COUNT(0x020D);
+ bfin_write_DMA0_Y_MODIFY(0x0002);
+ bfin_write_DMA0_CONFIG(0x1015);
+ bfin_write_PPI_CONTROL(0x0083);
+}
+
+int drv_video_init(void)
+{
+ device_t videodev;
+
+ video_init((void *)NTSC_FRAME_ADDR);
+
+ memset(&videodev, 0, sizeof(videodev));
+ strcpy(videodev.name, "video");
+ videodev.ext = DEV_EXT_VIDEO;
+ videodev.flags = DEV_FLAGS_SYSTEM;
+
+ return device_register(&videodev);
+}
diff --git a/board/bf533-stamp/video.h b/board/bf533-stamp/video.h
new file mode 100644
index 00000000000..80837e2323b
--- /dev/null
+++ b/board/bf533-stamp/video.h
@@ -0,0 +1,25 @@
+#include <video_logo.h>
+#define write_dest_byte(val) {*dest++=val;}
+#define BLACK (0x01800180) /* black pixel pattern */
+#define BLUE (0x296E29F0) /* blue pixel pattern */
+#define RED (0x51F0515A) /* red pixel pattern */
+#define MAGENTA (0x6ADE6ACA) /* magenta pixel pattern */
+#define GREEN (0x91229136) /* green pixel pattern */
+#define CYAN (0xAA10AAA6) /* cyan pixel pattern */
+#define YELLOW (0xD292D210) /* yellow pixel pattern */
+#define WHITE (0xFE80FE80) /* white pixel pattern */
+
+#define true 1
+#define false 0
+
+typedef struct {
+ unsigned int sav;
+ unsigned int eav;
+} system_code_type;
+
+const system_code_type system_code_map[] = {
+ { 0xFF000080, 0xFF00009D },
+ { 0xFF0000AB, 0xFF0000B6 },
+ { 0xFF0000C7, 0xFF0000DA },
+ { 0xFF0000EC, 0xFF0000F1 },
+};
diff --git a/board/bf537-stamp/Makefile b/board/bf537-stamp/Makefile
index e5ef9af5c59..cb38b96a3b3 100644
--- a/board/bf537-stamp/Makefile
+++ b/board/bf537-stamp/Makefile
@@ -29,11 +29,13 @@ include $(TOPDIR)/config.mk
LIB = $(obj)lib$(BOARD).a
-COBJS := $(BOARD).o post-memory.o spi_flash.o cmd_bf537led.o nand.o
+COBJS-y := $(BOARD).o post-memory.o cmd_bf537led.o
+COBJS-$(CONFIG_CMD_EEPROM) += spi_flash.o
+COBJS-$(CONFIG_CMD_NAND) += nand.o
-SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c)
-OBJS := $(addprefix $(obj),$(COBJS))
-SOBJS := $(addprefix $(obj),$(SOBJS))
+SRCS := $(SOBJS-y:.o=.S) $(COBJS-y:.o=.c)
+OBJS := $(addprefix $(obj),$(COBJS-y))
+SOBJS := $(addprefix $(obj),$(SOBJS-y))
$(LIB): $(obj).depend $(OBJS) $(SOBJS) $(obj)u-boot.lds
$(AR) $(ARFLAGS) $@ $(OBJS) $(SOBJS)
diff --git a/board/bf537-stamp/bf537-stamp.c b/board/bf537-stamp/bf537-stamp.c
index 7303f1b4155..63992f6093c 100644
--- a/board/bf537-stamp/bf537-stamp.c
+++ b/board/bf537-stamp/bf537-stamp.c
@@ -100,21 +100,9 @@ void cf_outsw(unsigned short *addr, unsigned short *sect_buf, int words)
phys_size_t initdram(int board_type)
{
-#ifdef DEBUG
- int brate;
- char *tmp = getenv("baudrate");
- brate = simple_strtoul(tmp, NULL, 16);
- printf("Serial Port initialized with Baud rate = %x\n", brate);
- printf("SDRAM attributes:\n");
- printf("tRCD %d SCLK Cycles,tRP %d SCLK Cycles,tRAS %d SCLK Cycles"
- "tWR %d SCLK Cycles,CAS Latency %d SCLK cycles \n",
- 3, 3, 6, 2, 3);
- printf("SDRAM Begin: 0x%x\n", CONFIG_SYS_SDRAM_BASE);
- printf("Bank size = %d MB\n", CONFIG_SYS_MAX_RAM_SIZE >> 20);
-#endif
gd->bd->bi_memstart = CONFIG_SYS_SDRAM_BASE;
gd->bd->bi_memsize = CONFIG_SYS_MAX_RAM_SIZE;
- return CONFIG_SYS_MAX_RAM_SIZE;
+ return gd->bd->bi_memsize;
}
#if defined(CONFIG_MISC_INIT_R)
diff --git a/board/bf537-stamp/nand.c b/board/bf537-stamp/nand.c
index 20a7d0ef4c6..181e83d6a1b 100644
--- a/board/bf537-stamp/nand.c
+++ b/board/bf537-stamp/nand.c
@@ -1,5 +1,5 @@
/*
- * (C) Copyright 2006 Aubrey.Li, aubrey.li@analog.com
+ * Copyright (c) 2006-2007 Analog Devices Inc.
*
* See file CREDITS for list of people who contributed to this
* project.
@@ -23,8 +23,6 @@
#include <common.h>
#include <asm/io.h>
-#if defined(CONFIG_CMD_NAND)
-
#include <nand.h>
#define CONCAT(a,b,c,d) a ## b ## c ## d
@@ -43,11 +41,11 @@ static void bfin_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl)
u32 IO_ADDR_W = (u32) this->IO_ADDR_W;
if (ctrl & NAND_CTRL_CHANGE) {
- if( ctrl & NAND_CLE )
+ if (ctrl & NAND_CLE)
IO_ADDR_W = CONFIG_SYS_NAND_BASE + BFIN_NAND_CLE;
else
IO_ADDR_W = CONFIG_SYS_NAND_BASE;
- if( ctrl & NAND_ALE )
+ if (ctrl & NAND_ALE)
IO_ADDR_W = CONFIG_SYS_NAND_BASE + BFIN_NAND_ALE;
else
IO_ADDR_W = CONFIG_SYS_NAND_BASE;
@@ -100,4 +98,3 @@ int board_nand_init(struct nand_chip *nand)
return 0;
}
-#endif
diff --git a/board/bf537-stamp/post-memory.c b/board/bf537-stamp/post-memory.c
index 889aa5c4f8c..9626f4cd7af 100644
--- a/board/bf537-stamp/post-memory.c
+++ b/board/bf537-stamp/post-memory.c
@@ -21,10 +21,10 @@ int post_init_sdram(int sclk);
void post_init_uart(int sclk);
const int pll[CCLK_NUM][SCLK_NUM][2] = {
- {{20, 4}, {20, 5}, {20, 10}}, /* CCLK = 500M */
- {{16, 4}, {16, 5}, {16, 8}}, /* CCLK = 400M */
- {{8, 2}, {8, 4}, {8, 5}}, /* CCLK = 200M */
- {{4, 1}, {4, 2}, {4, 4}} /* CCLK = 100M */
+ { {20, 4}, {20, 5}, {20, 10} }, /* CCLK = 500M */
+ { {16, 4}, {16, 5}, {16, 8} }, /* CCLK = 400M */
+ { {8, 2}, {8, 4}, {8, 5} }, /* CCLK = 200M */
+ { {4, 1}, {4, 2}, {4, 4} } /* CCLK = 100M */
};
const char *const log[CCLK_NUM][SCLK_NUM] = {
{"CCLK-500MHz SCLK-125MHz: Writing...\0",
@@ -119,7 +119,8 @@ void post_out_buff(char *buff)
{
int i = 0;
- for (i = 0; i < 0x80000; i++) ;
+ for (i = 0; i < 0x80000; i++)
+ ;
i = 0;
while ((buff[i] != '\0') && (i != 100)) {
while (!(*pUART_LSR & 0x20)) ;
@@ -127,7 +128,8 @@ void post_out_buff(char *buff)
SSYNC();
i++;
}
- for (i = 0; i < 0x80000; i++) ;
+ for (i = 0; i < 0x80000; i++)
+ ;
}
/* Using sw10-PF5 as the hotkey */
@@ -150,9 +152,8 @@ int post_key_pressed(void)
value = 0;
goto key_pressed;
}
- if (value != 0) {
+ if (value != 0)
goto key_pressed;
- }
for (n = 0; n < KEY_DELAY; n++)
asm("nop");
}
@@ -164,9 +165,8 @@ int post_key_pressed(void)
value = 0;
goto key_pressed;
}
- if (value != 0) {
+ if (value != 0)
goto key_pressed;
- }
for (n = 0; n < KEY_DELAY; n++)
asm("nop");
}
@@ -178,9 +178,8 @@ int post_key_pressed(void)
value = 0;
goto key_pressed;
}
- if (value != 0) {
+ if (value != 0)
goto key_pressed;
- }
for (n = 0; n < KEY_DELAY; n++)
asm("nop");
}
diff --git a/board/bf537-stamp/spi_flash.c b/board/bf537-stamp/spi_flash.c
index 11a2803e6f2..99caa96c416 100644
--- a/board/bf537-stamp/spi_flash.c
+++ b/board/bf537-stamp/spi_flash.c
@@ -182,8 +182,8 @@ static struct manufacturer_info flash_manufacturers[] = {
* BF533, BF561: SSEL2
*/
#ifndef CONFIG_SPI_FLASH_SSEL
-# if defined(__ADSPBF531__) || defined(__ADSPBF532__) || \
- defined(__ADSPBF533__) || defined(__ADSPBF561__)
+# if defined(__ADSPBF531__) || defined(__ADSPBF532__) || defined(__ADSPBF533__) || \
+ defined(__ADSPBF538__) || defined(__ADSPBF539__) || defined(__ADSPBF561__)
# define CONFIG_SPI_FLASH_SSEL 2
# else
# define CONFIG_SPI_FLASH_SSEL 1
@@ -797,8 +797,8 @@ int eeprom_info(void)
ret = 1;
else
printf("SPI Device: %s 0x%02X (%s) 0x%02X 0x%02X\n"
- "Parameters: num sectors = %i, sector size = %i, write size = %i\n"
- "Flash Size: %i mbit (%i mbyte)\n"
+ "Parameters: num sectors = %lu, sector size = %lu, write size = %i\n"
+ "Flash Size: %lu mbit (%lu mbyte)\n"
"Status: 0x%02X\n",
flash.flash->name, flash.manufacturer_id, flash.manufacturer->name,
flash.device_id1, flash.device_id2, flash.num_sectors,
diff --git a/board/bf561-ezkit/Makefile b/board/bf561-ezkit/Makefile
index e7ee2435698..daebb74578b 100644
--- a/board/bf561-ezkit/Makefile
+++ b/board/bf561-ezkit/Makefile
@@ -29,11 +29,11 @@ include $(TOPDIR)/config.mk
LIB = $(obj)lib$(BOARD).a
-COBJS := $(BOARD).o
+COBJS-y := $(BOARD).o
-SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c)
-OBJS := $(addprefix $(obj),$(COBJS))
-SOBJS := $(addprefix $(obj),$(SOBJS))
+SRCS := $(SOBJS-y:.o=.S) $(COBJS-y:.o=.c)
+OBJS := $(addprefix $(obj),$(COBJS-y))
+SOBJS := $(addprefix $(obj),$(SOBJS-y))
$(LIB): $(obj).depend $(OBJS) $(SOBJS) $(obj)u-boot.lds
$(AR) $(ARFLAGS) $@ $(OBJS) $(SOBJS)
diff --git a/board/bf561-ezkit/bf561-ezkit.c b/board/bf561-ezkit/bf561-ezkit.c
index 7f8598c71f8..5aede174d88 100644
--- a/board/bf561-ezkit/bf561-ezkit.c
+++ b/board/bf561-ezkit/bf561-ezkit.c
@@ -39,19 +39,7 @@ int checkboard(void)
phys_size_t initdram(int board_type)
{
-#ifdef DEBUG
- int brate;
- char *tmp = getenv("baudrate");
- brate = simple_strtoul(tmp, NULL, 16);
- printf("Serial Port initialized with Baud rate = %x\n", brate);
- printf("SDRAM attributes:\n");
- printf("tRCD %d SCLK Cycles,tRP %d SCLK Cycles,tRAS %d SCLK Cycles"
- "tWR %d SCLK Cycles,CAS Latency %d SCLK cycles \n",
- 3, 3, 6, 2, 3);
- printf("SDRAM Begin: 0x%x\n", CONFIG_SYS_SDRAM_BASE);
- printf("Bank size = %d MB\n", CONFIG_SYS_MAX_RAM_SIZE >> 20);
-#endif
gd->bd->bi_memstart = CONFIG_SYS_SDRAM_BASE;
gd->bd->bi_memsize = CONFIG_SYS_MAX_RAM_SIZE;
- return CONFIG_SYS_MAX_RAM_SIZE;
+ return gd->bd->bi_memsize;
}
diff --git a/common/cmd_bootldr.c b/common/cmd_bootldr.c
index b525f0d602d..48d113f1f12 100644
--- a/common/cmd_bootldr.c
+++ b/common/cmd_bootldr.c
@@ -16,6 +16,125 @@
#include <asm/blackfin.h>
#include <asm/mach-common/bits/bootrom.h>
+/* Simple sanity check on the specified address to make sure it contains
+ * an LDR image of some sort.
+ */
+static bool ldr_valid_signature(uint8_t *data)
+{
+#if defined(__ADSPBF561__)
+
+ /* BF56x has a 4 byte global header */
+ if (data[3] == 0xA0)
+ return true;
+
+#elif defined(__ADSPBF531__) || defined(__ADSPBF532__) || defined(__ADSPBF533__) || \
+ defined(__ADSPBF534__) || defined(__ADSPBF536__) || defined(__ADSPBF537__) || \
+ defined(__ADSPBF538__) || defined(__ADSPBF539__)
+
+ /* all the BF53x should start at this address mask */
+ uint32_t addr;
+ memmove(&addr, data, sizeof(addr));
+ if ((addr & 0xFF0FFF0F) == 0xFF000000)
+ return true;
+#else
+
+ /* everything newer has a magic byte */
+ uint32_t count;
+ memmove(&count, data + 8, sizeof(count));
+ if (data[3] == 0xAD && count == 0)
+ return true;
+
+#endif
+
+ return false;
+}
+
+/* If the Blackfin is new enough, the Blackfin on-chip ROM supports loading
+ * LDRs from random memory addresses. So whenever possible, use that. In
+ * the older cases (BF53x/BF561), parse the LDR format ourselves.
+ */
+#define ZEROFILL 0x0001
+#define RESVECT 0x0002
+#define INIT 0x0008
+#define IGNORE 0x0010
+#define FINAL 0x8000
+static void ldr_load(uint8_t *base_addr)
+{
+#if defined(__ADSPBF531__) || defined(__ADSPBF532__) || defined(__ADSPBF533__) || \
+ /*defined(__ADSPBF534__) || defined(__ADSPBF536__) || defined(__ADSPBF537__) ||*/\
+ defined(__ADSPBF538__) || defined(__ADSPBF539__) || defined(__ADSPBF561__)
+
+ uint32_t addr;
+ uint32_t count;
+ uint16_t flags;
+
+ /* the bf56x has a 4 byte global header ... but it is useless to
+ * us when booting an LDR from a memory address, so skip it
+ */
+# ifdef __ADSPBF561__
+ base_addr += 4;
+# endif
+
+ memmove(&flags, base_addr + 8, sizeof(flags));
+ bfin_write_EVT1(flags & RESVECT ? 0xFFA00000 : 0xFFA08000);
+
+ do {
+ /* block header may not be aligned */
+ memmove(&addr, base_addr, sizeof(addr));
+ memmove(&count, base_addr+4, sizeof(count));
+ memmove(&flags, base_addr+8, sizeof(flags));
+ base_addr += sizeof(addr) + sizeof(count) + sizeof(flags);
+
+ printf("loading to 0x%08x (0x%x bytes) flags: 0x%04x\n",
+ addr, count, flags);
+
+ if (!(flags & IGNORE)) {
+ if (flags & ZEROFILL)
+ memset((void *)addr, 0x00, count);
+ else
+ memcpy((void *)addr, base_addr, count);
+
+ if (flags & INIT) {
+ void (*init)(void) = (void *)addr;
+ init();
+ }
+ }
+
+ if (!(flags & ZEROFILL))
+ base_addr += count;
+ } while (!(flags & FINAL));
+
+#endif
+}
+
+/* For BF537, we use the _BOOTROM_BOOT_DXE_FLASH funky ROM function.
+ * For all other BF53x/BF56x, we just call the entry point.
+ * For everything else (newer), we use _BOOTROM_MEMBOOT ROM function.
+ */
+static void ldr_exec(void *addr)
+{
+#if defined(__ADSPBF534__) || defined(__ADSPBF536__) || defined(__ADSPBF537__)
+
+ /* restore EVT1 to reset value as this is what the bootrom uses as
+ * the default entry point when booting the final block of LDRs
+ */
+ bfin_write_EVT1(L1_INST_SRAM);
+ __asm__("call (%0);" : : "a"(_BOOTROM_MEMBOOT), "q7"(addr) : "RETS", "memory");
+
+#elif defined(__ADSPBF531__) || defined(__ADSPBF532__) || defined(__ADSPBF533__) || \
+ defined(__ADSPBF538__) || defined(__ADSPBF539__) || defined(__ADSPBF561__)
+
+ void (*ldr_entry)(void) = (void *)bfin_read_EVT1();
+ ldr_entry();
+
+#else
+
+ int32_t (*BOOTROM_MEM)(void *, int32_t, int32_t, void *) = (void *)_BOOTROM_MEMBOOT;
+ BOOTROM_MEM(addr, 0, 0, NULL);
+
+#endif
+}
+
/*
* the bootldr command loads an address, checks to see if there
* is a Boot stream that the on-chip BOOTROM can understand,
@@ -23,11 +142,9 @@
* to also add booting from SPI, or TWI, but this function does
* not currently support that.
*/
-
int do_bootldr(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{
void *addr;
- uint32_t *data;
/* Get the address */
if (argc < 2)
@@ -36,22 +153,14 @@ int do_bootldr(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
addr = (void *)simple_strtoul(argv[1], NULL, 16);
/* Check if it is a LDR file */
- data = addr;
-#if defined(__ADSPBF54x__) || defined(__ADSPBF52x__)
- if ((*data & 0xFF000000) == 0xAD000000 && data[2] == 0x00000000) {
-#else
- if (*data == 0xFF800060 || *data == 0xFF800040 || *data == 0xFF800020) {
-#endif
- /* We want to boot from FLASH or SDRAM */
+ if (ldr_valid_signature(addr)) {
printf("## Booting ldr image at 0x%p ...\n", addr);
+ ldr_load(addr);
icache_disable();
dcache_disable();
- __asm__(
- "jump (%1);"
- :
- : "q7" (addr), "a" (_BOOTROM_MEMBOOT));
+ ldr_exec(addr);
} else
printf("## No ldr image at address 0x%p\n", addr);
diff --git a/common/cmd_cplbinfo.c b/common/cmd_cplbinfo.c
index 629e6a9389e..56e70d6155a 100644
--- a/common/cmd_cplbinfo.c
+++ b/common/cmd_cplbinfo.c
@@ -26,11 +26,11 @@ static const char *cplb_page_size(uint32_t data)
*/
static void show_cplb_table(uint32_t *addr, uint32_t *data)
{
- size_t i;
+ int i;
printf(" Address Data Size Valid Locked\n");
for (i = 1; i <= 16; ++i) {
printf(" %2i 0x%p 0x%05X %s %c %c\n",
- i, *addr, *data,
+ i, (void *)*addr, *data,
cplb_page_size(*data),
(*data & CPLB_VALID ? 'Y' : 'N'),
(*data & CPLB_LOCK ? 'Y' : 'N'));
diff --git a/common/cmd_otp.c b/common/cmd_otp.c
index e27bb29217d..65232903b22 100644
--- a/common/cmd_otp.c
+++ b/common/cmd_otp.c
@@ -6,7 +6,7 @@
* Licensed under the GPL-2 or later.
*/
-/* There are 512 128-bit "pages" (0x000 to 0x1FF).
+/* There are 512 128-bit "pages" (0x000 through 0x1FF).
* The pages are accessable as 64-bit "halfpages" (an upper and lower half).
* The pages are not part of the memory map. There is an OTP controller which
* handles scanning in/out of bits. While access is done through OTP MMRs,
@@ -17,8 +17,6 @@
#include <common.h>
#include <command.h>
-#ifdef CONFIG_CMD_OTP
-
#include <asm/blackfin.h>
#include <asm/mach-common/bits/otp.h>
@@ -40,30 +38,87 @@ static const char *otp_strerror(uint32_t err)
#define lowup(x) ((x) % 2 ? "upper" : "lower")
-int do_otp(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
+static int check_voltage(void)
+{
+ /* Make sure voltage limits are within datasheet spec */
+ uint16_t vr_ctl = bfin_read_VR_CTL();
+
+#ifdef __ADSPBF54x__
+ /* 0.9V <= VDDINT <= 1.1V */
+ if ((vr_ctl & 0xc) && (vr_ctl & 0xc0) == 0xc0)
+ return 1;
+#else
+ /* for the parts w/out qualification yet */
+ (void)vr_ctl;
+#endif
+
+ return 0;
+}
+
+static void set_otp_timing(bool write)
{
- bool force = false;
- if (!strcmp(argv[1], "--force")) {
- force = true;
- argv[1] = argv[0];
- argv++;
- --argc;
+ static uint32_t timing;
+ if (!timing) {
+ uint32_t tp1, tp2, tp3;
+ /* OTP_TP1 = 1000 / sclk_period (in nanoseconds)
+ * OTP_TP1 = 1000 / (1 / get_sclk() * 10^9)
+ * OTP_TP1 = (1000 * get_sclk()) / 10^9
+ * OTP_TP1 = get_sclk() / 10^6
+ */
+ tp1 = get_sclk() / 1000000;
+ /* OTP_TP2 = 400 / (2 * sclk_period)
+ * OTP_TP2 = 400 / (2 * 1 / get_sclk() * 10^9)
+ * OTP_TP2 = (400 * get_sclk()) / (2 * 10^9)
+ * OTP_TP2 = (2 * get_sclk()) / 10^7
+ */
+ tp2 = (2 * get_sclk() / 10000000) << 8;
+ /* OTP_TP3 = magic constant */
+ tp3 = (0x1401) << 15;
+ timing = tp1 | tp2 | tp3;
}
+ bfrom_OtpCommand(OTP_INIT, write ? timing : timing & ~(-1 << 15));
+}
+
+int do_otp(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
+{
+ uint32_t ret, base_flags;
+ bool prompt_user, force_read;
uint32_t (*otp_func)(uint32_t page, uint32_t flags, uint64_t *page_content);
- if (!strcmp(argv[1], "read"))
- otp_func = otp_read;
- else if (!strcmp(argv[1], "write"))
- otp_func = otp_write;
- else {
+
+ if (argc < 4) {
usage:
cmd_usage(cmdtp);
return 1;
}
+ prompt_user = false;
+ base_flags = 0;
+ if (!strcmp(argv[1], "read"))
+ otp_func = bfrom_OtpRead;
+ else if (!strcmp(argv[1], "dump")) {
+ otp_func = bfrom_OtpRead;
+ force_read = true;
+ } else if (!strcmp(argv[1], "write")) {
+ otp_func = bfrom_OtpWrite;
+ base_flags = OTP_CHECK_FOR_PREV_WRITE;
+ if (!strcmp(argv[2], "--force")) {
+ argv[2] = argv[1];
+ argv++;
+ --argc;
+ } else
+ prompt_user = false;
+ } else if (!strcmp(argv[1], "lock")) {
+ if (argc != 4)
+ goto usage;
+ otp_func = bfrom_OtpWrite;
+ base_flags = OTP_LOCK;
+ } else
+ goto usage;
+
uint64_t *addr = (uint64_t *)simple_strtoul(argv[2], NULL, 16);
uint32_t page = simple_strtoul(argv[3], NULL, 16);
- uint32_t flags, ret;
+ uint32_t flags;
size_t i, count;
ulong half;
@@ -81,14 +136,21 @@ int do_otp(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
} else
half = 0;
+ /* "otp lock" has slightly different semantics */
+ if (base_flags & OTP_LOCK) {
+ count = page;
+ page = (uint32_t)addr;
+ addr = NULL;
+ }
+
/* do to the nature of OTP, make sure users are sure */
- if (!force && otp_func == otp_write) {
+ if (prompt_user) {
printf(
"Writing one time programmable memory\n"
"Make sure your operating voltages and temperature are within spec\n"
" source address: 0x%p\n"
- " OTP destination: %s page 0x%03X - %s page 0x%03X\n"
- " number to write: %ld halfpages\n"
+ " OTP destination: %s page 0x%03X - %s page 0x%03lX\n"
+ " number to write: %lu halfpages\n"
" type \"YES\" (no quotes) to confirm: ",
addr,
lowup(half), page,
@@ -111,30 +173,42 @@ int do_otp(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
}
}
}
-
- /* Only supported in newer silicon ... enable writing */
-#if (0)
- otp_command(OTP_INIT, ...);
-#else
- *pOTP_TIMING = 0x32149485;
-#endif
}
- printf("OTP memory %s: addr 0x%08lx page 0x%03X count %ld ... ",
+ printf("OTP memory %s: addr 0x%p page 0x%03X count %zu ... ",
argv[1], addr, page, count);
+ set_otp_timing(otp_func == bfrom_OtpWrite);
+ if (otp_func == bfrom_OtpWrite && check_voltage()) {
+ puts("ERROR: VDDINT voltage is out of spec for writing\n");
+ return -1;
+ }
+
+ /* Do the actual reading/writing stuff */
ret = 0;
for (i = half; i < count + half; ++i) {
- flags = (i % 2) ? OTP_UPPER_HALF : OTP_LOWER_HALF;
+ flags = base_flags | (i % 2 ? OTP_UPPER_HALF : OTP_LOWER_HALF);
+ try_again:
ret = otp_func(page, flags, addr);
- if (ret & 0x1)
- break;
- else if (ret)
+ if (ret & OTP_MASTER_ERROR) {
+ if (force_read) {
+ if (flags & OTP_NO_ECC)
+ break;
+ else
+ flags |= OTP_NO_ECC;
+ puts("E");
+ goto try_again;
+ } else
+ break;
+ } else if (ret)
puts("W");
else
puts(".");
- ++addr;
- if (i % 2)
+ if (!(base_flags & OTP_LOCK)) {
+ ++addr;
+ if (i % 2)
+ ++page;
+ } else
++page;
}
if (ret & 0x1)
@@ -143,21 +217,20 @@ int do_otp(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
else
puts(" done\n");
- if (otp_func == otp_write)
- /* Only supported in newer silicon ... disable writing */
-#if (0)
- otp_command(OTP_INIT, ...);
-#else
- *pOTP_TIMING = 0x1485;
-#endif
+ /* Make sure we disable writing */
+ set_otp_timing(false);
+ bfrom_OtpCommand(OTP_CLOSE, 0);
return ret;
}
-U_BOOT_CMD(otp, 6, 0, do_otp,
- "One-Time-Programmable sub-system",
+U_BOOT_CMD(otp, 7, 0, do_otp,
+ "One-Time-Programmable sub-system\n",
"read <addr> <page> [count] [half]\n"
+ " - read 'count' half-pages starting at 'page' (offset 'half') to 'addr'\n"
+ "otp dump <addr> <page> [count] [half]\n"
+ " - like 'otp read', but skip read errors\n"
"otp write [--force] <addr> <page> [count] [half]\n"
- " - read/write 'count' half-pages starting at page 'page' (offset 'half')\n");
-
-#endif
+ " - write 'count' half-pages starting at 'page' (offset 'half') from 'addr'\n"
+ "otp lock <page> <count>\n"
+ " - lock 'count' pages starting at 'page'\n");
diff --git a/common/devices.c b/common/devices.c
index ce3b7a00f90..38f1bbc6ae9 100644
--- a/common/devices.c
+++ b/common/devices.c
@@ -240,6 +240,9 @@ int devices_init (void)
#ifdef CONFIG_NETCONSOLE
drv_nc_init ();
#endif
+#ifdef CONFIG_JTAG_CONSOLE
+ drv_jtag_console_init ();
+#endif
return (0);
}
diff --git a/cpu/blackfin/Makefile b/cpu/blackfin/Makefile
index 8fed4b422b7..b4049ff874b 100644
--- a/cpu/blackfin/Makefile
+++ b/cpu/blackfin/Makefile
@@ -17,14 +17,15 @@ EXTRA :=
CEXTRA := initcode.o
SEXTRA := start.o
SOBJS := interrupt.o cache.o
-COBJS := cpu.o traps.o interrupts.o reset.o serial.o i2c.o watchdog.o
+COBJS-y := cpu.o traps.o interrupts.o reset.o serial.o watchdog.o
+COBJS-$(CONFIG_JTAG_CONSOLE) += jtag-console.o
ifeq ($(CONFIG_BFIN_BOOT_MODE),BFIN_BOOT_BYPASS)
-COBJS += initcode.o
+COBJS-y += initcode.o
endif
-SRCS := $(SEXTRA:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c)
-OBJS := $(addprefix $(obj),$(COBJS) $(SOBJS))
+SRCS := $(SEXTRA:.o=.S) $(SOBJS:.o=.S) $(COBJS-y:.o=.c)
+OBJS := $(addprefix $(obj),$(COBJS-y) $(SOBJS))
EXTRA := $(addprefix $(obj),$(EXTRA))
CEXTRA := $(addprefix $(obj),$(CEXTRA))
SEXTRA := $(addprefix $(obj),$(SEXTRA))
diff --git a/cpu/blackfin/cache.S b/cpu/blackfin/cache.S
index 51bdb30e329..9facadfd171 100644
--- a/cpu/blackfin/cache.S
+++ b/cpu/blackfin/cache.S
@@ -39,7 +39,7 @@ ENTRY(_blackfin_dcache_flush_range)
RTS;
ENDPROC(_blackfin_dcache_flush_range)
-ENTRY(_blackfin_dcache_invalidate_range)
+ENTRY(_blackfin_dcache_flush_invalidate_range)
R2 = -32;
R2 = R0 & R2;
P0 = R2;
@@ -58,4 +58,4 @@ ENTRY(_blackfin_dcache_invalidate_range)
FLUSHINV[P0];
SSYNC;
RTS;
-ENDPROC(_blackfin_dcache_invalidate_range)
+ENDPROC(_blackfin_dcache_flush_invalidate_range)
diff --git a/cpu/blackfin/cpu.c b/cpu/blackfin/cpu.c
index 9efd88e7ec9..30c214be7bc 100644
--- a/cpu/blackfin/cpu.c
+++ b/cpu/blackfin/cpu.c
@@ -14,11 +14,14 @@
#include <asm/blackfin.h>
#include <asm/cplb.h>
#include <asm/mach-common/bits/core.h>
+#include <asm/mach-common/bits/ebiu.h>
#include <asm/mach-common/bits/trace.h>
#include "cpu.h"
#include "serial.h"
+ulong bfin_poweron_retx;
+
__attribute__ ((__noreturn__))
void cpu_init_f(ulong bootflag, ulong loaded_from_ldr)
{
@@ -48,6 +51,9 @@ void cpu_init_f(ulong bootflag, ulong loaded_from_ldr)
bfin_write_EBIU_AMGCTL(CONFIG_EBIU_AMGCTL_VAL);
#endif
+ /* Save RETX so we can pass it while booting Linux */
+ bfin_poweron_retx = bootflag;
+
#ifdef CONFIG_DEBUG_DUMP
/* Turn on hardware trace buffer */
bfin_write_TBUFCTL(TBUFPWR | TBUFEN);
diff --git a/cpu/blackfin/i2c.c b/cpu/blackfin/i2c.c
deleted file mode 100644
index 2a3e2238c36..00000000000
--- a/cpu/blackfin/i2c.c
+++ /dev/null
@@ -1,428 +0,0 @@
-/*
- * i2c.c - driver for Blackfin on-chip TWI/I2C
- *
- * Copyright (c) 2006-2008 Analog Devices Inc.
- *
- * Licensed under the GPL-2 or later.
- */
-
-#include <common.h>
-
-#ifdef CONFIG_HARD_I2C
-
-#include <asm/blackfin.h>
-#include <i2c.h>
-#include <asm/io.h>
-#include <asm/mach-common/bits/twi.h>
-
-/* Two-Wire Interface (0xFFC01400 - 0xFFC014FF) */
-#ifdef TWI0_CLKDIV
-#define bfin_read_TWI_CLKDIV() bfin_read_TWI0_CLKDIV()
-#define bfin_write_TWI_CLKDIV(val) bfin_write_TWI0_CLKDIV(val)
-#define bfin_read_TWI_CONTROL() bfin_read_TWI0_CONTROL()
-#define bfin_write_TWI_CONTROL(val) bfin_write_TWI0_CONTROL(val)
-#define bfin_read_TWI_SLAVE_CTL() bfin_read_TWI0_SLAVE_CTL()
-#define bfin_write_TWI_SLAVE_CTL(val) bfin_write_TWI0_SLAVE_CTL(val)
-#define bfin_read_TWI_SLAVE_STAT() bfin_read_TWI0_SLAVE_STAT()
-#define bfin_write_TWI_SLAVE_STAT(val) bfin_write_TWI0_SLAVE_STAT(val)
-#define bfin_read_TWI_SLAVE_ADDR() bfin_read_TWI0_SLAVE_ADDR()
-#define bfin_write_TWI_SLAVE_ADDR(val) bfin_write_TWI0_SLAVE_ADDR(val)
-#define bfin_read_TWI_MASTER_CTL() bfin_read_TWI0_MASTER_CTL()
-#define bfin_write_TWI_MASTER_CTL(val) bfin_write_TWI0_MASTER_CTL(val)
-#define bfin_read_TWI_MASTER_STAT() bfin_read_TWI0_MASTER_STAT()
-#define bfin_write_TWI_MASTER_STAT(val) bfin_write_TWI0_MASTER_STAT(val)
-#define bfin_read_TWI_MASTER_ADDR() bfin_read_TWI0_MASTER_ADDR()
-#define bfin_write_TWI_MASTER_ADDR(val) bfin_write_TWI0_MASTER_ADDR(val)
-#define bfin_read_TWI_INT_STAT() bfin_read_TWI0_INT_STAT()
-#define bfin_write_TWI_INT_STAT(val) bfin_write_TWI0_INT_STAT(val)
-#define bfin_read_TWI_INT_MASK() bfin_read_TWI0_INT_MASK()
-#define bfin_write_TWI_INT_MASK(val) bfin_write_TWI0_INT_MASK(val)
-#define bfin_read_TWI_FIFO_CTL() bfin_read_TWI0_FIFO_CTL()
-#define bfin_write_TWI_FIFO_CTL(val) bfin_write_TWI0_FIFO_CTL(val)
-#define bfin_read_TWI_FIFO_STAT() bfin_read_TWI0_FIFO_STAT()
-#define bfin_write_TWI_FIFO_STAT(val) bfin_write_TWI0_FIFO_STAT(val)
-#define bfin_read_TWI_XMT_DATA8() bfin_read_TWI0_XMT_DATA8()
-#define bfin_write_TWI_XMT_DATA8(val) bfin_write_TWI0_XMT_DATA8(val)
-#define bfin_read_TWI_XMT_DATA_16() bfin_read_TWI0_XMT_DATA16()
-#define bfin_write_TWI_XMT_DATA16(val) bfin_write_TWI0_XMT_DATA16(val)
-#define bfin_read_TWI_RCV_DATA8() bfin_read_TWI0_RCV_DATA8()
-#define bfin_write_TWI_RCV_DATA8(val) bfin_write_TWI0_RCV_DATA8(val)
-#define bfin_read_TWI_RCV_DATA16() bfin_read_TWI0_RCV_DATA16()
-#define bfin_write_TWI_RCV_DATA16(val) bfin_write_TWI0_RCV_DATA16(val)
-#endif
-
-#ifdef DEBUG_I2C
-#define PRINTD(fmt,args...) do { \
- DECLARE_GLOBAL_DATA_PTR; \
- if (gd->have_console) \
- printf(fmt ,##args); \
- } while (0)
-#else
-#define PRINTD(fmt,args...)
-#endif
-
-#ifndef CONFIG_TWICLK_KHZ
-#define CONFIG_TWICLK_KHZ 50
-#endif
-
-/* All transfers are described by this data structure */
-struct i2c_msg {
- u16 addr; /* slave address */
- u16 flags;
-#define I2C_M_STOP 0x2
-#define I2C_M_RD 0x1
- u16 len; /* msg length */
- u8 *buf; /* pointer to msg data */
-};
-
-/**
- * i2c_reset: - reset the host controller
- */
-static void i2c_reset(void)
-{
- /* Disable TWI */
- bfin_write_TWI_CONTROL(0);
- SSYNC();
-
- /* Set TWI internal clock as 10MHz */
- bfin_write_TWI_CONTROL(((get_sclk() / 1024 / 1024 + 5) / 10) & 0x7F);
-
- /* Set Twi interface clock as specified */
- if (CONFIG_TWICLK_KHZ > 400)
- bfin_write_TWI_CLKDIV(((5 * 1024 / 400) << 8) | ((5 * 1024 /
- 400) & 0xFF));
- else
- bfin_write_TWI_CLKDIV(((5 * 1024 /
- CONFIG_TWICLK_KHZ) << 8) | ((5 * 1024 /
- CONFIG_TWICLK_KHZ)
- & 0xFF));
-
- /* Enable TWI */
- bfin_write_TWI_CONTROL(bfin_read_TWI_CONTROL() | TWI_ENA);
- SSYNC();
-}
-
-int wait_for_completion(struct i2c_msg *msg, int timeout_count)
-{
- unsigned short twi_int_stat;
- unsigned short mast_stat;
- int i;
-
- for (i = 0; i < timeout_count; i++) {
- twi_int_stat = bfin_read_TWI_INT_STAT();
- mast_stat = bfin_read_TWI_MASTER_STAT();
-
- if (XMTSERV & twi_int_stat) {
- /* Transmit next data */
- if (msg->len > 0) {
- bfin_write_TWI_XMT_DATA8(*(msg->buf++));
- msg->len--;
- } else if (msg->flags & I2C_M_STOP)
- bfin_write_TWI_MASTER_CTL
- (bfin_read_TWI_MASTER_CTL() | STOP);
- SSYNC();
- /* Clear status */
- bfin_write_TWI_INT_STAT(XMTSERV);
- SSYNC();
- i = 0;
- }
- if (RCVSERV & twi_int_stat) {
- if (msg->len > 0) {
- /* Receive next data */
- *(msg->buf++) = bfin_read_TWI_RCV_DATA8();
- msg->len--;
- } else if (msg->flags & I2C_M_STOP) {
- bfin_write_TWI_MASTER_CTL
- (bfin_read_TWI_MASTER_CTL() | STOP);
- SSYNC();
- }
- /* Clear interrupt source */
- bfin_write_TWI_INT_STAT(RCVSERV);
- SSYNC();
- i = 0;
- }
- if (MERR & twi_int_stat) {
- bfin_write_TWI_INT_STAT(MERR);
- bfin_write_TWI_INT_MASK(0);
- bfin_write_TWI_MASTER_STAT(0x3e);
- bfin_write_TWI_MASTER_CTL(0);
- SSYNC();
- /*
- * if both err and complete int stats are set,
- * return proper results.
- */
- if (MCOMP & twi_int_stat) {
- bfin_write_TWI_INT_STAT(MCOMP);
- bfin_write_TWI_INT_MASK(0);
- bfin_write_TWI_MASTER_CTL(0);
- SSYNC();
- /*
- * If it is a quick transfer,
- * only address bug no data, not an err.
- */
- if (msg->len == 0 && mast_stat & BUFRDERR)
- return 0;
- /*
- * If address not acknowledged return -3,
- * else return 0.
- */
- else if (!(mast_stat & ANAK))
- return 0;
- else
- return -3;
- }
- return -1;
- }
- if (MCOMP & twi_int_stat) {
- bfin_write_TWI_INT_STAT(MCOMP);
- SSYNC();
- bfin_write_TWI_INT_MASK(0);
- bfin_write_TWI_MASTER_CTL(0);
- SSYNC();
- return 0;
- }
- }
- if (msg->flags & I2C_M_RD)
- return -4;
- else
- return -2;
-}
-
-/**
- * i2c_transfer: - Transfer one byte over the i2c bus
- *
- * This function can tranfer a byte over the i2c bus in both directions.
- * It is used by the public API functions.
- *
- * @return: 0: transfer successful
- * -1: transfer fail
- * -2: transmit timeout
- * -3: ACK missing
- * -4: receive timeout
- * -5: controller not ready
- */
-int i2c_transfer(struct i2c_msg *msg)
-{
- int ret = 0;
- int timeout_count = 10000;
- int len = msg->len;
-
- if (!(bfin_read_TWI_CONTROL() & TWI_ENA)) {
- ret = -5;
- goto transfer_error;
- }
-
- while (bfin_read_TWI_MASTER_STAT() & BUSBUSY)
- continue;
-
- /* Set Transmit device address */
- bfin_write_TWI_MASTER_ADDR(msg->addr);
-
- /*
- * FIFO Initiation.
- * Data in FIFO should be discarded before start a new operation.
- */
- bfin_write_TWI_FIFO_CTL(0x3);
- SSYNC();
- bfin_write_TWI_FIFO_CTL(0);
- SSYNC();
-
- if (!(msg->flags & I2C_M_RD)) {
- /* Transmit first data */
- if (msg->len > 0) {
- PRINTD("1 in i2c_transfer: buf=%d, len=%d\n", *msg->buf,
- len);
- bfin_write_TWI_XMT_DATA8(*(msg->buf++));
- msg->len--;
- SSYNC();
- }
- }
-
- /* clear int stat */
- bfin_write_TWI_INT_STAT(MERR | MCOMP | XMTSERV | RCVSERV);
-
- /* Interrupt mask . Enable XMT, RCV interrupt */
- bfin_write_TWI_INT_MASK(MCOMP | MERR |
- ((msg->flags & I2C_M_RD) ? RCVSERV : XMTSERV));
- SSYNC();
-
- if (len > 0 && len <= 255)
- bfin_write_TWI_MASTER_CTL((len << 6));
- else if (msg->len > 255) {
- bfin_write_TWI_MASTER_CTL((0xff << 6));
- msg->flags &= I2C_M_STOP;
- } else
- bfin_write_TWI_MASTER_CTL(0);
-
- /* Master enable */
- bfin_write_TWI_MASTER_CTL(bfin_read_TWI_MASTER_CTL() | MEN |
- ((msg->flags & I2C_M_RD)
- ? MDIR : 0) | ((CONFIG_TWICLK_KHZ >
- 100) ? FAST : 0));
- SSYNC();
-
- ret = wait_for_completion(msg, timeout_count);
- PRINTD("3 in i2c_transfer: ret=%d\n", ret);
-
- transfer_error:
- switch (ret) {
- case 1:
- PRINTD(("i2c_transfer: error: transfer fail\n"));
- break;
- case 2:
- PRINTD(("i2c_transfer: error: transmit timeout\n"));
- break;
- case 3:
- PRINTD(("i2c_transfer: error: ACK missing\n"));
- break;
- case 4:
- PRINTD(("i2c_transfer: error: receive timeout\n"));
- break;
- case 5:
- PRINTD(("i2c_transfer: error: controller not ready\n"));
- i2c_reset();
- break;
- default:
- break;
- }
- return ret;
-
-}
-
-/* ---------------------------------------------------------------------*/
-/* API Functions */
-/* ---------------------------------------------------------------------*/
-
-void i2c_init(int speed, int slaveaddr)
-{
- i2c_reset();
-}
-
-/**
- * i2c_probe: - Test if a chip answers for a given i2c address
- *
- * @chip: address of the chip which is searched for
- * @return: 0 if a chip was found, -1 otherwhise
- */
-
-int i2c_probe(uchar chip)
-{
- struct i2c_msg msg;
- u8 probebuf;
-
- i2c_reset();
-
- probebuf = 0;
- msg.addr = chip;
- msg.flags = 0;
- msg.len = 1;
- msg.buf = &probebuf;
- if (i2c_transfer(&msg))
- return -1;
-
- msg.addr = chip;
- msg.flags = I2C_M_RD;
- msg.len = 1;
- msg.buf = &probebuf;
- if (i2c_transfer(&msg))
- return -1;
-
- return 0;
-}
-
-/**
- * i2c_read: - Read multiple bytes from an i2c device
- *
- * chip: I2C chip address, range 0..127
- * addr: Memory (register) address within the chip
- * alen: Number of bytes to use for addr (typically 1, 2 for larger
- * memories, 0 for register type devices with only one
- * register)
- * buffer: Where to read/write the data
- * len: How many bytes to read/write
- *
- * Returns: 0 on success, not 0 on failure
- */
-
-int i2c_read(uchar chip, uint addr, int alen, uchar * buffer, int len)
-{
- struct i2c_msg msg;
- u8 addr_bytes[3]; /* lowest...highest byte of data address */
-
- PRINTD("i2c_read: chip=0x%x, addr=0x%x, alen=0x%x, len=0x%x\n", chip,
- addr, alen, len);
-
- if (alen > 0) {
- addr_bytes[0] = (u8) ((addr >> 0) & 0x000000FF);
- addr_bytes[1] = (u8) ((addr >> 8) & 0x000000FF);
- addr_bytes[2] = (u8) ((addr >> 16) & 0x000000FF);
- msg.addr = chip;
- msg.flags = 0;
- msg.len = alen;
- msg.buf = addr_bytes;
- if (i2c_transfer(&msg))
- return -1;
- }
-
- /* start read sequence */
- PRINTD(("i2c_read: start read sequence\n"));
- msg.addr = chip;
- msg.flags = I2C_M_RD;
- msg.len = len;
- msg.buf = buffer;
- if (i2c_transfer(&msg))
- return -1;
-
- return 0;
-}
-
-/**
- * i2c_write: - Write multiple bytes to an i2c device
- *
- * chip: I2C chip address, range 0..127
- * addr: Memory (register) address within the chip
- * alen: Number of bytes to use for addr (typically 1, 2 for larger
- * memories, 0 for register type devices with only one
- * register)
- * buffer: Where to read/write the data
- * len: How many bytes to read/write
- *
- * Returns: 0 on success, not 0 on failure
- */
-
-int i2c_write(uchar chip, uint addr, int alen, uchar * buffer, int len)
-{
- struct i2c_msg msg;
- u8 addr_bytes[3]; /* lowest...highest byte of data address */
-
- PRINTD
- ("i2c_write: chip=0x%x, addr=0x%x, alen=0x%x, len=0x%x, buf0=0x%x\n",
- chip, addr, alen, len, buffer[0]);
-
- /* chip address write */
- if (alen > 0) {
- addr_bytes[0] = (u8) ((addr >> 0) & 0x000000FF);
- addr_bytes[1] = (u8) ((addr >> 8) & 0x000000FF);
- addr_bytes[2] = (u8) ((addr >> 16) & 0x000000FF);
- msg.addr = chip;
- msg.flags = 0;
- msg.len = alen;
- msg.buf = addr_bytes;
- if (i2c_transfer(&msg))
- return -1;
- }
-
- /* start read sequence */
- PRINTD(("i2c_write: start write sequence\n"));
- msg.addr = chip;
- msg.flags = 0;
- msg.len = len;
- msg.buf = buffer;
- if (i2c_transfer(&msg))
- return -1;
-
- return 0;
-
-}
-
-#endif /* CONFIG_HARD_I2C */
diff --git a/cpu/blackfin/initcode.c b/cpu/blackfin/initcode.c
index ffc8420f1a9..e733dd20fd1 100644
--- a/cpu/blackfin/initcode.c
+++ b/cpu/blackfin/initcode.c
@@ -158,7 +158,7 @@ static inline void serial_putc(char c)
#endif
#ifndef CONFIG_PLL_CTL_VAL
-# define CONFIG_PLL_CTL_VAL (SPORT_HYST | (CONFIG_VCO_MULT << 9))
+# define CONFIG_PLL_CTL_VAL (SPORT_HYST | (CONFIG_VCO_MULT << 9) | CONFIG_CLKIN_HALF)
#endif
#ifndef CONFIG_EBIU_RSTCTL_VAL
diff --git a/cpu/blackfin/jtag-console.c b/cpu/blackfin/jtag-console.c
new file mode 100644
index 00000000000..44c0a839ecc
--- /dev/null
+++ b/cpu/blackfin/jtag-console.c
@@ -0,0 +1,125 @@
+/*
+ * jtag-console.c - console driver over Blackfin JTAG
+ *
+ * Copyright (c) 2008 Analog Devices Inc.
+ *
+ * Licensed under the GPL-2 or later.
+ */
+
+#include <common.h>
+#include <devices.h>
+#include <asm/blackfin.h>
+
+#ifndef CONFIG_JTAG_CONSOLE_TIMEOUT
+# define CONFIG_JTAG_CONSOLE_TIMEOUT 100
+#endif
+
+/* The Blackfin tends to be much much faster than the JTAG hardware. */
+static void jtag_write_emudat(uint32_t emudat)
+{
+ static bool overflowed = false;
+ ulong timeout = get_timer(0) + CONFIG_JTAG_CONSOLE_TIMEOUT;
+ while (bfin_read_DBGSTAT() & 0x1) {
+ if (overflowed)
+ return;
+ if (timeout < get_timer(0))
+ overflowed = true;
+ }
+ overflowed = false;
+ __asm__ __volatile__("emudat = %0;" : : "d"(emudat));
+}
+/* Transmit a buffer. The format is:
+ * [32bit length][actual data]
+ */
+static void jtag_send(const char *c, uint32_t len)
+{
+ uint32_t i;
+
+ if (len == 0)
+ return;
+
+ /* First send the length */
+ jtag_write_emudat(len);
+
+ /* Then send the data */
+ for (i = 0; i < len; i += 4)
+ jtag_write_emudat((c[i] << 0) | (c[i+1] << 8) | (c[i+2] << 16) | (c[i+3] << 24));
+}
+static void jtag_putc(const char c)
+{
+ jtag_send(&c, 1);
+}
+static void jtag_puts(const char *s)
+{
+ jtag_send(s, strlen(s));
+}
+
+static int jtag_tstc(void)
+{
+ return (bfin_read_DBGSTAT() & 0x2);
+}
+
+/* Receive a buffer. The format is:
+ * [32bit length][actual data]
+ */
+static size_t inbound_len;
+static int leftovers_len;
+static uint32_t leftovers;
+static int jtag_getc(void)
+{
+ int ret;
+ uint32_t emudat;
+
+ /* see if any data is left over */
+ if (leftovers_len) {
+ --leftovers_len;
+ ret = leftovers & 0xff;
+ leftovers >>= 8;
+ return ret;
+ }
+
+ /* wait for new data ! */
+ while (!jtag_tstc())
+ continue;
+ __asm__("%0 = emudat;" : "=d"(emudat));
+
+ if (inbound_len == 0) {
+ /* grab the length */
+ inbound_len = emudat;
+ } else {
+ /* store the bytes */
+ leftovers_len = min(4, inbound_len);
+ inbound_len -= leftovers_len;
+ leftovers = emudat;
+ }
+
+ return jtag_getc();
+}
+
+int drv_jtag_console_init(void)
+{
+ device_t dev;
+ int ret;
+
+ memset(&dev, 0x00, sizeof(dev));
+ strcpy(dev.name, "jtag");
+ dev.flags = DEV_FLAGS_OUTPUT | DEV_FLAGS_INPUT | DEV_FLAGS_SYSTEM;
+ dev.putc = jtag_putc;
+ dev.puts = jtag_puts;
+ dev.tstc = jtag_tstc;
+ dev.getc = jtag_getc;
+
+ ret = device_register(&dev);
+ return (ret == 0 ? 1 : ret);
+}
+
+#ifdef CONFIG_UART_CONSOLE_IS_JTAG
+/* Since the JTAG is always available (at power on), allow it to fake a UART */
+void serial_set_baud(uint32_t baud) {}
+void serial_setbrg(void) {}
+int serial_init(void) { return 0; }
+void serial_putc(const char c) __attribute__((alias("jtag_putc")));
+void serial_puts(const char *s) __attribute__((alias("jtag_puts")));
+int serial_tstc(void) __attribute__((alias("jtag_tstc")));
+int serial_getc(void) __attribute__((alias("jtag_getc")));
+#endif
diff --git a/cpu/blackfin/reset.c b/cpu/blackfin/reset.c
index d1e34b3f94c..284cea579d0 100644
--- a/cpu/blackfin/reset.c
+++ b/cpu/blackfin/reset.c
@@ -29,26 +29,35 @@ void bfin_reset(void)
*/
__builtin_bfin_ssync();
- while (1) {
+ /* The bootrom checks to see how it was reset and will
+ * automatically perform a software reset for us when
+ * it starts executing after the core reset.
+ */
+ if (ANOMALY_05000353 || ANOMALY_05000386) {
/* Initiate System software reset. */
bfin_write_SWRST(0x7);
/* Due to the way reset is handled in the hardware, we need
- * to delay for 7 SCLKS. The only reliable way to do this is
- * to calculate the CCLK/SCLK ratio and multiply 7. For now,
+ * to delay for 10 SCLKS. The only reliable way to do this is
+ * to calculate the CCLK/SCLK ratio and multiply 10. For now,
* we'll assume worse case which is a 1:15 ratio.
*/
asm(
"LSETUP (1f, 1f) LC0 = %0\n"
"1: nop;"
:
- : "a" (15 * 7)
+ : "a" (15 * 10)
: "LC0", "LB0", "LT0"
);
/* Clear System software reset */
bfin_write_SWRST(0);
+ /* The BF526 ROM will crash during reset */
+#if defined(__ADSPBF522__) || defined(__ADSPBF524__) || defined(__ADSPBF526__)
+ bfin_read_SWRST();
+#endif
+
/* Wait for the SWRST write to complete. Cannot rely on SSYNC
* though as the System state is all reset now.
*/
@@ -59,10 +68,11 @@ void bfin_reset(void)
: "a" (15 * 1)
: "LC1", "LB1", "LT1"
);
+ }
+ while (1)
/* Issue core reset */
asm("raise 1");
- }
}
/* We need to trampoline ourselves up into L1 since our linker
diff --git a/cpu/blackfin/serial.c b/cpu/blackfin/serial.c
index 0d6f377c058..42534bd9b9c 100644
--- a/cpu/blackfin/serial.c
+++ b/cpu/blackfin/serial.c
@@ -29,6 +29,8 @@
#include <asm/blackfin.h>
#include <asm/mach-common/bits/uart.h>
+#ifdef CONFIG_UART_CONSOLE
+
#if defined(UART_LSR) && (CONFIG_UART_CONSOLE != 0)
# error CONFIG_UART_CONSOLE must be 0 on parts with only one UART
#endif
@@ -170,3 +172,5 @@ void serial_puts(const char *s)
while (*s)
serial_putc(*s++);
}
+
+#endif
diff --git a/cpu/blackfin/serial.h b/cpu/blackfin/serial.h
index ec40c266ac5..f671096768b 100644
--- a/cpu/blackfin/serial.h
+++ b/cpu/blackfin/serial.h
@@ -14,6 +14,10 @@
#include <asm/blackfin.h>
#include <asm/mach-common/bits/uart.h>
+#ifndef CONFIG_UART_CONSOLE
+# define CONFIG_UART_CONSOLE 0
+#endif
+
#ifdef CONFIG_DEBUG_EARLY_SERIAL
# define BFIN_DEBUG_EARLY_SERIAL 1
#else
@@ -95,7 +99,16 @@
__attribute__((always_inline))
static inline void serial_do_portmux(void)
{
-#ifdef __ADSPBF52x__
+#if defined(__ADSPBF51x__)
+# define DO_MUX(port, mux_tx, mux_rx, tx, rx) \
+ bfin_write_PORT##port##_MUX((bfin_read_PORT##port##_MUX() & ~(PORT_x_MUX_##mux_tx##_MASK | PORT_x_MUX_##mux_rx##_MASK)) | PORT_x_MUX_##mux_tx##_FUNC_2 | PORT_x_MUX_##mux_rx##_FUNC_2); \
+ bfin_write_PORT##port##_FER(bfin_read_PORT##port##_FER() | P##port##tx | P##port##rx);
+ switch (CONFIG_UART_CONSOLE) {
+ case 0: DO_MUX(G, 5, 5, 9, 10); break; /* Port G; mux 5; PG9 and PG10 */
+ case 1: DO_MUX(F, 2, 3, 14, 15); break; /* Port H; mux 2/3; PH14 and PH15 */
+ }
+ SSYNC();
+#elif defined(__ADSPBF52x__)
# define DO_MUX(port, mux, tx, rx) \
bfin_write_PORT##port##_MUX((bfin_read_PORT##port##_MUX() & ~PORT_x_MUX_##mux##_MASK) | PORT_x_MUX_##mux##_FUNC_3); \
bfin_write_PORT##port##_FER(bfin_read_PORT##port##_FER() | P##port##tx | P##port##rx);
diff --git a/cpu/blackfin/start.S b/cpu/blackfin/start.S
index 9975a0c62f5..6c8def48162 100644
--- a/cpu/blackfin/start.S
+++ b/cpu/blackfin/start.S
@@ -125,8 +125,11 @@ ENTRY(_start)
*/
r6 = 1 (x);
- /* Relocate from wherever are (FLASH/RAM/etc...) to the
- * hardcoded monitor location in the end of RAM.
+ /* Relocate from wherever we are (FLASH/RAM/etc...) to the hardcoded
+ * monitor location in the end of RAM. We know that memcpy() only
+ * uses registers, so it is safe to call here. Note that this only
+ * copies to external memory ... we do not start executing out of
+ * it yet (see "lower to 15" below).
*/
serial_early_puts("Relocate");
call _get_pc;
@@ -135,27 +138,16 @@ ENTRY(_start)
r2.h = .Loffset;
r3.l = _start;
r3.h = _start;
- r1 = r2 - r3;
-
- r0 = r0 - r1;
-
- cc = r0 == r3;
+ r2 = r2 - r3;
+ r1 = r0 - r2;
+ cc = r1 == r3;
if cc jump .Lnorelocate;
-
r6 = 0 (x);
- p1 = r0;
-
- p2.l = LO(CONFIG_SYS_MONITOR_BASE);
- p2.h = HI(CONFIG_SYS_MONITOR_BASE);
- p3 = 0x04;
- p4.l = LO(CONFIG_SYS_MONITOR_BASE + CONFIG_SYS_MONITOR_LEN);
- p4.h = HI(CONFIG_SYS_MONITOR_BASE + CONFIG_SYS_MONITOR_LEN);
-.Lloop1:
- r1 = [p1 ++ p3];
- [p2 ++ p3] = r1;
- cc=p2==p4;
- if !cc jump .Lloop1;
+ r0 = r3;
+ r2.l = LO(CONFIG_SYS_MONITOR_LEN);
+ r2.h = HI(CONFIG_SYS_MONITOR_LEN);
+ call _memcpy_ASM;
/* Initialize BSS section ... we know that memset() does not
* use the BSS, so it is safe to call here. The bootrom LDR
@@ -173,9 +165,8 @@ ENTRY(_start)
.Lnorelocate:
/* Setup the actual stack in external memory */
- r0.h = HI(CONFIG_STACKBASE);
- r0.l = LO(CONFIG_STACKBASE);
- sp = r0;
+ sp.h = HI(CONFIG_STACKBASE);
+ sp.l = LO(CONFIG_STACKBASE);
fp = sp;
/* Now lower ourselves from the highest interrupt level to
@@ -183,7 +174,9 @@ ENTRY(_start)
* setting the 15 handler to ".Lenable_nested", raising the 15
* interrupt, and then returning from the highest interrupt
* level to the dummy "jump" until the interrupt controller
- * services the pending 15 interrupt.
+ * services the pending 15 interrupt. If executing out of
+ * flash, these steps also changes the code flow from flash
+ * to external memory.
*/
serial_early_puts("Lower to 15");
r0 = r7;
diff --git a/cpu/blackfin/traps.c b/cpu/blackfin/traps.c
index d17c0a195dc..a2c6f1eceba 100644
--- a/cpu/blackfin/traps.c
+++ b/cpu/blackfin/traps.c
@@ -111,23 +111,12 @@ void trap_c(struct pt_regs *regs)
}
if (i == ARRAY_SIZE(bfin_memory_map)) {
printf("%cCPLB exception outside of memory map at 0x%p\n",
- (data ? 'D' : 'I'), new_cplb_addr);
+ (data ? 'D' : 'I'), (void *)new_cplb_addr);
bfin_panic(regs);
} else
debug("CPLB addr %p matches map 0x%p - 0x%p\n", new_cplb_addr, bfin_memory_map[i].start, bfin_memory_map[i].end);
new_cplb_data = (data ? bfin_memory_map[i].data_flags : bfin_memory_map[i].inst_flags);
- /* Turn the cache off */
- SSYNC();
- if (data) {
- asm(" .align 8; ");
- *pDMEM_CONTROL &= ~ENDCPLB;
- } else {
- asm(" .align 8; ");
- *pIMEM_CONTROL &= ~ENICPLB;
- }
- SSYNC();
-
if (data) {
CPLB_ADDR_BASE = (uint32_t *)DCPLB_ADDR0;
CPLB_DATA_BASE = (uint32_t *)DCPLB_DATA0;
@@ -149,8 +138,17 @@ void trap_c(struct pt_regs *regs)
debug("evicting entry %i: 0x%p 0x%08X\n", i, *CPLB_ADDR, *CPLB_DATA);
last_evicted = i + 1;
+
+ /* need to turn off cplbs whenever we muck with the cplb table */
+#if ENDCPLB != ENICPLB
+# error cplb enable bit violates my sanity
+#endif
+ uint32_t mem_control = (data ? DMEM_CONTROL : IMEM_CONTROL);
+ bfin_write32(mem_control, bfin_read32(mem_control) & ~ENDCPLB);
*CPLB_ADDR = new_cplb_addr;
*CPLB_DATA = new_cplb_data;
+ bfin_write32(mem_control, bfin_read32(mem_control) | ENDCPLB);
+ SSYNC();
/* dump current table for debugging purposes */
CPLB_ADDR = CPLB_ADDR_BASE;
@@ -158,17 +156,6 @@ void trap_c(struct pt_regs *regs)
for (i = 0; i < 16; ++i)
debug("%2i 0x%p 0x%08X\n", i, *CPLB_ADDR++, *CPLB_DATA++);
- /* Turn the cache back on */
- SSYNC();
- if (data) {
- asm(" .align 8; ");
- *pDMEM_CONTROL |= ENDCPLB;
- } else {
- asm(" .align 8; ");
- *pIMEM_CONTROL |= ENICPLB;
- }
- SSYNC();
-
break;
}
@@ -220,20 +207,21 @@ static const char *symbol_lookup(unsigned long addr, unsigned long *caddr)
static void decode_address(char *buf, unsigned long address)
{
unsigned long sym_addr;
+ void *paddr = (void *)address;
const char *sym = symbol_lookup(address, &sym_addr);
if (sym) {
- sprintf(buf, "<0x%p> { %s + 0x%x }", address, sym, address - sym_addr);
+ sprintf(buf, "<0x%p> { %s + 0x%lx }", paddr, sym, address - sym_addr);
return;
}
if (!address)
- sprintf(buf, "<0x%p> /* Maybe null pointer? */", address);
+ sprintf(buf, "<0x%p> /* Maybe null pointer? */", paddr);
else if (address >= CONFIG_SYS_MONITOR_BASE &&
address < CONFIG_SYS_MONITOR_BASE + CONFIG_SYS_MONITOR_LEN)
- sprintf(buf, "<0x%p> /* somewhere in u-boot */", address);
+ sprintf(buf, "<0x%p> /* somewhere in u-boot */", paddr);
else
- sprintf(buf, "<0x%p> /* unknown address */", address);
+ sprintf(buf, "<0x%p> /* unknown address */", paddr);
}
static char *strhwerrcause(uint16_t hwerrcause)
@@ -273,7 +261,7 @@ static char *strexcause(uint16_t excause)
void dump(struct pt_regs *fp)
{
char buf[150];
- size_t i;
+ int i;
uint16_t hwerrcause, excause;
if (!ENABLE_DUMP)
@@ -288,8 +276,8 @@ void dump(struct pt_regs *fp)
printf("SEQUENCER STATUS:\n");
printf(" SEQSTAT: %08lx IPEND: %04lx SYSCFG: %04lx\n",
fp->seqstat, fp->ipend, fp->syscfg);
- printf(" HWERRCAUSE: 0x%lx: %s\n", hwerrcause, strhwerrcause(hwerrcause));
- printf(" EXCAUSE : 0x%lx: %s\n", excause, strexcause(excause));
+ printf(" HWERRCAUSE: 0x%x: %s\n", hwerrcause, strhwerrcause(hwerrcause));
+ printf(" EXCAUSE : 0x%x: %s\n", excause, strexcause(excause));
for (i = 6; i <= 15; ++i) {
if (fp->ipend & (1 << i)) {
decode_address(buf, bfin_read32(EVT0 + 4*i));
@@ -323,7 +311,7 @@ void dump(struct pt_regs *fp)
printf(" P0 : %08lx P1 : %08lx P2 : %08lx P3 : %08lx\n",
fp->p0, fp->p1, fp->p2, fp->p3);
printf(" P4 : %08lx P5 : %08lx FP : %08lx SP : %08lx\n",
- fp->p4, fp->p5, fp->fp, fp);
+ fp->p4, fp->p5, fp->fp, (unsigned long)fp);
printf(" LB0: %08lx LT0: %08lx LC0: %08lx\n",
fp->lb0, fp->lt0, fp->lc0);
printf(" LB1: %08lx LT1: %08lx LC1: %08lx\n",
@@ -349,7 +337,7 @@ void dump_bfin_trace_buffer(void)
{
char buf[150];
unsigned long tflags;
- size_t i = 0;
+ int i = 0;
if (!ENABLE_DUMP)
return;
diff --git a/drivers/i2c/Makefile b/drivers/i2c/Makefile
index 6079c05ade3..08cb91d600e 100644
--- a/drivers/i2c/Makefile
+++ b/drivers/i2c/Makefile
@@ -25,6 +25,7 @@ include $(TOPDIR)/config.mk
LIB := $(obj)libi2c.a
+COBJS-$(CONFIG_BFIN_TWI_I2C) += bfin-twi_i2c.o
COBJS-$(CONFIG_FSL_I2C) += fsl_i2c.o
COBJS-$(CONFIG_I2C_MXC) += mxc_i2c.o
COBJS-$(CONFIG_DRIVER_OMAP1510_I2C) += omap1510_i2c.o
diff --git a/drivers/i2c/bfin-twi_i2c.c b/drivers/i2c/bfin-twi_i2c.c
new file mode 100644
index 00000000000..cfe55cd1d28
--- /dev/null
+++ b/drivers/i2c/bfin-twi_i2c.c
@@ -0,0 +1,285 @@
+/*
+ * i2c.c - driver for Blackfin on-chip TWI/I2C
+ *
+ * Copyright (c) 2006-2008 Analog Devices Inc.
+ *
+ * Licensed under the GPL-2 or later.
+ */
+
+#include <common.h>
+#include <i2c.h>
+
+#include <asm/blackfin.h>
+#include <asm/mach-common/bits/twi.h>
+
+#ifdef DEBUG
+# define dmemset(s, c, n) memset(s, c, n)
+#else
+# define dmemset(s, c, n)
+#endif
+#define debugi(fmt, args...) \
+ debug( \
+ "MSTAT:0x%03x FSTAT:0x%x ISTAT:0x%02x\t" \
+ "%-20s:%-3i: " fmt "\n", \
+ bfin_read_TWI_MASTER_STAT(), bfin_read_TWI_FIFO_STAT(), bfin_read_TWI_INT_STAT(), \
+ __func__, __LINE__, ## args)
+
+#ifdef TWI0_CLKDIV
+#define bfin_write_TWI_CLKDIV(val) bfin_write_TWI0_CLKDIV(val)
+#define bfin_write_TWI_CONTROL(val) bfin_write_TWI0_CONTROL(val)
+#define bfin_read_TWI_CONTROL(val) bfin_read_TWI0_CONTROL(val)
+#define bfin_write_TWI_MASTER_ADDR(val) bfin_write_TWI0_MASTER_ADDR(val)
+#define bfin_write_TWI_XMT_DATA8(val) bfin_write_TWI0_XMT_DATA8(val)
+#define bfin_read_TWI_RCV_DATA8() bfin_read_TWI0_RCV_DATA8()
+#define bfin_read_TWI_INT_STAT() bfin_read_TWI0_INT_STAT()
+#define bfin_write_TWI_INT_STAT(val) bfin_write_TWI0_INT_STAT(val)
+#define bfin_read_TWI_MASTER_STAT() bfin_read_TWI0_MASTER_STAT()
+#define bfin_write_TWI_MASTER_STAT(val) bfin_write_TWI0_MASTER_STAT(val)
+#define bfin_read_TWI_MASTER_CTL() bfin_read_TWI0_MASTER_CTL()
+#define bfin_write_TWI_MASTER_CTL(val) bfin_write_TWI0_MASTER_CTL(val)
+#define bfin_write_TWI_INT_MASK(val) bfin_write_TWI0_INT_MASK(val)
+#define bfin_write_TWI_FIFO_CTL(val) bfin_write_TWI0_FIFO_CTL(val)
+#endif
+
+#ifdef CONFIG_TWICLK_KHZ
+# error do not define CONFIG_TWICLK_KHZ ... use CONFIG_SYS_I2C_SPEED
+#endif
+#if CONFIG_SYS_I2C_SPEED > 400000
+# error The Blackfin I2C hardware can only operate at 400KHz max
+#endif
+
+/* All transfers are described by this data structure */
+struct i2c_msg {
+ u8 flags;
+#define I2C_M_COMBO 0x4
+#define I2C_M_STOP 0x2
+#define I2C_M_READ 0x1
+ int len; /* msg length */
+ u8 *buf; /* pointer to msg data */
+ int alen; /* addr length */
+ u8 *abuf; /* addr buffer */
+};
+
+/**
+ * wait_for_completion - manage the actual i2c transfer
+ * @msg: the i2c msg
+ */
+static int wait_for_completion(struct i2c_msg *msg)
+{
+ uint16_t int_stat;
+
+ while (!ctrlc()) {
+ int_stat = bfin_read_TWI_INT_STAT();
+
+ if (int_stat & XMTSERV) {
+ debugi("processing XMTSERV");
+ bfin_write_TWI_INT_STAT(XMTSERV);
+ SSYNC();
+ if (msg->alen) {
+ bfin_write_TWI_XMT_DATA8(*(msg->abuf++));
+ --msg->alen;
+ } else if (!(msg->flags & I2C_M_COMBO) && msg->len) {
+ bfin_write_TWI_XMT_DATA8(*(msg->buf++));
+ --msg->len;
+ } else {
+ bfin_write_TWI_MASTER_CTL(bfin_read_TWI_MASTER_CTL() |
+ (msg->flags & I2C_M_COMBO ? RSTART | MDIR : STOP));
+ SSYNC();
+ }
+ }
+ if (int_stat & RCVSERV) {
+ debugi("processing RCVSERV");
+ bfin_write_TWI_INT_STAT(RCVSERV);
+ SSYNC();
+ if (msg->len) {
+ *(msg->buf++) = bfin_read_TWI_RCV_DATA8();
+ --msg->len;
+ } else if (msg->flags & I2C_M_STOP) {
+ bfin_write_TWI_MASTER_CTL(bfin_read_TWI_MASTER_CTL() | STOP);
+ SSYNC();
+ }
+ }
+ if (int_stat & MERR) {
+ debugi("processing MERR");
+ bfin_write_TWI_INT_STAT(MERR);
+ SSYNC();
+ break;
+ }
+ if (int_stat & MCOMP) {
+ debugi("processing MCOMP");
+ bfin_write_TWI_INT_STAT(MCOMP);
+ SSYNC();
+ if (msg->flags & I2C_M_COMBO && msg->len) {
+ bfin_write_TWI_MASTER_CTL((bfin_read_TWI_MASTER_CTL() & ~RSTART) |
+ (min(msg->len, 0xff) << 6) | MEN | MDIR);
+ SSYNC();
+ } else
+ break;
+ }
+ }
+
+ return msg->len;
+}
+
+/**
+ * i2c_transfer - setup an i2c transfer
+ * @return: 0 if things worked, non-0 if things failed
+ *
+ * Here we just get the i2c stuff all prepped and ready, and then tail off
+ * into wait_for_completion() for all the bits to go.
+ */
+static int i2c_transfer(uchar chip, uint addr, int alen, uchar *buffer, int len, u8 flags)
+{
+ uchar addr_buffer[] = {
+ (addr >> 0),
+ (addr >> 8),
+ (addr >> 16),
+ };
+ struct i2c_msg msg = {
+ .flags = flags | (len >= 0xff ? I2C_M_STOP : 0),
+ .buf = buffer,
+ .len = len,
+ .abuf = addr_buffer,
+ .alen = alen,
+ };
+ int ret;
+
+ dmemset(buffer, 0xff, len);
+ debugi("chip=0x%x addr=0x%02x alen=%i buf[0]=0x%02x len=%i flags=0x%02x[%s] ",
+ chip, addr, alen, buffer[0], len, flags, (flags & I2C_M_READ ? "rd" : "wr"));
+
+ /* wait for things to settle */
+ while (bfin_read_TWI_MASTER_STAT() & BUSBUSY)
+ if (ctrlc())
+ return 1;
+
+ /* Set Transmit device address */
+ bfin_write_TWI_MASTER_ADDR(chip);
+
+ /* Clear the FIFO before starting things */
+ bfin_write_TWI_FIFO_CTL(XMTFLUSH | RCVFLUSH);
+ SSYNC();
+ bfin_write_TWI_FIFO_CTL(0);
+ SSYNC();
+
+ /* prime the pump */
+ if (msg.alen) {
+ len = msg.alen;
+ debugi("first byte=0x%02x", *msg.abuf);
+ bfin_write_TWI_XMT_DATA8(*(msg.abuf++));
+ --msg.alen;
+ } else if (!(msg.flags & I2C_M_READ) && msg.len) {
+ debugi("first byte=0x%02x", *msg.buf);
+ bfin_write_TWI_XMT_DATA8(*(msg.buf++));
+ --msg.len;
+ }
+
+ /* clear int stat */
+ bfin_write_TWI_MASTER_STAT(-1);
+ bfin_write_TWI_INT_STAT(-1);
+ bfin_write_TWI_INT_MASK(0);
+ SSYNC();
+
+ /* Master enable */
+ bfin_write_TWI_MASTER_CTL(
+ (bfin_read_TWI_MASTER_CTL() & FAST) |
+ (min(len, 0xff) << 6) | MEN |
+ ((msg.flags & I2C_M_READ) ? MDIR : 0)
+ );
+ SSYNC();
+ debugi("CTL=0x%04x", bfin_read_TWI_MASTER_CTL());
+
+ /* process the rest */
+ ret = wait_for_completion(&msg);
+ debugi("ret=%d", ret);
+
+ if (ret) {
+ bfin_write_TWI_MASTER_CTL(bfin_read_TWI_MASTER_CTL() & ~MEN);
+ bfin_write_TWI_CONTROL(bfin_read_TWI_CONTROL() & ~TWI_ENA);
+ SSYNC();
+ bfin_write_TWI_CONTROL(bfin_read_TWI_CONTROL() | TWI_ENA);
+ SSYNC();
+ }
+
+ return ret;
+}
+
+/*
+ * i2c_init - initialize the i2c bus
+ * @speed: bus speed (in HZ)
+ * @slaveaddr: address of device in slave mode (0 - not slave)
+ *
+ * Slave mode isn't actually implemented. It'll stay that way until
+ * we get a real request for it.
+ */
+void i2c_init(int speed, int slaveaddr)
+{
+ uint8_t prescale = ((get_sclk() / 1024 / 1024 + 5) / 10) & 0x7F;
+
+ /* Set TWI internal clock as 10MHz */
+ bfin_write_TWI_CONTROL(prescale);
+
+ /* Set TWI interface clock as specified */
+ bfin_write_TWI_CLKDIV(
+ ((5 * 1024 / (speed / 1000)) << 8) |
+ ((5 * 1024 / (speed / 1000)) & 0xFF)
+ );
+
+ /* Don't turn it on */
+ bfin_write_TWI_MASTER_CTL(speed > 100000 ? FAST : 0);
+
+ /* But enable it */
+ bfin_write_TWI_CONTROL(TWI_ENA | prescale);
+ SSYNC();
+
+ debugi("CONTROL:0x%04x CLKDIV:0x%04x",
+ bfin_read_TWI_CONTROL(), bfin_read_TWI_CLKDIV());
+
+#if CONFIG_SYS_I2C_SLAVE
+# error I2C slave support not tested/supported
+ /* If they want us as a slave, do it */
+ if (slaveaddr) {
+ bfin_write_TWI_SLAVE_ADDR(slaveaddr);
+ bfin_write_TWI_SLAVE_CTL(SEN);
+ }
+#endif
+}
+
+/**
+ * i2c_probe - test if a chip exists at a given i2c address
+ * @chip: i2c chip addr to search for
+ * @return: 0 if found, non-0 if not found
+ */
+int i2c_probe(uchar chip)
+{
+ u8 byte;
+ return i2c_read(chip, 0, 0, &byte, 1);
+}
+
+/**
+ * i2c_read - read data from an i2c device
+ * @chip: i2c chip addr
+ * @addr: memory (register) address in the chip
+ * @alen: byte size of address
+ * @buffer: buffer to store data read from chip
+ * @len: how many bytes to read
+ * @return: 0 on success, non-0 on failure
+ */
+int i2c_read(uchar chip, uint addr, int alen, uchar *buffer, int len)
+{
+ return i2c_transfer(chip, addr, alen, buffer, len, (alen ? I2C_M_COMBO : I2C_M_READ));
+}
+
+/**
+ * i2c_write - write data to an i2c device
+ * @chip: i2c chip addr
+ * @addr: memory (register) address in the chip
+ * @alen: byte size of address
+ * @buffer: buffer to store data read from chip
+ * @len: how many bytes to write
+ * @return: 0 on success, non-0 on failure
+ */
+int i2c_write(uchar chip, uint addr, int alen, uchar *buffer, int len)
+{
+ return i2c_transfer(chip, addr, alen, buffer, len, 0);
+}
diff --git a/drivers/net/bfin_mac.c b/drivers/net/bfin_mac.c
index 504fd100a4d..dddbb78b1ce 100644
--- a/drivers/net/bfin_mac.c
+++ b/drivers/net/bfin_mac.c
@@ -331,20 +331,43 @@ static int SetupSystemRegs(int *opmode)
*pVR_CTL |= CLKBUFOE;
/* Set all the pins to peripheral mode */
-#ifndef CONFIG_BFIN_MAC_RMII
- *pPORTH_FER = 0xFFFF;
-#ifdef __ADSPBF52x__
- *pPORTH_MUX = PORT_x_MUX_0_FUNC_2 | PORT_x_MUX_1_FUNC_2 | PORT_x_MUX_2_FUNC_2;
-#endif
+#ifdef CONFIG_BFIN_MAC_RMII
+ /* grab RMII pins */
+# if defined(__ADSPBF51x__)
+ *pPORTF_MUX = (*pPORTF_MUX & \
+ ~(PORT_x_MUX_3_MASK | PORT_x_MUX_4_MASK | PORT_x_MUX_5_MASK)) | \
+ PORT_x_MUX_3_FUNC_1 | PORT_x_MUX_4_FUNC_1 | PORT_x_MUX_5_FUNC_1;
+ *pPORTF_FER |= PF8 | PF9 | PF10 | PF11 | PF12 | PF13 | PF14 | PF15;
+ *pPORTG_MUX = (*pPORTG_MUX & ~PORT_x_MUX_0_MASK) | PORT_x_MUX_0_FUNC_1;
+ *pPORTG_FER |= PG0 | PG1 | PG2;
+# elif defined(__ADSPBF52x__)
+ *pPORTG_MUX = (*pPORTG_MUX & ~PORT_x_MUX_6_MASK) | PORT_x_MUX_6_FUNC_2;
+ *pPORTG_FER |= PG14 | PG15;
+ *pPORTH_MUX = (*pPORTH_MUX & ~(PORT_x_MUX_0_MASK | PORT_x_MUX_1_MASK)) | \
+ PORT_x_MUX_0_FUNC_2 | PORT_x_MUX_1_FUNC_2;
+ *pPORTH_FER |= PH0 | PH1 | PH2 | PH3 | PH4 | PH5 | PH6 | PH7 | PH8;
+# else
+ *pPORTH_FER |= PH0 | PH1 | PH4 | PH5 | PH6 | PH8 | PH9 | PH14 | PH15;
+# endif
#else
-#if defined(__ADSPBF536__) || defined(__ADSPBF537__)
- *pPORTH_FER = 0xC373;
-#endif
-#ifdef __ADSPBF52x__
- *pPORTH_FER = 0x01FF;
- *pPORTH_MUX = PORT_x_MUX_0_FUNC_2 | PORT_x_MUX_1_FUNC_2;
-#endif
+ /* grab MII & RMII pins */
+# if defined(__ADSPBF51x__)
+ *pPORTF_MUX = (*pPORTF_MUX & \
+ ~(PORT_x_MUX_0_MASK | PORT_x_MUX_1_MASK | PORT_x_MUX_3_MASK | PORT_x_MUX_4_MASK | PORT_x_MUX_5_MASK)) | \
+ PORT_x_MUX_0_FUNC_1 | PORT_x_MUX_1_FUNC_1 | PORT_x_MUX_3_FUNC_1 | PORT_x_MUX_4_FUNC_1 | PORT_x_MUX_5_FUNC_1;
+ *pPORTF_FER |= PF0 | PF1 | PF2 | PF3 | PF4 | PF5 | PF6 | PF8 | PF9 | PF10 | PF11 | PF12 | PF13 | PF14 | PF15;
+ *pPORTG_MUX = (*pPORTG_MUX & ~PORT_x_MUX_0_MASK) | PORT_x_MUX_0_FUNC_1;
+ *pPORTG_FER |= PG0 | PG1 | PG2;
+# elif defined(__ADSPBF52x__)
+ *pPORTG_MUX = (*pPORTG_MUX & ~PORT_x_MUX_6_MASK) | PORT_x_MUX_6_FUNC_2;
+ *pPORTG_FER |= PG14 | PG15;
+ *pPORTH_MUX = PORT_x_MUX_0_FUNC_2 | PORT_x_MUX_1_FUNC_2 | PORT_x_MUX_2_FUNC_2;
+ *pPORTH_FER = -1; /* all pins */
+# else
+ *pPORTH_FER = -1; /* all pins */
+# endif
#endif
+
/* MDC = 2.5 MHz */
sysctl = SET_MDCDIV(24);
/* Odd word alignment for Receive Frame DMA word */
diff --git a/include/asm-blackfin/blackfin-config-post.h b/include/asm-blackfin/blackfin-config-post.h
index 0ab68ace75f..21abd724fbe 100644
--- a/include/asm-blackfin/blackfin-config-post.h
+++ b/include/asm-blackfin/blackfin-config-post.h
@@ -1,7 +1,7 @@
/*
* blackfin-config-post.h - setup common defines for Blackfin boards based on config.h
*
- * Copyright (c) 2007 Analog Devices Inc.
+ * Copyright (c) 2007-2008 Analog Devices Inc.
*
* Licensed under the GPL-2 or later.
*/
@@ -9,11 +9,6 @@
#ifndef __ASM_BLACKFIN_CONFIG_POST_H__
#define __ASM_BLACKFIN_CONFIG_POST_H__
-/* Check to make sure everything fits in external RAM */
-#if ((CONFIG_SYS_MONITOR_BASE + CONFIG_SYS_MONITOR_LEN) > CONFIG_SYS_MAX_RAM_SIZE)
-# error Memory Map does not fit into configuration
-#endif
-
/* Sanity check CONFIG_BFIN_CPU */
#ifndef CONFIG_BFIN_CPU
# error CONFIG_BFIN_CPU: your board config needs to define this
@@ -65,8 +60,81 @@
#endif
/* Using L1 scratch pad makes sense for everyone by default. */
-#ifndef CMD_LINE_ADDR
-# define CMD_LINE_ADDR L1_SRAM_SCRATCH
+#ifndef CONFIG_LINUX_CMDLINE_ADDR
+# define CONFIG_LINUX_CMDLINE_ADDR L1_SRAM_SCRATCH
+#endif
+#ifndef CONFIG_LINUX_CMDLINE_SIZE
+# define CONFIG_LINUX_CMDLINE_SIZE L1_SRAM_SCRATCH_SIZE
+#endif
+
+/* Default/common Blackfin memory layout */
+#ifndef CONFIG_SYS_SDRAM_BASE
+# define CONFIG_SYS_SDRAM_BASE 0
+#endif
+#ifndef CONFIG_SYS_MAX_RAM_SIZE
+# define CONFIG_SYS_MAX_RAM_SIZE (CONFIG_MEM_SIZE * 1024 * 1024)
+#endif
+#ifndef CONFIG_SYS_MONITOR_BASE
+# define CONFIG_SYS_MONITOR_BASE (CONFIG_SYS_MAX_RAM_SIZE - CONFIG_SYS_MONITOR_LEN)
+#endif
+#ifndef CONFIG_SYS_MALLOC_BASE
+# define CONFIG_SYS_MALLOC_BASE (CONFIG_SYS_MONITOR_BASE - CONFIG_SYS_MALLOC_LEN)
+#endif
+#ifndef CONFIG_SYS_GBL_DATA_SIZE
+# define CONFIG_SYS_GBL_DATA_SIZE (128)
+#endif
+#ifndef CONFIG_SYS_GBL_DATA_ADDR
+# define CONFIG_SYS_GBL_DATA_ADDR (CONFIG_SYS_MALLOC_BASE - CONFIG_SYS_GBL_DATA_SIZE)
+#endif
+#ifndef CONFIG_STACKBASE
+# define CONFIG_STACKBASE (CONFIG_SYS_GBL_DATA_ADDR - 4)
+#endif
+#ifndef CONFIG_SYS_MEMTEST_START
+# define CONFIG_SYS_MEMTEST_START 0
+#endif
+#ifndef CONFIG_SYS_MEMTEST_END
+# define CONFIG_SYS_MEMTEST_END (CONFIG_STACKBASE - 8192 + 4)
+#endif
+
+/* Check to make sure everything fits in external RAM */
+#if ((CONFIG_SYS_MONITOR_BASE + CONFIG_SYS_MONITOR_LEN) > CONFIG_SYS_MAX_RAM_SIZE)
+# error Memory Map does not fit into configuration
+#endif
+
+/* Default/common Blackfin environment settings */
+#ifndef CONFIG_LOADADDR
+# define CONFIG_LOADADDR 0x1000000
+#endif
+#ifndef CONFIG_SYS_LOAD_ADDR
+# define CONFIG_SYS_LOAD_ADDR CONFIG_LOADADDR
+#endif
+#ifndef CONFIG_SYS_BOOTM_LEN
+# define CONFIG_SYS_BOOTM_LEN 0x4000000
+#endif
+#ifndef CONFIG_SYS_PROMPT
+# define CONFIG_SYS_PROMPT "bfin> "
+#endif
+#ifndef CONFIG_SYS_CBSIZE
+# ifdef CONFIG_CMD_KGDB
+# define CONFIG_SYS_CBSIZE 1024
+# else
+# define CONFIG_SYS_CBSIZE 256
+# endif
+#endif
+#ifndef CONFIG_SYS_BARGSIZE
+# define CONFIG_SYS_BARGSIZE CONFIG_SYS_CBSIZE
+#endif
+#ifndef CONFIG_SYS_PBSIZE
+# define CONFIG_SYS_PBSIZE (CONFIG_SYS_CBSIZE + sizeof(CONFIG_SYS_PROMPT) + 16)
+#endif
+#ifndef CONFIG_SYS_MAXARGS
+# define CONFIG_SYS_MAXARGS 16
+#endif
+#ifndef CONFIG_SYS_HZ
+# define CONFIG_SYS_HZ 1000
+#endif
+#ifndef CONFIG_SYS_BAUDRATE_TABLE
+# define CONFIG_SYS_BAUDRATE_TABLE { 9600, 19200, 38400, 57600, 115200 }
#endif
#endif
diff --git a/include/asm-blackfin/blackfin_local.h b/include/asm-blackfin/blackfin_local.h
index 6f0e662a959..c9ee91a4390 100644
--- a/include/asm-blackfin/blackfin_local.h
+++ b/include/asm-blackfin/blackfin_local.h
@@ -58,7 +58,7 @@ extern u_long get_sclk(void);
extern void blackfin_icache_flush_range(const void *, const void *);
extern void blackfin_dcache_flush_range(const void *, const void *);
-extern void blackfin_dcache_invalidate_range(const void *, const void *);
+extern void blackfin_dcache_flush_invalidate_range(const void *, const void *);
/* Use DMA to move data from on chip to external memory. While this is
* required for only L1 instruction (it is not directly readable by the
diff --git a/include/asm-blackfin/mach-common/bits/bootrom.h b/include/asm-blackfin/mach-common/bits/bootrom.h
index 6cdaa4f8944..fb97ff81b3b 100644
--- a/include/asm-blackfin/mach-common/bits/bootrom.h
+++ b/include/asm-blackfin/mach-common/bits/bootrom.h
@@ -88,27 +88,42 @@
#define _BOOTROM_REV 0xEF000040
#define _BOOTROM_SESR 0xEF001000
+#define BOOTROM_FOLLOWS_C_ABI 1
+
#define BOOTROM_CAPS_ADI_BOOT_STRUCTS 1
-/* Not available on initial BF54x or BF52x */
-#if (defined(__ADSPBF54x__) && __SILICON_REVISION__ < 1) || \
- (defined(__ADSPBF52x__) && __SILICON_REVISION__ < 2)
-#define BOOTROM_CAPS_SYSCONTROL 0
-#else
-#define BOOTROM_CAPS_SYSCONTROL 1
#endif
+#ifndef BOOTROM_FOLLOWS_C_ABI
+#define BOOTROM_FOLLOWS_C_ABI 0
#endif
-
#ifndef BOOTROM_CAPS_ADI_BOOT_STRUCTS
#define BOOTROM_CAPS_ADI_BOOT_STRUCTS 0
#endif
-#ifndef BOOTROM_CAPS_SYSCONTROL
-#define BOOTROM_CAPS_SYSCONTROL 0
-#endif
+
+/* Possible syscontrol action flags */
+#define SYSCTRL_READ 0x00000000 /* read registers */
+#define SYSCTRL_WRITE 0x00000001 /* write registers */
+#define SYSCTRL_SYSRESET 0x00000002 /* perform system reset */
+#define SYSCTRL_CORERESET 0x00000004 /* perform core reset */
+#define SYSCTRL_SOFTRESET 0x00000006 /* perform core and system reset */
+#define SYSCTRL_VRCTL 0x00000010 /* read/write VR_CTL register */
+#define SYSCTRL_EXTVOLTAGE 0x00000020 /* VDDINT supplied externally */
+#define SYSCTRL_INTVOLTAGE 0x00000000 /* VDDINT generated by on-chip regulator */
+#define SYSCTRL_OTPVOLTAGE 0x00000040 /* For Factory Purposes Only */
+#define SYSCTRL_PLLCTL 0x00000100 /* read/write PLL_CTL register */
+#define SYSCTRL_PLLDIV 0x00000200 /* read/write PLL_DIV register */
+#define SYSCTRL_LOCKCNT 0x00000400 /* read/write PLL_LOCKCNT register */
+#define SYSCTRL_PLLSTAT 0x00000800 /* read/write PLL_STAT register */
#ifndef __ASSEMBLY__
+#if BOOTROM_FOLLOWS_C_ABI
+# define BOOTROM_CALLED_FUNC_ATTR
+#else
+# define BOOTROM_CALLED_FUNC_ATTR __attribute__((saveall))
+#endif
+
/* Structures for the syscontrol() function */
typedef struct ADI_SYSCTRL_VALUES {
uint16_t uwVrCtl;
@@ -121,25 +136,26 @@ typedef struct ADI_SYSCTRL_VALUES {
#ifndef _BOOTROM_SYSCONTROL
#define _BOOTROM_SYSCONTROL 0
#endif
-static uint32_t (* const syscontrol)(uint32_t action_flags, ADI_SYSCTRL_VALUES *power_settings, void *reserved) = (void *)_BOOTROM_SYSCONTROL;
-
-#endif /* __ASSEMBLY__ */
-
-/* Possible syscontrol action flags */
-#define SYSCTRL_READ 0x00000000 /* read registers */
-#define SYSCTRL_WRITE 0x00000001 /* write registers */
-#define SYSCTRL_SYSRESET 0x00000002 /* perform system reset */
-#define SYSCTRL_SOFTRESET 0x00000004 /* perform core and system reset */
-#define SYSCTRL_VRCTL 0x00000010 /* read/write VR_CTL register */
-#define SYSCTRL_EXTVOLTAGE 0x00000020 /* VDDINT supplied externally */
-#define SYSCTRL_INTVOLTAGE 0x00000000 /* VDDINT generated by on-chip regulator */
-#define SYSCTRL_OTPVOLTAGE 0x00000040 /* For Factory Purposes Only */
-#define SYSCTRL_PLLCTL 0x00000100 /* read/write PLL_CTL register */
-#define SYSCTRL_PLLDIV 0x00000200 /* read/write PLL_DIV register */
-#define SYSCTRL_LOCKCNT 0x00000400 /* read/write PLL_LOCKCNT register */
-#define SYSCTRL_PLLSTAT 0x00000800 /* read/write PLL_STAT register */
+static uint32_t (* const bfrom_SysControl)(uint32_t action_flags, ADI_SYSCTRL_VALUES *power_settings, void *reserved) = (void *)_BOOTROM_SYSCONTROL;
-#ifndef __ASSEMBLY__
+/* We need a dedicated function since we need to screw with the stack pointer
+ * when resetting. The on-chip ROM will save/restore registers on the stack
+ * when doing a system reset, so the stack cannot be outside of the chip.
+ */
+__attribute__((__noreturn__))
+static inline void bfrom_SoftReset(void *new_stack)
+{
+ while (1)
+ __asm__ __volatile__(
+ "sp = %[stack];"
+ "jump (%[bfrom_syscontrol]);"
+ : : [bfrom_syscontrol] "p"(bfrom_SysControl),
+ "q0"(SYSCTRL_SOFTRESET),
+ "q1"(0),
+ "q2"(NULL),
+ [stack] "p"(new_stack)
+ );
+}
/* Structures for working with LDRs and boot rom callbacks */
typedef struct ADI_BOOT_HEADER {
diff --git a/include/asm-blackfin/mach-common/bits/ebiu.h b/include/asm-blackfin/mach-common/bits/ebiu.h
index ab530ad869e..af456fbe980 100644
--- a/include/asm-blackfin/mach-common/bits/ebiu.h
+++ b/include/asm-blackfin/mach-common/bits/ebiu.h
@@ -410,12 +410,31 @@
/* EBIU_SDSTAT Masks */
#define SDCI 0x0001 /* SDRAM controller is idle */
-#define SDSRA 0x0002 /* SDRAM SDRAM self refresh is active */
+#define SDSRA 0x0002 /* SDRAM self refresh is active */
#define SDPUA 0x0004 /* SDRAM power up active */
#define SDRS 0x0008 /* SDRAM is in reset state */
#define SDEASE 0x0010 /* SDRAM EAB sticky error status - W1C */
#define BGSTAT 0x0020 /* Bus granted */
+/* Only available on DDR based-parts */
+#else
+
+/* EBIU_ERRMST Masks */
+#define DEB0_ERROR 0x0001 /* DEB0 access on reserved memory */
+#define DEB1_ERROR 0x0002 /* DEB1 access on reserved memory */
+#define DEB2_ERROR 0x0004 /* DEB2 (USB) access on reserved memory */
+#define CORE_ERROR 0x0008 /* Core access on reserved memory */
+#define DEB0_MERROR 0x0010 /* DEB0 access on reserved memory and DEB0_ERROR is set */
+#define DEB1_MERROR 0x0020 /* DEB1 access on reserved memory and DEB1_ERROR is set */
+#define DEB2_MERROR 0x0040 /* DEB2 access on reserved memory and DEB2_ERROR is set */
+#define CORE_MERROR 0x0080 /* Core access on reserved memory and CORE_ERROR is set */
+
+/* EBIU_RSTCTL Masks */
+#define DDR_SRESET 0x0001 /* Reset Control to DDR Controller */
+#define SRREQ 0x0008 /* Self Refresh Request */
+#define SRACK 0x0010 /* Self Refresh Request Acknowledgement */
+#define MDDRENABLE 0x0020 /* Mobile DDR Enable */
+
#endif /* EBIU_SDGCTL */
#endif
diff --git a/include/asm-blackfin/mach-common/bits/otp.h b/include/asm-blackfin/mach-common/bits/otp.h
index d529a0a9829..4e3f1afcfa0 100644
--- a/include/asm-blackfin/mach-common/bits/otp.h
+++ b/include/asm-blackfin/mach-common/bits/otp.h
@@ -9,23 +9,22 @@
#include "bootrom.h"
-static uint32_t (* const otp_command)(uint32_t command, uint32_t value) = (void *)_BOOTROM_OTP_COMMAND;
-static uint32_t (* const otp_read)(uint32_t page, uint32_t flags, uint64_t *page_content) = (void *)_BOOTROM_OTP_READ;
-static uint32_t (* const otp_write)(uint32_t page, uint32_t flags, uint64_t *page_content) = (void *)_BOOTROM_OTP_WRITE;
+static uint32_t (* const bfrom_OtpCommand)(uint32_t command, uint32_t value) = (void *)_BOOTROM_OTP_COMMAND;
+static uint32_t (* const bfrom_OtpRead)(uint32_t page, uint32_t flags, uint64_t *page_content) = (void *)_BOOTROM_OTP_READ;
+static uint32_t (* const bfrom_OtpWrite)(uint32_t page, uint32_t flags, uint64_t *page_content) = (void *)_BOOTROM_OTP_WRITE;
#endif
/* otp_command(): defines for "command" */
-#define OTP_INIT 0x00000001
-#define OTP_CLOSE 0x00000002
+#define OTP_INIT 0x00000001
+#define OTP_CLOSE 0x00000002
/* otp_{read,write}(): defines for "flags" */
-#define OTP_LOWER_HALF 0x00000000 /* select upper/lower 64-bit half (bit 0) */
-#define OTP_UPPER_HALF 0x00000001
-#define OTP_NO_ECC 0x00000010 /* do not use ECC */
-#define OTP_LOCK 0x00000020 /* sets page protection bit for page */
-#define OTP_ACCESS_READ 0x00001000
-#define OTP_ACCESS_READWRITE 0x00002000
+#define OTP_LOWER_HALF 0x00000000 /* select upper/lower 64-bit half (bit 0) */
+#define OTP_UPPER_HALF 0x00000001
+#define OTP_NO_ECC 0x00000010 /* do not use ECC */
+#define OTP_LOCK 0x00000020 /* sets page protection bit for page */
+#define OTP_CHECK_FOR_PREV_WRITE 0x00000080
/* Return values for all functions */
#define OTP_SUCCESS 0x00000000
diff --git a/include/configs/bf533-ezkit.h b/include/configs/bf533-ezkit.h
index e871737177a..48c0252e46e 100644
--- a/include/configs/bf533-ezkit.h
+++ b/include/configs/bf533-ezkit.h
@@ -198,7 +198,7 @@
#define I2C_DELAY udelay(5) /* 1/4 I2C clock duration */
#define CONFIG_SYS_I2C_SPEED 50000
-#define CONFIG_SYS_I2C_SLAVE 0xFE
+#define CONFIG_SYS_I2C_SLAVE 0
#define CONFIG_SYS_BOOTM_LEN 0x4000000 /* Large Image Length, set to 64 Meg */
diff --git a/include/configs/bf533-stamp.h b/include/configs/bf533-stamp.h
index 5ad99a2fd49..ee41c7e78f8 100644
--- a/include/configs/bf533-stamp.h
+++ b/include/configs/bf533-stamp.h
@@ -300,7 +300,7 @@
#define I2C_DELAY udelay(5) /* 1/4 I2C clock duration */
#define CONFIG_SYS_I2C_SPEED 50000
-#define CONFIG_SYS_I2C_SLAVE 0xFE
+#define CONFIG_SYS_I2C_SLAVE 0
#endif /* CONFIG_SOFT_I2C */
/*
diff --git a/include/configs/bf537-stamp.h b/include/configs/bf537-stamp.h
index ac5aaa59aed..27567faab28 100644
--- a/include/configs/bf537-stamp.h
+++ b/include/configs/bf537-stamp.h
@@ -305,13 +305,11 @@
/*
* I2C settings
- * By default PF1 is used as SDA and PF0 as SCL on the Stamp board
*/
-/* #define CONFIG_SOFT_I2C 1*/ /* I2C bit-banged */
-#define CONFIG_HARD_I2C 1 /* I2C TWI */
-#if defined CONFIG_HARD_I2C
-#define CONFIG_TWICLK_KHZ 50
-#endif
+#define CONFIG_HARD_I2C 1
+#define CONFIG_BFIN_TWI_I2C 1
+#define CFG_I2C_SPEED 50000
+#define CFG_I2C_SLAVE 0
#define CONFIG_EBIU_SDRRC_VAL 0x306
#define CONFIG_EBIU_SDGCTL_VAL 0x91114d
@@ -321,39 +319,6 @@
#define CONFIG_EBIU_AMBCTL0_VAL 0x7BB07BB0
#define CONFIG_EBIU_AMBCTL1_VAL 0xFFC27BB0
-#if defined CONFIG_SOFT_I2C
-/*
- * Software (bit-bang) I2C driver configuration
- */
-#define PF_SCL PF0
-#define PF_SDA PF1
-
-#define I2C_INIT (*pFIO_DIR |= PF_SCL); asm("ssync;")
-#define I2C_ACTIVE (*pFIO_DIR |= PF_SDA); *pFIO_INEN &= ~PF_SDA; asm("ssync;")
-#define I2C_TRISTATE (*pFIO_DIR &= ~PF_SDA); *pFIO_INEN |= PF_SDA; asm("ssync;")
-#define I2C_READ ((volatile)(*pFIO_FLAG_D & PF_SDA) != 0); asm("ssync;")
-#define I2C_SDA(bit) if(bit) { \
- *pFIO_FLAG_S = PF_SDA; \
- asm("ssync;"); \
- } \
- else { \
- *pFIO_FLAG_C = PF_SDA; \
- asm("ssync;"); \
- }
-#define I2C_SCL(bit) if(bit) { \
- *pFIO_FLAG_S = PF_SCL; \
- asm("ssync;"); \
- } \
- else { \
- *pFIO_FLAG_C = PF_SCL; \
- asm("ssync;"); \
- }
-#define I2C_DELAY udelay(5) /* 1/4 I2C clock duration */
-#endif
-
-#define CONFIG_SYS_I2C_SPEED 50000
-#define CONFIG_SYS_I2C_SLAVE 0xFE
-
/* 0xFF, 0x7BB07BB0, 0x22547BB0 */
/* #define AMGCTLVAL (AMBEN_P0 | AMBEN_P1 | AMBEN_P2 | AMCKEN)
#define AMBCTL0VAL (B1WAT_7 | B1RAT_11 | B1HT_2 | B1ST_3 | B1TT_4 | ~B1RDYPOL | \
diff --git a/include/devices.h b/include/devices.h
index 20ddfc43427..84c4514880e 100644
--- a/include/devices.h
+++ b/include/devices.h
@@ -116,5 +116,8 @@ int drv_usbtty_init (void);
#ifdef CONFIG_NETCONSOLE
int drv_nc_init (void);
#endif
+#ifdef CONFIG_JTAG_CONSOLE
+int drv_jtag_console_init (void);
+#endif
#endif /* _DEVICES_H_ */
diff --git a/include/status_led.h b/include/status_led.h
index 79be6988501..175972a0527 100644
--- a/include/status_led.h
+++ b/include/status_led.h
@@ -346,6 +346,9 @@ void status_led_set (int led, int state);
#elif defined(CONFIG_NIOS2)
/* XXX empty just to avoid the error */
/************************************************************************/
+#elif defined(CONFIG_BLACKFIN)
+/* XXX empty just to avoid the error */
+/************************************************************************/
#elif defined(CONFIG_V38B)
# define STATUS_LED_BIT 0x0010 /* Timer7 GPIO */
diff --git a/lib_blackfin/Makefile b/lib_blackfin/Makefile
index 3f69770d678..fee0fdaca36 100644
--- a/lib_blackfin/Makefile
+++ b/lib_blackfin/Makefile
@@ -37,7 +37,7 @@ SOBJS-y += memmove.o
SOBJS-y += memset.o
COBJS-y += board.o
-COBJS-y += bootm.o
+COBJS-y += boot.o
COBJS-y += cache.o
COBJS-y += muldi3.o
COBJS-y += post.o
diff --git a/lib_blackfin/board.c b/lib_blackfin/board.c
index ddf81442883..01b71d44813 100644
--- a/lib_blackfin/board.c
+++ b/lib_blackfin/board.c
@@ -13,10 +13,10 @@
#include <command.h>
#include <devices.h>
#include <environment.h>
-#include <i2c.h>
#include <malloc.h>
#include <net.h>
#include <timestamp.h>
+#include <status_led.h>
#include <version.h>
#include <asm/cplb.h>
@@ -279,9 +279,13 @@ void board_init_f(ulong bootflag)
dcache_enable();
#endif
+#ifdef DEBUG
+ if (CONFIG_SYS_GBL_DATA_SIZE < sizeof(*gd))
+ hang();
+#endif
serial_early_puts("Init global data\n");
gd = (gd_t *) (CONFIG_SYS_GBL_DATA_ADDR);
- memset((void *)gd, 0, sizeof(gd_t));
+ memset((void *)gd, 0, CONFIG_SYS_GBL_DATA_SIZE);
/* Board data initialization */
addr = (CONFIG_SYS_GBL_DATA_ADDR + sizeof(gd_t));
@@ -331,16 +335,6 @@ void board_init_f(ulong bootflag)
board_init_r((gd_t *) gd, 0x20000010);
}
-#if defined(CONFIG_SOFT_I2C) || defined(CONFIG_HARD_I2C)
-static int init_func_i2c(void)
-{
- puts("I2C: ");
- i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
- puts("ready\n");
- return (0);
-}
-#endif
-
void board_init_r(gd_t * id, ulong dest_addr)
{
extern void malloc_bin_reloc(void);
@@ -356,14 +350,14 @@ void board_init_r(gd_t * id, ulong dest_addr)
#endif
#if !defined(CONFIG_SYS_NO_FLASH)
- /* There are some other pointer constants we must deal with */
- /* configure available FLASH banks */
+ /* Initialize the flash and protect u-boot by default */
extern flash_info_t flash_info[];
ulong size = flash_init();
puts("Flash: ");
print_size(size, "\n");
flash_protect(FLAG_PROTECT_SET, CONFIG_SYS_FLASH_BASE,
- CONFIG_SYS_FLASH_BASE + 0x1ffff, &flash_info[0]);
+ CONFIG_SYS_FLASH_BASE + CONFIG_SYS_MONITOR_LEN - 1,
+ &flash_info[0]);
bd->bi_flashstart = CONFIG_SYS_FLASH_BASE;
bd->bi_flashsize = size;
bd->bi_flashoffset = 0;
@@ -420,6 +414,11 @@ void board_init_r(gd_t * id, ulong dest_addr)
/* Initialize the console (after the relocation and devices init) */
console_init_r();
+#ifdef CONFIG_STATUS_LED
+ status_led_set(STATUS_LED_BOOT, STATUS_LED_BLINKING);
+ status_led_set(STATUS_LED_CRASH, STATUS_LED_OFF);
+#endif
+
/* Initialize from environment */
if ((s = getenv("loadaddr")) != NULL)
load_addr = simple_strtoul(s, NULL, 16);
@@ -442,10 +441,6 @@ void board_init_r(gd_t * id, ulong dest_addr)
bd->bi_enetaddr[3], bd->bi_enetaddr[4], bd->bi_enetaddr[5]);
#endif
-#if defined(CONFIG_SOFT_I2C) || defined(CONFIG_HARD_I2C)
- init_func_i2c();
-#endif
-
display_global_data();
#if defined(CONFIG_POST)
@@ -460,6 +455,10 @@ void board_init_r(gd_t * id, ulong dest_addr)
void hang(void)
{
+#ifdef CONFIG_STATUS_LED
+ status_led_set(STATUS_LED_BOOT, STATUS_LED_OFF);
+ status_led_set(STATUS_LED_CRASH, STATUS_LED_BLINKING);
+#endif
puts("### ERROR ### Please RESET the board ###\n");
while (1)
/* If a JTAG emulator is hooked up, we'll automatically trigger
diff --git a/lib_blackfin/bootm.c b/lib_blackfin/boot.c
index 195eb9c0097..951d5b0d027 100644
--- a/lib_blackfin/bootm.c
+++ b/lib_blackfin/boot.c
@@ -1,5 +1,5 @@
/*
- * U-boot - bootm.c - misc boot helper functions
+ * U-boot - boot.c - misc boot helper functions
*
* Copyright (c) 2005-2008 Analog Devices Inc.
*
@@ -20,17 +20,19 @@ extern void swap_to(int device_id);
static char *make_command_line(void)
{
- char *dest = (char *)CMD_LINE_ADDR;
+ char *dest = (char *)CONFIG_LINUX_CMDLINE_ADDR;
char *bootargs = getenv("bootargs");
if (bootargs == NULL)
return NULL;
- strncpy(dest, bootargs, 0x1000);
- dest[0xfff] = 0;
+ strncpy(dest, bootargs, CONFIG_LINUX_CMDLINE_SIZE);
+ dest[CONFIG_LINUX_CMDLINE_SIZE - 1] = 0;
return dest;
}
+extern ulong bfin_poweron_retx;
+
int do_bootm_linux(int flag, int argc, char *argv[], bootm_headers_t *images)
{
int (*appl) (char *cmdline);
@@ -45,11 +47,16 @@ int do_bootm_linux(int flag, int argc, char *argv[], bootm_headers_t *images)
appl = (int (*)(char *))images->ep;
- printf("Starting Kernel at = %x\n", appl);
+ printf("Starting Kernel at = %p\n", appl);
cmdline = make_command_line();
icache_disable();
dcache_disable();
- (*appl) (cmdline);
+ asm __volatile__(
+ "RETX = %[retx];"
+ "CALL (%0);"
+ :
+ : "p"(appl), "q0"(cmdline), [retx] "d"(bfin_poweron_retx)
+ );
/* does not return */
return 1;
diff --git a/lib_blackfin/string.c b/lib_blackfin/string.c
index 6887c93decd..36eecdff4c5 100644
--- a/lib_blackfin/string.c
+++ b/lib_blackfin/string.c
@@ -1,7 +1,7 @@
/*
* U-boot - string.c Contains library routines.
*
- * Copyright (c) 2005-2007 Analog Devices Inc.
+ * Copyright (c) 2005-2008 Analog Devices Inc.
*
* (C) Copyright 2000-2004
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
@@ -130,12 +130,22 @@ int strncmp(const char *cs, const char *ct, size_t count)
# define bfin_write_MDMA_D0_IRQ_STATUS bfin_write_MDMA1_D0_IRQ_STATUS
# define bfin_read_MDMA_D0_IRQ_STATUS bfin_read_MDMA1_D0_IRQ_STATUS
#endif
-static void *dma_memcpy(void *dst, const void *src, size_t count)
+/* This version misbehaves for count values of 0 and 2^16+.
+ * Perhaps we should detect that ? Nowhere do we actually
+ * use dma memcpy for those types of lengths though ...
+ */
+void dma_memcpy_nocache(void *dst, const void *src, size_t count)
{
- if (dcache_status())
- blackfin_dcache_flush_range(src, src + count);
+ /* Scratchpad cannot be a DMA source or destination */
+ if (((unsigned long)src >= L1_SRAM_SCRATCH &&
+ (unsigned long)src < L1_SRAM_SCRATCH_END) ||
+ ((unsigned long)dst >= L1_SRAM_SCRATCH &&
+ (unsigned long)dst < L1_SRAM_SCRATCH_END))
+ hang();
- bfin_write_MDMA_D0_IRQ_STATUS(DMA_DONE | DMA_ERR);
+ bfin_write_MDMA_S0_CONFIG(0);
+ bfin_write_MDMA_D0_CONFIG(0);
+ bfin_write_MDMA_D0_IRQ_STATUS(DMA_RUN | DMA_DONE | DMA_ERR);
/* Copy sram functions from sdram to sram */
/* Setup destination start address */
@@ -154,20 +164,33 @@ static void *dma_memcpy(void *dst, const void *src, size_t count)
/* Enable source DMA */
bfin_write_MDMA_S0_CONFIG(DMAEN);
- SSYNC();
bfin_write_MDMA_D0_CONFIG(WNR | DMAEN);
+ SSYNC();
while (bfin_read_MDMA_D0_IRQ_STATUS() & DMA_RUN)
- bfin_write_MDMA_D0_IRQ_STATUS(bfin_read_MDMA_D0_IRQ_STATUS() | DMA_DONE | DMA_ERR);
- bfin_write_MDMA_D0_IRQ_STATUS(bfin_read_MDMA_D0_IRQ_STATUS() | DMA_DONE | DMA_ERR);
+ continue;
+
+ bfin_write_MDMA_D0_IRQ_STATUS(bfin_read_MDMA_D0_IRQ_STATUS() | DMA_RUN | DMA_DONE | DMA_ERR);
+ bfin_write_MDMA_D0_CONFIG(0);
+ bfin_write_MDMA_S0_CONFIG(0);
+}
+/* We should do a dcache invalidate on the destination after the dma, but since
+ * we lack such hardware capability, we'll flush/invalidate the destination
+ * before the dma and bank on the idea that u-boot is single threaded.
+ */
+void *dma_memcpy(void *dst, const void *src, size_t count)
+{
+ if (dcache_status()) {
+ blackfin_dcache_flush_range(src, src + count);
+ blackfin_dcache_flush_invalidate_range(dst, dst + count);
+ }
+
+ dma_memcpy_nocache(dst, src, count);
if (icache_status())
blackfin_icache_flush_range(dst, dst + count);
- if (dcache_status())
- blackfin_dcache_invalidate_range(dst, dst + count);
-
return dst;
}