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