1 | // SPDX-License-Identifier: GPL-2.0-or-later |
2 | /* |
3 | * Copyright © 2011 Tony Breeds IBM Corporation |
4 | * |
5 | * Based on earlier code: |
6 | * Copyright (C) Paul Mackerras 1997. |
7 | * |
8 | * Matt Porter <mporter@kernel.crashing.org> |
9 | * Copyright 2002-2005 MontaVista Software Inc. |
10 | * |
11 | * Eugene Surovegin <eugene.surovegin@zultys.com> or <ebs@ebshome.net> |
12 | * Copyright (c) 2003, 2004 Zultys Technologies |
13 | * |
14 | * Copyright 2007 David Gibson, IBM Corporation. |
15 | * Copyright 2010 Ben. Herrenschmidt, IBM Corporation. |
16 | * Copyright © 2011 David Kleikamp IBM Corporation |
17 | */ |
18 | #include <stdarg.h> |
19 | #include <stddef.h> |
20 | #include "types.h" |
21 | #include "elf.h" |
22 | #include "string.h" |
23 | #include "stdio.h" |
24 | #include "page.h" |
25 | #include "ops.h" |
26 | #include "reg.h" |
27 | #include "io.h" |
28 | #include "dcr.h" |
29 | #include "4xx.h" |
30 | #include "44x.h" |
31 | #include "libfdt.h" |
32 | |
33 | BSS_STACK(4096); |
34 | |
35 | #define MAX_RANKS 0x4 |
36 | #define DDR3_MR0CF 0x80010011U |
37 | |
38 | static unsigned long long ibm_currituck_memsize; |
39 | static unsigned long long ibm_currituck_detect_memsize(void) |
40 | { |
41 | u32 reg; |
42 | unsigned i; |
43 | unsigned long long memsize = 0; |
44 | |
45 | for(i = 0; i < MAX_RANKS; i++){ |
46 | reg = mfdcrx(DDR3_MR0CF + i); |
47 | |
48 | if (!(reg & 1)) |
49 | continue; |
50 | |
51 | reg &= 0x0000f000; |
52 | reg >>= 12; |
53 | memsize += (0x800000ULL << reg); |
54 | } |
55 | |
56 | return memsize; |
57 | } |
58 | |
59 | static void ibm_currituck_fixups(void) |
60 | { |
61 | void *devp = finddevice(name: "/" ); |
62 | u32 dma_ranges[7]; |
63 | |
64 | dt_fixup_memory(start: 0x0ULL, size: ibm_currituck_memsize); |
65 | |
66 | while ((devp = find_node_by_devtype(prev: devp, type: "pci" ))) { |
67 | if (getprop(devp, name: "dma-ranges" , buf: dma_ranges, buflen: sizeof(dma_ranges)) < 0) { |
68 | printf(fmt: "%s: Failed to get dma-ranges\r\n" , __func__); |
69 | continue; |
70 | } |
71 | |
72 | dma_ranges[5] = ibm_currituck_memsize >> 32; |
73 | dma_ranges[6] = ibm_currituck_memsize & 0xffffffffUL; |
74 | |
75 | setprop(devp, name: "dma-ranges" , buf: dma_ranges, buflen: sizeof(dma_ranges)); |
76 | } |
77 | } |
78 | |
79 | #define SPRN_PIR 0x11E /* Processor Identification Register */ |
80 | void platform_init(void) |
81 | { |
82 | unsigned long end_of_ram, avail_ram; |
83 | u32 pir_reg; |
84 | int node, size; |
85 | const u32 *timebase; |
86 | |
87 | ibm_currituck_memsize = ibm_currituck_detect_memsize(); |
88 | if (ibm_currituck_memsize >> 32) |
89 | end_of_ram = ~0UL; |
90 | else |
91 | end_of_ram = ibm_currituck_memsize; |
92 | avail_ram = end_of_ram - (unsigned long)_end; |
93 | |
94 | simple_alloc_init(base: _end, heap_size: avail_ram, granularity: 128, max_allocs: 64); |
95 | platform_ops.fixups = ibm_currituck_fixups; |
96 | platform_ops.exit = ibm44x_dbcr_reset; |
97 | pir_reg = mfspr(SPRN_PIR); |
98 | |
99 | /* Make sure FDT blob is sane */ |
100 | if (fdt_check_header(_dtb_start) != 0) |
101 | fatal("Invalid device tree blob\n" ); |
102 | |
103 | node = fdt_node_offset_by_prop_value(_dtb_start, -1, "device_type" , |
104 | "cpu" , sizeof("cpu" )); |
105 | if (!node) |
106 | fatal("Cannot find cpu node\n" ); |
107 | timebase = fdt_getprop(_dtb_start, node, "timebase-frequency" , &size); |
108 | if (timebase && (size == 4)) |
109 | timebase_period_ns = 1000000000 / *timebase; |
110 | |
111 | fdt_set_boot_cpuid_phys(_dtb_start, pir_reg); |
112 | fdt_init(blob: _dtb_start); |
113 | |
114 | serial_console_init(); |
115 | } |
116 | |