diff options
Diffstat (limited to 'board/bf533-stamp')
-rw-r--r-- | board/bf533-stamp/Makefile | 58 | ||||
-rw-r--r-- | board/bf533-stamp/bf533-stamp.c | 276 | ||||
-rw-r--r-- | board/bf533-stamp/bf533-stamp.h | 56 | ||||
-rw-r--r-- | board/bf533-stamp/config.mk | 25 | ||||
-rw-r--r-- | board/bf533-stamp/spi.c | 473 | ||||
-rw-r--r-- | board/bf533-stamp/u-boot.lds.S | 152 |
6 files changed, 1040 insertions, 0 deletions
diff --git a/board/bf533-stamp/Makefile b/board/bf533-stamp/Makefile new file mode 100644 index 0000000000..8223d591ce --- /dev/null +++ b/board/bf533-stamp/Makefile @@ -0,0 +1,58 @@ +# +# U-boot - Makefile +# +# Copyright (c) 2007 Analog Device Inc. +# +# (C) Copyright 2000-2006 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# See file CREDITS for list of people who contributed to this +# project. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# + +include $(TOPDIR)/config.mk + +LIB = $(obj)lib$(BOARD).a + +COBJS := $(BOARD).o spi.o + +SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) +OBJS := $(addprefix $(obj),$(COBJS)) +SOBJS := $(addprefix $(obj),$(SOBJS)) + +$(LIB): $(obj).depend $(OBJS) $(SOBJS) u-boot.lds + $(AR) $(ARFLAGS) $@ $(OBJS) $(SOBJS) + +u-boot.lds: u-boot.lds.S + $(CPP) $(CPPFLAGS) -P -Ubfin $^ > $@.tmp + mv -f $@.tmp $@ + +clean: + rm -f $(SOBJS) $(OBJS) + +distclean: clean + rm -f $(LIB) core *.bak .depend + +######################################################################### + +# defines $(obj).depend target +include $(SRCTREE)/rules.mk + +sinclude $(obj).depend + +######################################################################### diff --git a/board/bf533-stamp/bf533-stamp.c b/board/bf533-stamp/bf533-stamp.c new file mode 100644 index 0000000000..2f6e75187b --- /dev/null +++ b/board/bf533-stamp/bf533-stamp.c @@ -0,0 +1,276 @@ +/* + * U-boot - stamp.c STAMP board specific routines + * + * Copyright (c) 2005 blackfin.uclinux.org + * + * (C) Copyright 2000-2004 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <common.h> +#include <asm/mem_init.h> +#include <asm/io.h> +#include "bf533-stamp.h" + +#define STATUS_LED_OFF 0 +#define STATUS_LED_ON 1 + +#ifdef CONFIG_SHOW_BOOT_PROGRESS +# define SHOW_BOOT_PROGRESS(arg) show_boot_progress(arg) +#else +# define SHOW_BOOT_PROGRESS(arg) +#endif + +int checkboard(void) +{ +#if (BFIN_CPU == ADSP_BF531) + printf("CPU: ADSP BF531 Rev.: 0.%d\n", *pCHIPID >> 28); +#elif (BFIN_CPU == ADSP_BF532) + printf("CPU: ADSP BF532 Rev.: 0.%d\n", *pCHIPID >> 28); +#else + printf("CPU: ADSP BF533 Rev.: 0.%d\n", *pCHIPID >> 28); +#endif + printf("Board: ADI BF533 Stamp board\n"); + printf(" Support: http://blackfin.uclinux.org/\n"); + return 0; +} + +long int initdram(int board_type) +{ + DECLARE_GLOBAL_DATA_PTR; +#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", CFG_SDRAM_BASE); + printf("Bank size = %d MB\n", 128); +#endif + gd->bd->bi_memstart = CFG_SDRAM_BASE; + gd->bd->bi_memsize = CFG_MAX_RAM_SIZE; + return (gd->bd->bi_memsize); +} + +void swap_to(int device_id) +{ + + if (device_id == ETHERNET) { + *pFIO_DIR = PF0; + sync(); + *pFIO_FLAG_S = PF0; + sync(); + } 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); + sync(); + } else { + printf("Unknown bank to switch\n"); + } + + return; +} + +#if defined(CONFIG_MISC_INIT_R) +/* miscellaneous platform dependent initialisations */ +int misc_init_r(void) +{ + int i; + int cf_stat = 0; + + /* Check whether CF card is inserted */ + *pFIO_EDGE = FIO_EDGE_CF_BITS; + *pFIO_POLAR = FIO_POLAR_CF_BITS; + for (i = 0; i < 0x300; i++) + asm("nop;"); + + if ((*pFIO_FLAG_S) & CF_STAT_BITS) { + cf_stat = 0; + } else { + cf_stat = 1; + } + + *pFIO_EDGE = FIO_EDGE_BITS; + *pFIO_POLAR = FIO_POLAR_BITS; + + 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++) + asm("nop;"); + for (i = 0; i < 0x1000; i++) + asm("nop;"); + + serial_setbrg(); + ide_init(); + + setenv("bootargs", ""); + setenv("bootcmd", + "fatload ide 0:1 0x1000000 uImage-stamp;bootm 0x1000000;bootm 0x20100000"); + } else { + printf("Booting from FLASH\n"); + } + + return 0; +} +#endif + +#ifdef CONFIG_STAMP_CF + +void cf_outb(unsigned char val, volatile unsigned char *addr) +{ + /* + * Set PF1 PF0 respectively to 0 1 to divert address + * to the expansion memory banks + */ + *pFIO_FLAG_S = CF_PF0; + *pFIO_FLAG_C = CF_PF1; + sync(); + + *(addr) = val; + sync(); + + /* Setback PF1 PF0 to 0 0 to address external + * memory banks */ + *(volatile unsigned short *)pFIO_FLAG_C = CF_PF1_PF0; + sync(); +} + +unsigned char cf_inb(volatile unsigned char *addr) +{ + volatile unsigned char c; + + *pFIO_FLAG_S = CF_PF0; + *pFIO_FLAG_C = CF_PF1; + sync(); + + c = *(addr); + sync(); + + *pFIO_FLAG_C = CF_PF1_PF0; + sync(); + + return c; +} + +void cf_insw(unsigned short *sect_buf, unsigned short *addr, int words) +{ + int i; + + *pFIO_FLAG_S = CF_PF0; + *pFIO_FLAG_C = CF_PF1; + sync(); + + for (i = 0; i < words; i++) { + *(sect_buf + i) = *(addr); + sync(); + } + + *pFIO_FLAG_C = CF_PF1_PF0; + sync(); +} + +void cf_outsw(unsigned short *addr, unsigned short *sect_buf, int words) +{ + int i; + + *pFIO_FLAG_S = CF_PF0; + *pFIO_FLAG_C = CF_PF1; + sync(); + + for (i = 0; i < words; i++) { + *(addr) = *(sect_buf + i); + sync(); + } + + *pFIO_FLAG_C = CF_PF1_PF0; + sync(); +} +#endif + +void stamp_led_set(int LED1, int LED2, int LED3) +{ + *pFIO_INEN &= ~(PF2 | PF3 | PF4); + *pFIO_DIR |= (PF2 | PF3 | PF4); + + if (LED1 == STATUS_LED_OFF) + *pFIO_FLAG_S = PF2; + else + *pFIO_FLAG_C = PF2; + if (LED2 == STATUS_LED_OFF) + *pFIO_FLAG_S = PF3; + else + *pFIO_FLAG_C = PF3; + if (LED3 == STATUS_LED_OFF) + *pFIO_FLAG_S = PF4; + else + *pFIO_FLAG_C = PF4; + sync(); +} + +void show_boot_progress(int status) +{ + switch (status) { + case 1: + stamp_led_set(STATUS_LED_OFF, STATUS_LED_OFF, STATUS_LED_ON); + break; + case 2: + stamp_led_set(STATUS_LED_OFF, STATUS_LED_ON, STATUS_LED_OFF); + break; + case 3: + stamp_led_set(STATUS_LED_OFF, STATUS_LED_ON, STATUS_LED_ON); + break; + case 4: + stamp_led_set(STATUS_LED_ON, STATUS_LED_OFF, STATUS_LED_OFF); + break; + case 5: + case 6: + stamp_led_set(STATUS_LED_ON, STATUS_LED_OFF, STATUS_LED_ON); + break; + case 7: + case 8: + stamp_led_set(STATUS_LED_ON, STATUS_LED_ON, STATUS_LED_OFF); + break; + case 9: + case 10: + case 11: + case 12: + case 13: + case 14: + case 15: + stamp_led_set(STATUS_LED_OFF, STATUS_LED_OFF, STATUS_LED_OFF); + break; + default: + stamp_led_set(STATUS_LED_ON, STATUS_LED_ON, STATUS_LED_ON); + break; + } +} diff --git a/board/bf533-stamp/bf533-stamp.h b/board/bf533-stamp/bf533-stamp.h new file mode 100644 index 0000000000..b2b51aa2ba --- /dev/null +++ b/board/bf533-stamp/bf533-stamp.h @@ -0,0 +1,56 @@ +/* + * U-boot - stamp.h + * + * Copyright (c) 2005 blackfin.uclinux.org + * + * (C) Copyright 2000-2004 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#ifndef __STAMP_H__ +#define __STAMP_H__ + +extern void init_Flags(void); + +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 +#define FIO_EDGE_BITS 0x1E0 +#define FIO_POLAR_BITS 0x160 + +/* Compact flash status bits in status register */ +#define CF_STAT_BITS 0x00000060 + +/* CF Flags used to switch between expansion and external + * memory banks + */ +#define CF_PF0 0x0001 +#define CF_PF1 0x0002 +#define CF_PF1_PF0 0x0003 + +#endif diff --git a/board/bf533-stamp/config.mk b/board/bf533-stamp/config.mk new file mode 100644 index 0000000000..113438b4ff --- /dev/null +++ b/board/bf533-stamp/config.mk @@ -0,0 +1,25 @@ +# +# (C) Copyright 2001 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# See file CREDITS for list of people who contributed to this +# project. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# +# TEXT_BASE should be defined as the MAX_SDRAM Address - 256k bytes +# 256k is defined as CFG_MONITOR_LEN in ./include/configs/<board>.h +TEXT_BASE = 0x07FC0000 diff --git a/board/bf533-stamp/spi.c b/board/bf533-stamp/spi.c new file mode 100644 index 0000000000..d30750faa3 --- /dev/null +++ b/board/bf533-stamp/spi.c @@ -0,0 +1,473 @@ +/**************************************************************************** + * SPI flash driver for M25P64 + ****************************************************************************/ +#include <common.h> +#include <linux/ctype.h> +#include <asm/io.h> + +#if defined(CONFIG_SPI) + + /*Application definitions */ + +#define NUM_SECTORS 128 /* number of sectors */ +#define SECTOR_SIZE 0x10000 +#define NOP_NUM 1000 + +#define COMMON_SPI_SETTINGS (SPE|MSTR|CPHA|CPOL) /*Settings to the SPI_CTL */ +#define TIMOD01 (0x01) /*stes the SPI to work with core instructions */ + + /*Flash commands */ +#define SPI_WREN (0x06) /*Set Write Enable Latch */ +#define SPI_WRDI (0x04) /*Reset Write Enable Latch */ +#define SPI_RDSR (0x05) /*Read Status Register */ +#define SPI_WRSR (0x01) /*Write Status Register */ +#define SPI_READ (0x03) /*Read data from memory */ +#define SPI_PP (0x02) /*Program Data into memory */ +#define SPI_SE (0xD8) /*Erase one sector in memory */ +#define SPI_BE (0xC7) /*Erase all memory */ +#define WIP (0x1) /*Check the write in progress bit of the SPI status register */ +#define WEL (0x2) /*Check the write enable bit of the SPI status register */ + +#define TIMEOUT 350000000 + +typedef enum { + NO_ERR, + POLL_TIMEOUT, + INVALID_SECTOR, + INVALID_BLOCK, +} ERROR_CODE; + +void spi_init_f(void); +void spi_init_r(void); +ssize_t spi_read(uchar *, int, uchar *, int); +ssize_t spi_write(uchar *, int, uchar *, int); + +char ReadStatusRegister(void); +void Wait_For_SPIF(void); +void SetupSPI(const int spi_setting); +void SPI_OFF(void); +void SendSingleCommand(const int iCommand); + +ERROR_CODE GetSectorNumber(unsigned long ulOffset, int *pnSector); +ERROR_CODE EraseBlock(int nBlock); +ERROR_CODE ReadData(unsigned long ulStart, long lCount, int *pnData); +ERROR_CODE WriteData(unsigned long ulStart, long lCount, int *pnData); +ERROR_CODE Wait_For_Status(char Statusbit); +ERROR_CODE Wait_For_WEL(void); + +/* ------------------- + * Variables + * ------------------- */ + +/* ************************************************************************** + * + * Function: spi_init_f + * + * Description: Init SPI-Controller (ROM part) + * + * return: --- + * + * *********************************************************************** */ +void spi_init_f(void) +{ +} + +/* ************************************************************************** + * + * Function: spi_init_r + * + * Description: Init SPI-Controller (RAM part) - + * The malloc engine is ready and we can move our buffers to + * normal RAM + * + * return: --- + * + * *********************************************************************** */ +void spi_init_r(void) +{ + return; +} + +/**************************************************************************** + * Function: spi_write + **************************************************************************** */ +ssize_t spi_write(uchar * addr, int alen, uchar * buffer, int len) +{ + unsigned long offset; + int start_block, end_block; + int start_byte, end_byte; + ERROR_CODE result = NO_ERR; + uchar temp[SECTOR_SIZE]; + int i, num; + + offset = addr[0] << 16 | addr[1] << 8 | addr[2]; + /* Get the start block number */ + result = GetSectorNumber(offset, &start_block); + if (result == INVALID_SECTOR) { + printf("Invalid sector! "); + return 0; + } + /* Get the end block number */ + result = GetSectorNumber(offset + len - 1, &end_block); + if (result == INVALID_SECTOR) { + printf("Invalid sector! "); + return 0; + } + + for (num = start_block; num <= end_block; num++) { + ReadData(num * SECTOR_SIZE, SECTOR_SIZE, (int *)temp); + start_byte = num * SECTOR_SIZE; + end_byte = (num + 1) * SECTOR_SIZE - 1; + if (start_byte < offset) + start_byte = offset; + if (end_byte > (offset + len)) + end_byte = (offset + len - 1); + for (i = start_byte; i <= end_byte; i++) + temp[i - num * SECTOR_SIZE] = buffer[i - offset]; + EraseBlock(num); + result = WriteData(num * SECTOR_SIZE, SECTOR_SIZE, (int *)temp); + if (result != NO_ERR) + return 0; + printf("."); + } + return len; +} + +/**************************************************************************** + * Function: spi_read + **************************************************************************** */ +ssize_t spi_read(uchar * addr, int alen, uchar * buffer, int len) +{ + unsigned long offset; + offset = addr[0] << 16 | addr[1] << 8 | addr[2]; + ReadData(offset, len, (int *)buffer); + return len; +} + +void SendSingleCommand(const int iCommand) +{ + unsigned short dummy; + + /*turns on the SPI in single write mode */ + SetupSPI((COMMON_SPI_SETTINGS | TIMOD01)); + + /*sends the actual command to the SPI TX register */ + *pSPI_TDBR = iCommand; + sync(); + + /*The SPI status register will be polled to check the SPIF bit */ + Wait_For_SPIF(); + + dummy = *pSPI_RDBR; + + /*The SPI will be turned off */ + SPI_OFF(); + +} + +void SetupSPI(const int spi_setting) +{ + + if (icache_status() || dcache_status()) + udelay(CONFIG_CCLK_HZ / 50000000); + /*sets up the PF2 to be the slave select of the SPI */ + *pSPI_FLG = 0xFB04; + *pSPI_BAUD = CONFIG_SPI_BAUD; + *pSPI_CTL = spi_setting; + sync(); +} + +void SPI_OFF(void) +{ + + *pSPI_CTL = 0x0400; /* disable SPI */ + *pSPI_FLG = 0; + *pSPI_BAUD = 0; + sync(); + udelay(CONFIG_CCLK_HZ / 50000000); + +} + +void Wait_For_SPIF(void) +{ + unsigned short dummyread; + while ((*pSPI_STAT & TXS)) ; + while (!(*pSPI_STAT & SPIF)) ; + while (!(*pSPI_STAT & RXS)) ; + dummyread = *pSPI_RDBR; /* Read dummy to empty the receive register */ + +} + +ERROR_CODE Wait_For_WEL(void) +{ + int i; + char status_register = 0; + ERROR_CODE ErrorCode = NO_ERR; /* tells us if there was an error erasing flash */ + + for (i = 0; i < TIMEOUT; i++) { + status_register = ReadStatusRegister(); + if ((status_register & WEL)) { + ErrorCode = NO_ERR; /* tells us if there was an error erasing flash */ + break; + } + ErrorCode = POLL_TIMEOUT; /* Time out error */ + }; + + return ErrorCode; +} + +ERROR_CODE Wait_For_Status(char Statusbit) +{ + int i; + char status_register = 0xFF; + ERROR_CODE ErrorCode = NO_ERR; /* tells us if there was an error erasing flash */ + + for (i = 0; i < TIMEOUT; i++) { + status_register = ReadStatusRegister(); + if (!(status_register & Statusbit)) { + ErrorCode = NO_ERR; /* tells us if there was an error erasing flash */ + break; + } + ErrorCode = POLL_TIMEOUT; /* Time out error */ + }; + + return ErrorCode; +} + +char ReadStatusRegister(void) +{ + char status_register = 0; + + SetupSPI((COMMON_SPI_SETTINGS | TIMOD01)); /* Turn on the SPI */ + + *pSPI_TDBR = SPI_RDSR; /* send instruction to read status register */ + sync(); + Wait_For_SPIF(); /*wait until the instruction has been sent */ + *pSPI_TDBR = 0; /*send dummy to receive the status register */ + sync(); + Wait_For_SPIF(); /*wait until the data has been sent */ + status_register = *pSPI_RDBR; /*read the status register */ + + SPI_OFF(); /* Turn off the SPI */ + + return status_register; +} + +ERROR_CODE GetSectorNumber(unsigned long ulOffset, int *pnSector) +{ + int nSector = 0; + ERROR_CODE ErrorCode = NO_ERR; + + if (ulOffset > (NUM_SECTORS * 0x10000 - 1)) { + ErrorCode = INVALID_SECTOR; + return ErrorCode; + } + + nSector = (int)ulOffset / 0x10000; + *pnSector = nSector; + + /* ok */ + return ErrorCode; +} + +ERROR_CODE EraseBlock(int nBlock) +{ + unsigned long ulSectorOff = 0x0, ShiftValue; + ERROR_CODE ErrorCode = NO_ERR; + + /* if the block is invalid just return */ + if ((nBlock < 0) || (nBlock > NUM_SECTORS)) { + ErrorCode = INVALID_BLOCK; /* tells us if there was an error erasing flash */ + return ErrorCode; + } + /* figure out the offset of the block in flash */ + if ((nBlock >= 0) && (nBlock < NUM_SECTORS)) { + ulSectorOff = (nBlock * SECTOR_SIZE); + + } else { + ErrorCode = INVALID_BLOCK; /* tells us if there was an error erasing flash */ + return ErrorCode; + } + + /* A write enable instruction must previously have been executed */ + SendSingleCommand(SPI_WREN); + + /*The status register will be polled to check the write enable latch "WREN" */ + ErrorCode = Wait_For_WEL(); + + if (POLL_TIMEOUT == ErrorCode) { + printf("SPI Erase block error\n"); + return ErrorCode; + } else + /*Turn on the SPI to send single commands */ + SetupSPI((COMMON_SPI_SETTINGS | TIMOD01)); + + /* Send the erase block command to the flash followed by the 24 address */ + /* to point to the start of a sector. */ + *pSPI_TDBR = SPI_SE; + sync(); + Wait_For_SPIF(); + ShiftValue = (ulSectorOff >> 16); /* Send the highest byte of the 24 bit address at first */ + *pSPI_TDBR = ShiftValue; + sync(); + Wait_For_SPIF(); /* Wait until the instruction has been sent */ + ShiftValue = (ulSectorOff >> 8); /* Send the middle byte of the 24 bit address at second */ + *pSPI_TDBR = ShiftValue; + sync(); + Wait_For_SPIF(); /* Wait until the instruction has been sent */ + *pSPI_TDBR = ulSectorOff; /* Send the lowest byte of the 24 bit address finally */ + sync(); + Wait_For_SPIF(); /* Wait until the instruction has been sent */ + + /*Turns off the SPI */ + SPI_OFF(); + + /* Poll the status register to check the Write in Progress bit */ + /* Sector erase takes time */ + ErrorCode = Wait_For_Status(WIP); + + /* block erase should be complete */ + return ErrorCode; +} + +/***************************************************************************** +* ERROR_CODE ReadData() +* +* Read a value from flash for verify purpose +* +* Inputs: unsigned long ulStart - holds the SPI start address +* int pnData - pointer to store value read from flash +* long lCount - number of elements to read +***************************************************************************** */ +ERROR_CODE ReadData(unsigned long ulStart, long lCount, int *pnData) +{ + unsigned long ShiftValue; + char *cnData; + int i; + + cnData = (char *)pnData; /* Pointer cast to be able to increment byte wise */ + + /* Start SPI interface */ + SetupSPI((COMMON_SPI_SETTINGS | TIMOD01)); + + *pSPI_TDBR = SPI_READ; /* Send the read command to SPI device */ + sync(); + Wait_For_SPIF(); /* Wait until the instruction has been sent */ + ShiftValue = (ulStart >> 16); /* Send the highest byte of the 24 bit address at first */ + *pSPI_TDBR = ShiftValue; /* Send the byte to the SPI device */ + sync(); + Wait_For_SPIF(); /* Wait until the instruction has been sent */ + ShiftValue = (ulStart >> 8); /* Send the middle byte of the 24 bit address at second */ + *pSPI_TDBR = ShiftValue; /* Send the byte to the SPI device */ + sync(); + Wait_For_SPIF(); /* Wait until the instruction has been sent */ + *pSPI_TDBR = ulStart; /* Send the lowest byte of the 24 bit address finally */ + sync(); + Wait_For_SPIF(); /* Wait until the instruction has been sent */ + + /* After the SPI device address has been placed on the MOSI pin the data can be */ + /* received on the MISO pin. */ + for (i = 0; i < lCount; i++) { + *pSPI_TDBR = 0; /*send dummy */ + sync(); + while (!(*pSPI_STAT & RXS)) ; + *cnData++ = *pSPI_RDBR; /*read */ + + if ((i >= SECTOR_SIZE) && (i % SECTOR_SIZE == 0)) + printf("."); + } + + SPI_OFF(); /* Turn off the SPI */ + + return NO_ERR; +} + +ERROR_CODE WriteFlash(unsigned long ulStartAddr, long lTransferCount, + int *iDataSource, long *lWriteCount) +{ + + unsigned long ulWAddr; + long lWTransferCount = 0; + int i; + char iData; + char *temp = (char *)iDataSource; + ERROR_CODE ErrorCode = NO_ERR; /* tells us if there was an error erasing flash */ + + /* First, a Write Enable Command must be sent to the SPI. */ + SendSingleCommand(SPI_WREN); + + /* Second, the SPI Status Register will be tested whether the */ + /* Write Enable Bit has been set. */ + ErrorCode = Wait_For_WEL(); + if (POLL_TIMEOUT == ErrorCode) { + printf("SPI Write Time Out\n"); + return ErrorCode; + } else + /* Third, the 24 bit address will be shifted out the SPI MOSI bytewise. */ + SetupSPI((COMMON_SPI_SETTINGS | TIMOD01)); /* Turns the SPI on */ + *pSPI_TDBR = SPI_PP; + sync(); + Wait_For_SPIF(); /*wait until the instruction has been sent */ + ulWAddr = (ulStartAddr >> 16); + *pSPI_TDBR = ulWAddr; + sync(); + Wait_For_SPIF(); /*wait until the instruction has been sent */ + ulWAddr = (ulStartAddr >> 8); + *pSPI_TDBR = ulWAddr; + sync(); + Wait_For_SPIF(); /*wait until the instruction has been sent */ + ulWAddr = ulStartAddr; + *pSPI_TDBR = ulWAddr; + sync(); + Wait_For_SPIF(); /*wait until the instruction has been sent */ + /* Fourth, maximum number of 256 bytes will be taken from the Buffer */ + /* and sent to the SPI device. */ + for (i = 0; (i < lTransferCount) && (i < 256); i++, lWTransferCount++) { + iData = *temp; + *pSPI_TDBR = iData; + sync(); + Wait_For_SPIF(); /*wait until the instruction has been sent */ + temp++; + } + + SPI_OFF(); /* Turns the SPI off */ + + /* Sixth, the SPI Write in Progress Bit must be toggled to ensure the */ + /* programming is done before start of next transfer. */ + ErrorCode = Wait_For_Status(WIP); + + if (POLL_TIMEOUT == ErrorCode) { + printf("SPI Program Time out!\n"); + return ErrorCode; + } else + + *lWriteCount = lWTransferCount; + + return ErrorCode; +} + +ERROR_CODE WriteData(unsigned long ulStart, long lCount, int *pnData) +{ + + unsigned long ulWStart = ulStart; + long lWCount = lCount, lWriteCount; + long *pnWriteCount = &lWriteCount; + + ERROR_CODE ErrorCode = NO_ERR; + + while (lWCount != 0) { + ErrorCode = WriteFlash(ulWStart, lWCount, pnData, pnWriteCount); + + /* After each function call of WriteFlash the counter must be adjusted */ + lWCount -= *pnWriteCount; + + /* Also, both address pointers must be recalculated. */ + ulWStart += *pnWriteCount; + pnData += *pnWriteCount / 4; + } + + /* return the appropriate error code */ + return ErrorCode; +} + +#endif /* CONFIG_SPI */ diff --git a/board/bf533-stamp/u-boot.lds.S b/board/bf533-stamp/u-boot.lds.S new file mode 100644 index 0000000000..03ef72b609 --- /dev/null +++ b/board/bf533-stamp/u-boot.lds.S @@ -0,0 +1,152 @@ +/* + * U-boot - u-boot.lds.S + * + * Copyright (c) 2005-2007 Analog Device Inc. + * + * (C) Copyright 2000-2004 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <config.h> + +OUTPUT_ARCH(bfin) +SEARCH_DIR(/lib); SEARCH_DIR(/usr/lib); SEARCH_DIR(/usr/local/lib); +/* Do we need any of these for elf? + __DYNAMIC = 0; */ +SECTIONS +{ + /* Read-only sections, merged into text segment: */ + . = + SIZEOF_HEADERS; + .interp : { *(.interp) } + .hash : { *(.hash) } + .dynsym : { *(.dynsym) } + .dynstr : { *(.dynstr) } + .rel.text : { *(.rel.text) } + .rela.text : { *(.rela.text) } + .rel.data : { *(.rel.data) } + .rela.data : { *(.rela.data) } + .rel.rodata : { *(.rel.rodata) } + .rela.rodata : { *(.rela.rodata) } + .rel.got : { *(.rel.got) } + .rela.got : { *(.rela.got) } + .rel.ctors : { *(.rel.ctors) } + .rela.ctors : { *(.rela.ctors) } + .rel.dtors : { *(.rel.dtors) } + .rela.dtors : { *(.rela.dtors) } + .rel.bss : { *(.rel.bss) } + .rela.bss : { *(.rela.bss) } + .rel.plt : { *(.rel.plt) } + .rela.plt : { *(.rela.plt) } + .init : { *(.init) } + .plt : { *(.plt) } + . = CFG_MONITOR_BASE; + .text : + { + /* WARNING - the following is hand-optimized to fit within */ + /* the sector before the environment sector. If it throws */ + /* an error during compilation remove an object here to get */ + /* it linked after the configuration sector. */ + + cpu/bf533/start.o (.text) + cpu/bf533/start1.o (.text) + cpu/bf533/traps.o (.text) + cpu/bf533/interrupt.o (.text) + cpu/bf533/serial.o (.text) + common/dlmalloc.o (.text) +/* lib_blackfin/bf533_string.o (.text) */ +/* lib_generic/vsprintf.o (.text) */ + lib_generic/crc32.o (.text) +/* lib_generic/zlib.o (.text) */ +/* board/stamp/stamp.o (.text) */ + + . = DEFINED(env_offset) ? env_offset : .; + common/environment.o (.text) + + *(.text) + *(.fixup) + *(.got1) + } + _etext = .; + PROVIDE (etext = .); + .rodata : + { + *(.rodata) + *(.rodata1) + *(.rodata.str1.4) + } + .fini : { *(.fini) } =0 + .ctors : { *(.ctors) } + .dtors : { *(.dtors) } + + /* Read-write section, merged into data segment: */ + . = (. + 0x00FF) & 0xFFFFFF00; + _erotext = .; + PROVIDE (erotext = .); + .reloc : + { + *(.got) + _GOT2_TABLE_ = .; + *(.got2) + _FIXUP_TABLE_ = .; + *(.fixup) + } + __got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >>2; + __fixup_entries = (. - _FIXUP_TABLE_)>>2; + + .data : + { + *(.data) + *(.data1) + *(.sdata) + *(.sdata2) + *(.dynamic) + CONSTRUCTORS + } + _edata = .; + PROVIDE (edata = .); + + ___u_boot_cmd_start = .; + .u_boot_cmd : { *(.u_boot_cmd) } + ___u_boot_cmd_end = .; + + + __start___ex_table = .; + __ex_table : { *(__ex_table) } + __stop___ex_table = .; + + . = ALIGN(256); + __init_begin = .; + .text.init : { *(.text.init) } + .data.init : { *(.data.init) } + . = ALIGN(256); + __init_end = .; + + __bss_start = .; + .bss : + { + *(.sbss) *(.scommon) + *(.dynbss) + *(.bss) + *(COMMON) + } + _end = . ; + PROVIDE (end = .); +} |