1 // SPDX-License-Identifier: GPL-2.0+
3 * Copyright (C) 2016 Stefan Roese <sr@denx.de>
4 * Copyright (C) 2020 Marek BehĂșn <kabel@kernel.org>
11 #include <fdt_support.h>
13 #include <asm/global_data.h>
14 #include <linux/bitops.h>
15 #include <linux/libfdt.h>
16 #include <linux/sizes.h>
18 #include <asm/system.h>
19 #include <asm/arch/cpu.h>
20 #include <asm/arch/soc.h>
21 #include <asm/armv8/mmu.h>
25 #define MVEBU_GPIO_NB_REG_BASE (MVEBU_REGISTER(0x13800))
27 #define MVEBU_TEST_PIN_LATCH_N (MVEBU_GPIO_NB_REG_BASE + 0x8)
28 #define MVEBU_XTAL_MODE_MASK BIT(9)
29 #define MVEBU_XTAL_MODE_OFFS 9
30 #define MVEBU_XTAL_CLOCK_25MHZ 0x0
31 #define MVEBU_XTAL_CLOCK_40MHZ 0x1
33 #define MVEBU_NB_WARM_RST_REG (MVEBU_GPIO_NB_REG_BASE + 0x40)
34 #define MVEBU_NB_WARM_RST_MAGIC_NUM 0x1d1e
36 /* Armada 3700 CPU Address Decoder registers */
37 #define MVEBU_CPU_DEC_WIN_REG_BASE (size_t)(MVEBU_REGISTER(0xcf00))
38 #define MVEBU_CPU_DEC_WIN_CTRL(w) \
39 (MVEBU_CPU_DEC_WIN_REG_BASE + ((w) << 4))
40 #define MVEBU_CPU_DEC_WIN_CTRL_EN BIT(0)
41 #define MVEBU_CPU_DEC_WIN_CTRL_TGT_MASK 0xf
42 #define MVEBU_CPU_DEC_WIN_CTRL_TGT_OFFS 4
43 #define MVEBU_CPU_DEC_WIN_CTRL_TGT_DRAM 0
44 #define MVEBU_CPU_DEC_WIN_CTRL_TGT_PCIE 2
45 #define MVEBU_CPU_DEC_WIN_SIZE(w) (MVEBU_CPU_DEC_WIN_CTRL(w) + 0x4)
46 #define MVEBU_CPU_DEC_WIN_BASE(w) (MVEBU_CPU_DEC_WIN_CTRL(w) + 0x8)
47 #define MVEBU_CPU_DEC_WIN_REMAP(w) (MVEBU_CPU_DEC_WIN_CTRL(w) + 0xc)
48 #define MVEBU_CPU_DEC_WIN_GRANULARITY 16
49 #define MVEBU_CPU_DEC_WINS 5
50 #define MVEBU_CPU_DEC_CCI_BASE (MVEBU_CPU_DEC_WIN_REG_BASE + 0xe0)
51 #define MVEBU_CPU_DEC_ROM_BASE (MVEBU_CPU_DEC_WIN_REG_BASE + 0xf4)
53 #define MAX_MEM_MAP_REGIONS (MVEBU_CPU_DEC_WINS + 4)
55 #define A3700_PTE_BLOCK_NORMAL \
56 (PTE_BLOCK_MEMTYPE(MT_NORMAL) | PTE_BLOCK_INNER_SHARE)
57 #define A3700_PTE_BLOCK_DEVICE \
58 (PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | PTE_BLOCK_NON_SHARE)
60 DECLARE_GLOBAL_DATA_PTR
;
62 static struct mm_region mvebu_mem_map
[MAX_MEM_MAP_REGIONS
] = {
66 * Don't remove this, build_mem_map needs it.
68 .phys
= SOC_REGS_PHY_BASE
,
69 .virt
= SOC_REGS_PHY_BASE
,
70 .size
= 0x02000000UL
, /* 32MiB internal registers */
71 .attrs
= A3700_PTE_BLOCK_DEVICE
75 struct mm_region
*mem_map
= mvebu_mem_map
;
77 static int get_cpu_dec_win(int win
, u32
*tgt
, u32
*base
, u32
*size
)
81 reg
= readl(MVEBU_CPU_DEC_WIN_CTRL(win
));
82 if (!(reg
& MVEBU_CPU_DEC_WIN_CTRL_EN
))
86 reg
>>= MVEBU_CPU_DEC_WIN_CTRL_TGT_OFFS
;
87 reg
&= MVEBU_CPU_DEC_WIN_CTRL_TGT_MASK
;
92 reg
= readl(MVEBU_CPU_DEC_WIN_BASE(win
));
93 *base
= reg
<< MVEBU_CPU_DEC_WIN_GRANULARITY
;
98 * Window size is encoded as the number of 1s from LSB to MSB,
99 * followed by 0s. The number of 1s specifies the size in 64 KiB
102 reg
= readl(MVEBU_CPU_DEC_WIN_SIZE(win
));
103 *size
= ((reg
+ 1) << MVEBU_CPU_DEC_WIN_GRANULARITY
);
110 * Builds mem_map according to CPU Address Decoder settings, which were set by
111 * the TIMH image on the Cortex-M3 secure processor, or by ARM Trusted Firmware
113 static void build_mem_map(void)
121 reg
= readl(MVEBU_CPU_DEC_CCI_BASE
);
122 mvebu_mem_map
[region
].phys
= reg
<< 20;
123 mvebu_mem_map
[region
].virt
= reg
<< 20;
124 mvebu_mem_map
[region
].size
= SZ_64K
;
125 mvebu_mem_map
[region
].attrs
= A3700_PTE_BLOCK_DEVICE
;
129 reg
= readl(MVEBU_CPU_DEC_ROM_BASE
);
130 mvebu_mem_map
[region
].phys
= reg
<< 20;
131 mvebu_mem_map
[region
].virt
= reg
<< 20;
132 mvebu_mem_map
[region
].size
= SZ_1M
;
133 mvebu_mem_map
[region
].attrs
= A3700_PTE_BLOCK_NORMAL
;
136 for (win
= 0; win
< MVEBU_CPU_DEC_WINS
; ++win
) {
140 /* skip disabled windows */
141 if (get_cpu_dec_win(win
, &tgt
, &base
, &size
))
144 if (tgt
== MVEBU_CPU_DEC_WIN_CTRL_TGT_DRAM
)
145 attrs
= A3700_PTE_BLOCK_NORMAL
;
146 else if (tgt
== MVEBU_CPU_DEC_WIN_CTRL_TGT_PCIE
)
147 attrs
= A3700_PTE_BLOCK_DEVICE
;
149 /* skip windows with other targets */
152 mvebu_mem_map
[region
].phys
= base
;
153 mvebu_mem_map
[region
].virt
= base
;
154 mvebu_mem_map
[region
].size
= size
;
155 mvebu_mem_map
[region
].attrs
= attrs
;
159 /* add list terminator */
160 mvebu_mem_map
[region
].size
= 0;
161 mvebu_mem_map
[region
].attrs
= 0;
164 void enable_caches(void)
170 int a3700_dram_init(void)
177 for (win
= 0; win
< MVEBU_CPU_DEC_WINS
; ++win
) {
180 /* skip disabled windows */
181 if (get_cpu_dec_win(win
, &tgt
, &base
, &size
))
184 /* skip non-DRAM windows */
185 if (tgt
!= MVEBU_CPU_DEC_WIN_CTRL_TGT_DRAM
)
189 * It is possible that one image was built for boards with
190 * different RAM sizes, for example 512 MiB and 1 GiB.
191 * We therefore try to determine the actual RAM size in the
192 * window with get_ram_size.
194 gd
->ram_size
+= get_ram_size((void *)(size_t)base
, size
);
200 struct a3700_dram_window
{
204 static int dram_win_cmp(const void *a
, const void *b
)
208 ab
= ((const struct a3700_dram_window
*)a
)->base
;
209 bb
= ((const struct a3700_dram_window
*)b
)->base
;
219 int a3700_dram_init_banksize(void)
221 struct a3700_dram_window dram_wins
[MVEBU_CPU_DEC_WINS
];
222 int bank
, win
, ndram_wins
;
227 for (win
= 0; win
< MVEBU_CPU_DEC_WINS
; ++win
) {
230 /* skip disabled windows */
231 if (get_cpu_dec_win(win
, &tgt
, &base
, &size
))
234 /* skip non-DRAM windows */
235 if (tgt
!= MVEBU_CPU_DEC_WIN_CTRL_TGT_DRAM
)
238 dram_wins
[win
].base
= base
;
239 dram_wins
[win
].size
= size
;
243 qsort(dram_wins
, ndram_wins
, sizeof(dram_wins
[0]), dram_win_cmp
);
248 for (win
= 0; win
< ndram_wins
; ++win
) {
249 /* again determining actual RAM size as in a3700_dram_init */
250 size
= get_ram_size((void *)dram_wins
[win
].base
,
251 dram_wins
[win
].size
);
254 * Check if previous window ends as the current starts. If yes,
255 * merge these windows into one "bank". This is possible by this
256 * simple check thanks to mem_map regions being qsorted in
259 if (last_end
== dram_wins
[win
].base
) {
260 gd
->bd
->bi_dram
[bank
- 1].size
+= size
;
263 if (bank
== CONFIG_NR_DRAM_BANKS
) {
264 printf("Need more CONFIG_NR_DRAM_BANKS\n");
268 gd
->bd
->bi_dram
[bank
].start
= dram_wins
[win
].base
;
269 gd
->bd
->bi_dram
[bank
].size
= size
;
270 last_end
= dram_wins
[win
].base
+ size
;
276 * If there is more place for DRAM BANKS definitions than needed, fill
277 * the rest with zeros.
279 for (; bank
< CONFIG_NR_DRAM_BANKS
; ++bank
) {
280 gd
->bd
->bi_dram
[bank
].start
= 0;
281 gd
->bd
->bi_dram
[bank
].size
= 0;
287 static u32
find_pcie_window_base(void)
291 for (win
= 0; win
< MVEBU_CPU_DEC_WINS
; ++win
) {
294 /* skip disabled windows */
295 if (get_cpu_dec_win(win
, &tgt
, &base
, NULL
))
298 if (tgt
== MVEBU_CPU_DEC_WIN_CTRL_TGT_PCIE
)
305 static int fdt_setprop_inplace_u32_partial(void *blob
, int node
,
309 val
= cpu_to_fdt32(val
);
311 return fdt_setprop_inplace_namelen_partial(blob
, node
, name
,
317 int a3700_fdt_fix_pcie_regions(void *blob
)
319 u32 base
, lowest_cpu_addr
, fix_offset
;
320 int pci_cells
, cpu_cells
, size_cells
;
325 base
= find_pcie_window_base();
329 node
= fdt_node_offset_by_compatible(blob
, -1, "marvell,armada-3700-pcie");
333 ranges
= fdt_getprop(blob
, node
, "ranges", &len
);
334 if (!ranges
|| !len
|| len
% sizeof(u32
))
338 * The "ranges" property is an array of
339 * { <PCI address> <CPU address> <size in PCI address space> }
340 * where number of PCI address cells and size cells is stored in the
341 * "#address-cells" and "#size-cells" properties of the same node
342 * containing the "ranges" property and number of CPU address cells
343 * is stored in the parent's "#address-cells" property.
345 * All 3 elements can span a diffent number of cells. Fetch them.
347 pnode
= fdt_parent_offset(blob
, node
);
348 pci_cells
= fdt_address_cells(blob
, node
);
349 cpu_cells
= fdt_address_cells(blob
, pnode
);
350 size_cells
= fdt_size_cells(blob
, node
);
352 /* PCI addresses always use 3 cells */
356 /* CPU addresses on Armada 37xx always use 2 cells */
360 for (i
= 0; i
< len
/ sizeof(u32
);
361 i
+= pci_cells
+ cpu_cells
+ size_cells
) {
363 * Parent CPU addresses on Armada 37xx are always 32-bit, so
364 * check that the high word is zero.
366 if (fdt32_to_cpu(ranges
[i
+ pci_cells
]))
370 fdt32_to_cpu(ranges
[i
+ pci_cells
+ 1]) < lowest_cpu_addr
)
371 lowest_cpu_addr
= fdt32_to_cpu(ranges
[i
+ pci_cells
+ 1]);
374 /* Calculate fixup offset from the lowest (first) CPU address */
375 fix_offset
= base
- lowest_cpu_addr
;
377 /* If fixup offset is zero there is nothing to fix */
382 * Fix each CPU address and corresponding PCI address if PCI address
383 * is not already remapped (has the same value)
385 for (i
= 0; i
< len
/ sizeof(u32
);
386 i
+= pci_cells
+ cpu_cells
+ size_cells
) {
391 /* Fix CPU address */
392 idx
= i
+ pci_cells
+ cpu_cells
- 1;
393 cpu_addr
= fdt32_to_cpu(ranges
[idx
]);
394 ret
= fdt_setprop_inplace_u32_partial(blob
, node
, "ranges", idx
,
395 cpu_addr
+ fix_offset
);
399 /* Fix PCI address only if it isn't remapped (is same as CPU) */
400 idx
= i
+ pci_cells
- 1;
401 pci_addr
= ((u64
)fdt32_to_cpu(ranges
[idx
- 1]) << 32) |
402 fdt32_to_cpu(ranges
[idx
]);
403 if (cpu_addr
!= pci_addr
)
406 ret
= fdt_setprop_inplace_u32_partial(blob
, node
, "ranges", idx
,
407 cpu_addr
+ fix_offset
);
418 * Write magic number of 0x1d1e to North Bridge Warm Reset register
419 * to trigger warm reset
421 writel(MVEBU_NB_WARM_RST_MAGIC_NUM
, MVEBU_NB_WARM_RST_REG
);
427 * return: reference clock in MHz (25 or 40)
429 u32
get_ref_clk(void)
433 regval
= (readl(MVEBU_TEST_PIN_LATCH_N
) & MVEBU_XTAL_MODE_MASK
) >>
434 MVEBU_XTAL_MODE_OFFS
;
436 if (regval
== MVEBU_XTAL_CLOCK_25MHZ
)