blob: 7a0b68caaef6eba220ccc5ab8952a1fc5cf0da5a [file] [log] [blame]
Pali Rohár6763ff82024-06-06 18:33:26 +02001// 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
19DECLARE_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
39int 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
88static 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 */
101static 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
209err:
210 printf("Error: Cannot update \"ranges\" property\n");
211}
212
213static 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
224void 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
252static 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
279void 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
311int 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 */
319extern int checkboard_p1_p2(void);
320
321int 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
343static 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
411static 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
441static 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
561int last_stage_init(void)
562{
563 handle_reset_button();
564 recalculate_used_pcie_mem();
565 return 0;
566}
567
568int get_serial_clock(void)
569{
570 return get_bus_freq(0);
571}