sdram_ast2600.c 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * Copyright (C) ASPEED Technology Inc.
  4. */
  5. #include <common.h>
  6. #include <clk.h>
  7. #include <dm.h>
  8. #include <errno.h>
  9. #include <ram.h>
  10. #include <regmap.h>
  11. #include <reset.h>
  12. #include <asm/io.h>
  13. #include <asm/arch/scu_ast2600.h>
  14. #include <asm/arch/sdram_ast2600.h>
  15. #include <asm/global_data.h>
  16. #include <linux/err.h>
  17. #include <linux/kernel.h>
  18. #include <dt-bindings/clock/ast2600-clock.h>
  19. #define DDR_PHY_TBL_CHG_ADDR 0xaeeddeea
  20. #define DDR_PHY_TBL_END 0xaeededed
  21. #if defined(CONFIG_ASPEED_DDR4_800)
  22. u32 ast2600_sdramphy_config[165] = {
  23. 0x1e6e0100, // start address
  24. 0x00000000, // phyr000
  25. 0x0c002062, // phyr004
  26. 0x1a7a0063, // phyr008
  27. 0x5a7a0063, // phyr00c
  28. 0x1a7a0063, // phyr010
  29. 0x1a7a0063, // phyr014
  30. 0x20000000, // phyr018
  31. 0x20000000, // phyr01c
  32. 0x20000000, // phyr020
  33. 0x20000000, // phyr024
  34. 0x00000008, // phyr028
  35. 0x00000000, // phyr02c
  36. 0x00077600, // phyr030
  37. 0x00000000, // phyr034
  38. 0x00000000, // phyr038
  39. 0x20000000, // phyr03c
  40. 0x50506000, // phyr040
  41. 0x50505050, // phyr044
  42. 0x00002f07, // phyr048
  43. 0x00003080, // phyr04c
  44. 0x04000000, // phyr050
  45. 0x00000200, // phyr054
  46. 0x03140201, // phyr058
  47. 0x04800000, // phyr05c
  48. 0x0800044e, // phyr060
  49. 0x00000000, // phyr064
  50. 0x00180008, // phyr068
  51. 0x00e00400, // phyr06c
  52. 0x00140206, // phyr070
  53. 0x1d4c0000, // phyr074
  54. 0x493e0107, // phyr078
  55. 0x08060404, // phyr07c
  56. 0x90000a00, // phyr080
  57. 0x06420618, // phyr084
  58. 0x00001002, // phyr088
  59. 0x05701016, // phyr08c
  60. 0x10000000, // phyr090
  61. 0xaeeddeea, // change address
  62. 0x1e6e019c, // new address
  63. 0x20202020, // phyr09c
  64. 0x20202020, // phyr0a0
  65. 0x00002020, // phyr0a4
  66. 0x00002020, // phyr0a8
  67. 0x00000001, // phyr0ac
  68. 0xaeeddeea, // change address
  69. 0x1e6e01cc, // new address
  70. 0x01010101, // phyr0cc
  71. 0x01010101, // phyr0d0
  72. 0x80808080, // phyr0d4
  73. 0x80808080, // phyr0d8
  74. 0xaeeddeea, // change address
  75. 0x1e6e0288, // new address
  76. 0x80808080, // phyr188
  77. 0x80808080, // phyr18c
  78. 0x80808080, // phyr190
  79. 0x80808080, // phyr194
  80. 0xaeeddeea, // change address
  81. 0x1e6e02f8, // new address
  82. 0x90909090, // phyr1f8
  83. 0x88888888, // phyr1fc
  84. 0xaeeddeea, // change address
  85. 0x1e6e0300, // new address
  86. 0x00000000, // phyr200
  87. 0xaeeddeea, // change address
  88. 0x1e6e0194, // new address
  89. 0x80118260, // phyr094
  90. 0xaeeddeea, // change address
  91. 0x1e6e019c, // new address
  92. 0x20202020, // phyr09c
  93. 0x20202020, // phyr0a0
  94. 0x00002020, // phyr0a4
  95. 0x80000000, // phyr0a8
  96. 0x00000001, // phyr0ac
  97. 0xaeeddeea, // change address
  98. 0x1e6e0318, // new address
  99. 0x09222719, // phyr218
  100. 0x00aa4403, // phyr21c
  101. 0xaeeddeea, // change address
  102. 0x1e6e0198, // new address
  103. 0x08060000, // phyr098
  104. 0xaeeddeea, // change address
  105. 0x1e6e01b0, // new address
  106. 0x00000000, // phyr0b0
  107. 0x00000000, // phyr0b4
  108. 0x00000000, // phyr0b8
  109. 0x00000000, // phyr0bc
  110. 0x00000000, // phyr0c0
  111. 0x00000000, // phyr0c4
  112. 0x000aff2c, // phyr0c8
  113. 0xaeeddeea, // change address
  114. 0x1e6e01dc, // new address
  115. 0x00080000, // phyr0dc
  116. 0x00000000, // phyr0e0
  117. 0xaa55aa55, // phyr0e4
  118. 0x55aa55aa, // phyr0e8
  119. 0xaaaa5555, // phyr0ec
  120. 0x5555aaaa, // phyr0f0
  121. 0xaa55aa55, // phyr0f4
  122. 0x55aa55aa, // phyr0f8
  123. 0xaaaa5555, // phyr0fc
  124. 0x5555aaaa, // phyr100
  125. 0xaa55aa55, // phyr104
  126. 0x55aa55aa, // phyr108
  127. 0xaaaa5555, // phyr10c
  128. 0x5555aaaa, // phyr110
  129. 0xaa55aa55, // phyr114
  130. 0x55aa55aa, // phyr118
  131. 0xaaaa5555, // phyr11c
  132. 0x5555aaaa, // phyr120
  133. 0x20202020, // phyr124
  134. 0x20202020, // phyr128
  135. 0x20202020, // phyr12c
  136. 0x20202020, // phyr130
  137. 0x20202020, // phyr134
  138. 0x20202020, // phyr138
  139. 0x20202020, // phyr13c
  140. 0x20202020, // phyr140
  141. 0x20202020, // phyr144
  142. 0x20202020, // phyr148
  143. 0x20202020, // phyr14c
  144. 0x20202020, // phyr150
  145. 0x20202020, // phyr154
  146. 0x20202020, // phyr158
  147. 0x20202020, // phyr15c
  148. 0x20202020, // phyr160
  149. 0x20202020, // phyr164
  150. 0x20202020, // phyr168
  151. 0x20202020, // phyr16c
  152. 0x20202020, // phyr170
  153. 0xaeeddeea, // change address
  154. 0x1e6e0298, // new address
  155. 0x20200800, // phyr198
  156. 0x20202020, // phyr19c
  157. 0x20202020, // phyr1a0
  158. 0x20202020, // phyr1a4
  159. 0x20202020, // phyr1a8
  160. 0x20202020, // phyr1ac
  161. 0x20202020, // phyr1b0
  162. 0x20202020, // phyr1b4
  163. 0x20202020, // phyr1b8
  164. 0x20202020, // phyr1bc
  165. 0x20202020, // phyr1c0
  166. 0x20202020, // phyr1c4
  167. 0x20202020, // phyr1c8
  168. 0x20202020, // phyr1cc
  169. 0x20202020, // phyr1d0
  170. 0x20202020, // phyr1d4
  171. 0x20202020, // phyr1d8
  172. 0x20202020, // phyr1dc
  173. 0x20202020, // phyr1e0
  174. 0x20202020, // phyr1e4
  175. 0x00002020, // phyr1e8
  176. 0xaeeddeea, // change address
  177. 0x1e6e0304, // new address
  178. 0x00000800, // phyr204
  179. 0xaeeddeea, // change address
  180. 0x1e6e027c, // new address
  181. 0x4e400000, // phyr17c
  182. 0x59595959, // phyr180
  183. 0x40404040, // phyr184
  184. 0xaeeddeea, // change address
  185. 0x1e6e02f4, // new address
  186. 0x00000059, // phyr1f4
  187. 0xaeededed, // end
  188. };
  189. #else
  190. u32 ast2600_sdramphy_config[165] = {
  191. 0x1e6e0100, // start address
  192. 0x00000000, // phyr000
  193. 0x0c002062, // phyr004
  194. 0x1a7a0063, // phyr008
  195. 0x5a7a0063, // phyr00c
  196. 0x1a7a0063, // phyr010
  197. 0x1a7a0063, // phyr014
  198. 0x20000000, // phyr018
  199. 0x20000000, // phyr01c
  200. 0x20000000, // phyr020
  201. 0x20000000, // phyr024
  202. 0x00000008, // phyr028
  203. 0x00000000, // phyr02c
  204. 0x00077600, // phyr030
  205. 0x00000000, // phyr034
  206. 0x00000000, // phyr038
  207. 0x20000000, // phyr03c
  208. 0x50506000, // phyr040
  209. 0x50505050, // phyr044
  210. 0x00002f07, // phyr048
  211. 0x00003080, // phyr04c
  212. 0x04000000, // phyr050
  213. 0x00000200, // phyr054
  214. 0x03140501, // phyr058-rtt:40
  215. 0x04800000, // phyr05c
  216. 0x0800044e, // phyr060
  217. 0x00000000, // phyr064
  218. 0x00180008, // phyr068
  219. 0x00e00400, // phyr06c
  220. 0x00140206, // phyr070
  221. 0x1d4c0000, // phyr074
  222. 0x493e0107, // phyr078
  223. 0x08060404, // phyr07c
  224. 0x90000a00, // phyr080
  225. 0x06420c30, // phyr084
  226. 0x00001002, // phyr088
  227. 0x05701016, // phyr08c
  228. 0x10000000, // phyr090
  229. 0xaeeddeea, // change address
  230. 0x1e6e019c, // new address
  231. 0x20202020, // phyr09c
  232. 0x20202020, // phyr0a0
  233. 0x00002020, // phyr0a4
  234. 0x00002020, // phyr0a8
  235. 0x00000001, // phyr0ac
  236. 0xaeeddeea, // change address
  237. 0x1e6e01cc, // new address
  238. 0x01010101, // phyr0cc
  239. 0x01010101, // phyr0d0
  240. 0x80808080, // phyr0d4
  241. 0x80808080, // phyr0d8
  242. 0xaeeddeea, // change address
  243. 0x1e6e0288, // new address
  244. 0x80808080, // phyr188
  245. 0x80808080, // phyr18c
  246. 0x80808080, // phyr190
  247. 0x80808080, // phyr194
  248. 0xaeeddeea, // change address
  249. 0x1e6e02f8, // new address
  250. 0x90909090, // phyr1f8
  251. 0x88888888, // phyr1fc
  252. 0xaeeddeea, // change address
  253. 0x1e6e0300, // new address
  254. 0x00000000, // phyr200
  255. 0xaeeddeea, // change address
  256. 0x1e6e0194, // new address
  257. 0x801112e0, // phyr094 - bit12=1,15=0,- write window is ok
  258. 0xaeeddeea, // change address
  259. 0x1e6e019c, // new address
  260. 0x20202020, // phyr09c
  261. 0x20202020, // phyr0a0
  262. 0x00002020, // phyr0a4
  263. 0x80000000, // phyr0a8
  264. 0x00000001, // phyr0ac
  265. 0xaeeddeea, // change address
  266. 0x1e6e0318, // new address
  267. 0x09222719, // phyr218
  268. 0x00aa4403, // phyr21c
  269. 0xaeeddeea, // change address
  270. 0x1e6e0198, // new address
  271. 0x08060000, // phyr098
  272. 0xaeeddeea, // change address
  273. 0x1e6e01b0, // new address
  274. 0x00000000, // phyr0b0
  275. 0x00000000, // phyr0b4
  276. 0x00000000, // phyr0b8
  277. 0x00000000, // phyr0bc
  278. 0x00000000, // phyr0c0 - ori
  279. 0x00000000, // phyr0c4
  280. 0x000aff2c, // phyr0c8
  281. 0xaeeddeea, // change address
  282. 0x1e6e01dc, // new address
  283. 0x00080000, // phyr0dc
  284. 0x00000000, // phyr0e0
  285. 0xaa55aa55, // phyr0e4
  286. 0x55aa55aa, // phyr0e8
  287. 0xaaaa5555, // phyr0ec
  288. 0x5555aaaa, // phyr0f0
  289. 0xaa55aa55, // phyr0f4
  290. 0x55aa55aa, // phyr0f8
  291. 0xaaaa5555, // phyr0fc
  292. 0x5555aaaa, // phyr100
  293. 0xaa55aa55, // phyr104
  294. 0x55aa55aa, // phyr108
  295. 0xaaaa5555, // phyr10c
  296. 0x5555aaaa, // phyr110
  297. 0xaa55aa55, // phyr114
  298. 0x55aa55aa, // phyr118
  299. 0xaaaa5555, // phyr11c
  300. 0x5555aaaa, // phyr120
  301. 0x20202020, // phyr124
  302. 0x20202020, // phyr128
  303. 0x20202020, // phyr12c
  304. 0x20202020, // phyr130
  305. 0x20202020, // phyr134
  306. 0x20202020, // phyr138
  307. 0x20202020, // phyr13c
  308. 0x20202020, // phyr140
  309. 0x20202020, // phyr144
  310. 0x20202020, // phyr148
  311. 0x20202020, // phyr14c
  312. 0x20202020, // phyr150
  313. 0x20202020, // phyr154
  314. 0x20202020, // phyr158
  315. 0x20202020, // phyr15c
  316. 0x20202020, // phyr160
  317. 0x20202020, // phyr164
  318. 0x20202020, // phyr168
  319. 0x20202020, // phyr16c
  320. 0x20202020, // phyr170
  321. 0xaeeddeea, // change address
  322. 0x1e6e0298, // new address
  323. 0x20200800, // phyr198
  324. 0x20202020, // phyr19c
  325. 0x20202020, // phyr1a0
  326. 0x20202020, // phyr1a4
  327. 0x20202020, // phyr1a8
  328. 0x20202020, // phyr1ac
  329. 0x20202020, // phyr1b0
  330. 0x20202020, // phyr1b4
  331. 0x20202020, // phyr1b8
  332. 0x20202020, // phyr1bc
  333. 0x20202020, // phyr1c0
  334. 0x20202020, // phyr1c4
  335. 0x20202020, // phyr1c8
  336. 0x20202020, // phyr1cc
  337. 0x20202020, // phyr1d0
  338. 0x20202020, // phyr1d4
  339. 0x20202020, // phyr1d8
  340. 0x20202020, // phyr1dc
  341. 0x20202020, // phyr1e0
  342. 0x20202020, // phyr1e4
  343. 0x00002020, // phyr1e8
  344. 0xaeeddeea, // change address
  345. 0x1e6e0304, // new address
  346. 0x00000800, // phyr204
  347. 0xaeeddeea, // change address
  348. 0x1e6e027c, // new address
  349. 0x4e400000, // phyr17c
  350. 0x59595959, // phyr180
  351. 0x40404040, // phyr184
  352. 0xaeeddeea, // change address
  353. 0x1e6e02f4, // new address
  354. 0x00000059, // phyr1f4
  355. 0xaeededed, // end
  356. };
  357. #endif
  358. /* MPLL configuration */
  359. #define SCU_MPLL_FREQ_400M 0x0008405F
  360. #define SCU_MPLL_EXT_400M 0x0000002F
  361. #define SCU_MPLL_FREQ_333M 0x00488299
  362. #define SCU_MPLL_EXT_333M 0x0000014C
  363. #define SCU_MPLL_FREQ_200M 0x0078007F
  364. #define SCU_MPLL_EXT_200M 0x0000003F
  365. #define SCU_MPLL_FREQ_100M 0x0078003F
  366. #define SCU_MPLL_EXT_100M 0x0000001F
  367. #if defined(CONFIG_ASPEED_DDR4_1600)
  368. #define SCU_MPLL_FREQ_CFG SCU_MPLL_FREQ_400M
  369. #define SCU_MPLL_EXT_CFG SCU_MPLL_EXT_400M
  370. #elif defined(CONFIG_ASPEED_DDR4_1333)
  371. #define SCU_MPLL_FREQ_CFG SCU_MPLL_FREQ_333M
  372. #define SCU_MPLL_EXT_CFG SCU_MPLL_EXT_333M
  373. #elif defined(CONFIG_ASPEED_DDR4_800)
  374. #define SCU_MPLL_FREQ_CFG SCU_MPLL_FREQ_200M
  375. #define SCU_MPLL_EXT_CFG SCU_MPLL_EXT_200M
  376. #elif defined(CONFIG_ASPEED_DDR4_400)
  377. #define SCU_MPLL_FREQ_CFG SCU_MPLL_FREQ_100M
  378. #define SCU_MPLL_EXT_CFG SCU_MPLL_EXT_100M
  379. #else
  380. #error "undefined DDR4 target rate\n"
  381. #endif
  382. /*
  383. * AC timing and SDRAM mode register setting
  384. * for real chip are derived from the model GDDR4-1600
  385. */
  386. #define DDR4_MR01_MODE 0x03010510
  387. #define DDR4_MR23_MODE 0x00000000
  388. #define DDR4_MR45_MODE 0x04000000
  389. #define DDR4_MR6_MODE 0x00000400
  390. #define DDR4_TRFC_1600 0x467299f1
  391. #define DDR4_TRFC_1333 0x3a5f80c9
  392. #define DDR4_TRFC_800 0x23394c78
  393. #define DDR4_TRFC_400 0x111c263c
  394. #if defined(CONFIG_ASPEED_DDR4_1600)
  395. #define DDR4_TRFC DDR4_TRFC_1600
  396. #define DDR4_PHY_TRAIN_TRFC 0xc30
  397. #elif defined(CONFIG_ASPEED_DDR4_1333)
  398. #define DDR4_TRFC DDR4_TRFC_1333
  399. #define DDR4_PHY_TRAIN_TRFC 0xa25
  400. #elif defined(CONFIG_ASPEED_DDR4_800)
  401. #define DDR4_TRFC DDR4_TRFC_800
  402. #define DDR4_PHY_TRAIN_TRFC 0x618
  403. #elif defined(CONFIG_ASPEED_DDR4_400)
  404. #define DDR4_TRFC DDR4_TRFC_400
  405. #define DDR4_PHY_TRAIN_TRFC 0x30c
  406. #else
  407. #error "undefined tRFC setting"
  408. #endif
  409. /* supported SDRAM size */
  410. #define SDRAM_SIZE_1KB (1024U)
  411. #define SDRAM_SIZE_1MB (SDRAM_SIZE_1KB * SDRAM_SIZE_1KB)
  412. #define SDRAM_MIN_SIZE (256 * SDRAM_SIZE_1MB)
  413. #define SDRAM_MAX_SIZE (2048 * SDRAM_SIZE_1MB)
  414. DECLARE_GLOBAL_DATA_PTR;
  415. static const u32 ddr4_ac_timing[4] = {
  416. 0x040e0307, 0x0f4711f1, 0x0e060304, 0x00001240 };
  417. static const u32 ddr_max_grant_params[4] = {
  418. 0x44444444, 0x44444444, 0x44444444, 0x44444444 };
  419. struct dram_info {
  420. struct ram_info info;
  421. struct clk ddr_clk;
  422. struct ast2600_sdrammc_regs *regs;
  423. struct ast2600_scu *scu;
  424. struct ast2600_ddr_phy *phy;
  425. void __iomem *phy_setting;
  426. void __iomem *phy_status;
  427. ulong clock_rate;
  428. };
  429. static void ast2600_sdramphy_kick_training(struct dram_info *info)
  430. {
  431. u32 data;
  432. struct ast2600_sdrammc_regs *regs = info->regs;
  433. writel(SDRAM_PHYCTRL0_NRST, &regs->phy_ctrl[0]);
  434. udelay(5);
  435. writel(SDRAM_PHYCTRL0_NRST | SDRAM_PHYCTRL0_INIT, &regs->phy_ctrl[0]);
  436. udelay(1000);
  437. while (1) {
  438. data = readl(&regs->phy_ctrl[0]) & SDRAM_PHYCTRL0_INIT;
  439. if (~data)
  440. break;
  441. }
  442. }
  443. /**
  444. * @brief load DDR-PHY configurations table to the PHY registers
  445. * @param[in] p_tbl - pointer to the configuration table
  446. * @param[in] info - pointer to the DRAM info struct
  447. *
  448. * There are two sets of MRS (Mode Registers) configuration in ast2600 memory
  449. * system: one is in the SDRAM MC (memory controller) which is used in run
  450. * time, and the other is in the DDR-PHY IP which is used during DDR-PHY
  451. * training.
  452. */
  453. static void ast2600_sdramphy_init(u32 *p_tbl, struct dram_info *info)
  454. {
  455. u32 reg_base = (u32)info->phy_setting;
  456. u32 addr = p_tbl[0];
  457. u32 data;
  458. int i = 1;
  459. writel(0, &info->regs->phy_ctrl[0]);
  460. udelay(10);
  461. while (1) {
  462. if (addr < reg_base) {
  463. debug("invalid DDR-PHY addr: 0x%08x\n", addr);
  464. break;
  465. }
  466. data = p_tbl[i++];
  467. if (data == DDR_PHY_TBL_END) {
  468. break;
  469. } else if (data == DDR_PHY_TBL_CHG_ADDR) {
  470. addr = p_tbl[i++];
  471. } else {
  472. writel(data, addr);
  473. addr += 4;
  474. }
  475. }
  476. data = readl(info->phy_setting + 0x84) & ~GENMASK(16, 0);
  477. data |= DDR4_PHY_TRAIN_TRFC;
  478. writel(data, info->phy_setting + 0x84);
  479. }
  480. static int ast2600_sdramphy_check_status(struct dram_info *info)
  481. {
  482. u32 value, tmp;
  483. u32 reg_base = (u32)info->phy_status;
  484. int need_retrain = 0;
  485. debug("\nSDRAM PHY training report:\n");
  486. /* training status */
  487. value = readl(reg_base + 0x00);
  488. debug("rO_DDRPHY_reg offset 0x00 = 0x%08x\n", value);
  489. if (value & BIT(3))
  490. debug("\tinitial PVT calibration fail\n");
  491. if (value & BIT(5))
  492. debug("\truntime calibration fail\n");
  493. /* PU & PD */
  494. value = readl(reg_base + 0x30);
  495. debug("rO_DDRPHY_reg offset 0x30 = 0x%08x\n", value);
  496. debug(" PU = 0x%02x\n", value & 0xff);
  497. debug(" PD = 0x%02x\n", (value >> 16) & 0xff);
  498. /* read eye window */
  499. value = readl(reg_base + 0x68);
  500. if (0 == (value & GENMASK(7, 0)))
  501. need_retrain = 1;
  502. debug("rO_DDRPHY_reg offset 0x68 = 0x%08x\n", value);
  503. debug(" rising edge of read data eye training pass window\n");
  504. tmp = (((value & GENMASK(7, 0)) >> 0) * 100) / 255;
  505. debug(" B0:%d%%\n", tmp);
  506. tmp = (((value & GENMASK(15, 8)) >> 8) * 100) / 255;
  507. debug(" B1:%d%%\n", tmp);
  508. value = readl(reg_base + 0xC8);
  509. debug("rO_DDRPHY_reg offset 0xC8 = 0x%08x\n", value);
  510. debug(" falling edge of read data eye training pass window\n");
  511. tmp = (((value & GENMASK(7, 0)) >> 0) * 100) / 255;
  512. debug(" B0:%d%%\n", tmp);
  513. tmp = (((value & GENMASK(15, 8)) >> 8) * 100) / 255;
  514. debug(" B1:%d%%\n", tmp);
  515. /* write eye window */
  516. value = readl(reg_base + 0x7c);
  517. if (0 == (value & GENMASK(7, 0)))
  518. need_retrain = 1;
  519. debug("rO_DDRPHY_reg offset 0x7C = 0x%08x\n", value);
  520. debug(" rising edge of write data eye training pass window\n");
  521. tmp = (((value & GENMASK(7, 0)) >> 0) * 100) / 255;
  522. debug(" B0:%d%%\n", tmp);
  523. tmp = (((value & GENMASK(15, 8)) >> 8) * 100) / 255;
  524. debug(" B1:%d%%\n", tmp);
  525. /* read Vref training result */
  526. value = readl(reg_base + 0x88);
  527. debug("rO_DDRPHY_reg offset 0x88 = 0x%08x\n", value);
  528. debug(" read Vref training result\n");
  529. tmp = (((value & GENMASK(7, 0)) >> 0) * 100) / 127;
  530. debug(" B0:%d%%\n", tmp);
  531. tmp = (((value & GENMASK(15, 8)) >> 8) * 100) / 127;
  532. debug(" B1:%d%%\n", tmp);
  533. /* write Vref training result */
  534. value = readl(reg_base + 0x90);
  535. debug("rO_DDRPHY_reg offset 0x90 = 0x%08x\n", value);
  536. /* gate train */
  537. value = readl(reg_base + 0x50);
  538. if ((0 == (value & GENMASK(15, 0))) ||
  539. (0 == (value & GENMASK(31, 16)))) {
  540. need_retrain = 1;
  541. }
  542. debug("rO_DDRPHY_reg offset 0x50 = 0x%08x\n", value);
  543. return need_retrain;
  544. }
  545. #ifndef CONFIG_ASPEED_BYPASS_SELFTEST
  546. #define MC_TEST_PATTERN_N 8
  547. static u32 as2600_sdrammc_test_pattern[MC_TEST_PATTERN_N] = {
  548. 0xcc33cc33, 0xff00ff00, 0xaa55aa55, 0x88778877,
  549. 0x92cc4d6e, 0x543d3cde, 0xf1e843c7, 0x7c61d253 };
  550. #define TIMEOUT_DRAM 5000000
  551. int ast2600_sdrammc_dg_test(struct dram_info *info, unsigned int datagen, u32 mode)
  552. {
  553. unsigned int data;
  554. unsigned int timeout = 0;
  555. struct ast2600_sdrammc_regs *regs = info->regs;
  556. writel(0, &regs->ecc_test_ctrl);
  557. if (mode == 0)
  558. writel(0x00000085 | (datagen << 3), &regs->ecc_test_ctrl);
  559. else
  560. writel(0x000000C1 | (datagen << 3), &regs->ecc_test_ctrl);
  561. do {
  562. data = readl(&regs->ecc_test_ctrl) & GENMASK(13, 12);
  563. if (data & BIT(13))
  564. return 0;
  565. if (++timeout > TIMEOUT_DRAM) {
  566. debug("Timeout!!\n");
  567. writel(0, &regs->ecc_test_ctrl);
  568. return -1;
  569. }
  570. } while (!data);
  571. writel(0, &regs->ecc_test_ctrl);
  572. return 0;
  573. }
  574. int ast2600_sdrammc_cbr_test(struct dram_info *info)
  575. {
  576. u32 i;
  577. struct ast2600_sdrammc_regs *regs = info->regs;
  578. clrsetbits_le32(&regs->test_addr, GENMASK(30, 4), 0x7ffff0);
  579. /* single */
  580. for (i = 0; i < 8; i++)
  581. if (ast2600_sdrammc_dg_test(info, i, 0))
  582. return -1;
  583. /* burst */
  584. for (i = 0; i < 8; i++)
  585. if (ast2600_sdrammc_dg_test(info, i, i))
  586. return -1;
  587. return 0;
  588. }
  589. static int ast2600_sdrammc_test(struct dram_info *info)
  590. {
  591. struct ast2600_sdrammc_regs *regs = info->regs;
  592. u32 pass_cnt = 0;
  593. u32 fail_cnt = 0;
  594. u32 target_cnt = 2;
  595. u32 test_cnt = 0;
  596. u32 pattern;
  597. u32 i = 0;
  598. bool finish = false;
  599. debug("sdram mc test:\n");
  600. while (!finish) {
  601. pattern = as2600_sdrammc_test_pattern[i++];
  602. i = i % MC_TEST_PATTERN_N;
  603. debug(" pattern = %08X : ", pattern);
  604. writel(pattern, &regs->test_init_val);
  605. if (ast2600_sdrammc_cbr_test(info)) {
  606. debug("fail\n");
  607. fail_cnt++;
  608. } else {
  609. debug("pass\n");
  610. pass_cnt++;
  611. }
  612. if (++test_cnt == target_cnt)
  613. finish = true;
  614. }
  615. debug("statistics: pass/fail/total:%d/%d/%d\n", pass_cnt, fail_cnt,
  616. target_cnt);
  617. return fail_cnt;
  618. }
  619. #endif
  620. /*
  621. * scu500[14:13]
  622. * 2b'00: VGA memory size = 16MB
  623. * 2b'01: VGA memory size = 16MB
  624. * 2b'10: VGA memory size = 32MB
  625. * 2b'11: VGA memory size = 64MB
  626. *
  627. * mcr04[3:2]
  628. * 2b'00: VGA memory size = 8MB
  629. * 2b'01: VGA memory size = 16MB
  630. * 2b'10: VGA memory size = 32MB
  631. * 2b'11: VGA memory size = 64MB
  632. */
  633. static size_t ast2600_sdrammc_get_vga_mem_size(struct dram_info *info)
  634. {
  635. u32 vga_hwconf;
  636. size_t vga_mem_size_base = 8 * 1024 * 1024;
  637. vga_hwconf =
  638. (readl(&info->scu->hwstrap1) & SCU_HWSTRAP1_VGA_MEM_MASK) >>
  639. SCU_HWSTRAP1_VGA_MEM_SHIFT;
  640. if (vga_hwconf == 0) {
  641. vga_hwconf = 1;
  642. writel(vga_hwconf << SCU_HWSTRAP1_VGA_MEM_SHIFT,
  643. &info->scu->hwstrap1);
  644. }
  645. clrsetbits_le32(&info->regs->config, SDRAM_CONF_VGA_SIZE_MASK,
  646. ((vga_hwconf << SDRAM_CONF_VGA_SIZE_SHIFT) &
  647. SDRAM_CONF_VGA_SIZE_MASK));
  648. /* no need to reserve VGA memory if efuse[VGA disable] is set */
  649. if (readl(&info->scu->efuse) & SCU_EFUSE_DIS_VGA)
  650. return 0;
  651. return vga_mem_size_base << vga_hwconf;
  652. }
  653. /*
  654. * Find out RAM size and save it in dram_info
  655. *
  656. * The procedure is taken from Aspeed SDK
  657. */
  658. static void ast2600_sdrammc_calc_size(struct dram_info *info)
  659. {
  660. /* The controller supports 256/512/1024/2048 MB ram */
  661. size_t ram_size = SDRAM_MIN_SIZE;
  662. const int write_test_offset = 0x100000;
  663. u32 test_pattern = 0xdeadbeef;
  664. u32 cap_param = SDRAM_CONF_CAP_2048M;
  665. u32 refresh_timing_param = DDR4_TRFC;
  666. const u32 write_addr_base = CONFIG_SYS_SDRAM_BASE + write_test_offset;
  667. for (ram_size = SDRAM_MAX_SIZE; ram_size > SDRAM_MIN_SIZE;
  668. ram_size >>= 1) {
  669. writel(test_pattern, write_addr_base + (ram_size >> 1));
  670. test_pattern = (test_pattern >> 4) | (test_pattern << 28);
  671. }
  672. /* One last write to overwrite all wrapped values */
  673. writel(test_pattern, write_addr_base);
  674. /* Reset the pattern and see which value was really written */
  675. test_pattern = 0xdeadbeef;
  676. for (ram_size = SDRAM_MAX_SIZE; ram_size > SDRAM_MIN_SIZE;
  677. ram_size >>= 1) {
  678. if (readl(write_addr_base + (ram_size >> 1)) == test_pattern)
  679. break;
  680. --cap_param;
  681. refresh_timing_param >>= 8;
  682. test_pattern = (test_pattern >> 4) | (test_pattern << 28);
  683. }
  684. clrsetbits_le32(&info->regs->ac_timing[1],
  685. (SDRAM_AC_TRFC_MASK << SDRAM_AC_TRFC_SHIFT),
  686. ((refresh_timing_param & SDRAM_AC_TRFC_MASK)
  687. << SDRAM_AC_TRFC_SHIFT));
  688. info->info.base = CONFIG_SYS_SDRAM_BASE;
  689. info->info.size = ram_size - ast2600_sdrammc_get_vga_mem_size(info);
  690. clrsetbits_le32(&info->regs->config, SDRAM_CONF_CAP_MASK,
  691. ((cap_param << SDRAM_CONF_CAP_SHIFT) & SDRAM_CONF_CAP_MASK));
  692. }
  693. static int ast2600_sdrammc_init_ddr4(struct dram_info *info)
  694. {
  695. const u32 power_ctrl = MCR34_CKE_EN | MCR34_AUTOPWRDN_EN |
  696. MCR34_MREQ_BYPASS_DIS | MCR34_RESETN_DIS |
  697. MCR34_ODT_EN | MCR34_ODT_AUTO_ON |
  698. (0x1 << MCR34_ODT_EXT_SHIFT);
  699. /* init SDRAM-PHY only on real chip */
  700. ast2600_sdramphy_init(ast2600_sdramphy_config, info);
  701. writel((MCR34_CKE_EN | MCR34_MREQI_DIS | MCR34_RESETN_DIS),
  702. &info->regs->power_ctrl);
  703. udelay(5);
  704. ast2600_sdramphy_kick_training(info);
  705. udelay(500);
  706. writel(SDRAM_RESET_DLL_ZQCL_EN, &info->regs->refresh_timing);
  707. writel(MCR30_SET_MR(3), &info->regs->mode_setting_control);
  708. writel(MCR30_SET_MR(6), &info->regs->mode_setting_control);
  709. writel(MCR30_SET_MR(5), &info->regs->mode_setting_control);
  710. writel(MCR30_SET_MR(4), &info->regs->mode_setting_control);
  711. writel(MCR30_SET_MR(2), &info->regs->mode_setting_control);
  712. writel(MCR30_SET_MR(1), &info->regs->mode_setting_control);
  713. writel(MCR30_SET_MR(0) | MCR30_RESET_DLL_DELAY_EN,
  714. &info->regs->mode_setting_control);
  715. writel(SDRAM_REFRESH_EN | SDRAM_RESET_DLL_ZQCL_EN |
  716. (0x5f << SDRAM_REFRESH_PERIOD_SHIFT),
  717. &info->regs->refresh_timing);
  718. /* wait self-refresh idle */
  719. while (readl(&info->regs->power_ctrl) &
  720. MCR34_SELF_REFRESH_STATUS_MASK)
  721. ;
  722. writel(SDRAM_REFRESH_EN | SDRAM_LOW_PRI_REFRESH_EN |
  723. SDRAM_REFRESH_ZQCS_EN |
  724. (0x5f << SDRAM_REFRESH_PERIOD_SHIFT) |
  725. (0x42aa << SDRAM_REFRESH_PERIOD_ZQCS_SHIFT),
  726. &info->regs->refresh_timing);
  727. writel(power_ctrl, &info->regs->power_ctrl);
  728. udelay(500);
  729. return 0;
  730. }
  731. static void ast2600_sdrammc_unlock(struct dram_info *info)
  732. {
  733. writel(SDRAM_UNLOCK_KEY, &info->regs->protection_key);
  734. while (!readl(&info->regs->protection_key))
  735. ;
  736. }
  737. static void ast2600_sdrammc_lock(struct dram_info *info)
  738. {
  739. writel(~SDRAM_UNLOCK_KEY, &info->regs->protection_key);
  740. while (readl(&info->regs->protection_key))
  741. ;
  742. }
  743. static void ast2600_sdrammc_common_init(struct ast2600_sdrammc_regs *regs)
  744. {
  745. int i;
  746. writel(MCR34_MREQI_DIS | MCR34_RESETN_DIS, &regs->power_ctrl);
  747. writel(SDRAM_VIDEO_UNLOCK_KEY, &regs->gm_protection_key);
  748. writel(0x10 << MCR38_RW_MAX_GRANT_CNT_RQ_SHIFT,
  749. &regs->arbitration_ctrl);
  750. writel(0xFFBBFFF4, &regs->req_limit_mask);
  751. for (i = 0; i < ARRAY_SIZE(ddr_max_grant_params); ++i)
  752. writel(ddr_max_grant_params[i], &regs->max_grant_len[i]);
  753. writel(MCR50_RESET_ALL_INTR, &regs->intr_ctrl);
  754. writel(0x07FFFFFF, &regs->ecc_range_ctrl);
  755. writel(0, &regs->ecc_test_ctrl);
  756. writel(0x80000001, &regs->test_addr);
  757. writel(0, &regs->test_fail_dq_bit);
  758. writel(0, &regs->test_init_val);
  759. writel(0xFFFFFFFF, &regs->req_input_ctrl);
  760. writel(0, &regs->req_high_pri_ctrl);
  761. udelay(600);
  762. #ifdef CONFIG_ASPEED_DDR4_DUALX8
  763. writel(0x37, &regs->config);
  764. #else
  765. writel(0x17, &regs->config);
  766. #endif
  767. /* load controller setting */
  768. for (i = 0; i < ARRAY_SIZE(ddr4_ac_timing); ++i)
  769. writel(ddr4_ac_timing[i], &regs->ac_timing[i]);
  770. writel(DDR4_MR01_MODE, &regs->mr01_mode_setting);
  771. writel(DDR4_MR23_MODE, &regs->mr23_mode_setting);
  772. writel(DDR4_MR45_MODE, &regs->mr45_mode_setting);
  773. writel(DDR4_MR6_MODE, &regs->mr6_mode_setting);
  774. }
  775. /*
  776. * Update size info according to the ECC HW setting
  777. *
  778. * Assume SDRAM has been initialized by SPL or the host. To get the RAM size, we
  779. * don't need to calculate the ECC size again but read from MCR04 and derive the
  780. * size from its value.
  781. */
  782. static void ast2600_sdrammc_update_size(struct dram_info *info)
  783. {
  784. struct ast2600_sdrammc_regs *regs = info->regs;
  785. u32 conf = readl(&regs->config);
  786. u32 cap_param;
  787. size_t ram_size = SDRAM_MAX_SIZE;
  788. size_t hw_size;
  789. cap_param = (conf & SDRAM_CONF_CAP_MASK) >> SDRAM_CONF_CAP_SHIFT;
  790. switch (cap_param) {
  791. case SDRAM_CONF_CAP_2048M:
  792. ram_size = 2048 * SDRAM_SIZE_1MB;
  793. break;
  794. case SDRAM_CONF_CAP_1024M:
  795. ram_size = 1024 * SDRAM_SIZE_1MB;
  796. break;
  797. case SDRAM_CONF_CAP_512M:
  798. ram_size = 512 * SDRAM_SIZE_1MB;
  799. break;
  800. case SDRAM_CONF_CAP_256M:
  801. ram_size = 256 * SDRAM_SIZE_1MB;
  802. break;
  803. }
  804. info->info.base = CONFIG_SYS_SDRAM_BASE;
  805. info->info.size = ram_size - ast2600_sdrammc_get_vga_mem_size(info);
  806. if (0 == (conf & SDRAM_CONF_ECC_SETUP))
  807. return;
  808. hw_size = readl(&regs->ecc_range_ctrl) & SDRAM_ECC_RANGE_ADDR_MASK;
  809. hw_size += (1 << SDRAM_ECC_RANGE_ADDR_SHIFT);
  810. info->info.size = hw_size;
  811. }
  812. #ifdef CONFIG_ASPEED_ECC
  813. static void ast2600_sdrammc_ecc_enable(struct dram_info *info)
  814. {
  815. struct ast2600_sdrammc_regs *regs = info->regs;
  816. size_t conf_size;
  817. u32 reg;
  818. conf_size = CONFIG_ASPEED_ECC_SIZE * SDRAM_SIZE_1MB;
  819. if (conf_size > info->info.size) {
  820. printf("warning: ECC configured %dMB but actual size is %dMB\n",
  821. CONFIG_ASPEED_ECC_SIZE,
  822. info->info.size / SDRAM_SIZE_1MB);
  823. conf_size = info->info.size;
  824. } else if (conf_size == 0) {
  825. conf_size = info->info.size;
  826. }
  827. info->info.size = (((conf_size / 9) * 8) >> 20) << 20;
  828. writel(((info->info.size >> 20) - 1) << 20, &regs->ecc_range_ctrl);
  829. reg = readl(&regs->config) | SDRAM_CONF_ECC_SETUP;
  830. writel(reg, &regs->config);
  831. writel(0, &regs->test_init_val);
  832. writel(0x80000001, &regs->test_addr);
  833. writel(0x221, &regs->ecc_test_ctrl);
  834. while (0 == (readl(&regs->ecc_test_ctrl) & BIT(12)))
  835. ;
  836. writel(0, &regs->ecc_test_ctrl);
  837. writel(BIT(31), &regs->intr_ctrl);
  838. writel(0, &regs->intr_ctrl);
  839. }
  840. #endif
  841. static int ast2600_sdrammc_probe(struct udevice *dev)
  842. {
  843. int ret;
  844. u32 reg;
  845. struct dram_info *priv = (struct dram_info *)dev_get_priv(dev);
  846. struct ast2600_sdrammc_regs *regs = priv->regs;
  847. struct udevice *clk_dev;
  848. /* find SCU base address from clock device */
  849. ret = uclass_get_device_by_driver(UCLASS_CLK,
  850. DM_DRIVER_GET(aspeed_ast2600_scu), &clk_dev);
  851. if (ret) {
  852. debug("clock device not defined\n");
  853. return ret;
  854. }
  855. priv->scu = devfdt_get_addr_ptr(clk_dev);
  856. if (IS_ERR(priv->scu)) {
  857. debug("%s(): can't get SCU\n", __func__);
  858. return PTR_ERR(priv->scu);
  859. }
  860. if (readl(&priv->scu->dram_hdshk) & SCU_DRAM_HDSHK_RDY) {
  861. printf("already initialized, ");
  862. ast2600_sdrammc_update_size(priv);
  863. return 0;
  864. }
  865. reg = readl(&priv->scu->mpll);
  866. reg &= ~(SCU_PLL_BYPASS | SCU_PLL_DIV_MASK |
  867. SCU_PLL_DENUM_MASK | SCU_PLL_NUM_MASK);
  868. reg |= (SCU_PLL_RST | SCU_PLL_OFF | SCU_MPLL_FREQ_CFG);
  869. writel(reg, &priv->scu->mpll);
  870. writel(SCU_MPLL_EXT_CFG, &priv->scu->mpll_ext);
  871. udelay(100);
  872. reg &= ~(SCU_PLL_RST | SCU_PLL_OFF);
  873. writel(reg, &priv->scu->mpll);
  874. while ((readl(&priv->scu->mpll_ext) & BIT(31)) == 0)
  875. ;
  876. ast2600_sdrammc_unlock(priv);
  877. ast2600_sdrammc_common_init(regs);
  878. L_ast2600_sdramphy_train:
  879. ast2600_sdrammc_init_ddr4(priv);
  880. /* make sure DDR-PHY is ready before access */
  881. do {
  882. reg = readl(priv->phy_status) & BIT(1);
  883. } while (reg == 0);
  884. if (ast2600_sdramphy_check_status(priv) != 0) {
  885. printf("DDR4 PHY training fail, retrain\n");
  886. goto L_ast2600_sdramphy_train;
  887. }
  888. ast2600_sdrammc_calc_size(priv);
  889. #ifndef CONFIG_ASPEED_BYPASS_SELFTEST
  890. if (ast2600_sdrammc_test(priv) != 0) {
  891. printf("%s: DDR4 init fail\n", __func__);
  892. return -EINVAL;
  893. }
  894. #endif
  895. #ifdef CONFIG_ASPEED_ECC
  896. ast2600_sdrammc_ecc_enable(priv);
  897. #endif
  898. writel(readl(&priv->scu->dram_hdshk) | SCU_DRAM_HDSHK_RDY,
  899. &priv->scu->dram_hdshk);
  900. clrbits_le32(&regs->intr_ctrl, MCR50_RESET_ALL_INTR);
  901. ast2600_sdrammc_lock(priv);
  902. return 0;
  903. }
  904. static int ast2600_sdrammc_of_to_plat(struct udevice *dev)
  905. {
  906. struct dram_info *priv = dev_get_priv(dev);
  907. priv->regs = (void *)(uintptr_t)devfdt_get_addr_index(dev, 0);
  908. priv->phy_setting = (void *)(uintptr_t)devfdt_get_addr_index(dev, 1);
  909. priv->phy_status = (void *)(uintptr_t)devfdt_get_addr_index(dev, 2);
  910. priv->clock_rate = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev),
  911. "clock-frequency", 0);
  912. if (!priv->clock_rate) {
  913. debug("DDR Clock Rate not defined\n");
  914. return -EINVAL;
  915. }
  916. return 0;
  917. }
  918. static int ast2600_sdrammc_get_info(struct udevice *dev, struct ram_info *info)
  919. {
  920. struct dram_info *priv = dev_get_priv(dev);
  921. *info = priv->info;
  922. return 0;
  923. }
  924. static struct ram_ops ast2600_sdrammc_ops = {
  925. .get_info = ast2600_sdrammc_get_info,
  926. };
  927. static const struct udevice_id ast2600_sdrammc_ids[] = {
  928. { .compatible = "aspeed,ast2600-sdrammc" },
  929. { }
  930. };
  931. U_BOOT_DRIVER(sdrammc_ast2600) = {
  932. .name = "aspeed_ast2600_sdrammc",
  933. .id = UCLASS_RAM,
  934. .of_match = ast2600_sdrammc_ids,
  935. .ops = &ast2600_sdrammc_ops,
  936. .of_to_plat = ast2600_sdrammc_of_to_plat,
  937. .probe = ast2600_sdrammc_probe,
  938. .priv_auto = sizeof(struct dram_info),
  939. };