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