blob: f56beb896414b2c074ea82c362b85c3e8a9bb94b [file] [log] [blame]
Aaron Williams0dc4ab92020-06-30 12:08:56 +02001// SPDX-License-Identifier: GPL-2.0+
2/*
3 * Copyright (C) 2020 Marvell International Ltd.
4 */
5
Stefan Roese480fa832021-04-07 09:12:32 +02006#include <dm.h>
7#include <dm/uclass.h>
8#include <env.h>
9#include <iomux.h>
Aaron Williams0dc4ab92020-06-30 12:08:56 +020010#include <asm/global_data.h>
11#include <linux/bitfield.h>
12#include <linux/bitops.h>
13#include <linux/compat.h>
14#include <linux/io.h>
15#include <mach/clock.h>
16#include <mach/cavm-reg.h>
Stefan Roese480fa832021-04-07 09:12:32 +020017#include <mach/cvmx-bootmem.h>
Stefan Roese60941452021-04-07 09:12:33 +020018#include <mach/cvmx-regs.h>
19#include <mach/cvmx-sata-defs.h>
Aaron Williams0dc4ab92020-06-30 12:08:56 +020020
21DECLARE_GLOBAL_DATA_PTR;
22
Stefan Roesefd569c82020-08-24 13:04:39 +020023/*
Stefan Roese480fa832021-04-07 09:12:32 +020024 * Important:
25 * This address cannot be changed as the PCI console tool relies on exactly
26 * this value!
27 */
28#define BOOTLOADER_BOOTMEM_DESC_ADDR 0x6c100
29#define BOOTLOADER_BOOTMEM_DESC_SPACE (BOOTLOADER_BOOTMEM_DESC_ADDR + 0x8)
30
31#define OCTEON_RESERVED_LOW_BOOT_MEM_SIZE (1024 * 1024)
32
33#define BOOTCMD_NAME "pci-bootcmd"
34#define CONSOLE_NAME "pci-console@0"
35#define OCTEON_BOOTLOADER_LOAD_MEM_NAME "__tmp_load"
36
37/*
Stefan Roesefd569c82020-08-24 13:04:39 +020038 * TRUE for devices having registers with little-endian byte
39 * order, FALSE for registers with native-endian byte order.
40 * PCI mandates little-endian, USB and SATA are configurable,
41 * but we chose little-endian for these.
42 *
43 * This table will be referened in the Octeon platform specific
44 * mangle-port.h header.
45 */
46const bool octeon_should_swizzle_table[256] = {
47 [0x00] = true, /* bootbus/CF */
48 [0x1b] = true, /* PCI mmio window */
49 [0x1c] = true, /* PCI mmio window */
50 [0x1d] = true, /* PCI mmio window */
51 [0x1e] = true, /* PCI mmio window */
52 [0x68] = true, /* OCTEON III USB */
53 [0x69] = true, /* OCTEON III USB */
Stefan Roesefd569c82020-08-24 13:04:39 +020054 [0x6f] = true, /* OCTEON II USB */
55};
56
Aaron Williams0dc4ab92020-06-30 12:08:56 +020057static int get_clocks(void)
58{
59 const u64 ref_clock = PLL_REF_CLK;
60 void __iomem *rst_boot;
61 u64 val;
62
63 rst_boot = ioremap(CAVM_RST_BOOT, 0);
64 val = ioread64(rst_boot);
65 gd->cpu_clk = ref_clock * FIELD_GET(RST_BOOT_C_MUL, val);
66 gd->bus_clk = ref_clock * FIELD_GET(RST_BOOT_PNR_MUL, val);
67
68 debug("%s: cpu: %lu, bus: %lu\n", __func__, gd->cpu_clk, gd->bus_clk);
69
70 return 0;
71}
72
73/* Early mach init code run from flash */
74int mach_cpu_init(void)
75{
76 void __iomem *mio_boot_reg_cfg0;
77
78 /* Remap boot-bus 0x1fc0.0000 -> 0x1f40.0000 */
79 /* ToDo: Move this to an early running bus (bootbus) DM driver */
80 mio_boot_reg_cfg0 = ioremap(CAVM_MIO_BOOT_REG_CFG0, 0);
81 clrsetbits_be64(mio_boot_reg_cfg0, 0xffff, 0x1f40);
82
83 /* Get clocks and store them in GD */
84 get_clocks();
85
86 return 0;
87}
88
89/**
90 * Returns number of cores
91 *
92 * @return number of CPU cores for the specified node
93 */
94static int cavm_octeon_num_cores(void)
95{
96 void __iomem *ciu_fuse;
97
98 ciu_fuse = ioremap(CAVM_CIU_FUSE, 0);
99 return fls64(ioread64(ciu_fuse) & 0xffffffffffff);
100}
101
102int print_cpuinfo(void)
103{
104 printf("SoC: Octeon CN73xx (%d cores)\n", cavm_octeon_num_cores());
105
106 return 0;
107}
Stefan Roese480fa832021-04-07 09:12:32 +0200108
109static int octeon_bootmem_init(void)
110{
111 int ret;
112
113 /* Call old single-node func: it uses only gd->ram_size */
114 ret = cvmx_bootmem_phy_mem_list_init(gd->ram_size,
115 OCTEON_RESERVED_LOW_BOOT_MEM_SIZE,
116 (void *)CKSEG0ADDR(BOOTLOADER_BOOTMEM_DESC_SPACE));
117 if (!ret) {
118 printf("FATAL: Error initializing bootmem list\n");
119 return -ENOSPC;
120 }
121
122 /*
123 * Put bootmem descriptor address in known location for host.
124 * Make sure it is not in kseg0, as we want physical address
125 */
126 writeq((u64)__cvmx_bootmem_internal_get_desc_ptr() & 0x7fffffffull,
127 (void *)CKSEG0ADDR(BOOTLOADER_BOOTMEM_DESC_ADDR));
128
129 debug("Reserving first 1MB of memory\n");
130 ret = cvmx_bootmem_reserve_memory(0, OCTEON_RESERVED_LOW_BOOT_MEM_SIZE,
131 "__low_reserved", 0);
132 if (!ret)
133 puts("Error reserving low 1MB of memory\n");
134
135#ifdef DEBUG
136 cvmx_bootmem_phy_list_print();
137#endif
138
139 return 0;
140}
141
142static int octeon_configure_load_memory(void)
143{
144 char *eptr;
145 u32 addr;
146 u32 size;
147 int ret;
148
149 eptr = env_get("octeon_reserved_mem_load_size");
150 if (!eptr || !strcmp("auto", eptr)) {
151 /*
152 * Pick a size that we think is appropriate.
153 * Please note that for small memory boards this guess
154 * will likely not be ideal.
155 * Please pick a specific size for boards/applications
156 * that require it.
157 */
158 if (gd->ram_size <= (256 << 20)) {
159 size = min_t(u64, (128 << 20),
160 ((gd->ram_size * 2) / 5) & ~0xFFFFF);
161 } else {
162 size = min_t(u64, (256 << 20),
163 ((gd->ram_size - (256 << 20)) / 3) & ~0xFFFFF);
164 }
165 } else {
166 size = simple_strtol(eptr, NULL, 16);
167 debug("octeon_reserved_mem_load_size=0x%08x\n", size);
168 }
169
170 if (size) {
171 debug("Linux reserved load size 0x%08x\n", size);
172 eptr = env_get("octeon_reserved_mem_load_base");
173 if (!eptr || !strcmp("auto", eptr)) {
174 u64 mem_top;
175 /*
176 * Leave some room for previous allocations that
177 * are made starting at the top of the low
178 * 256 Mbytes of DRAM
179 */
180 int adjust = (1 << 20);
181
182 if (gd->ram_size <= (512 << 20))
183 adjust = (17 << 20);
184
185 /* Put block at the top of DDR0, or bottom of DDR2 */
186 if ((gd->ram_size <= (256 << 20)) ||
187 (size > (gd->ram_size - (256 << 20)))) {
188 mem_top = min_t(u64, gd->ram_size - adjust,
189 (256 << 20) - adjust);
190 } else if ((gd->ram_size <= (512 << 20)) ||
191 (size > (gd->ram_size - (512 << 20)))) {
192 mem_top = min_t(u64, gd->ram_size - adjust,
193 (512 << 20) - adjust);
194 } else {
195 /*
196 * We have enough room, so set
197 * mem_top so that the block is
198 * at the base of the DDR2
199 * segment
200 */
201 mem_top = (512 << 20) + size;
202 }
203
204 /*
205 * Adjust for boot bus memory hole on OCTEON II
206 * and later.
207 */
208 if ((gd->ram_size > (256 << 20)))
209 mem_top += (256 << 20);
210
211 debug("Adjusted memory top is 0x%llx\n", mem_top);
212 addr = mem_top - size;
213 if (addr > (512 << 20))
214 addr = (512 << 20);
215 if ((addr >= (256 << 20)) && addr < (512 << 20)) {
216 /*
217 * The address landed in the boot-bus
218 * memory hole. Dig it out of the hole.
219 */
220 addr = (512 << 20);
221 }
222 } else {
223 addr = simple_strtol(eptr, NULL, 16);
224 }
225
226 ret = cvmx_bootmem_phy_named_block_alloc(size, addr,
227 addr + size, 0,
228 OCTEON_BOOTLOADER_LOAD_MEM_NAME,
229 0);
230 if (ret < 0) {
231 printf("ERROR: Unable to allocate bootloader reserved memory (addr: 0x%x, size: 0x%x).\n",
232 addr, size);
233 } else {
234 /*
235 * Set default load address to base of memory
236 * reserved for loading. The setting of the
237 * env. variable also sets the load_addr global
238 * variable.
239 * This environment variable is overridden each
240 * boot if a reserved block is created.
241 */
242 char str[20];
243
244 snprintf(str, sizeof(str), "0x%x", addr);
245 env_set("loadaddr", str);
246 debug("Setting load address to 0x%08x, size 0x%x\n",
247 addr, size);
248 }
249 return 0;
250 }
251
252 printf("WARNING: No reserved memory for image loading.\n");
253 return -1;
254}
255
256static int init_pcie_console(void)
257{
258 char *stdinname = env_get("stdin");
259 char *stdoutname = env_get("stdout");
260 char *stderrname = env_get("stderr");
261 struct udevice *pcie_console_dev = NULL;
262 bool stdin_set, stdout_set, stderr_set;
263 char iomux_name[128];
264 int ret = 0;
265
266 debug("%s: stdin: %s, stdout: %s, stderr: %s\n", __func__, stdinname,
267 stdoutname, stderrname);
268 if (!stdinname) {
269 env_set("stdin", "serial");
270 stdinname = env_get("stdin");
271 }
272 if (!stdoutname) {
273 env_set("stdout", "serial");
274 stdoutname = env_get("stdout");
275 }
276 if (!stderrname) {
277 env_set("stderr", "serial");
278 stderrname = env_get("stderr");
279 }
280
281 if (!stdinname || !stdoutname || !stderrname) {
282 printf("%s: Error setting environment variables for serial\n",
283 __func__);
284 return -1;
285 }
286
287 stdin_set = !!strstr(stdinname, CONSOLE_NAME);
288 stdout_set = !!strstr(stdoutname, CONSOLE_NAME);
289 stderr_set = !!strstr(stderrname, CONSOLE_NAME);
290
291 log_debug("stdin: %d, \"%s\", stdout: %d, \"%s\", stderr: %d, \"%s\"\n",
292 stdin_set, stdinname, stdout_set, stdoutname,
293 stderr_set, stderrname);
294 ret = uclass_get_device_by_name(UCLASS_SERIAL, CONSOLE_NAME,
295 &pcie_console_dev);
296 if (ret || !pcie_console_dev) {
297 debug("%s: No PCI console device %s found\n", __func__,
298 CONSOLE_NAME);
299 return 0;
300 }
301
302 if (stdin_set)
303 strncpy(iomux_name, stdinname, sizeof(iomux_name));
304 else
305 snprintf(iomux_name, sizeof(iomux_name), "%s,%s",
306 stdinname, pcie_console_dev->name);
307
308 ret = iomux_doenv(stdin, iomux_name);
309 if (ret) {
310 log_err("%s: Error setting I/O stdin MUX to %s\n",
311 __func__, iomux_name);
312 return ret;
313 }
314
315 if (!stdin_set)
316 env_set("stdin", iomux_name);
317
318 if (stdout_set)
319 strncpy(iomux_name, stdoutname, sizeof(iomux_name));
320 else
321 snprintf(iomux_name, sizeof(iomux_name), "%s,%s", stdoutname,
322 pcie_console_dev->name);
323
324 ret = iomux_doenv(stdout, iomux_name);
325 if (ret) {
326 log_err("%s: Error setting I/O stdout MUX to %s\n",
327 __func__, iomux_name);
328 return ret;
329 }
330 if (!stdout_set)
331 env_set("stdout", iomux_name);
332
333 if (stderr_set)
334 strncpy(iomux_name, stderrname, sizeof(iomux_name));
335 else
336 snprintf(iomux_name, sizeof(iomux_name), "%s,%s", stderrname,
337 pcie_console_dev->name);
338
339 ret = iomux_doenv(stderr, iomux_name);
340 if (ret) {
341 log_err("%s: Error setting I/O stderr MUX to %s\n",
342 __func__, iomux_name);
343 return ret;
344 }
345
346 if (!stderr_set)
347 env_set("stderr", iomux_name);
348
349 debug("%s: stdin: %s, stdout: %s, stderr: %s, ret: %d\n",
350 __func__, env_get("stdin"), env_get("stdout"),
351 env_get("stderr"), ret);
352
353 return ret;
354}
355
356static int init_bootcmd_console(void)
357{
358 char *stdinname = env_get("stdin");
359 struct udevice *bootcmd_dev = NULL;
360 bool stdin_set;
361 char iomux_name[128];
362 int ret = 0;
363
364 debug("%s: stdin before: %s\n", __func__,
365 stdinname ? stdinname : "NONE");
366 if (!stdinname) {
367 env_set("stdin", "serial");
368 stdinname = env_get("stdin");
369 }
370 stdin_set = !!strstr(stdinname, BOOTCMD_NAME);
371 ret = uclass_get_device_by_driver(UCLASS_SERIAL,
372 DM_DRIVER_GET(octeon_bootcmd),
373 &bootcmd_dev);
374 if (ret) {
375 log_err("%s: Error getting %s serial class\n", __func__,
376 BOOTCMD_NAME);
377 } else if (bootcmd_dev) {
378 if (stdin_set)
379 strncpy(iomux_name, stdinname, sizeof(iomux_name));
380 else
381 snprintf(iomux_name, sizeof(iomux_name), "%s,%s",
382 stdinname, bootcmd_dev->name);
383 ret = iomux_doenv(stdin, iomux_name);
384 if (ret)
385 log_err("%s: Error %d enabling the PCI bootcmd input console \"%s\"\n",
386 __func__, ret, iomux_name);
387 if (!stdin_set)
388 env_set("stdin", iomux_name);
389 }
390
391 debug("%s: Set iomux and stdin to %s (ret: %d)\n",
392 __func__, iomux_name, ret);
393 return ret;
394}
395
396int arch_misc_init(void)
397{
398 int ret;
399
400 ret = octeon_bootmem_init();
401 if (ret)
402 return ret;
403
404 ret = octeon_configure_load_memory();
405 if (ret)
406 return ret;
407
408 if (CONFIG_IS_ENABLED(OCTEON_SERIAL_PCIE_CONSOLE))
409 init_pcie_console();
410
411 if (CONFIG_IS_ENABLED(OCTEON_SERIAL_BOOTCMD))
412 init_bootcmd_console();
413
414 return 0;
415}
Stefan Roese60941452021-04-07 09:12:33 +0200416
417int board_ahci_enable(void)
418{
419 cvmx_sata_uctl_shim_cfg_t shim_cfg;
420
421 /*
422 * Configure proper endian swapping for the AHCI port so that the
423 * common AHCI code can be used
424 */
425 shim_cfg.u64 = csr_rd(CVMX_SATA_UCTL_SHIM_CFG);
426 shim_cfg.s.dma_endian_mode = 1;
427 /* Use 1 for LE mode when running BE, or 3 for BE mode running BE */
428 shim_cfg.s.csr_endian_mode = 3; /* Don't byte swap */
429 shim_cfg.s.dma_read_cmd = 1; /* No allocate L2C */
430 csr_wr(CVMX_SATA_UCTL_SHIM_CFG, shim_cfg.u64);
431
432 return 0;
433}