aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/boot/cuboot-c2k.c
diff options
context:
space:
mode:
authorRemi Machet <rmachet@slac.stanford.edu>2008-05-20 16:50:10 -0400
committerPaul Mackerras <paulus@samba.org>2008-06-08 23:42:25 -0400
commitc6ec08e03dd06b8dfa3f6d938b0a89c6ed8475c9 (patch)
tree12571414b76d9ca8d4054f8cc0f7ee8558e14386 /arch/powerpc/boot/cuboot-c2k.c
parent61586476cda599c64ab2b8f4f808d6a615a2fab2 (diff)
powerpc: Boot code for the C2K
Support for the C2K cPCI Single Board Computer from GEFanuc (PowerPC MPC7448 with a Marvell MV64460 chipset). All features of the board are not supported yet, but the board boots, flash works, all Ethernet ports are working and PCI devices are all found (USB and SATA on PCI1 do not work yet). Part 2 of 5: support for the board in arch/powerpc/boot. Signed-off-by: Remi Machet <rmachet@slac.stanford.edu> Signed-off-by: Paul Mackerras <paulus@samba.org>
Diffstat (limited to 'arch/powerpc/boot/cuboot-c2k.c')
-rw-r--r--arch/powerpc/boot/cuboot-c2k.c190
1 files changed, 190 insertions, 0 deletions
diff --git a/arch/powerpc/boot/cuboot-c2k.c b/arch/powerpc/boot/cuboot-c2k.c
new file mode 100644
index 000000000000..e43594950ba3
--- /dev/null
+++ b/arch/powerpc/boot/cuboot-c2k.c
@@ -0,0 +1,190 @@
1/*
2 * GEFanuc C2K platform code.
3 *
4 * Author: Remi Machet <rmachet@slac.stanford.edu>
5 *
6 * Originated from prpmc2800.c
7 *
8 * 2008 (c) Stanford University
9 * 2007 (c) MontaVista, Software, Inc.
10 *
11 * This program is free software; you can redistribute it and/or modify it
12 * under the terms of the GNU General Public License version 2 as published
13 * by the Free Software Foundation.
14 */
15
16#include "types.h"
17#include "stdio.h"
18#include "io.h"
19#include "ops.h"
20#include "elf.h"
21#include "gunzip_util.h"
22#include "mv64x60.h"
23#include "cuboot.h"
24#include "ppcboot.h"
25
26static u8 *bridge_base;
27
28static void c2k_bridge_setup(u32 mem_size)
29{
30 u32 i, v[30], enables, acc_bits;
31 u32 pci_base_hi, pci_base_lo, size, buf[2];
32 unsigned long cpu_base;
33 int rc;
34 void *devp, *mv64x60_devp;
35 u8 *bridge_pbase, is_coherent;
36 struct mv64x60_cpu2pci_win *tbl;
37 int bus;
38
39 bridge_pbase = mv64x60_get_bridge_pbase();
40 is_coherent = mv64x60_is_coherent();
41
42 if (is_coherent)
43 acc_bits = MV64x60_PCI_ACC_CNTL_SNOOP_WB
44 | MV64x60_PCI_ACC_CNTL_SWAP_NONE
45 | MV64x60_PCI_ACC_CNTL_MBURST_32_BYTES
46 | MV64x60_PCI_ACC_CNTL_RDSIZE_32_BYTES;
47 else
48 acc_bits = MV64x60_PCI_ACC_CNTL_SNOOP_NONE
49 | MV64x60_PCI_ACC_CNTL_SWAP_NONE
50 | MV64x60_PCI_ACC_CNTL_MBURST_128_BYTES
51 | MV64x60_PCI_ACC_CNTL_RDSIZE_256_BYTES;
52
53 mv64x60_config_ctlr_windows(bridge_base, bridge_pbase, is_coherent);
54 mv64x60_devp = find_node_by_compatible(NULL, "marvell,mv64360");
55 if (mv64x60_devp == NULL)
56 fatal("Error: Missing marvell,mv64360 device tree node\n\r");
57
58 enables = in_le32((u32 *)(bridge_base + MV64x60_CPU_BAR_ENABLE));
59 enables |= 0x007ffe00; /* Disable all cpu->pci windows */
60 out_le32((u32 *)(bridge_base + MV64x60_CPU_BAR_ENABLE), enables);
61
62 /* Get the cpu -> pci i/o & mem mappings from the device tree */
63 devp = NULL;
64 for (bus = 0; ; bus++) {
65 char name[] = "pci ";
66
67 name[strlen(name)-1] = bus+'0';
68
69 devp = find_node_by_alias(name);
70 if (devp == NULL)
71 break;
72
73 if (bus >= 2)
74 fatal("Error: Only 2 PCI controllers are supported at" \
75 " this time.\n");
76
77 mv64x60_config_pci_windows(bridge_base, bridge_pbase, bus, 0,
78 mem_size, acc_bits);
79
80 rc = getprop(devp, "ranges", v, sizeof(v));
81 if (rc == 0)
82 fatal("Error: Can't find marvell,mv64360-pci ranges"
83 " property\n\r");
84
85 /* Get the cpu -> pci i/o & mem mappings from the device tree */
86
87 for (i = 0; i < rc; i += 6) {
88 switch (v[i] & 0xff000000) {
89 case 0x01000000: /* PCI I/O Space */
90 tbl = mv64x60_cpu2pci_io;
91 break;
92 case 0x02000000: /* PCI MEM Space */
93 tbl = mv64x60_cpu2pci_mem;
94 break;
95 default:
96 continue;
97 }
98
99 pci_base_hi = v[i+1];
100 pci_base_lo = v[i+2];
101 cpu_base = v[i+3];
102 size = v[i+5];
103
104 buf[0] = cpu_base;
105 buf[1] = size;
106
107 if (!dt_xlate_addr(devp, buf, sizeof(buf), &cpu_base))
108 fatal("Error: Can't translate PCI address " \
109 "0x%x\n\r", (u32)cpu_base);
110
111 mv64x60_config_cpu2pci_window(bridge_base, bus,
112 pci_base_hi, pci_base_lo, cpu_base, size, tbl);
113 }
114
115 enables &= ~(3<<(9+bus*5)); /* Enable cpu->pci<bus> i/o,
116 cpu->pci<bus> mem0 */
117 out_le32((u32 *)(bridge_base + MV64x60_CPU_BAR_ENABLE),
118 enables);
119 };
120}
121
122static void c2k_fixups(void)
123{
124 u32 mem_size;
125
126 mem_size = mv64x60_get_mem_size(bridge_base);
127 c2k_bridge_setup(mem_size); /* Do necessary bridge setup */
128}
129
130#define MV64x60_MPP_CNTL_0 0xf000
131#define MV64x60_MPP_CNTL_2 0xf008
132#define MV64x60_GPP_IO_CNTL 0xf100
133#define MV64x60_GPP_LEVEL_CNTL 0xf110
134#define MV64x60_GPP_VALUE_SET 0xf118
135
136static void c2k_reset(void)
137{
138 u32 temp;
139
140 udelay(5000000);
141
142 if (bridge_base != 0) {
143 temp = in_le32((u32 *)(bridge_base + MV64x60_MPP_CNTL_0));
144 temp &= 0xFFFF0FFF;
145 out_le32((u32 *)(bridge_base + MV64x60_MPP_CNTL_0), temp);
146
147 temp = in_le32((u32 *)(bridge_base + MV64x60_GPP_LEVEL_CNTL));
148 temp |= 0x00000004;
149 out_le32((u32 *)(bridge_base + MV64x60_GPP_LEVEL_CNTL), temp);
150
151 temp = in_le32((u32 *)(bridge_base + MV64x60_GPP_IO_CNTL));
152 temp |= 0x00000004;
153 out_le32((u32 *)(bridge_base + MV64x60_GPP_IO_CNTL), temp);
154
155 temp = in_le32((u32 *)(bridge_base + MV64x60_MPP_CNTL_2));
156 temp &= 0xFFFF0FFF;
157 out_le32((u32 *)(bridge_base + MV64x60_MPP_CNTL_2), temp);
158
159 temp = in_le32((u32 *)(bridge_base + MV64x60_GPP_LEVEL_CNTL));
160 temp |= 0x00080000;
161 out_le32((u32 *)(bridge_base + MV64x60_GPP_LEVEL_CNTL), temp);
162
163 temp = in_le32((u32 *)(bridge_base + MV64x60_GPP_IO_CNTL));
164 temp |= 0x00080000;
165 out_le32((u32 *)(bridge_base + MV64x60_GPP_IO_CNTL), temp);
166
167 out_le32((u32 *)(bridge_base + MV64x60_GPP_VALUE_SET),
168 0x00080004);
169 }
170
171 for (;;);
172}
173
174static bd_t bd;
175
176void platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
177 unsigned long r6, unsigned long r7)
178{
179 CUBOOT_INIT();
180
181 fdt_init(_dtb_start);
182
183 bridge_base = mv64x60_get_bridge_base();
184
185 platform_ops.fixups = c2k_fixups;
186 platform_ops.exit = c2k_reset;
187
188 if (serial_console_init() < 0)
189 exit();
190}