Merge branch 'master' of git://git.denx.de/u-boot-blackfin
This commit is contained in:
commit
ee64d0acc9
2
Makefile
2
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
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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)
|
||||
|
@ -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++)
|
||||
|
@ -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
167
board/bf533-stamp/video.c
Normal 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
25
board/bf533-stamp/video.h
Normal 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 },
|
||||
};
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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");
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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'));
|
||||
|
163
common/cmd_otp.c
163
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)
|
||||
{
|
||||
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");
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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))
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
|
@ -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 */
|
@ -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
125
cpu/blackfin/jtag-console.c
Normal 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
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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
285
drivers/i2c/bfin-twi_i2c.c
Normal 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);
|
||||
}
|
@ -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 */
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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 {
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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 */
|
||||
|
||||
|
@ -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 */
|
||||
|
||||
/*
|
||||
|
@ -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 | \
|
||||
|
@ -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_ */
|
||||
|
@ -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 */
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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;
|
@ -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;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user