1 // SPDX-License-Identifier: GPL-2.0+
2 // (C) 2022 Pali Rohár <pali@kernel.org>
3 
4 #include <init.h>
5 #include <env.h>
6 #include <fdt_support.h>
7 #include <clock_legacy.h>
8 #include <image.h>
9 #include <asm/fsl_law.h>
10 #include <asm/global_data.h>
11 #include <asm/mmu.h>
12 #include <dm/device.h>
13 #include <dm/ofnode.h>
14 #include <linux/build_bug.h>
15 #include <display_options.h>
16 
17 #include "../turris_atsha_otp.h"
18 
19 DECLARE_GLOBAL_DATA_PTR;
20 
21 /*
22  * Reset time cycle register provided by Turris CPLD firmware.
23  * Turris CPLD firmware is open source and available at:
24  * https://gitlab.nic.cz/turris/hw/turris_cpld/-/blob/master/CZ_NIC_Router_CPLD.v
25  */
26 #define TURRIS_CPLD_RESET_TIME_CYCLE_REG	((void *)CFG_SYS_CPLD_BASE + 0x1f)
27 #define  TURRIS_CPLD_RESET_TIME_CYCLE_300MS	BIT(0)
28 #define  TURRIS_CPLD_RESET_TIME_CYCLE_1S	BIT(1)
29 #define  TURRIS_CPLD_RESET_TIME_CYCLE_2S	BIT(2)
30 #define  TURRIS_CPLD_RESET_TIME_CYCLE_3S	BIT(3)
31 #define  TURRIS_CPLD_RESET_TIME_CYCLE_4S	BIT(4)
32 #define  TURRIS_CPLD_RESET_TIME_CYCLE_5S	BIT(5)
33 #define  TURRIS_CPLD_RESET_TIME_CYCLE_6S	BIT(6)
34 
35 #define TURRIS_CPLD_LED_BRIGHTNESS_REG_FIRST	((void *)CFG_SYS_CPLD_BASE + 0x13)
36 #define TURRIS_CPLD_LED_BRIGHTNESS_REG_LAST	((void *)CFG_SYS_CPLD_BASE + 0x1e)
37 #define TURRIS_CPLD_LED_SW_OVERRIDE_REG		((void *)CFG_SYS_CPLD_BASE + 0x22)
38 
dram_init_banksize(void)39 int dram_init_banksize(void)
40 {
41 	phys_size_t size = gd->ram_size;
42 
43 	static_assert(CONFIG_NR_DRAM_BANKS >= 3);
44 
45 	gd->bd->bi_dram[0].start = gd->ram_base;
46 	gd->bd->bi_dram[0].size = get_effective_memsize();
47 	size -= gd->bd->bi_dram[0].size;
48 
49 	/* Note: This address space is not mapped via TLB entries in U-Boot */
50 
51 #ifndef CONFIG_SDCARD
52 	if (size > 0) {
53 		/*
54 		 * Setup additional overlapping 1 GB DDR LAW at the end of
55 		 * 32-bit physical address space. It overlaps with all other
56 		 * peripherals on P2020 mapped to physical address space.
57 		 * But this is not issue because documentation says:
58 		 * P2020 QorIQ Integrated Processor Reference Manual,
59 		 * section 2.3.1 Precedence of local access windows:
60 		 * If two local access windows overlap, the lower
61 		 * numbered window takes precedence.
62 		 */
63 		if (set_ddr_laws(0xc0000000, SZ_1G, LAW_TRGT_IF_DDR_1) < 0) {
64 			printf("Error: Cannot setup DDR LAW for more than 2 GB\n");
65 			return 0;
66 		}
67 	}
68 
69 	if (size > 0) {
70 		/* Free space between PCIe bus 3 MEM and NOR */
71 		gd->bd->bi_dram[1].start = 0xc0200000;
72 		gd->bd->bi_dram[1].size = min(size, 0xef000000 - gd->bd->bi_dram[1].start);
73 		size -= gd->bd->bi_dram[1].size;
74 	}
75 
76 	if (size > 0) {
77 		/* Free space between NOR and NAND */
78 		gd->bd->bi_dram[2].start = 0xf0000000;
79 		gd->bd->bi_dram[2].size = min(size, 0xff800000 - gd->bd->bi_dram[2].start);
80 		size -= gd->bd->bi_dram[2].size;
81 	}
82 #else
83 	puts("\n\n!!! TODO: fix sdcard >2GB RAM\n\n\n");
84 #endif
85 	return 0;
86 }
87 
fdt_setprop_inplace_u32_partial(void * blob,int node,const char * name,u32 idx,u32 val)88 static inline int fdt_setprop_inplace_u32_partial(void *blob, int node,
89 						  const char *name,
90 						  u32 idx, u32 val)
91 {
92 	val = cpu_to_fdt32(val);
93 
94 	return fdt_setprop_inplace_namelen_partial(blob, node, name,
95 						   strlen(name),
96 						   idx * sizeof(u32),
97 						   &val, sizeof(u32));
98 }
99 
100 /* Setup correct size of PCIe controller MEM in DT "ranges" property recursively */
fdt_fixup_pcie_mem_size(void * blob,int node,phys_size_t pcie1_mem,phys_size_t pcie2_mem,phys_size_t pcie3_mem)101 static void fdt_fixup_pcie_mem_size(void *blob, int node, phys_size_t pcie1_mem,
102 				    phys_size_t pcie2_mem, phys_size_t pcie3_mem)
103 {
104 	int pci_cells, cpu_cells, size_cells;
105 	const u32 *ranges;
106 	int pnode;
107 	int i, len;
108 	u32 pci_flags;
109 	u64 cpu_addr;
110 	u64 size;
111 	u64 new_size;
112 	int pcie_id;
113 	int idx;
114 	int subnode;
115 	int ret;
116 
117 	if (!fdtdec_get_is_enabled(blob, node))
118 		return;
119 
120 	ranges = fdt_getprop(blob, node, "ranges", &len);
121 	if (!ranges || !len || len % sizeof(u32))
122 		return;
123 
124 	/*
125 	 * The "ranges" property is an array of
126 	 *   { <PCI address> <CPU address> <size in PCI address space> }
127 	 * where number of PCI address cells and size cells is stored in the
128 	 * "#address-cells" and "#size-cells" properties of the same node
129 	 * containing the "ranges" property and number of CPU address cells
130 	 * is stored in the parent's "#address-cells" property.
131 	 *
132 	 * All 3 elements can span a different number of cells. Fetch them.
133 	 */
134 	pnode = fdt_parent_offset(blob, node);
135 	pci_cells = fdt_address_cells(blob, node);
136 	cpu_cells = fdt_address_cells(blob, pnode);
137 	size_cells = fdt_size_cells(blob, node);
138 
139 	/* PCI addresses always use 3 cells */
140 	if (pci_cells != 3)
141 		return;
142 
143 	/* CPU addresses and sizes on P2020 may be 32-bit (1 cell) or 64-bit (2 cells) */
144 	if (cpu_cells != 1 && cpu_cells != 2)
145 		return;
146 	if (size_cells != 1 && size_cells != 2)
147 		return;
148 
149 	for (i = 0; i < len / sizeof(u32); i += pci_cells + cpu_cells + size_cells) {
150 		/* PCI address consists of 3 cells: flags, addr.hi, addr.lo */
151 		pci_flags = fdt32_to_cpu(ranges[i]);
152 
153 		cpu_addr = fdt32_to_cpu(ranges[i + pci_cells]);
154 		if (cpu_cells == 2) {
155 			cpu_addr <<= 32;
156 			cpu_addr |= fdt32_to_cpu(ranges[i + pci_cells + 1]);
157 		}
158 
159 		size = fdt32_to_cpu(ranges[i + pci_cells + cpu_cells]);
160 		if (size_cells == 2) {
161 			size <<= 32;
162 			size |= fdt32_to_cpu(ranges[i + pci_cells + cpu_cells + 1]);
163 		}
164 
165 		/*
166 		 * Bits [25:24] of PCI flags defines space code
167 		 * 0b10 is 32-bit MEM and 0b11 is 64-bit MEM.
168 		 * Check for any type of PCIe MEM mapping.
169 		 */
170 		if (!(pci_flags & 0x02000000))
171 			continue;
172 
173 		if (cpu_addr == CFG_SYS_PCIE1_MEM_PHYS && size > pcie1_mem) {
174 			pcie_id = 1;
175 			new_size = pcie1_mem;
176 		} else if (cpu_addr == CFG_SYS_PCIE2_MEM_PHYS && size > pcie2_mem) {
177 			pcie_id = 2;
178 			new_size = pcie2_mem;
179 		} else if (cpu_addr == CFG_SYS_PCIE3_MEM_PHYS && size > pcie3_mem) {
180 			pcie_id = 3;
181 			new_size = pcie3_mem;
182 		} else {
183 			continue;
184 		}
185 
186 		printf("Decreasing PCIe MEM %d size from ", pcie_id);
187 		print_size(size, " to ");
188 		print_size(new_size, "\n");
189 		idx = i + pci_cells + cpu_cells;
190 		if (size_cells == 2) {
191 			ret = fdt_setprop_inplace_u32_partial(blob, node,
192 							      "ranges", idx, 0);
193 			if (ret)
194 				goto err;
195 			idx++;
196 		}
197 		ret = fdt_setprop_inplace_u32_partial(blob, node,
198 						      "ranges", idx, SZ_2M);
199 		if (ret)
200 			goto err;
201 	}
202 
203 	/* Recursively fix also all subnodes */
204 	fdt_for_each_subnode(subnode, blob, node)
205 		fdt_fixup_pcie_mem_size(blob, subnode, pcie1_mem, pcie2_mem, pcie3_mem);
206 
207 	return;
208 
209 err:
210 	printf("Error: Cannot update \"ranges\" property\n");
211 }
212 
get_law_size(phys_addr_t addr,enum law_trgt_if id)213 static inline phys_size_t get_law_size(phys_addr_t addr, enum law_trgt_if id)
214 {
215 	struct law_entry e;
216 
217 	e = find_law_by_addr_id(addr, id);
218 	if (e.index < 0)
219 		return 0;
220 
221 	return 2ULL << e.size;
222 }
223 
ft_memory_setup(void * blob,struct bd_info * bd)224 void ft_memory_setup(void *blob, struct bd_info *bd)
225 {
226 	phys_size_t pcie1_mem, pcie2_mem, pcie3_mem;
227 	u64 start[CONFIG_NR_DRAM_BANKS];
228 	u64 size[CONFIG_NR_DRAM_BANKS];
229 	int count;
230 	int node;
231 
232 	if (!env_get("bootm_low") && !env_get("bootm_size")) {
233 		for (count = 0; count < CONFIG_NR_DRAM_BANKS; count++) {
234 			start[count] = gd->bd->bi_dram[count].start;
235 			size[count] = gd->bd->bi_dram[count].size;
236 			if (!size[count])
237 				break;
238 		}
239 		fdt_fixup_memory_banks(blob, start, size, count);
240 	} else {
241 		fdt_fixup_memory(blob, env_get_bootm_low(), env_get_bootm_size());
242 	}
243 
244 	pcie1_mem = get_law_size(CFG_SYS_PCIE1_MEM_PHYS, LAW_TRGT_IF_PCIE_1);
245 	pcie2_mem = get_law_size(CFG_SYS_PCIE2_MEM_PHYS, LAW_TRGT_IF_PCIE_2);
246 	pcie3_mem = get_law_size(CFG_SYS_PCIE3_MEM_PHYS, LAW_TRGT_IF_PCIE_3);
247 
248 	fdt_for_each_node_by_compatible(node, blob, -1, "fsl,mpc8548-pcie")
249 		fdt_fixup_pcie_mem_size(blob, node, pcie1_mem, pcie2_mem, pcie3_mem);
250 }
251 
detect_model_serial(const char ** model,char serial[17])252 static int detect_model_serial(const char **model, char serial[17])
253 {
254 	u32 version_num;
255 	int err;
256 
257 	err = turris_atsha_otp_get_serial_number(serial);
258 	if (err) {
259 		*model = "Turris 1.x";
260 		strcpy(serial, "unknown");
261 		return -1;
262 	}
263 
264 	version_num = simple_strtoull(serial, NULL, 16) >> 32;
265 
266 	/*
267 	 * Turris 1.0 boards (RTRS01) have version_num 0x5.
268 	 * Turris 1.1 boards (RTRS02) have version_num 0x6, 0x7, 0x8 and 0x9.
269 	 */
270 	if (be32_to_cpu(version_num) >= 0x6) {
271 		*model = "Turris 1.1 (RTRS02)";
272 		return 1;
273 	}
274 
275 	*model = "Turris 1.0 (RTRS01)";
276 	return 0;
277 }
278 
p1_p2_rdb_pc_fix_fdt_model(void * blob)279 void p1_p2_rdb_pc_fix_fdt_model(void *blob)
280 {
281 	const char *model;
282 	char serial[17];
283 	int len;
284 	int off;
285 	int rev;
286 	char c;
287 
288 	rev = detect_model_serial(&model, serial);
289 	if (rev < 0)
290 		return;
291 
292 	/* Turris 1.0 boards (RTRS01) do not have third PCIe controller */
293 	if (rev == 0) {
294 		off = fdt_path_offset(blob, "pci2");
295 		if (off >= 0)
296 			fdt_del_node(blob, off);
297 	}
298 
299 	/* Fix model string only in case it is generic "Turris 1.x" */
300 	model = fdt_getprop(blob, 0, "model", &len);
301 	if (len < sizeof("Turris 1.x") - 1)
302 		return;
303 	if (memcmp(model, "Turris 1.x", sizeof("Turris 1.x") - 1) != 0)
304 		return;
305 
306 	c = '0' + rev;
307 	fdt_setprop_inplace_namelen_partial(blob, 0, "model", sizeof("model") - 1,
308 					    sizeof("Turris 1.") - 1, &c, 1);
309 }
310 
misc_init_r(void)311 int misc_init_r(void)
312 {
313 	turris_atsha_otp_init_mac_addresses(0);
314 	turris_atsha_otp_init_serial_number();
315 	return 0;
316 }
317 
318 /* This comes from ../../freescale/p1_p2_rdb_pc/p1_p2_rdb_pc.c */
319 extern int checkboard_p1_p2(void);
320 
checkboard(void)321 int checkboard(void)
322 {
323 	const char *model;
324 	char serial[17];
325 	void *reg;
326 
327 	/* Disable software control of all Turris LEDs */
328 	out_8(TURRIS_CPLD_LED_SW_OVERRIDE_REG, 0x00);
329 
330 	/* Reset colors of all Turris LEDs to their default values */
331 	for (reg = TURRIS_CPLD_LED_BRIGHTNESS_REG_FIRST;
332 	     reg <= TURRIS_CPLD_LED_BRIGHTNESS_REG_LAST;
333 	     reg++)
334 		out_8(reg, 0xff);
335 
336 	detect_model_serial(&model, serial);
337 	printf("Revision: %s\n", model);
338 	printf("Serial Number: %s\n", serial);
339 
340 	return checkboard_p1_p2();
341 }
342 
handle_reset_button(void)343 static void handle_reset_button(void)
344 {
345 	const char * const vars[1] = { "bootcmd_rescue", };
346 	u8 reset_time_raw, reset_time;
347 
348 	/*
349 	 * Ensure that bootcmd_rescue has always stock value, so that running
350 	 *   run bootcmd_rescue
351 	 * always works correctly.
352 	 */
353 	env_set_default_vars(1, (char * const *)vars, 0);
354 
355 	reset_time_raw = in_8(TURRIS_CPLD_RESET_TIME_CYCLE_REG);
356 	if (reset_time_raw & TURRIS_CPLD_RESET_TIME_CYCLE_6S)
357 		reset_time = 6;
358 	else if (reset_time_raw & TURRIS_CPLD_RESET_TIME_CYCLE_5S)
359 		reset_time = 5;
360 	else if (reset_time_raw & TURRIS_CPLD_RESET_TIME_CYCLE_4S)
361 		reset_time = 4;
362 	else if (reset_time_raw & TURRIS_CPLD_RESET_TIME_CYCLE_3S)
363 		reset_time = 3;
364 	else if (reset_time_raw & TURRIS_CPLD_RESET_TIME_CYCLE_2S)
365 		reset_time = 2;
366 	else if (reset_time_raw & TURRIS_CPLD_RESET_TIME_CYCLE_1S)
367 		reset_time = 1;
368 	else
369 		reset_time = 0;
370 
371 	env_set_ulong("turris_reset", reset_time);
372 
373 	/* Check if red reset button was hold for at least six seconds. */
374 	if (reset_time >= 6) {
375 		const char * const vars[3] = {
376 			"bootcmd",
377 			"bootdelay",
378 			"distro_bootcmd",
379 		};
380 
381 		/*
382 		 * Set the above envs to their default values, in case the user
383 		 * managed to break them.
384 		 */
385 		env_set_default_vars(3, (char * const *)vars, 0);
386 
387 		/* Ensure bootcmd_rescue is used by distroboot */
388 		env_set("boot_targets", "rescue");
389 
390 		printf("RESET button was hold for >= 6s, overwriting boot_targets for system rescue!\n");
391 	} else {
392 		/*
393 		 * In case the user somehow managed to save environment with
394 		 * boot_targets=rescue, reset boot_targets to default value.
395 		 * This could happen in subsequent commands if bootcmd_rescue
396 		 * failed.
397 		 */
398 		if (!strcmp(env_get("boot_targets"), "rescue")) {
399 			const char * const vars[1] = {
400 				"boot_targets",
401 			};
402 
403 			env_set_default_vars(1, (char * const *)vars, 0);
404 		}
405 
406 		if (reset_time > 0)
407 			printf("RESET button was hold for %us.\n", reset_time);
408 	}
409 }
410 
recalculate_pcie_mem_law(phys_addr_t addr,pci_size_t pcie_size,enum law_trgt_if id,phys_addr_t * free_start,phys_size_t * free_size)411 static int recalculate_pcie_mem_law(phys_addr_t addr,
412 				    pci_size_t pcie_size,
413 				    enum law_trgt_if id,
414 				    phys_addr_t *free_start,
415 				    phys_size_t *free_size)
416 {
417 	phys_size_t cur_size, new_size;
418 	struct law_entry e;
419 
420 	e = find_law_by_addr_id(addr, id);
421 	if (e.index < 0) {
422 		*free_start = *free_size = 0;
423 		return 0;
424 	}
425 
426 	cur_size = 2ULL << e.size;
427 	new_size = roundup_pow_of_two(pcie_size);
428 
429 	if (new_size >= cur_size) {
430 		*free_start = *free_size = 0;
431 		return 0;
432 	}
433 
434 	set_law(e.index, addr, law_size_bits(new_size), id);
435 
436 	*free_start = addr + new_size;
437 	*free_size = cur_size - new_size;
438 	return 1;
439 }
440 
recalculate_used_pcie_mem(void)441 static void recalculate_used_pcie_mem(void)
442 {
443 	phys_addr_t free_start1, free_start2;
444 	phys_size_t free_size1, free_size2;
445 	pci_size_t pcie1_used_mem_size;
446 	pci_size_t pcie2_used_mem_size;
447 	struct law_entry e;
448 	phys_size_t size;
449 	ofnode node;
450 	int i;
451 
452 	size = gd->ram_size;
453 
454 	for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++)
455 		size -= gd->bd->bi_dram[i].size;
456 
457 	if (size == 0)
458 		return;
459 
460 	e = find_law_by_addr_id(CFG_SYS_PCIE3_MEM_PHYS, LAW_TRGT_IF_PCIE_3);
461 	if (e.index < 0 && gd->bd->bi_dram[1].size > 0) {
462 		/*
463 		 * If there is no LAW for PCIe 3 MEM then 3rd PCIe controller
464 		 * is inactive, which is the case for Turris 1.0 boards. So
465 		 * use its reserved 2 MB physical space for DDR RAM.
466 		 */
467 		unsigned int bank_size = SZ_2M;
468 
469 		if (bank_size > size)
470 			bank_size = size;
471 		printf("Reserving unused ");
472 		print_size(bank_size, "");
473 		printf(" of PCIe 3 MEM for DDR RAM\n");
474 		gd->bd->bi_dram[1].start -= bank_size;
475 		gd->bd->bi_dram[1].size += bank_size;
476 		size -= bank_size;
477 		if (size == 0)
478 			return;
479 	}
480 
481 #ifdef CONFIG_PCI_PNP
482 	/*
483 	 * Detect how much space of PCIe MEM is needed for both PCIe 1 and
484 	 * PCIe 2 controllers with all connected cards on whole hierarchy.
485 	 * This works only when U-Boot has enabled PCI PNP code which scans
486 	 * all PCI devices and calculate required memory for every PCI BAR of
487 	 * every PCI device.
488 	 */
489 	ofnode_for_each_compatible_node(node, "fsl,mpc8548-pcie") {
490 		struct udevice *dev;
491 
492 		if (device_find_global_by_ofnode(node, &dev))
493 			continue;
494 
495 		struct pci_controller *hose = dev_get_uclass_priv(pci_get_controller(dev));
496 
497 		if (!hose)
498 			continue;
499 		if (!hose->pci_mem)
500 			continue;
501 		if (!hose->pci_mem->size)
502 			continue;
503 
504 		pci_size_t used_mem_size = hose->pci_mem->bus_lower - hose->pci_mem->bus_start;
505 
506 		if (hose->pci_mem->phys_start == CFG_SYS_PCIE1_MEM_PHYS)
507 			pcie1_used_mem_size = used_mem_size;
508 		else if (hose->pci_mem->phys_start == CFG_SYS_PCIE2_MEM_PHYS)
509 			pcie2_used_mem_size = used_mem_size;
510 	}
511 
512 	if (pcie1_used_mem_size == 0 && pcie2_used_mem_size == 0)
513 		return;
514 
515 	e = find_law_by_addr_id(0xc0000000, LAW_TRGT_IF_DDR_1);
516 	if (e.index < 0) {
517 		printf("Error: Cannot setup DDR LAW for more than 3 GB of RAM\n");
518 		return;
519 	}
520 
521 	/*
522 	 * Increase additional overlapping 1 GB DDR LAW from 1GB to 2GB by
523 	 * moving its left side from 0xc0000000 to 0x80000000. After this
524 	 * change it would overlap with PCIe MEM 1 and 2 LAWs.
525 	 */
526 	set_law(e.index, 0x80000000, LAW_SIZE_2G, LAW_TRGT_IF_DDR_1);
527 
528 	i = 3;
529 	static_assert(CONFIG_NR_DRAM_BANKS >= 3 + 2);
530 
531 	if (recalculate_pcie_mem_law(CFG_SYS_PCIE2_MEM_PHYS,
532 				     pcie2_used_mem_size, LAW_TRGT_IF_PCIE_2,
533 				     &free_start2, &free_size2)) {
534 		printf("Reserving unused ");
535 		print_size(free_size2, "");
536 		printf(" of PCIe 2 MEM for DDR RAM\n");
537 		gd->bd->bi_dram[i].start = free_start2;
538 		gd->bd->bi_dram[i].size = min(size, free_size2);
539 		size -= gd->bd->bi_dram[i].start;
540 		i++;
541 		if (size == 0)
542 			return;
543 	}
544 
545 	if (recalculate_pcie_mem_law(CFG_SYS_PCIE1_MEM_PHYS,
546 				     pcie1_used_mem_size, LAW_TRGT_IF_PCIE_1,
547 				     &free_start1, &free_size1)) {
548 		printf("Reserving unused ");
549 		print_size(free_size1, "");
550 		printf(" of PCIe 1 MEM for DDR RAM\n");
551 		gd->bd->bi_dram[i].start = free_start1;
552 		gd->bd->bi_dram[i].size = min(size, free_size1);
553 		size -= gd->bd->bi_dram[i].size;
554 		i++;
555 		if (size == 0)
556 			return;
557 	}
558 #endif
559 }
560 
last_stage_init(void)561 int last_stage_init(void)
562 {
563 	handle_reset_button();
564 	recalculate_used_pcie_mem();
565 	return 0;
566 }
567 
get_serial_clock(void)568 int get_serial_clock(void)
569 {
570 	return get_bus_freq(0);
571 }
572