blob: 0bfbc473ec1d6693bca7b56cc346acf7a153d8c0 [file] [log] [blame]
Mark Kettenis003b6572021-10-23 16:58:03 +02001// SPDX-License-Identifier: GPL-2.0+
2/*
3 * (C) Copyright 2021 Mark Kettenis <kettenis@openbsd.org>
4 */
5
6#include <common.h>
7#include <dm.h>
8#include <efi_loader.h>
9
10#include <asm/armv8/mmu.h>
11#include <asm/global_data.h>
12#include <asm/io.h>
13#include <asm/system.h>
14
15DECLARE_GLOBAL_DATA_PTR;
16
17static struct mm_region apple_mem_map[] = {
18 {
19 /* I/O */
20 .virt = 0x200000000,
21 .phys = 0x200000000,
22 .size = 8UL * SZ_1G,
23 .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
24 PTE_BLOCK_NON_SHARE |
25 PTE_BLOCK_PXN | PTE_BLOCK_UXN
26 }, {
27 /* I/O */
28 .virt = 0x500000000,
29 .phys = 0x500000000,
30 .size = 2UL * SZ_1G,
31 .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
32 PTE_BLOCK_NON_SHARE |
33 PTE_BLOCK_PXN | PTE_BLOCK_UXN
34 }, {
35 /* I/O */
36 .virt = 0x680000000,
37 .phys = 0x680000000,
38 .size = SZ_512M,
39 .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
40 PTE_BLOCK_NON_SHARE |
41 PTE_BLOCK_PXN | PTE_BLOCK_UXN
42 }, {
43 /* PCIE */
44 .virt = 0x6a0000000,
45 .phys = 0x6a0000000,
46 .size = SZ_512M,
47 .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRE) |
48 PTE_BLOCK_INNER_SHARE |
49 PTE_BLOCK_PXN | PTE_BLOCK_UXN
50 }, {
51 /* PCIE */
52 .virt = 0x6c0000000,
53 .phys = 0x6c0000000,
54 .size = SZ_1G,
55 .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRE) |
56 PTE_BLOCK_INNER_SHARE |
57 PTE_BLOCK_PXN | PTE_BLOCK_UXN
58 }, {
59 /* RAM */
60 .virt = 0x800000000,
61 .phys = 0x800000000,
62 .size = 8UL * SZ_1G,
63 .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
64 PTE_BLOCK_INNER_SHARE
65 }, {
66 /* Empty entry for framebuffer */
67 0,
68 }, {
69 /* List terminator */
70 0,
71 }
72};
73
74struct mm_region *mem_map = apple_mem_map;
75
76int board_init(void)
77{
78 return 0;
79}
80
81int dram_init(void)
82{
83 ofnode node;
84 int index, ret;
85 fdt_addr_t base;
86 fdt_size_t size;
87
88 ret = fdtdec_setup_mem_size_base();
89 if (ret)
90 return ret;
91
92 /* Update RAM mapping */
93 index = ARRAY_SIZE(apple_mem_map) - 3;
94 apple_mem_map[index].virt = gd->ram_base;
95 apple_mem_map[index].phys = gd->ram_base;
96 apple_mem_map[index].size = gd->ram_size;
97
98 node = ofnode_path("/chosen/framebuffer");
99 if (!ofnode_valid(node))
100 return 0;
101
102 base = ofnode_get_addr_size(node, "reg", &size);
103 if (base == FDT_ADDR_T_NONE)
104 return 0;
105
106 /* Add framebuffer mapping */
107 index = ARRAY_SIZE(apple_mem_map) - 2;
108 apple_mem_map[index].virt = base;
109 apple_mem_map[index].phys = base;
110 apple_mem_map[index].size = size;
111 apple_mem_map[index].attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL_NC) |
112 PTE_BLOCK_INNER_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN;
113
114 return 0;
115}
116
117int dram_init_banksize(void)
118{
119 return fdtdec_setup_memory_banksize();
120}
121
122#define APPLE_WDT_BASE 0x23d2b0000ULL
123
124#define APPLE_WDT_SYS_CTL_ENABLE BIT(2)
125
126typedef struct apple_wdt {
127 u32 reserved0[3];
128 u32 chip_ctl;
129 u32 sys_tmr;
130 u32 sys_cmp;
131 u32 reserved1;
132 u32 sys_ctl;
133} apple_wdt_t;
134
135void reset_cpu(void)
136{
137 apple_wdt_t *wdt = (apple_wdt_t *)APPLE_WDT_BASE;
138
139 writel(0, &wdt->sys_cmp);
140 writel(APPLE_WDT_SYS_CTL_ENABLE, &wdt->sys_ctl);
141
142 while(1)
143 wfi();
144}
145
146extern long fw_dtb_pointer;
147
148void *board_fdt_blob_setup(int *err)
149{
150 /* Return DTB pointer passed by m1n1 */
151 *err = 0;
152 return (void *)fw_dtb_pointer;
153}
154
155ulong board_get_usable_ram_top(ulong total_size)
156{
157 /*
158 * Top part of RAM is used by firmware for things like the
159 * framebuffer. This gives us plenty of room to play with.
160 */
161 return 0x980000000;
162}