imxrt_sdram.c 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * Copyright (C) 2019
  4. * Author(s): Giulio Benetti <giulio.benetti@benettiengineering.com>
  5. */
  6. #include <common.h>
  7. #include <clk.h>
  8. #include <dm.h>
  9. #include <dm/device_compat.h>
  10. #include <init.h>
  11. #include <log.h>
  12. #include <ram.h>
  13. #include <asm/io.h>
  14. #include <linux/bitops.h>
  15. #include <linux/delay.h>
  16. #include <linux/err.h>
  17. /* SDRAM Command Code */
  18. #define SD_CC_ARD 0x0 /* Master Bus (AXI) command - Read */
  19. #define SD_CC_AWR 0x1 /* Master Bus (AXI) command - Write */
  20. #define SD_CC_IRD 0x8 /* IP command - Read */
  21. #define SD_CC_IWR 0x9 /* IP command - Write */
  22. #define SD_CC_IMS 0xA /* IP command - Set Mode Register */
  23. #define SD_CC_IACT 0xB /* IP command - ACTIVE */
  24. #define SD_CC_IAF 0xC /* IP command - Auto Refresh */
  25. #define SD_CC_ISF 0xD /* IP Command - Self Refresh */
  26. #define SD_CC_IPRE 0xE /* IP command - Precharge */
  27. #define SD_CC_IPREA 0xF /* IP command - Precharge ALL */
  28. #define SEMC_MCR_MDIS BIT(1)
  29. #define SEMC_MCR_DQSMD BIT(2)
  30. #define SEMC_INTR_IPCMDERR BIT(1)
  31. #define SEMC_INTR_IPCMDDONE BIT(0)
  32. #define SEMC_IPCMD_KEY 0xA55A0000
  33. struct imxrt_semc_regs {
  34. /* 0x0 */
  35. u32 mcr;
  36. u32 iocr;
  37. u32 bmcr0;
  38. u32 bmcr1;
  39. u32 br[9];
  40. /* 0x34 */
  41. u32 res1;
  42. u32 inten;
  43. u32 intr;
  44. /* 0x40 */
  45. u32 sdramcr0;
  46. u32 sdramcr1;
  47. u32 sdramcr2;
  48. u32 sdramcr3;
  49. /* 0x50 */
  50. u32 nandcr0;
  51. u32 nandcr1;
  52. u32 nandcr2;
  53. u32 nandcr3;
  54. /* 0x60 */
  55. u32 norcr0;
  56. u32 norcr1;
  57. u32 norcr2;
  58. u32 norcr3;
  59. /* 0x70 */
  60. u32 sramcr0;
  61. u32 sramcr1;
  62. u32 sramcr2;
  63. u32 sramcr3;
  64. /* 0x80 */
  65. u32 dbicr0;
  66. u32 dbicr1;
  67. u32 res2[2];
  68. /* 0x90 */
  69. u32 ipcr0;
  70. u32 ipcr1;
  71. u32 ipcr2;
  72. u32 ipcmd;
  73. /* 0xA0 */
  74. u32 iptxdat;
  75. u32 res3[3];
  76. /* 0xB0 */
  77. u32 iprxdat;
  78. u32 res4[3];
  79. /* 0xC0 */
  80. u32 sts[16];
  81. };
  82. #define SEMC_IOCR_MUX_A8_SHIFT 0
  83. #define SEMC_IOCR_MUX_CSX0_SHIFT 3
  84. #define SEMC_IOCR_MUX_CSX1_SHIFT 6
  85. #define SEMC_IOCR_MUX_CSX2_SHIFT 9
  86. #define SEMC_IOCR_MUX_CSX3_SHIFT 12
  87. #define SEMC_IOCR_MUX_RDY_SHIFT 15
  88. struct imxrt_sdram_mux {
  89. u8 a8;
  90. u8 csx0;
  91. u8 csx1;
  92. u8 csx2;
  93. u8 csx3;
  94. u8 rdy;
  95. };
  96. #define SEMC_SDRAMCR0_PS_SHIFT 0
  97. #define SEMC_SDRAMCR0_BL_SHIFT 4
  98. #define SEMC_SDRAMCR0_COL_SHIFT 8
  99. #define SEMC_SDRAMCR0_CL_SHIFT 10
  100. struct imxrt_sdram_control {
  101. u8 memory_width;
  102. u8 burst_len;
  103. u8 no_columns;
  104. u8 cas_latency;
  105. };
  106. #define SEMC_SDRAMCR1_PRE2ACT_SHIFT 0
  107. #define SEMC_SDRAMCR1_ACT2RW_SHIFT 4
  108. #define SEMC_SDRAMCR1_RFRC_SHIFT 8
  109. #define SEMC_SDRAMCR1_WRC_SHIFT 13
  110. #define SEMC_SDRAMCR1_CKEOFF_SHIFT 16
  111. #define SEMC_SDRAMCR1_ACT2PRE_SHIFT 20
  112. #define SEMC_SDRAMCR2_SRRC_SHIFT 0
  113. #define SEMC_SDRAMCR2_REF2REF_SHIFT 8
  114. #define SEMC_SDRAMCR2_ACT2ACT_SHIFT 16
  115. #define SEMC_SDRAMCR2_ITO_SHIFT 24
  116. #define SEMC_SDRAMCR3_REN BIT(0)
  117. #define SEMC_SDRAMCR3_REBL_SHIFT 1
  118. #define SEMC_SDRAMCR3_PRESCALE_SHIFT 8
  119. #define SEMC_SDRAMCR3_RT_SHIFT 16
  120. #define SEMC_SDRAMCR3_UT_SHIFT 24
  121. struct imxrt_sdram_timing {
  122. u8 pre2act;
  123. u8 act2rw;
  124. u8 rfrc;
  125. u8 wrc;
  126. u8 ckeoff;
  127. u8 act2pre;
  128. u8 srrc;
  129. u8 ref2ref;
  130. u8 act2act;
  131. u8 ito;
  132. u8 rebl;
  133. u8 prescale;
  134. u8 rt;
  135. u8 ut;
  136. };
  137. enum imxrt_semc_bank {
  138. SDRAM_BANK1,
  139. SDRAM_BANK2,
  140. SDRAM_BANK3,
  141. SDRAM_BANK4,
  142. MAX_SDRAM_BANK,
  143. };
  144. #define SEMC_BR_VLD_MASK 1
  145. #define SEMC_BR_MS_SHIFT 1
  146. struct bank_params {
  147. enum imxrt_semc_bank target_bank;
  148. u32 base_address;
  149. u32 memory_size;
  150. };
  151. struct imxrt_sdram_params {
  152. struct imxrt_semc_regs *base;
  153. struct imxrt_sdram_mux *sdram_mux;
  154. struct imxrt_sdram_control *sdram_control;
  155. struct imxrt_sdram_timing *sdram_timing;
  156. struct bank_params bank_params[MAX_SDRAM_BANK];
  157. u8 no_sdram_banks;
  158. };
  159. static int imxrt_sdram_wait_ipcmd_done(struct imxrt_semc_regs *regs)
  160. {
  161. do {
  162. readl(&regs->intr);
  163. if (regs->intr & SEMC_INTR_IPCMDDONE)
  164. return 0;
  165. if (regs->intr & SEMC_INTR_IPCMDERR)
  166. return -EIO;
  167. mdelay(50);
  168. } while (1);
  169. }
  170. static int imxrt_sdram_ipcmd(struct imxrt_semc_regs *regs, u32 mem_addr,
  171. u32 ipcmd, u32 wd, u32 *rd)
  172. {
  173. int ret;
  174. if (ipcmd == SD_CC_IWR || ipcmd == SD_CC_IMS)
  175. writel(wd, &regs->iptxdat);
  176. /* set slave address for every command as specified on RM */
  177. writel(mem_addr, &regs->ipcr0);
  178. /* execute command */
  179. writel(SEMC_IPCMD_KEY | ipcmd, &regs->ipcmd);
  180. ret = imxrt_sdram_wait_ipcmd_done(regs);
  181. if (ret < 0)
  182. return ret;
  183. if (ipcmd == SD_CC_IRD) {
  184. if (!rd)
  185. return -EINVAL;
  186. *rd = readl(&regs->iprxdat);
  187. }
  188. return 0;
  189. }
  190. int imxrt_sdram_init(struct udevice *dev)
  191. {
  192. struct imxrt_sdram_params *params = dev_get_platdata(dev);
  193. struct imxrt_sdram_mux *mux = params->sdram_mux;
  194. struct imxrt_sdram_control *ctrl = params->sdram_control;
  195. struct imxrt_sdram_timing *time = params->sdram_timing;
  196. struct imxrt_semc_regs *regs = params->base;
  197. struct bank_params *bank_params;
  198. u32 rd;
  199. int i;
  200. /* enable the SEMC controller */
  201. clrbits_le32(&regs->mcr, SEMC_MCR_MDIS);
  202. /* set DQS mode from DQS pad */
  203. setbits_le32(&regs->mcr, SEMC_MCR_DQSMD);
  204. for (i = 0, bank_params = params->bank_params;
  205. i < params->no_sdram_banks; bank_params++,
  206. i++)
  207. writel((bank_params->base_address & 0xfffff000)
  208. | bank_params->memory_size << SEMC_BR_MS_SHIFT
  209. | SEMC_BR_VLD_MASK,
  210. &regs->br[bank_params->target_bank]);
  211. writel(mux->a8 << SEMC_IOCR_MUX_A8_SHIFT
  212. | mux->csx0 << SEMC_IOCR_MUX_CSX0_SHIFT
  213. | mux->csx1 << SEMC_IOCR_MUX_CSX1_SHIFT
  214. | mux->csx2 << SEMC_IOCR_MUX_CSX2_SHIFT
  215. | mux->csx3 << SEMC_IOCR_MUX_CSX3_SHIFT
  216. | mux->rdy << SEMC_IOCR_MUX_RDY_SHIFT,
  217. &regs->iocr);
  218. writel(ctrl->memory_width << SEMC_SDRAMCR0_PS_SHIFT
  219. | ctrl->burst_len << SEMC_SDRAMCR0_BL_SHIFT
  220. | ctrl->no_columns << SEMC_SDRAMCR0_COL_SHIFT
  221. | ctrl->cas_latency << SEMC_SDRAMCR0_CL_SHIFT,
  222. &regs->sdramcr0);
  223. writel(time->pre2act << SEMC_SDRAMCR1_PRE2ACT_SHIFT
  224. | time->act2rw << SEMC_SDRAMCR1_ACT2RW_SHIFT
  225. | time->rfrc << SEMC_SDRAMCR1_RFRC_SHIFT
  226. | time->wrc << SEMC_SDRAMCR1_WRC_SHIFT
  227. | time->ckeoff << SEMC_SDRAMCR1_CKEOFF_SHIFT
  228. | time->act2pre << SEMC_SDRAMCR1_ACT2PRE_SHIFT,
  229. &regs->sdramcr1);
  230. writel(time->srrc << SEMC_SDRAMCR2_SRRC_SHIFT
  231. | time->ref2ref << SEMC_SDRAMCR2_REF2REF_SHIFT
  232. | time->act2act << SEMC_SDRAMCR2_ACT2ACT_SHIFT
  233. | time->ito << SEMC_SDRAMCR2_ITO_SHIFT,
  234. &regs->sdramcr2);
  235. writel(time->rebl << SEMC_SDRAMCR3_REBL_SHIFT
  236. | time->prescale << SEMC_SDRAMCR3_PRESCALE_SHIFT
  237. | time->rt << SEMC_SDRAMCR3_RT_SHIFT
  238. | time->ut << SEMC_SDRAMCR3_UT_SHIFT
  239. | SEMC_SDRAMCR3_REN,
  240. &regs->sdramcr3);
  241. writel(2, &regs->ipcr1);
  242. for (i = 0, bank_params = params->bank_params;
  243. i < params->no_sdram_banks; bank_params++,
  244. i++) {
  245. mdelay(250);
  246. imxrt_sdram_ipcmd(regs, bank_params->base_address, SD_CC_IPREA,
  247. 0, &rd);
  248. imxrt_sdram_ipcmd(regs, bank_params->base_address, SD_CC_IAF,
  249. 0, &rd);
  250. imxrt_sdram_ipcmd(regs, bank_params->base_address, SD_CC_IAF,
  251. 0, &rd);
  252. imxrt_sdram_ipcmd(regs, bank_params->base_address, SD_CC_IMS,
  253. ctrl->burst_len | (ctrl->cas_latency << 4),
  254. &rd);
  255. mdelay(250);
  256. }
  257. return 0;
  258. }
  259. static int imxrt_semc_ofdata_to_platdata(struct udevice *dev)
  260. {
  261. struct imxrt_sdram_params *params = dev_get_platdata(dev);
  262. ofnode bank_node;
  263. u8 bank = 0;
  264. params->sdram_mux =
  265. (struct imxrt_sdram_mux *)
  266. dev_read_u8_array_ptr(dev,
  267. "fsl,sdram-mux",
  268. sizeof(struct imxrt_sdram_mux));
  269. if (!params->sdram_mux) {
  270. pr_err("fsl,sdram-mux not found");
  271. return -EINVAL;
  272. }
  273. params->sdram_control =
  274. (struct imxrt_sdram_control *)
  275. dev_read_u8_array_ptr(dev,
  276. "fsl,sdram-control",
  277. sizeof(struct imxrt_sdram_control));
  278. if (!params->sdram_control) {
  279. pr_err("fsl,sdram-control not found");
  280. return -EINVAL;
  281. }
  282. params->sdram_timing =
  283. (struct imxrt_sdram_timing *)
  284. dev_read_u8_array_ptr(dev,
  285. "fsl,sdram-timing",
  286. sizeof(struct imxrt_sdram_timing));
  287. if (!params->sdram_timing) {
  288. pr_err("fsl,sdram-timing not found");
  289. return -EINVAL;
  290. }
  291. dev_for_each_subnode(bank_node, dev) {
  292. struct bank_params *bank_params;
  293. char *bank_name;
  294. int ret;
  295. /* extract the bank index from DT */
  296. bank_name = (char *)ofnode_get_name(bank_node);
  297. strsep(&bank_name, "@");
  298. if (!bank_name) {
  299. pr_err("missing sdram bank index");
  300. return -EINVAL;
  301. }
  302. bank_params = &params->bank_params[bank];
  303. strict_strtoul(bank_name, 10,
  304. (unsigned long *)&bank_params->target_bank);
  305. if (bank_params->target_bank >= MAX_SDRAM_BANK) {
  306. pr_err("Found bank %d , but only bank 0,1,2,3 are supported",
  307. bank_params->target_bank);
  308. return -EINVAL;
  309. }
  310. ret = ofnode_read_u32(bank_node,
  311. "fsl,memory-size",
  312. &bank_params->memory_size);
  313. if (ret < 0) {
  314. pr_err("fsl,memory-size not found");
  315. return -EINVAL;
  316. }
  317. ret = ofnode_read_u32(bank_node,
  318. "fsl,base-address",
  319. &bank_params->base_address);
  320. if (ret < 0) {
  321. pr_err("fsl,base-address not found");
  322. return -EINVAL;
  323. }
  324. debug("Found bank %s %u\n", bank_name,
  325. bank_params->target_bank);
  326. bank++;
  327. }
  328. params->no_sdram_banks = bank;
  329. debug("%s, no of banks = %d\n", __func__, params->no_sdram_banks);
  330. return 0;
  331. }
  332. static int imxrt_semc_probe(struct udevice *dev)
  333. {
  334. struct imxrt_sdram_params *params = dev_get_platdata(dev);
  335. int ret;
  336. fdt_addr_t addr;
  337. addr = dev_read_addr(dev);
  338. if (addr == FDT_ADDR_T_NONE)
  339. return -EINVAL;
  340. params->base = (struct imxrt_semc_regs *)addr;
  341. #ifdef CONFIG_CLK
  342. struct clk clk;
  343. ret = clk_get_by_index(dev, 0, &clk);
  344. if (ret < 0)
  345. return ret;
  346. ret = clk_enable(&clk);
  347. if (ret) {
  348. dev_err(dev, "failed to enable clock\n");
  349. return ret;
  350. }
  351. #endif
  352. ret = imxrt_sdram_init(dev);
  353. if (ret)
  354. return ret;
  355. return 0;
  356. }
  357. static int imxrt_semc_get_info(struct udevice *dev, struct ram_info *info)
  358. {
  359. return 0;
  360. }
  361. static struct ram_ops imxrt_semc_ops = {
  362. .get_info = imxrt_semc_get_info,
  363. };
  364. static const struct udevice_id imxrt_semc_ids[] = {
  365. { .compatible = "fsl,imxrt-semc", .data = 0 },
  366. { }
  367. };
  368. U_BOOT_DRIVER(imxrt_semc) = {
  369. .name = "imxrt_semc",
  370. .id = UCLASS_RAM,
  371. .of_match = imxrt_semc_ids,
  372. .ops = &imxrt_semc_ops,
  373. .ofdata_to_platdata = imxrt_semc_ofdata_to_platdata,
  374. .probe = imxrt_semc_probe,
  375. .platdata_auto_alloc_size = sizeof(struct imxrt_sdram_params),
  376. };