summaryrefslogtreecommitdiff
path: root/cleopatre/u-boot-1.1.6
diff options
context:
space:
mode:
authordraskovic2009-07-15 09:37:21 +0000
committerdraskovic2009-07-15 09:37:21 +0000
commit5d60ffc9a92e328c446cb516a6880c4376c8eb67 (patch)
tree42a22c0dfd90d0911960ca0596f8664b208c4634 /cleopatre/u-boot-1.1.6
parentee47edfc35fb3546b5975476ffea7be89fb55c22 (diff)
[CLEO][U-BOOT]Malika has only SPI flash, deleted flash_gen. Change in nvram detection in C files - we have nvram addr in gd stuct now.
git-svn-id: svn+ssh://pessac/svn/cesar/trunk@4956 017c9cb6-072f-447c-8318-d5b54f68fe89
Diffstat (limited to 'cleopatre/u-boot-1.1.6')
-rw-r--r--cleopatre/u-boot-1.1.6/board/arizona/sdram_init.S11
-rw-r--r--cleopatre/u-boot-1.1.6/board/malika/Makefile2
-rw-r--r--cleopatre/u-boot-1.1.6/board/malika/flash.c2290
-rw-r--r--cleopatre/u-boot-1.1.6/common/cmd_spidboot.c1
-rw-r--r--cleopatre/u-boot-1.1.6/cpu/spc300-fcm3/start.S8
-rw-r--r--cleopatre/u-boot-1.1.6/cpu/spc300/pll_init.S16
-rw-r--r--cleopatre/u-boot-1.1.6/cpu/spc300/start.S16
-rw-r--r--cleopatre/u-boot-1.1.6/include/configs/arizona.h10
-rw-r--r--cleopatre/u-boot-1.1.6/lib_arm/board.c70
9 files changed, 1844 insertions, 580 deletions
diff --git a/cleopatre/u-boot-1.1.6/board/arizona/sdram_init.S b/cleopatre/u-boot-1.1.6/board/arizona/sdram_init.S
index d9f42ae6e9..94686cbf88 100644
--- a/cleopatre/u-boot-1.1.6/board/arizona/sdram_init.S
+++ b/cleopatre/u-boot-1.1.6/board/arizona/sdram_init.S
@@ -48,7 +48,7 @@ sdram_init:
ldr r1, = -1
.Lsect:
- add r1, r1, #1
+ add r1, r1, #1 /* r1 = 0 */
cmp r1, #LAST_SECTOR
bge .Lnotfound
mov r0, r1, lsl #16 @ r0= r1<<16 = r1*0x10000
@@ -64,23 +64,24 @@ sdram_init:
bne .Lsect @ nvram not found in this sector
.Lfound:
/* NVRAM found on begining of the sector, addr kept in r0 */
+ mov r10, r0 /* store NVRAM addr to r10 */
ldr r1, =SDRAM_CTRL_BASE
/* SCONR */
- ldr r2, [r0, #12] @ load SCONR content from NVRAM
+ ldr r2, [r0, #20] @ load SCONR content from NVRAM
str r2, [r1, #0x00] @ store configuration to config reg
/* STMG0R */
- ldr r2, [r0, #16] @ load STMG0R content from NVRAM
+ ldr r2, [r0, #24] @ load STMG0R content from NVRAM
str r2, [r1, #0x04] @ store configuration to config reg
/* STMG1R */
- ldr r2, [r0, #20] @ load STMG1R content from NVRAM
+ ldr r2, [r0, #28] @ load STMG1R content from NVRAM
str r2, [r1, #0x08] @ store configuration to config reg
/* SREFR */
- ldr r2, [r0, #24] @ load SREFR content from NVRAM
+ ldr r2, [r0, #32] @ load SREFR content from NVRAM
str r2, [r1, #0x10] @ store configuration to config reg
/* reinitialize SDRAM for changes to take effect */
diff --git a/cleopatre/u-boot-1.1.6/board/malika/Makefile b/cleopatre/u-boot-1.1.6/board/malika/Makefile
index 5c3dbe37fe..250801227c 100644
--- a/cleopatre/u-boot-1.1.6/board/malika/Makefile
+++ b/cleopatre/u-boot-1.1.6/board/malika/Makefile
@@ -21,7 +21,7 @@ include $(TOPDIR)/config.mk
LIB = lib$(BOARD).a
-OBJS := malika.o flash.o flash_spi.o flash_gen.o
+OBJS := malika.o flash.o
SOBJS := lowlevel_init.o platform.o
$(LIB): $(OBJS) $(SOBJS)
diff --git a/cleopatre/u-boot-1.1.6/board/malika/flash.c b/cleopatre/u-boot-1.1.6/board/malika/flash.c
index 8fea15ede7..d64d32c66f 100644
--- a/cleopatre/u-boot-1.1.6/board/malika/flash.c
+++ b/cleopatre/u-boot-1.1.6/board/malika/flash.c
@@ -1,495 +1,1795 @@
-/*
- * board/malika/flash.c
- *
- * Copyright (C) 2009 SPiDCOM Technologies
- *
- * 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>
-
-ulong myflush(void);
-
-
-/* Flash Organization Structure */
-typedef struct OrgDef
-{
- unsigned int sector_number;
- unsigned int sector_size;
-} OrgDef;
-
-
-OrgDef OrgS29GL064MR4[] =
-{
- { 8, 8*1024 }, /* 8 * 8 kBytes sectors */
- { 127, 64*1024 }, /* 127 * 64 kBytes sectors */
-};
-
-
-
-
-extern flash_info_t flash_info[]; /* info for FLASH chips */
-
-
-#define FLASH_CODE1 (unsigned char)(0xAA)
-#define FLASH_CODE2 (unsigned char)(0x55)
-#define ID_IN_CODE (unsigned char)(0x90)
-#define ID_OUT_CODE (unsigned char)(0xF0)
-
-
-#define CMD_READ_ARRAY (unsigned char)(0xF0)
-#define CMD_UNLOCK1 (unsigned char)(0xAA)
-#define CMD_UNLOCK2 (unsigned char)(0x55)
-#define CMD_ERASE_SETUP (unsigned char)(0x80)
-#define CMD_ERASE_CONFIRM (unsigned char)(0x30)
-#define CMD_PROGRAM (unsigned char)(0xA0)
-#define CMD_UNLOCK_BYPASS (unsigned char)(0x20)
-#define CMD_SECTOR_UNLOCK (unsigned char)(0x70)
-#define CMD_BUST (unsigned char)(0xc0)
-#define CMD_BUST_ENABLE (unsigned char)(0x01)
-#define CMD_BUST_DISABLE (unsigned char)(0x00)
-
-
-#define MEM_FLASH_ADDR1 (*(volatile unsigned char *)(CFG_FLASH_BASE + (0x00000AAA)))
-#define MEM_FLASH_ADDR2 (*(volatile unsigned char *)(CFG_FLASH_BASE + (0x00000555)))
-
-#define BIT_ERASE_DONE 0x00000080
-#define BIT_RDY_MASK 0x00000080
-#define BIT_PROGRAM_ERROR 0x00000020
-#define BIT_TIMEOUT 0x80000000 /* our flag */
-
-#define READY 0x00000001
-#define ERR 0x00000002
-#define TMO 0x00000004
-
-
-#define S29GL064MR4_ID 0x7E
-
-int ERROR_FLASH = 0;
-
-void seterr_flash(int val)
-{
- ERROR_FLASH = val;
-
-}
-
-
-/**
- * Function: flash_identification
- * Parameters: flash_info_t * info
- * Purpose: Identify flash information
- * Return Value: void
- */
-void flash_identification (flash_info_t * info)
-{
- volatile unsigned char manuf_code, device_code;
-
-
- MEM_FLASH_ADDR1 = ID_OUT_CODE;
-
- MEM_FLASH_ADDR1 = FLASH_CODE1;
- MEM_FLASH_ADDR2 = FLASH_CODE2;
- MEM_FLASH_ADDR1 = ID_IN_CODE;
-
- manuf_code = *(volatile unsigned char *) CFG_FLASH_BASE;
- device_code = *(volatile unsigned char *) (CFG_FLASH_BASE + 2);
-
-
- MEM_FLASH_ADDR1 = ID_OUT_CODE;
-
- if ( device_code == S29GL064MR4_ID) {
- printf ("S29GL064MR4 (64Mbit)\n");
- info->flash_id = S29GL064MR4_ID;
- }
-} /* flash_identification */
-
-/**
- * Function: flash_number_sector
- * Parameters: OrgDef *pOrgDef, unsigned int nb_blocks
- * Purpose: Determine the number of sector
- * Return Value: ushort
- */
-ushort flash_number_sector(OrgDef *pOrgDef, unsigned int nb_blocks)
-{
- int i, nb_sectors = 0;
-
- for (i=0; i<nb_blocks; i++){
- nb_sectors += pOrgDef[i].sector_number;
- }
-
- return nb_sectors;
-} /* flash_number_sector */
-
-/**
- * Function: flash_unlock_sector
- * Parameters: flash_info_t * info, unsigned int sector
- * Purpose: Unlock a sector
- * Return Value: void
- */
-void flash_unlock_sector(flash_info_t * info, unsigned int sector)
-{
- volatile u16 *addr = (volatile u16 *) (info->start[sector]);
-
- MEM_FLASH_ADDR1 = CMD_UNLOCK1;
- *addr = CMD_SECTOR_UNLOCK;
-} /* flash_number_sector */
-
-/**
- * Function: flash_init_std
- * Parameters: void
- * Purpose: Init flash
- * Return Value: ulong
- */
-ulong flash_init_std (void)
-{
- int i, j, k;
- unsigned int flash_nb_blocks, sector;
- unsigned int start_address;
- OrgDef *pOrgDef;
-
- ulong size = 0;
-
- for (i = 0; i < CFG_MAX_FLASH_BANKS; i++) {
- ulong flashbase = 0;
-
- flash_identification (&flash_info[i]);
-
- if ( flash_info[i].flash_id == S29GL064MR4_ID) {
-
- pOrgDef = OrgS29GL064MR4;
- flash_nb_blocks = sizeof (OrgS29GL064MR4) / sizeof (OrgDef);
- }
- else {
- flash_nb_blocks = 0;
- printf ("No standard flash recognized\n");
- return(size);
- }
-
- flash_info[i].sector_count = flash_number_sector(pOrgDef, flash_nb_blocks);
- memset (flash_info[i].protect, 0, flash_info[i].sector_count);
-
- if (i == 0)
- flashbase = PHYS_FLASH_1;
- else
- panic ("configured too many flash banks!\n");
-
- sector = 0;
- start_address = flashbase;
- flash_info[i].size = 0;
-
- for (j = 0; j < flash_nb_blocks; j++) {
- for (k = 0; k < pOrgDef[j].sector_number; k++) {
- flash_info[i].start[sector++] = start_address;
- start_address += pOrgDef[j].sector_size;
- flash_info[i].size += pOrgDef[j].sector_size;
- }
- }
-
- size += flash_info[i].size;
- }
-
- /* Protect binary boot image */
- flash_protect (FLAG_PROTECT_SET,
- CFG_FLASH_BASE,
- CFG_FLASH_BASE + CFG_BOOT_SIZE - 1, &flash_info[0]);
-
-#if 0
- /* Protect U-Boot gzipped image */
- flash_protect (FLAG_PROTECT_SET,
- CFG_U_BOOT_BASE,
- CFG_U_BOOT_BASE + CFG_U_BOOT_SIZE - 1, &flash_info[0]);
-#endif
-
- return size;
-} /* flash_init_std */
-
-
-/**
- * Function: flash_print_info_std
- * Parameters: flash_info_t * info
- * Purpose: Get flash info
- * Return Value: void
- */
-void flash_print_info_std (flash_info_t * info)
-{
- int i;
-
- switch (info->flash_id ) {
- case (S29GL064MR4_ID):
- printf ("SPANSION : flash S29GL064MR4 8bit ");
-
- break;
- default:
- printf ("Unknown Vendor ");
- goto Done;
- break;
- }
-
-
- printf (" Size: %ld MB in %d Sectors\n",
- info->size >> 20, info->sector_count);
-
- printf (" Sector Start Addresses:");
- for (i = 0; i < info->sector_count; i++) {
- if ((i % 5) == 0) {
- printf ("\n ");
- }
- printf (" %08lX%s", info->start[i],
- info->protect[i] ? " (RO)" : " ");
- }
- printf ("\n");
-
-Done: ;
-} /* flash_print_info_std */
-
-/**
- * Function: flash_erase_std
- * Parameters: flash_info_t * info, int s_first, int s_last
- * Purpose: Erase flash
- * Return Value: int
- */
-int flash_erase_std (flash_info_t * info, int s_first, int s_last)
-{
- ulong result;
- int iflag, cflag, prot, sect;
- int rc = ERR_OK;
- int chip1;
- static ulong timeStart; /* Time base value */
-
- /* first look for protection bits */
-
- if (info->flash_id == FLASH_UNKNOWN)
- {
- seterr_flash(ERR_UNKNOWN_FLASH_TYPE);
- return ERR_UNKNOWN_FLASH_TYPE;
- } /* if */
-
- if ((s_first < 0) || (s_first > s_last)) {
- seterr_flash(ERR_INVAL);
- return ERR_INVAL;
- } /* if */
-
- prot = 0;
- for (sect = s_first; sect <= s_last; ++sect) {
- if (info->protect[sect]) {
- prot++;
- } /* if */
- } /* for */
- if (prot)
- {
- seterr_flash(ERR_PROTECTED);
- return ERR_PROTECTED;
- } /* if */
-
- /*
- * Disable interrupts which might cause a timeout
- * here. Remember that our exception vectors are
- * at address 0 in the flash, and we don't want a
- * (ticker) exception to happen while the flash
- * chip is in programming mode.
- */
- cflag = icache_status ();
- icache_disable ();
- iflag = disable_interrupts ();
-
- /* Start erase on unprotected sectors */
- for (sect = s_first; sect <= s_last && !ctrlc (); sect++) {
- printf ("Erasing sector %2d ... ", sect);
-
- /* arm simple, non interrupt dependent timer */
- reset_timer_masked ();
- timeStart = get_timer(0);
-
- if (info->protect[sect] == 0) { /* not protected */
- volatile unsigned char *addr = (volatile unsigned char *) (info->start[sect]);
-
- MEM_FLASH_ADDR1 = CMD_UNLOCK1;
- MEM_FLASH_ADDR2 = CMD_UNLOCK2;
- MEM_FLASH_ADDR1 = CMD_ERASE_SETUP;
-
- MEM_FLASH_ADDR1 = CMD_UNLOCK1;
- MEM_FLASH_ADDR2 = CMD_UNLOCK2;
- *addr = CMD_ERASE_CONFIRM;
-
- /* wait until flash is ready */
- chip1 = 0;
-
- do {
- result = *addr;
-
- /* check timeout */
- if (get_timer(timeStart) > CFG_FLASH_ERASE_TOUT) {
- MEM_FLASH_ADDR1 = CMD_READ_ARRAY;
- chip1 = TMO;
- break;
- } /* if */
-
- if (!chip1 && (result & 0x80))
- chip1 = READY;
-
- } while (!chip1); /* do ... while */
-
- MEM_FLASH_ADDR1 = CMD_READ_ARRAY;
-
- if (chip1 == TMO) {
- seterr_flash(ERR_TIMOUT);
- rc = ERR_TIMOUT;
- goto outahere;
- } /* if */
-
- printf ("ok.\n");
- } else { /* it was protected */
- printf ("protected!\n");
- } /* if */
- } /* for */
-
- if (ctrlc ())
- printf ("User Interrupt!\n");
-
-outahere:
- /* allow flash to settle - wait 10 ms */
- udelay_masked (10000);
-
- if (iflag)
- enable_interrupts ();
-
- if (cflag)
- icache_enable ();
-
- return rc;
-} /* flash_erase_std */
-
-
-/**
- * Function: write_int
- * Parameters: flash_info_t * info, ulong dest,ulong data
- * Purpose: TBD
- * Return Value: int
- */
-volatile static int write_char (flash_info_t * info, ulong dest,unsigned char data)
-{
- volatile unsigned char *addr = (volatile unsigned char *) dest;
- unsigned char result;
- int rc = ERR_OK;
- int chip1;
- static ulong timeStart; /* Time base value */
-
- /*
- * Check if Flash is (sufficiently) erased
- */
- result = *addr;
- if ((result & data) != data)
- {
- printf("result = 0x%x, data = 0x%x \n",result,data);
- printf("addr = 0x%x \n",addr);
- seterr_flash(ERR_NOT_ERASED);
- return ERR_NOT_ERASED;
- }
-
-
- MEM_FLASH_ADDR1 = CMD_UNLOCK1;
- MEM_FLASH_ADDR2 = CMD_UNLOCK2;
- MEM_FLASH_ADDR1 = CMD_PROGRAM;
- *addr = data;
-
- /* arm simple, non interrupt dependent timer */
- timeStart = get_timer(0);
-
- /* wait until flash is ready */
- chip1 = 0;
- do {
- result = *addr;
-
- /* check timeout */
- if ( get_timer(timeStart) > CFG_FLASH_ERASE_TOUT ) {
- chip1 = ERR | TMO;
- break;
- }
- if (!chip1 && ((result & 0x80) == (data & 0x80)) )
- chip1 = READY;
-
- } while (!chip1); /* do ... while */
-
-// *addr = CMD_READ_ARRAY;
-
- if (chip1 == ERR || *addr != data)
- {
- rc = ERR_PROG_ERROR;
- seterr_flash(rc);
- } /* if */
-
-
- return rc;
-} /* write_int */
-
-
-/**
- * Function: write_buff_std
- * Parameters: flash_info_t * info, uchar * src, ulong addr, ulong cnt
- * Purpose: Write buffer
- * Return Value: int
- */
-int write_buff_std (flash_info_t * info, uchar * src, ulong addr, ulong cnt)
-{
- ulong wp;
- unsigned char data;
- int rc;
- int lenght = cnt;
- int kprint = 0;
- int cflag, iflag;
-
- wp = addr;
-
-
- /*
- * Disable interrupts which might cause a timeout
- * here. Remember that our exception vectors are
- * at address 0 in the flash, and we don't want a
- * (ticker) exception to happen while the flash
- * chip is in programming mode.
- */
- cflag = icache_status ();
- icache_disable ();
- iflag = disable_interrupts ();
-
- while (lenght > 0) {
- data = *((volatile unsigned char *) src);
- if ((rc = write_char (info, wp, data)) != 0) {
- return (rc);
- }
- src ++;
- wp ++;
- lenght --;
- kprint ++;
- if(kprint >= 10240)
- {
- kprint = 0;
- printf(".");
- }
-
- } /* while */
-
-
-
- if (iflag)
- enable_interrupts ();
-
- if (cflag)
- icache_enable ();
-
-
- return ERR_OK;
-} /* write_buff_std */
+/*
+ * board/malika/flash_spi.c
+ *
+ * Copyright (C) 2009 SPiDCOM Technologies
+ *
+ * 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
+ *
+ * Author(s):
+ * Drasko DRASKOVIC, drasko.draskovic@spidcom.com
+ */
+
+#include <common.h>
+#include <malloc.h>
+
+//#define DEBUG_FLASH_SPI
+
+/* Flash Organization Structure */
+typedef struct OrgDef
+{
+ unsigned int sector_number;
+ unsigned int sector_size;
+} OrgDef;
+
+OrgDef OrgS25FL064A[] =
+{
+ { 127, 64*1024 }, /* 127 * 64 kBytes sectors */
+};
+
+flash_info_t flash_info[CFG_MAX_FLASH_BANKS]; /* info for FLASH chips */
+ENV_SECTOR_SIZE = 0;
+
+
+/* OPCODES (all one byte long for Spansion S25FL064A SPI Flash */
+
+/* write */
+#define READ (unsigned char)(0x03) /* Read Data Bytes */
+#define FAST_READ (unsigned char)(0x0B) /* Read Data Bytes at Higher Speed */
+#define RDID (unsigned char)(0x9F) /* Read Identification */
+
+/* write */
+#define WREN (unsigned char)(0x06) /* Write Enable */
+#define WRDI (unsigned char)(0x04) /* Write Disable */
+
+/* erase */
+#define SE (unsigned char)(0xD8) /* Sector Erase */
+#define BE (unsigned char)(0xC7) /* Bulk (Chip) Erase */
+
+/* program */
+#define PP (unsigned char)(0x02) /* Page Program */
+
+/* Status Register */
+#define RDSR (unsigned char)(0x05) /* Read from Status Register */
+#define WRSR (unsigned char)(0x01) /* Write to Status Register */
+
+/* Status Register bits. */
+#define SR_WIP 0x01 /* Write in progress */
+#define SR_WEL 0x02 /* Write enable latch */
+#define SR_BP0 0x04 /* Block protect 0 */
+#define SR_BP1 0x08 /* Block protect 1 */
+#define SR_BP2 0x10 /* Block protect 2 */
+#define SR_SRWD 0x80 /* SR write protect */
+
+
+
+/* SPC300 SPI Controller registers */
+#define SPI_CTL_MASTER_SLAVE_REG ( *( (volatile unsigned int *)(CFG_FLASH_SPI_BASE + 0x00) ) )
+#define SPI_CTL_CONTROL_CONFIG_REG ( *( (volatile unsigned int *)(CFG_FLASH_SPI_BASE + 0x04) ) )
+#define SPI_CTL_FREQ_REG ( *( (volatile unsigned int *)(CFG_FLASH_SPI_BASE + 0x08) ) )
+#define SPI_CTL_CONF_TX ( *( (volatile unsigned int *)(CFG_FLASH_SPI_BASE + 0x10) ) )
+#define SPI_CTL_CONF_RX ( *( (volatile unsigned int *)(CFG_FLASH_SPI_BASE + 0x14) ) )
+#define SPI_CTL_CS_LATENCY ( *( (volatile unsigned int *)(CFG_FLASH_SPI_BASE + 0x18) ) )
+#define SPI_CTL_TX_REG ( *( (volatile unsigned int *)(CFG_FLASH_SPI_BASE + 0x20) ) )
+#define SPI_CTL_RX_REG ( *( (volatile unsigned int *)(CFG_FLASH_SPI_BASE + 0x24) ) )
+#define SPI_CTL_MASK_REG ( *( (volatile unsigned int *)(CFG_FLASH_SPI_BASE + 0x34) ) )
+#define SPI_CTL_STATUS_REG ( *( (volatile unsigned int *)(CFG_FLASH_SPI_BASE + 0x38) ) )
+
+/* status bits */
+enum
+{
+ EMPTY_FIFO_TX = 0x01,
+ FULL_FIFO_TX = 0x02,
+ EMPTY_FIFO_RX = 0x04,
+ FULL_FIFO_RX = 0x08,
+ RECEIVED_WORD = 0x10,
+ BUSY_MASTER = 0x20
+};
+
+
+#define S25FL064A_ID 0x7F
+
+#define READY_SPI 0x00000001
+#define ERR_SPI 0x00000002
+#define TMO_SPI 0x00000004
+
+int ERROR_FLASH_SPI = 0;
+
+int flash_read_status_spi(unsigned char *flash_spi_status);
+int flash_read_id_spi(unsigned int *flash_spi_id);
+
+void swap_endians (int *in)
+{
+ *in = (
+ ( (*in & 0xFF000000) >> 24 ) |
+ ( (*in & 0x00FF0000) >> 8 ) |
+ ( (*in & 0x0000FF00) << 8 ) |
+ ( (*in & 0x000000FF) << 24 )
+ );
+}
+
+
+void seterr_flash_spi(int val)
+{
+ ERROR_FLASH_SPI = val;
+}
+
+/**
+ * Function: init_spi_controller
+ * Parameters:
+ * Purpose: Initialize SPI controller to use SPI flash
+ * Return Value: ushort
+ */
+void init_spi_controller(void)
+{
+ //printf("Initializing SPI controller...\n");
+
+ SPI_CTL_MASTER_SLAVE_REG = 0x01; /* Master */
+ SPI_CTL_CONTROL_CONFIG_REG = 0x00; /* 3 wires Master */
+ SPI_CTL_FREQ_REG = 0x00; /* 12.5 Mhz (MARIA_MASTER_CLOCK/2) */
+ SPI_CTL_CS_LATENCY = 0x20; /* 32 cycle clock AHB */
+ SPI_CTL_CONF_TX = 0x00010008; /* send one byte (i.e. one word of lenght of 8 bits) */
+ SPI_CTL_CONF_RX = 0x00010008; /* receive one byte */
+ SPI_CTL_MASK_REG = 0x0; /* mask all interrupts */
+}
+
+
+/**
+ * Function: flash_read_id_spi
+ * Parameters: none
+ * Purpose: Read flash id
+ * Return Value: int
+ */
+int flash_read_id_spi(unsigned int *flash_spi_id)
+{
+ int rc = ERR_OK;
+ unsigned long nowtime;
+
+ /* do not reset timer, because this function
+ might be called from another which already
+ checks timer. This would clobber the result
+ for the caller. Rather use delta time */
+ nowtime = get_timer(0);
+
+ /* poll until Tx and Rx FIFOs are empty
+ and SPI bus is not busy
+ to be sure that no other transmissoin is in progress */
+ while (
+ ( (SPI_CTL_STATUS_REG & EMPTY_FIFO_TX) == 0 ) ||
+ ( (SPI_CTL_STATUS_REG & EMPTY_FIFO_RX) == 0 ) ||
+ ( (SPI_CTL_STATUS_REG & BUSY_MASTER) != 0 )
+ )
+ {
+ /* check timeout */
+ if ( get_timer(nowtime) > SPI_CTL_TMO )
+ {
+ seterr_flash_spi(ERR_TIMOUT);
+ rc = ERR_TIMOUT;
+ return rc;
+ } /* if */
+ }
+
+ /* read spi flash status reg */
+ SPI_CTL_CONF_TX = 0x00010008; /* send one byte */
+ SPI_CTL_CONF_RX = 0x00010018; /* receive 3 bytes */
+ /*issue the command to spi flash */
+ SPI_CTL_TX_REG = RDID;
+
+ /* busy wait for RECEIVED_WORD bit in status reg */
+ nowtime = get_timer(0);
+ while ( (SPI_CTL_STATUS_REG & RECEIVED_WORD) == 0 )
+ {
+ /* check timeout */
+ if ( get_timer(nowtime) > SPI_CTL_TMO )
+ {
+ seterr_flash_spi(ERR_TIMOUT);
+ rc = ERR_TIMOUT;
+ return rc;
+ } /* if */
+ } /* while */
+
+ /* flash spi status is now in SPI Controller Rx reg */
+
+ *flash_spi_id = SPI_CTL_RX_REG;
+
+ return rc;
+}
+
+/**
+ * Function: flash_identification
+ * Parameters: flash_info_t * info
+ * Purpose: Identify flash information
+ * Return Value: void
+ */
+void flash_spi_identification (flash_info_t * info)
+{
+ //volatile unsigned char manuf_code;
+ volatile unsigned char device_code;
+
+
+ // manuf_code = *(volatile unsigned char *) CFG_FLASH_BASE;
+ // device_code = *(volatile unsigned char *) (CFG_FLASH_BASE + 2);
+ // shold be readed from the flash, for now just hardcoded
+
+ device_code = S25FL064A_ID;
+
+ if ( device_code == S25FL064A_ID) {
+ printf ("S25FL064A_ID (64Mbit SPI Flash)\n");
+ info->flash_id = S25FL064A_ID;
+ }
+ else
+ {
+ // TBD
+ }
+
+} /* flash_spi_identification */
+
+/**
+ * Function: flash_spi_number_sector
+ * Parameters: OrgDef *pOrgDef, unsigned int nb_blocks
+ * Purpose: Determine the number of sector
+ * Return Value: ushort
+ */
+ushort flash_number_sector_spi(OrgDef *pOrgDef, unsigned int nb_blocks)
+{
+ int i, nb_sectors = 0;
+
+ for (i=0; i<nb_blocks; i++)
+ nb_sectors += pOrgDef[i].sector_number;
+
+ return nb_sectors;
+} /* flash_spi_number_sector */
+
+/**
+ * Function: flash_init
+ * Parameters: void
+ * Purpose: Init flash
+ * Return Value: ulong
+ */
+ulong flash_init (void)
+{
+ int i, j, k;
+ unsigned int flash_nb_blocks, sector;
+ unsigned int start_address;
+ OrgDef *pOrgDef;
+
+ ulong size = 0;
+
+ /* initialize our SPI controler */
+ init_spi_controller();
+
+ for (i = 0; i < CFG_MAX_FLASH_SPI_BANKS; i++)
+ {
+ ulong flashbase = 0;
+
+ flash_spi_identification (&flash_info[i]);
+
+ if ( flash_info[i].flash_id == S25FL064A_ID)
+ {
+ pOrgDef = OrgS25FL064A;
+ flash_nb_blocks = sizeof (OrgS25FL064A) / sizeof (OrgDef);
+ }
+ else
+ {
+ flash_nb_blocks = 0;
+ printf ("No standard flash recognized\n");
+ return(size);
+ }
+
+ flash_info[i].sector_count = flash_number_sector_spi(pOrgDef, flash_nb_blocks);
+ memset (flash_info[i].protect, 0, flash_info[i].sector_count);
+
+ if (i == 0)
+ flashbase = PHYS_FLASH_SPI_1;
+ else
+ panic ("configured too many flash banks!\n");
+
+ sector = 0;
+ start_address = flashbase;
+ flash_info[i].size = 0;
+
+ for (j = 0; j < flash_nb_blocks; j++)
+ {
+ for (k = 0; k < pOrgDef[j].sector_number; k++)
+ {
+ flash_info[i].start[sector++] = start_address;
+ start_address += pOrgDef[j].sector_size;
+ flash_info[i].size += pOrgDef[j].sector_size;
+ }
+ }
+
+ size += flash_info[i].size;
+ }
+
+ if(size == 0)
+ {
+ printf ("No flash recognised ...\n");
+ }
+ while((flash_info[0].start[i] != CFG_ENV_ADDR) && (i<flash_info[0].sector_count))
+ i++;
+
+ ENV_SECTOR_SIZE = flash_info[0].start[i+1] - flash_info[0].start[i];
+
+ return size;
+
+} /* flash_init */
+
+/**
+ * Function: flash_print_info
+ * Parameters: flash_info_t * info
+ * Purpose: Get flash info
+ * Return Value: void
+ */
+void flash_print_info (flash_info_t * info)
+{
+ int i;
+
+ switch (info->flash_id ) {
+ case (S25FL064A_ID):
+ printf ("SPANSION : flash spi S25FL064A_ID (64 Mbit)");
+ break;
+ default:
+ printf ("Unknown Vendor ");
+ goto Done;
+ break;
+ }
+
+
+ printf (" Size: %ld MB in %d Sectors\n",
+ info->size >> 20, info->sector_count);
+
+ printf (" Sector Start Addresses:");
+ for (i = 0; i < info->sector_count; i++) {
+ if ((i % 5) == 0) {
+ printf ("\n ");
+ }
+ printf (" %08lX%s", info->start[i],
+ info->protect[i] ? " (RO)" : " ");
+ }
+ printf ("\n");
+
+Done: ;
+} /* flash_print_info */
+
+/**
+ * Function: flash_read_status_spi
+ * Parameters: unsigned char *flash_spi_status
+ * Purpose: read from flash status register
+ * Return Value: int
+ */
+int flash_read_status_spi(unsigned char *flash_spi_status)
+{
+ int rc = ERR_OK;
+ unsigned long nowtime;
+
+ /* do not reset timer, because this function
+ might be called from another which already
+ checks timer. This would clobber the result
+ for the caller. Rather use delta time */
+ nowtime = get_timer(0);
+
+ /* poll until Tx and Rx FIFOs are empty
+ and SPI bus is not busy
+ to be sure that no other transmissoin is in progress */
+ while (
+ ( (SPI_CTL_STATUS_REG & EMPTY_FIFO_TX) == 0 ) ||
+ ( (SPI_CTL_STATUS_REG & EMPTY_FIFO_RX) == 0 ) ||
+ ( (SPI_CTL_STATUS_REG & BUSY_MASTER) != 0 )
+ )
+ {
+ /* check timeout */
+ if ( get_timer(nowtime) > SPI_CTL_TMO )
+ {
+ seterr_flash_spi(ERR_TIMOUT);
+ rc = ERR_TIMOUT;
+ return rc;
+ } /* if */
+ }
+
+ /* read spi flash status reg */
+ SPI_CTL_CONF_TX = 0x00010008; /* send one byte */
+ SPI_CTL_CONF_RX = 0x00010008; /* receive one byte */
+ /*issue the command to spi flash */
+ SPI_CTL_TX_REG = RDSR;
+
+ /* busy wait for RECEIVED_WORD bit in status reg */
+ nowtime = get_timer(0);
+ while ( (SPI_CTL_STATUS_REG & RECEIVED_WORD) == 0 )
+ {
+ /* check timeout */
+ if ( get_timer(nowtime) > SPI_CTL_TMO )
+ {
+ seterr_flash_spi(ERR_TIMOUT);
+ rc = ERR_TIMOUT;
+ return rc;
+ } /* if */
+ } /* while */
+
+ /* flash spi status is now in SPI Controller Rx reg */
+ *flash_spi_status = SPI_CTL_RX_REG;
+
+ return rc;
+}
+
+
+/**
+ * Function: flash_write_enable_spi
+ * Parameters: int s_first, int s_last
+ * Purpose: WREN command to the SPI Flash
+ * Return Value: int
+ */
+int flash_write_enable_spi (void)
+{
+ int rc = ERR_OK;
+ unsigned long nowtime;
+
+ nowtime = get_timer(0);
+ /* poll until Tx and Rx FIFOs are empty
+ and SPI bus is not busy
+ to be sure that no other transmissoin is in progress */
+ while (
+ ( (SPI_CTL_STATUS_REG & EMPTY_FIFO_TX) == 0 ) ||
+ ( (SPI_CTL_STATUS_REG & BUSY_MASTER) != 0 )
+ )
+ {
+ /* check timeout */
+ if ( get_timer(nowtime) > SPI_CTL_TMO)
+ {
+ seterr_flash_spi(ERR_TIMOUT);
+ rc = ERR_TIMOUT;
+ return rc;
+ } /* if */
+ } /* while */
+
+ /* write enable spi flash */
+ SPI_CTL_CONF_TX = 0x00010008; /* send one byte (just command) */
+ /* reset SPI_CTL_CONF_RX - no bytes expected to be received.
+ This step is needed because it will not be
+ auto-reset from the previous operaton */
+ SPI_CTL_CONF_RX = 0x00000008;
+ /*issue the command to spi flash */
+ SPI_CTL_TX_REG = WREN;
+
+ nowtime = get_timer(0);
+ /* poll until Tx FIFO is empty
+ and SPI bus is not busy
+ to be sure that our transmission finished */
+ while (
+ ( (SPI_CTL_STATUS_REG & EMPTY_FIFO_TX) == 0 ) ||
+ ( (SPI_CTL_STATUS_REG & BUSY_MASTER) != 0 )
+ )
+ {
+ /* check timeout */
+ if ( get_timer(nowtime) > SPI_CTL_TMO)
+ {
+ seterr_flash_spi(ERR_TIMOUT);
+ rc = ERR_TIMOUT;
+ return rc;
+ } /* if */
+ }
+
+ return rc;
+}
+
+/**
+ * Function: flash_erase
+ * Parameters: int s_first, int s_last
+ * Purpose: Erase flash
+ * Return Value: int
+ */
+int flash_erase (flash_info_t * info, int s_first, int s_last)
+{
+ int iflag, cflag, prot, sect;
+ int rc = ERR_OK;
+ int chip1;
+ unsigned char flash_spi_status;
+ int low_protected_addr = 0;
+ int erase_flash_spi_command = 0;
+ unsigned long nowtime;
+
+ /* first look for protection bits */
+ if ((s_first < 0) || (s_first > s_last))
+ {
+ seterr_flash_spi(ERR_INVAL);
+ return ERR_INVAL;
+ } /* if */
+
+
+ prot = 0;
+ if ( flash_read_status_spi(&flash_spi_status) == ERR_TIMOUT )
+ {
+ rc = ERR_TIMOUT;
+ return rc;
+ }
+ /* there are 8 variants of protection,
+ see Spanson datasheet */
+ prot = (flash_spi_status & 0x1C) >> 2;
+ if (prot != 0)
+ {
+ /* determine which part is protected */
+ int part = 64;
+ part >>= (prot + 1);
+ low_protected_addr = 0x800000 - (0x800000 / part);
+ if (info->start[s_last] > low_protected_addr)
+ {
+ seterr_flash_spi(ERR_PROTECTED);
+ return ERR_PROTECTED;
+ } /* if */
+ }
+
+ /*
+ * Disable interrupts which might cause a timeout
+ * here. Remember that our exception vectors are
+ * at address 0 in the flash, and we don't want a
+ * (ticker) exception to happen while the flash
+ * chip is in programming mode.
+ */
+ cflag = icache_status ();
+ icache_disable ();
+ iflag = disable_interrupts ();
+
+ putc('\n');
+
+ /* Start erase on unprotected sectors */
+ for (sect = s_first; sect <= s_last && !ctrlc (); sect++)
+ {
+ printf ("Erasing sector %2d ... ", sect);
+
+ if (info->protect[sect] == 0)
+ {
+ /* not protected */
+ volatile unsigned char *addr = (volatile unsigned char *) (info->start[sect]);
+
+ /* mask MSB byte, i.e. set it to all-zero */
+ addr = (volatile unsigned char *) ( (unsigned int)addr & ~(0xFF << 24) );
+ erase_flash_spi_command = SE<<24 | (unsigned int)addr;
+
+ swap_endians(&erase_flash_spi_command);
+
+ /* before erase we have to write-enable SPI flash */
+ if ( flash_write_enable_spi() == ERR_TIMOUT )
+ {
+ printf ("Cannot write-enable SPI flash.\n");
+ seterr_flash_spi(ERR_TIMOUT);
+ rc = ERR_TIMOUT;
+ goto outahere;
+ }
+
+ /* arm simple, non interrupt dependent timer */
+ nowtime = get_timer(0);
+ /* poll until Tx FIFO is empty
+ and SPI bus is not busy
+ to be sure that no other transmissions are in progress */
+ while (
+ ( (SPI_CTL_STATUS_REG & EMPTY_FIFO_TX) == 0 ) ||
+ ( (SPI_CTL_STATUS_REG & BUSY_MASTER) != 0 )
+ )
+ {
+ /* check timeout */
+ if (get_timer(nowtime) > SPI_CTL_TMO)
+ {
+ seterr_flash_spi(ERR_TIMOUT);
+ rc = ERR_TIMOUT;
+ goto outahere;
+ } /* if */
+ }
+ /* start command SPI controller seqence */
+ SPI_CTL_CONF_TX = 0x00010020; /* send 32 bit message (command + address) */
+ /* reset SPI_CTL_CONF_RX - no bytes expected to be received.
+ This step is needed because it will not be
+ auto-reset from the previous operaton */
+ SPI_CTL_CONF_RX = 0x00000000;
+ /*issue the command to spi flash */
+ SPI_CTL_TX_REG = erase_flash_spi_command; /* send command + address to SPI flash via SPI controller */
+
+ /* busy wait for transaction to finish (poll status reg) */
+ nowtime = get_timer(0);
+ /* poll until Tx FIFO is empty
+ and SPI bus is not busy
+ to be sure that our transmission finished
+ */
+ while (
+ ( (SPI_CTL_STATUS_REG & EMPTY_FIFO_TX) == 0 ) ||
+ ( (SPI_CTL_STATUS_REG & BUSY_MASTER) != 0 )
+ )
+ {
+ /* check timeout */
+ if (get_timer(nowtime) > SPI_CTL_TMO)
+ {
+ seterr_flash_spi(ERR_TIMOUT);
+ rc = ERR_TIMOUT;
+ goto outahere;
+ } /* if */
+ }
+
+ /* Wait until flash is ready. */
+ nowtime = get_timer(0);
+ chip1 = 0;
+ do
+ {
+
+ if ( flash_read_status_spi(&flash_spi_status) == ERR_TIMOUT )
+ {
+ chip1 = TMO_SPI;
+ break;
+ }
+
+ /* check timeout */
+ if (get_timer(nowtime) > CFG_FLASH_SPI_ERASE_TOUT)
+ {
+ chip1 = TMO_SPI;
+ break;
+ } /* if */
+
+ if ( !chip1 && ( (flash_spi_status & SR_WIP) == 0 ) )
+ chip1 = READY_SPI;
+
+ } while (!chip1); /* do ... while */
+
+ if (chip1 == TMO_SPI)
+ {
+ seterr_flash_spi(ERR_TIMOUT);
+ rc = ERR_TIMOUT;
+ goto outahere;
+ } /* if */
+
+ printf ("ok.\n");
+ }
+ else
+ { /* it was protected */
+ printf ("protected!\n");
+ } /* if */
+ } /* for */
+
+ if (ctrlc ())
+ printf ("User Interrupt!\n");
+
+outahere:
+ /* allow flash to settle - wait 10 ms */
+ udelay_masked (10000);
+
+ if (iflag)
+ enable_interrupts ();
+
+ if (cflag)
+ icache_enable ();
+
+ return rc;
+} /* flash_erase_std */
+
+/**
+ * Function: flash_read_spi
+ * Parameters: volatile unsigned char *dst, unsigned char *tmp_buf, int lenght
+ * Purpose: Read SPI flash
+ * Return Value: int
+ */
+int flash_read_spi (volatile unsigned char *addr, volatile unsigned char *data, int lenght, int dirty_flag, int do_cmp)
+{
+ int rc = ERR_OK;
+ unsigned int tx_conf, rx_conf, rx_max_words, int_len, words_to_read;
+ unsigned int nb_read = 0; /* number of read words */
+ int i=0, j=0;
+ unsigned int cur_addr;
+ unsigned int result;
+ int error_flag = 0;
+ unsigned long nowtime;
+ //unsigned int kprint = 0;
+ int read_flash_spi_command = 0;
+ int rest = 0;
+ char get_first_time = 0;
+
+ char addr_boundary_flag = 0;
+ union tmp
+ {
+ unsigned char byte[4];
+ unsigned int val;
+ } tmp;
+
+ /* maximum number of byted that SPI controller
+ can receive in one go is size of RX FIFO - 8 bytes */
+ rx_max_words = 0xffff;
+ //rx_max_bytes = 0x3f;
+
+ rest = lenght % 4;
+ int_len = lenght / 4;
+
+ if ( ((unsigned int)(data) % 4) != 0)
+ /* dest address is NOT on word boundary
+ * we will have to read byte by byte and form
+ * internaly one word
+ */
+ addr_boundary_flag = 0;
+ else
+ addr_boundary_flag = 1; /* dest address is on word boundary */
+
+ while ( int_len > nb_read)
+ {
+ if ( (int_len - nb_read) > rx_max_words )
+ {
+ tx_conf = (0x1 << 16) | 0x20; /* command + address*/
+ rx_conf = ( (rx_max_words) << 16) | 0x20;
+
+ words_to_read = rx_max_words;
+ }
+ else
+ {
+ tx_conf = (0x1 << 16) | 0x20;
+ /* expected number od data to be read */
+ rx_conf = ( (int_len - nb_read) << 16 ) | 0x20;
+
+ words_to_read = int_len - nb_read;
+ }
+
+ get_first_time = 1;
+ /* poll until Tx and Rx FIFOs are empty
+ and SPI bus is not busy
+ to be sure that no other transmissoin is in progress */
+ while (
+ ( (SPI_CTL_STATUS_REG & EMPTY_FIFO_TX) == 0 ) ||
+ ( (SPI_CTL_STATUS_REG & EMPTY_FIFO_RX) == 0 ) ||
+ ( (SPI_CTL_STATUS_REG & BUSY_MASTER) != 0 )
+ )
+ {
+ if (get_first_time == 1)
+ {
+ nowtime = get_timer(0);
+ get_first_time = 0;
+ }
+
+ /* check timeout */
+ if ( get_timer(nowtime) > SPI_CTL_TMO)
+ {
+ seterr_flash_spi(ERR_TIMOUT);
+ rc = ERR_TIMOUT;
+ return rc;
+ } /* if */
+ } /* while */
+
+
+
+#ifdef DEBUG_FLASH_SPI
+printf("tx_conf = %#x\n", tx_conf);
+printf("rx_conf = %#x\n", rx_conf);
+#endif
+
+ /* configure how many bytes to send/receive */
+ SPI_CTL_CONF_TX = tx_conf;
+ SPI_CTL_CONF_RX = rx_conf;
+
+
+
+ /* send addr in order MSB first */
+ cur_addr = (unsigned int)(addr + nb_read*4);
+
+ /* mask MSB byte, i.e. set it to all-zero */
+ cur_addr &= ~(0xFF << 24);
+ read_flash_spi_command = READ<<24 | (unsigned int)cur_addr;
+ swap_endians(&read_flash_spi_command);
+
+#ifdef DEBUG_FLASH_SPI
+//printf("read_flash_spi_command = %#x\n", read_flash_spi_command);
+#endif
+
+ get_first_time = 1;
+ while ( (SPI_CTL_STATUS_REG & FULL_FIFO_TX) != 0 )
+ {
+ if (get_first_time == 1)
+ {
+ nowtime = get_timer(0);
+ get_first_time = 0;
+ }
+
+ if ( get_timer(nowtime) > SPI_CTL_TMO)
+ {
+ seterr_flash_spi(ERR_TIMOUT);
+ rc = ERR_TIMOUT;
+ return rc;
+ } /* if */
+ }
+
+ SPI_CTL_TX_REG = read_flash_spi_command; /* send command + address to SPI flash via SPI controller */
+
+
+#ifdef DEBUG_FLASH_SPI
+//printf("words_to_read = %#x\n\n", words_to_read);
+#endif
+
+
+ /* and now receive the data */
+ for (i=0; i<words_to_read; i++)
+ {
+ /* busy wait for RECEIVED_WORD bit in status reg */
+ get_first_time = 1;
+ while ( (SPI_CTL_STATUS_REG & RECEIVED_WORD) == 0 )
+ {
+ if (get_first_time == 1)
+ {
+ nowtime = get_timer(0);
+ get_first_time = 0;
+ }
+
+ /* check timeout */
+ if ( get_timer(nowtime) > SPI_CTL_TMO )
+ {
+ seterr_flash_spi(ERR_TIMOUT);
+ rc = ERR_TIMOUT;
+ return rc;
+ } /* if */
+ } /* while */
+
+ result = SPI_CTL_RX_REG;
+
+#ifdef DEBUG_FLASH_SPI
+//printf("result = %#x\n", result);
+#endif
+
+ if (do_cmp)
+ {
+ /*
+ * do_cmp == 1 => flash_read_spi() was called from write_buff(),
+ * and result read should be either all 1 (if flash is clean)
+ * or what was in data[] given to the function
+ */
+
+ /* Check the result for errors.
+ If there has been an error we can not go out emmidiately,
+ we must wait SPI controller to finish transsaction,
+ because we configured rx_config, and cannot repprogram it in the
+ middle of transaction */
+ if (dirty_flag == 0)
+ {
+ /* flash is supposed to be clean (erased) */
+ if (addr_boundary_flag == 1)
+ {
+ /* we can read whole integer from addr, because it is on word boundary */
+ if ( (result & *( (unsigned int *)(data) + nb_read ) ) != *( (unsigned int *)(data) + nb_read ) )
+ {
+ error_flag = 1;
+ rc = ERR_NOT_ERASED;
+ }
+ }
+ else
+ {
+ for (j=0; j<4; j++)
+ {
+
+//printf("(&result)[%d] = %#x\n", j, ( (unsigned char *)&result )[j]);
+//printf("*( (unsigned char *)(data) + nb_read*4 + %d) = %#x\n", j, *( (unsigned char *)(data) + nb_read*4 + j) );
+
+ if ( ( ( (unsigned char *)&result )[j] & *( (unsigned char *)(data) + nb_read*4 + j) ) !=
+ *( (unsigned char *)(data) + nb_read*4 + j) )
+ {
+ error_flag = 1;
+ rc = ERR_NOT_ERASED;
+ }
+ }
+
+ }
+
+ }
+ else /* flash is dirty (written to) */
+ {
+ if (addr_boundary_flag == 1)
+ {
+ /* we can read whole integer from addr, because it is on word boundary */
+ if ( result != *( (unsigned int *)data + nb_read ) )
+ {
+ error_flag = 1;
+ rc = ERR_PROG_ERROR;
+ }
+ }
+ else
+ {
+ for (j=0; j<4; j++)
+ {
+ if ( ( (unsigned char *)&result )[j] != *( (unsigned char *)data + nb_read*4 + j ) )
+ {
+ error_flag = 1;
+ rc = ERR_PROG_ERROR;
+ }
+ }
+ }
+ }
+ }
+ else
+ {
+ /* flash was not called from write_buff(),
+ * that means it was not called in compare purposes,
+ * but we really want to retreive data.
+ * So we will set data[nb_read] to appropriate value
+ */
+ if (addr_boundary_flag == 1)
+ {
+ /* we can read whole integer into dest addr, because it is on word boundary */
+ *( (unsigned int *)(data) + nb_read ) = result;
+ }
+ else
+ {
+ /* we must write in byte by byte */
+ for (j=0; j<4; j++)
+ {
+ *( (unsigned char *)(data) + nb_read*4 + j) = ( (unsigned char *)&result )[j];
+ }
+ }
+ }
+
+ /* OK, go to the next word */
+ nb_read ++;
+
+ } /* for */
+
+#if 0
+ /* print output to user to know that writing is in progress.
+ On every 64 kb written print "W" */
+ if( kprint % 50 == 0)
+ putc('\n');
+ putc('R');
+ kprint ++;
+#endif
+
+ /* we read all the bytes we promised in rx_config,
+ now it is safe to go out if there is an error */
+ if (error_flag != 0)
+ {
+ seterr_flash_spi(rc);
+ return rc;
+ }
+ } /* while */
+
+
+ /* Now pick up leftover bytes, that rest from a multiple of four */
+ if (rest > 0)
+ {
+ /* how many bytes were read so far */
+ nb_read *= 4;
+
+ tx_conf = (0x1 << 16) | 0x20;
+ /* expected number od data to be read */
+ rx_conf = ( rest << 16 ) | 0x08;
+
+ words_to_read = rest;
+
+ get_first_time = 1;
+ /* poll until Tx and Rx FIFOs are empty
+ and SPI bus is not busy
+ to be sure that no other transmissoin is in progress */
+ while (
+ ( (SPI_CTL_STATUS_REG & EMPTY_FIFO_TX) == 0 ) ||
+ ( (SPI_CTL_STATUS_REG & EMPTY_FIFO_RX) == 0 ) ||
+ ( (SPI_CTL_STATUS_REG & BUSY_MASTER) != 0 )
+ )
+ {
+ if (get_first_time == 1)
+ {
+ nowtime = get_timer(0);
+ get_first_time = 0;
+ }
+ /* check timeout */
+ if ( get_timer(nowtime) > SPI_CTL_TMO)
+ {
+ seterr_flash_spi(ERR_TIMOUT);
+ rc = ERR_TIMOUT;
+ return rc;
+ } /* if */
+ } /* while */
+
+ /* configure how many bytes to send/receive */
+ SPI_CTL_CONF_TX = tx_conf;
+ SPI_CTL_CONF_RX = rx_conf;
+
+
+ /* send addr in order MSB first */
+ cur_addr = 0;
+ for (i=2; i>=0; i--)
+ cur_addr = (unsigned int)(addr + nb_read);
+
+ /* form the command to send through SPI Controller.
+ In case of ERASE command is composed of SE (Sector Erase) opcode
+ plus address of the sector within SPI flash */
+ read_flash_spi_command = 0;
+ read_flash_spi_command |= READ<<24 | (unsigned int)cur_addr;
+
+ swap_endians(&read_flash_spi_command);
+
+ get_first_time = 1;
+ while ( (SPI_CTL_STATUS_REG & FULL_FIFO_TX) != 0 )
+ {
+ if (get_first_time == 1)
+ {
+ nowtime = get_timer(0);
+ get_first_time = 0;
+ }
+
+ if ( get_timer(nowtime) > SPI_CTL_TMO)
+ {
+ seterr_flash_spi(ERR_TIMOUT);
+ rc = ERR_TIMOUT;
+ return rc;
+ } /* if */
+ }
+
+ SPI_CTL_TX_REG = read_flash_spi_command; /* send command + address to SPI flash via SPI controller */
+
+
+ /* and now receive the data */
+ for (i=0; i<words_to_read; i++)
+ {
+ /* busy wait for RECEIVED_WORD bit in status reg */
+ get_first_time = 1;
+ while ( (SPI_CTL_STATUS_REG & EMPTY_FIFO_RX) != 0 )
+ {
+ if (get_first_time == 1)
+ {
+ nowtime = get_timer(0);
+ get_first_time = 0;
+ }
+
+ /* check timeout */
+ if ( get_timer(nowtime) > SPI_CTL_TMO )
+ {
+ seterr_flash_spi(ERR_TIMOUT);
+ rc = ERR_TIMOUT;
+ return rc;
+ } /* if */
+ } /* while */
+ result = SPI_CTL_RX_REG;
+
+ if (do_cmp)
+ {
+ /*
+ * do_cmp == 1 => flash_read_spi() was called from write_buff(),
+ * and result read should be either all 1 (if flash is clean)
+ * or what was in data[] given to the function
+ */
+
+ /* Check the result for errors.
+ If there has been an error we can not go out emmidiately,
+ we must wait SPI controller to finish transsaction,
+ because we configured rx_config, and cannot repprogram it in the
+ middle of transaction */
+ if (dirty_flag == 0)
+ {
+ /* flash is supposed to be clean (erased) */
+ if ((result & data[nb_read]) != data[nb_read])
+ {
+ error_flag = 1;
+ rc = ERR_NOT_ERASED;
+ }
+
+ }
+ else /* flash is dirty (written to) */
+ {
+ if ( (unsigned char)result != data[nb_read] )
+ {
+ error_flag = 1;
+ rc = ERR_PROG_ERROR;
+ }
+ }
+ }
+ else
+ {
+ /* flash was not called from write_buff(),
+ * that means it was not called in compare purposes,
+ * but we really want to retreive data.
+ * So we will set data[nb_read] to appropriate value
+ */
+ data[nb_read] = (char)result;
+ }
+
+ nb_read++;
+
+ } /* for */
+
+#if 0
+ /* print output to user to know that writing is in progress.
+ On every 64 kb written print "W" */
+ if( kprint % 50 == 0)
+ putc('\n');
+ putc('R');
+ kprint ++;
+#endif
+
+ /* we read all the bytes we promised in rx_config,
+ now it is safe to go out if there is an error */
+ if (error_flag != 0)
+ {
+ seterr_flash_spi(rc);
+ return rc;
+ }
+ } /* if */
+
+ return rc;
+}
+
+/**
+ * Function: write_buff
+ * Parameters: flash_info_t * info, uchar * src, ulong addr, ulong cnt
+ * Purpose: Write buffer
+ * Return Value: int
+ */
+int write_buff (flash_info_t * info, uchar * src, ulong dest, ulong cnt)
+{
+ volatile unsigned char *data = (volatile unsigned char *) src;
+ volatile unsigned char *addr = (volatile unsigned char *) dest;
+ int lenght = cnt;
+ unsigned int kprint = 0;
+ int cflag, iflag;
+ unsigned char flash_spi_status;
+ int rc = ERR_OK;
+ int chip1;
+ int i=0, j=0;
+ int nb_written = 0;
+ int nw_written = 0;
+ unsigned int tx_max_words, words_to_write, int_len;
+ unsigned int tx_conf, rx_conf;
+ unsigned int cur_addr;
+ unsigned long nowtime;
+ int write_flash_spi_command = 0;
+ int rest = 0;
+ char get_first_time = 0;
+ unsigned int align_bytes = 0;
+ char addr_boundary_flag = 0;
+
+ union tmp
+ {
+ unsigned char byte[4];
+ unsigned int val;
+ } tmp;
+
+ /*
+ * Check if Flash is (sufficiently) erased
+ */
+ /* call to SPI flash READ function with drty_flag = 0 */
+ putc('\n');
+ if ( ( rc = flash_read_spi (addr, data, lenght, 0, 1) ) != ERR_OK )
+ {
+ seterr_flash_spi(rc);
+ goto outahere;
+ }
+ putc('\n');
+
+ /* reset lenght wor WRITE operation */
+ lenght = cnt;
+
+ /* maximum of bytes that our SPI Flash
+ can write in one go is 256,
+ if we start on 256 boundary.
+ It is because the write that begun within one 256 byte region must finish
+ in the same region in order for addresses to be well written */
+ tx_max_words = 0x41; /* bytes of data, without 1 byte needed for command and 3 for addr */
+ //tx_max_bytes = 0x3f - 1 - 3;
+
+ rest = lenght % 4;
+ int_len = lenght / 4;
+
+ if ( ((unsigned int)(addr) % 4) != 0)
+ align_bytes = 4 - ( (unsigned int)(addr) % 4 ); // nb of bytes needed to align to 4 byte boundary
+ else
+ {
+ align_bytes = 0;
+ addr_boundary_flag = 1; /* source address is on word boundary */
+ }
+
+
+
+ if (align_bytes > 0)
+ {
+ if (align_bytes > lenght)
+ {
+ /* will do these bytes in the "rest" loop */
+ align_bytes = 0;
+ }
+ else
+ {
+ int_len = (lenght - align_bytes) / 4;
+ rest = (lenght - align_bytes) % 4;
+ }
+ }
+
+
+//printf("rest = %#x\n", rest);
+//printf("int_len = %#x\n", int_len);
+//printf("align_bytes = %#x\n", align_bytes);
+//getc();
+
+ /* ALIGN (BYTE-BY-BYTE) LOOP */
+ while (align_bytes > 0)
+ {
+
+ tx_conf = ( (align_bytes + 1 + 3) << 16 ) | 0x08;
+ rx_conf = 0x0;
+
+ words_to_write = align_bytes;
+
+ /* First write-enable the SPI flash */
+ if ( flash_write_enable_spi() == ERR_TIMOUT )
+ {
+ printf ("Cannot write-enable SPI flash\n");
+ seterr_flash_spi(ERR_TIMOUT);
+ rc = ERR_TIMOUT;
+ goto outahere;
+ }
+
+ /* And then program flash */
+ get_first_time = 1;
+ /* poll until Tx and Rx FIFOs are empty
+ and SPI bus is not busy
+ to be sure that no other transmissoin is in progress */
+ while (
+ ( (SPI_CTL_STATUS_REG & EMPTY_FIFO_TX) == 0 ) ||
+ ( (SPI_CTL_STATUS_REG & EMPTY_FIFO_RX) == 0 ) ||
+ ( (SPI_CTL_STATUS_REG & BUSY_MASTER) != 0 )
+ )
+ {
+ if (get_first_time == 1)
+ {
+ nowtime = get_timer(0);
+ get_first_time = 0;
+ }
+ /* check timeout */
+ if (get_timer(nowtime) > SPI_CTL_TMO)
+ {
+ seterr_flash_spi(ERR_TIMOUT);
+ rc = ERR_TIMOUT;
+ goto outahere;
+ } /* if */
+ } /* while */
+
+ SPI_CTL_CONF_TX = tx_conf;
+ SPI_CTL_CONF_RX = rx_conf;
+
+ /* first send out command */
+ get_first_time = 1;
+ while (
+ ( (SPI_CTL_STATUS_REG & EMPTY_FIFO_TX) == 0 ) ||
+ ( (SPI_CTL_STATUS_REG & BUSY_MASTER) != 0 )
+ )
+ {
+ if (get_first_time == 1)
+ {
+ nowtime = get_timer(0);
+ get_first_time = 0;
+ }
+ if ( get_timer(nowtime) > SPI_CTL_TMO)
+ {
+ seterr_flash_spi(ERR_TIMOUT);
+ rc = ERR_TIMOUT;
+ goto outahere;
+ } /* if */
+ }
+ SPI_CTL_TX_REG = PP;
+
+ cur_addr = (unsigned int)addr;
+
+ /* send addr in order MSB first */
+ for (i=2; i>=0; i--)
+ {
+ get_first_time = 1;
+ while ( (SPI_CTL_STATUS_REG & FULL_FIFO_TX) != 0 )
+ {
+ if (get_first_time == 1)
+ {
+ nowtime = get_timer(0);
+ get_first_time = 0;
+ }
+ if ( get_timer(nowtime) > SPI_CTL_TMO)
+ {
+ seterr_flash_spi(ERR_TIMOUT);
+ rc = ERR_TIMOUT;
+ goto outahere;
+ } /* if */
+ }
+
+ SPI_CTL_TX_REG = ( (volatile unsigned char *)(&cur_addr) )[i];
+ }
+
+ for (i=0; i < words_to_write; i++)
+ {
+ /* and send byte of data to be written */
+ get_first_time = 1;
+ while ( (SPI_CTL_STATUS_REG & FULL_FIFO_TX) != 0 )
+ {
+ if (get_first_time == 1)
+ {
+ nowtime = get_timer(0);
+ get_first_time = 0;
+ }
+ if ( get_timer(nowtime) > SPI_CTL_TMO)
+ {
+ seterr_flash_spi(ERR_TIMOUT);
+ rc = ERR_TIMOUT;
+ goto outahere;
+ } /* if */
+ }
+
+ SPI_CTL_TX_REG = data[nb_written];
+
+ nb_written++;
+ align_bytes--;
+
+ } /* for */
+
+ /* arm simple, non interrupt dependent timer */
+ get_first_time = 1;
+ /* poll until Tx FIFO is empty
+ and SPI bus is not busy
+ to be sure that our transmission finished */
+ while (
+ ( (SPI_CTL_STATUS_REG & EMPTY_FIFO_TX) == 0 ) ||
+ ( (SPI_CTL_STATUS_REG & BUSY_MASTER) != 0 )
+ )
+ {
+ if (get_first_time == 1)
+ {
+ nowtime = get_timer(0);
+ get_first_time = 0;
+ }
+ /* check timeout */
+
+ if (get_timer(nowtime) > SPI_CTL_TMO)
+ {
+ seterr_flash_spi(ERR_TIMOUT);
+ rc = ERR_TIMOUT;
+ goto outahere;
+ } /* if */
+ }
+
+ /* wait until flash is ready */
+ /* arm simple, non interrupt dependent timer */
+ nowtime = get_timer(0);
+ chip1 = 0;
+ do
+ {
+ if ( flash_read_status_spi(&flash_spi_status) == ERR_TIMOUT)
+ {
+ chip1 = TMO_SPI;
+ break;
+ }
+
+ /* check timeout */
+ if (get_timer(nowtime) > CFG_FLASH_SPI_WRITE_TOUT)
+ {
+ chip1 = TMO_SPI;
+ break;
+ }
+ if ( !chip1 && ( (flash_spi_status & SR_WIP) == 0 ) )
+ chip1 = READY_SPI;
+
+ } while (!chip1); /* do ... while */
+
+ if (chip1 == TMO_SPI)
+ {
+ seterr_flash_spi(ERR_TIMOUT);
+ rc = ERR_TIMOUT;
+ goto outahere;
+ }
+ } /*while */
+
+ /* WORD (4-byte) LOOP */
+ while (int_len > nw_written)
+ {
+ if ( (int_len - nw_written) > tx_max_words )
+ {
+ tx_conf = (tx_max_words << 16) | 0x20;
+ rx_conf = 0x0;
+
+ words_to_write = tx_max_words - 1;
+ }
+ else
+ {
+ /* 1 byte for the command and 3 bytes of addr per data to be read */
+ tx_conf = ( (1 + (int_len - nw_written) ) << 16 ) | 0x20;
+ /* expected number od data to be read */
+ rx_conf = 0x0;
+
+ words_to_write = int_len - nw_written;
+ }
+
+ /* Check if we will do writing within same 256 byte region.
+ It is not allowed to cross to next region within same PP operation.
+ If we are crossing to the next region, lower the bytes_to_write,
+ in order to finish writing on 256 byte region boundary (i.e. to do all
+ the writing in the same region in which we are starting). */
+ cur_addr = (unsigned int)(addr + nb_written + nw_written*4);
+ if ( (cur_addr % 256) + words_to_write*4 > 256)
+ {
+ words_to_write = ( 256 - (cur_addr % 256) ) / 4;
+ tx_conf = ( (words_to_write + 1) << 16) | 0x20;
+ }
+
+ /* First write-enable the SPI flash */
+ if ( flash_write_enable_spi() == ERR_TIMOUT )
+ {
+ printf ("Cannot write-enable SPI flash\n");
+ seterr_flash_spi(ERR_TIMOUT);
+ rc = ERR_TIMOUT;
+ goto outahere;
+ }
+
+ /* And then program flash */
+ get_first_time = 1;
+ /* poll until Tx and Rx FIFOs are empty
+ and SPI bus is not busy
+ to be sure that no other transmissoin is in progress */
+ while (
+ ( (SPI_CTL_STATUS_REG & EMPTY_FIFO_TX) == 0 ) ||
+ ( (SPI_CTL_STATUS_REG & EMPTY_FIFO_RX) == 0 ) ||
+ ( (SPI_CTL_STATUS_REG & BUSY_MASTER) != 0 )
+ )
+ {
+ if (get_first_time == 1)
+ {
+ nowtime = get_timer(0);
+ get_first_time = 0;
+ }
+ /* check timeout */
+ if (get_timer(nowtime) > SPI_CTL_TMO)
+ {
+ seterr_flash_spi(ERR_TIMOUT);
+ rc = ERR_TIMOUT;
+ goto outahere;
+ } /* if */
+ } /* while */
+
+ SPI_CTL_CONF_TX = tx_conf; /* send 32 bit message (command + address) */
+ SPI_CTL_CONF_RX = rx_conf;
+
+ /* send addr in order MSB first */
+ cur_addr = (unsigned int)(addr + nb_written + nw_written*4);
+
+ /* mask MSB byte, i.e. set it to all-zero */
+ cur_addr &= ~(0xFF << 24);
+ write_flash_spi_command = PP<<24 | (unsigned int)cur_addr;
+ swap_endians(&write_flash_spi_command);
+
+
+ /* first send out command */
+ get_first_time = 1;
+ while (
+ ( (SPI_CTL_STATUS_REG & EMPTY_FIFO_TX) == 0 ) ||
+ ( (SPI_CTL_STATUS_REG & BUSY_MASTER) != 0 )
+ )
+ {
+ if (get_first_time == 1)
+ {
+ nowtime = get_timer(0);
+ get_first_time = 0;
+ }
+ if ( get_timer(nowtime) > SPI_CTL_TMO)
+ {
+ seterr_flash_spi(ERR_TIMOUT);
+ rc = ERR_TIMOUT;
+ goto outahere;
+ } /* if */
+ }
+ SPI_CTL_TX_REG = write_flash_spi_command;
+
+ for (i=0; i < words_to_write; i++)
+ {
+ /* and send byte of data to be written */
+ get_first_time = 1;
+ while ( (SPI_CTL_STATUS_REG & FULL_FIFO_TX) != 0 )
+ {
+ if (get_first_time == 1)
+ {
+ nowtime = get_timer(0);
+ get_first_time = 0;
+ }
+
+ if ( get_timer(nowtime) > SPI_CTL_TMO)
+ {
+ seterr_flash_spi(ERR_TIMOUT);
+ rc = ERR_TIMOUT;
+ goto outahere;
+ } /* if */
+ }
+
+ if (addr_boundary_flag == 0)
+ {
+ /* source addr is not on int boundary, so we must take 4 bytes
+ * byte-by-byte
+ */
+ for (j=0; j < 4; j++)
+ {
+ tmp.byte[j] = *( (unsigned char *)(data + nb_written + nw_written*4 + j) );
+ }
+
+ SPI_CTL_TX_REG = tmp.val;
+ }
+ else
+ {
+ /* since source addr is on word boundary, we can cast it to int pointer,
+ * and take all 4 bytes in one go
+ */
+ SPI_CTL_TX_REG = *( (unsigned int *)(data + nb_written + nw_written*4) );
+ }
+
+ nw_written++;
+
+ } /* for */
+
+ /* print output to user to know that writing is in progress.
+ On every 512*256b written print "W" */
+ if( kprint % (50*512) == 0)
+ putc('\n');
+
+ if( kprint % 512 == 0)
+ putc('W');
+ kprint ++;
+
+ /* arm simple, non interrupt dependent timer */
+ get_first_time = 1;
+ /* poll until Tx FIFO is empty
+ and SPI bus is not busy
+ to be sure that our transmission finished */
+ while (
+ ( (SPI_CTL_STATUS_REG & EMPTY_FIFO_TX) == 0 ) ||
+ ( (SPI_CTL_STATUS_REG & BUSY_MASTER) != 0 )
+ )
+ {
+ if (get_first_time == 1)
+ {
+ nowtime = get_timer(0);
+ get_first_time = 0;
+ }
+ /* check timeout */
+
+ if (get_timer(nowtime) > SPI_CTL_TMO)
+ {
+ seterr_flash_spi(ERR_TIMOUT);
+ rc = ERR_TIMOUT;
+ goto outahere;
+ } /* if */
+ }
+
+ /* wait until flash is ready */
+ /* arm simple, non interrupt dependent timer */
+ nowtime = get_timer(0);
+ chip1 = 0;
+ do
+ {
+ if ( flash_read_status_spi(&flash_spi_status) == ERR_TIMOUT)
+ {
+ chip1 = TMO_SPI;
+ break;
+ }
+
+ /* check timeout */
+ if (get_timer(nowtime) > CFG_FLASH_SPI_WRITE_TOUT)
+ {
+ chip1 = TMO_SPI;
+ break;
+ }
+ if ( !chip1 && ( (flash_spi_status & SR_WIP) == 0 ) )
+ chip1 = READY_SPI;
+
+ } while (!chip1); /* do ... while */
+
+ if (chip1 == TMO_SPI)
+ {
+ seterr_flash_spi(ERR_TIMOUT);
+ rc = ERR_TIMOUT;
+ goto outahere;
+ }
+ } /* while */
+
+ /* REST (BYTE-BY-BYTE) LOOP */
+ nb_written = nb_written + nw_written*4;
+ while (rest > 0)
+ {
+
+ tx_conf = ( (rest + 1 + 3) << 16 ) | 0x08;
+ rx_conf = 0x0;
+
+ words_to_write = rest;
+
+ /* Check if we will do writing within same 256 byte region.
+ It is not allowed to cross to next region within same PP operation.
+ If we are crossing to the next region, lower the bytes_to_write,
+ in order to finish writing on 256 byte region boundary (i.e. to do all
+ the writing in the same region in which we are starting). */
+ cur_addr = (unsigned int)(addr + nb_written);
+ if ( (cur_addr % 256) + words_to_write > 256)
+ {
+ words_to_write = 256 - (cur_addr % 256);
+ tx_conf = ( (words_to_write + 1 + 3) << 16) | 0x8;
+ }
+
+
+ /* First write-enable the SPI flash */
+ if ( flash_write_enable_spi() == ERR_TIMOUT )
+ {
+ printf ("Cannot write-enable SPI flash\n");
+ seterr_flash_spi(ERR_TIMOUT);
+ rc = ERR_TIMOUT;
+ goto outahere;
+ }
+
+ /* And then program flash */
+ get_first_time = 1;
+ /* poll until Tx and Rx FIFOs are empty
+ and SPI bus is not busy
+ to be sure that no other transmissoin is in progress */
+ while (
+ ( (SPI_CTL_STATUS_REG & EMPTY_FIFO_TX) == 0 ) ||
+ ( (SPI_CTL_STATUS_REG & EMPTY_FIFO_RX) == 0 ) ||
+ ( (SPI_CTL_STATUS_REG & BUSY_MASTER) != 0 )
+ )
+ {
+ if (get_first_time == 1)
+ {
+ nowtime = get_timer(0);
+ get_first_time = 0;
+ }
+ /* check timeout */
+ if (get_timer(nowtime) > SPI_CTL_TMO)
+ {
+ seterr_flash_spi(ERR_TIMOUT);
+ rc = ERR_TIMOUT;
+ goto outahere;
+ } /* if */
+ } /* while */
+
+ SPI_CTL_CONF_TX = tx_conf;
+ SPI_CTL_CONF_RX = rx_conf;
+
+ /* first send out command */
+ get_first_time = 1;
+ while (
+ ( (SPI_CTL_STATUS_REG & EMPTY_FIFO_TX) == 0 ) ||
+ ( (SPI_CTL_STATUS_REG & BUSY_MASTER) != 0 )
+ )
+ {
+ if (get_first_time == 1)
+ {
+ nowtime = get_timer(0);
+ get_first_time = 0;
+ }
+ if ( get_timer(nowtime) > SPI_CTL_TMO)
+ {
+ seterr_flash_spi(ERR_TIMOUT);
+ rc = ERR_TIMOUT;
+ goto outahere;
+ } /* if */
+ }
+ SPI_CTL_TX_REG = PP;
+
+ /* send addr in order MSB first */
+ for (i=2; i>=0; i--)
+ {
+ get_first_time = 1;
+ while ( (SPI_CTL_STATUS_REG & FULL_FIFO_TX) != 0 )
+ {
+ if (get_first_time == 1)
+ {
+ nowtime = get_timer(0);
+ get_first_time = 0;
+ }
+ if ( get_timer(nowtime) > SPI_CTL_TMO)
+ {
+ seterr_flash_spi(ERR_TIMOUT);
+ rc = ERR_TIMOUT;
+ goto outahere;
+ } /* if */
+ }
+
+ SPI_CTL_TX_REG = ( (volatile unsigned char *)(&cur_addr) )[i];
+ }
+
+ for (i=0; i < words_to_write; i++)
+ {
+ /* and send byte of data to be written */
+ get_first_time = 1;
+ while ( (SPI_CTL_STATUS_REG & FULL_FIFO_TX) != 0 )
+ {
+ if (get_first_time == 1)
+ {
+ nowtime = get_timer(0);
+ get_first_time = 0;
+ }
+ if ( get_timer(nowtime) > SPI_CTL_TMO)
+ {
+ seterr_flash_spi(ERR_TIMOUT);
+ rc = ERR_TIMOUT;
+ goto outahere;
+ } /* if */
+ }
+
+ SPI_CTL_TX_REG = data[nb_written];
+
+ nb_written++;
+ rest--;
+
+ } /* for */
+
+ /* arm simple, non interrupt dependent timer */
+ get_first_time = 1;
+ /* poll until Tx FIFO is empty
+ and SPI bus is not busy
+ to be sure that our transmission finished */
+ while (
+ ( (SPI_CTL_STATUS_REG & EMPTY_FIFO_TX) == 0 ) ||
+ ( (SPI_CTL_STATUS_REG & BUSY_MASTER) != 0 )
+ )
+ {
+ if (get_first_time == 1)
+ {
+ nowtime = get_timer(0);
+ get_first_time = 0;
+ }
+ /* check timeout */
+
+ if (get_timer(nowtime) > SPI_CTL_TMO)
+ {
+ seterr_flash_spi(ERR_TIMOUT);
+ rc = ERR_TIMOUT;
+ goto outahere;
+ } /* if */
+ }
+
+ /* wait until flash is ready */
+ /* arm simple, non interrupt dependent timer */
+ nowtime = get_timer(0);
+ chip1 = 0;
+ do
+ {
+ if ( flash_read_status_spi(&flash_spi_status) == ERR_TIMOUT)
+ {
+ chip1 = TMO_SPI;
+ break;
+ }
+
+ /* check timeout */
+ if (get_timer(nowtime) > CFG_FLASH_SPI_WRITE_TOUT)
+ {
+ chip1 = TMO_SPI;
+ break;
+ }
+ if ( !chip1 && ( (flash_spi_status & SR_WIP) == 0 ) )
+ chip1 = READY_SPI;
+
+ } while (!chip1); /* do ... while */
+
+ if (chip1 == TMO_SPI)
+ {
+ seterr_flash_spi(ERR_TIMOUT);
+ rc = ERR_TIMOUT;
+ goto outahere;
+ }
+ } /*while */
+
+ /*
+ * read the data to verify the write
+ */
+ /* call to SPI flash READ function with drty_flag = 1 */
+ putc('\n');
+
+ if ( ( rc = flash_read_spi (addr, data, lenght, 1, 1) ) != ERR_OK )
+ {
+ seterr_flash_spi(rc);
+ goto outahere;
+ } /* if */
+ putc('\n');
+
+outahere:
+
+ if (iflag)
+ enable_interrupts ();
+
+ if (cflag)
+ icache_enable ();
+
+ return rc;
+} /* write_buff */
diff --git a/cleopatre/u-boot-1.1.6/common/cmd_spidboot.c b/cleopatre/u-boot-1.1.6/common/cmd_spidboot.c
index ec2d71f595..ac53ca787b 100644
--- a/cleopatre/u-boot-1.1.6/common/cmd_spidboot.c
+++ b/cleopatre/u-boot-1.1.6/common/cmd_spidboot.c
@@ -785,6 +785,7 @@ int do_spidboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
#ifdef CONFIG_CMDLINE_TAG
setup_commandline_tag (bd, commandline);
#endif
+
#ifdef CONFIG_SPC300_TAG
setup_spc300_tag (bd, &params);
#endif
diff --git a/cleopatre/u-boot-1.1.6/cpu/spc300-fcm3/start.S b/cleopatre/u-boot-1.1.6/cpu/spc300-fcm3/start.S
index bf522ab1dc..54a18cf829 100644
--- a/cleopatre/u-boot-1.1.6/cpu/spc300-fcm3/start.S
+++ b/cleopatre/u-boot-1.1.6/cpu/spc300-fcm3/start.S
@@ -199,8 +199,8 @@ reset:
add r2, r0, #0x1000 /* r2 = end of remap code address */
remap_copy_loop:
- ldmia r0!, {r3-r10} /* copy from source address [r0] */
- stmia r1!, {r3-r10} /* copy to target address [r1] */
+ ldmia r0!, {r3-r9, r11} /* copy from source address [r0], do not clobber r10 (holds NVRAM addr) */
+ stmia r1!, {r3-r9, r11} /* copy to target address [r1] */
cmp r0, r2 /* until source end addreee [r2] */
ble remap_copy_loop
@@ -280,8 +280,8 @@ relocate: /* relocate U-Boot to RAM */
add r2, r0, r2 /* r2 <- source end address */
copy_loop:
- ldmia r0!, {r3-r10} /* copy from source address [r0] */
- stmia r1!, {r3-r10} /* copy to target address [r1] */
+ ldmia r0!, {r3-r9, r11} /* copy from source address [r0], do not clobber r10 (holds NVRAM addr) */
+ stmia r1!, {r3-r9, r11} /* copy to target address [r1] */
cmp r0, r2 /* until source end addreee [r2] */
ble copy_loop
#endif /* CONFIG_SKIP_RELOCATE_UBOOT */
diff --git a/cleopatre/u-boot-1.1.6/cpu/spc300/pll_init.S b/cleopatre/u-boot-1.1.6/cpu/spc300/pll_init.S
index 95bdacea51..776ea32fa9 100644
--- a/cleopatre/u-boot-1.1.6/cpu/spc300/pll_init.S
+++ b/cleopatre/u-boot-1.1.6/cpu/spc300/pll_init.S
@@ -150,10 +150,10 @@ pll_init:
/* active wait */
ldr r0, =PLL_WAIT_TIME
-wait_pll:
+.Lwaitpll:
sub r0, r0, #1
cmp r0, #0
- bne wait_pll
+ bne .Lwaitpll
/*
* Switch to PLL clock
@@ -162,28 +162,28 @@ wait_pll:
ldr r0, =REGBANK_BASE
ldr r1, =0x00000000
str r1, [r0, #0x580] /* RB_SPLL_BYPASS */
-poll_RB_SPLL_BYPASS_STAT:
+.LpollSPLLstat:
ldr r1, [r0, #0x584] /* RB_SPLL_BYPASS_STAT */
cmp r1, #0x02
- bne poll_RB_SPLL_BYPASS_STAT
+ bne .LpollSPLLstat
/* Peripheral PLL */
ldr r0, =REGBANK_BASE
ldr r1, =0x00000000
str r1, [r0, #0x540] /* RB_PPLL_BYPASS */
-poll_RB_PPLL_BYPASS_STAT:
+.LpollPPLLstat:
ldr r1, [r0, #0x544] /* RB_PPLL_BYPASS_STAT */
cmp r1, #0x02
- bne poll_RB_PPLL_BYPASS_STAT
+ bne .LpollPPLLstat
/* DSP PLL */
ldr r0, =REGBANK_BASE
ldr r1, =0x00000000
str r1, [r0, #0x560] /* RB_DPLL_BYPASS */
-poll_RB_DPLL_BYPASS_STAT:
+.LpollDPLLstat:
ldr r1, [r0, #0x564] /* RB_DPLL_BYPASS_STAT */
cmp r1, #0x02
- bne poll_RB_DPLL_BYPASS_STAT
+ bne .LpollDPLLstat
/**************************************************************
diff --git a/cleopatre/u-boot-1.1.6/cpu/spc300/start.S b/cleopatre/u-boot-1.1.6/cpu/spc300/start.S
index b55358f978..f11f8da1b3 100644
--- a/cleopatre/u-boot-1.1.6/cpu/spc300/start.S
+++ b/cleopatre/u-boot-1.1.6/cpu/spc300/start.S
@@ -228,7 +228,7 @@ first_init_end:
bl detect_nvram /* r10 will hold the NVRAM address */
mov lr, ip /* restore link */
#else
- bl cpu_init_crit
+ bl cpu_init_crit /* after cpu_init_crit, r10 will hold NVRAM addr, so do not clobber this reg */
#endif
#endif
@@ -245,9 +245,9 @@ relocate: /* relocate U-Boot to RAM */
add r2, r0, r2 /* r2 <- source end address */
copy_loop:
- ldmia r0!, {r3-r10} /* copy from source address [r0] */
- stmia r1!, {r3-r10} /* copy to target address [r1] */
- cmp r0, r2 /* until source end addreee [r2] */
+ ldmia r0!, {r3-r9, r11} /* copy from source address [r0] (preserve r10 which holds the address of NVRAM) */
+ stmia r1!, {r3-r9, r11} /* copy to target address [r1] (preserve r10 which holds the address of NVRAM) */
+ cmp r0, r2 /* until source end addreee [r2] */
ble copy_loop
#endif /* CONFIG_SKIP_RELOCATE_UBOOT */
@@ -385,19 +385,19 @@ poll_RB_CLK_DIV_STAT_ARM:
ldr r1, =SDRAM_CTRL_BASE
/* SCONR */
- ldr r2, [r10, #12] /* load SCONR content from NVRAM */
+ ldr r2, [r10, #20] /* load SCONR content from NVRAM */
str r2, [r1, #0x00] /* store configuration to config reg */
/* STMG0R */
- ldr r2, [r10, #16] /* load STMG0R content from NVRAM */
+ ldr r2, [r10, #24] /* load STMG0R content from NVRAM */
str r2, [r1, #0x04] /* store configuration to config reg */
/* STMG1R */
- ldr r2, [r10, #20] /* load STMG1R content from NVRAM */
+ ldr r2, [r10, #28] /* load STMG1R content from NVRAM */
str r2, [r1, #0x08] /* store configuration to config reg */
/* SREFR */
- ldr r2, [r10, #24] /* load SREFR content from NVRAM */
+ ldr r2, [r10, #32] /* load SREFR content from NVRAM */
str r2, [r1, #0x10] /* store configuration to config reg */
/* reinitialize SDRAM for changes to take effect */
diff --git a/cleopatre/u-boot-1.1.6/include/configs/arizona.h b/cleopatre/u-boot-1.1.6/include/configs/arizona.h
index d1d720823c..f2e7036f5e 100644
--- a/cleopatre/u-boot-1.1.6/include/configs/arizona.h
+++ b/cleopatre/u-boot-1.1.6/include/configs/arizona.h
@@ -29,7 +29,7 @@
#include <asm/hardware.h>
/* Use SPI Flash */
-#define USE_SPI_FLASH
+//#define USE_SPI_FLASH
/*
* If we are developing, we might want to start armboot from ram
@@ -37,7 +37,7 @@
*/
#undef CONFIG_INIT_CRITICAL /* undef for developing */
#define CONFIG_EXEC_FROM_SDRAM 1
-#define CONFIG_EXEC_FROM_SPI 1 /* boot on the SPI flash */
+//#define CONFIG_EXEC_FROM_SPI 1 /* boot on the SPI flash */
//#define MARIA_CORE_90MHZ 1
//#define MARIA_MASTER_CLOCK 45000000 /* peripheral clock */
@@ -164,10 +164,10 @@
#endif
#define CONFIG_ETHADDR 00:50:c2:38:00:0B
-#define CONFIG_SERVERIP 192.168.003.011
-#define CONFIG_IPADDR 192.168.003.199
+#define CONFIG_SERVERIP 192.168.002.069
+#define CONFIG_IPADDR 192.168.002.199
#define CONFIG_NETMASK 255.255.255.000
-#define CONFIG_GATEWAYIP 192.168.003.011
+#define CONFIG_GATEWAYIP 192.168.002.069
#define CONFIG_HOSTNAME spc300
#define CONFIG_BOOTFILE "linux-kernel-2.6.25.10-arm"
diff --git a/cleopatre/u-boot-1.1.6/lib_arm/board.c b/cleopatre/u-boot-1.1.6/lib_arm/board.c
index 612e79997a..425005e659 100644
--- a/cleopatre/u-boot-1.1.6/lib_arm/board.c
+++ b/cleopatre/u-boot-1.1.6/lib_arm/board.c
@@ -248,6 +248,9 @@ void start_armboot (void)
#if defined(CONFIG_VFD) || defined(CONFIG_LCD)
unsigned long addr;
#endif
+#ifdef CONFIG_ARCH_SPC300
+ register volatile unsigned int tmp asm ("r10");
+#endif
/* Pointer is writable since we allocated a register for it */
gd = (gd_t*)(_armboot_start - CFG_MALLOC_LEN - sizeof(gd_t));
@@ -258,6 +261,11 @@ void start_armboot (void)
gd->bd = (bd_t*)((char*)gd - sizeof(bd_t));
memset (gd->bd, 0, sizeof (bd_t));
+#ifdef CONFIG_ARCH_SPC300
+ /* NVRAM address will be passed to C from assembly start-up in reg r10 */
+ gd->bd->bi_nvram_addr = tmp;
+#endif
+
monitor_flash_len = _bss_start - _armboot_start;
for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr) {
@@ -328,79 +336,33 @@ void start_armboot (void)
#ifdef SPC300_NVRAM
{
flash_info_t * flinfo = &( flash_info[0] ); /* we expect HW to have only one flash, thus only one flinfo */
- char *nvram_addr = NULL;
spc300_nvram_t *nvram = NULL;
- int sect = 0;
- char nvram_magic[8];
char nvram_eth[6];
char eth_str[18] = {0}; /* in the form 11:22:33:44:55:66, i.e. with ':' delimiters */
- int i =0;
- /* search for the "NVRAM\0\0\0" string on the begining of the each sector */
- for (sect=0; sect < flinfo->sector_count; ++sect)
+
+ nvram = (spc300_nvram_t *)(gd->bd->bi_nvram_addr);
+
+ if (nvram != NULL)
{
/* read begining of the sector in local array variable */
- if ( flash_read_spi ((unsigned char *)flinfo->start[sect], (unsigned char *)nvram_magic, 8, 1, 0) != ERR_OK )
+ if ( flash_read_spi ((unsigned char *)(nvram->eth_address), (unsigned char *)nvram_eth, 6, 1, 0) != ERR_OK )
{
printf("ERROR : read from SPI flash failed.\n");
return;
}
- /* compare this with magic word (for SPC300 that is "NVRAM\0\0\0") */
- if ( memcmp( nvram_magic, "NVRAM\0\0\0", 8 ) != 0 )
- {
- continue;
- }
- else
- {
- /* found it! */
- nvram_addr = flinfo->start[sect];
-
-#ifndef CONFIG_EXEC_FROM_SPI
- nvram_addr -= 0x78000000; /* FCM3 fix when executed from Flash NOR -- remove later!!! */
-#endif /* CONFIG_EXEC_FROM_SPI */
-
- //printf ("FOUND NVRAM at address %#x\n", nvram_addr);
- break;
- }
}
-
- if ( nvram_addr == NULL )
- {
- printf ("Error : NVRAM not found in flash.\n");
- return;
- }
-
- nvram = (spc300_nvram_t *)nvram_addr;
-
- /* read begining of the sector in local array variable */
- if ( flash_read_spi ((unsigned char *)(nvram->eth_address), (unsigned char *)nvram_eth, 6, 1, 0) != ERR_OK )
+ else
{
- printf("ERROR : read from SPI flash failed.\n");
- return;
+ strcpy(nvram_eth, "\x1\x1:\x2\x2:\x3\x3:\x4\x4:\x5\x5:\x6\x6");
}
-#if 0
- printf("nvram->eth_address : ");
- for (i=0; i<6; i++)
- printf("%#x ", nvram_eth[i]);
- putc('\n');
-#endif
-
- /* set eth addr in global data */
- memcpy(gd->bd->bi_enetaddr, nvram_eth, 6);
-
-#if 0
- printf("gd->bd->bi_enetaddr : ");
- for (i=0; i<6; i++)
- printf("%#x ", (gd->bd->bi_enetaddr)[i]);
- putc('\n');
-#endif
sprintf( eth_str, "%.2x:%.2x:%.2x:%.2x:%.2x:%.2x",
nvram_eth[0], nvram_eth[1], nvram_eth[2],
nvram_eth[3], nvram_eth[4], nvram_eth[5] );
- //printf("Setting eth addr to : %s\n", eth_str);
+printf("Setting eth addr to : %s\n", eth_str);
/* now set env with it */
setenv("ethaddr", eth_str);