]>
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 | * | |
f6974712 SW |
19 | * We assume bank 0 is RAM completely below 4G mostly ignore other banks; |
20 | * assuming they contain RAM above 4G. This is all a fairly safe assumption, | |
21 | * since the L4T kernel makes the same assumption, so the bootloader is | |
22 | * unlikely to change. | |
2a5f7f20 SW |
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; | |
f6974712 | 32 | } ram_banks[CONFIG_NR_DRAM_BANKS] = {{1}}; |
2a5f7f20 SW |
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 | ||
f6974712 SW |
57 | /* Calculate the true # of base/size pairs to read */ |
58 | len /= 4; /* Convert bytes to number of cells */ | |
59 | len /= (na + ns); /* Convert cells to number of banks */ | |
2a5f7f20 SW |
60 | if (len > ARRAY_SIZE(ram_banks)) |
61 | len = ARRAY_SIZE(ram_banks); | |
62 | ||
63 | gd->ram_size = 0; | |
64 | for (i = 0; i < len; i++) { | |
eed36609 | 65 | ram_banks[i].start = fdt_read_number(prop, na); |
2a5f7f20 | 66 | prop += na; |
eed36609 | 67 | ram_banks[i].size = fdt_read_number(prop, ns); |
2a5f7f20 SW |
68 | prop += ns; |
69 | gd->ram_size += ram_banks[i].size; | |
70 | } | |
71 | ||
72 | return 0; | |
73 | } | |
74 | ||
75 | extern unsigned long nvtboot_boot_x0; | |
76 | ||
76b00aca | 77 | int dram_init_banksize(void) |
2a5f7f20 SW |
78 | { |
79 | int i; | |
80 | ||
f6974712 | 81 | for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) { |
2a5f7f20 SW |
82 | gd->bd->bi_dram[i].start = ram_banks[i].start; |
83 | gd->bd->bi_dram[i].size = ram_banks[i].size; | |
84 | } | |
76b00aca | 85 | |
f6974712 SW |
86 | #ifdef CONFIG_PCI |
87 | gd->pci_ram_top = gd->bd->bi_dram[0].start + gd->bd->bi_dram[0].size; | |
88 | #endif | |
89 | ||
76b00aca | 90 | return 0; |
2a5f7f20 SW |
91 | } |
92 | ||
93 | ulong board_get_usable_ram_top(ulong total_size) | |
94 | { | |
95 | return ram_banks[0].start + ram_banks[0].size; | |
96 | } |