aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/powerpc/Kconfig11
-rw-r--r--arch/powerpc/platforms/Makefile1
-rw-r--r--arch/powerpc/platforms/pasemi/Makefile1
-rw-r--r--arch/powerpc/platforms/pasemi/pasemi.h8
-rw-r--r--arch/powerpc/platforms/pasemi/pci.c198
-rw-r--r--arch/powerpc/platforms/pasemi/setup.c188
-rw-r--r--arch/powerpc/platforms/pasemi/time.c29
7 files changed, 436 insertions, 0 deletions
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index 904798fd4e74..c9dcec7f3c61 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -413,6 +413,17 @@ config PPC_MAPLE
413 This option enables support for the Maple 970FX Evaluation Board. 413 This option enables support for the Maple 970FX Evaluation Board.
414 For more informations, refer to <http://www.970eval.com> 414 For more informations, refer to <http://www.970eval.com>
415 415
416config PPC_PASEMI
417 depends on PPC_MULTIPLATFORM && PPC64
418 bool "PA Semi SoC-based platforms"
419 default n
420 select MPIC
421 select PPC_UDBG_16550
422 select GENERIC_TBSYNC
423 help
424 This option enables support for PA Semi's PWRficient line
425 of SoC processors, including PA6T-1682M
426
416config PPC_CELL 427config PPC_CELL
417 bool 428 bool
418 default n 429 default n
diff --git a/arch/powerpc/platforms/Makefile b/arch/powerpc/platforms/Makefile
index 5cf46dc57895..e58fa953a50b 100644
--- a/arch/powerpc/platforms/Makefile
+++ b/arch/powerpc/platforms/Makefile
@@ -13,5 +13,6 @@ obj-$(CONFIG_PPC_86xx) += 86xx/
13obj-$(CONFIG_PPC_PSERIES) += pseries/ 13obj-$(CONFIG_PPC_PSERIES) += pseries/
14obj-$(CONFIG_PPC_ISERIES) += iseries/ 14obj-$(CONFIG_PPC_ISERIES) += iseries/
15obj-$(CONFIG_PPC_MAPLE) += maple/ 15obj-$(CONFIG_PPC_MAPLE) += maple/
16obj-$(CONFIG_PPC_PASEMI) += pasemi/
16obj-$(CONFIG_PPC_CELL) += cell/ 17obj-$(CONFIG_PPC_CELL) += cell/
17obj-$(CONFIG_EMBEDDED6xx) += embedded6xx/ 18obj-$(CONFIG_EMBEDDED6xx) += embedded6xx/
diff --git a/arch/powerpc/platforms/pasemi/Makefile b/arch/powerpc/platforms/pasemi/Makefile
new file mode 100644
index 000000000000..1be1a993c5f5
--- /dev/null
+++ b/arch/powerpc/platforms/pasemi/Makefile
@@ -0,0 +1 @@
obj-y += setup.o pci.o time.o
diff --git a/arch/powerpc/platforms/pasemi/pasemi.h b/arch/powerpc/platforms/pasemi/pasemi.h
new file mode 100644
index 000000000000..fd71d72736b2
--- /dev/null
+++ b/arch/powerpc/platforms/pasemi/pasemi.h
@@ -0,0 +1,8 @@
1#ifndef _PASEMI_PASEMI_H
2#define _PASEMI_PASEMI_H
3
4extern unsigned long pas_get_boot_time(void);
5extern void pas_pci_init(void);
6extern void pas_pcibios_fixup(void);
7
8#endif /* _PASEMI_PASEMI_H */
diff --git a/arch/powerpc/platforms/pasemi/pci.c b/arch/powerpc/platforms/pasemi/pci.c
new file mode 100644
index 000000000000..4679c5230413
--- /dev/null
+++ b/arch/powerpc/platforms/pasemi/pci.c
@@ -0,0 +1,198 @@
1/*
2 * Copyright (C) 2006 PA Semi, Inc
3 *
4 * Authors: Kip Walker, PA Semi
5 * Olof Johansson, PA Semi
6 *
7 * Maintained by: Olof Johansson <olof@lixom.net>
8 *
9 * Based on arch/powerpc/platforms/maple/pci.c
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License version 2 as
13 * published by the Free Software Foundation.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 */
24
25
26#include <linux/kernel.h>
27#include <linux/pci.h>
28
29#include <asm/pci-bridge.h>
30#include <asm/machdep.h>
31
32#include <asm/ppc-pci.h>
33
34#define PA_PXP_CFA(bus, devfn, off) (((bus) << 20) | ((devfn) << 12) | (off))
35
36#define CONFIG_OFFSET_VALID(off) ((off) < 4096)
37
38static unsigned long pa_pxp_cfg_addr(struct pci_controller *hose,
39 u8 bus, u8 devfn, int offset)
40{
41 return ((unsigned long)hose->cfg_data) + PA_PXP_CFA(bus, devfn, offset);
42}
43
44static int pa_pxp_read_config(struct pci_bus *bus, unsigned int devfn,
45 int offset, int len, u32 *val)
46{
47 struct pci_controller *hose;
48 unsigned long addr;
49
50 hose = pci_bus_to_host(bus);
51 if (!hose)
52 return PCIBIOS_DEVICE_NOT_FOUND;
53
54 if (!CONFIG_OFFSET_VALID(offset))
55 return PCIBIOS_BAD_REGISTER_NUMBER;
56
57 addr = pa_pxp_cfg_addr(hose, bus->number, devfn, offset);
58
59 /*
60 * Note: the caller has already checked that offset is
61 * suitably aligned and that len is 1, 2 or 4.
62 */
63 switch (len) {
64 case 1:
65 *val = in_8((u8 *)addr);
66 break;
67 case 2:
68 *val = in_le16((u16 *)addr);
69 break;
70 default:
71 *val = in_le32((u32 *)addr);
72 break;
73 }
74
75 return PCIBIOS_SUCCESSFUL;
76}
77
78static int pa_pxp_write_config(struct pci_bus *bus, unsigned int devfn,
79 int offset, int len, u32 val)
80{
81 struct pci_controller *hose;
82 unsigned long addr;
83
84 hose = pci_bus_to_host(bus);
85 if (!hose)
86 return PCIBIOS_DEVICE_NOT_FOUND;
87
88 if (!CONFIG_OFFSET_VALID(offset))
89 return PCIBIOS_BAD_REGISTER_NUMBER;
90
91 addr = pa_pxp_cfg_addr(hose, bus->number, devfn, offset);
92
93 /*
94 * Note: the caller has already checked that offset is
95 * suitably aligned and that len is 1, 2 or 4.
96 */
97 switch (len) {
98 case 1:
99 out_8((u8 *)addr, val);
100 (void) in_8((u8 *)addr);
101 break;
102 case 2:
103 out_le16((u16 *)addr, val);
104 (void) in_le16((u16 *)addr);
105 break;
106 default:
107 out_le32((u32 *)addr, val);
108 (void) in_le32((u32 *)addr);
109 break;
110 }
111 return PCIBIOS_SUCCESSFUL;
112}
113
114static struct pci_ops pa_pxp_ops = {
115 pa_pxp_read_config,
116 pa_pxp_write_config,
117};
118
119static void __init setup_pa_pxp(struct pci_controller *hose)
120{
121 hose->ops = &pa_pxp_ops;
122 hose->cfg_data = ioremap(0xe0000000, 0x10000000);
123}
124
125static int __init add_bridge(struct device_node *dev)
126{
127 struct pci_controller *hose;
128
129 pr_debug("Adding PCI host bridge %s\n", dev->full_name);
130
131 hose = pcibios_alloc_controller(dev);
132 if (!hose)
133 return -ENOMEM;
134
135 hose->first_busno = 0;
136 hose->last_busno = 0xff;
137
138 setup_pa_pxp(hose);
139
140 printk(KERN_INFO "Found PA-PXP PCI host bridge.\n");
141
142 /* Interpret the "ranges" property */
143 /* This also maps the I/O region and sets isa_io/mem_base */
144 pci_process_bridge_OF_ranges(hose, dev, 1);
145 pci_setup_phb_io(hose, 1);
146
147 return 0;
148}
149
150
151void __init pas_pcibios_fixup(void)
152{
153 struct pci_dev *dev = NULL;
154
155 for_each_pci_dev(dev)
156 pci_read_irq_line(dev);
157}
158
159static void __init pas_fixup_phb_resources(void)
160{
161 struct pci_controller *hose, *tmp;
162
163 list_for_each_entry_safe(hose, tmp, &hose_list, list_node) {
164 unsigned long offset = (unsigned long)hose->io_base_virt - pci_io_base;
165 hose->io_resource.start += offset;
166 hose->io_resource.end += offset;
167 printk(KERN_INFO "PCI Host %d, io start: %lx; io end: %lx\n",
168 hose->global_number,
169 hose->io_resource.start, hose->io_resource.end);
170 }
171}
172
173
174void __init pas_pci_init(void)
175{
176 struct device_node *np, *root;
177
178 root = of_find_node_by_path("/");
179 if (!root) {
180 printk(KERN_CRIT "pas_pci_init: can't find root "
181 "of device tree\n");
182 return;
183 }
184
185 for (np = NULL; (np = of_get_next_child(root, np)) != NULL;)
186 if (np->name && !strcmp(np->name, "pxp") && !add_bridge(np))
187 of_node_get(np);
188
189 of_node_put(root);
190
191 pas_fixup_phb_resources();
192
193 /* Setup the linkage between OF nodes and PHBs */
194 pci_devs_phb_init();
195
196 /* Use the common resource allocation mechanism */
197 pci_probe_only = 1;
198}
diff --git a/arch/powerpc/platforms/pasemi/setup.c b/arch/powerpc/platforms/pasemi/setup.c
new file mode 100644
index 000000000000..628482671c15
--- /dev/null
+++ b/arch/powerpc/platforms/pasemi/setup.c
@@ -0,0 +1,188 @@
1/*
2 * Copyright (C) 2006 PA Semi, Inc
3 *
4 * Authors: Kip Walker, PA Semi
5 * Olof Johansson, PA Semi
6 *
7 * Maintained by: Olof Johansson <olof@lixom.net>
8 *
9 * Based on arch/powerpc/platforms/maple/setup.c
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License version 2 as
13 * published by the Free Software Foundation.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 */
24
25#include <linux/config.h>
26#include <linux/errno.h>
27#include <linux/kernel.h>
28#include <linux/delay.h>
29#include <linux/console.h>
30
31#include <asm/prom.h>
32#include <asm/system.h>
33#include <asm/iommu.h>
34#include <asm/machdep.h>
35#include <asm/mpic.h>
36#include <asm/smp.h>
37#include <asm/time.h>
38
39#include "pasemi.h"
40
41static void pas_restart(char *cmd)
42{
43 printk("restart unimplemented, looping...\n");
44 for (;;) ;
45}
46
47static void pas_power_off(void)
48{
49 printk("power off unimplemented, looping...\n");
50 for (;;) ;
51}
52
53static void pas_halt(void)
54{
55 pas_power_off();
56}
57
58#ifdef CONFIG_SMP
59struct smp_ops_t pas_smp_ops = {
60 .probe = smp_mpic_probe,
61 .message_pass = smp_mpic_message_pass,
62 .kick_cpu = smp_generic_kick_cpu,
63 .setup_cpu = smp_mpic_setup_cpu,
64 .give_timebase = smp_generic_give_timebase,
65 .take_timebase = smp_generic_take_timebase,
66};
67#endif /* CONFIG_SMP */
68
69void __init pas_setup_arch(void)
70{
71#ifdef CONFIG_SMP
72 /* Setup SMP callback */
73 smp_ops = &pas_smp_ops;
74#endif
75 /* Lookup PCI hosts */
76 pas_pci_init();
77
78#ifdef CONFIG_DUMMY_CONSOLE
79 conswitchp = &dummy_con;
80#endif
81
82 printk(KERN_DEBUG "Using default idle loop\n");
83}
84
85static void iommu_dev_setup_null(struct pci_dev *dev) { }
86static void iommu_bus_setup_null(struct pci_bus *bus) { }
87
88static void __init pas_init_early(void)
89{
90 /* No iommu code yet */
91 ppc_md.iommu_dev_setup = iommu_dev_setup_null;
92 ppc_md.iommu_bus_setup = iommu_bus_setup_null;
93 pci_direct_iommu_init();
94}
95
96/* No legacy IO on our parts */
97static int pas_check_legacy_ioport(unsigned int baseport)
98{
99 return -ENODEV;
100}
101
102static __init void pas_init_IRQ(void)
103{
104 struct device_node *np;
105 struct device_node *root, *mpic_node;
106 unsigned long openpic_addr;
107 const unsigned int *opprop;
108 int naddr, opplen;
109 struct mpic *mpic;
110
111 mpic_node = NULL;
112
113 for_each_node_by_type(np, "interrupt-controller")
114 if (device_is_compatible(np, "open-pic")) {
115 mpic_node = np;
116 break;
117 }
118 if (!mpic_node)
119 for_each_node_by_type(np, "open-pic") {
120 mpic_node = np;
121 break;
122 }
123 if (!mpic_node) {
124 printk(KERN_ERR
125 "Failed to locate the MPIC interrupt controller\n");
126 return;
127 }
128
129 /* Find address list in /platform-open-pic */
130 root = of_find_node_by_path("/");
131 naddr = prom_n_addr_cells(root);
132 opprop = get_property(root, "platform-open-pic", &opplen);
133 if (!opprop) {
134 printk(KERN_ERR "No platform-open-pic property.\n");
135 of_node_put(root);
136 return;
137 }
138 openpic_addr = of_read_number(opprop, naddr);
139 printk(KERN_DEBUG "OpenPIC addr: %lx\n", openpic_addr);
140 of_node_put(root);
141
142 mpic = mpic_alloc(mpic_node, openpic_addr, MPIC_PRIMARY, 0, 0,
143 " PAS-OPIC ");
144 BUG_ON(!mpic);
145
146 mpic_assign_isu(mpic, 0, openpic_addr + 0x10000);
147 mpic_init(mpic);
148 of_node_put(mpic_node);
149 of_node_put(root);
150}
151
152static void __init pas_progress(char *s, unsigned short hex)
153{
154 printk("[%04x] : %s\n", hex, s ? s : "");
155}
156
157
158/*
159 * Called very early, MMU is off, device-tree isn't unflattened
160 */
161static int __init pas_probe(void)
162{
163 unsigned long root = of_get_flat_dt_root();
164
165 if (!of_flat_dt_is_compatible(root, "PA6T-1682M"))
166 return 0;
167
168 hpte_init_native();
169
170 return 1;
171}
172
173define_machine(pas) {
174 .name = "PA Semi PA6T-1682M",
175 .probe = pas_probe,
176 .setup_arch = pas_setup_arch,
177 .init_early = pas_init_early,
178 .init_IRQ = pas_init_IRQ,
179 .get_irq = mpic_get_irq,
180 .pcibios_fixup = pas_pcibios_fixup,
181 .restart = pas_restart,
182 .power_off = pas_power_off,
183 .halt = pas_halt,
184 .get_boot_time = pas_get_boot_time,
185 .calibrate_decr = generic_calibrate_decr,
186 .check_legacy_ioport = pas_check_legacy_ioport,
187 .progress = pas_progress,
188};
diff --git a/arch/powerpc/platforms/pasemi/time.c b/arch/powerpc/platforms/pasemi/time.c
new file mode 100644
index 000000000000..9bd410b8fec6
--- /dev/null
+++ b/arch/powerpc/platforms/pasemi/time.c
@@ -0,0 +1,29 @@
1/*
2 * Copyright (C) 2006 PA Semi, Inc
3 *
4 * Maintained by: Olof Johansson <olof@lixom.net>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 */
19
20#include <linux/config.h>
21#include <linux/time.h>
22
23#include <asm/time.h>
24
25unsigned long __init pas_get_boot_time(void)
26{
27 /* Let's just return a fake date right now */
28 return mktime(2006, 1, 1, 12, 0, 0);
29}