blob: c2c176e3d44f5274dc81c31c87ee7bdf01895d30 [file] [log] [blame]
Stefan Roese21b29fc2016-05-25 08:13:45 +02001/*
2 * Copyright (C) 2016 Stefan Roese <sr@denx.de>
3 *
4 * SPDX-License-Identifier: GPL-2.0+
5 */
6
7#include <common.h>
8#include <dm.h>
9#include <fdtdec.h>
10#include <libfdt.h>
Konstantin Porotchkinf4f194e2017-04-05 17:42:33 +030011#include <pci.h>
Stefan Roese21b29fc2016-05-25 08:13:45 +020012#include <asm/io.h>
13#include <asm/system.h>
14#include <asm/arch/cpu.h>
15#include <asm/arch/soc.h>
16#include <asm/armv8/mmu.h>
17
18DECLARE_GLOBAL_DATA_PTR;
19
20/*
Stefan Roese059f75d2016-11-11 08:18:44 +010021 * Not all memory is mapped in the MMU. So we need to restrict the
22 * memory size so that U-Boot does not try to access it. Also, the
23 * internal registers are located at 0xf000.0000 - 0xffff.ffff.
24 * Currently only 2GiB are mapped for system memory. This is what
25 * we pass to the U-Boot subsystem here.
26 */
27#define USABLE_RAM_SIZE 0x80000000
28
29ulong board_get_usable_ram_top(ulong total_size)
30{
31 if (gd->ram_size > USABLE_RAM_SIZE)
32 return USABLE_RAM_SIZE;
33
34 return gd->ram_size;
35}
36
37/*
Stefan Roese21b29fc2016-05-25 08:13:45 +020038 * On ARMv8, MBus is not configured in U-Boot. To enable compilation
39 * of the already implemented drivers, lets add a dummy version of
40 * this function so that linking does not fail.
41 */
42const struct mbus_dram_target_info *mvebu_mbus_dram_info(void)
43{
44 return NULL;
45}
46
47/* DRAM init code ... */
48
49static const void *get_memory_reg_prop(const void *fdt, int *lenp)
50{
51 int offset;
52
53 offset = fdt_path_offset(fdt, "/memory");
54 if (offset < 0)
55 return NULL;
56
57 return fdt_getprop(fdt, offset, "reg", lenp);
58}
59
60int dram_init(void)
61{
62 const void *fdt = gd->fdt_blob;
63 const fdt32_t *val;
64 int ac, sc, len;
65
66 ac = fdt_address_cells(fdt, 0);
67 sc = fdt_size_cells(fdt, 0);
68 if (ac < 0 || sc < 1 || sc > 2) {
69 printf("invalid address/size cells\n");
70 return -EINVAL;
71 }
72
73 val = get_memory_reg_prop(fdt, &len);
74 if (len / sizeof(*val) < ac + sc)
75 return -EINVAL;
76
77 val += ac;
78
79 gd->ram_size = fdtdec_get_number(val, sc);
80
81 debug("DRAM size = %08lx\n", (unsigned long)gd->ram_size);
82
83 return 0;
84}
85
Simon Glass76b00ac2017-03-31 08:40:32 -060086int dram_init_banksize(void)
Stefan Roese21b29fc2016-05-25 08:13:45 +020087{
88 const void *fdt = gd->fdt_blob;
89 const fdt32_t *val;
90 int ac, sc, cells, len, i;
91
92 val = get_memory_reg_prop(fdt, &len);
93 if (len < 0)
Simon Glass76b00ac2017-03-31 08:40:32 -060094 return -ENXIO;
Stefan Roese21b29fc2016-05-25 08:13:45 +020095
96 ac = fdt_address_cells(fdt, 0);
97 sc = fdt_size_cells(fdt, 0);
xypron.glpk@gmx.de1275a442017-05-03 23:31:58 +020098 if (ac < 1 || ac > 2 || sc < 1 || sc > 2) {
Stefan Roese21b29fc2016-05-25 08:13:45 +020099 printf("invalid address/size cells\n");
Simon Glass76b00ac2017-03-31 08:40:32 -0600100 return -ENXIO;
Stefan Roese21b29fc2016-05-25 08:13:45 +0200101 }
102
103 cells = ac + sc;
104
105 len /= sizeof(*val);
106
107 for (i = 0; i < CONFIG_NR_DRAM_BANKS && len >= cells;
108 i++, len -= cells) {
109 gd->bd->bi_dram[i].start = fdtdec_get_number(val, ac);
110 val += ac;
111 gd->bd->bi_dram[i].size = fdtdec_get_number(val, sc);
112 val += sc;
113
114 debug("DRAM bank %d: start = %08lx, size = %08lx\n",
115 i, (unsigned long)gd->bd->bi_dram[i].start,
116 (unsigned long)gd->bd->bi_dram[i].size);
117 }
Simon Glass76b00ac2017-03-31 08:40:32 -0600118
119 return 0;
Stefan Roese21b29fc2016-05-25 08:13:45 +0200120}
121
122int arch_cpu_init(void)
123{
124 /* Nothing to do (yet) */
125 return 0;
126}
127
128int arch_early_init_r(void)
129{
130 struct udevice *dev;
131 int ret;
Stefan Roesed7dd3582016-10-25 18:12:40 +0200132 int i;
Stefan Roese21b29fc2016-05-25 08:13:45 +0200133
Stefan Roesed7dd3582016-10-25 18:12:40 +0200134 /*
135 * Loop over all MISC uclass drivers to call the comphy code
136 * and init all CP110 devices enabled in the DT
137 */
138 i = 0;
139 while (1) {
140 /* Call the comphy code via the MISC uclass driver */
141 ret = uclass_get_device(UCLASS_MISC, i++, &dev);
142
143 /* We're done, once no further CP110 device is found */
144 if (ret)
145 break;
Stefan Roese21b29fc2016-05-25 08:13:45 +0200146 }
147
148 /* Cause the SATA device to do its early init */
149 uclass_first_device(UCLASS_AHCI, &dev);
150
Konstantin Porotchkinf4f194e2017-04-05 17:42:33 +0300151#ifdef CONFIG_DM_PCI
152 /* Trigger PCIe devices detection */
153 pci_init();
154#endif
155
Stefan Roese21b29fc2016-05-25 08:13:45 +0200156 return 0;
157}