1 /* 2 * (C) Copyright 2000-2003 3 * Wolfgang Denk, DENX Software Engineering, wd@denx.de. 4 * 5 * SPDX-License-Identifier: GPL-2.0+ 6 */ 7 8 #include <common.h> 9 #include <console.h> 10 11 #define PHYS_FLASH_1 CONFIG_SYS_FLASH_BASE 12 #define FLASH_BANK_SIZE 0x200000 13 14 flash_info_t flash_info[CONFIG_SYS_MAX_FLASH_BANKS]; 15 16 void flash_print_info (flash_info_t * info) 17 { 18 int i; 19 20 switch (info->flash_id & FLASH_VENDMASK) { 21 case (AMD_MANUFACT & FLASH_VENDMASK): 22 printf ("AMD: "); 23 break; 24 default: 25 printf ("Unknown Vendor "); 26 break; 27 } 28 29 switch (info->flash_id & FLASH_TYPEMASK) { 30 case (AMD_ID_PL160CB & FLASH_TYPEMASK): 31 printf ("AM29PL160CB (16Mbit)\n"); 32 break; 33 default: 34 printf ("Unknown Chip Type\n"); 35 goto Done; 36 break; 37 } 38 39 printf (" Size: %ld MB in %d Sectors\n", 40 info->size >> 20, info->sector_count); 41 42 printf (" Sector Start Addresses:"); 43 for (i = 0; i < info->sector_count; i++) { 44 if ((i % 5) == 0) { 45 printf ("\n "); 46 } 47 printf (" %08lX%s", info->start[i], 48 info->protect[i] ? " (RO)" : " "); 49 } 50 printf ("\n"); 51 52 Done: 53 return; 54 } 55 56 57 unsigned long flash_init (void) 58 { 59 int i, j; 60 ulong size = 0; 61 62 for (i = 0; i < CONFIG_SYS_MAX_FLASH_BANKS; i++) { 63 ulong flashbase = 0; 64 65 flash_info[i].flash_id = 66 (AMD_MANUFACT & FLASH_VENDMASK) | 67 (AMD_ID_PL160CB & FLASH_TYPEMASK); 68 flash_info[i].size = FLASH_BANK_SIZE; 69 flash_info[i].sector_count = CONFIG_SYS_MAX_FLASH_SECT; 70 memset (flash_info[i].protect, 0, CONFIG_SYS_MAX_FLASH_SECT); 71 if (i == 0) 72 flashbase = PHYS_FLASH_1; 73 else 74 panic ("configured to many flash banks!\n"); 75 76 for (j = 0; j < flash_info[i].sector_count; j++) { 77 if (j == 0) { 78 /* 1st is 16 KiB */ 79 flash_info[i].start[j] = flashbase; 80 } 81 if ((j >= 1) && (j <= 2)) { 82 /* 2nd and 3rd are 8 KiB */ 83 flash_info[i].start[j] = 84 flashbase + 0x4000 + 0x2000 * (j - 1); 85 } 86 if (j == 3) { 87 /* 4th is 224 KiB */ 88 flash_info[i].start[j] = flashbase + 0x8000; 89 } 90 if ((j >= 4) && (j <= 10)) { 91 /* rest is 256 KiB */ 92 flash_info[i].start[j] = 93 flashbase + 0x40000 + 0x40000 * (j - 94 4); 95 } 96 } 97 size += flash_info[i].size; 98 } 99 100 flash_protect (FLAG_PROTECT_SET, 101 CONFIG_SYS_FLASH_BASE, 102 CONFIG_SYS_FLASH_BASE + 0x3ffff, &flash_info[0]); 103 104 return size; 105 } 106 107 108 #define CMD_READ_ARRAY 0x00F0 109 #define CMD_UNLOCK1 0x00AA 110 #define CMD_UNLOCK2 0x0055 111 #define CMD_ERASE_SETUP 0x0080 112 #define CMD_ERASE_CONFIRM 0x0030 113 #define CMD_PROGRAM 0x00A0 114 #define CMD_UNLOCK_BYPASS 0x0020 115 116 #define MEM_FLASH_ADDR1 (*(volatile u16 *)(CONFIG_SYS_FLASH_BASE + (0x00000555<<1))) 117 #define MEM_FLASH_ADDR2 (*(volatile u16 *)(CONFIG_SYS_FLASH_BASE + (0x000002AA<<1))) 118 119 #define BIT_ERASE_DONE 0x0080 120 #define BIT_RDY_MASK 0x0080 121 #define BIT_PROGRAM_ERROR 0x0020 122 #define BIT_TIMEOUT 0x80000000 /* our flag */ 123 124 #define READY 1 125 #define ERR 2 126 #define TMO 4 127 128 129 int flash_erase (flash_info_t * info, int s_first, int s_last) 130 { 131 ulong result; 132 int iflag, cflag, prot, sect; 133 int rc = ERR_OK; 134 int chip1; 135 ulong start; 136 137 /* first look for protection bits */ 138 139 if (info->flash_id == FLASH_UNKNOWN) 140 return ERR_UNKNOWN_FLASH_TYPE; 141 142 if ((s_first < 0) || (s_first > s_last)) { 143 return ERR_INVAL; 144 } 145 146 if ((info->flash_id & FLASH_VENDMASK) != 147 (AMD_MANUFACT & FLASH_VENDMASK)) { 148 return ERR_UNKNOWN_FLASH_VENDOR; 149 } 150 151 prot = 0; 152 for (sect = s_first; sect <= s_last; ++sect) { 153 if (info->protect[sect]) { 154 prot++; 155 } 156 } 157 if (prot) 158 return ERR_PROTECTED; 159 160 /* 161 * Disable interrupts which might cause a timeout 162 * here. Remember that our exception vectors are 163 * at address 0 in the flash, and we don't want a 164 * (ticker) exception to happen while the flash 165 * chip is in programming mode. 166 */ 167 168 cflag = icache_status (); 169 icache_disable (); 170 iflag = disable_interrupts (); 171 172 printf ("\n"); 173 174 /* Start erase on unprotected sectors */ 175 for (sect = s_first; sect <= s_last && !ctrlc (); sect++) { 176 printf ("Erasing sector %2d ... ", sect); 177 178 /* arm simple, non interrupt dependent timer */ 179 start = get_timer(0); 180 181 if (info->protect[sect] == 0) { /* not protected */ 182 volatile u16 *addr = 183 (volatile u16 *) (info->start[sect]); 184 185 MEM_FLASH_ADDR1 = CMD_UNLOCK1; 186 MEM_FLASH_ADDR2 = CMD_UNLOCK2; 187 MEM_FLASH_ADDR1 = CMD_ERASE_SETUP; 188 189 MEM_FLASH_ADDR1 = CMD_UNLOCK1; 190 MEM_FLASH_ADDR2 = CMD_UNLOCK2; 191 *addr = CMD_ERASE_CONFIRM; 192 193 /* wait until flash is ready */ 194 chip1 = 0; 195 196 do { 197 result = *addr; 198 199 /* check timeout */ 200 if (get_timer(start) > CONFIG_SYS_FLASH_ERASE_TOUT) { 201 MEM_FLASH_ADDR1 = CMD_READ_ARRAY; 202 chip1 = TMO; 203 break; 204 } 205 206 if (!chip1 207 && (result & 0xFFFF) & BIT_ERASE_DONE) 208 chip1 = READY; 209 210 } while (!chip1); 211 212 MEM_FLASH_ADDR1 = CMD_READ_ARRAY; 213 214 if (chip1 == ERR) { 215 rc = ERR_PROG_ERROR; 216 goto outahere; 217 } 218 if (chip1 == TMO) { 219 rc = ERR_TIMEOUT; 220 goto outahere; 221 } 222 223 printf ("ok.\n"); 224 } else { /* it was protected */ 225 226 printf ("protected!\n"); 227 } 228 } 229 230 if (ctrlc ()) 231 printf ("User Interrupt!\n"); 232 233 outahere: 234 /* allow flash to settle - wait 10 ms */ 235 udelay (10000); 236 237 if (iflag) 238 enable_interrupts (); 239 240 if (cflag) 241 icache_enable (); 242 243 return rc; 244 } 245 246 static int write_word (flash_info_t * info, ulong dest, ulong data) 247 { 248 volatile u16 *addr = (volatile u16 *) dest; 249 ulong result; 250 int rc = ERR_OK; 251 int cflag, iflag; 252 int chip1; 253 ulong start; 254 255 /* 256 * Check if Flash is (sufficiently) erased 257 */ 258 result = *addr; 259 if ((result & data) != data) 260 return ERR_NOT_ERASED; 261 262 263 /* 264 * Disable interrupts which might cause a timeout 265 * here. Remember that our exception vectors are 266 * at address 0 in the flash, and we don't want a 267 * (ticker) exception to happen while the flash 268 * chip is in programming mode. 269 */ 270 271 cflag = icache_status (); 272 icache_disable (); 273 iflag = disable_interrupts (); 274 275 MEM_FLASH_ADDR1 = CMD_UNLOCK1; 276 MEM_FLASH_ADDR2 = CMD_UNLOCK2; 277 MEM_FLASH_ADDR1 = CMD_PROGRAM; 278 *addr = data; 279 280 /* arm simple, non interrupt dependent timer */ 281 start = get_timer(0); 282 283 /* wait until flash is ready */ 284 chip1 = 0; 285 do { 286 result = *addr; 287 288 /* check timeout */ 289 if (get_timer(start) > CONFIG_SYS_FLASH_ERASE_TOUT) { 290 chip1 = ERR | TMO; 291 break; 292 } 293 if (!chip1 && ((result & 0x80) == (data & 0x80))) 294 chip1 = READY; 295 296 } while (!chip1); 297 298 *addr = CMD_READ_ARRAY; 299 300 if (chip1 == ERR || *addr != data) 301 rc = ERR_PROG_ERROR; 302 303 if (iflag) 304 enable_interrupts (); 305 306 if (cflag) 307 icache_enable (); 308 309 return rc; 310 } 311 312 313 int write_buff (flash_info_t * info, uchar * src, ulong addr, ulong cnt) 314 { 315 ulong wp, data; 316 int rc; 317 318 if (addr & 1) { 319 printf ("unaligned destination not supported\n"); 320 return ERR_ALIGN; 321 } 322 323 #if 0 324 if (cnt & 1) { 325 printf ("odd transfer sizes not supported\n"); 326 return ERR_ALIGN; 327 } 328 #endif 329 330 wp = addr; 331 332 if (addr & 1) { 333 data = (*((volatile u8 *) addr) << 8) | *((volatile u8 *) 334 src); 335 if ((rc = write_word (info, wp - 1, data)) != 0) { 336 return (rc); 337 } 338 src += 1; 339 wp += 1; 340 cnt -= 1; 341 } 342 343 while (cnt >= 2) { 344 data = *((volatile u16 *) src); 345 if ((rc = write_word (info, wp, data)) != 0) { 346 return (rc); 347 } 348 src += 2; 349 wp += 2; 350 cnt -= 2; 351 } 352 353 if (cnt == 1) { 354 data = (*((volatile u8 *) src) << 8) | 355 *((volatile u8 *) (wp + 1)); 356 if ((rc = write_word (info, wp, data)) != 0) { 357 return (rc); 358 } 359 src += 1; 360 wp += 1; 361 cnt -= 1; 362 } 363 364 return ERR_OK; 365 } 366