This patch enables writing (the environment) to the internal flash in
the microcontroller.

Signed-off-by: Gunnar Rangoy <[EMAIL PROTECTED]>
Signed-off-by: Paul Driveklepp <[EMAIL PROTECTED]>
Signed-off-by: Olav Morken <[EMAIL PROTECTED]>
---
 cpu/at32uc/flashc.c         |   69 +++++++++++++++++++++++++++++++++++++++++--
 cpu/at32uc/flashc.h         |   17 ++++++++++
 include/configs/atevk1100.h |    2 +-
 3 files changed, 84 insertions(+), 4 deletions(-)

diff --git a/cpu/at32uc/flashc.c b/cpu/at32uc/flashc.c
index f33a4bb..e626e1f 100644
--- a/cpu/at32uc/flashc.c
+++ b/cpu/at32uc/flashc.c
@@ -45,6 +45,7 @@ unsigned long flash_init(void)
 {
        unsigned long fsz;
        unsigned long size;
+       unsigned int i;
 
        fsz = FLASHC_BFEXT(FSZ, flashc_readl(FSR));
 
@@ -55,6 +56,10 @@ unsigned long flash_init(void)
        /* Currently, all interflash have pages which are 128 words. */
        flash_info[0].sector_count = size / (128*4);
 
+       for(i=0; i<flash_info[0].sector_count; i++){
+               flash_info[0].start[i] = i*128*4 + CFG_FLASH_BASE;
+       }
+
        return size;
 }
 
@@ -62,19 +67,77 @@ void flash_print_info(flash_info_t *info)
 {
        printf("Flash: Vendor ID: 0x%02lx, Product ID: 0x%02lx\n",
               info->flash_id >> 16, info->flash_id & 0xffff);
-       printf("Size: %ld MB in %d sectors\n",
+       printf("Size: %ld kB in %d sectors\n",
               info->size >> 10, info->sector_count);
 }
 
+static void flash_wait_ready(void)
+{
+       while(! flashc_readl(FSR) & FLASHC_BIT(FRDY) );
+}
+
 int flash_erase(flash_info_t *info, int s_first, int s_last)
 {
-       /* TODO */
+       int page;
+
+       for(page=s_first;page<s_last; page++){
+               flash_wait_ready();
+               flashc_writel(
+                       FCMD,FLASHC_BF(CMD, FLASHC_EP)
+                       |FLASHC_BF(PAGEN, page)
+                       |FLASHC_BF(KEY, 0xa5));
+       }
        return ERR_OK;
 }
 
+static void write_flash_page(unsigned int pagen, const u32 *data)
+{
+       unsigned int i;
+       u32 *dst;
+
+       dst = (u32 *) CFG_FLASH_BASE;
+
+       /* clear page buffer */
+       flash_wait_ready();
+       flashc_writel(FCMD,
+               FLASHC_BF(CMD, FLASHC_CPB) |
+               FLASHC_BF(KEY, 0xa5));
+
+       /* fill page buffer*/
+       flash_wait_ready();
+       for(i=0; i<128; i++){
+               dst[i]=data[i];
+       }
+
+       /* issue write command */
+       flashc_writel(FCMD,
+               FLASHC_BF(CMD, FLASHC_WP)|
+               FLASHC_BF(PAGEN, pagen)|
+               FLASHC_BF(KEY, 0xa5));
+}
+
 int write_buff(flash_info_t *info, uchar *src, ulong addr, ulong count)
 {
-       /* TODO */
+       unsigned int i;
+
+       if (addr % (4*128)) {
+               printf("flash: write_buff(): ERROR, addr(0x%08lx) not "
+                       "on page boundary", addr);
+               return ERR_ALIGN;
+       }
+       if (count % (4*128)) {
+               printf("flash: write_buff(): ERROR, count(0x%lu) not "
+                       "a multiple of pagesize", count);
+               return ERR_ALIGN;
+       }
+
+       for (i = 0; i < count; i += 128*4) {
+               unsigned int pagen;
+               pagen = (addr-CFG_FLASH_BASE+i) / (128*4);
+               write_flash_page(pagen, (u32*) (src+i));
+       }
+
+
        return ERR_OK;
 }
 
diff --git a/cpu/at32uc/flashc.h b/cpu/at32uc/flashc.h
index 23618bc..3e97781 100644
--- a/cpu/at32uc/flashc.h
+++ b/cpu/at32uc/flashc.h
@@ -43,6 +43,23 @@
 #define FLASHC_LOCK_OFFSET                     16
 #define FLASHC_LOCK_SIZE                       16
 
+#define FLASHC_NOP     0 /*No operation*/
+#define FLASHC_WP      1 /*Write Page*/
+#define FLASHC_EP      2 /*Erase Page*/
+#define FLASHC_CPB     3 /*Clear Page Buffer*/
+#define FLASHC_LP      4 /*Lock region containing given Page*/
+#define FLASHC_UP      5 /*Unlock region containing given Page*/
+#define FLASHC_EA      6 /*Erase All*/
+#define FLASHC_WGPB    7 /*Write General-Purpose Fuse Bit*/
+#define FLASHC_EGPB    8 /*Erase General-Purpose Fuse Bit*/
+#define FLASHC_SSB     9 /*Set Security Bit*/
+#define FLASHC_PGPFB   10 /*Program GP Fuse Byte*/
+#define FLASHC_EAGPF   11 /*Erase All GPFuses*/
+#define FLASHC_QPR     12 /*Quick Page Read*/
+#define FLASHC_WUP     13 /*Write User Page*/
+#define FLASHC_EUP     14 /*Erase User Page*/
+#define FLASHC_QPRUP   15 /*Quick Page Read User Page*/
+
 
 /* Bit manipulation macros */
 #define FLASHC_BIT(name)                                       \
diff --git a/include/configs/atevk1100.h b/include/configs/atevk1100.h
index 166027a..776a3a1 100644
--- a/include/configs/atevk1100.h
+++ b/include/configs/atevk1100.h
@@ -160,7 +160,7 @@
 #define CFG_FLASH_BASE                 0x80000000
 #define CFG_FLASH_SIZE                 0x80000
 #define CFG_MAX_FLASH_BANKS            1
-#define CFG_MAX_FLASH_SECT             135
+#define CFG_MAX_FLASH_SECT             1024
 
 #define CFG_MONITOR_BASE               CFG_FLASH_BASE
 
-- 
1.5.6.3

_______________________________________________
U-Boot mailing list
U-Boot@lists.denx.de
http://lists.denx.de/mailman/listinfo/u-boot

Reply via email to