aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc
diff options
context:
space:
mode:
authorNicolas DET <nd@bplan-gmbh.de>2006-11-05 06:57:16 -0500
committerPaul Mackerras <paulus@samba.org>2006-11-12 22:45:04 -0500
commitc37858d333a50815c74349396e31a535f4128e0b (patch)
treee277f9aaf79196855ef984d99f1288ca66eab051 /arch/powerpc
parent0f6c95dcabdaa8fdc95b125582bd12625adfbde6 (diff)
[PATCH] Add Efika platform support
Add Efika (http://www.bplan-gmbh.de/efika_spec_en.html) platform support for arch/powerpc. Signed-off-by: Nicolas DET <nd@bplan-gmbh.de> Acked-by: Benjamin Herrenschmidt <benh@kernel.crashing.org> Signed-off-by: Paul Mackerras <paulus@samba.org>
Diffstat (limited to 'arch/powerpc')
-rw-r--r--arch/powerpc/Kconfig8
-rw-r--r--arch/powerpc/platforms/Makefile1
-rw-r--r--arch/powerpc/platforms/efika/Makefile1
-rw-r--r--arch/powerpc/platforms/efika/efika.h19
-rw-r--r--arch/powerpc/platforms/efika/pci.c119
-rw-r--r--arch/powerpc/platforms/efika/setup.c149
6 files changed, 297 insertions, 0 deletions
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index 7107d472413f..a41d191bf1be 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -386,6 +386,14 @@ config PPC_CHRP
386 select PPC_UDBG_16550 386 select PPC_UDBG_16550
387 default y 387 default y
388 388
389config PPC_EFIKA
390 bool "bPlan Efika 5k2. MPC5200B based computer"
391 depends on PPC_MULTIPLATFORM && PPC32
392 select PPC_RTAS
393 select RTAS_PROC
394 select PPC_MPC52xx
395 default y
396
389config PPC_PMAC 397config PPC_PMAC
390 bool "Apple PowerMac based machines" 398 bool "Apple PowerMac based machines"
391 depends on PPC_MULTIPLATFORM 399 depends on PPC_MULTIPLATFORM
diff --git a/arch/powerpc/platforms/Makefile b/arch/powerpc/platforms/Makefile
index e58fa953a50b..7ad2673d0aa5 100644
--- a/arch/powerpc/platforms/Makefile
+++ b/arch/powerpc/platforms/Makefile
@@ -5,6 +5,7 @@ ifeq ($(CONFIG_PPC64),y)
5obj-$(CONFIG_PPC_PMAC) += powermac/ 5obj-$(CONFIG_PPC_PMAC) += powermac/
6endif 6endif
7endif 7endif
8obj-$(CONFIG_PPC_EFIKA) += efika/
8obj-$(CONFIG_PPC_CHRP) += chrp/ 9obj-$(CONFIG_PPC_CHRP) += chrp/
9obj-$(CONFIG_4xx) += 4xx/ 10obj-$(CONFIG_4xx) += 4xx/
10obj-$(CONFIG_PPC_83xx) += 83xx/ 11obj-$(CONFIG_PPC_83xx) += 83xx/
diff --git a/arch/powerpc/platforms/efika/Makefile b/arch/powerpc/platforms/efika/Makefile
new file mode 100644
index 000000000000..17b2a781fbae
--- /dev/null
+++ b/arch/powerpc/platforms/efika/Makefile
@@ -0,0 +1 @@
obj-y += setup.o mpc52xx.o pci.o
diff --git a/arch/powerpc/platforms/efika/efika.h b/arch/powerpc/platforms/efika/efika.h
new file mode 100644
index 000000000000..2f060fd097d7
--- /dev/null
+++ b/arch/powerpc/platforms/efika/efika.h
@@ -0,0 +1,19 @@
1/*
2 * Efika 5K2 platform setup - Header file
3 *
4 * Copyright (C) 2006 bplan GmbH
5 *
6 * This file is licensed under the terms of the GNU General Public License
7 * version 2. This program is licensed "as is" without any warranty of any
8 * kind, whether express or implied.
9 *
10 */
11
12#ifndef __ARCH_POWERPC_EFIKA__
13#define __ARCH_POWERPC_EFIKA__
14
15#define EFIKA_PLATFORM_NAME "Efika"
16
17extern void __init efika_pcisetup(void);
18
19#endif
diff --git a/arch/powerpc/platforms/efika/pci.c b/arch/powerpc/platforms/efika/pci.c
new file mode 100644
index 000000000000..62e05b2a9227
--- /dev/null
+++ b/arch/powerpc/platforms/efika/pci.c
@@ -0,0 +1,119 @@
1
2#include <linux/kernel.h>
3#include <linux/pci.h>
4#include <linux/string.h>
5#include <linux/init.h>
6
7#include <asm/io.h>
8#include <asm/irq.h>
9#include <asm/prom.h>
10#include <asm/machdep.h>
11#include <asm/sections.h>
12#include <asm/pci-bridge.h>
13#include <asm/rtas.h>
14
15#include "efika.h"
16
17#ifdef CONFIG_PCI
18/*
19 * Access functions for PCI config space using RTAS calls.
20 */
21static int rtas_read_config(struct pci_bus *bus, unsigned int devfn, int offset,
22 int len, u32 * val)
23{
24 struct pci_controller *hose = bus->sysdata;
25 unsigned long addr = (offset & 0xff) | ((devfn & 0xff) << 8)
26 | (((bus->number - hose->first_busno) & 0xff) << 16)
27 | (hose->index << 24);
28 int ret = -1;
29 int rval;
30
31 rval = rtas_call(rtas_token("read-pci-config"), 2, 2, &ret, addr, len);
32 *val = ret;
33 return rval ? PCIBIOS_DEVICE_NOT_FOUND : PCIBIOS_SUCCESSFUL;
34}
35
36static int rtas_write_config(struct pci_bus *bus, unsigned int devfn,
37 int offset, int len, u32 val)
38{
39 struct pci_controller *hose = bus->sysdata;
40 unsigned long addr = (offset & 0xff) | ((devfn & 0xff) << 8)
41 | (((bus->number - hose->first_busno) & 0xff) << 16)
42 | (hose->index << 24);
43 int rval;
44
45 rval = rtas_call(rtas_token("write-pci-config"), 3, 1, NULL,
46 addr, len, val);
47 return rval ? PCIBIOS_DEVICE_NOT_FOUND : PCIBIOS_SUCCESSFUL;
48}
49
50static struct pci_ops rtas_pci_ops = {
51 rtas_read_config,
52 rtas_write_config
53};
54
55void __init efika_pcisetup(void)
56{
57 const int *bus_range;
58 int len;
59 struct pci_controller *hose;
60 struct device_node *root;
61 struct device_node *pcictrl;
62
63 root = of_find_node_by_path("/");
64 if (root == NULL) {
65 printk(KERN_WARNING EFIKA_PLATFORM_NAME
66 ": Unable to find the root node\n");
67 return;
68 }
69
70 for (pcictrl = NULL;;) {
71 pcictrl = of_get_next_child(root, pcictrl);
72 if ((pcictrl == NULL) || (strcmp(pcictrl->name, "pci") == 0))
73 break;
74 }
75
76 of_node_put(root);
77
78 if (pcictrl == NULL) {
79 printk(KERN_WARNING EFIKA_PLATFORM_NAME
80 ": Unable to find the PCI bridge node\n");
81 return;
82 }
83
84 bus_range = get_property(pcictrl, "bus-range", &len);
85 if (bus_range == NULL || len < 2 * sizeof(int)) {
86 printk(KERN_WARNING EFIKA_PLATFORM_NAME
87 ": Can't get bus-range for %s\n", pcictrl->full_name);
88 return;
89 }
90
91 if (bus_range[1] == bus_range[0])
92 printk(KERN_INFO EFIKA_PLATFORM_NAME ": PCI bus %d",
93 bus_range[0]);
94 else
95 printk(KERN_INFO EFIKA_PLATFORM_NAME ": PCI buses %d..%d",
96 bus_range[0], bus_range[1]);
97 printk(" controlled by %s\n", pcictrl->full_name);
98 printk("\n");
99
100 hose = pcibios_alloc_controller();
101 if (!hose) {
102 printk(KERN_WARNING EFIKA_PLATFORM_NAME
103 ": Can't allocate PCI controller structure for %s\n",
104 pcictrl->full_name);
105 return;
106 }
107
108 hose->arch_data = of_node_get(pcictrl);
109 hose->first_busno = bus_range[0];
110 hose->last_busno = bus_range[1];
111 hose->ops = &rtas_pci_ops;
112
113 pci_process_bridge_OF_ranges(hose, pcictrl, 0);
114}
115
116#else
117void __init efika_pcisetup(void)
118{}
119#endif
diff --git a/arch/powerpc/platforms/efika/setup.c b/arch/powerpc/platforms/efika/setup.c
new file mode 100644
index 000000000000..3bc1b5fe0cea
--- /dev/null
+++ b/arch/powerpc/platforms/efika/setup.c
@@ -0,0 +1,149 @@
1/*
2 *
3 * Efika 5K2 platform setup
4 * Some code really inspired from the lite5200b platform.
5 *
6 * Copyright (C) 2006 bplan GmbH
7 *
8 * This file is licensed under the terms of the GNU General Public License
9 * version 2. This program is licensed "as is" without any warranty of any
10 * kind, whether express or implied.
11 *
12 */
13
14#include <linux/errno.h>
15#include <linux/kernel.h>
16#include <linux/slab.h>
17#include <linux/reboot.h>
18#include <linux/init.h>
19#include <linux/utsrelease.h>
20#include <linux/seq_file.h>
21#include <linux/root_dev.h>
22#include <linux/initrd.h>
23#include <linux/timer.h>
24#include <linux/pci.h>
25
26#include <asm/pgtable.h>
27#include <asm/prom.h>
28#include <asm/time.h>
29#include <asm/machdep.h>
30#include <asm/rtas.h>
31#include <asm/of_device.h>
32#include <asm/mpc52xx.h>
33
34#include "efika.h"
35
36static void efika_show_cpuinfo(struct seq_file *m)
37{
38 struct device_node *root;
39 const char *revision = NULL;
40 const char *codegendescription = NULL;
41 const char *codegenvendor = NULL;
42
43 root = of_find_node_by_path("/");
44 if (root) {
45 revision = get_property(root, "revision", NULL);
46 codegendescription =
47 get_property(root, "CODEGEN,description", NULL);
48 codegenvendor = get_property(root, "CODEGEN,vendor", NULL);
49
50 of_node_put(root);
51 }
52
53 if (codegendescription)
54 seq_printf(m, "machine\t\t: %s\n", codegendescription);
55 else
56 seq_printf(m, "machine\t\t: Efika\n");
57
58 if (revision)
59 seq_printf(m, "revision\t: %s\n", revision);
60
61 if (codegenvendor)
62 seq_printf(m, "vendor\t\t: %s\n", codegenvendor);
63
64 of_node_put(root);
65}
66
67static void __init efika_setup_arch(void)
68{
69 rtas_initialize();
70
71#ifdef CONFIG_BLK_DEV_INITRD
72 initrd_below_start_ok = 1;
73
74 if (initrd_start)
75 ROOT_DEV = Root_RAM0;
76 else
77#endif
78 ROOT_DEV = Root_SDA2; /* sda2 (sda1 is for the kernel) */
79
80 efika_pcisetup();
81
82 if (ppc_md.progress)
83 ppc_md.progress("Linux/PPC " UTS_RELEASE " runnung on Efika ;-)\n", 0x0);
84}
85
86static void __init efika_init(void)
87{
88 struct device_node *np;
89 struct device_node *cnp = NULL;
90 const u32 *base;
91
92 /* Find every child of the SOC node and add it to of_platform */
93 np = of_find_node_by_name(NULL, "builtin");
94 if (np) {
95 char name[BUS_ID_SIZE];
96 while ((cnp = of_get_next_child(np, cnp))) {
97 strcpy(name, cnp->name);
98
99 base = get_property(cnp, "reg", NULL);
100 if (base == NULL)
101 continue;
102
103 snprintf(name+strlen(name), BUS_ID_SIZE, "@%x", *base);
104 of_platform_device_create(cnp, name, NULL);
105
106 printk(KERN_INFO EFIKA_PLATFORM_NAME" : Added %s (type '%s' at '%s') to the known devices\n", name, cnp->type, cnp->full_name);
107 }
108 }
109
110 if (ppc_md.progress)
111 ppc_md.progress(" Have fun with your Efika! ", 0x7777);
112}
113
114static int __init efika_probe(void)
115{
116 char *model = of_get_flat_dt_prop(of_get_flat_dt_root(),
117 "model", NULL);
118
119 if (model == NULL)
120 return 0;
121 if (strcmp(model, "EFIKA5K2"))
122 return 0;
123
124 ISA_DMA_THRESHOLD = ~0L;
125 DMA_MODE_READ = 0x44;
126 DMA_MODE_WRITE = 0x48;
127
128 return 1;
129}
130
131define_machine(efika)
132{
133 .name = EFIKA_PLATFORM_NAME,
134 .probe = efika_probe,
135 .setup_arch = efika_setup_arch,
136 .init = efika_init,
137 .show_cpuinfo = efika_show_cpuinfo,
138 .init_IRQ = mpc52xx_init_irq,
139 .get_irq = mpc52xx_get_irq,
140 .restart = rtas_restart,
141 .power_off = rtas_power_off,
142 .halt = rtas_halt,
143 .set_rtc_time = rtas_set_rtc_time,
144 .get_rtc_time = rtas_get_rtc_time,
145 .progress = rtas_progress,
146 .get_boot_time = rtas_get_boot_time,
147 .calibrate_decr = generic_calibrate_decr,
148 .phys_mem_access_prot = pci_phys_mem_access_prot,
149};