sc520_sdram.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479
  1. /*
  2. * (C) Copyright 2010,2011
  3. * Graeme Russ, <graeme.russ@gmail.com>
  4. *
  5. * See file CREDITS for list of people who contributed to this
  6. * project.
  7. *
  8. * This program is free software; you can redistribute it and/or
  9. * modify it under the terms of the GNU General Public License as
  10. * published by the Free Software Foundation; either version 2 of
  11. * the License, or (at your option) any later version.
  12. *
  13. * This program is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. * GNU General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU General Public License
  19. * along with this program; if not, write to the Free Software
  20. * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  21. * MA 02111-1307 USA
  22. */
  23. #include <common.h>
  24. #include <asm/io.h>
  25. #include <asm/processor-flags.h>
  26. #include <asm/arch/sc520.h>
  27. DECLARE_GLOBAL_DATA_PTR;
  28. struct sc520_sdram_info {
  29. u8 banks;
  30. u8 columns;
  31. u8 rows;
  32. u8 size;
  33. };
  34. static void sc520_sizemem(void);
  35. static void sc520_set_dram_timing(void);
  36. static void sc520_set_dram_refresh_rate(void);
  37. static void sc520_enable_dram_refresh(void);
  38. static void sc520_enable_sdram(void);
  39. int dram_init_f(void)
  40. {
  41. sc520_sizemem();
  42. sc520_set_dram_timing();
  43. sc520_set_dram_refresh_rate();
  44. sc520_enable_dram_refresh();
  45. sc520_enable_sdram();
  46. return 0;
  47. }
  48. static inline void sc520_dummy_write(void)
  49. {
  50. writew(0x0000, CACHELINESZ);
  51. }
  52. static inline void sc520_issue_sdram_op_mode_select(u8 command)
  53. {
  54. writeb(command, &sc520_mmcr->drcctl);
  55. sc520_dummy_write();
  56. }
  57. static inline int check_long(u32 test_long)
  58. {
  59. u8 i;
  60. u8 tmp_byte = (u8)(test_long & 0x000000ff);
  61. for (i = 1; i < 4; i++) {
  62. if ((u8)((test_long >> (i * 8)) & 0x000000ff) != tmp_byte)
  63. return -1;
  64. }
  65. return 0;
  66. }
  67. static inline int write_and_test(u32 data, u32 address)
  68. {
  69. writel(data, address);
  70. if (readl(address) == data)
  71. return 0; /* Good */
  72. else
  73. return -1; /* Bad */
  74. }
  75. static void sc520_enable_sdram(void)
  76. {
  77. u32 par_config;
  78. /* Enable Writes, Caching and Code Execution to SDRAM */
  79. par_config = readl(&sc520_mmcr->par[3]);
  80. par_config &= ~(SC520_PAR_EXEC_DIS |
  81. SC520_PAR_CACHE_DIS |
  82. SC520_PAR_WRITE_DIS);
  83. writel(par_config, &sc520_mmcr->par[3]);
  84. par_config = readl(&sc520_mmcr->par[4]);
  85. par_config &= ~(SC520_PAR_EXEC_DIS |
  86. SC520_PAR_CACHE_DIS |
  87. SC520_PAR_WRITE_DIS);
  88. writel(par_config, &sc520_mmcr->par[4]);
  89. }
  90. static void sc520_set_dram_timing(void)
  91. {
  92. u8 drctmctl = 0x00;
  93. #if defined CONFIG_SYS_SDRAM_DRCTMCTL
  94. /* just have your hardware designer _GIVE_ you what you need here! */
  95. drctmctl = CONFIG_SYS_SDRAM_DRCTMCTL;
  96. #else
  97. switch (CONFIG_SYS_SDRAM_RAS_CAS_DELAY) {
  98. case 2:
  99. break;
  100. case 3:
  101. drctmctl |= 0x01;
  102. break;
  103. case 4:
  104. default:
  105. drctmctl |= 0x02;
  106. break;
  107. }
  108. switch (CONFIG_SYS_SDRAM_PRECHARGE_DELAY) {
  109. case 2:
  110. break;
  111. case 3:
  112. drctmctl |= 0x04;
  113. break;
  114. case 4:
  115. default:
  116. drctmctl |= 0x08;
  117. break;
  118. case 6:
  119. drctmctl |= 0x0c;
  120. break;
  121. }
  122. switch (CONFIG_SYS_SDRAM_CAS_LATENCY) {
  123. case 2:
  124. break;
  125. case 3:
  126. default:
  127. drctmctl |= 0x10;
  128. break;
  129. }
  130. #endif
  131. writeb(drctmctl, &sc520_mmcr->drctmctl);
  132. /* Issue load mode register command */
  133. sc520_issue_sdram_op_mode_select(0x03);
  134. }
  135. static void sc520_set_dram_refresh_rate(void)
  136. {
  137. u8 drctl;
  138. drctl = readb(&sc520_mmcr->drcctl);
  139. drctl &= 0xcf;
  140. switch (CONFIG_SYS_SDRAM_REFRESH_RATE) {
  141. case 78:
  142. break;
  143. case 156:
  144. default:
  145. drctl |= 0x10;
  146. break;
  147. case 312:
  148. drctl |= 0x20;
  149. break;
  150. case 624:
  151. drctl |= 0x30;
  152. break;
  153. }
  154. writeb(drctl, &sc520_mmcr->drcctl);
  155. }
  156. static void sc520_enable_dram_refresh(void)
  157. {
  158. u8 drctl;
  159. drctl = readb(&sc520_mmcr->drcctl);
  160. drctl &= 0x30; /* keep refresh rate */
  161. drctl |= 0x08; /* enable refresh, normal mode */
  162. writeb(drctl, &sc520_mmcr->drcctl);
  163. }
  164. static void sc520_get_bank_info(int bank, struct sc520_sdram_info *bank_info)
  165. {
  166. u32 col_data;
  167. u32 row_data;
  168. u32 drcbendadr;
  169. u16 drccfg;
  170. u8 banks = 0x00;
  171. u8 columns = 0x00;
  172. u8 rows = 0x00;
  173. bank_info->banks = 0x00;
  174. bank_info->columns = 0x00;
  175. bank_info->rows = 0x00;
  176. bank_info->size = 0x00;
  177. if ((bank < 0) || (bank > 3)) {
  178. printf("Bad Bank ID\n");
  179. return;
  180. }
  181. /* Save configuration */
  182. drcbendadr = readl(&sc520_mmcr->drcbendadr);
  183. drccfg = readw(&sc520_mmcr->drccfg);
  184. /* Setup SDRAM Bank to largest possible size */
  185. writew(0x000b << (bank * 4), &sc520_mmcr->drccfg);
  186. /* Set ending address for this bank */
  187. writel(0x000000ff << (bank * 8), &sc520_mmcr->drcbendadr);
  188. /* write col 11 wrap adr */
  189. if (write_and_test(COL11_DATA, COL11_ADR) != 0)
  190. goto restore_and_exit;
  191. /* write col 10 wrap adr */
  192. if (write_and_test(COL10_DATA, COL10_ADR) != 0)
  193. goto restore_and_exit;
  194. /* write col 9 wrap adr */
  195. if (write_and_test(COL09_DATA, COL09_ADR) != 0)
  196. goto restore_and_exit;
  197. /* write col 8 wrap adr */
  198. if (write_and_test(COL08_DATA, COL08_ADR) != 0)
  199. goto restore_and_exit;
  200. col_data = readl(COL11_ADR);
  201. /* All four bytes in the read long must be the same */
  202. if (check_long(col_data) < 0)
  203. goto restore_and_exit;
  204. if ((col_data >= COL08_DATA) && (col_data <= COL11_DATA))
  205. columns = (u8)(col_data & 0x000000ff);
  206. else
  207. goto restore_and_exit;
  208. /* write row 14 wrap adr */
  209. if (write_and_test(ROW14_DATA, ROW14_ADR) != 0)
  210. goto restore_and_exit;
  211. /* write row 13 wrap adr */
  212. if (write_and_test(ROW13_DATA, ROW13_ADR) != 0)
  213. goto restore_and_exit;
  214. /* write row 12 wrap adr */
  215. if (write_and_test(ROW12_DATA, ROW12_ADR) != 0)
  216. goto restore_and_exit;
  217. /* write row 11 wrap adr */
  218. if (write_and_test(ROW11_DATA, ROW11_ADR) != 0)
  219. goto restore_and_exit;
  220. if (write_and_test(ROW10_DATA, ROW10_ADR) != 0)
  221. goto restore_and_exit;
  222. /*
  223. * read data @ row 12 wrap adr to determine number of banks,
  224. * and read data @ row 14 wrap adr to determine number of rows.
  225. * if data @ row 12 wrap adr is not AA, 11 or 12 we have bad RAM.
  226. * if data @ row 12 wrap == AA, we only have 2 banks, NOT 4
  227. * if data @ row 12 wrap == 11 or 12, we have 4 banks,
  228. */
  229. row_data = readl(ROW12_ADR);
  230. /* All four bytes in the read long must be the same */
  231. if (check_long(row_data) != 0)
  232. goto restore_and_exit;
  233. switch (row_data) {
  234. case ROW10_DATA:
  235. banks = 2;
  236. break;
  237. case ROW11_DATA:
  238. case ROW12_DATA:
  239. banks = 4;
  240. break;
  241. default:
  242. goto restore_and_exit;
  243. }
  244. row_data = readl(ROW14_ADR);
  245. /* All four bytes in the read long must be the same */
  246. if (check_long(row_data) != 0)
  247. goto restore_and_exit;
  248. switch (row_data) {
  249. case ROW11_DATA:
  250. case ROW12_DATA:
  251. case ROW13_DATA:
  252. case ROW14_DATA:
  253. rows = (u8)(row_data & 0x000000ff);
  254. break;
  255. default:
  256. goto restore_and_exit;
  257. }
  258. bank_info->banks = banks;
  259. bank_info->columns = columns;
  260. bank_info->rows = rows;
  261. if ((bank_info->banks != 0) &&
  262. (bank_info->columns != 0) &&
  263. (bank_info->rows != 0)) {
  264. bank_info->size = bank_info->rows;
  265. bank_info->size >>= (11 - bank_info->columns);
  266. bank_info->size++;
  267. }
  268. restore_and_exit:
  269. /* Restore configuration */
  270. writel(drcbendadr, &sc520_mmcr->drcbendadr);
  271. writew(drccfg, &sc520_mmcr->drccfg);
  272. }
  273. static void sc520_setup_sizemem(void)
  274. {
  275. u8 i;
  276. /* Disable write buffer */
  277. writeb(0x00, &sc520_mmcr->dbctl);
  278. /* Disable ECC */
  279. writeb(0x00, &sc520_mmcr->eccctl);
  280. /* Set slowest SDRAM timing */
  281. writeb(0x1e, &sc520_mmcr->drctmctl);
  282. /* Issue a NOP to all SDRAM banks */
  283. sc520_issue_sdram_op_mode_select(0x01);
  284. /* Delay for 100 microseconds */
  285. udelay(100);
  286. /* Issue 'All Banks Precharge' command */
  287. sc520_issue_sdram_op_mode_select(0x02);
  288. /* Issue 2 'Auto Refresh Enable' command */
  289. sc520_issue_sdram_op_mode_select(0x04);
  290. sc520_dummy_write();
  291. /* Issue 'Load Mode Register' command */
  292. sc520_issue_sdram_op_mode_select(0x03);
  293. /* Issue 8 more 'Auto Refresh Enable' commands */
  294. sc520_issue_sdram_op_mode_select(0x04);
  295. for (i = 0; i < 7; i++)
  296. sc520_dummy_write();
  297. /* Set control register to 'Normal Mode' */
  298. writeb(0x00, &sc520_mmcr->drcctl);
  299. }
  300. static void sc520_sizemem(void)
  301. {
  302. struct sc520_sdram_info sdram_info[4];
  303. u8 bank_config = 0x00;
  304. u8 end_addr = 0x00;
  305. u16 drccfg = 0x0000;
  306. u32 drcbendadr = 0x00000000;
  307. u8 i;
  308. /* Use PARs to disable caching of maximum allowable 256MB SDRAM */
  309. writel(SC520_SDRAM1_PAR | SC520_PAR_CACHE_DIS, &sc520_mmcr->par[3]);
  310. writel(SC520_SDRAM2_PAR | SC520_PAR_CACHE_DIS, &sc520_mmcr->par[4]);
  311. sc520_setup_sizemem();
  312. gd->ram_size = 0;
  313. /* Size each SDRAM bank */
  314. for (i = 0; i <= 3; i++) {
  315. sc520_get_bank_info(i, &sdram_info[i]);
  316. if (sdram_info[i].banks != 0) {
  317. /* Update Configuration register */
  318. bank_config = sdram_info[i].columns - 8;
  319. if (sdram_info[i].banks == 4)
  320. bank_config |= 0x08;
  321. drccfg |= bank_config << (i * 4);
  322. /* Update End Address register */
  323. end_addr += sdram_info[i].size;
  324. drcbendadr |= (end_addr | 0x80) << (i * 8);
  325. gd->ram_size += sdram_info[i].size << 22;
  326. }
  327. /* Issue 'All Banks Precharge' command */
  328. sc520_issue_sdram_op_mode_select(0x02);
  329. /* Set control register to 'Normal Mode' */
  330. writeb(0x00, &sc520_mmcr->drcctl);
  331. }
  332. writel(drcbendadr, &sc520_mmcr->drcbendadr);
  333. writew(drccfg, &sc520_mmcr->drccfg);
  334. /* Clear PARs preventing caching of SDRAM */
  335. writel(0x00000000, &sc520_mmcr->par[3]);
  336. writel(0x00000000, &sc520_mmcr->par[4]);
  337. }
  338. int dram_init(void)
  339. {
  340. ulong dram_ctrl;
  341. ulong dram_present = 0x00000000;
  342. /*
  343. * We read-back the configuration of the dram
  344. * controller that the assembly code wrote
  345. */
  346. dram_ctrl = readl(&sc520_mmcr->drcbendadr);
  347. gd->bd->bi_dram[0].start = 0;
  348. if (dram_ctrl & 0x80) {
  349. /* bank 0 enabled */
  350. gd->bd->bi_dram[1].start = (dram_ctrl & 0x7f) << 22;
  351. dram_present = gd->bd->bi_dram[1].start;
  352. gd->bd->bi_dram[0].size = gd->bd->bi_dram[1].start;
  353. } else {
  354. gd->bd->bi_dram[0].size = 0;
  355. gd->bd->bi_dram[1].start = gd->bd->bi_dram[0].start;
  356. }
  357. if (dram_ctrl & 0x8000) {
  358. /* bank 1 enabled */
  359. gd->bd->bi_dram[2].start = (dram_ctrl & 0x7f00) << 14;
  360. dram_present = gd->bd->bi_dram[2].start;
  361. gd->bd->bi_dram[1].size = gd->bd->bi_dram[2].start -
  362. gd->bd->bi_dram[1].start;
  363. } else {
  364. gd->bd->bi_dram[1].size = 0;
  365. gd->bd->bi_dram[2].start = gd->bd->bi_dram[1].start;
  366. }
  367. if (dram_ctrl & 0x800000) {
  368. /* bank 2 enabled */
  369. gd->bd->bi_dram[3].start = (dram_ctrl & 0x7f0000) << 6;
  370. dram_present = gd->bd->bi_dram[3].start;
  371. gd->bd->bi_dram[2].size = gd->bd->bi_dram[3].start -
  372. gd->bd->bi_dram[2].start;
  373. } else {
  374. gd->bd->bi_dram[2].size = 0;
  375. gd->bd->bi_dram[3].start = gd->bd->bi_dram[2].start;
  376. }
  377. if (dram_ctrl & 0x80000000) {
  378. /* bank 3 enabled */
  379. dram_present = (dram_ctrl & 0x7f000000) >> 2;
  380. gd->bd->bi_dram[3].size = dram_present -
  381. gd->bd->bi_dram[3].start;
  382. } else {
  383. gd->bd->bi_dram[3].size = 0;
  384. }
  385. gd->ram_size = dram_present;
  386. return 0;
  387. }