gdc.c 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363
  1. /*
  2. * (C) Copyright 2008 Dmitry Rakhchev, EmCraft Systems, rda@emcraft.com
  3. *
  4. * Developed for DENX Software Engineering GmbH
  5. *
  6. * SPDX-License-Identifier: GPL-2.0+
  7. */
  8. #include <common.h>
  9. /* This test attempts to verify board GDC. A scratch register tested, then
  10. * simple memory test (get_ram_size()) run over GDC memory.
  11. */
  12. #include <post.h>
  13. #include <watchdog.h>
  14. #include <asm/io.h>
  15. #include <video.h>
  16. DECLARE_GLOBAL_DATA_PTR;
  17. #define GDC_SCRATCH_REG 0xC1FF8044
  18. #define GDC_VERSION_REG 0xC1FF8084
  19. #define GDC_HOST_BASE 0xC1FC0000
  20. #define GDC_RAM_START 0xC0000000
  21. #define GDC_RAM_END (GDC_HOST_BASE - 1)
  22. #define GDC_RAM_SIZE (GDC_RAM_END - GDC_RAM_START)
  23. #if CONFIG_POST & CONFIG_SYS_POST_BSPEC4
  24. const static unsigned long pattern[] = {
  25. 0xffffffff,
  26. 0xaaaaaaaa,
  27. 0xcccccccc,
  28. 0xf0f0f0f0,
  29. 0xff00ff00,
  30. 0xffff0000,
  31. 0x0000ffff,
  32. 0x00ff00ff,
  33. 0x0f0f0f0f,
  34. 0x33333333,
  35. 0x55555555,
  36. 0x00000000
  37. };
  38. const static unsigned long otherpattern = 0x01234567;
  39. /* test write/read og a given LIME Register */
  40. static int gdc_test_reg_one(uint value)
  41. {
  42. uint read_value;
  43. /* write test pattern */
  44. out_be32((void *)GDC_SCRATCH_REG, value);
  45. /* read other location (protect against data lines capacity) */
  46. in_be32((void *)GDC_RAM_START);
  47. /* verify test pattern */
  48. read_value = in_be32((void *)GDC_SCRATCH_REG);
  49. if (read_value != value) {
  50. post_log("GDC SCRATCH test failed write %08X, read %08X\n",
  51. value, read_value);
  52. }
  53. return (read_value != value);
  54. }
  55. /* test with a given static 32 bit pattern in a given memory addressrange */
  56. static int gdc_post_test1(ulong *start, ulong size, ulong val)
  57. {
  58. int ret = 0;
  59. ulong i = 0;
  60. ulong *mem = start;
  61. ulong readback;
  62. for (i = 0; i < size / sizeof(ulong); i++) {
  63. mem[i] = val;
  64. if (i % 1024 == 0)
  65. WATCHDOG_RESET();
  66. }
  67. for (i = 0; i < size / sizeof(ulong); i++) {
  68. readback = mem[i];
  69. if (readback != val) {
  70. post_log("GDC Memory error at %08x, "
  71. "wrote %08x, read %08x !\n",
  72. mem + i, val, readback);
  73. ret = -1;
  74. break;
  75. }
  76. if (i % 1024 == 0)
  77. WATCHDOG_RESET();
  78. }
  79. return ret;
  80. }
  81. /* test with dynamic 32 bit pattern in a given memory addressrange */
  82. static int gdc_post_test2(ulong *start, ulong size)
  83. {
  84. int ret = 0;
  85. ulong i = 0;
  86. ulong *mem = start;
  87. ulong readback;
  88. for (i = 0; i < size / sizeof(ulong); i++) {
  89. mem[i] = 1 << (i % 32);
  90. if (i % 1024 == 0)
  91. WATCHDOG_RESET();
  92. }
  93. for (i = 0; i < size / sizeof(ulong); i++) {
  94. readback = mem[i];
  95. if (readback != 1 << (i % 32)) {
  96. post_log("GDC Memory error at %08x, "
  97. "wrote %08x, read %08x !\n",
  98. mem + i, 1 << (i % 32), readback);
  99. ret = -1;
  100. break;
  101. }
  102. if (i % 1024 == 0)
  103. WATCHDOG_RESET();
  104. }
  105. return ret;
  106. }
  107. /* test with dynamic 32 bit pattern in a given memory addressrange */
  108. static int gdc_post_test3(ulong *start, ulong size)
  109. {
  110. int ret = 0;
  111. ulong i = 0;
  112. ulong *mem = start;
  113. ulong readback;
  114. for (i = 0; i < size / sizeof(ulong); i++) {
  115. mem[i] = i;
  116. if (i % 1024 == 0)
  117. WATCHDOG_RESET();
  118. }
  119. for (i = 0; i < size / sizeof(ulong); i++) {
  120. readback = mem[i];
  121. if (readback != i) {
  122. post_log("GDC Memory error at %08x, "
  123. "wrote %08x, read %08x !\n",
  124. mem + i, i, readback);
  125. ret = -1;
  126. break;
  127. }
  128. if (i % 1024 == 0)
  129. WATCHDOG_RESET();
  130. }
  131. return ret;
  132. }
  133. /* test with dynamic 32 bit pattern in a given memory addressrange */
  134. static int gdc_post_test4(ulong *start, ulong size)
  135. {
  136. int ret = 0;
  137. ulong i = 0;
  138. ulong *mem = start;
  139. ulong readback;
  140. for (i = 0; i < size / sizeof(ulong); i++) {
  141. mem[i] = ~i;
  142. if (i % 1024 == 0)
  143. WATCHDOG_RESET();
  144. }
  145. for (i = 0; i < size / sizeof(ulong); i++) {
  146. readback = mem[i];
  147. if (readback != ~i) {
  148. post_log("GDC Memory error at %08x, "
  149. "wrote %08x, read %08x !\n",
  150. mem + i, ~i, readback);
  151. ret = -1;
  152. break;
  153. }
  154. if (i % 1024 == 0)
  155. WATCHDOG_RESET();
  156. }
  157. return ret;
  158. }
  159. /* do some patterntests in a given addressrange */
  160. int gdc_mem_test(ulong *start, ulong size)
  161. {
  162. int ret = 0;
  163. /*
  164. * check addressrange and do different static and dynamic
  165. * pattern tests with it.
  166. */
  167. if (((void *)start) + size <= (void *)GDC_RAM_END) {
  168. if (ret == 0)
  169. ret = gdc_post_test1(start, size, 0x00000000);
  170. if (ret == 0)
  171. ret = gdc_post_test1(start, size, 0xffffffff);
  172. if (ret == 0)
  173. ret = gdc_post_test1(start, size, 0x55555555);
  174. if (ret == 0)
  175. ret = gdc_post_test1(start, size, 0xaaaaaaaa);
  176. if (ret == 0)
  177. ret = gdc_post_test2(start, size);
  178. if (ret == 0)
  179. ret = gdc_post_test3(start, size);
  180. if (ret == 0)
  181. ret = gdc_post_test4(start, size);
  182. }
  183. return ret;
  184. }
  185. /* test function of gdc memory addresslines*/
  186. static int gdc_post_addrline(ulong *address, ulong *base, ulong size)
  187. {
  188. ulong *target;
  189. ulong *end;
  190. ulong readback = 0;
  191. ulong xor = 0;
  192. int ret = 0;
  193. end = (ulong *)((ulong)base + size);
  194. for (xor = sizeof(long); xor > 0; xor <<= 1) {
  195. target = (ulong *)((ulong)address ^ xor);
  196. if ((target >= base) && (target < end)) {
  197. *address = ~*target;
  198. readback = *target;
  199. }
  200. if (readback == *address) {
  201. post_log("GDC Memory (address line) error at %08x"
  202. "XOR value %08x !\n",
  203. address, target , xor);
  204. ret = -1;
  205. break;
  206. }
  207. }
  208. return ret;
  209. }
  210. static int gdc_post_dataline(ulong *address)
  211. {
  212. unsigned long temp32 = 0;
  213. int i = 0;
  214. int ret = 0;
  215. for (i = 0; i < ARRAY_SIZE(pattern); i++) {
  216. *address = pattern[i];
  217. /*
  218. * Put a different pattern on the data lines: otherwise they
  219. * may float long enough to read back what we wrote.
  220. */
  221. *(address + 1) = otherpattern;
  222. temp32 = *address;
  223. if (temp32 != pattern[i]){
  224. post_log("GDC Memory (date line) error at %08x, "
  225. "wrote %08x, read %08x !\n",
  226. address, pattern[i], temp32);
  227. ret = 1;
  228. }
  229. }
  230. return ret;
  231. }
  232. /* Verify GDC, get memory size, verify GDC memory */
  233. int gdc_post_test(int flags)
  234. {
  235. uint old_value;
  236. int i = 0;
  237. int ret = 0;
  238. post_log("\n");
  239. old_value = in_be32((void *)GDC_SCRATCH_REG);
  240. /*
  241. * GPIOC2 register behaviour: the LIME graphics processor has a
  242. * maximum of 5 GPIO ports that can be used in this hardware
  243. * configuration. Thus only the bits for these 5 GPIOs can be
  244. * activated in the GPIOC2 register. All other bits will always be
  245. * read as zero.
  246. */
  247. if (gdc_test_reg_one(0x00150015))
  248. ret = 1;
  249. if (gdc_test_reg_one(0x000A000A))
  250. ret = 1;
  251. out_be32((void *)GDC_SCRATCH_REG, old_value);
  252. old_value = in_be32((void *)GDC_VERSION_REG);
  253. post_log("GDC chip version %u.%u, year %04X\n",
  254. (old_value >> 8) & 0xFF, old_value & 0xFF,
  255. (old_value >> 16) & 0xFFFF);
  256. old_value = get_ram_size((void *)GDC_RAM_START,
  257. 0x02000000);
  258. debug("GDC RAM size (ist): %d bytes\n", old_value);
  259. debug("GDC RAM size (soll): %d bytes\n", GDC_RAM_SIZE);
  260. post_log("GDC RAM size: %d bytes\n", old_value);
  261. /* Test SDRAM datalines */
  262. if (gdc_post_dataline((ulong *)GDC_RAM_START)) {
  263. ret = 1;
  264. goto out;
  265. }
  266. WATCHDOG_RESET();
  267. /* Test SDRAM adresslines */
  268. if (gdc_post_addrline((ulong *)GDC_RAM_START,
  269. (ulong *)GDC_RAM_START, GDC_RAM_SIZE)) {
  270. ret = 1;
  271. goto out;
  272. }
  273. WATCHDOG_RESET();
  274. if (gdc_post_addrline((ulong *)GDC_RAM_END - sizeof(long),
  275. (ulong *)GDC_RAM_START, GDC_RAM_SIZE)) {
  276. ret = 1;
  277. goto out;
  278. }
  279. WATCHDOG_RESET();
  280. /* memory pattern test */
  281. debug("GDC Memory test (flags %8x:%8x)\n", flags,
  282. POST_SLOWTEST | POST_MANUAL);
  283. if (flags & POST_MANUAL) {
  284. debug("Full memory test\n");
  285. if (gdc_mem_test((ulong *)GDC_RAM_START, GDC_RAM_SIZE)) {
  286. ret = 1;
  287. goto out;
  288. }
  289. /* load splashscreen again */
  290. } else {
  291. debug("smart memory test\n");
  292. for (i = 0; i < (GDC_RAM_SIZE >> 20) && ret == 0; i++) {
  293. if (ret == 0)
  294. ret = gdc_mem_test((ulong *)(GDC_RAM_START +
  295. (i << 20)),
  296. 0x800);
  297. if (ret == 0)
  298. ret = gdc_mem_test((ulong *)(GDC_RAM_START +
  299. (i << 20) + 0xff800),
  300. 0x800);
  301. }
  302. }
  303. WATCHDOG_RESET();
  304. out:
  305. return ret;
  306. }
  307. #endif /* CONFIG_POST & CONFIG_SYS_POST_BSPEC4 */