blob: f2a54116237098006605ba5e009d6f2134a6ebd0 [file] [log] [blame]
Tom Rini10e47792018-05-06 17:58:06 -04001// SPDX-License-Identifier: GPL-2.0
Stephen Warrendad11a92012-09-01 16:27:56 +00002/*
3 * (C) Copyright 2012 Stephen Warren
4 *
5 * See file CREDITS for list of people who contributed to this
6 * project.
Stephen Warrendad11a92012-09-01 16:27:56 +00007 */
8
9#include <common.h>
Simon Glass1d91ba72019-11-14 12:57:37 -070010#include <cpu_func.h>
Simon Glass97589732020-05-10 11:40:02 -060011#include <init.h>
Matthias Brugger51683d12019-11-19 16:01:04 +010012#include <dm/device.h>
13#include <fdt_support.h>
Stephen Warrendad11a92012-09-01 16:27:56 +000014
Marek Szyprowskid79c6882020-05-25 13:39:55 +020015#define BCM2711_RPI4_PCIE_XHCI_MMIO_PHYS 0x600000000UL
16#define BCM2711_RPI4_PCIE_XHCI_MMIO_SIZE 0x800000UL
17
Matthias Brugger82e74702019-11-19 16:01:05 +010018#ifdef CONFIG_ARM64
19#include <asm/armv8/mmu.h>
20
Marek Szyprowskid79c6882020-05-25 13:39:55 +020021#define MEM_MAP_MAX_ENTRIES (4)
22
23static struct mm_region bcm283x_mem_map[MEM_MAP_MAX_ENTRIES] = {
Matthias Brugger82e74702019-11-19 16:01:05 +010024 {
25 .virt = 0x00000000UL,
26 .phys = 0x00000000UL,
27 .size = 0x3f000000UL,
28 .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
29 PTE_BLOCK_INNER_SHARE
30 }, {
31 .virt = 0x3f000000UL,
32 .phys = 0x3f000000UL,
33 .size = 0x01000000UL,
34 .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
35 PTE_BLOCK_NON_SHARE |
36 PTE_BLOCK_PXN | PTE_BLOCK_UXN
37 }, {
38 /* List terminator */
39 0,
40 }
41};
42
Marek Szyprowskid79c6882020-05-25 13:39:55 +020043static struct mm_region bcm2711_mem_map[MEM_MAP_MAX_ENTRIES] = {
Matthias Brugger82e74702019-11-19 16:01:05 +010044 {
45 .virt = 0x00000000UL,
46 .phys = 0x00000000UL,
Marek Szyprowskia6e042e2020-05-25 13:39:54 +020047 .size = 0xfc000000UL,
Matthias Brugger82e74702019-11-19 16:01:05 +010048 .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
49 PTE_BLOCK_INNER_SHARE
50 }, {
Amit Singh Tomara94f80e2020-01-27 01:14:43 +000051 .virt = 0xfc000000UL,
52 .phys = 0xfc000000UL,
53 .size = 0x03800000UL,
Matthias Brugger82e74702019-11-19 16:01:05 +010054 .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
55 PTE_BLOCK_NON_SHARE |
56 PTE_BLOCK_PXN | PTE_BLOCK_UXN
57 }, {
Marek Szyprowskid79c6882020-05-25 13:39:55 +020058 .virt = BCM2711_RPI4_PCIE_XHCI_MMIO_PHYS,
59 .phys = BCM2711_RPI4_PCIE_XHCI_MMIO_PHYS,
60 .size = BCM2711_RPI4_PCIE_XHCI_MMIO_SIZE,
61 .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
62 PTE_BLOCK_NON_SHARE |
63 PTE_BLOCK_PXN | PTE_BLOCK_UXN
64 }, {
Matthias Brugger82e74702019-11-19 16:01:05 +010065 /* List terminator */
66 0,
67 }
68};
69
70struct mm_region *mem_map = bcm283x_mem_map;
71
72/*
73 * I/O address space varies on different chip versions.
74 * We set the base address by inspecting the DTB.
75 */
76static const struct udevice_id board_ids[] = {
77 { .compatible = "brcm,bcm2837", .data = (ulong)&bcm283x_mem_map},
78 { .compatible = "brcm,bcm2838", .data = (ulong)&bcm2711_mem_map},
79 { .compatible = "brcm,bcm2711", .data = (ulong)&bcm2711_mem_map},
80 { },
81};
82
83static void _rpi_update_mem_map(struct mm_region *pd)
84{
85 int i;
86
Marek Szyprowskid79c6882020-05-25 13:39:55 +020087 for (i = 0; i < MEM_MAP_MAX_ENTRIES; i++) {
Matthias Brugger82e74702019-11-19 16:01:05 +010088 mem_map[i].virt = pd[i].virt;
89 mem_map[i].phys = pd[i].phys;
90 mem_map[i].size = pd[i].size;
91 mem_map[i].attrs = pd[i].attrs;
92 }
93}
94
95static void rpi_update_mem_map(void)
96{
97 int ret;
98 struct mm_region *mm;
99 const struct udevice_id *of_match = board_ids;
100
101 while (of_match->compatible) {
102 ret = fdt_node_check_compatible(gd->fdt_blob, 0,
103 of_match->compatible);
104 if (!ret) {
105 mm = (struct mm_region *)of_match->data;
106 _rpi_update_mem_map(mm);
107 break;
108 }
109
110 of_match++;
111 }
112}
113#else
114static void rpi_update_mem_map(void) {}
115#endif
116
Matthias Brugger51683d12019-11-19 16:01:04 +0100117unsigned long rpi_bcm283x_base = 0x3f000000;
Matthias Brugger2c68dee2019-11-19 16:01:03 +0100118
Stephen Warrendad11a92012-09-01 16:27:56 +0000119int arch_cpu_init(void)
120{
121 icache_enable();
122
123 return 0;
124}
Alexander Graf169892f2016-03-16 15:41:23 +0100125
Matthias Brugger2c68dee2019-11-19 16:01:03 +0100126int mach_cpu_init(void)
127{
Matthias Brugger51683d12019-11-19 16:01:04 +0100128 int ret, soc_offset;
129 u64 io_base, size;
130
Matthias Brugger82e74702019-11-19 16:01:05 +0100131 rpi_update_mem_map();
132
Matthias Brugger51683d12019-11-19 16:01:04 +0100133 /* Get IO base from device tree */
134 soc_offset = fdt_path_offset(gd->fdt_blob, "/soc");
135 if (soc_offset < 0)
136 return soc_offset;
137
138 ret = fdt_read_range((void *)gd->fdt_blob, soc_offset, 0, NULL,
139 &io_base, &size);
140 if (ret)
141 return ret;
142
143 rpi_bcm283x_base = io_base;
Matthias Brugger2c68dee2019-11-19 16:01:03 +0100144
145 return 0;
146}
Matthias Brugger51683d12019-11-19 16:01:04 +0100147
Alexander Graf169892f2016-03-16 15:41:23 +0100148#ifdef CONFIG_ARMV7_LPAE
Marek Szyprowskiab9d99a2020-06-03 14:43:44 +0200149#ifdef CONFIG_TARGET_RPI_4_32B
150#define BCM2711_RPI4_PCIE_XHCI_MMIO_VIRT 0xff800000UL
151#include <addr_map.h>
152#include <asm/system.h>
153
154void init_addr_map(void)
155{
156 mmu_set_region_dcache_behaviour_phys(BCM2711_RPI4_PCIE_XHCI_MMIO_VIRT,
157 BCM2711_RPI4_PCIE_XHCI_MMIO_PHYS,
158 BCM2711_RPI4_PCIE_XHCI_MMIO_SIZE,
159 DCACHE_OFF);
160
161 /* identity mapping for 0..BCM2711_RPI4_PCIE_XHCI_MMIO_VIRT */
162 addrmap_set_entry(0, 0, BCM2711_RPI4_PCIE_XHCI_MMIO_VIRT, 0);
163 /* XHCI MMIO on PCIe at BCM2711_RPI4_PCIE_XHCI_MMIO_VIRT */
164 addrmap_set_entry(BCM2711_RPI4_PCIE_XHCI_MMIO_VIRT,
165 BCM2711_RPI4_PCIE_XHCI_MMIO_PHYS,
166 BCM2711_RPI4_PCIE_XHCI_MMIO_SIZE, 1);
167}
168#endif
169
Alexander Graf169892f2016-03-16 15:41:23 +0100170void enable_caches(void)
171{
172 dcache_enable();
173}
174#endif