dram_sun50i_h6.h 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336
  1. /*
  2. * H6 dram controller register and constant defines
  3. *
  4. * (C) Copyright 2017 Icenowy Zheng <icenowy@aosc.io>
  5. *
  6. * SPDX-License-Identifier: GPL-2.0+
  7. */
  8. #ifndef _SUNXI_DRAM_SUN50I_H6_H
  9. #define _SUNXI_DRAM_SUN50I_H6_H
  10. #include <stdbool.h>
  11. #ifndef __ASSEMBLY__
  12. #include <linux/bitops.h>
  13. #endif
  14. enum sunxi_dram_type {
  15. SUNXI_DRAM_TYPE_DDR3 = 3,
  16. SUNXI_DRAM_TYPE_DDR4,
  17. SUNXI_DRAM_TYPE_LPDDR2 = 6,
  18. SUNXI_DRAM_TYPE_LPDDR3,
  19. };
  20. static inline bool sunxi_dram_is_lpddr(int type)
  21. {
  22. return type >= SUNXI_DRAM_TYPE_LPDDR2;
  23. }
  24. /*
  25. * The following information is mainly retrieved by disassembly and some FPGA
  26. * test code of sun50iw3 platform.
  27. */
  28. struct sunxi_mctl_com_reg {
  29. u32 cr; /* 0x000 control register */
  30. u8 reserved_0x004[4]; /* 0x004 */
  31. u32 unk_0x008; /* 0x008 */
  32. u32 tmr; /* 0x00c timer register */
  33. u8 reserved_0x010[4]; /* 0x010 */
  34. u32 unk_0x014; /* 0x014 */
  35. u8 reserved_0x018[8]; /* 0x018 */
  36. u32 maer0; /* 0x020 master enable register 0 */
  37. u32 maer1; /* 0x024 master enable register 1 */
  38. u32 maer2; /* 0x028 master enable register 2 */
  39. u8 reserved_0x02c[468]; /* 0x02c */
  40. u32 bwcr; /* 0x200 bandwidth control register */
  41. u8 reserved_0x204[12]; /* 0x204 */
  42. /*
  43. * The last master configured by BSP libdram is at 0x49x, so the
  44. * size of this struct array is set to 41 (0x29) now.
  45. */
  46. struct {
  47. u32 cfg0; /* 0x0 */
  48. u32 cfg1; /* 0x4 */
  49. u8 reserved_0x8[8]; /* 0x8 */
  50. } master[41]; /* 0x210 + index * 0x10 */
  51. };
  52. check_member(sunxi_mctl_com_reg, master[40].reserved_0x8, 0x498);
  53. /*
  54. * The following register information are retrieved from some similar DRAM
  55. * controllers, including the DRAM controllers in Allwinner A23/A80 SoCs,
  56. * Rockchip RK3328 SoC, NXP i.MX7 SoCs and Xilinx Zynq UltraScale+ SoCs.
  57. *
  58. * The DRAM controller in Allwinner A23/A80 SoCs and NXP i.MX7 SoCs seems
  59. * to be older than the one in Allwinner H6, as the DRAMTMG9 register
  60. * is missing in these SoCs. (From the product specifications of these
  61. * SoCs they're not capable of DDR4)
  62. *
  63. * Information sources:
  64. * - dram_sun9i.h and dram_sun8i_a23.h in the same directory.
  65. * - sdram_rk3328.h from the RK3328 TPL DRAM patchset
  66. * - i.MX 7Solo Applications Processor Reference Manual (IMX7SRM)
  67. * - Zynq UltraScale+ MPSoC Register Reference (UG1087)
  68. */
  69. struct sunxi_mctl_ctl_reg {
  70. u32 mstr; /* 0x000 */
  71. u32 statr; /* 0x004 unused */
  72. u32 mstr1; /* 0x008 unused */
  73. u32 unk_0x00c; /* 0x00c */
  74. u32 mrctrl0; /* 0x010 unused */
  75. u32 mrctrl1; /* 0x014 unused */
  76. u32 mrstatr; /* 0x018 unused */
  77. u32 mrctrl2; /* 0x01c unused */
  78. u32 derateen; /* 0x020 unused */
  79. u32 derateint; /* 0x024 unused */
  80. u8 reserved_0x028[8]; /* 0x028 */
  81. u32 pwrctl; /* 0x030 unused */
  82. u32 pwrtmg; /* 0x034 unused */
  83. u32 hwlpctl; /* 0x038 unused */
  84. u8 reserved_0x03c[20]; /* 0x03c */
  85. u32 rfshctl0; /* 0x050 unused */
  86. u32 rfshctl1; /* 0x054 unused */
  87. u8 reserved_0x058[8]; /* 0x05c */
  88. u32 rfshctl3; /* 0x060 */
  89. u32 rfshtmg; /* 0x064 */
  90. u8 reserved_0x068[104]; /* 0x068 reserved for ECC&CRC (from ZynqMP) */
  91. u32 init[8]; /* 0x0d0 */
  92. u32 dimmctl; /* 0x0f0 unused */
  93. u32 rankctl; /* 0x0f4 */
  94. u8 reserved_0x0f8[8]; /* 0x0f8 */
  95. u32 dramtmg[17]; /* 0x100 */
  96. u8 reserved_0x144[60]; /* 0x144 */
  97. u32 zqctl[3]; /* 0x180 */
  98. u32 zqstat; /* 0x18c unused */
  99. u32 dfitmg0; /* 0x190 */
  100. u32 dfitmg1; /* 0x194 */
  101. u32 dfilpcfg[2]; /* 0x198 unused */
  102. u32 dfiupd[3]; /* 0x1a0 */
  103. u32 reserved_0x1ac; /* 0x1ac */
  104. u32 dfimisc; /* 0x1b0 */
  105. u32 dfitmg2; /* 0x1b4 unused, may not exist */
  106. u8 reserved_0x1b8[8]; /* 0x1b8 */
  107. u32 dbictl; /* 0x1c0 */
  108. u8 reserved_0x1c4[60]; /* 0x1c4 */
  109. u32 addrmap[12]; /* 0x200 */
  110. u8 reserved_0x230[16]; /* 0x230 */
  111. u32 odtcfg; /* 0x240 */
  112. u32 odtmap; /* 0x244 */
  113. u8 reserved_0x248[8]; /* 0x248 */
  114. u32 sched[2]; /* 0x250 */
  115. u8 reserved_0x258[180]; /* 0x258 */
  116. u32 dbgcmd; /* 0x30c unused */
  117. u32 dbgstat; /* 0x310 unused */
  118. u8 reserved_0x314[12]; /* 0x314 */
  119. u32 swctl; /* 0x320 */
  120. u32 swstat; /* 0x324 */
  121. };
  122. check_member(sunxi_mctl_ctl_reg, swstat, 0x324);
  123. #define MSTR_DEVICETYPE_DDR3 BIT(0)
  124. #define MSTR_DEVICETYPE_LPDDR2 BIT(2)
  125. #define MSTR_DEVICETYPE_LPDDR3 BIT(3)
  126. #define MSTR_DEVICETYPE_DDR4 BIT(4)
  127. #define MSTR_DEVICETYPE_MASK GENMASK(5, 0)
  128. #define MSTR_2TMODE BIT(10)
  129. #define MSTR_BUSWIDTH_FULL (0 << 12)
  130. #define MSTR_BUSWIDTH_HALF (1 << 12)
  131. #define MSTR_ACTIVE_RANKS(x) (((x == 2) ? 3 : 1) << 24)
  132. #define MSTR_BURST_LENGTH(x) (((x) >> 1) << 16)
  133. /*
  134. * The following register information is based on Zynq UltraScale+
  135. * MPSoC Register Reference, as it's the currently only known
  136. * DDR PHY similar to the one used in H6; however although the
  137. * map is similar, the bit fields definitions are different.
  138. *
  139. * Other DesignWare DDR PHY's have similar register names, but the
  140. * offset and definitions are both different.
  141. */
  142. struct sunxi_mctl_phy_reg {
  143. u32 ver; /* 0x000 guess based on similar PHYs */
  144. u32 pir; /* 0x004 */
  145. u8 reserved_0x008[8]; /* 0x008 */
  146. /*
  147. * The ZynqMP manual didn't document PGCR1, however this register
  148. * exists on H6 and referenced by libdram.
  149. */
  150. u32 pgcr[8]; /* 0x010 */
  151. /*
  152. * By comparing the hardware and the ZynqMP manual, the PGSR seems
  153. * to start at 0x34 on H6.
  154. */
  155. u8 reserved_0x030[4]; /* 0x030 */
  156. u32 pgsr[3]; /* 0x034 */
  157. u32 ptr[7]; /* 0x040 */
  158. /*
  159. * According to ZynqMP reference there's PLLCR0~6 in this area,
  160. * but they're tagged "Type B PLL Only" and H6 seems to have
  161. * no them.
  162. * 0x080 is not present in ZynqMP reference but it seems to be
  163. * present on H6.
  164. */
  165. u8 reserved_0x05c[36]; /* 0x05c */
  166. u32 unk_0x080; /* 0x080 */
  167. u8 reserved_0x084[4]; /* 0x084 */
  168. u32 dxccr; /* 0x088 */
  169. u8 reserved_0x08c[4]; /* 0x08c */
  170. u32 dsgcr; /* 0x090 */
  171. u8 reserved_0x094[4]; /* 0x094 */
  172. u32 odtcr; /* 0x098 */
  173. u8 reserved_0x09c[4]; /* 0x09c */
  174. u32 aacr; /* 0x0a0 */
  175. u8 reserved_0x0a4[32]; /* 0x0a4 */
  176. u32 gpr1; /* 0x0c4 */
  177. u8 reserved_0x0c8[56]; /* 0x0c8 */
  178. u32 dcr; /* 0x100 */
  179. u8 reserved_0x104[12]; /* 0x104 */
  180. u32 dtpr[7]; /* 0x110 */
  181. u8 reserved_0x12c[20]; /* 0x12c */
  182. u32 rdimmgcr[3]; /* 0x140 */
  183. u8 reserved_0x14c[4]; /* 0x14c */
  184. u32 rdimmcr[5]; /* 0x150 */
  185. u8 reserved_0x164[4]; /* 0x164 */
  186. u32 schcr[2]; /* 0x168 */
  187. u8 reserved_0x170[16]; /* 0x170 */
  188. /*
  189. * The ZynqMP manual documents MR0~7, 11~14 and 22.
  190. */
  191. u32 mr[23]; /* 0x180 */
  192. u8 reserved_0x1dc[36]; /* 0x1dc */
  193. u32 dtcr[2]; /* 0x200 */
  194. u32 dtar[3]; /* 0x208 */
  195. u8 reserved_0x214[4]; /* 0x214 */
  196. u32 dtdr[2]; /* 0x218 */
  197. u8 reserved_0x220[16]; /* 0x220 */
  198. u32 dtedr0; /* 0x230 */
  199. u32 dtedr1; /* 0x234 */
  200. u32 dtedr2; /* 0x238 */
  201. u32 vtdr; /* 0x23c */
  202. u32 catr[2]; /* 0x240 */
  203. u8 reserved_0x248[8];
  204. u32 dqsdr[3]; /* 0x250 */
  205. u32 dtedr3; /* 0x25c */
  206. u8 reserved_0x260[160]; /* 0x260 */
  207. u32 dcuar; /* 0x300 */
  208. u32 dcudr; /* 0x304 */
  209. u32 dcurr; /* 0x308 */
  210. u32 dculr; /* 0x30c */
  211. u32 dcugcr; /* 0x310 */
  212. u32 dcutpr; /* 0x314 */
  213. u32 dcusr[2]; /* 0x318 */
  214. u8 reserved_0x320[444]; /* 0x320 */
  215. u32 rankidr; /* 0x4dc */
  216. u32 riocr[6]; /* 0x4e0 */
  217. u8 reserved_0x4f8[8]; /* 0x4f8 */
  218. u32 aciocr[6]; /* 0x500 */
  219. u8 reserved_0x518[8]; /* 0x518 */
  220. u32 iovcr[2]; /* 0x520 */
  221. u32 vtcr[2]; /* 0x528 */
  222. u8 reserved_0x530[16]; /* 0x530 */
  223. u32 acbdlr[17]; /* 0x540 */
  224. u32 aclcdlr; /* 0x584 */
  225. u8 reserved_0x588[24]; /* 0x588 */
  226. u32 acmdlr[2]; /* 0x5a0 */
  227. u8 reserved_0x5a8[216]; /* 0x5a8 */
  228. struct {
  229. u32 zqcr; /* 0x00 only the first one valid */
  230. u32 zqpr[2]; /* 0x04 */
  231. u32 zqdr[2]; /* 0x0c */
  232. u32 zqor[2]; /* 0x14 */
  233. u32 zqsr; /* 0x1c */
  234. } zq[2]; /* 0x680, 0x6a0 */
  235. u8 reserved_0x6c0[64]; /* 0x6c0 */
  236. struct {
  237. u32 gcr[7]; /* 0x00 */
  238. u8 reserved_0x1c[36]; /* 0x1c */
  239. u32 bdlr0; /* 0x40 */
  240. u32 bdlr1; /* 0x44 */
  241. u32 bdlr2; /* 0x48 */
  242. u8 reserved_0x4c[4]; /* 0x4c */
  243. u32 bdlr3; /* 0x50 */
  244. u32 bdlr4; /* 0x54 */
  245. u32 bdlr5; /* 0x58 */
  246. u8 reserved_0x5c[4]; /* 0x5c */
  247. u32 bdlr6; /* 0x60 */
  248. u8 reserved_0x64[28]; /* 0x64 */
  249. u32 lcdlr[6]; /* 0x80 */
  250. u8 reserved_0x98[8]; /* 0x98 */
  251. u32 mdlr[2]; /* 0xa0 */
  252. u8 reserved_0xa8[24]; /* 0xa8 */
  253. u32 gtr0; /* 0xc0 */
  254. u8 reserved_0xc4[12]; /* 0xc4 */
  255. /*
  256. * DXnRSR0 is not documented in ZynqMP manual but
  257. * it's used in libdram.
  258. */
  259. u32 rsr[4]; /* 0xd0 */
  260. u32 gsr[4]; /* 0xe0 */
  261. u8 reserved_0xf0[16]; /* 0xf0 */
  262. } dx[4]; /* 0x700, 0x800, 0x900, 0xa00 */
  263. };
  264. check_member(sunxi_mctl_phy_reg, dx[3].reserved_0xf0, 0xaf0);
  265. #define PIR_INIT BIT(0)
  266. #define PIR_ZCAL BIT(1)
  267. #define PIR_CA BIT(2)
  268. #define PIR_PLLINIT BIT(4)
  269. #define PIR_DCAL BIT(5)
  270. #define PIR_PHYRST BIT(6)
  271. #define PIR_DRAMRST BIT(7)
  272. #define PIR_DRAMINIT BIT(8)
  273. #define PIR_WL BIT(9)
  274. #define PIR_QSGATE BIT(10)
  275. #define PIR_WLADJ BIT(11)
  276. #define PIR_RDDSKW BIT(12)
  277. #define PIR_WRDSKW BIT(13)
  278. #define PIR_RDEYE BIT(14)
  279. #define PIR_WREYE BIT(15)
  280. #define PIR_VREF BIT(17)
  281. #define PIR_CTLDINIT BIT(18)
  282. #define PIR_DQS2DQ BIT(20)
  283. #define PIR_DCALPSE BIT(29)
  284. #define PIR_ZCALBYP BIT(30)
  285. #define DCR_LPDDR3 (1 << 0)
  286. #define DCR_DDR3 (3 << 0)
  287. #define DCR_DDR4 (4 << 0)
  288. #define DCR_DDR8BANK BIT(3)
  289. #define DCR_DDR2T BIT(28)
  290. /*
  291. * The delay parameters allow to allegedly specify delay times of some
  292. * unknown unit for each individual bit trace in each of the four data bytes
  293. * the 32-bit wide access consists of. Also three control signals can be
  294. * adjusted individually.
  295. */
  296. #define NR_OF_BYTE_LANES (32 / BITS_PER_BYTE)
  297. /* The eight data lines (DQn) plus DM, DQS, DQS/DM/DQ Output Enable and DQSN */
  298. #define WR_LINES_PER_BYTE_LANE (BITS_PER_BYTE + 4)
  299. /*
  300. * The eight data lines (DQn) plus DM, DQS, DQS/DM/DQ Output Enable, DQSN,
  301. * Termination and Power down
  302. */
  303. #define RD_LINES_PER_BYTE_LANE (BITS_PER_BYTE + 6)
  304. struct dram_para {
  305. u32 clk;
  306. enum sunxi_dram_type type;
  307. u8 cols;
  308. u8 rows;
  309. u8 ranks;
  310. u8 bus_full_width;
  311. const u8 dx_read_delays[NR_OF_BYTE_LANES][RD_LINES_PER_BYTE_LANE];
  312. const u8 dx_write_delays[NR_OF_BYTE_LANES][WR_LINES_PER_BYTE_LANE];
  313. };
  314. static inline int ns_to_t(int nanoseconds)
  315. {
  316. const unsigned int ctrl_freq = CONFIG_DRAM_CLK / 2;
  317. return DIV_ROUND_UP(ctrl_freq * nanoseconds, 1000);
  318. }
  319. void mctl_set_timing_params(struct dram_para *para);
  320. #endif /* _SUNXI_DRAM_SUN50I_H6_H */