wdenk | 2d24a3a | 2004-06-09 21:50:45 +0000 | [diff] [blame] | 1 | /* |
| 2 | * board/mx1ads/syncflash.c |
wdenk | 49822e2 | 2004-06-19 21:19:10 +0000 | [diff] [blame] | 3 | * |
wdenk | 2d24a3a | 2004-06-09 21:50:45 +0000 | [diff] [blame] | 4 | * (c) Copyright 2004 |
| 5 | * Techware Information Technology, Inc. |
| 6 | * http://www.techware.com.tw/ |
| 7 | * |
| 8 | * Ming-Len Wu <minglen_wu@techware.com.tw> |
| 9 | * |
Wolfgang Denk | 1a45966 | 2013-07-08 09:37:19 +0200 | [diff] [blame] | 10 | * SPDX-License-Identifier: GPL-2.0+ |
wdenk | 2d24a3a | 2004-06-09 21:50:45 +0000 | [diff] [blame] | 11 | */ |
| 12 | |
| 13 | #include <common.h> |
wdenk | 281e00a | 2004-08-01 22:48:16 +0000 | [diff] [blame] | 14 | /*#include <mc9328.h>*/ |
| 15 | #include <asm/arch/imx-regs.h> |
wdenk | 2d24a3a | 2004-06-09 21:50:45 +0000 | [diff] [blame] | 16 | |
| 17 | typedef unsigned long * p_u32; |
| 18 | |
| 19 | /* 4Mx16x2 IAM=0 CSD1 */ |
| 20 | |
Jean-Christophe PLAGNIOL-VILLARD | 6d0f6bc | 2008-10-16 15:01:15 +0200 | [diff] [blame] | 21 | flash_info_t flash_info[CONFIG_SYS_MAX_FLASH_BANKS]; /* info for FLASH chips */ |
wdenk | 2d24a3a | 2004-06-09 21:50:45 +0000 | [diff] [blame] | 22 | |
| 23 | /* Following Setting is for CSD1 */ |
wdenk | 281e00a | 2004-08-01 22:48:16 +0000 | [diff] [blame] | 24 | #define SFCTL 0x00221004 |
| 25 | #define reg_SFCTL __REG(SFCTL) |
wdenk | 2d24a3a | 2004-06-09 21:50:45 +0000 | [diff] [blame] | 26 | |
wdenk | 281e00a | 2004-08-01 22:48:16 +0000 | [diff] [blame] | 27 | #define SYNCFLASH_A10 (0x00100000) |
wdenk | 2d24a3a | 2004-06-09 21:50:45 +0000 | [diff] [blame] | 28 | |
wdenk | 281e00a | 2004-08-01 22:48:16 +0000 | [diff] [blame] | 29 | #define CMD_NORMAL (0x81020300) /* Normal Mode */ |
Wolfgang Denk | 53677ef | 2008-05-20 16:00:29 +0200 | [diff] [blame] | 30 | #define CMD_PREC (CMD_NORMAL + 0x10000000) /* Precharge Command */ |
| 31 | #define CMD_AUTO (CMD_NORMAL + 0x20000000) /* Auto Refresh Command */ |
| 32 | #define CMD_LMR (CMD_NORMAL + 0x30000000) /* Load Mode Register Command */ |
| 33 | #define CMD_LCR (CMD_NORMAL + 0x60000000) /* LCR Command */ |
wdenk | 281e00a | 2004-08-01 22:48:16 +0000 | [diff] [blame] | 34 | #define CMD_PROGRAM (CMD_NORMAL + 0x70000000) |
wdenk | 2d24a3a | 2004-06-09 21:50:45 +0000 | [diff] [blame] | 35 | |
Jean-Christophe PLAGNIOL-VILLARD | 6d0f6bc | 2008-10-16 15:01:15 +0200 | [diff] [blame] | 36 | #define MODE_REG_VAL (CONFIG_SYS_FLASH_BASE+0x0008CC00) /* Cas Latency 3 */ |
wdenk | 2d24a3a | 2004-06-09 21:50:45 +0000 | [diff] [blame] | 37 | |
| 38 | /* LCR Command */ |
wdenk | 281e00a | 2004-08-01 22:48:16 +0000 | [diff] [blame] | 39 | #define LCR_READSTATUS (0x0001C000) /* 0x70 */ |
| 40 | #define LCR_ERASE_CONFIRM (0x00008000) /* 0x20 */ |
| 41 | #define LCR_ERASE_NVMODE (0x0000C000) /* 0x30 */ |
| 42 | #define LCR_PROG_NVMODE (0x00028000) /* 0xA0 */ |
| 43 | #define LCR_SR_CLEAR (0x00014000) /* 0x50 */ |
wdenk | 2d24a3a | 2004-06-09 21:50:45 +0000 | [diff] [blame] | 44 | |
Wolfgang Denk | 53677ef | 2008-05-20 16:00:29 +0200 | [diff] [blame] | 45 | /* Get Status register */ |
wdenk | 2d24a3a | 2004-06-09 21:50:45 +0000 | [diff] [blame] | 46 | u32 SF_SR(void) { |
Anatolij Gustschin | 6859ea7 | 2011-11-19 13:12:16 +0000 | [diff] [blame] | 47 | u32 tmp; |
wdenk | 2d24a3a | 2004-06-09 21:50:45 +0000 | [diff] [blame] | 48 | |
| 49 | reg_SFCTL = CMD_PROGRAM; |
Jean-Christophe PLAGNIOL-VILLARD | 6d0f6bc | 2008-10-16 15:01:15 +0200 | [diff] [blame] | 50 | tmp = __REG(CONFIG_SYS_FLASH_BASE); |
wdenk | 49822e2 | 2004-06-19 21:19:10 +0000 | [diff] [blame] | 51 | |
wdenk | 2d24a3a | 2004-06-09 21:50:45 +0000 | [diff] [blame] | 52 | reg_SFCTL = CMD_NORMAL; |
| 53 | |
Wolfgang Denk | 53677ef | 2008-05-20 16:00:29 +0200 | [diff] [blame] | 54 | reg_SFCTL = CMD_LCR; /* Activate LCR Mode */ |
Anatolij Gustschin | 6859ea7 | 2011-11-19 13:12:16 +0000 | [diff] [blame] | 55 | __REG(CONFIG_SYS_FLASH_BASE + LCR_SR_CLEAR); |
wdenk | 2d24a3a | 2004-06-09 21:50:45 +0000 | [diff] [blame] | 56 | |
| 57 | return tmp; |
| 58 | } |
| 59 | |
Wolfgang Denk | 53677ef | 2008-05-20 16:00:29 +0200 | [diff] [blame] | 60 | /* check if SyncFlash is ready */ |
wdenk | 2d24a3a | 2004-06-09 21:50:45 +0000 | [diff] [blame] | 61 | u8 SF_Ready(void) { |
| 62 | u32 tmp; |
| 63 | |
| 64 | tmp = SF_SR(); |
| 65 | |
| 66 | if ((tmp & 0x00800000) && (tmp & 0x001C0000)) { |
| 67 | printf ("SyncFlash Error code %08x\n",tmp); |
| 68 | }; |
| 69 | |
| 70 | if ((tmp & 0x00000080) && (tmp & 0x0000001C)) { |
| 71 | printf ("SyncFlash Error code %08x\n",tmp); |
wdenk | 2d24a3a | 2004-06-09 21:50:45 +0000 | [diff] [blame] | 72 | }; |
| 73 | |
Wolfgang Denk | 53677ef | 2008-05-20 16:00:29 +0200 | [diff] [blame] | 74 | if (tmp == 0x00800080) /* Test Bit 7 of SR */ |
wdenk | 2d24a3a | 2004-06-09 21:50:45 +0000 | [diff] [blame] | 75 | return 1; |
| 76 | else |
| 77 | return 0; |
| 78 | } |
| 79 | |
Wolfgang Denk | 53677ef | 2008-05-20 16:00:29 +0200 | [diff] [blame] | 80 | /* Issue the precharge all command */ |
wdenk | 2d24a3a | 2004-06-09 21:50:45 +0000 | [diff] [blame] | 81 | void SF_PrechargeAll(void) { |
| 82 | |
Anatolij Gustschin | 6859ea7 | 2011-11-19 13:12:16 +0000 | [diff] [blame] | 83 | /* Set Precharge Command */ |
| 84 | reg_SFCTL = CMD_PREC; |
| 85 | /* Issue Precharge All Command */ |
| 86 | __REG(CONFIG_SYS_FLASH_BASE + SYNCFLASH_A10); |
wdenk | 2d24a3a | 2004-06-09 21:50:45 +0000 | [diff] [blame] | 87 | } |
| 88 | |
| 89 | /* set SyncFlash to normal mode */ |
| 90 | void SF_Normal(void) { |
| 91 | |
| 92 | SF_PrechargeAll(); |
wdenk | 49822e2 | 2004-06-19 21:19:10 +0000 | [diff] [blame] | 93 | |
wdenk | 2d24a3a | 2004-06-09 21:50:45 +0000 | [diff] [blame] | 94 | reg_SFCTL = CMD_NORMAL; |
| 95 | } |
| 96 | |
Wolfgang Denk | 53677ef | 2008-05-20 16:00:29 +0200 | [diff] [blame] | 97 | /* Erase SyncFlash */ |
wdenk | 2d24a3a | 2004-06-09 21:50:45 +0000 | [diff] [blame] | 98 | void SF_Erase(u32 RowAddress) { |
wdenk | 2d24a3a | 2004-06-09 21:50:45 +0000 | [diff] [blame] | 99 | |
| 100 | reg_SFCTL = CMD_NORMAL; |
Anatolij Gustschin | 6859ea7 | 2011-11-19 13:12:16 +0000 | [diff] [blame] | 101 | __REG(RowAddress); |
wdenk | 2d24a3a | 2004-06-09 21:50:45 +0000 | [diff] [blame] | 102 | |
| 103 | reg_SFCTL = CMD_PREC; |
Anatolij Gustschin | 6859ea7 | 2011-11-19 13:12:16 +0000 | [diff] [blame] | 104 | __REG(RowAddress); |
wdenk | 49822e2 | 2004-06-19 21:19:10 +0000 | [diff] [blame] | 105 | |
Wolfgang Denk | 53677ef | 2008-05-20 16:00:29 +0200 | [diff] [blame] | 106 | reg_SFCTL = CMD_LCR; /* Set LCR mode */ |
| 107 | __REG(RowAddress + LCR_ERASE_CONFIRM) = 0; /* Issue Erase Setup Command */ |
wdenk | 49822e2 | 2004-06-19 21:19:10 +0000 | [diff] [blame] | 108 | |
Wolfgang Denk | 53677ef | 2008-05-20 16:00:29 +0200 | [diff] [blame] | 109 | reg_SFCTL = CMD_NORMAL; /* return to Normal mode */ |
| 110 | __REG(RowAddress) = 0xD0D0D0D0; /* Confirm */ |
wdenk | 2d24a3a | 2004-06-09 21:50:45 +0000 | [diff] [blame] | 111 | |
| 112 | while(!SF_Ready()); |
| 113 | } |
| 114 | |
wdenk | 2d24a3a | 2004-06-09 21:50:45 +0000 | [diff] [blame] | 115 | void SF_NvmodeErase(void) { |
| 116 | SF_PrechargeAll(); |
| 117 | |
| 118 | reg_SFCTL = CMD_LCR; /* Set to LCR mode */ |
Jean-Christophe PLAGNIOL-VILLARD | 6d0f6bc | 2008-10-16 15:01:15 +0200 | [diff] [blame] | 119 | __REG(CONFIG_SYS_FLASH_BASE + LCR_ERASE_NVMODE) = 0; /* Issue Erase Nvmode Reg Command */ |
wdenk | 49822e2 | 2004-06-19 21:19:10 +0000 | [diff] [blame] | 120 | |
Wolfgang Denk | 53677ef | 2008-05-20 16:00:29 +0200 | [diff] [blame] | 121 | reg_SFCTL = CMD_NORMAL; /* Return to Normal mode */ |
Jean-Christophe PLAGNIOL-VILLARD | 6d0f6bc | 2008-10-16 15:01:15 +0200 | [diff] [blame] | 122 | __REG(CONFIG_SYS_FLASH_BASE + LCR_ERASE_NVMODE) = 0xC0C0C0C0; /* Confirm */ |
wdenk | 2d24a3a | 2004-06-09 21:50:45 +0000 | [diff] [blame] | 123 | |
| 124 | while(!SF_Ready()); |
| 125 | } |
| 126 | |
| 127 | void SF_NvmodeWrite(void) { |
| 128 | SF_PrechargeAll(); |
| 129 | |
Wolfgang Denk | 53677ef | 2008-05-20 16:00:29 +0200 | [diff] [blame] | 130 | reg_SFCTL = CMD_LCR; /* Set to LCR mode */ |
Jean-Christophe PLAGNIOL-VILLARD | 6d0f6bc | 2008-10-16 15:01:15 +0200 | [diff] [blame] | 131 | __REG(CONFIG_SYS_FLASH_BASE+LCR_PROG_NVMODE) = 0; /* Issue Program Nvmode reg command */ |
wdenk | 49822e2 | 2004-06-19 21:19:10 +0000 | [diff] [blame] | 132 | |
Wolfgang Denk | 53677ef | 2008-05-20 16:00:29 +0200 | [diff] [blame] | 133 | reg_SFCTL = CMD_NORMAL; /* Return to Normal mode */ |
Jean-Christophe PLAGNIOL-VILLARD | 6d0f6bc | 2008-10-16 15:01:15 +0200 | [diff] [blame] | 134 | __REG(CONFIG_SYS_FLASH_BASE+LCR_PROG_NVMODE) = 0xC0C0C0C0; /* Confirm not needed */ |
wdenk | 2d24a3a | 2004-06-09 21:50:45 +0000 | [diff] [blame] | 135 | } |
| 136 | |
wdenk | 2d24a3a | 2004-06-09 21:50:45 +0000 | [diff] [blame] | 137 | /****************************************************************************************/ |
| 138 | |
| 139 | ulong flash_init(void) { |
| 140 | int i, j; |
wdenk | 2d24a3a | 2004-06-09 21:50:45 +0000 | [diff] [blame] | 141 | |
| 142 | /* Turn on CSD1 for negating RESETSF of SyncFLash */ |
| 143 | |
Wolfgang Denk | 53677ef | 2008-05-20 16:00:29 +0200 | [diff] [blame] | 144 | reg_SFCTL |= 0x80000000; /* enable CSD1 for SyncFlash */ |
wdenk | 2d24a3a | 2004-06-09 21:50:45 +0000 | [diff] [blame] | 145 | udelay(200); |
| 146 | |
Wolfgang Denk | 53677ef | 2008-05-20 16:00:29 +0200 | [diff] [blame] | 147 | reg_SFCTL = CMD_LMR; /* Set Load Mode Register Command */ |
Anatolij Gustschin | 6859ea7 | 2011-11-19 13:12:16 +0000 | [diff] [blame] | 148 | __REG(MODE_REG_VAL); /* Issue Load Mode Register Command */ |
wdenk | 2d24a3a | 2004-06-09 21:50:45 +0000 | [diff] [blame] | 149 | |
| 150 | SF_Normal(); |
wdenk | 49822e2 | 2004-06-19 21:19:10 +0000 | [diff] [blame] | 151 | |
wdenk | 2d24a3a | 2004-06-09 21:50:45 +0000 | [diff] [blame] | 152 | i = 0; |
| 153 | |
Wolfgang Denk | 53677ef | 2008-05-20 16:00:29 +0200 | [diff] [blame] | 154 | flash_info[i].flash_id = FLASH_MAN_MT | FLASH_MT28S4M16LC; |
wdenk | 49822e2 | 2004-06-19 21:19:10 +0000 | [diff] [blame] | 155 | |
Wolfgang Denk | 53677ef | 2008-05-20 16:00:29 +0200 | [diff] [blame] | 156 | flash_info[i].size = FLASH_BANK_SIZE; |
Jean-Christophe PLAGNIOL-VILLARD | 6d0f6bc | 2008-10-16 15:01:15 +0200 | [diff] [blame] | 157 | flash_info[i].sector_count = CONFIG_SYS_MAX_FLASH_SECT; |
wdenk | 2d24a3a | 2004-06-09 21:50:45 +0000 | [diff] [blame] | 158 | |
Jean-Christophe PLAGNIOL-VILLARD | 6d0f6bc | 2008-10-16 15:01:15 +0200 | [diff] [blame] | 159 | memset(flash_info[i].protect, 0, CONFIG_SYS_MAX_FLASH_SECT); |
wdenk | 2d24a3a | 2004-06-09 21:50:45 +0000 | [diff] [blame] | 160 | |
| 161 | for (j = 0; j < flash_info[i].sector_count; j++) { |
Jean-Christophe PLAGNIOL-VILLARD | 6d0f6bc | 2008-10-16 15:01:15 +0200 | [diff] [blame] | 162 | flash_info[i].start[j] = CONFIG_SYS_FLASH_BASE + j * 0x00100000; |
wdenk | 2d24a3a | 2004-06-09 21:50:45 +0000 | [diff] [blame] | 163 | } |
wdenk | 49822e2 | 2004-06-19 21:19:10 +0000 | [diff] [blame] | 164 | |
wdenk | 2d24a3a | 2004-06-09 21:50:45 +0000 | [diff] [blame] | 165 | flash_protect(FLAG_PROTECT_SET, |
Jean-Christophe PLAGNIOL-VILLARD | 6d0f6bc | 2008-10-16 15:01:15 +0200 | [diff] [blame] | 166 | CONFIG_SYS_FLASH_BASE, |
| 167 | CONFIG_SYS_FLASH_BASE + monitor_flash_len - 1, |
wdenk | 2d24a3a | 2004-06-09 21:50:45 +0000 | [diff] [blame] | 168 | &flash_info[0]); |
| 169 | |
| 170 | flash_protect(FLAG_PROTECT_SET, |
Jean-Christophe PLAGNIOL-VILLARD | 0e8d158 | 2008-09-10 22:48:06 +0200 | [diff] [blame] | 171 | CONFIG_ENV_ADDR, |
| 172 | CONFIG_ENV_ADDR + CONFIG_ENV_SIZE - 1, |
wdenk | 2d24a3a | 2004-06-09 21:50:45 +0000 | [diff] [blame] | 173 | &flash_info[0]); |
| 174 | |
| 175 | return FLASH_BANK_SIZE; |
| 176 | } |
| 177 | |
wdenk | 2d24a3a | 2004-06-09 21:50:45 +0000 | [diff] [blame] | 178 | void flash_print_info (flash_info_t *info) { |
| 179 | |
| 180 | int i; |
| 181 | |
| 182 | switch (info->flash_id & FLASH_VENDMASK) { |
| 183 | case (FLASH_MAN_MT & FLASH_VENDMASK): |
| 184 | printf("Micron: "); |
| 185 | break; |
| 186 | default: |
| 187 | printf("Unknown Vendor "); |
| 188 | break; |
| 189 | } |
wdenk | 49822e2 | 2004-06-19 21:19:10 +0000 | [diff] [blame] | 190 | |
wdenk | 2d24a3a | 2004-06-09 21:50:45 +0000 | [diff] [blame] | 191 | switch (info->flash_id & FLASH_TYPEMASK) { |
| 192 | case (FLASH_MT28S4M16LC & FLASH_TYPEMASK): |
| 193 | printf("2x FLASH_MT28S4M16LC (16MB Total)\n"); |
| 194 | break; |
| 195 | default: |
| 196 | printf("Unknown Chip Type\n"); |
| 197 | return; |
| 198 | break; |
| 199 | } |
| 200 | |
| 201 | printf(" Size: %ld MB in %d Sectors\n", |
| 202 | info->size >> 20, info->sector_count); |
| 203 | |
| 204 | printf(" Sector Start Addresses: "); |
| 205 | |
| 206 | for (i = 0; i < info->sector_count; i++) { |
wdenk | 49822e2 | 2004-06-19 21:19:10 +0000 | [diff] [blame] | 207 | if ((i % 5) == 0) |
wdenk | 2d24a3a | 2004-06-09 21:50:45 +0000 | [diff] [blame] | 208 | printf ("\n "); |
| 209 | |
| 210 | printf (" %08lX%s", info->start[i], |
| 211 | info->protect[i] ? " (RO)" : " "); |
| 212 | } |
wdenk | 49822e2 | 2004-06-19 21:19:10 +0000 | [diff] [blame] | 213 | |
wdenk | 2d24a3a | 2004-06-09 21:50:45 +0000 | [diff] [blame] | 214 | printf ("\n"); |
| 215 | } |
| 216 | |
wdenk | 2d24a3a | 2004-06-09 21:50:45 +0000 | [diff] [blame] | 217 | /*-----------------------------------------------------------------------*/ |
| 218 | |
| 219 | int flash_erase (flash_info_t *info, int s_first, int s_last) { |
| 220 | int iflag, cflag, prot, sect; |
| 221 | int rc = ERR_OK; |
| 222 | |
| 223 | /* first look for protection bits */ |
| 224 | |
| 225 | if (info->flash_id == FLASH_UNKNOWN) |
| 226 | return ERR_UNKNOWN_FLASH_TYPE; |
| 227 | |
wdenk | 49822e2 | 2004-06-19 21:19:10 +0000 | [diff] [blame] | 228 | if ((s_first < 0) || (s_first > s_last)) |
wdenk | 2d24a3a | 2004-06-09 21:50:45 +0000 | [diff] [blame] | 229 | return ERR_INVAL; |
| 230 | |
wdenk | 49822e2 | 2004-06-19 21:19:10 +0000 | [diff] [blame] | 231 | if ((info->flash_id & FLASH_VENDMASK) != (FLASH_MAN_MT & FLASH_VENDMASK)) |
wdenk | 2d24a3a | 2004-06-09 21:50:45 +0000 | [diff] [blame] | 232 | return ERR_UNKNOWN_FLASH_VENDOR; |
| 233 | |
| 234 | prot = 0; |
| 235 | |
| 236 | for (sect = s_first; sect <= s_last; ++sect) { |
wdenk | 49822e2 | 2004-06-19 21:19:10 +0000 | [diff] [blame] | 237 | if (info->protect[sect]) |
wdenk | 2d24a3a | 2004-06-09 21:50:45 +0000 | [diff] [blame] | 238 | prot++; |
| 239 | } |
wdenk | 49822e2 | 2004-06-19 21:19:10 +0000 | [diff] [blame] | 240 | |
wdenk | 2d24a3a | 2004-06-09 21:50:45 +0000 | [diff] [blame] | 241 | if (prot) { |
| 242 | printf("protected!\n"); |
| 243 | return ERR_PROTECTED; |
| 244 | } |
| 245 | /* |
| 246 | * Disable interrupts which might cause a timeout |
| 247 | * here. Remember that our exception vectors are |
| 248 | * at address 0 in the flash, and we don't want a |
| 249 | * (ticker) exception to happen while the flash |
| 250 | * chip is in programming mode. |
| 251 | */ |
| 252 | |
| 253 | cflag = icache_status(); |
| 254 | icache_disable(); |
| 255 | iflag = disable_interrupts(); |
| 256 | |
| 257 | /* Start erase on unprotected sectors */ |
| 258 | for (sect = s_first; sect <= s_last && !ctrlc(); sect++) { |
wdenk | 49822e2 | 2004-06-19 21:19:10 +0000 | [diff] [blame] | 259 | |
wdenk | 2d24a3a | 2004-06-09 21:50:45 +0000 | [diff] [blame] | 260 | printf("Erasing sector %2d ... ", sect); |
| 261 | |
| 262 | /* arm simple, non interrupt dependent timer */ |
| 263 | |
Graeme Russ | a60d1e5 | 2011-07-15 23:31:37 +0000 | [diff] [blame] | 264 | get_timer(0); |
wdenk | 2d24a3a | 2004-06-09 21:50:45 +0000 | [diff] [blame] | 265 | |
| 266 | SF_NvmodeErase(); |
| 267 | SF_NvmodeWrite(); |
| 268 | |
Jean-Christophe PLAGNIOL-VILLARD | 6d0f6bc | 2008-10-16 15:01:15 +0200 | [diff] [blame] | 269 | SF_Erase(CONFIG_SYS_FLASH_BASE + (0x0100000 * sect)); |
wdenk | 2d24a3a | 2004-06-09 21:50:45 +0000 | [diff] [blame] | 270 | SF_Normal(); |
| 271 | |
| 272 | printf("ok.\n"); |
| 273 | } |
| 274 | |
| 275 | if (ctrlc()) |
| 276 | printf("User Interrupt!\n"); |
| 277 | |
| 278 | if (iflag) |
| 279 | enable_interrupts(); |
| 280 | |
| 281 | if (cflag) |
| 282 | icache_enable(); |
| 283 | |
| 284 | return rc; |
| 285 | } |
| 286 | |
wdenk | 2d24a3a | 2004-06-09 21:50:45 +0000 | [diff] [blame] | 287 | /*----------------------------------------------------------------------- |
| 288 | * Copy memory to flash. |
| 289 | */ |
| 290 | |
| 291 | int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt) { |
| 292 | int i; |
| 293 | |
wdenk | 49822e2 | 2004-06-19 21:19:10 +0000 | [diff] [blame] | 294 | for(i = 0; i < cnt; i += 4) { |
wdenk | 2d24a3a | 2004-06-09 21:50:45 +0000 | [diff] [blame] | 295 | |
| 296 | SF_PrechargeAll(); |
| 297 | |
| 298 | reg_SFCTL = CMD_PROGRAM; /* Enter SyncFlash Program mode */ |
| 299 | __REG(addr + i) = __REG((u32)src + i); |
| 300 | |
| 301 | while(!SF_Ready()); |
| 302 | } |
| 303 | |
| 304 | SF_Normal(); |
wdenk | 49822e2 | 2004-06-19 21:19:10 +0000 | [diff] [blame] | 305 | |
wdenk | 2d24a3a | 2004-06-09 21:50:45 +0000 | [diff] [blame] | 306 | return ERR_OK; |
| 307 | } |