flash.c 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818
  1. /*
  2. * (C) Copyright 2002
  3. * Brad Kemp, Seranoa Networks, Brad.Kemp@seranoa.com
  4. *
  5. * Copyright (C) 2003 Arabella Software Ltd.
  6. * Yuli Barcohen <yuli@arabellasw.com>
  7. * Modified to work with AMD flashes
  8. *
  9. * See file CREDITS for list of people who contributed to this
  10. * project.
  11. *
  12. * This program is free software; you can redistribute it and/or
  13. * modify it under the terms of the GNU General Public License as
  14. * published by the Free Software Foundation; either version 2 of
  15. * the License, or (at your option) any later version.
  16. *
  17. * This program is distributed in the hope that it will be useful,
  18. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  19. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  20. * GNU General Public License for more details.
  21. *
  22. * You should have received a copy of the GNU General Public License
  23. * along with this program; if not, write to the Free Software
  24. * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  25. * MA 02111-1307 USA
  26. */
  27. #include <common.h>
  28. #include <asm/processor.h>
  29. #undef DEBUG_FLASH
  30. /*
  31. * This file implements a Common Flash Interface (CFI) driver for U-Boot.
  32. * The width of the port and the width of the chips are determined at initialization.
  33. * These widths are used to calculate the address for access CFI data structures.
  34. * It has been tested on an Intel Strataflash implementation and AMD 29F016D.
  35. *
  36. * References
  37. * JEDEC Standard JESD68 - Common Flash Interface (CFI)
  38. * JEDEC Standard JEP137-A Common Flash Interface (CFI) ID Codes
  39. * Intel Application Note 646 Common Flash Interface (CFI) and Command Sets
  40. * Intel 290667-008 3 Volt Intel StrataFlash Memory datasheet
  41. *
  42. * TODO
  43. *
  44. * Use Primary Extended Query table (PRI) and Alternate Algorithm Query
  45. * Table (ALT) to determine if protection is available
  46. *
  47. * Add support for other command sets Use the PRI and ALT to determine command set
  48. * Verify erase and program timeouts.
  49. */
  50. #define FLASH_CMD_CFI 0x98
  51. #define FLASH_CMD_READ_ID 0x90
  52. #define FLASH_CMD_RESET 0xff
  53. #define FLASH_CMD_BLOCK_ERASE 0x20
  54. #define FLASH_CMD_ERASE_CONFIRM 0xD0
  55. #define FLASH_CMD_WRITE 0x40
  56. #define FLASH_CMD_PROTECT 0x60
  57. #define FLASH_CMD_PROTECT_SET 0x01
  58. #define FLASH_CMD_PROTECT_CLEAR 0xD0
  59. #define FLASH_CMD_CLEAR_STATUS 0x50
  60. #define FLASH_CMD_WRITE_TO_BUFFER 0xE8
  61. #define FLASH_CMD_WRITE_BUFFER_CONFIRM 0xD0
  62. #define FLASH_STATUS_DONE 0x80
  63. #define FLASH_STATUS_ESS 0x40
  64. #define FLASH_STATUS_ECLBS 0x20
  65. #define FLASH_STATUS_PSLBS 0x10
  66. #define FLASH_STATUS_VPENS 0x08
  67. #define FLASH_STATUS_PSS 0x04
  68. #define FLASH_STATUS_DPS 0x02
  69. #define FLASH_STATUS_R 0x01
  70. #define FLASH_STATUS_PROTECT 0x01
  71. #define AMD_CMD_RESET 0xF0
  72. #define AMD_CMD_WRITE 0xA0
  73. #define AMD_CMD_ERASE_START 0x80
  74. #define AMD_CMD_ERASE_SECTOR 0x30
  75. #define AMD_STATUS_TOGGLE 0x40
  76. #define AMD_STATUS_ERROR 0x20
  77. #define FLASH_OFFSET_CFI 0x55
  78. #define FLASH_OFFSET_CFI_RESP 0x10
  79. #define FLASH_OFFSET_WTOUT 0x1F
  80. #define FLASH_OFFSET_WBTOUT 0x20
  81. #define FLASH_OFFSET_ETOUT 0x21
  82. #define FLASH_OFFSET_CETOUT 0x22
  83. #define FLASH_OFFSET_WMAX_TOUT 0x23
  84. #define FLASH_OFFSET_WBMAX_TOUT 0x24
  85. #define FLASH_OFFSET_EMAX_TOUT 0x25
  86. #define FLASH_OFFSET_CEMAX_TOUT 0x26
  87. #define FLASH_OFFSET_SIZE 0x27
  88. #define FLASH_OFFSET_INTERFACE 0x28
  89. #define FLASH_OFFSET_BUFFER_SIZE 0x2A
  90. #define FLASH_OFFSET_NUM_ERASE_REGIONS 0x2C
  91. #define FLASH_OFFSET_ERASE_REGIONS 0x2D
  92. #define FLASH_OFFSET_PROTECT 0x02
  93. #define FLASH_OFFSET_USER_PROTECTION 0x85
  94. #define FLASH_OFFSET_INTEL_PROTECTION 0x81
  95. #define FLASH_MAN_CFI 0x01000000
  96. typedef union {
  97. unsigned char c;
  98. unsigned short w;
  99. unsigned long l;
  100. } cfiword_t;
  101. typedef union {
  102. volatile unsigned char *cp;
  103. volatile unsigned short *wp;
  104. volatile unsigned long *lp;
  105. } cfiptr_t;
  106. #define NUM_ERASE_REGIONS 4
  107. static ulong bank_base[CFG_MAX_FLASH_BANKS] = CFG_FLASH_BANKS_LIST;
  108. flash_info_t flash_info[CFG_MAX_FLASH_BANKS]; /* info for FLASH chips */
  109. /*-----------------------------------------------------------------------
  110. * Functions
  111. */
  112. static void flash_add_byte(flash_info_t *info, cfiword_t * cword, uchar c);
  113. static void flash_make_cmd(flash_info_t * info, uchar cmd, void * cmdbuf);
  114. static void flash_write_cmd(flash_info_t * info, int sect, uint offset, uchar cmd);
  115. static void flash_unlock_seq(flash_info_t *info);
  116. static int flash_isequal(flash_info_t * info, int sect, uint offset, uchar cmd);
  117. static int flash_isset(flash_info_t * info, int sect, uint offset, uchar cmd);
  118. static int flash_toggle(flash_info_t * info, int sect, uint offset, uchar cmd);
  119. static int flash_detect_cfi(flash_info_t * info);
  120. static ulong flash_get_size (ulong base, int banknum);
  121. static int flash_write_cfiword (flash_info_t *info, ulong dest, cfiword_t cword);
  122. static int flash_full_status_check(flash_info_t * info, ulong sector, ulong tout, char * prompt);
  123. #ifdef CFG_FLASH_USE_BUFFER_WRITE
  124. static int flash_write_cfibuffer(flash_info_t * info, ulong dest, uchar * cp, int len);
  125. #endif
  126. /*-----------------------------------------------------------------------
  127. * create an address based on the offset and the port width
  128. */
  129. inline uchar * flash_make_addr(flash_info_t * info, int sect, uint offset)
  130. {
  131. return ((uchar *)(info->start[sect] + (offset * info->portwidth)));
  132. }
  133. /*-----------------------------------------------------------------------
  134. * read a character at a port width address
  135. */
  136. inline uchar flash_read_uchar(flash_info_t * info, uint offset)
  137. {
  138. uchar *cp;
  139. cp = flash_make_addr(info, 0, offset);
  140. return (cp[info->portwidth - 1]);
  141. }
  142. /*-----------------------------------------------------------------------
  143. * read a short word by swapping for ppc format.
  144. */
  145. ushort flash_read_ushort(flash_info_t * info, int sect, uint offset)
  146. {
  147. uchar * addr;
  148. addr = flash_make_addr(info, sect, offset);
  149. return ((addr[(2*info->portwidth) - 1] << 8) | addr[info->portwidth - 1]);
  150. }
  151. /*-----------------------------------------------------------------------
  152. * read a long word by picking the least significant byte of each maiximum
  153. * port size word. Swap for ppc format.
  154. */
  155. ulong flash_read_long(flash_info_t * info, int sect, uint offset)
  156. {
  157. uchar * addr;
  158. addr = flash_make_addr(info, sect, offset);
  159. return ( (addr[(2*info->portwidth) - 1] << 24 ) | (addr[(info->portwidth) -1] << 16) |
  160. (addr[(4*info->portwidth) - 1] << 8) | addr[(3*info->portwidth) - 1]);
  161. }
  162. /*-----------------------------------------------------------------------
  163. */
  164. unsigned long flash_init (void)
  165. {
  166. unsigned long size = 0;
  167. int i;
  168. /* Init: no FLASHes known */
  169. for (i=0; i<CFG_MAX_FLASH_BANKS; ++i) {
  170. flash_info[i].flash_id = FLASH_UNKNOWN;
  171. size += flash_info[i].size = flash_get_size(bank_base[i], i);
  172. if (flash_info[i].flash_id == FLASH_UNKNOWN) {
  173. printf ("## Unknown FLASH on Bank %d - Size = 0x%08lx = %ld MB\n",
  174. i, flash_info[i].size, flash_info[i].size << 20);
  175. }
  176. }
  177. /* Monitor protection ON by default */
  178. #if (CFG_MONITOR_BASE >= CFG_FLASH_BASE)
  179. flash_protect(FLAG_PROTECT_SET,
  180. CFG_MONITOR_BASE,
  181. CFG_MONITOR_BASE + monitor_flash_len - 1,
  182. &flash_info[0]);
  183. #endif
  184. return (size);
  185. }
  186. /*-----------------------------------------------------------------------
  187. */
  188. int flash_erase (flash_info_t *info, int s_first, int s_last)
  189. {
  190. int rcode = 0;
  191. int prot;
  192. int sect;
  193. if( info->flash_id != FLASH_MAN_CFI) {
  194. printf ("Can't erase unknown flash type - aborted\n");
  195. return 1;
  196. }
  197. if ((s_first < 0) || (s_first > s_last)) {
  198. printf ("- no sectors to erase\n");
  199. return 1;
  200. }
  201. prot = 0;
  202. for (sect=s_first; sect<=s_last; ++sect) {
  203. if (info->protect[sect]) {
  204. prot++;
  205. }
  206. }
  207. if (prot) {
  208. printf ("- Warning: %d protected sectors will not be erased!\n",
  209. prot);
  210. } else {
  211. printf ("\n");
  212. }
  213. for (sect = s_first; sect<=s_last; sect++) {
  214. if (info->protect[sect] == 0) { /* not protected */
  215. #ifdef INTEL_COMMANDS
  216. flash_write_cmd(info, sect, 0, FLASH_CMD_CLEAR_STATUS);
  217. flash_write_cmd(info, sect, 0, FLASH_CMD_BLOCK_ERASE);
  218. flash_write_cmd(info, sect, 0, FLASH_CMD_ERASE_CONFIRM);
  219. #else
  220. flash_unlock_seq(info);
  221. flash_write_cmd(info, sect, 0x555, AMD_CMD_ERASE_START);
  222. flash_unlock_seq(info);
  223. flash_write_cmd(info, sect, 0, AMD_CMD_ERASE_SECTOR);
  224. #endif
  225. if(flash_full_status_check(info, sect, info->erase_blk_tout, "erase")) {
  226. rcode = 1;
  227. } else
  228. printf(".");
  229. }
  230. }
  231. printf (" done\n");
  232. return rcode;
  233. }
  234. /*-----------------------------------------------------------------------
  235. */
  236. void flash_print_info (flash_info_t *info)
  237. {
  238. int i;
  239. if (info->flash_id != FLASH_MAN_CFI) {
  240. printf ("missing or unknown FLASH type\n");
  241. return;
  242. }
  243. printf("CFI conformant FLASH (%d x %d)",
  244. (info->portwidth << 3 ), (info->chipwidth << 3 ));
  245. printf (" Size: %ld MB in %d Sectors\n",
  246. info->size >> 20, info->sector_count);
  247. printf(" Erase timeout %ld ms, write timeout %ld ms, buffer write timeout %ld ms, buffer size %d\n",
  248. info->erase_blk_tout, info->write_tout, info->buffer_write_tout, info->buffer_size);
  249. printf (" Sector Start Addresses:");
  250. for (i=0; i<info->sector_count; ++i) {
  251. if ((i % 5) == 0)
  252. printf ("\n");
  253. printf (" %08lX%5s",
  254. info->start[i],
  255. info->protect[i] ? " (RO)" : " "
  256. );
  257. }
  258. printf ("\n");
  259. return;
  260. }
  261. /*-----------------------------------------------------------------------
  262. * Copy memory to flash, returns:
  263. * 0 - OK
  264. * 1 - write timeout
  265. * 2 - Flash not erased
  266. */
  267. int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt)
  268. {
  269. ulong wp;
  270. ulong cp;
  271. int aln;
  272. cfiword_t cword;
  273. int i, rc;
  274. /* get lower aligned address */
  275. wp = (addr & ~(info->portwidth - 1));
  276. /* handle unaligned start */
  277. if((aln = addr - wp) != 0) {
  278. cword.l = 0;
  279. cp = wp;
  280. for(i=0;i<aln; ++i, ++cp)
  281. flash_add_byte(info, &cword, (*(uchar *)cp));
  282. for(; (i< info->portwidth) && (cnt > 0) ; i++) {
  283. flash_add_byte(info, &cword, *src++);
  284. cnt--;
  285. cp++;
  286. }
  287. for(; (cnt == 0) && (i < info->portwidth); ++i, ++cp)
  288. flash_add_byte(info, &cword, (*(uchar *)cp));
  289. if((rc = flash_write_cfiword(info, wp, cword)) != 0)
  290. return rc;
  291. wp = cp;
  292. }
  293. #ifdef CFG_FLASH_USE_BUFFER_WRITE
  294. while(cnt >= info->portwidth) {
  295. i = info->buffer_size > cnt? cnt: info->buffer_size;
  296. if((rc = flash_write_cfibuffer(info, wp, src,i)) != ERR_OK)
  297. return rc;
  298. wp += i;
  299. src += i;
  300. cnt -=i;
  301. }
  302. #else
  303. /* handle the aligned part */
  304. while(cnt >= info->portwidth) {
  305. cword.l = 0;
  306. for(i = 0; i < info->portwidth; i++) {
  307. flash_add_byte(info, &cword, *src++);
  308. }
  309. if((rc = flash_write_cfiword(info, wp, cword)) != 0)
  310. return rc;
  311. wp += info->portwidth;
  312. cnt -= info->portwidth;
  313. }
  314. #endif /* CFG_FLASH_USE_BUFFER_WRITE */
  315. if (cnt == 0) {
  316. return (0);
  317. }
  318. /*
  319. * handle unaligned tail bytes
  320. */
  321. cword.l = 0;
  322. for (i=0, cp=wp; (i<info->portwidth) && (cnt>0); ++i, ++cp) {
  323. flash_add_byte(info, &cword, *src++);
  324. --cnt;
  325. }
  326. for (; i<info->portwidth; ++i, ++cp) {
  327. flash_add_byte(info, & cword, (*(uchar *)cp));
  328. }
  329. return flash_write_cfiword(info, wp, cword);
  330. }
  331. /*-----------------------------------------------------------------------
  332. */
  333. #ifdef CFG_FLASH_PROTECTION
  334. int flash_real_protect(flash_info_t *info, long sector, int prot)
  335. {
  336. int retcode = 0;
  337. flash_write_cmd(info, sector, 0, FLASH_CMD_CLEAR_STATUS);
  338. flash_write_cmd(info, sector, 0, FLASH_CMD_PROTECT);
  339. if(prot)
  340. flash_write_cmd(info, sector, 0, FLASH_CMD_PROTECT_SET);
  341. else
  342. flash_write_cmd(info, sector, 0, FLASH_CMD_PROTECT_CLEAR);
  343. if((retcode = flash_full_status_check(info, sector, info->erase_blk_tout,
  344. prot?"protect":"unprotect")) == 0) {
  345. info->protect[sector] = prot;
  346. /* Intel's unprotect unprotects all locking */
  347. if(prot == 0) {
  348. int i;
  349. for(i = 0 ; i<info->sector_count; i++) {
  350. if(info->protect[i])
  351. flash_real_protect(info, i, 1);
  352. }
  353. }
  354. }
  355. return retcode;
  356. }
  357. #endif /* CFG_FLASH_PROTECTION */
  358. /*-----------------------------------------------------------------------
  359. * wait for XSR.7 to be set. Time out with an error if it does not.
  360. * This routine does not set the flash to read-array mode.
  361. */
  362. static int flash_status_check(flash_info_t * info, ulong sector, ulong tout, char * prompt)
  363. {
  364. ulong start;
  365. /* Wait for command completion */
  366. start = get_timer (0);
  367. while (
  368. #ifdef INTEL_COMMANDS
  369. !flash_isset(info, sector, 0, FLASH_STATUS_DONE)
  370. #else
  371. flash_toggle(info, sector, 0, AMD_STATUS_TOGGLE)
  372. #endif
  373. ) {
  374. if (get_timer(start) > info->erase_blk_tout) {
  375. printf("Flash %s timeout at address %lx\n", prompt, info->start[sector]);
  376. #ifdef INTEL_COMMANDS
  377. flash_write_cmd(info, sector, 0, FLASH_CMD_RESET);
  378. #else
  379. flash_write_cmd(info, sector, 0, AMD_CMD_RESET);
  380. #endif
  381. return ERR_TIMOUT;
  382. }
  383. }
  384. return ERR_OK;
  385. }
  386. /*-----------------------------------------------------------------------
  387. * Wait for XSR.7 to be set, if it times out print an error, otherwise do a full status check.
  388. * This routine sets the flash to read-array mode.
  389. */
  390. static int flash_full_status_check(flash_info_t * info, ulong sector, ulong tout, char * prompt)
  391. {
  392. int retcode;
  393. retcode = flash_status_check(info, sector, tout, prompt);
  394. #ifdef INTEL_COMMANDS
  395. if((retcode == ERR_OK) && !flash_isequal(info,sector, 0, FLASH_STATUS_DONE)) {
  396. retcode = ERR_INVAL;
  397. printf("Flash %s error at address %lx\n", prompt,info->start[sector]);
  398. if(flash_isset(info, sector, 0, FLASH_STATUS_ECLBS | FLASH_STATUS_PSLBS)){
  399. printf("Command Sequence Error.\n");
  400. } else if(flash_isset(info, sector, 0, FLASH_STATUS_ECLBS)){
  401. printf("Block Erase Error.\n");
  402. retcode = ERR_NOT_ERASED;
  403. } else if (flash_isset(info, sector, 0, FLASH_STATUS_PSLBS)) {
  404. printf("Locking Error\n");
  405. }
  406. if(flash_isset(info, sector, 0, FLASH_STATUS_DPS)){
  407. printf("Block locked.\n");
  408. retcode = ERR_PROTECTED;
  409. }
  410. if(flash_isset(info, sector, 0, FLASH_STATUS_VPENS))
  411. printf("Vpp Low Error.\n");
  412. }
  413. flash_write_cmd(info, sector, 0, FLASH_CMD_RESET);
  414. #endif
  415. return retcode;
  416. }
  417. /*-----------------------------------------------------------------------
  418. */
  419. static void flash_add_byte(flash_info_t *info, cfiword_t * cword, uchar c)
  420. {
  421. switch(info->portwidth) {
  422. case FLASH_CFI_8BIT:
  423. cword->c = c;
  424. break;
  425. case FLASH_CFI_16BIT:
  426. cword->w = (cword->w << 8) | c;
  427. break;
  428. case FLASH_CFI_32BIT:
  429. cword->l = (cword->l << 8) | c;
  430. }
  431. }
  432. /*-----------------------------------------------------------------------
  433. * make a proper sized command based on the port and chip widths
  434. */
  435. static void flash_make_cmd(flash_info_t * info, uchar cmd, void * cmdbuf)
  436. {
  437. int i;
  438. uchar *cp = (uchar *)cmdbuf;
  439. for(i=0; i< info->portwidth; i++)
  440. *cp++ = ((i+1) % info->chipwidth) ? '\0':cmd;
  441. }
  442. /*
  443. * Write a proper sized command to the correct address
  444. */
  445. static void flash_write_cmd(flash_info_t * info, int sect, uint offset, uchar cmd)
  446. {
  447. volatile cfiptr_t addr;
  448. cfiword_t cword;
  449. addr.cp = flash_make_addr(info, sect, offset);
  450. flash_make_cmd(info, cmd, &cword);
  451. switch(info->portwidth) {
  452. case FLASH_CFI_8BIT:
  453. *addr.cp = cword.c;
  454. break;
  455. case FLASH_CFI_16BIT:
  456. *addr.wp = cword.w;
  457. break;
  458. case FLASH_CFI_32BIT:
  459. *addr.lp = cword.l;
  460. break;
  461. }
  462. }
  463. static void flash_unlock_seq(flash_info_t *info)
  464. {
  465. flash_write_cmd(info, 0, 0x555, 0xAA);
  466. flash_write_cmd(info, 0, 0x2AA, 0x55);
  467. }
  468. /*-----------------------------------------------------------------------
  469. */
  470. static int flash_isequal(flash_info_t * info, int sect, uint offset, uchar cmd)
  471. {
  472. cfiptr_t cptr;
  473. cfiword_t cword;
  474. int retval;
  475. cptr.cp = flash_make_addr(info, sect, offset);
  476. flash_make_cmd(info, cmd, &cword);
  477. switch(info->portwidth) {
  478. case FLASH_CFI_8BIT:
  479. retval = (cptr.cp[0] == cword.c);
  480. break;
  481. case FLASH_CFI_16BIT:
  482. retval = (cptr.wp[0] == cword.w);
  483. break;
  484. case FLASH_CFI_32BIT:
  485. retval = (cptr.lp[0] == cword.l);
  486. break;
  487. default:
  488. retval = 0;
  489. break;
  490. }
  491. return retval;
  492. }
  493. /*-----------------------------------------------------------------------
  494. */
  495. static int flash_isset(flash_info_t * info, int sect, uint offset, uchar cmd)
  496. {
  497. cfiptr_t cptr;
  498. cfiword_t cword;
  499. int retval;
  500. cptr.cp = flash_make_addr(info, sect, offset);
  501. flash_make_cmd(info, cmd, &cword);
  502. switch(info->portwidth) {
  503. case FLASH_CFI_8BIT:
  504. retval = ((cptr.cp[0] & cword.c) == cword.c);
  505. break;
  506. case FLASH_CFI_16BIT:
  507. retval = ((cptr.wp[0] & cword.w) == cword.w);
  508. break;
  509. case FLASH_CFI_32BIT:
  510. retval = ((cptr.lp[0] & cword.l) == cword.l);
  511. break;
  512. default:
  513. retval = 0;
  514. break;
  515. }
  516. return retval;
  517. }
  518. /*-----------------------------------------------------------------------
  519. */
  520. static int flash_toggle(flash_info_t * info, int sect, uint offset, uchar cmd)
  521. {
  522. cfiptr_t cptr;
  523. cfiword_t cword;
  524. int retval;
  525. cptr.cp = flash_make_addr(info, sect, offset);
  526. flash_make_cmd(info, cmd, &cword);
  527. switch(info->portwidth) {
  528. case FLASH_CFI_8BIT:
  529. retval = ((cptr.cp[0] & cword.c) != (cptr.cp[0] & cword.c));
  530. break;
  531. case FLASH_CFI_16BIT:
  532. retval = ((cptr.wp[0] & cword.w) != (cptr.wp[0] & cword.w));
  533. break;
  534. case FLASH_CFI_32BIT:
  535. retval = ((cptr.lp[0] & cword.l) != (cptr.lp[0] & cword.l));
  536. break;
  537. default:
  538. retval = 0;
  539. break;
  540. }
  541. return retval;
  542. }
  543. /*-----------------------------------------------------------------------
  544. * detect if flash is compatible with the Common Flash Interface (CFI)
  545. * http://www.jedec.org/download/search/jesd68.pdf
  546. *
  547. */
  548. static int flash_detect_cfi(flash_info_t * info)
  549. {
  550. for(info->portwidth=FLASH_CFI_8BIT; info->portwidth <= FLASH_CFI_32BIT;
  551. info->portwidth <<= 1) {
  552. for(info->chipwidth =FLASH_CFI_BY8;
  553. info->chipwidth <= info->portwidth;
  554. info->chipwidth <<= 1) {
  555. flash_write_cmd(info, 0, 0, FLASH_CMD_RESET);
  556. flash_write_cmd(info, 0, FLASH_OFFSET_CFI, FLASH_CMD_CFI);
  557. if(flash_isequal(info, 0, FLASH_OFFSET_CFI_RESP,'Q') &&
  558. flash_isequal(info, 0, FLASH_OFFSET_CFI_RESP + 1, 'R') &&
  559. flash_isequal(info, 0, FLASH_OFFSET_CFI_RESP + 2, 'Y'))
  560. return 1;
  561. }
  562. }
  563. return 0;
  564. }
  565. /*
  566. * The following code cannot be run from FLASH!
  567. *
  568. */
  569. static ulong flash_get_size (ulong base, int banknum)
  570. {
  571. flash_info_t * info = &flash_info[banknum];
  572. int i, j;
  573. int sect_cnt;
  574. unsigned long sector;
  575. unsigned long tmp;
  576. int size_ratio;
  577. uchar num_erase_regions;
  578. int erase_region_size;
  579. int erase_region_count;
  580. info->start[0] = base;
  581. if(flash_detect_cfi(info)){
  582. size_ratio = info->portwidth / info->chipwidth;
  583. num_erase_regions = flash_read_uchar(info, FLASH_OFFSET_NUM_ERASE_REGIONS);
  584. #ifdef DEBUG_FLASH
  585. printf("found %d erase regions\n", num_erase_regions);
  586. #endif
  587. sect_cnt = 0;
  588. sector = base;
  589. for(i = 0 ; i < num_erase_regions; i++) {
  590. if(i > NUM_ERASE_REGIONS) {
  591. printf("%d erase regions found, only %d used\n",
  592. num_erase_regions, NUM_ERASE_REGIONS);
  593. break;
  594. }
  595. tmp = flash_read_long(info, 0, FLASH_OFFSET_ERASE_REGIONS);
  596. erase_region_size = (tmp & 0xffff)? ((tmp & 0xffff) * 256): 128;
  597. tmp >>= 16;
  598. erase_region_count = (tmp & 0xffff) +1;
  599. for(j = 0; j< erase_region_count; j++) {
  600. info->start[sect_cnt] = sector;
  601. sector += (erase_region_size * size_ratio);
  602. info->protect[sect_cnt] = flash_isset(info, sect_cnt, FLASH_OFFSET_PROTECT, FLASH_STATUS_PROTECT);
  603. sect_cnt++;
  604. }
  605. }
  606. info->sector_count = sect_cnt;
  607. /* multiply the size by the number of chips */
  608. info->size = (1 << flash_read_uchar(info, FLASH_OFFSET_SIZE)) * size_ratio;
  609. info->buffer_size = (1 << flash_read_ushort(info, 0, FLASH_OFFSET_BUFFER_SIZE));
  610. tmp = 1 << flash_read_uchar(info, FLASH_OFFSET_ETOUT);
  611. info->erase_blk_tout = (tmp * (1 << flash_read_uchar(info, FLASH_OFFSET_EMAX_TOUT)));
  612. tmp = 1 << flash_read_uchar(info, FLASH_OFFSET_WBTOUT);
  613. info->buffer_write_tout = (tmp * (1 << flash_read_uchar(info, FLASH_OFFSET_WBMAX_TOUT)));
  614. tmp = 1 << flash_read_uchar(info, FLASH_OFFSET_WTOUT);
  615. info->write_tout = (tmp * (1 << flash_read_uchar(info, FLASH_OFFSET_WMAX_TOUT)))/ 1000;
  616. info->flash_id = FLASH_MAN_CFI;
  617. }
  618. flash_write_cmd(info, 0, 0, FLASH_CMD_RESET);
  619. return(info->size);
  620. }
  621. /*-----------------------------------------------------------------------
  622. */
  623. static int flash_write_cfiword (flash_info_t *info, ulong dest, cfiword_t cword)
  624. {
  625. cfiptr_t ctladdr;
  626. cfiptr_t cptr;
  627. int flag;
  628. ctladdr.cp = flash_make_addr(info, 0, 0);
  629. cptr.cp = (uchar *)dest;
  630. /* Check if Flash is (sufficiently) erased */
  631. switch(info->portwidth) {
  632. case FLASH_CFI_8BIT:
  633. flag = ((cptr.cp[0] & cword.c) == cword.c);
  634. break;
  635. case FLASH_CFI_16BIT:
  636. flag = ((cptr.wp[0] & cword.w) == cword.w);
  637. break;
  638. case FLASH_CFI_32BIT:
  639. flag = ((cptr.lp[0] & cword.l) == cword.l);
  640. break;
  641. default:
  642. return 2;
  643. }
  644. if(!flag)
  645. return 2;
  646. /* Disable interrupts which might cause a timeout here */
  647. flag = disable_interrupts();
  648. #ifdef INTEL_COMMANDS
  649. flash_write_cmd(info, 0, 0, FLASH_CMD_CLEAR_STATUS);
  650. flash_write_cmd(info, 0, 0, FLASH_CMD_WRITE);
  651. #else
  652. flash_unlock_seq(info);
  653. flash_write_cmd(info, 0, 0x555, AMD_CMD_WRITE);
  654. #endif
  655. switch(info->portwidth) {
  656. case FLASH_CFI_8BIT:
  657. cptr.cp[0] = cword.c;
  658. break;
  659. case FLASH_CFI_16BIT:
  660. cptr.wp[0] = cword.w;
  661. break;
  662. case FLASH_CFI_32BIT:
  663. cptr.lp[0] = cword.l;
  664. break;
  665. }
  666. /* re-enable interrupts if necessary */
  667. if(flag)
  668. enable_interrupts();
  669. return flash_full_status_check(info, 0, info->write_tout, "write");
  670. }
  671. #ifdef CFG_FLASH_USE_BUFFER_WRITE
  672. /* loop through the sectors from the highest address
  673. * when the passed address is greater or equal to the sector address
  674. * we have a match
  675. */
  676. static int find_sector(flash_info_t *info, ulong addr)
  677. {
  678. int sector;
  679. for(sector = info->sector_count - 1; sector >= 0; sector--) {
  680. if(addr >= info->start[sector])
  681. break;
  682. }
  683. return sector;
  684. }
  685. static int flash_write_cfibuffer(flash_info_t * info, ulong dest, uchar * cp, int len)
  686. {
  687. int sector;
  688. int cnt;
  689. int retcode;
  690. volatile cfiptr_t src;
  691. volatile cfiptr_t dst;
  692. src.cp = cp;
  693. dst.cp = (uchar *)dest;
  694. sector = find_sector(info, dest);
  695. flash_write_cmd(info, sector, 0, FLASH_CMD_CLEAR_STATUS);
  696. flash_write_cmd(info, sector, 0, FLASH_CMD_WRITE_TO_BUFFER);
  697. if((retcode = flash_status_check(info, sector, info->buffer_write_tout,
  698. "write to buffer")) == ERR_OK) {
  699. switch(info->portwidth) {
  700. case FLASH_CFI_8BIT:
  701. cnt = len;
  702. break;
  703. case FLASH_CFI_16BIT:
  704. cnt = len >> 1;
  705. break;
  706. case FLASH_CFI_32BIT:
  707. cnt = len >> 2;
  708. break;
  709. default:
  710. return ERR_INVAL;
  711. break;
  712. }
  713. flash_write_cmd(info, sector, 0, (uchar)cnt-1);
  714. while(cnt-- > 0) {
  715. switch(info->portwidth) {
  716. case FLASH_CFI_8BIT:
  717. *dst.cp++ = *src.cp++;
  718. break;
  719. case FLASH_CFI_16BIT:
  720. *dst.wp++ = *src.wp++;
  721. break;
  722. case FLASH_CFI_32BIT:
  723. *dst.lp++ = *src.lp++;
  724. break;
  725. default:
  726. return ERR_INVAL;
  727. break;
  728. }
  729. }
  730. flash_write_cmd(info, sector, 0, FLASH_CMD_WRITE_BUFFER_CONFIRM);
  731. retcode = flash_full_status_check(info, sector, info->buffer_write_tout,
  732. "buffer write");
  733. }
  734. flash_write_cmd(info, sector, 0, FLASH_CMD_CLEAR_STATUS);
  735. return retcode;
  736. }
  737. #endif /* CFG_USE_FLASH_BUFFER_WRITE */