aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/boot
diff options
context:
space:
mode:
authorBenjamin Herrenschmidt <benh@kernel.crashing.org>2007-12-20 23:39:26 -0500
committerJosh Boyer <jwboyer@linux.vnet.ibm.com>2007-12-23 14:13:14 -0500
commit619740384cebe2601a8d307654a22d9ed85f2fcb (patch)
treea354c4b83554f2c718afea3ba6aa91d50702e03d /arch/powerpc/boot
parent9dae8afdf212d39bc7c25f1b1ca9b10f10f6beaa (diff)
[POWERPC] 4xx: EP405 boards support for arch/powerpc
Brings EP405 support to arch/powerpc. The IRQ routing for the CPLD comes from a device-tree property, PCI is working to the point where I can see the video card, USB device, and south bridge. This should work with both EP405 and EP405PC. I've not totally figured out how IRQs are wired on this hardware though, thus at this stage, expect only USB interrupts working, pretty much the same as what arch/ppc did. Also, the flash, nvram, rtc and temp control still have to be wired. Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org> Signed-off-by: Josh Boyer <jwboyer@linux.vnet.ibm.com>
Diffstat (limited to 'arch/powerpc/boot')
-rw-r--r--arch/powerpc/boot/4xx.c55
-rw-r--r--arch/powerpc/boot/4xx.h1
-rw-r--r--arch/powerpc/boot/Makefile3
-rw-r--r--arch/powerpc/boot/dts/ep405.dts221
-rw-r--r--arch/powerpc/boot/ep405.c74
-rw-r--r--arch/powerpc/boot/treeboot-walnut.c49
-rwxr-xr-xarch/powerpc/boot/wrapper2
7 files changed, 353 insertions, 52 deletions
diff --git a/arch/powerpc/boot/4xx.c b/arch/powerpc/boot/4xx.c
index 3d0e4f921f1d..852992b146e3 100644
--- a/arch/powerpc/boot/4xx.c
+++ b/arch/powerpc/boot/4xx.c
@@ -179,13 +179,16 @@ void ibm40x_dbcr_reset(void)
179#define EMAC_RESET 0x20000000 179#define EMAC_RESET 0x20000000
180void ibm4xx_quiesce_eth(u32 *emac0, u32 *emac1) 180void ibm4xx_quiesce_eth(u32 *emac0, u32 *emac1)
181{ 181{
182 /* Quiesce the MAL and EMAC(s) since PIBS/OpenBIOS don't do this for us */ 182 /* Quiesce the MAL and EMAC(s) since PIBS/OpenBIOS don't
183 * do this for us
184 */
183 if (emac0) 185 if (emac0)
184 *emac0 = EMAC_RESET; 186 *emac0 = EMAC_RESET;
185 if (emac1) 187 if (emac1)
186 *emac1 = EMAC_RESET; 188 *emac1 = EMAC_RESET;
187 189
188 mtdcr(DCRN_MAL0_CFG, MAL_RESET); 190 mtdcr(DCRN_MAL0_CFG, MAL_RESET);
191 while (mfdcr(DCRN_MAL0_CFG) & MAL_RESET) {};
189} 192}
190 193
191/* Read 4xx EBC bus bridge registers to get mappings of the peripheral 194/* Read 4xx EBC bus bridge registers to get mappings of the peripheral
@@ -298,3 +301,53 @@ void ibm440ep_fixup_clocks(unsigned int sysclk, unsigned int ser_clk)
298 dt_fixup_clock("/plb/opb/serial@ef600500", uart0); 301 dt_fixup_clock("/plb/opb/serial@ef600500", uart0);
299 dt_fixup_clock("/plb/opb/serial@ef600600", uart0); 302 dt_fixup_clock("/plb/opb/serial@ef600600", uart0);
300} 303}
304
305void ibm405gp_fixup_clocks(unsigned int sysclk, unsigned int ser_clk)
306{
307 u32 pllmr = mfdcr(DCRN_CPC0_PLLMR);
308 u32 cpc0_cr0 = mfdcr(DCRN_405_CPC0_CR0);
309 u32 cpc0_cr1 = mfdcr(DCRN_405_CPC0_CR1);
310 u32 cpu, plb, opb, ebc, tb, uart0, uart1, m;
311 u32 fwdv, fbdv, cbdv, opdv, epdv, udiv;
312
313 fwdv = (8 - ((pllmr & 0xe0000000) >> 29));
314 fbdv = (pllmr & 0x1e000000) >> 25;
315 cbdv = ((pllmr & 0x00060000) >> 17) + 1;
316 opdv = ((pllmr & 0x00018000) >> 15) + 1;
317 epdv = ((pllmr & 0x00001800) >> 13) + 2;
318 udiv = ((cpc0_cr0 & 0x3e) >> 1) + 1;
319
320 m = fwdv * fbdv * cbdv;
321
322 cpu = sysclk * m / fwdv;
323 plb = cpu / cbdv;
324 opb = plb / opdv;
325 ebc = plb / epdv;
326
327 if (cpc0_cr0 & 0x80) {
328 /* uart0 uses the external clock */
329 uart0 = ser_clk;
330 } else {
331 uart0 = cpu / udiv;
332 }
333
334 if (cpc0_cr0 & 0x40) {
335 /* uart1 uses the external clock */
336 uart1 = ser_clk;
337 } else {
338 uart1 = cpu / udiv;
339 }
340
341 /* setup the timebase clock to tick at the cpu frequency */
342 cpc0_cr1 = cpc0_cr1 & ~0x00800000;
343 mtdcr(DCRN_405_CPC0_CR1, cpc0_cr1);
344 tb = cpu;
345
346 dt_fixup_cpu_clocks(cpu, tb, 0);
347 dt_fixup_clock("/plb", plb);
348 dt_fixup_clock("/plb/opb", opb);
349 dt_fixup_clock("/plb/ebc", ebc);
350 dt_fixup_clock("/plb/opb/serial@ef600300", uart0);
351 dt_fixup_clock("/plb/opb/serial@ef600400", uart1);
352}
353
diff --git a/arch/powerpc/boot/4xx.h b/arch/powerpc/boot/4xx.h
index adba6a599a93..6af14a01c7f0 100644
--- a/arch/powerpc/boot/4xx.h
+++ b/arch/powerpc/boot/4xx.h
@@ -18,5 +18,6 @@ void ibm40x_dbcr_reset(void);
18void ibm4xx_quiesce_eth(u32 *emac0, u32 *emac1); 18void ibm4xx_quiesce_eth(u32 *emac0, u32 *emac1);
19void ibm4xx_fixup_ebc_ranges(const char *ebc); 19void ibm4xx_fixup_ebc_ranges(const char *ebc);
20void ibm440ep_fixup_clocks(unsigned int sysclk, unsigned int ser_clk); 20void ibm440ep_fixup_clocks(unsigned int sysclk, unsigned int ser_clk);
21void ibm405gp_fixup_clocks(unsigned int sysclk, unsigned int ser_clk);
21 22
22#endif /* _POWERPC_BOOT_4XX_H_ */ 23#endif /* _POWERPC_BOOT_4XX_H_ */
diff --git a/arch/powerpc/boot/Makefile b/arch/powerpc/boot/Makefile
index 9149bb8ed03c..8e5bdd35fd48 100644
--- a/arch/powerpc/boot/Makefile
+++ b/arch/powerpc/boot/Makefile
@@ -58,7 +58,7 @@ src-plat := of.c cuboot-52xx.c cuboot-83xx.c cuboot-85xx.c holly.c \
58 cuboot-ebony.c treeboot-ebony.c prpmc2800.c \ 58 cuboot-ebony.c treeboot-ebony.c prpmc2800.c \
59 ps3-head.S ps3-hvcall.S ps3.c treeboot-bamboo.c cuboot-8xx.c \ 59 ps3-head.S ps3-hvcall.S ps3.c treeboot-bamboo.c cuboot-8xx.c \
60 cuboot-pq2.c cuboot-sequoia.c treeboot-walnut.c cuboot-bamboo.c \ 60 cuboot-pq2.c cuboot-sequoia.c treeboot-walnut.c cuboot-bamboo.c \
61 fixed-head.S ep88xc.c cuboot-hpc2.c 61 fixed-head.S ep88xc.c cuboot-hpc2.c ep405.c
62src-boot := $(src-wlib) $(src-plat) empty.c 62src-boot := $(src-wlib) $(src-plat) empty.c
63 63
64src-boot := $(addprefix $(obj)/, $(src-boot)) 64src-boot := $(addprefix $(obj)/, $(src-boot))
@@ -189,6 +189,7 @@ image-$(CONFIG_DEFAULT_UIMAGE) += uImage
189ifneq ($(CONFIG_DEVICE_TREE),"") 189ifneq ($(CONFIG_DEVICE_TREE),"")
190image-$(CONFIG_PPC_8xx) += cuImage.8xx 190image-$(CONFIG_PPC_8xx) += cuImage.8xx
191image-$(CONFIG_PPC_EP88XC) += zImage.ep88xc 191image-$(CONFIG_PPC_EP88XC) += zImage.ep88xc
192image-$(CONFIG_EP405) += zImage.ep405
192image-$(CONFIG_8260) += cuImage.pq2 193image-$(CONFIG_8260) += cuImage.pq2
193image-$(CONFIG_PPC_MPC52xx) += cuImage.52xx 194image-$(CONFIG_PPC_MPC52xx) += cuImage.52xx
194image-$(CONFIG_PPC_83xx) += cuImage.83xx 195image-$(CONFIG_PPC_83xx) += cuImage.83xx
diff --git a/arch/powerpc/boot/dts/ep405.dts b/arch/powerpc/boot/dts/ep405.dts
new file mode 100644
index 000000000000..007f3c24d3f2
--- /dev/null
+++ b/arch/powerpc/boot/dts/ep405.dts
@@ -0,0 +1,221 @@
1/*
2 * Device Tree Source for EP405
3 *
4 * Copyright 2007 IBM Corp.
5 * Benjamin Herrenschmidt <benh@kernel.crashing.org>
6 *
7 * This file is licensed under the terms of the GNU General Public
8 * License version 2. This program is licensed "as is" without
9 * any warranty of any kind, whether express or implied.
10 */
11
12/ {
13 #address-cells = <1>;
14 #size-cells = <1>;
15 model = "ep405";
16 compatible = "ep405";
17 dcr-parent = <&/cpus/PowerPC,405GP@0>;
18
19 cpus {
20 #address-cells = <1>;
21 #size-cells = <0>;
22
23 PowerPC,405GP@0 {
24 device_type = "cpu";
25 reg = <0>;
26 clock-frequency = <bebc200>; /* Filled in by zImage */
27 timebase-frequency = <0>; /* Filled in by zImage */
28 i-cache-line-size = <20>;
29 d-cache-line-size = <20>;
30 i-cache-size = <4000>;
31 d-cache-size = <4000>;
32 dcr-controller;
33 dcr-access-method = "native";
34 };
35 };
36
37 memory {
38 device_type = "memory";
39 reg = <0 0>; /* Filled in by zImage */
40 };
41
42 UIC0: interrupt-controller {
43 compatible = "ibm,uic";
44 interrupt-controller;
45 cell-index = <0>;
46 dcr-reg = <0c0 9>;
47 #address-cells = <0>;
48 #size-cells = <0>;
49 #interrupt-cells = <2>;
50 };
51
52 plb {
53 compatible = "ibm,plb3";
54 #address-cells = <1>;
55 #size-cells = <1>;
56 ranges;
57 clock-frequency = <0>; /* Filled in by zImage */
58
59 SDRAM0: memory-controller {
60 compatible = "ibm,sdram-405gp";
61 dcr-reg = <010 2>;
62 };
63
64 MAL: mcmal {
65 compatible = "ibm,mcmal-405gp", "ibm,mcmal";
66 dcr-reg = <180 62>;
67 num-tx-chans = <1>;
68 num-rx-chans = <1>;
69 interrupt-parent = <&UIC0>;
70 interrupts = <
71 b 4 /* TXEOB */
72 c 4 /* RXEOB */
73 a 4 /* SERR */
74 d 4 /* TXDE */
75 e 4 /* RXDE */>;
76 };
77
78 POB0: opb {
79 compatible = "ibm,opb-405gp", "ibm,opb";
80 #address-cells = <1>;
81 #size-cells = <1>;
82 ranges = <ef600000 ef600000 a00000>;
83 dcr-reg = <0a0 5>;
84 clock-frequency = <0>; /* Filled in by zImage */
85
86 UART0: serial@ef600300 {
87 device_type = "serial";
88 compatible = "ns16550";
89 reg = <ef600300 8>;
90 virtual-reg = <ef600300>;
91 clock-frequency = <0>; /* Filled in by zImage */
92 current-speed = <2580>;
93 interrupt-parent = <&UIC0>;
94 interrupts = <0 4>;
95 };
96
97 UART1: serial@ef600400 {
98 device_type = "serial";
99 compatible = "ns16550";
100 reg = <ef600400 8>;
101 virtual-reg = <ef600400>;
102 clock-frequency = <0>; /* Filled in by zImage */
103 current-speed = <2580>;
104 interrupt-parent = <&UIC0>;
105 interrupts = <1 4>;
106 };
107
108 IIC: i2c@ef600500 {
109 compatible = "ibm,iic-405gp", "ibm,iic";
110 reg = <ef600500 11>;
111 interrupt-parent = <&UIC0>;
112 interrupts = <2 4>;
113 };
114
115 GPIO: gpio@ef600700 {
116 compatible = "ibm,gpio-405gp";
117 reg = <ef600700 20>;
118 };
119
120 EMAC: ethernet@ef600800 {
121 linux,network-index = <0>;
122 device_type = "network";
123 compatible = "ibm,emac-405gp", "ibm,emac";
124 interrupt-parent = <&UIC0>;
125 interrupts = <
126 f 4 /* Ethernet */
127 9 4 /* Ethernet Wake Up */>;
128 local-mac-address = [000000000000]; /* Filled in by zImage */
129 reg = <ef600800 70>;
130 mal-device = <&MAL>;
131 mal-tx-channel = <0>;
132 mal-rx-channel = <0>;
133 cell-index = <0>;
134 max-frame-size = <5dc>;
135 rx-fifo-size = <1000>;
136 tx-fifo-size = <800>;
137 phy-mode = "rmii";
138 phy-map = <00000000>;
139 };
140
141 };
142
143 EBC0: ebc {
144 compatible = "ibm,ebc-405gp", "ibm,ebc";
145 dcr-reg = <012 2>;
146 #address-cells = <2>;
147 #size-cells = <1>;
148
149
150 /* The ranges property is supplied by the bootwrapper
151 * and is based on the firmware's configuration of the
152 * EBC bridge
153 */
154 clock-frequency = <0>; /* Filled in by zImage */
155
156 /* NVRAM and RTC */
157 nvrtc@4,200000 {
158 compatible = "ds1742";
159 reg = <4 200000 0>; /* size fixed up by zImage */
160 };
161
162 /* "BCSR" CPLD contains a PCI irq controller */
163 bcsr@4,0 {
164 compatible = "ep405-bcsr";
165 reg = <4 0 10>;
166 interrupt-controller;
167 /* Routing table */
168 irq-routing = [ 00 /* SYSERR */
169 01 /* STTM */
170 01 /* RTC */
171 01 /* FENET */
172 02 /* NB PCIIRQ mux ? */
173 03 /* SB Winbond 8259 ? */
174 04 /* Serial Ring */
175 05 /* USB (ep405pc) */
176 06 /* XIRQ 0 */
177 06 /* XIRQ 1 */
178 06 /* XIRQ 2 */
179 06 /* XIRQ 3 */
180 06 /* XIRQ 4 */
181 06 /* XIRQ 5 */
182 06 /* XIRQ 6 */
183 07]; /* Reserved */
184 };
185 };
186
187 PCI0: pci@ec000000 {
188 device_type = "pci";
189 #interrupt-cells = <1>;
190 #size-cells = <2>;
191 #address-cells = <3>;
192 compatible = "ibm,plb405gp-pci", "ibm,plb-pci";
193 primary;
194 reg = <eec00000 8 /* Config space access */
195 eed80000 4 /* IACK */
196 eed80000 4 /* Special cycle */
197 ef480000 40>; /* Internal registers */
198
199 /* Outbound ranges, one memory and one IO,
200 * later cannot be changed. Chip supports a second
201 * IO range but we don't use it for now
202 */
203 ranges = <02000000 0 80000000 80000000 0 20000000
204 01000000 0 00000000 e8000000 0 00010000>;
205
206 /* Inbound 2GB range starting at 0 */
207 dma-ranges = <42000000 0 0 0 0 80000000>;
208
209 /* That's all I know about IRQs on that thing ... */
210 interrupt-map-mask = <f800 0 0 0>;
211 interrupt-map = <
212 /* USB */
213 7000 0 0 0 &UIC0 1e 8 /* IRQ5 */
214 >;
215 };
216 };
217
218 chosen {
219 linux,stdout-path = "/plb/opb/serial@ef600300";
220 };
221};
diff --git a/arch/powerpc/boot/ep405.c b/arch/powerpc/boot/ep405.c
new file mode 100644
index 000000000000..2d08a862cbea
--- /dev/null
+++ b/arch/powerpc/boot/ep405.c
@@ -0,0 +1,74 @@
1/*
2 * Embedded Planet EP405 with PlanetCore firmware
3 *
4 * (c) Benjamin Herrenschmidt <benh@kernel.crashing.org>, IBM Corp,\
5 *
6 * Based on ep88xc.c by
7 *
8 * Scott Wood <scottwood@freescale.com>
9 *
10 * Copyright (c) 2007 Freescale Semiconductor, Inc.
11 *
12 * This program is free software; you can redistribute it and/or modify it
13 * under the terms of the GNU General Public License version 2 as published
14 * by the Free Software Foundation.
15 */
16
17#include "ops.h"
18#include "stdio.h"
19#include "planetcore.h"
20#include "dcr.h"
21#include "4xx.h"
22#include "io.h"
23
24static char *table;
25static u64 mem_size;
26
27static void platform_fixups(void)
28{
29 u64 val;
30 void *nvrtc;
31
32 dt_fixup_memory(0, mem_size);
33 planetcore_set_mac_addrs(table);
34
35 if (!planetcore_get_decimal(table, PLANETCORE_KEY_CRYSTAL_HZ, &val)) {
36 printf("No PlanetCore crystal frequency key.\r\n");
37 return;
38 }
39 ibm405gp_fixup_clocks(val, 0xa8c000);
40 ibm4xx_quiesce_eth((u32 *)0xef600800, NULL);
41 ibm4xx_fixup_ebc_ranges("/plb/ebc");
42
43 if (!planetcore_get_decimal(table, PLANETCORE_KEY_KB_NVRAM, &val)) {
44 printf("No PlanetCore NVRAM size key.\r\n");
45 return;
46 }
47 nvrtc = finddevice("/plb/ebc/nvrtc@4,200000");
48 if (nvrtc != NULL) {
49 u32 reg[3] = { 4, 0x200000, 0};
50 getprop(nvrtc, "reg", reg, 3);
51 reg[2] = (val << 10) & 0xffffffff;
52 setprop(nvrtc, "reg", reg, 3);
53 }
54}
55
56void platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
57 unsigned long r6, unsigned long r7)
58{
59 table = (char *)r3;
60 planetcore_prepare_table(table);
61
62 if (!planetcore_get_decimal(table, PLANETCORE_KEY_MB_RAM, &mem_size))
63 return;
64
65 mem_size *= 1024 * 1024;
66 simple_alloc_init(_end, mem_size - (unsigned long)_end, 32, 64);
67
68 fdt_init(_dtb_start);
69
70 planetcore_set_stdout_path(table);
71
72 serial_console_init();
73 platform_ops.fixups = platform_fixups;
74}
diff --git a/arch/powerpc/boot/treeboot-walnut.c b/arch/powerpc/boot/treeboot-walnut.c
index 70ffce343c0a..330485f47825 100644
--- a/arch/powerpc/boot/treeboot-walnut.c
+++ b/arch/powerpc/boot/treeboot-walnut.c
@@ -20,55 +20,6 @@
20 20
21BSS_STACK(4096); 21BSS_STACK(4096);
22 22
23void ibm405gp_fixup_clocks(unsigned int sysclk, unsigned int ser_clk)
24{
25 u32 pllmr = mfdcr(DCRN_CPC0_PLLMR);
26 u32 cpc0_cr0 = mfdcr(DCRN_405_CPC0_CR0);
27 u32 cpc0_cr1 = mfdcr(DCRN_405_CPC0_CR1);
28 u32 cpu, plb, opb, ebc, tb, uart0, uart1, m;
29 u32 fwdv, fbdv, cbdv, opdv, epdv, udiv;
30
31 fwdv = (8 - ((pllmr & 0xe0000000) >> 29));
32 fbdv = (pllmr & 0x1e000000) >> 25;
33 cbdv = ((pllmr & 0x00060000) >> 17) + 1;
34 opdv = ((pllmr & 0x00018000) >> 15) + 1;
35 epdv = ((pllmr & 0x00001800) >> 13) + 2;
36 udiv = ((cpc0_cr0 & 0x3e) >> 1) + 1;
37
38 m = fwdv * fbdv * cbdv;
39
40 cpu = sysclk * m / fwdv;
41 plb = cpu / cbdv;
42 opb = plb / opdv;
43 ebc = plb / epdv;
44
45 if (cpc0_cr0 & 0x80) {
46 /* uart0 uses the external clock */
47 uart0 = ser_clk;
48 } else {
49 uart0 = cpu / udiv;
50 }
51
52 if (cpc0_cr0 & 0x40) {
53 /* uart1 uses the external clock */
54 uart1 = ser_clk;
55 } else {
56 uart1 = cpu / udiv;
57 }
58
59 /* setup the timebase clock to tick at the cpu frequency */
60 cpc0_cr1 = cpc0_cr1 & ~0x00800000;
61 mtdcr(DCRN_405_CPC0_CR1, cpc0_cr1);
62 tb = cpu;
63
64 dt_fixup_cpu_clocks(cpu, tb, 0);
65 dt_fixup_clock("/plb", plb);
66 dt_fixup_clock("/plb/opb", opb);
67 dt_fixup_clock("/plb/ebc", ebc);
68 dt_fixup_clock("/plb/opb/serial@ef600300", uart0);
69 dt_fixup_clock("/plb/opb/serial@ef600400", uart1);
70}
71
72static void walnut_flashsel_fixup(void) 23static void walnut_flashsel_fixup(void)
73{ 24{
74 void *devp, *sram; 25 void *devp, *sram;
diff --git a/arch/powerpc/boot/wrapper b/arch/powerpc/boot/wrapper
index f961cdeb97a2..154df055aad2 100755
--- a/arch/powerpc/boot/wrapper
+++ b/arch/powerpc/boot/wrapper
@@ -168,7 +168,7 @@ ps3)
168 ksection=.kernel:vmlinux.bin 168 ksection=.kernel:vmlinux.bin
169 isection=.kernel:initrd 169 isection=.kernel:initrd
170 ;; 170 ;;
171ep88xc) 171ep88xc|ep405)
172 platformo="$object/fixed-head.o $object/$platform.o" 172 platformo="$object/fixed-head.o $object/$platform.o"
173 binary=y 173 binary=y
174 ;; 174 ;;