flash.c 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183
  1. /*
  2. * (C) Copyright 2000-2005
  3. * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
  4. *
  5. * SPDX-License-Identifier: GPL-2.0+
  6. */
  7. /*
  8. * Modified 4/5/2001
  9. * Wait for completion of each sector erase command issued
  10. * 4/5/2001
  11. * Chris Hallinan - DS4.COM, Inc. - clh@net1plus.com
  12. */
  13. #include <common.h>
  14. #include <asm/ppc4xx.h>
  15. #include <asm/processor.h>
  16. #undef DEBUG
  17. #ifdef DEBUG
  18. #define DEBUGF(x...) printf(x)
  19. #else
  20. #define DEBUGF(x...)
  21. #endif /* DEBUG */
  22. /*
  23. * include common flash code (for amcc boards)
  24. */
  25. #include "../common/flash.c"
  26. /*-----------------------------------------------------------------------
  27. * Functions
  28. */
  29. static ulong flash_get_size(vu_long * addr, flash_info_t * info);
  30. static void flash_get_offsets(ulong base, flash_info_t * info);
  31. unsigned long flash_init(void)
  32. {
  33. unsigned long size_b0, size_b1;
  34. int i;
  35. uint pbcr;
  36. unsigned long base_b0, base_b1;
  37. /* Init: no FLASHes known */
  38. for (i = 0; i < CONFIG_SYS_MAX_FLASH_BANKS; ++i) {
  39. flash_info[i].flash_id = FLASH_UNKNOWN;
  40. }
  41. /* Static FLASH Bank configuration here - FIXME XXX */
  42. size_b0 =
  43. flash_get_size((vu_long *) FLASH_BASE0_PRELIM, &flash_info[0]);
  44. if (flash_info[0].flash_id == FLASH_UNKNOWN) {
  45. printf("## Unknown FLASH on Bank 0 - Size = 0x%08lx = %ld MB\n",
  46. size_b0, size_b0 << 20);
  47. }
  48. /* Only one bank */
  49. if (CONFIG_SYS_MAX_FLASH_BANKS == 1) {
  50. /* Setup offsets */
  51. flash_get_offsets(FLASH_BASE0_PRELIM, &flash_info[0]);
  52. /* Monitor protection ON by default */
  53. (void)flash_protect(FLAG_PROTECT_SET,
  54. CONFIG_SYS_MONITOR_BASE,
  55. CONFIG_SYS_MONITOR_BASE + CONFIG_SYS_MONITOR_LEN - 1,
  56. &flash_info[0]);
  57. #ifdef CONFIG_ENV_IS_IN_FLASH
  58. (void)flash_protect(FLAG_PROTECT_SET, CONFIG_ENV_ADDR,
  59. CONFIG_ENV_ADDR + CONFIG_ENV_SECT_SIZE - 1,
  60. &flash_info[0]);
  61. (void)flash_protect(FLAG_PROTECT_SET, CONFIG_ENV_ADDR_REDUND,
  62. CONFIG_ENV_ADDR_REDUND + CONFIG_ENV_SECT_SIZE - 1,
  63. &flash_info[0]);
  64. #endif
  65. size_b1 = 0;
  66. flash_info[0].size = size_b0;
  67. } else {
  68. /* 2 banks */
  69. size_b1 =
  70. flash_get_size((vu_long *) FLASH_BASE1_PRELIM,
  71. &flash_info[1]);
  72. /* Re-do sizing to get full correct info */
  73. if (size_b1) {
  74. mtdcr(EBC0_CFGADDR, PB0CR);
  75. pbcr = mfdcr(EBC0_CFGDATA);
  76. mtdcr(EBC0_CFGADDR, PB0CR);
  77. base_b1 = -size_b1;
  78. pbcr =
  79. (pbcr & 0x0001ffff) | base_b1 |
  80. (((size_b1 / 1024 / 1024) - 1) << 17);
  81. mtdcr(EBC0_CFGDATA, pbcr);
  82. /* printf("PB1CR = %x\n", pbcr); */
  83. }
  84. if (size_b0) {
  85. mtdcr(EBC0_CFGADDR, PB1CR);
  86. pbcr = mfdcr(EBC0_CFGDATA);
  87. mtdcr(EBC0_CFGADDR, PB1CR);
  88. base_b0 = base_b1 - size_b0;
  89. pbcr =
  90. (pbcr & 0x0001ffff) | base_b0 |
  91. (((size_b0 / 1024 / 1024) - 1) << 17);
  92. mtdcr(EBC0_CFGDATA, pbcr);
  93. /* printf("PB0CR = %x\n", pbcr); */
  94. }
  95. size_b0 = flash_get_size((vu_long *) base_b0, &flash_info[0]);
  96. flash_get_offsets(base_b0, &flash_info[0]);
  97. /* monitor protection ON by default */
  98. (void)flash_protect(FLAG_PROTECT_SET,
  99. base_b0 + size_b0 - monitor_flash_len,
  100. base_b0 + size_b0 - 1, &flash_info[0]);
  101. if (size_b1) {
  102. /* Re-do sizing to get full correct info */
  103. size_b1 =
  104. flash_get_size((vu_long *) base_b1, &flash_info[1]);
  105. flash_get_offsets(base_b1, &flash_info[1]);
  106. /* monitor protection ON by default */
  107. (void)flash_protect(FLAG_PROTECT_SET,
  108. base_b1 + size_b1 -
  109. monitor_flash_len,
  110. base_b1 + size_b1 - 1,
  111. &flash_info[1]);
  112. /* monitor protection OFF by default (one is enough) */
  113. (void)flash_protect(FLAG_PROTECT_CLEAR,
  114. base_b0 + size_b0 -
  115. monitor_flash_len,
  116. base_b0 + size_b0 - 1,
  117. &flash_info[0]);
  118. } else {
  119. flash_info[1].flash_id = FLASH_UNKNOWN;
  120. flash_info[1].sector_count = -1;
  121. }
  122. flash_info[0].size = size_b0;
  123. flash_info[1].size = size_b1;
  124. } /* else 2 banks */
  125. return (size_b0 + size_b1);
  126. }
  127. static void flash_get_offsets(ulong base, flash_info_t * info)
  128. {
  129. int i;
  130. /* set up sector start address table */
  131. if (((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_SST) ||
  132. (info->flash_id == FLASH_AM040)) {
  133. for (i = 0; i < info->sector_count; i++)
  134. info->start[i] = base + (i * 0x00010000);
  135. } else {
  136. if (info->flash_id & FLASH_BTYPE) {
  137. /* set sector offsets for bottom boot block type */
  138. info->start[0] = base + 0x00000000;
  139. info->start[1] = base + 0x00004000;
  140. info->start[2] = base + 0x00006000;
  141. info->start[3] = base + 0x00008000;
  142. for (i = 4; i < info->sector_count; i++) {
  143. info->start[i] =
  144. base + (i * 0x00010000) - 0x00030000;
  145. }
  146. } else {
  147. /* set sector offsets for top boot block type */
  148. i = info->sector_count - 1;
  149. info->start[i--] = base + info->size - 0x00004000;
  150. info->start[i--] = base + info->size - 0x00006000;
  151. info->start[i--] = base + info->size - 0x00008000;
  152. for (; i >= 0; i--) {
  153. info->start[i] = base + i * 0x00010000;
  154. }
  155. }
  156. }
  157. }