• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * (C) Copyright 2012 Stephen Warren
4  *
5  * See file CREDITS for list of people who contributed to this
6  * project.
7  */
8 
9 #include <common.h>
10 #include <cpu_func.h>
11 #include <dm/device.h>
12 #include <fdt_support.h>
13 
14 #ifdef CONFIG_ARM64
15 #include <asm/armv8/mmu.h>
16 
17 static struct mm_region bcm283x_mem_map[] = {
18 	{
19 		.virt = 0x00000000UL,
20 		.phys = 0x00000000UL,
21 		.size = 0x3f000000UL,
22 		.attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
23 			 PTE_BLOCK_INNER_SHARE
24 	}, {
25 		.virt = 0x3f000000UL,
26 		.phys = 0x3f000000UL,
27 		.size = 0x01000000UL,
28 		.attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
29 			 PTE_BLOCK_NON_SHARE |
30 			 PTE_BLOCK_PXN | PTE_BLOCK_UXN
31 	}, {
32 		/* List terminator */
33 		0,
34 	}
35 };
36 
37 static struct mm_region bcm2711_mem_map[] = {
38 	{
39 		.virt = 0x00000000UL,
40 		.phys = 0x00000000UL,
41 		.size = 0xfe000000UL,
42 		.attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
43 			 PTE_BLOCK_INNER_SHARE
44 	}, {
45 		.virt = 0xfe000000UL,
46 		.phys = 0xfe000000UL,
47 		.size = 0x01800000UL,
48 		.attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
49 			 PTE_BLOCK_NON_SHARE |
50 			 PTE_BLOCK_PXN | PTE_BLOCK_UXN
51 	}, {
52 		/* List terminator */
53 		0,
54 	}
55 };
56 
57 struct mm_region *mem_map = bcm283x_mem_map;
58 
59 /*
60  * I/O address space varies on different chip versions.
61  * We set the base address by inspecting the DTB.
62  */
63 static const struct udevice_id board_ids[] = {
64 	{ .compatible = "brcm,bcm2837", .data = (ulong)&bcm283x_mem_map},
65 	{ .compatible = "brcm,bcm2838", .data = (ulong)&bcm2711_mem_map},
66 	{ .compatible = "brcm,bcm2711", .data = (ulong)&bcm2711_mem_map},
67 	{ },
68 };
69 
_rpi_update_mem_map(struct mm_region * pd)70 static void _rpi_update_mem_map(struct mm_region *pd)
71 {
72 	int i;
73 
74 	for (i = 0; i < 2; i++) {
75 		mem_map[i].virt = pd[i].virt;
76 		mem_map[i].phys = pd[i].phys;
77 		mem_map[i].size = pd[i].size;
78 		mem_map[i].attrs = pd[i].attrs;
79 	}
80 }
81 
rpi_update_mem_map(void)82 static void rpi_update_mem_map(void)
83 {
84 	int ret;
85 	struct mm_region *mm;
86 	const struct udevice_id *of_match = board_ids;
87 
88 	while (of_match->compatible) {
89 		ret = fdt_node_check_compatible(gd->fdt_blob, 0,
90 						of_match->compatible);
91 		if (!ret) {
92 			mm = (struct mm_region *)of_match->data;
93 			_rpi_update_mem_map(mm);
94 			break;
95 		}
96 
97 		of_match++;
98 	}
99 }
100 #else
rpi_update_mem_map(void)101 static void rpi_update_mem_map(void) {}
102 #endif
103 
104 unsigned long rpi_bcm283x_base = 0x3f000000;
105 
arch_cpu_init(void)106 int arch_cpu_init(void)
107 {
108 	icache_enable();
109 
110 	return 0;
111 }
112 
mach_cpu_init(void)113 int mach_cpu_init(void)
114 {
115 	int ret, soc_offset;
116 	u64 io_base, size;
117 
118 	rpi_update_mem_map();
119 
120 	/* Get IO base from device tree */
121 	soc_offset = fdt_path_offset(gd->fdt_blob, "/soc");
122 	if (soc_offset < 0)
123 		return soc_offset;
124 
125 	ret = fdt_read_range((void *)gd->fdt_blob, soc_offset, 0, NULL,
126 				&io_base, &size);
127 	if (ret)
128 		return ret;
129 
130 	rpi_bcm283x_base = io_base;
131 
132 	return 0;
133 }
134 
135 #ifdef CONFIG_ARMV7_LPAE
enable_caches(void)136 void enable_caches(void)
137 {
138 	dcache_enable();
139 }
140 #endif
141