imxrt_sdram.c 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454
  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. #if !defined(TARGET_IMXRT1170_EVK)
  83. #define SEMC_IOCR_MUX_A8_SHIFT 0
  84. #define SEMC_IOCR_MUX_CSX0_SHIFT 3
  85. #define SEMC_IOCR_MUX_CSX1_SHIFT 6
  86. #define SEMC_IOCR_MUX_CSX2_SHIFT 9
  87. #define SEMC_IOCR_MUX_CSX3_SHIFT 12
  88. #define SEMC_IOCR_MUX_RDY_SHIFT 15
  89. #else
  90. #define SEMC_IOCR_MUX_A8_SHIFT 0
  91. #define SEMC_IOCR_MUX_CSX0_SHIFT 4
  92. #define SEMC_IOCR_MUX_CSX1_SHIFT 8
  93. #define SEMC_IOCR_MUX_CSX2_SHIFT 12
  94. #define SEMC_IOCR_MUX_CSX3_SHIFT 16
  95. #define SEMC_IOCR_MUX_RDY_SHIFT 20
  96. #endif
  97. struct imxrt_sdram_mux {
  98. u8 a8;
  99. u8 csx0;
  100. u8 csx1;
  101. u8 csx2;
  102. u8 csx3;
  103. u8 rdy;
  104. };
  105. #define SEMC_SDRAMCR0_PS_SHIFT 0
  106. #define SEMC_SDRAMCR0_BL_SHIFT 4
  107. #define SEMC_SDRAMCR0_COL_SHIFT 8
  108. #define SEMC_SDRAMCR0_CL_SHIFT 10
  109. struct imxrt_sdram_control {
  110. u8 memory_width;
  111. u8 burst_len;
  112. u8 no_columns;
  113. u8 cas_latency;
  114. };
  115. #define SEMC_SDRAMCR1_PRE2ACT_SHIFT 0
  116. #define SEMC_SDRAMCR1_ACT2RW_SHIFT 4
  117. #define SEMC_SDRAMCR1_RFRC_SHIFT 8
  118. #define SEMC_SDRAMCR1_WRC_SHIFT 13
  119. #define SEMC_SDRAMCR1_CKEOFF_SHIFT 16
  120. #define SEMC_SDRAMCR1_ACT2PRE_SHIFT 20
  121. #define SEMC_SDRAMCR2_SRRC_SHIFT 0
  122. #define SEMC_SDRAMCR2_REF2REF_SHIFT 8
  123. #define SEMC_SDRAMCR2_ACT2ACT_SHIFT 16
  124. #define SEMC_SDRAMCR2_ITO_SHIFT 24
  125. #define SEMC_SDRAMCR3_REN BIT(0)
  126. #define SEMC_SDRAMCR3_REBL_SHIFT 1
  127. #define SEMC_SDRAMCR3_PRESCALE_SHIFT 8
  128. #define SEMC_SDRAMCR3_RT_SHIFT 16
  129. #define SEMC_SDRAMCR3_UT_SHIFT 24
  130. struct imxrt_sdram_timing {
  131. u8 pre2act;
  132. u8 act2rw;
  133. u8 rfrc;
  134. u8 wrc;
  135. u8 ckeoff;
  136. u8 act2pre;
  137. u8 srrc;
  138. u8 ref2ref;
  139. u8 act2act;
  140. u8 ito;
  141. u8 rebl;
  142. u8 prescale;
  143. u8 rt;
  144. u8 ut;
  145. };
  146. enum imxrt_semc_bank {
  147. SDRAM_BANK1,
  148. SDRAM_BANK2,
  149. SDRAM_BANK3,
  150. SDRAM_BANK4,
  151. MAX_SDRAM_BANK,
  152. };
  153. #define SEMC_BR_VLD_MASK 1
  154. #define SEMC_BR_MS_SHIFT 1
  155. struct bank_params {
  156. enum imxrt_semc_bank target_bank;
  157. u32 base_address;
  158. u32 memory_size;
  159. };
  160. struct imxrt_sdram_params {
  161. struct imxrt_semc_regs *base;
  162. struct imxrt_sdram_mux *sdram_mux;
  163. struct imxrt_sdram_control *sdram_control;
  164. struct imxrt_sdram_timing *sdram_timing;
  165. struct bank_params bank_params[MAX_SDRAM_BANK];
  166. u8 no_sdram_banks;
  167. };
  168. static int imxrt_sdram_wait_ipcmd_done(struct imxrt_semc_regs *regs)
  169. {
  170. do {
  171. readl(&regs->intr);
  172. if (regs->intr & SEMC_INTR_IPCMDDONE)
  173. return 0;
  174. if (regs->intr & SEMC_INTR_IPCMDERR)
  175. return -EIO;
  176. mdelay(50);
  177. } while (1);
  178. }
  179. static int imxrt_sdram_ipcmd(struct imxrt_semc_regs *regs, u32 mem_addr,
  180. u32 ipcmd, u32 wd, u32 *rd)
  181. {
  182. int ret;
  183. if (ipcmd == SD_CC_IWR || ipcmd == SD_CC_IMS)
  184. writel(wd, &regs->iptxdat);
  185. /* set slave address for every command as specified on RM */
  186. writel(mem_addr, &regs->ipcr0);
  187. /* execute command */
  188. writel(SEMC_IPCMD_KEY | ipcmd, &regs->ipcmd);
  189. ret = imxrt_sdram_wait_ipcmd_done(regs);
  190. if (ret < 0)
  191. return ret;
  192. if (ipcmd == SD_CC_IRD) {
  193. if (!rd)
  194. return -EINVAL;
  195. *rd = readl(&regs->iprxdat);
  196. }
  197. return 0;
  198. }
  199. int imxrt_sdram_init(struct udevice *dev)
  200. {
  201. struct imxrt_sdram_params *params = dev_get_plat(dev);
  202. struct imxrt_sdram_mux *mux = params->sdram_mux;
  203. struct imxrt_sdram_control *ctrl = params->sdram_control;
  204. struct imxrt_sdram_timing *time = params->sdram_timing;
  205. struct imxrt_semc_regs *regs = params->base;
  206. struct bank_params *bank_params;
  207. u32 rd;
  208. int i;
  209. /* enable the SEMC controller */
  210. clrbits_le32(&regs->mcr, SEMC_MCR_MDIS);
  211. /* set DQS mode from DQS pad */
  212. setbits_le32(&regs->mcr, SEMC_MCR_DQSMD);
  213. for (i = 0, bank_params = params->bank_params;
  214. i < params->no_sdram_banks; bank_params++,
  215. i++)
  216. writel((bank_params->base_address & 0xfffff000)
  217. | bank_params->memory_size << SEMC_BR_MS_SHIFT
  218. | SEMC_BR_VLD_MASK,
  219. &regs->br[bank_params->target_bank]);
  220. writel(mux->a8 << SEMC_IOCR_MUX_A8_SHIFT
  221. | mux->csx0 << SEMC_IOCR_MUX_CSX0_SHIFT
  222. | mux->csx1 << SEMC_IOCR_MUX_CSX1_SHIFT
  223. | mux->csx2 << SEMC_IOCR_MUX_CSX2_SHIFT
  224. | mux->csx3 << SEMC_IOCR_MUX_CSX3_SHIFT
  225. | mux->rdy << SEMC_IOCR_MUX_RDY_SHIFT,
  226. &regs->iocr);
  227. writel(ctrl->memory_width << SEMC_SDRAMCR0_PS_SHIFT
  228. | ctrl->burst_len << SEMC_SDRAMCR0_BL_SHIFT
  229. | ctrl->no_columns << SEMC_SDRAMCR0_COL_SHIFT
  230. | ctrl->cas_latency << SEMC_SDRAMCR0_CL_SHIFT,
  231. &regs->sdramcr0);
  232. writel(time->pre2act << SEMC_SDRAMCR1_PRE2ACT_SHIFT
  233. | time->act2rw << SEMC_SDRAMCR1_ACT2RW_SHIFT
  234. | time->rfrc << SEMC_SDRAMCR1_RFRC_SHIFT
  235. | time->wrc << SEMC_SDRAMCR1_WRC_SHIFT
  236. | time->ckeoff << SEMC_SDRAMCR1_CKEOFF_SHIFT
  237. | time->act2pre << SEMC_SDRAMCR1_ACT2PRE_SHIFT,
  238. &regs->sdramcr1);
  239. writel(time->srrc << SEMC_SDRAMCR2_SRRC_SHIFT
  240. | time->ref2ref << SEMC_SDRAMCR2_REF2REF_SHIFT
  241. | time->act2act << SEMC_SDRAMCR2_ACT2ACT_SHIFT
  242. | time->ito << SEMC_SDRAMCR2_ITO_SHIFT,
  243. &regs->sdramcr2);
  244. writel(time->rebl << SEMC_SDRAMCR3_REBL_SHIFT
  245. | time->prescale << SEMC_SDRAMCR3_PRESCALE_SHIFT
  246. | time->rt << SEMC_SDRAMCR3_RT_SHIFT
  247. | time->ut << SEMC_SDRAMCR3_UT_SHIFT
  248. | SEMC_SDRAMCR3_REN,
  249. &regs->sdramcr3);
  250. writel(2, &regs->ipcr1);
  251. for (i = 0, bank_params = params->bank_params;
  252. i < params->no_sdram_banks; bank_params++,
  253. i++) {
  254. mdelay(250);
  255. imxrt_sdram_ipcmd(regs, bank_params->base_address, SD_CC_IPREA,
  256. 0, &rd);
  257. imxrt_sdram_ipcmd(regs, bank_params->base_address, SD_CC_IAF,
  258. 0, &rd);
  259. imxrt_sdram_ipcmd(regs, bank_params->base_address, SD_CC_IAF,
  260. 0, &rd);
  261. imxrt_sdram_ipcmd(regs, bank_params->base_address, SD_CC_IMS,
  262. ctrl->burst_len | (ctrl->cas_latency << 4),
  263. &rd);
  264. mdelay(250);
  265. }
  266. return 0;
  267. }
  268. static int imxrt_semc_of_to_plat(struct udevice *dev)
  269. {
  270. struct imxrt_sdram_params *params = dev_get_plat(dev);
  271. ofnode bank_node;
  272. u8 bank = 0;
  273. params->sdram_mux =
  274. (struct imxrt_sdram_mux *)
  275. dev_read_u8_array_ptr(dev,
  276. "fsl,sdram-mux",
  277. sizeof(struct imxrt_sdram_mux));
  278. if (!params->sdram_mux) {
  279. pr_err("fsl,sdram-mux not found");
  280. return -EINVAL;
  281. }
  282. params->sdram_control =
  283. (struct imxrt_sdram_control *)
  284. dev_read_u8_array_ptr(dev,
  285. "fsl,sdram-control",
  286. sizeof(struct imxrt_sdram_control));
  287. if (!params->sdram_control) {
  288. pr_err("fsl,sdram-control not found");
  289. return -EINVAL;
  290. }
  291. params->sdram_timing =
  292. (struct imxrt_sdram_timing *)
  293. dev_read_u8_array_ptr(dev,
  294. "fsl,sdram-timing",
  295. sizeof(struct imxrt_sdram_timing));
  296. if (!params->sdram_timing) {
  297. pr_err("fsl,sdram-timing not found");
  298. return -EINVAL;
  299. }
  300. dev_for_each_subnode(bank_node, dev) {
  301. struct bank_params *bank_params;
  302. char *bank_name;
  303. int ret;
  304. /* extract the bank index from DT */
  305. bank_name = (char *)ofnode_get_name(bank_node);
  306. strsep(&bank_name, "@");
  307. if (!bank_name) {
  308. pr_err("missing sdram bank index");
  309. return -EINVAL;
  310. }
  311. bank_params = &params->bank_params[bank];
  312. strict_strtoul(bank_name, 10,
  313. (unsigned long *)&bank_params->target_bank);
  314. if (bank_params->target_bank >= MAX_SDRAM_BANK) {
  315. pr_err("Found bank %d , but only bank 0,1,2,3 are supported",
  316. bank_params->target_bank);
  317. return -EINVAL;
  318. }
  319. ret = ofnode_read_u32(bank_node,
  320. "fsl,memory-size",
  321. &bank_params->memory_size);
  322. if (ret < 0) {
  323. pr_err("fsl,memory-size not found");
  324. return -EINVAL;
  325. }
  326. ret = ofnode_read_u32(bank_node,
  327. "fsl,base-address",
  328. &bank_params->base_address);
  329. if (ret < 0) {
  330. pr_err("fsl,base-address not found");
  331. return -EINVAL;
  332. }
  333. debug("Found bank %s %u\n", bank_name,
  334. bank_params->target_bank);
  335. bank++;
  336. }
  337. params->no_sdram_banks = bank;
  338. debug("%s, no of banks = %d\n", __func__, params->no_sdram_banks);
  339. return 0;
  340. }
  341. static int imxrt_semc_probe(struct udevice *dev)
  342. {
  343. struct imxrt_sdram_params *params = dev_get_plat(dev);
  344. int ret;
  345. fdt_addr_t addr;
  346. addr = dev_read_addr(dev);
  347. if (addr == FDT_ADDR_T_NONE)
  348. return -EINVAL;
  349. params->base = (struct imxrt_semc_regs *)addr;
  350. #ifdef CONFIG_CLK
  351. struct clk clk;
  352. ret = clk_get_by_index(dev, 0, &clk);
  353. if (ret < 0)
  354. return ret;
  355. ret = clk_enable(&clk);
  356. if (ret) {
  357. dev_err(dev, "failed to enable clock\n");
  358. return ret;
  359. }
  360. #endif
  361. ret = imxrt_sdram_init(dev);
  362. if (ret)
  363. return ret;
  364. return 0;
  365. }
  366. static int imxrt_semc_get_info(struct udevice *dev, struct ram_info *info)
  367. {
  368. return 0;
  369. }
  370. static struct ram_ops imxrt_semc_ops = {
  371. .get_info = imxrt_semc_get_info,
  372. };
  373. static const struct udevice_id imxrt_semc_ids[] = {
  374. { .compatible = "fsl,imxrt-semc", .data = 0 },
  375. { }
  376. };
  377. U_BOOT_DRIVER(imxrt_semc) = {
  378. .name = "imxrt_semc",
  379. .id = UCLASS_RAM,
  380. .of_match = imxrt_semc_ids,
  381. .ops = &imxrt_semc_ops,
  382. .of_to_plat = imxrt_semc_of_to_plat,
  383. .probe = imxrt_semc_probe,
  384. .plat_auto = sizeof(struct imxrt_sdram_params),
  385. };