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