]> Git Repo - J-u-boot.git/blob - arch/mips/mach-octeon/cpu.c
mips: octeon: cpu.c: Move bootmem init to arch_early_init_r()
[J-u-boot.git] / arch / mips / mach-octeon / cpu.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Copyright (C) 2020 Marvell International Ltd.
4  */
5
6 #include <dm.h>
7 #include <dm/uclass.h>
8 #include <env.h>
9 #include <iomux.h>
10 #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>
17 #include <mach/cvmx-bootmem.h>
18 #include <mach/cvmx-regs.h>
19 #include <mach/cvmx-sata-defs.h>
20
21 DECLARE_GLOBAL_DATA_PTR;
22
23 /*
24  * 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 /*
38  * 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  */
46 const 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 */
54         [0x6f] = true,  /* OCTEON II USB */
55 };
56
57 static 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 */
74 int 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  */
94 static 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
102 int print_cpuinfo(void)
103 {
104         printf("SoC:   Octeon CN73xx (%d cores)\n", cavm_octeon_num_cores());
105
106         return 0;
107 }
108
109 static 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
142 static 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
256 static 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
356 static 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
396 int arch_early_init_r(void)
397 {
398         int ret;
399
400         /*
401          * Needs to be called pretty early, so that e.g. networking etc
402          * can access the bootmem infrastructure
403          */
404         ret = octeon_bootmem_init();
405         if (ret)
406                 return ret;
407
408         return 0;
409 }
410
411 int arch_misc_init(void)
412 {
413         int ret;
414
415         ret = octeon_configure_load_memory();
416         if (ret)
417                 return ret;
418
419         if (CONFIG_IS_ENABLED(OCTEON_SERIAL_PCIE_CONSOLE))
420                 init_pcie_console();
421
422         if (CONFIG_IS_ENABLED(OCTEON_SERIAL_BOOTCMD))
423                 init_bootcmd_console();
424
425         return 0;
426 }
427
428 int board_ahci_enable(void)
429 {
430         cvmx_sata_uctl_shim_cfg_t shim_cfg;
431
432         /*
433          * Configure proper endian swapping for the AHCI port so that the
434          * common AHCI code can be used
435          */
436         shim_cfg.u64 = csr_rd(CVMX_SATA_UCTL_SHIM_CFG);
437         shim_cfg.s.dma_endian_mode = 1;
438         /* Use 1 for LE mode when running BE, or 3 for BE mode running BE */
439         shim_cfg.s.csr_endian_mode = 3; /* Don't byte swap */
440         shim_cfg.s.dma_read_cmd = 1; /* No allocate L2C */
441         csr_wr(CVMX_SATA_UCTL_SHIM_CFG, shim_cfg.u64);
442
443         return 0;
444 }
This page took 0.055645 seconds and 4 git commands to generate.