]>
Commit | Line | Data |
---|---|---|
2a5f7f20 SW |
1 | /* |
2 | * Copyright (c) 2016, NVIDIA CORPORATION. | |
3 | * | |
4 | * SPDX-License-Identifier: GPL-2.0+ | |
5 | */ | |
6 | ||
7 | #include <common.h> | |
8 | #include <fdt_support.h> | |
9 | #include <fdtdec.h> | |
10 | #include <asm/arch/tegra.h> | |
11 | ||
12 | DECLARE_GLOBAL_DATA_PTR; | |
13 | ||
14 | extern unsigned long nvtboot_boot_x0; | |
15 | ||
16 | /* | |
17 | * A parsed version of /memory/reg from the DTB that is passed to U-Boot in x0. | |
18 | * | |
19 | * We only support up to two banks since that's all the binary bootloader | |
20 | * ever sets. We assume bank 0 is RAM below 4G and bank 1 is RAM above 4G. | |
21 | * This is all a fairly safe assumption, since the L4T kernel makes the same | |
22 | * assumptions, so the bootloader is unlikely to change. | |
23 | * | |
24 | * This is written to before relocation, and hence cannot be in .bss, since | |
25 | * .bss overlaps the DTB that's appended to the U-Boot binary. The initializer | |
26 | * forces this into .data and avoids this issue. This also has the nice side- | |
27 | * effect of the content being valid after relocation. | |
28 | */ | |
29 | static struct { | |
30 | u64 start; | |
31 | u64 size; | |
32 | } ram_banks[2] = {{1}}; | |
33 | ||
34 | int dram_init(void) | |
35 | { | |
36 | unsigned int na, ns; | |
37 | const void *nvtboot_blob = (void *)nvtboot_boot_x0; | |
38 | int node, len, i; | |
39 | const u32 *prop; | |
40 | ||
41 | memset(ram_banks, 0, sizeof(ram_banks)); | |
42 | ||
43 | na = fdtdec_get_uint(nvtboot_blob, 0, "#address-cells", 2); | |
44 | ns = fdtdec_get_uint(nvtboot_blob, 0, "#size-cells", 2); | |
45 | ||
46 | node = fdt_path_offset(nvtboot_blob, "/memory"); | |
47 | if (node < 0) { | |
9b643e31 | 48 | pr_err("Can't find /memory node in nvtboot DTB"); |
2a5f7f20 SW |
49 | hang(); |
50 | } | |
51 | prop = fdt_getprop(nvtboot_blob, node, "reg", &len); | |
52 | if (!prop) { | |
9b643e31 | 53 | pr_err("Can't find /memory/reg property in nvtboot DTB"); |
2a5f7f20 SW |
54 | hang(); |
55 | } | |
56 | ||
57 | len /= (na + ns); | |
58 | if (len > ARRAY_SIZE(ram_banks)) | |
59 | len = ARRAY_SIZE(ram_banks); | |
60 | ||
61 | gd->ram_size = 0; | |
62 | for (i = 0; i < len; i++) { | |
eed36609 | 63 | ram_banks[i].start = fdt_read_number(prop, na); |
2a5f7f20 | 64 | prop += na; |
eed36609 | 65 | ram_banks[i].size = fdt_read_number(prop, ns); |
2a5f7f20 SW |
66 | prop += ns; |
67 | gd->ram_size += ram_banks[i].size; | |
68 | } | |
69 | ||
70 | return 0; | |
71 | } | |
72 | ||
73 | extern unsigned long nvtboot_boot_x0; | |
74 | ||
76b00aca | 75 | int dram_init_banksize(void) |
2a5f7f20 SW |
76 | { |
77 | int i; | |
78 | ||
79 | for (i = 0; i < 2; i++) { | |
80 | gd->bd->bi_dram[i].start = ram_banks[i].start; | |
81 | gd->bd->bi_dram[i].size = ram_banks[i].size; | |
82 | } | |
76b00aca SG |
83 | |
84 | return 0; | |
2a5f7f20 SW |
85 | } |
86 | ||
87 | ulong board_get_usable_ram_top(ulong total_size) | |
88 | { | |
89 | return ram_banks[0].start + ram_banks[0].size; | |
90 | } |