Merge branch 'master' of git://git.denx.de/u-boot-blackfin

This commit is contained in:
Wolfgang Denk 2009-01-28 21:09:32 +01:00
commit ee64d0acc9
50 changed files with 1270 additions and 824 deletions

View File

@ -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

View File

@ -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

View File

@ -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)

View File

@ -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

View File

@ -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

View File

@ -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;
}

View File

@ -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)

View File

@ -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++)

View File

@ -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

167
board/bf533-stamp/video.c Normal file
View File

@ -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);
}

25
board/bf533-stamp/video.h Normal file
View File

@ -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 },
};

View File

@ -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)

View File

@ -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)

View File

@ -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

View File

@ -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");
}

View File

@ -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,

View File

@ -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)

View File

@ -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;
}

View File

@ -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);

View File

@ -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'));

View File

@ -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)
{
bool force = false;
if (!strcmp(argv[1], "--force")) {
force = true;
argv[1] = argv[0];
argv++;
--argc;
/* 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)
{
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");

View File

@ -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);
}

View File

@ -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))

View File

@ -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)

View File

@ -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);

View File

@ -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 */

View File

@ -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

125
cpu/blackfin/jtag-console.c Normal file
View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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);

View File

@ -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;

View File

@ -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;

View File

@ -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

285
drivers/i2c/bfin-twi_i2c.c Normal file
View File

@ -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);
}

View File

@ -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 */

View File

@ -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

View File

@ -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

View File

@ -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;
static uint32_t (* const bfrom_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 */
#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 {

View File

@ -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

View File

@ -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

View File

@ -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 */

View File

@ -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 */
/*

View File

@ -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 | \

View File

@ -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_ */

View File

@ -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 */

View File

@ -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

View File

@ -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

View File

@ -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;

View File

@ -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;
}