sdram_soc64.c 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * Copyright (C) 2016-2021 Intel Corporation <www.intel.com>
  4. *
  5. */
  6. #include <common.h>
  7. #include <cpu_func.h>
  8. #include <dm.h>
  9. #include <errno.h>
  10. #include <div64.h>
  11. #include <fdtdec.h>
  12. #include <hang.h>
  13. #include <init.h>
  14. #include <log.h>
  15. #include <ram.h>
  16. #include <reset.h>
  17. #include "sdram_soc64.h"
  18. #include <wait_bit.h>
  19. #include <asm/arch/firewall.h>
  20. #include <asm/arch/system_manager.h>
  21. #include <asm/arch/reset_manager.h>
  22. #include <asm/cache.h>
  23. #include <asm/global_data.h>
  24. #include <asm/io.h>
  25. #include <dm/device_compat.h>
  26. #include <linux/sizes.h>
  27. #define PGTABLE_OFF 0x4000
  28. u32 hmc_readl(struct altera_sdram_plat *plat, u32 reg)
  29. {
  30. return readl(plat->iomhc + reg);
  31. }
  32. u32 hmc_ecc_readl(struct altera_sdram_plat *plat, u32 reg)
  33. {
  34. return readl(plat->hmc + reg);
  35. }
  36. u32 hmc_ecc_writel(struct altera_sdram_plat *plat,
  37. u32 data, u32 reg)
  38. {
  39. return writel(data, plat->hmc + reg);
  40. }
  41. u32 ddr_sch_writel(struct altera_sdram_plat *plat, u32 data,
  42. u32 reg)
  43. {
  44. return writel(data, plat->ddr_sch + reg);
  45. }
  46. int emif_clear(struct altera_sdram_plat *plat)
  47. {
  48. hmc_ecc_writel(plat, 0, RSTHANDSHAKECTRL);
  49. return wait_for_bit_le32((const void *)(plat->hmc +
  50. RSTHANDSHAKESTAT),
  51. DDR_HMC_RSTHANDSHAKE_MASK,
  52. false, 1000, false);
  53. }
  54. int emif_reset(struct altera_sdram_plat *plat)
  55. {
  56. u32 c2s, s2c, ret;
  57. c2s = hmc_ecc_readl(plat, RSTHANDSHAKECTRL) & DDR_HMC_RSTHANDSHAKE_MASK;
  58. s2c = hmc_ecc_readl(plat, RSTHANDSHAKESTAT) & DDR_HMC_RSTHANDSHAKE_MASK;
  59. debug("DDR: c2s=%08x s2c=%08x nr0=%08x nr1=%08x nr2=%08x dst=%08x\n",
  60. c2s, s2c, hmc_readl(plat, NIOSRESERVED0),
  61. hmc_readl(plat, NIOSRESERVED1), hmc_readl(plat, NIOSRESERVED2),
  62. hmc_readl(plat, DRAMSTS));
  63. if (s2c && emif_clear(plat)) {
  64. printf("DDR: emif_clear() failed\n");
  65. return -1;
  66. }
  67. debug("DDR: Triggerring emif reset\n");
  68. hmc_ecc_writel(plat, DDR_HMC_CORE2SEQ_INT_REQ, RSTHANDSHAKECTRL);
  69. /* if seq2core[3] = 0, we are good */
  70. ret = wait_for_bit_le32((const void *)(plat->hmc +
  71. RSTHANDSHAKESTAT),
  72. DDR_HMC_SEQ2CORE_INT_RESP_MASK,
  73. false, 1000, false);
  74. if (ret) {
  75. printf("DDR: failed to get ack from EMIF\n");
  76. return ret;
  77. }
  78. ret = emif_clear(plat);
  79. if (ret) {
  80. printf("DDR: emif_clear() failed\n");
  81. return ret;
  82. }
  83. debug("DDR: %s triggered successly\n", __func__);
  84. return 0;
  85. }
  86. #if !IS_ENABLED(CONFIG_TARGET_SOCFPGA_N5X)
  87. int poll_hmc_clock_status(void)
  88. {
  89. return wait_for_bit_le32((const void *)(socfpga_get_sysmgr_addr() +
  90. SYSMGR_SOC64_HMC_CLK),
  91. SYSMGR_HMC_CLK_STATUS_MSK, true, 1000, false);
  92. }
  93. #endif
  94. void sdram_clear_mem(phys_addr_t addr, phys_size_t size)
  95. {
  96. phys_size_t i;
  97. if (addr % CONFIG_SYS_CACHELINE_SIZE) {
  98. printf("DDR: address 0x%llx is not cacheline size aligned.\n",
  99. addr);
  100. hang();
  101. }
  102. if (size % CONFIG_SYS_CACHELINE_SIZE) {
  103. printf("DDR: size 0x%llx is not multiple of cacheline size\n",
  104. size);
  105. hang();
  106. }
  107. /* Use DC ZVA instruction to clear memory to zeros by a cache line */
  108. for (i = 0; i < size; i = i + CONFIG_SYS_CACHELINE_SIZE) {
  109. asm volatile("dc zva, %0"
  110. :
  111. : "r"(addr)
  112. : "memory");
  113. addr += CONFIG_SYS_CACHELINE_SIZE;
  114. }
  115. }
  116. void sdram_init_ecc_bits(struct bd_info *bd)
  117. {
  118. phys_size_t size, size_init;
  119. phys_addr_t start_addr;
  120. int bank = 0;
  121. unsigned int start = get_timer(0);
  122. icache_enable();
  123. start_addr = bd->bi_dram[0].start;
  124. size = bd->bi_dram[0].size;
  125. /* Initialize small block for page table */
  126. memset((void *)start_addr, 0, PGTABLE_SIZE + PGTABLE_OFF);
  127. gd->arch.tlb_addr = start_addr + PGTABLE_OFF;
  128. gd->arch.tlb_size = PGTABLE_SIZE;
  129. start_addr += PGTABLE_SIZE + PGTABLE_OFF;
  130. size -= (PGTABLE_OFF + PGTABLE_SIZE);
  131. dcache_enable();
  132. while (1) {
  133. while (size) {
  134. size_init = min((phys_addr_t)SZ_1G, (phys_addr_t)size);
  135. sdram_clear_mem(start_addr, size_init);
  136. size -= size_init;
  137. start_addr += size_init;
  138. WATCHDOG_RESET();
  139. }
  140. bank++;
  141. if (bank >= CONFIG_NR_DRAM_BANKS)
  142. break;
  143. start_addr = bd->bi_dram[bank].start;
  144. size = bd->bi_dram[bank].size;
  145. }
  146. dcache_disable();
  147. icache_disable();
  148. printf("SDRAM-ECC: Initialized success with %d ms\n",
  149. (unsigned int)get_timer(start));
  150. }
  151. void sdram_size_check(struct bd_info *bd)
  152. {
  153. phys_size_t total_ram_check = 0;
  154. phys_size_t ram_check = 0;
  155. phys_addr_t start = 0;
  156. phys_size_t size, remaining_size;
  157. int bank;
  158. /* Sanity check ensure correct SDRAM size specified */
  159. debug("DDR: Running SDRAM size sanity check\n");
  160. for (bank = 0; bank < CONFIG_NR_DRAM_BANKS; bank++) {
  161. start = bd->bi_dram[bank].start;
  162. remaining_size = bd->bi_dram[bank].size;
  163. while (ram_check < bd->bi_dram[bank].size) {
  164. size = min((phys_addr_t)SZ_1G,
  165. (phys_addr_t)remaining_size);
  166. /*
  167. * Ensure the size is power of two, this is requirement
  168. * to run get_ram_size() / memory test
  169. */
  170. if (size != 0 && ((size & (size - 1)) == 0)) {
  171. ram_check += get_ram_size((void *)
  172. (start + ram_check), size);
  173. remaining_size = bd->bi_dram[bank].size -
  174. ram_check;
  175. } else {
  176. puts("DDR: Memory test requires SDRAM size ");
  177. puts("in power of two!\n");
  178. hang();
  179. }
  180. }
  181. total_ram_check += ram_check;
  182. ram_check = 0;
  183. }
  184. /* If the ram_size is 2GB smaller, we can assume the IO space is
  185. * not mapped in. gd->ram_size is the actual size of the dram
  186. * not the accessible size.
  187. */
  188. if (total_ram_check != gd->ram_size) {
  189. puts("DDR: SDRAM size check failed!\n");
  190. hang();
  191. }
  192. debug("DDR: SDRAM size check passed!\n");
  193. }
  194. /**
  195. * sdram_calculate_size() - Calculate SDRAM size
  196. *
  197. * Calculate SDRAM device size based on SDRAM controller parameters.
  198. * Size is specified in bytes.
  199. */
  200. phys_size_t sdram_calculate_size(struct altera_sdram_plat *plat)
  201. {
  202. u32 dramaddrw = hmc_readl(plat, DRAMADDRW);
  203. phys_size_t size = 1 << (DRAMADDRW_CFG_CS_ADDR_WIDTH(dramaddrw) +
  204. DRAMADDRW_CFG_BANK_GRP_ADDR_WIDTH(dramaddrw) +
  205. DRAMADDRW_CFG_BANK_ADDR_WIDTH(dramaddrw) +
  206. DRAMADDRW_CFG_ROW_ADDR_WIDTH(dramaddrw) +
  207. DRAMADDRW_CFG_COL_ADDR_WIDTH(dramaddrw));
  208. size *= (2 << (hmc_ecc_readl(plat, DDRIOCTRL) &
  209. DDR_HMC_DDRIOCTRL_IOSIZE_MSK));
  210. return size;
  211. }
  212. void sdram_set_firewall(struct bd_info *bd)
  213. {
  214. u32 i;
  215. phys_size_t value;
  216. u32 lower, upper;
  217. for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) {
  218. if (!bd->bi_dram[i].size)
  219. continue;
  220. value = bd->bi_dram[i].start;
  221. /* Keep first 1MB of SDRAM memory region as secure region when
  222. * using ATF flow, where the ATF code is located.
  223. */
  224. if (IS_ENABLED(CONFIG_SPL_ATF) && i == 0)
  225. value += SZ_1M;
  226. /* Setting non-secure MPU region base and base extended */
  227. lower = lower_32_bits(value);
  228. upper = upper_32_bits(value);
  229. FW_MPU_DDR_SCR_WRITEL(lower,
  230. FW_MPU_DDR_SCR_MPUREGION0ADDR_BASE +
  231. (i * 4 * sizeof(u32)));
  232. FW_MPU_DDR_SCR_WRITEL(upper & 0xff,
  233. FW_MPU_DDR_SCR_MPUREGION0ADDR_BASEEXT +
  234. (i * 4 * sizeof(u32)));
  235. /* Setting non-secure Non-MPU region base and base extended */
  236. FW_MPU_DDR_SCR_WRITEL(lower,
  237. FW_MPU_DDR_SCR_NONMPUREGION0ADDR_BASE +
  238. (i * 4 * sizeof(u32)));
  239. FW_MPU_DDR_SCR_WRITEL(upper & 0xff,
  240. FW_MPU_DDR_SCR_NONMPUREGION0ADDR_BASEEXT +
  241. (i * 4 * sizeof(u32)));
  242. /* Setting non-secure MPU limit and limit extexded */
  243. value = bd->bi_dram[i].start + bd->bi_dram[i].size - 1;
  244. lower = lower_32_bits(value);
  245. upper = upper_32_bits(value);
  246. FW_MPU_DDR_SCR_WRITEL(lower,
  247. FW_MPU_DDR_SCR_MPUREGION0ADDR_LIMIT +
  248. (i * 4 * sizeof(u32)));
  249. FW_MPU_DDR_SCR_WRITEL(upper & 0xff,
  250. FW_MPU_DDR_SCR_MPUREGION0ADDR_LIMITEXT +
  251. (i * 4 * sizeof(u32)));
  252. /* Setting non-secure Non-MPU limit and limit extexded */
  253. FW_MPU_DDR_SCR_WRITEL(lower,
  254. FW_MPU_DDR_SCR_NONMPUREGION0ADDR_LIMIT +
  255. (i * 4 * sizeof(u32)));
  256. FW_MPU_DDR_SCR_WRITEL(upper & 0xff,
  257. FW_MPU_DDR_SCR_NONMPUREGION0ADDR_LIMITEXT +
  258. (i * 4 * sizeof(u32)));
  259. FW_MPU_DDR_SCR_WRITEL(BIT(i) | BIT(i + 8),
  260. FW_MPU_DDR_SCR_EN_SET);
  261. }
  262. }
  263. static int altera_sdram_of_to_plat(struct udevice *dev)
  264. {
  265. struct altera_sdram_plat *plat = dev_get_plat(dev);
  266. fdt_addr_t addr;
  267. /* These regs info are part of DDR handoff in bitstream */
  268. #if IS_ENABLED(CONFIG_TARGET_SOCFPGA_N5X)
  269. return 0;
  270. #endif
  271. addr = dev_read_addr_index(dev, 0);
  272. if (addr == FDT_ADDR_T_NONE)
  273. return -EINVAL;
  274. plat->ddr_sch = (void __iomem *)addr;
  275. addr = dev_read_addr_index(dev, 1);
  276. if (addr == FDT_ADDR_T_NONE)
  277. return -EINVAL;
  278. plat->iomhc = (void __iomem *)addr;
  279. addr = dev_read_addr_index(dev, 2);
  280. if (addr == FDT_ADDR_T_NONE)
  281. return -EINVAL;
  282. plat->hmc = (void __iomem *)addr;
  283. return 0;
  284. }
  285. static int altera_sdram_probe(struct udevice *dev)
  286. {
  287. int ret;
  288. struct altera_sdram_priv *priv = dev_get_priv(dev);
  289. ret = reset_get_bulk(dev, &priv->resets);
  290. if (ret) {
  291. dev_err(dev, "Can't get reset: %d\n", ret);
  292. return -ENODEV;
  293. }
  294. reset_deassert_bulk(&priv->resets);
  295. if (sdram_mmr_init_full(dev) != 0) {
  296. puts("SDRAM init failed.\n");
  297. goto failed;
  298. }
  299. return 0;
  300. failed:
  301. reset_release_bulk(&priv->resets);
  302. return -ENODEV;
  303. }
  304. static int altera_sdram_get_info(struct udevice *dev,
  305. struct ram_info *info)
  306. {
  307. struct altera_sdram_priv *priv = dev_get_priv(dev);
  308. info->base = priv->info.base;
  309. info->size = priv->info.size;
  310. return 0;
  311. }
  312. static struct ram_ops altera_sdram_ops = {
  313. .get_info = altera_sdram_get_info,
  314. };
  315. static const struct udevice_id altera_sdram_ids[] = {
  316. { .compatible = "altr,sdr-ctl-s10" },
  317. { .compatible = "intel,sdr-ctl-agilex" },
  318. { .compatible = "intel,sdr-ctl-n5x" },
  319. { /* sentinel */ }
  320. };
  321. U_BOOT_DRIVER(altera_sdram) = {
  322. .name = "altr_sdr_ctl",
  323. .id = UCLASS_RAM,
  324. .of_match = altera_sdram_ids,
  325. .ops = &altera_sdram_ops,
  326. .of_to_plat = altera_sdram_of_to_plat,
  327. .plat_auto = sizeof(struct altera_sdram_plat),
  328. .probe = altera_sdram_probe,
  329. .priv_auto = sizeof(struct altera_sdram_priv),
  330. };